From 7cf24ce07484a6d86cd97a9af9c240da7e1a4043 Mon Sep 17 00:00:00 2001 From: Raptor Engineering Development Team Date: Fri, 29 Dec 2017 00:34:27 -0600 Subject: Initial conversion pass VHDL to Verilog --- I2C_SLAVE_LICENSE | 21 ++ LICENSE | 22 +++ i2c_slave.v | 252 +++++++++++++++++++++++ i2c_slave.vhd | 270 ------------------------- pwrseq.v | 207 +++++++++++++++++++ pwrseq.vhd | 196 ------------------ top.v | 536 +++++++++++++++++++++++++++++++++++++++++++++++++ top.vhd | 555 --------------------------------------------------- txt_util.vhd | 582 ------------------------------------------------------ 9 files changed, 1038 insertions(+), 1603 deletions(-) create mode 100644 I2C_SLAVE_LICENSE create mode 100644 LICENSE create mode 100644 i2c_slave.v delete mode 100644 i2c_slave.vhd create mode 100644 pwrseq.v delete mode 100644 pwrseq.vhd create mode 100644 top.v delete mode 100644 top.vhd delete mode 100644 txt_util.vhd diff --git a/I2C_SLAVE_LICENSE b/I2C_SLAVE_LICENSE new file mode 100644 index 0000000..1ae7d03 --- /dev/null +++ b/I2C_SLAVE_LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2014-2016 Peter Samarin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b7d0e74 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2017, Raptor Engineering, LLC +Copyright (c) 2017, International Business Machines Corp. +All rights reserved. +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: +1) Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer: 2) Redistributions in binary +form must reproduce the above copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other materials provided with the +distribution, and; 3) Neither the name of the Texas Instruments nor the names of its +contributors may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS, +STATUTORY OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/i2c_slave.v b/i2c_slave.v new file mode 100644 index 0000000..2701ef4 --- /dev/null +++ b/i2c_slave.v @@ -0,0 +1,252 @@ +// Copyright © 2017 Raptor Engineering, LLC +// Copyright © 2014-2016 Peter Samarin +// All Rights Reserved +// +// See I2C_SLAVE_LICENSE file for licensing details + +module I2C_slave( + inout wire scl, + inout wire sda, + input wire clk, + input wire rst, + + // User interface + output wire read_req, + input wire [7:0] data_to_master, + output wire data_valid, + output wire [7:0] data_from_master + ); + + parameter [6:0] SLAVE_ADDR; + + + //---------------------------------------------------------- + parameter [2:0] + i2c_idle = 0, + i2c_get_address_and_cmd = 1, + i2c_answer_ack_start = 2, + i2c_write = 3, + i2c_read = 4, + i2c_read_ack_start = 5, + i2c_read_ack_got_rising = 6, + i2c_read_stop = 7; + // I2C state management + reg [2:0] state_reg = i2c_idle; + reg cmd_reg = 1'b0; + reg [31:0] bits_processed_reg = 0; + reg continue_reg = 1'b0; // Helpers to figure out next state + reg start_reg = 1'b0; + reg stop_reg = 1'b0; + reg scl_rising_reg = 1'b0; + reg scl_falling_reg = 1'b0; // Address and data received from master + reg [6:0] addr_reg = 1'b0; + reg [7:0] data_reg = 1'b0; // Delayed SCL (by 1 clock cycle, and by 2 clock cycles) + reg scl_reg = 1'b1; + reg scl_prev_reg = 1'b1; // Slave writes on scl + wire scl_wen_reg = 1'b0; + wire scl_o_reg = 1'b0; // Delayed SDA (1 clock cycle, and 2 clock cycles) + reg sda_reg = 1'b1; + reg sda_prev_reg = 1'b1; // Slave writes on sda + reg sda_wen_reg = 1'b0; + reg sda_o_reg = 1'b0; // User interface + reg data_valid_reg = 1'b0; + reg read_req_reg = 1'b0; + reg [7:0] data_to_master_reg = 1'b0; + + always @(posedge clk) begin + // Delay SCL by 1 and 2 clock cycles + scl_reg <= scl; + scl_prev_reg <= scl_reg; + + // Delay SDA by 1 and 2 clock cycles + sda_reg <= sda; + sda_prev_reg <= sda_reg; + + // Detect rising and falling SCL + scl_rising_reg <= 1'b0; + if (scl_prev_reg == 1'b0 && scl_reg == 1'b1) begin + scl_rising_reg <= 1'b1; + end + scl_falling_reg <= 1'b0; + if (scl_prev_reg == 1'b1 && scl_reg == 1'b0) begin + scl_falling_reg <= 1'b1; + end + + // Detect I2C START condition + start_reg <= 1'b0; + stop_reg <= 1'b0; + if (scl_reg == 1'b1 && scl_prev_reg == 1'b1 && sda_prev_reg == 1'b1 && sda_reg == 1'b0) begin + start_reg <= 1'b1; + stop_reg <= 1'b0; + end + + // Detect I2C STOP condition + if (scl_prev_reg == 1'b1 && scl_reg == 1'b1 && sda_prev_reg == 1'b0 && sda_reg == 1'b1) begin + start_reg <= 1'b0; + stop_reg <= 1'b1; + end + end + + //-------------------------------------------------------- + // I2C state machine + //-------------------------------------------------------- + always @(posedge clk) begin + // Default assignments + sda_o_reg <= 1'b0; + sda_wen_reg <= 1'b0; + + // User interface + data_valid_reg <= 1'b0; + read_req_reg <= 1'b0; + + case(state_reg) + i2c_idle : begin + if (start_reg == 1'b1) begin + state_reg <= i2c_get_address_and_cmd; + bits_processed_reg <= 0; + end + end + i2c_get_address_and_cmd : begin + if (scl_rising_reg == 1'b1) begin + if (bits_processed_reg < 7) begin + bits_processed_reg <= bits_processed_reg + 1; + addr_reg[6 - bits_processed_reg] <= sda_reg; + end + else if (bits_processed_reg == 7) begin + bits_processed_reg <= bits_processed_reg + 1; + cmd_reg <= sda_reg; + end + end + if (bits_processed_reg == 8 && scl_falling_reg == 1'b1) begin + bits_processed_reg <= 0; + if (addr_reg == SLAVE_ADDR) begin + // check req address + state_reg <= i2c_answer_ack_start; + if (cmd_reg == 1'b1) begin + // issue read request + read_req_reg <= 1'b1; + data_to_master_reg <= data_to_master; + end + end else begin + state_reg <= i2c_idle; + end + end + end + i2c_answer_ack_start : begin + //-------------------------------------------------- + // I2C acknowledge to master + //-------------------------------------------------- + sda_wen_reg <= 1'b1; + sda_o_reg <= 1'b0; + if (scl_falling_reg == 1'b1) begin + if (cmd_reg == 1'b0) begin + state_reg <= i2c_write; + end else begin + state_reg <= i2c_read; + end + end + end + i2c_write : begin + //-------------------------------------------------- + // WRITE + //-------------------------------------------------- + if (scl_rising_reg == 1'b1) begin + if (bits_processed_reg <= 7) begin + data_reg[7 - bits_processed_reg] <= sda_reg; + bits_processed_reg <= bits_processed_reg + 1; + end + if (bits_processed_reg == 7) begin + data_valid_reg <= 1'b1; + end + end + if (scl_falling_reg == 1'b1 && bits_processed_reg == 8) begin + state_reg <= i2c_answer_ack_start; + bits_processed_reg <= 0; + end + end + i2c_read : begin + //-------------------------------------------------- + // READ: send data to master + //-------------------------------------------------- + sda_wen_reg <= 1'b1; + sda_o_reg <= data_to_master_reg[7 - bits_processed_reg]; + if (scl_falling_reg == 1'b1) begin + if (bits_processed_reg < 7) begin + bits_processed_reg <= bits_processed_reg + 1; + end + else if (bits_processed_reg == 7) begin + state_reg <= i2c_read_ack_start; + bits_processed_reg <= 0; + end + end + end + i2c_read_ack_start : begin + //-------------------------------------------------- + // I2C read master acknowledge + //-------------------------------------------------- + if (scl_rising_reg == 1'b1) begin + state_reg <= i2c_read_ack_got_rising; + if (sda_reg == 1'b1) begin + // nack = stop read + continue_reg <= 1'b0; + end else begin + // ack = continue read + continue_reg <= 1'b1; + read_req_reg <= 1'b1; + + // request reg byte + data_to_master_reg <= data_to_master; + end + end + end + i2c_read_ack_got_rising : begin + // Wait for START or STOP to get out of this state + if (scl_falling_reg == 1'b1) begin + if (continue_reg == 1'b1) begin + if (cmd_reg == 1'b0) begin + state_reg <= i2c_write; + end else begin + state_reg <= i2c_read; + end + end else begin + state_reg <= i2c_read_stop; + end + end + end + i2c_read_stop : begin + // Wait for START or STOP to get out of this state + end + default : begin + end + endcase + //------------------------------------------------------ + // Reset counter and state on start/stop + //------------------------------------------------------ + if (start_reg == 1'b1) begin + state_reg <= i2c_get_address_and_cmd; + bits_processed_reg <= 0; + end + if (stop_reg == 1'b1) begin + state_reg <= i2c_idle; + bits_processed_reg <= 0; + end + if (rst == 1'b1) begin + state_reg <= i2c_idle; + end + end + + //-------------------------------------------------------- + // I2C interface + //-------------------------------------------------------- + assign sda = sda_wen_reg == 1'b1 ? sda_o_reg : 1'bZ; + assign scl = scl_wen_reg == 1'b1 ? scl_o_reg : 1'bZ; + //-------------------------------------------------------- + // User interface + //-------------------------------------------------------- + // Master writes + assign data_valid = data_valid_reg; + assign data_from_master = data_reg; + // Master reads + assign read_req = read_req_reg; + +endmodule \ No newline at end of file diff --git a/i2c_slave.vhd b/i2c_slave.vhd deleted file mode 100644 index 80871a6..0000000 --- a/i2c_slave.vhd +++ /dev/null @@ -1,270 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; -use work.txt_util.all; ------------------------------------------------------------- -entity I2C_slave is - generic ( - SLAVE_ADDR : std_logic_vector(6 downto 0)); - port ( - scl : inout std_logic; - sda : inout std_logic; - clk : in std_logic; - rst : in std_logic; - -- User interface - read_req : out std_logic; - data_to_master : in std_logic_vector(7 downto 0); - data_valid : out std_logic; - data_from_master : out std_logic_vector(7 downto 0)); -end entity I2C_slave; ------------------------------------------------------------- -architecture arch of I2C_slave is - type state_t is (i2c_idle, i2c_get_address_and_cmd, - i2c_answer_ack_start, i2c_write, - i2c_read, i2c_read_ack_start, - i2c_read_ack_got_rising, i2c_read_stop); - -- I2C state management - signal state_reg : state_t := i2c_idle; - signal cmd_reg : std_logic := '0'; - signal bits_processed_reg : integer range 0 to 8 := 0; - signal continue_reg : std_logic := '0'; - - -- Helpers to figure out next state - signal start_reg : std_logic := '0'; - signal stop_reg : std_logic := '0'; - signal scl_rising_reg : std_logic := '0'; - signal scl_falling_reg : std_logic := '0'; - - -- Address and data received from master - signal addr_reg : std_logic_vector(6 downto 0) := (others => '0'); - signal data_reg : std_logic_vector(7 downto 0) := (others => '0'); - - -- Delayed SCL (by 1 clock cycle, and by 2 clock cycles) - signal scl_reg : std_logic := '1'; - signal scl_prev_reg : std_logic := '1'; - -- Slave writes on scl - signal scl_wen_reg : std_logic := '0'; - signal scl_o_reg : std_logic := '0'; - -- Delayed SDA (1 clock cycle, and 2 clock cycles) - signal sda_reg : std_logic := '1'; - signal sda_prev_reg : std_logic := '1'; - -- Slave writes on sda - signal sda_wen_reg : std_logic := '0'; - signal sda_o_reg : std_logic := '0'; - - -- User interface - signal data_valid_reg : std_logic := '0'; - signal read_req_reg : std_logic := '0'; - signal data_to_master_reg : std_logic_vector(7 downto 0) := (others => '0'); -begin - process (clk) is - begin - if rising_edge(clk) then - -- Delay SCL by 1 and 2 clock cycles - scl_reg <= scl; - scl_prev_reg <= scl_reg; - -- Delay SDA by 1 and 2 clock cycles - sda_reg <= sda; - sda_prev_reg <= sda_reg; - -- Detect rising and falling SCL - scl_rising_reg <= '0'; - if scl_prev_reg = '0' and scl_reg = '1' then - scl_rising_reg <= '1'; - end if; - scl_falling_reg <= '0'; - if scl_prev_reg = '1' and scl_reg = '0' then - scl_falling_reg <= '1'; - end if; - - -- Detect I2C START condition - start_reg <= '0'; - stop_reg <= '0'; - if scl_reg = '1' and scl_prev_reg = '1' and - sda_prev_reg = '1' and sda_reg = '0' then - start_reg <= '1'; - stop_reg <= '0'; - end if; - - -- Detect I2C STOP condition - if scl_prev_reg = '1' and scl_reg = '1' and - sda_prev_reg = '0' and sda_reg = '1' then - start_reg <= '0'; - stop_reg <= '1'; - end if; - - end if; - end process; - - ---------------------------------------------------------- - -- I2C state machine - ---------------------------------------------------------- - process (clk) is - begin - if rising_edge(clk) then - -- Default assignments - sda_o_reg <= '0'; - sda_wen_reg <= '0'; - -- User interface - data_valid_reg <= '0'; - read_req_reg <= '0'; - - case state_reg is - - when i2c_idle => - if start_reg = '1' then - state_reg <= i2c_get_address_and_cmd; - bits_processed_reg <= 0; - end if; - - when i2c_get_address_and_cmd => - if scl_rising_reg = '1' then - if bits_processed_reg < 7 then - bits_processed_reg <= bits_processed_reg + 1; - addr_reg(6-bits_processed_reg) <= sda_reg; - elsif bits_processed_reg = 7 then - bits_processed_reg <= bits_processed_reg + 1; - cmd_reg <= sda_reg; - end if; - end if; - - if bits_processed_reg = 8 and scl_falling_reg = '1' then - bits_processed_reg <= 0; - if addr_reg = SLAVE_ADDR then -- check req address - state_reg <= i2c_answer_ack_start; - if cmd_reg = '1' then -- issue read request - read_req_reg <= '1'; - data_to_master_reg <= data_to_master; - end if; - else - assert false - report ("I2C: slave address: " & str(SLAVE_ADDR) & - ", requested address: " & str(addr_reg)) - severity note; - state_reg <= i2c_idle; - end if; - end if; - - ---------------------------------------------------- - -- I2C acknowledge to master - ---------------------------------------------------- - when i2c_answer_ack_start => - sda_wen_reg <= '1'; - sda_o_reg <= '0'; - if scl_falling_reg = '1' then - if cmd_reg = '0' then - state_reg <= i2c_write; - else - state_reg <= i2c_read; - end if; - end if; - - ---------------------------------------------------- - -- WRITE - ---------------------------------------------------- - when i2c_write => - if scl_rising_reg = '1' then - if bits_processed_reg <= 7 then - data_reg(7-bits_processed_reg) <= sda_reg; - bits_processed_reg <= bits_processed_reg + 1; - end if; - if bits_processed_reg = 7 then - data_valid_reg <= '1'; - end if; - end if; - - if scl_falling_reg = '1' and bits_processed_reg = 8 then - state_reg <= i2c_answer_ack_start; - bits_processed_reg <= 0; - end if; - - ---------------------------------------------------- - -- READ: send data to master - ---------------------------------------------------- - when i2c_read => - sda_wen_reg <= '1'; - sda_o_reg <= data_to_master_reg(7-bits_processed_reg); - if scl_falling_reg = '1' then - if bits_processed_reg < 7 then - bits_processed_reg <= bits_processed_reg + 1; - elsif bits_processed_reg = 7 then - state_reg <= i2c_read_ack_start; - bits_processed_reg <= 0; - end if; - end if; - - ---------------------------------------------------- - -- I2C read master acknowledge - ---------------------------------------------------- - when i2c_read_ack_start => - if scl_rising_reg = '1' then - state_reg <= i2c_read_ack_got_rising; - if sda_reg = '1' then -- nack = stop read - continue_reg <= '0'; - else -- ack = continue read - continue_reg <= '1'; - read_req_reg <= '1'; -- request reg byte - data_to_master_reg <= data_to_master; - end if; - end if; - - when i2c_read_ack_got_rising => - if scl_falling_reg = '1' then - if continue_reg = '1' then - if cmd_reg = '0' then - state_reg <= i2c_write; - else - state_reg <= i2c_read; - end if; - else - state_reg <= i2c_read_stop; - end if; - end if; - - -- Wait for START or STOP to get out of this state - when i2c_read_stop => - null; - - -- Wait for START or STOP to get out of this state - when others => - assert false - report ("I2C: slave address: " & str(SLAVE_ADDR) & - "ended up in an impossible state.") - severity note; - null; - end case; - - -------------------------------------------------------- - -- Reset counter and state on start/stop - -------------------------------------------------------- - if start_reg = '1' then - state_reg <= i2c_get_address_and_cmd; - bits_processed_reg <= 0; - end if; - - if stop_reg = '1' then - state_reg <= i2c_idle; - bits_processed_reg <= 0; - end if; - - if rst = '1' then - state_reg <= i2c_idle; - end if; - end if; - end process; - - ---------------------------------------------------------- - -- I2C interface - ---------------------------------------------------------- - sda <= sda_o_reg when sda_wen_reg = '1' else - 'Z'; - scl <= scl_o_reg when scl_wen_reg = '1' else - 'Z'; - ---------------------------------------------------------- - -- User interface - ---------------------------------------------------------- - -- Master writes - data_valid <= data_valid_reg; - data_from_master <= data_reg; - -- Master reads - read_req <= read_req_reg; -end architecture arch; \ No newline at end of file diff --git a/pwrseq.v b/pwrseq.v new file mode 100644 index 0000000..c4f9f5a --- /dev/null +++ b/pwrseq.v @@ -0,0 +1,207 @@ +// Copyright © 2017 Raptor Engineering, LLC +// Copyright © 2017, International Business Machines Corp. +// All Rights Reserved +// +// See LICENSE file for licensing details + +module pwrseq( + output wire [rail_size - 1:0] EN, + input wire [rail_size - 1:0] PGOOD_A, + input wire SYSEN_A, + output wire SYSGOOD, + inout wire SCL, + inout wire SDA, + input wire CLK_IN + ); + + parameter [31:0] rail_size; + + // Input output buffers and synchronizers + reg [rail_size - 1:0] EN_BUF = 1'b0; + reg [rail_size - 1:0] PGOOD = 1'b0; + reg [rail_size - 1:0] PGOOD_S = 1'b0; + reg SYSEN = 1'b0; + reg SYSEN_S = 1'b0; + reg SYSGOOD_BUF = 1'b0; + + // Sequencer State Machine + parameter [2:0] idleon = 0; + parameter [2:0] shifton = 1; + parameter [2:0] waitpgood = 2; + parameter [2:0] waiten = 3; + parameter [2:0] idleoff = 4; + parameter [2:0] shiftoff = 5; + parameter [2:0] waitoff = 6; + + reg [2:0] state = idleoff; + reg ERR = 1'b0; + reg [15:0] err_msg = 1'b1; + parameter all_on = 1'b1; + parameter all_off = 1'b0; + + // Clocks and timers + parameter counter_size = 20; + reg [counter_size - 1:0] T_COUNT; + + // t_max_wait is max delay from Enable assert to Pgood assert (200 ms assumption 4.125MHz clk) + parameter t_max_wait = 825000; + + // t_delay is delay from Pgood assert to next Enable assert (1ms assumption 4.125MHz clk) + parameter t_delay = 4125; + + //I2C signals + wire i2c_read_req; + reg [7:0] i2c_data_to_master = 8'b00000000; + wire [7:0] i2c_data_from_master; + wire i2c_data_valid; + wire i2c_rst = 1'b0; + reg [7:0] i2c_reg_cur = 8'b00000000; + parameter i2c_addr = 7'b0110001; + parameter i2c_pg_reg_addr1 = 8'b00000001; + parameter i2c_pg_reg_addr2 = i2c_pg_reg_addr1 + 1; + parameter i2c_status_reg_addr = i2c_pg_reg_addr2 + 1; + + I2C_slave #(i2c_addr) + I2C_SLAVE( + SCL, + SDA, + CLK_IN, + i2c_rst, + i2c_read_req, + i2c_data_to_master, + i2c_data_valid, + i2c_data_from_master + ); + + // Handle I2C + // 2 8-bit registers with PGOOD state on error + always @(posedge CLK_IN) begin + //return high byte with any memory address, loop on any consecutive reads + if (i2c_data_valid == 1'b1) begin + i2c_reg_cur <= i2c_data_from_master; + end + else if (i2c_read_req == 1'b1) begin + i2c_reg_cur <= i2c_reg_cur + 1; + end + case(i2c_reg_cur) + i2c_pg_reg_addr1 : begin + i2c_data_to_master <= err_msg[15:8]; + end + i2c_pg_reg_addr2 : begin + i2c_data_to_master <= err_msg[7:0]; + end + i2c_status_reg_addr : begin + i2c_data_to_master <= {6'b000000,SYSEN,SYSGOOD_BUF}; + end + default : begin + i2c_data_to_master <= 8'b00000000; + end + endcase + end + + // Power Sequencer state machine + always @(posedge CLK_IN) begin + // Increase counter + T_COUNT <= T_COUNT + 1; + + // Synchronize Asynchronous inputs to clock + PGOOD_S <= PGOOD_A; + PGOOD <= PGOOD_S; + SYSEN_S <= SYSEN_A; + SYSEN <= SYSEN_S; + + // Decide next state + case(state) + idleoff : begin + //Only leave idle off if system enable active and no error + if (ERR == 1'b1) begin + state <= idleoff; + end + else if (SYSEN == 1'b1) begin + state <= shifton; + end else begin + state <= idleoff; + end + end + shifton : begin + // enable next power rail, reset counter, wait for pgood + EN_BUF[rail_size - 1:1] <= EN_BUF[rail_size - 2:0]; + EN_BUF[0] <= 1'b1; + T_COUNT <= {(((counter_size - 1))-((0))+1){1'b0}}; + state <= waitpgood; + end + waitpgood : begin + // Wait for enabled power rail's PGOOD, after time with no pgood, error + if (T_COUNT > t_max_wait) begin + ERR <= 1'b1; + err_msg <= {16{1'b0}}; + err_msg[rail_size - 1:0] <= EN_BUF & PGOOD; + state <= shiftoff; + end + else if ((EN_BUF & PGOOD) == all_on) begin + state <= idleon; + end + else if (((EN_BUF & PGOOD) == EN_BUF)) begin + T_COUNT <= {(((counter_size - 1))-((0))+1){1'b0}}; + state <= waiten; + end else begin + state <= waitpgood; + end + end + waiten : begin + // delay between last pgood and next enable + if (T_COUNT > t_delay) begin + T_COUNT <= {(((counter_size - 1))-((0))+1){1'b0}}; + state <= shifton; + end else begin + state <= waiten; + end + end + idleon : begin + // stay in idle on unless power rail goes down (error) or system enable removed + SYSGOOD_BUF <= 1'b1; + if ((!(PGOOD == all_on))) begin + ERR <= 1'b1; + err_msg <= {16{1'b0}}; + err_msg[rail_size - 1:0] <= PGOOD; + end + if (((SYSEN == 1'b0) || (ERR == 1'b1))) begin + SYSGOOD_BUF <= 1'b0; + state <= shiftoff; + end else begin + state <= idleon; + end + end + shiftoff : begin + // Turn off enable for next power rail + EN_BUF[rail_size - 2:0] <= EN_BUF[rail_size - 1:1]; + EN_BUF[rail_size - 1] <= 1'b0; + if ((EN_BUF == all_off)) begin + state <= idleoff; + end else begin + T_COUNT <= {(((counter_size - 1))-((0))+1){1'b0}}; + state <= waitoff; + end + end + waitoff : begin + // in controlled shutdown, delay between disabling power rails + if (ERR == 1'b1) begin + state <= shiftoff; + //LED_BUF <= "10"; + end + else if (T_COUNT > t_delay) begin + state <= shiftoff; + //LED_BUF <= "10"; + end else begin + state <= waitoff; + end + end + endcase + end + + // Output enable buffer to pins + assign EN = ~(EN_BUF); + assign i2c_rst = 1'b0; + assign SYSGOOD = SYSGOOD_BUF; + +endmodule \ No newline at end of file diff --git a/pwrseq.vhd b/pwrseq.vhd deleted file mode 100644 index 39b0f08..0000000 --- a/pwrseq.vhd +++ /dev/null @@ -1,196 +0,0 @@ -library IEEE; -use IEEE.numeric_std.ALL; -use IEEE.STD_LOGIC_1164.ALL; - -entity pwrseq is - generic (rail_size : integer); - Port (EN : out STD_LOGIC_VECTOR (rail_size-1 downto 0) := (others=>'0'); - PGOOD_A : in STD_LOGIC_VECTOR (rail_size-1 downto 0); - SYSEN_A : in STD_LOGIC; - SYSGOOD: out STD_LOGIC := '0'; - SCL: inout STD_LOGIC; - SDA: inout STD_LOGIC; - CLK_IN: in STD_LOGIC); -end pwrseq; - -architecture Behavioral of pwrseq is - --Input output buffers and synchronizers - --constant rail_size : integer := EN'LENGTH; - signal EN_BUF : STD_LOGIC_VECTOR (rail_size-1 downto 0) := (others => '0'); - signal PGOOD : STD_LOGIC_VECTOR (rail_size-1 downto 0) := (others => '0'); - signal PGOOD_S : STD_LOGIC_VECTOR (rail_size-1 downto 0) := (others => '0'); - signal SYSEN : STD_LOGIC := '0'; - signal SYSEN_S : STD_LOGIC := '0'; - signal SYSGOOD_BUF : STD_LOGIC := '0'; - - --Sequencer State Machine - type state_type is (idleon,shifton,waitpgood,waiten,idleoff,shiftoff,waitoff); - signal state : state_type := idleoff; - signal ERR : STD_LOGIC := '0'; - signal err_msg : STD_LOGIC_VECTOR (15 downto 0) := (others => '1'); - constant all_on : STD_LOGIC_VECTOR (rail_size-1 downto 0) := (others=>'1'); - constant all_off : STD_LOGIC_VECTOR (rail_size-1 downto 0) := (others =>'0'); - - --Clocks and timers - constant counter_size : integer := 20; - signal T_COUNT : UNSIGNED (counter_size-1 downto 0); - --t_max_wait is max delay from Enable assert to Pgood assert (200 ms assumption 4.125MHz clk) - constant t_max_wait : UNSIGNED (counter_size-1 downto 0) := TO_UNSIGNED(825000,counter_size); - --t_delay is delay from Pgood assert to next Enable assert (1ms assumption 4.125MHz clk) - constant t_delay : UNSIGNED (counter_size-1 downto 0) := TO_UNSIGNED(4125,counter_size); - - --i2c signals - signal i2c_read_req : STD_LOGIC; - signal i2c_data_to_master : STD_LOGIC_VECTOR(7 downto 0) := "00000000"; - signal i2c_data_from_master : STD_LOGIC_VECTOR(7 downto 0); - signal i2c_data_valid : STD_LOGIC; - signal i2c_rst : STD_LOGIC := '0'; - signal i2c_reg_cur : UNSIGNED(7 downto 0) := "00000000"; - constant i2c_addr : STD_LOGIC_VECTOR (6 downto 0) := "0110001"; - constant i2c_pg_reg_addr1 : UNSIGNED (7 downto 0) := "00000001"; - constant i2c_pg_reg_addr2 : UNSIGNED (7 downto 0) := i2c_pg_reg_addr1 + 1; - constant i2c_status_reg_addr : UNSIGNED (7 downto 0) := i2c_pg_reg_addr2 + 1; - - -begin - - ---I2C device -I2C_SLAVE: entity work.I2C_slave generic map(i2c_addr) port map( - SCL, SDA, CLK_IN, i2c_rst, - i2c_read_req,i2c_data_to_master, - i2c_data_valid,i2c_data_from_master); - ---Handle I2C - --2 8-bit registers with PGOOD state on error - process (CLK_IN) - begin - if (rising_edge(CLK_IN)) then - --return high byte with any memory address, loop on any consecutive reads - if i2c_data_valid = '1' then - i2c_reg_cur <= unsigned(i2c_data_from_master); - elsif i2c_read_req = '1' then - i2c_reg_cur <= i2c_reg_cur + 1; - end if; - - case i2c_reg_cur is - when i2c_pg_reg_addr1 => - i2c_data_to_master <= err_msg(15 downto 8); - when i2c_pg_reg_addr2 => - i2c_data_to_master <= err_msg(7 downto 0); - when i2c_status_reg_addr => - i2c_data_to_master <= "000000" & SYSEN & SYSGOOD_BUF; - when others => - i2c_data_to_master <= "00000000"; - end case; - end if; - end process; - --- Power Sequencer state machine - process (CLK_IN) - begin - if rising_edge(CLK_IN) then - - - -- Increase counter - T_COUNT <= T_COUNT + 1; - - -- Synchronize Asynchronous inputs to clock - PGOOD_S <= PGOOD_A; - PGOOD <= PGOOD_S; - SYSEN_S <= SYSEN_A; - SYSEN <= SYSEN_S; - -- Decide next state - case state is - when idleoff=> - --Only leave idle off if system enable active and no error - if ERR = '1' then - state <= idleoff; - elsif SYSEN = '1' then - state <= shifton; - else - state <= idleoff; - end if; - when shifton=> - -- enable next power rail, reset counter, wait for pgood - EN_BUF(rail_size-1 downto 1) <= EN_BUF(rail_size-2 downto 0); - EN_BUF(0) <= '1'; - T_COUNT <= (others=>'0'); - state <= waitpgood; - when waitpgood=> - -- Wait for enabled power rail's PGOOD, after time with no pgood, error - if T_COUNT > t_max_wait then - ERR <= '1'; - err_msg <= (others =>'0'); - err_msg(rail_size-1 downto 0) <= EN_BUF and PGOOD; - state <= shiftoff; - - elsif (EN_BUF and PGOOD) = all_on then - state <=idleon; - - elsif ((EN_BUF and PGOOD) = EN_BUF) then - T_COUNT <= (others => '0'); - state <= waiten; - else - state <= waitpgood; - end if; - -- delay between last pgood and next enable - when waiten=> - if T_COUNT > t_delay then - T_COUNT <= (others => '0'); - state <= shifton; - - else - state <= waiten; - end if; - - -- stay in idle on unless power rail goes down (error) or system enable removed - when idleon=> - SYSGOOD_BUF <= '1'; - if (not(PGOOD = all_on)) then - ERR <= '1'; - err_msg <= (others =>'0'); - err_msg(rail_size-1 downto 0) <= PGOOD; - end if; - if ((SYSEN = '0') or (ERR = '1')) then - SYSGOOD_BUF <= '0'; - state <= shiftoff; - - else - state <= idleon; - end if; - -- Turn off enable for next power rail - when shiftoff=> - EN_BUF(rail_size-2 downto 0) <= EN_BUF(rail_size-1 downto 1); - EN_BUF(rail_size-1) <= '0'; - if(EN_BUF=all_off) then - state <= idleoff; - - else - T_COUNT <= (others => '0'); - state <= waitoff; - end if; - -- in controlled shutdown, delay between disabling power rails - when waitoff=> - if ERR = '1' then - state <= shiftoff; - --LED_BUF <= "10"; - elsif T_COUNT > t_delay then - state <= shiftoff; - --LED_BUF <= "10"; - else - state <= waitoff; - end if; - end case; - end if; - end process; - - --- Output enable buffer to pins - EN <= not(EN_BUF); - i2c_rst <= '0'; - SYSGOOD <=SYSGOOD_BUF; - - -end Behavioral; - diff --git a/top.v b/top.v new file mode 100644 index 0000000..a107dda --- /dev/null +++ b/top.v @@ -0,0 +1,536 @@ +// Copyright © 2017 Raptor Engineering, LLC +// Copyright © 2017, International Business Machines Corp. +// All Rights Reserved +// +// See LICENSE file for licensing details + +module FPGA_TOP + ( + // General I/O + input wire SYSEN, + output wire SYSGOOD, + input wire DEBUG_IN, + + // DD1 temp fix for VCS overcurrent bug + input wire SEQ_CONT, + + // Enable outputs + output wire VDDA_EN, + output wire VDDB_EN, + output wire VCSA_EN, + output wire VCSB_EN, + output wire VDNA_EN, + output wire VDNB_EN, + output wire VIOA_EN, + output wire VIOB_EN, + output wire VPPAB_EN, + output wire VPPCD_EN, + output wire VDDRAB_EN, + output wire VTTAB_EN, + output wire VDDRCD_EN, + output wire VTTCD_EN, + output wire AVDD_EN, + output wire MISCIO_EN, + output wire ATX_EN, + + // Power Good inputs + input wire VDDA_PG, + input wire VDDB_PG, + input wire VCSA_PG, + input wire VCSB_PG, + input wire VDNA_PG, + input wire VDNB_PG, + input wire VIOA_PG, + input wire VIOB_PG, + input wire VPPAB_PG, + input wire VPPCD_PG, + input wire VDDRAB_PG, + input wire VDDRCD_PG, + input wire AVDD_PG, + input wire MISCIO_PG, + input wire ATX_PG, + input wire BMC_VR_PG, + + // I2C + inout wire SCL, + inout wire SDA, + + // Second CPU Present Detection + input wire CPUB_PRESENT_N, + output wire CPUB_CLK_OEA, + output wire CPUB_CLK_OEB, + + // Resets + output wire LPC_RST, + input wire BMC_SOFTWARE_PG, + output wire BMC_RST, + output wire FAN_RST, + output wire USBHUB_RST, + output wire CPU_STBY_RST, + + // Reserved for Future Use + output wire DUAL_5V_CTRL, + output wire WINDOW_OPEN_N + ); + + // FUTURE update version + parameter cpld_version = 8'b00000110; + parameter rail_size = 15; + wire [rail_size - 1:0] EN_BUF = 1'b0; + wire [rail_size - 1:0] PG_BUF; + wire SYSGOOD_BUF; + wire CLK_IN; + wire stdby_sed; + wire SYSEN_BUF; + parameter railarray_0 = 1'b0; + parameter railarray_1 = 1'b1; // synchronizing signals + reg [rail_size - 1:0] PG_S1 = 1'b0; + reg [rail_size - 1:0] PG_S2 = 1'b0; + reg SYSEN_S1 = 1'b0; + reg SYSEN_S2 = 1'b0; + reg SEQ_S1 = 1'b1; + reg SEQ_S2 = 1'b1; // Timer (Watchdog and Delay) signals + reg [rail_size - 1:0] DELAY_DONE = 1'b0; + reg [23:0] W_COUNT = 1'b0; + reg [16:0] D_COUNT = 1'b0; // at 4.16MHz, W_COUNT(23) being one means approximately 100ms have passed, good for checking watchdog between EN and PG + // D_COUNT(16) being one means approximately 15ms have passed, good enough for delay betwen One rail and the next + reg WAIT_ERR = 1'b0; + reg OPERATION_ERR = 1'b0; + reg ERR_FOUND = 1'b0; // signal FIRST_DELAY : STD_LOGIC := '1'; + wire CLEAR_ERR = 1'b0; //i2c signals + wire i2c_read_req; + reg [7:0] i2c_data_to_master = 8'b00000000; + wire [7:0] i2c_data_from_master; + wire i2c_data_valid; + wire i2c_rst = 1'b0; + reg [7:0] i2c_reg_cur = 8'b00000000; + parameter i2c_addr = 7'b0110001; + parameter i2c_clr_err_addr = 8'b00000011; + parameter i2c_pg_reg_addr1 = 8'b00000101; + parameter i2c_pg_reg_addr2 = i2c_pg_reg_addr1 + 1; + parameter i2c_status_reg_addr = i2c_pg_reg_addr2 + 1; + parameter i2c_version_reg_addr = 8'b00000000; + reg [15:0] i2c_pg_reg = 1'b0; + reg i2c_clr_err = 1'b0; + + OSCH OSC1( + .STDBY(1'b0), + .OSC(CLK_IN), + .SEDSTDBY(stdby_sed) + ); + + //debug + //CLEAR_ERR <= DUAL_5V_CTRL; + //Divide input 33MHz clock down to 4.125MHz + // process (CLK_IN) + // begin + // if (rising_edge(CLK_IN)) then + // CLK_REG <= CLK_REG + 1; + // end if; + // end process; + // CLK_DIV <= STD_LOGIC(CLK_REG(2)); + // Power Sequencer Instance + // SEQ1: entity work.pwrseq + // generic map(rail_size) + // port map( + // EN => EN_BUF, + // PGOOD_A => PG_BUF, + // SYSEN_A => SYSEN_BUF, + // SYSGOOD => SYSGOOD_BUF, + // SCL => SCL, + // SDA => SDA, + // CLK_IN => CLK_DIV + // CLK_IN => CLK_IN + // ); + //I2C device + I2C_slave #( + i2c_addr) + I2C_SLAVE( + SCL, + SDA, + CLK_IN, + i2c_rst, + i2c_read_req, + i2c_data_to_master, + i2c_data_valid, + i2c_data_from_master); + + assign i2c_rst = 1'b0; + //Handle I2C + //2 8-bit registers with PGOOD state on error + always @(posedge CLK_IN) begin + i2c_clr_err <= 1'b0; + + if (i2c_data_valid == 1'b1) begin + // data from master is register to be read + i2c_reg_cur <= i2c_data_from_master; + + //pulse clear err signal if i2c master reads register 0x03 + if (((i2c_data_from_master) == i2c_clr_err_addr)) begin + i2c_clr_err <= 1'b1; + end + end + else if (i2c_read_req == 1'b1) begin + i2c_reg_cur <= i2c_reg_cur + 1; + end + case(i2c_reg_cur) + i2c_clr_err_addr : begin + i2c_data_to_master <= 8'b11111111; + end + i2c_pg_reg_addr1 : begin + i2c_data_to_master <= i2c_pg_reg[15:8]; + end + i2c_pg_reg_addr2 : begin + i2c_data_to_master <= i2c_pg_reg[7:0]; + end + i2c_status_reg_addr : begin + //FUTURE add CPU1 Present detect + i2c_data_to_master <= {3'b000,WAIT_ERR,OPERATION_ERR,ERR_FOUND,SYSEN_BUF,SYSGOOD_BUF}; + end + i2c_version_reg_addr : begin + i2c_data_to_master <= cpld_version; + end + default : begin + i2c_data_to_master <= 8'b00000000; + end + endcase + end + + always @(posedge CLK_IN) begin + PG_S1 <= PG_BUF; + PG_S2 <= PG_S1; + SYSEN_S1 <= SYSEN_BUF; + SYSEN_S2 <= SYSEN_S1; + SEQ_S1 <= SEQ_CONT; + SEQ_S2 <= SEQ_S1; + if ((CLEAR_ERR == 1'b1)) begin + WAIT_ERR <= 1'b0; + OPERATION_ERR <= 1'b0; + ERR_FOUND <= 1'b0; + W_COUNT <= {24{1'b0}}; + D_COUNT <= {17{1'b0}}; + end + else if ((SYSEN_S2 == 1'b0 || ERR_FOUND == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= {17{1'b0}}; + DELAY_DONE <= {(((rail_size - 1))-((0))+1){1'b0}}; + end + else if ((PG_S2[0] == 1'b1 && EN_BUF[0] == 1'b1 && DELAY_DONE[0] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[0] <= 1'b1; + end + end + else if ((PG_S2[1] == 1'b1 && EN_BUF[1] == 1'b1 && DELAY_DONE[1] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[1] <= 1'b1; + end + end + else if ((PG_S2[2] == 1'b1 && EN_BUF[2] == 1'b1 && DELAY_DONE[2] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[2] <= 1'b1; + end + end + else if ((PG_S2[3] == 1'b1 && EN_BUF[3] == 1'b1 && DELAY_DONE[3] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[3] <= 1'b1; + end + end + else if ((PG_S2[4] == 1'b1 && EN_BUF[4] == 1'b1 && DELAY_DONE[4] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[4] <= 1'b1; + end + end + else if ((PG_S2[5] == 1'b1 && EN_BUF[5] == 1'b1 && DELAY_DONE[5] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[5] <= 1'b1; + end + end + else if ((PG_S2[6] == 1'b1 && EN_BUF[6] == 1'b1 && DELAY_DONE[6] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[6] <= 1'b1; + end + end + else if ((PG_S2[7] == 1'b1 && EN_BUF[7] == 1'b1 && DELAY_DONE[7] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[7] <= 1'b1; + end + end + else if ((PG_S2[8] == 1'b1 && EN_BUF[8] == 1'b1 && DELAY_DONE[8] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[8] <= 1'b1; + end + end + else if ((PG_S2[9] == 1'b1 && EN_BUF[9] == 1'b1 && DELAY_DONE[9] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[9] <= 1'b1; + end + end + else if ((PG_S2[10] == 1'b1 && EN_BUF[10] == 1'b1 && DELAY_DONE[10] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[10] <= 1'b1; + end + end + else if ((PG_S2[11] == 1'b1 && EN_BUF[11] == 1'b1 && DELAY_DONE[11] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[11] <= 1'b1; + end + end + else if ((PG_S2[12] == 1'b1 && EN_BUF[12] == 1'b1 && DELAY_DONE[12] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[12] <= 1'b1; + end + end + else if ((PG_S2[13] == 1'b1 && EN_BUF[13] == 1'b1 && DELAY_DONE[13] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[13] <= 1'b1; + end + end + else if ((PG_S2[14] == 1'b1 && EN_BUF[14] == 1'b1 && DELAY_DONE[14] == 1'b0)) begin + W_COUNT <= {24{1'b0}}; + D_COUNT <= D_COUNT + 1; + if ((D_COUNT[16] == 1'b1)) begin + D_COUNT <= {17{1'b0}}; + DELAY_DONE[14] <= 1'b1; + end + end + + // Error Checks + // Check time between Enables going high and PGOODs arriving. Error out after 100ms + else if ((PG_S2[0] == 1'b0 && EN_BUF[0] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[1] == 1'b0 && EN_BUF[1] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[2] == 1'b0 && EN_BUF[2] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[3] == 1'b0 && EN_BUF[3] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[4] == 1'b0 && EN_BUF[4] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[5] == 1'b0 && EN_BUF[5] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[6] == 1'b0 && EN_BUF[6] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[7] == 1'b0 && EN_BUF[7] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[8] == 1'b0 && EN_BUF[8] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[9] == 1'b0 && EN_BUF[9] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[10] == 1'b0 && EN_BUF[10] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[11] == 1'b0 && EN_BUF[11] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[12] == 1'b0 && EN_BUF[12] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[13] == 1'b0 && EN_BUF[13] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + else if ((PG_S2[14] == 1'b0 && EN_BUF[14] == 1'b1)) begin + W_COUNT <= W_COUNT + 1; + if ((W_COUNT[23] == 1'b1)) begin + W_COUNT <= {24{1'b0}}; + WAIT_ERR <= 1'b1; + end + end + if ((( ~(DELAY_DONE & ~PG_S2)) != railarray_1)) begin + OPERATION_ERR <= 1'b1; + end + if (((WAIT_ERR | OPERATION_ERR) == 1'b1 && CLEAR_ERR == 1'b0)) begin + ERR_FOUND <= 1'b1; + end else begin + i2c_pg_reg[14:0] <= PG_S2[14:0]; + end + end + + // Assign Ports to Enables + assign ATX_EN = ~EN_BUF[0]; + assign MISCIO_EN = EN_BUF[1]; + assign VDNA_EN = EN_BUF[2]; + assign VDNB_EN = EN_BUF[3] & ~CPUB_PRESENT_N; + assign AVDD_EN = EN_BUF[4]; + assign VIOA_EN = EN_BUF[5]; + assign VIOB_EN = EN_BUF[6] & ~CPUB_PRESENT_N; + assign VDDA_EN = EN_BUF[7]; + assign VDDB_EN = EN_BUF[8] & ~CPUB_PRESENT_N; + assign VCSA_EN = EN_BUF[9]; + assign VCSB_EN = EN_BUF[10] & ~CPUB_PRESENT_N; + assign VPPAB_EN = EN_BUF[11]; + assign VPPCD_EN = EN_BUF[12] & ~CPUB_PRESENT_N; + assign VDDRAB_EN = EN_BUF[13]; + assign VTTAB_EN = EN_BUF[13]; + assign VDDRCD_EN = EN_BUF[14] & ~CPUB_PRESENT_N; + assign VTTCD_EN = EN_BUF[14] & ~CPUB_PRESENT_N; + + // Assign Ports to PGood buffer + assign PG_BUF[0] = ATX_PG; + assign PG_BUF[1] = MISCIO_PG; + assign PG_BUF[2] = VDNA_PG; + assign PG_BUF[3] = VDNB_PG | (CPUB_PRESENT_N & EN_BUF[3]); + assign PG_BUF[4] = AVDD_PG; + assign PG_BUF[5] = VIOA_PG; + assign PG_BUF[6] = VIOB_PG | (CPUB_PRESENT_N & EN_BUF[6]); + assign PG_BUF[7] = VDDA_PG; + assign PG_BUF[8] = VDDB_PG | (CPUB_PRESENT_N & EN_BUF[8]); + assign PG_BUF[9] = VCSA_PG; + assign PG_BUF[10] = VCSB_PG | (CPUB_PRESENT_N & EN_BUF[10]); + assign PG_BUF[11] = VPPAB_PG; + assign PG_BUF[12] = VPPCD_PG | (CPUB_PRESENT_N & EN_BUF[12]); + assign PG_BUF[13] = VDDRAB_PG; + assign PG_BUF[14] = VDDRCD_PG | (CPUB_PRESENT_N & EN_BUF[14]); + + // Enable outputs + // Shut everything off if ann error has occurred + // Otherwise, if system enable is up, then enable short delay is done after previous rail + // Otherwise, disable after next rail goes down + assign EN_BUF[0] = (SYSEN_S2 | PG_S2[1]) & ~ERR_FOUND; + assign EN_BUF[1] = ((SYSEN_S2 & DELAY_DONE[0]) | PG_S2[2]) & ~ERR_FOUND; + assign EN_BUF[2] = ((SYSEN_S2 & DELAY_DONE[1]) | PG_S2[3]) & ~ERR_FOUND; + assign EN_BUF[3] = ((SYSEN_S2 & DELAY_DONE[2]) | PG_S2[4]) & ~ERR_FOUND; + assign EN_BUF[4] = ((SYSEN_S2 & DELAY_DONE[ + 1]) | PG_S2[ + 1]) & ~ERR_FOUND; + assign EN_BUF[5] = ((SYSEN_S2 & DELAY_DONE[4]) | PG_S2[6]) & ~ERR_FOUND; + assign EN_BUF[6] = ((SYSEN_S2 & DELAY_DONE[5]) | PG_S2[7]) & ~ERR_FOUND; + assign EN_BUF[7] = ((SYSEN_S2 & DELAY_DONE[6]) | PG_S2[8]) & ~ERR_FOUND; + assign EN_BUF[8] = ((SYSEN_S2 & DELAY_DONE[7]) | PG_S2[9]) & ~ERR_FOUND; + assign EN_BUF[9] = (( ~SEQ_S2 & SYSEN_S2 & DELAY_DONE[8]) | PG_S2[10]) & ~ERR_FOUND; + assign EN_BUF[10] = ((SYSEN_S2 & DELAY_DONE[9]) | PG_S2[11]) & ~ERR_FOUND; + assign EN_BUF[11] = ((SYSEN_S2 & DELAY_DONE[10]) | PG_S2[12]) & ~ERR_FOUND; + assign EN_BUF[12] = ((SYSEN_S2 & DELAY_DONE[11]) | PG_S2[13]) & ~ERR_FOUND; + assign EN_BUF[13] = ((SYSEN_S2 & DELAY_DONE[12]) | PG_S2[14]) & ~ERR_FOUND; + assign EN_BUF[14] = (SYSEN_S2 & DELAY_DONE[13]) & ~ERR_FOUND; + + //ERR state reset + assign CLEAR_ERR = i2c_clr_err; + + // CPUB clk enables + assign CPUB_CLK_OEA = ~CPUB_PRESENT_N; + assign CPUB_CLK_OEB = ~CPUB_PRESENT_N; + + // System PWRGOOD + assign SYSGOOD_BUF = DELAY_DONE[14]; + assign SYSGOOD = SYSGOOD_BUF & BMC_SOFTWARE_PG; + assign LPC_RST = SYSGOOD_BUF; + + // CPU Reset + assign CPU_STBY_RST = EN_BUF[0]; + + // BMC RESETs + assign BMC_RST = BMC_VR_PG; + assign USBHUB_RST = SYSGOOD_BUF & BMC_SOFTWARE_PG; + assign FAN_RST = ~BMC_VR_PG; + + // DEBUG_IN override allows non-BMC control of CPLD + assign SYSEN_BUF = SYSEN | ~DEBUG_IN; + // assign SYSEN_BUF = ~DEBUG_IN; + +endmodule \ No newline at end of file diff --git a/top.vhd b/top.vhd deleted file mode 100644 index 6f70ea0..0000000 --- a/top.vhd +++ /dev/null @@ -1,555 +0,0 @@ -library IEEE; -use IEEE.numeric_std.ALL; -use IEEE.STD_LOGIC_1164.ALL; -library machxo2; -use machxo2.all; - -entity FPGA_TOP is - Port ( SYSEN : in STD_LOGIC; - SYSGOOD: out STD_LOGIC := '0'; - DEBUG_IN: in STD_LOGIC; - - --DD1 temp fix for VCS overcurrent bug - SEQ_CONT: in STD_LOGIC; - - - --Enable outputs - VDDA_EN: out STD_LOGIC := '0'; - VDDB_EN: out STD_LOGIC := '0'; - VCSA_EN: out STD_LOGIC := '0'; - VCSB_EN: out STD_LOGIC := '0'; - VDNA_EN: out STD_LOGIC := '0'; - VDNB_EN: out STD_LOGIC := '0'; - VIOA_EN: out STD_LOGIC := '0'; - VIOB_EN: out STD_LOGIC := '0'; - VPPAB_EN: out STD_LOGIC := '0'; - VPPCD_EN: out STD_LOGIC := '0'; - VDDRAB_EN: out STD_LOGIC := '0'; - VTTAB_EN: out STD_LOGIC := '0'; - VDDRCD_EN: out STD_LOGIC := '0'; - VTTCD_EN: out STD_LOGIC := '0'; - AVDD_EN: out STD_LOGIC := '0'; - MISCIO_EN: out STD_LOGIC := '0'; - ATX_EN: out STD_LOGIC := '1'; - - --Power Good inputs - VDDA_PG: in STD_LOGIC; - VDDB_PG: in STD_LOGIC; - VCSA_PG: in STD_LOGIC; - VCSB_PG: in STD_LOGIC; - VDNA_PG: in STD_LOGIC; - VDNB_PG: in STD_LOGIC; - VIOA_PG: in STD_LOGIC; - VIOB_PG: in STD_LOGIC; - VPPAB_PG: in STD_LOGIC; - VPPCD_PG: in STD_LOGIC; - VDDRAB_PG: in STD_LOGIC; - VDDRCD_PG: in STD_LOGIC; - AVDD_PG: in STD_LOGIC; - MISCIO_PG: in STD_LOGIC; - ATX_PG: in STD_LOGIC; - BMC_VR_PG: in STD_LOGIC; - - --i2c - SCL: inout STD_LOGIC; - SDA: inout STD_LOGIC; - - --CLK_IN: in STD_LOGIC; - - --Second CPU Present Detection - CPUB_PRESENT_N: in STD_LOGIC; - CPUB_CLK_OEA: out STD_LOGIC; - CPUB_CLK_OEB: out STD_LOGIC; - - -- Resets - LPC_RST: out STD_LOGIC := '0'; - BMC_SOFTWARE_PG: in STD_LOGIC; - BMC_RST: out STD_LOGIC := '0'; - FAN_RST: out STD_LOGIC := '0'; - USBHUB_RST: out STD_LOGIC := '0'; - CPU_STBY_RST: out STD_LOGIC := '0'; - - -- Reserved for Future Use - DUAL_5V_CTRL: out STD_LOGIC := '0'; - --DUAL_5V_CTRL: in STD_LOGIC; - WINDOW_OPEN_N: out STD_LOGIC := '0' - ); - - -end FPGA_TOP; - -architecture Behavioral of FPGA_TOP is - --FUTURE update version - constant cpld_version : STD_LOGIC_VECTOR (7 downto 0) := "00000101"; - constant rail_size : integer := 15; - signal EN_BUF : STD_LOGIC_VECTOR(rail_size-1 downto 0) := (others => '0'); - signal PG_BUF : STD_LOGIC_VECTOR(rail_size-1 downto 0); - signal SYSGOOD_BUF : STD_LOGIC; --- signal CLK_DIV : STD_LOGIC; --- signal CLK_REG : UNSIGNED(2 downto 0) := "000"; - signal CLK_IN: STD_LOGIC; - signal stdby_sed: STD_LOGIC; - signal SYSEN_BUF: STD_LOGIC; --- signal DEBUG_BUF: STD_LOGIC; - constant railarray_0 : STD_LOGIC_VECTOR(rail_size-1 downto 0) := (others =>'0'); - constant railarray_1 : STD_LOGIC_VECTOR(rail_size-1 downto 0) := (others =>'1'); - - -- synchronizing signals - signal PG_S1 : STD_LOGIC_VECTOR(rail_size-1 downto 0) := (others => '0'); - signal PG_S2 : STD_LOGIC_VECTOR(rail_size-1 downto 0) := (others => '0'); - signal SYSEN_S1: STD_LOGIC := '0'; - signal SYSEN_S2: STD_LOGIC := '0'; - signal SEQ_S1: STD_LOGIC := '1'; - signal SEQ_S2: STD_LOGIC := '1'; - - -- Timer (Watchdog and Delay) signals - signal DELAY_DONE : STD_LOGIC_VECTOR(rail_size-1 downto 0) := (others => '0'); - signal W_COUNT : UNSIGNED(23 downto 0) := (others=> '0'); - signal D_COUNT : UNSIGNED(16 downto 0) := (others=> '0'); - -- at 4.16MHz, W_COUNT(23) being one means approximately 100ms have passed, good for checking watchdog between EN and PG - -- D_COUNT(16) being one means approximately 15ms have passed, good enough for delay betwen One rail and the next - signal WAIT_ERR : STD_LOGIC := '0'; - signal OPERATION_ERR : STD_LOGIC := '0'; - signal ERR_FOUND :STD_LOGIC := '0'; --- signal FIRST_DELAY : STD_LOGIC := '1'; - signal CLEAR_ERR : STD_LOGIC := '0'; - - --i2c signals - signal i2c_read_req : STD_LOGIC; - signal i2c_data_to_master : STD_LOGIC_VECTOR(7 downto 0) := "00000000"; - signal i2c_data_from_master : STD_LOGIC_VECTOR(7 downto 0); - signal i2c_data_valid : STD_LOGIC; - signal i2c_rst : STD_LOGIC := '0'; - signal i2c_reg_cur : UNSIGNED(7 downto 0) := "00000000"; - constant i2c_addr : STD_LOGIC_VECTOR (6 downto 0) := "0110001"; - constant i2c_clr_err_addr : UNSIGNED (7 downto 0) := "00000011"; - constant i2c_pg_reg_addr1 : UNSIGNED (7 downto 0) := "00000101"; - constant i2c_pg_reg_addr2 : UNSIGNED (7 downto 0) := i2c_pg_reg_addr1 + 1; - constant i2c_status_reg_addr : UNSIGNED (7 downto 0) := i2c_pg_reg_addr2 + 1; - constant i2c_version_reg_addr: UNSIGNED (7 downto 0) := "00000000"; - signal i2c_pg_reg : STD_LOGIC_VECTOR(15 downto 0) := (others=>'0'); - signal i2c_clr_err : STD_LOGIC := '0'; - - component OSCH - -- synthesis translate_off - generic (NOM_FREQ: string := "4.16"); - -- synthesis translate_on - PORT ( STDBY : in STD_LOGIC; - OSC: out STD_LOGIC; - SEDSTDBY: out STD_LOGIC); - end component; - attribute NOM_FREQ : string; - attribute NOM_FREQ of OSC1 : label is "4.16"; - - - -begin - OSC1: OSCH - -- synthesis translate_off - generic map( NOM_FREQ => "4.16") - -- synthesis translate_on - port map ( STDBY => '0', OSC=>CLK_IN, SEDSTDBY => stdby_sed); - - --debug - --CLEAR_ERR <= DUAL_5V_CTRL; - - --Divide input 33MHz clock down to 4.125MHz --- process (CLK_IN) --- begin --- if (rising_edge(CLK_IN)) then --- CLK_REG <= CLK_REG + 1; --- end if; --- end process; --- CLK_DIV <= STD_LOGIC(CLK_REG(2)); - - -- Power Sequencer Instance --- SEQ1: entity work.pwrseq - -- generic map(rail_size) - -- port map( - -- EN => EN_BUF, - -- PGOOD_A => PG_BUF, - -- SYSEN_A => SYSEN_BUF, - -- SYSGOOD => SYSGOOD_BUF, - -- SCL => SCL, - -- SDA => SDA, - -- CLK_IN => CLK_DIV - -- CLK_IN => CLK_IN - -- ); - - --I2C device -I2C_SLAVE: entity work.I2C_slave generic map(i2c_addr) port map( - SCL, SDA, CLK_IN, i2c_rst, - i2c_read_req,i2c_data_to_master, - i2c_data_valid,i2c_data_from_master); - - i2c_rst <= '0'; - ---Handle I2C - --2 8-bit registers with PGOOD state on error - process (CLK_IN) - begin - if (rising_edge(CLK_IN)) then - i2c_clr_err <= '0'; - if i2c_data_valid = '1' then - -- data from master is register to be read - i2c_reg_cur <= unsigned(i2c_data_from_master); - - --pulse clear err signal if i2c master reads register 0x03 - if(unsigned(i2c_data_from_master) = i2c_clr_err_addr) then - i2c_clr_err <= '1'; - end if; - elsif i2c_read_req = '1' then - i2c_reg_cur <= i2c_reg_cur + 1; - end if; - - case i2c_reg_cur is - when i2c_clr_err_addr => - i2c_data_to_master <= "11111111"; - when i2c_pg_reg_addr1 => - i2c_data_to_master <= i2c_pg_reg(15 downto 8); - when i2c_pg_reg_addr2 => - i2c_data_to_master <= i2c_pg_reg(7 downto 0); - when i2c_status_reg_addr => - --FUTURE add CPU1 Present detect - i2c_data_to_master <= "000" & WAIT_ERR & OPERATION_ERR & ERR_FOUND & SYSEN_BUF & SYSGOOD_BUF; - when i2c_version_reg_addr => - i2c_data_to_master <= cpld_version; - when others => - i2c_data_to_master <= "00000000"; - end case; - end if; - end process; - - process (CLK_IN) - begin - if (rising_edge(CLK_IN)) then - PG_S1 <= PG_BUF; - PG_S2 <= PG_S1; - SYSEN_S1 <= SYSEN_BUF; - SYSEN_S2 <= SYSEN_S1; - SEQ_S1 <= SEQ_CONT; - SEQ_S2 <= SEQ_S1; - if(CLEAR_ERR = '1') then - WAIT_ERR <= '0'; - OPERATION_ERR <= '0'; - ERR_FOUND <= '0'; - W_COUNT <= (others => '0'); - D_COUNT <= (others => '0'); - elsif(SYSEN_S2 = '0' or ERR_FOUND = '1') then - W_COUNT <= (others => '0'); - D_COUNT <= (others => '0'); - DELAY_DONE <= (others => '0'); - elsif (PG_S2(0) = '1' and EN_BUF(0) = '1' and DELAY_DONE(0) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(0) <= '1'; - end if; - elsif (PG_S2(1) = '1' and EN_BUF(1) = '1' and DELAY_DONE(1) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(1) <= '1'; - end if; - elsif (PG_S2(2) = '1' and EN_BUF(2) = '1' and DELAY_DONE(2) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(2) <= '1'; - end if; - elsif (PG_S2(3) = '1' and EN_BUF(3) = '1' and DELAY_DONE(3) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(3) <= '1'; - end if; - elsif (PG_S2(4) = '1' and EN_BUF(4) = '1' and DELAY_DONE(4) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(4) <= '1'; - end if; - elsif (PG_S2(5) = '1' and EN_BUF(5) = '1' and DELAY_DONE(5) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(5) <= '1'; - end if; - elsif (PG_S2(6) = '1' and EN_BUF(6) = '1' and DELAY_DONE(6) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(6) <= '1'; - end if; - elsif (PG_S2(7) = '1' and EN_BUF(7) = '1' and DELAY_DONE(7) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(7) <= '1'; - end if; - elsif (PG_S2(8) = '1' and EN_BUF(8) = '1' and DELAY_DONE(8) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(8) <= '1'; - end if; - elsif (PG_S2(9) = '1' and EN_BUF(9) = '1' and DELAY_DONE(9) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(9) <= '1'; - end if; - elsif (PG_S2(10) = '1' and EN_BUF(10) = '1' and DELAY_DONE(10) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(10) <= '1'; - end if; - elsif (PG_S2(11) = '1' and EN_BUF(11) = '1' and DELAY_DONE(11) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(11) <= '1'; - end if; - elsif (PG_S2(12) = '1' and EN_BUF(12) = '1' and DELAY_DONE(12) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(12) <= '1'; - end if; - elsif (PG_S2(13) = '1' and EN_BUF(13) = '1' and DELAY_DONE(13) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(13) <= '1'; - end if; - elsif (PG_S2(14) = '1' and EN_BUF(14) = '1' and DELAY_DONE(14) = '0') then - W_COUNT <= (others => '0'); - D_COUNT <= D_COUNT+1; - if (D_COUNT(16) = '1') then - D_COUNT <= (others => '0'); - DELAY_DONE(14) <= '1'; - end if; - - -- Error Checks - -- Check time between Enables going high and PGOODs arriving. Error out after 100ms - elsif (PG_S2(0) = '0' and EN_BUF(0) = '1') then - - W_COUNT <= W_COUNT+1; - if (W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(1) = '0' and EN_BUF(1) = '1') then - - W_COUNT <= W_COUNT+1; - if (W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(2) = '0' and EN_BUF(2) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(3) = '0' and EN_BUF(3) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(4) = '0' and EN_BUF(4) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(5) = '0' and EN_BUF(5) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(6) = '0' and EN_BUF(6) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(7) = '0' and EN_BUF(7) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(8) = '0' and EN_BUF(8) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(9) = '0' and EN_BUF(9) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(10) = '0' and EN_BUF(10) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(11) = '0' and EN_BUF(11) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(12) = '0' and EN_BUF(12) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(13) = '0' and EN_BUF(13) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - elsif (PG_S2(14) = '0' and EN_BUF(14) = '1') then - - W_COUNT <= W_COUNT+1; - if ( W_COUNT(23) = '1') then - W_COUNT <= (others => '0'); - WAIT_ERR <= '1'; - end if; - end if; - - if(not (DELAY_DONE and not PG_S2) /= railarray_1) then - OPERATION_ERR <= '1'; - end if; - - if ((WAIT_ERR or OPERATION_ERR) = '1' and CLEAR_ERR = '0') then - ERR_FOUND <= '1'; - else - i2c_pg_reg(14 downto 0) <= PG_S2(14 downto 0); - end if; - end if; - end process; - - - --Assign Ports to Enables - ATX_EN <= not EN_BUF(0); - MISCIO_EN <= EN_BUF(1); - VDNA_EN <= EN_BUF(2); - VDNB_EN <= EN_BUF(3) and not CPUB_PRESENT_N; - AVDD_EN <= EN_BUF(4); - VIOA_EN <= EN_BUF(5); - VIOB_EN <= EN_BUF(6) and not CPUB_PRESENT_N; - VDDA_EN <= EN_BUF(7); - VDDB_EN <= EN_BUF(8) and not CPUB_PRESENT_N; - VCSA_EN <= EN_BUF(9); - VCSB_EN <= EN_BUF(10) and not CPUB_PRESENT_N; - VPPAB_EN <= EN_BUF(11); - VPPCD_EN <= EN_BUF(12) and not CPUB_PRESENT_N; - VDDRAB_EN <= EN_BUF(13); - VTTAB_EN <= EN_BUF(13); - VDDRCD_EN <= EN_BUF(14) and not CPUB_PRESENT_N; - VTTCD_EN <= EN_BUF(14) and not CPUB_PRESENT_N; - - -- Assign Ports to PGood buffer - PG_BUF(0) <= ATX_PG; - PG_BUF(1) <= MISCIO_PG; - PG_BUF(2) <= VDNA_PG; - PG_BUF(3) <= VDNB_PG or (CPUB_PRESENT_N and EN_BUF(3)); - PG_BUF(4) <= AVDD_PG; - PG_BUF(5) <= VIOA_PG; - PG_BUF(6) <= VIOB_PG or (CPUB_PRESENT_N and EN_BUF(6)); - PG_BUF(7) <= VDDA_PG; - PG_BUF(8) <= VDDB_PG or (CPUB_PRESENT_N and EN_BUF(8)); - PG_BUF(9) <= VCSA_PG; - PG_BUF(10) <= VCSB_PG or (CPUB_PRESENT_N and EN_BUF(10)); - PG_BUF(11) <= VPPAB_PG; - PG_BUF(12) <= VPPCD_PG or (CPUB_PRESENT_N and EN_BUF(12)); - PG_BUF(13) <= VDDRAB_PG; - PG_BUF(14) <= VDDRCD_PG or (CPUB_PRESENT_N and EN_BUF(14)); - - --Enable outputs - -- Shut everything off if ann error has occurred - -- Otherwise, if system enable is up, then enable short delay is done after previous rail - -- Otherwise, disable after next rail goes down - EN_BUF(0) <= (SYSEN_S2 or PG_S2(1)) and not ERR_FOUND; - EN_BUF(1) <= ((SYSEN_S2 and DELAY_DONE(0)) or PG_S2(2)) and not ERR_FOUND; - EN_BUF(2) <= ((SYSEN_S2 and DELAY_DONE(1)) or PG_S2(3)) and not ERR_FOUND; - EN_BUF(3) <= ((SYSEN_S2 and DELAY_DONE(2)) or PG_S2(4)) and not ERR_FOUND; - EN_BUF(4) <= ((SYSEN_S2 and DELAY_DONE(3)) or PG_S2(5)) and not ERR_FOUND; - EN_BUF(5) <= ((SYSEN_S2 and DELAY_DONE(4)) or PG_S2(6)) and not ERR_FOUND; - EN_BUF(6) <= ((SYSEN_S2 and DELAY_DONE(5)) or PG_S2(7)) and not ERR_FOUND; - EN_BUF(7) <= ((SYSEN_S2 and DELAY_DONE(6)) or PG_S2(8)) and not ERR_FOUND; - EN_BUF(8) <= ((SYSEN_S2 and DELAY_DONE(7)) or PG_S2(9)) and not ERR_FOUND; - EN_BUF(9) <= ((not SEQ_S2 and SYSEN_S2 and DELAY_DONE(8)) or PG_S2(10)) and not ERR_FOUND; - EN_BUF(10) <= ((SYSEN_S2 and DELAY_DONE(9)) or PG_S2(11)) and not ERR_FOUND; - EN_BUF(11) <= ((SYSEN_S2 and DELAY_DONE(10)) or PG_S2(12)) and not ERR_FOUND; - EN_BUF(12) <= ((SYSEN_S2 and DELAY_DONE(11)) or PG_S2(13)) and not ERR_FOUND; - EN_BUF(13) <= ((SYSEN_S2 and DELAY_DONE(12)) or PG_S2(14)) and not ERR_FOUND; - EN_BUF(14) <= (SYSEN_S2 and DELAY_DONE(13)) and not ERR_FOUND; - - --ERR state reset - CLEAR_ERR <= i2c_clr_err; - - - -- CPUB clk enables - CPUB_CLK_OEA <= not CPUB_PRESENT_N; - CPUB_CLK_OEB <= not CPUB_PRESENT_N; - - -- System PWRGOOD - SYSGOOD_BUF <= DELAY_DONE(14); - SYSGOOD <= SYSGOOD_BUF and BMC_SOFTWARE_PG; - LPC_RST <= SYSGOOD_BUF; - - -- CPU Reset - CPU_STBY_RST <= EN_BUF(0); - - -- BMC RESETs - BMC_RST <= BMC_VR_PG; - USBHUB_RST <= SYSGOOD_BUF and BMC_SOFTWARE_PG; - FAN_RST <= not BMC_VR_PG; - - -- DEBUG_IN override allows non-BMC control of CPLD - SYSEN_BUF <= SYSEN or not DEBUG_IN; - --SYSEN_BUF <= not DEBUG_IN; - - - - -end Behavioral; - diff --git a/txt_util.vhd b/txt_util.vhd deleted file mode 100644 index a4c9ee5..0000000 --- a/txt_util.vhd +++ /dev/null @@ -1,582 +0,0 @@ -library ieee; -use ieee.std_logic_1164.all; -use std.textio.all; - - -package txt_util is - - -- prints a message to the screen - procedure print(text: string); - - -- prints the message when active - -- useful for debug switches - procedure print(active: boolean; text: string); - - -- converts std_logic into a character - function chr(sl: std_logic) return character; - - -- converts std_logic into a string (1 to 1) - function str(sl: std_logic) return string; - - -- converts std_logic_vector into a string (binary base) - function str(slv: std_logic_vector) return string; - - -- converts boolean into a string - function str(b: boolean) return string; - - -- converts an integer into a single character - -- (can also be used for hex conversion and other bases) - function chr(int: integer) return character; - - -- converts integer into string using specified base - function str(int: integer; base: integer) return string; - - -- converts integer to string, using base 10 - function str(int: integer) return string; - - -- convert std_logic_vector into a string in hex format - function hstr(slv: std_logic_vector) return string; - - - -- functions to manipulate strings - ----------------------------------- - - -- convert a character to upper case - function to_upper(c: character) return character; - - -- convert a character to lower case - function to_lower(c: character) return character; - - -- convert a string to upper case - function to_upper(s: string) return string; - - -- convert a string to lower case - function to_lower(s: string) return string; - - - - -- functions to convert strings into other formats - -------------------------------------------------- - - -- converts a character into std_logic - function to_std_logic(c: character) return std_logic; - - -- converts a string into std_logic_vector - function to_std_logic_vector(s: string) return std_logic_vector; - - - - -- file I/O - ----------- - - -- read variable length string from input file - procedure str_read(file in_file: TEXT; - res_string: out string); - - -- print string to a file and start new line - procedure print(file out_file: TEXT; - new_string: in string); - - -- print character to a file and start new line - procedure print(file out_file: TEXT; - char: in character); - -end txt_util; - - - - -package body txt_util is - - - - - -- prints text to the screen - - procedure print(text: string) is - variable msg_line: line; - begin - write(msg_line, text); - writeline(output, msg_line); - end print; - - - - - -- prints text to the screen when active - - procedure print(active: boolean; text: string) is - begin - if active then - print(text); - end if; - end print; - - - -- converts std_logic into a character - - function chr(sl: std_logic) return character is - variable c: character; - begin - case sl is - when 'U' => c:= 'U'; - when 'X' => c:= 'X'; - when '0' => c:= '0'; - when '1' => c:= '1'; - when 'Z' => c:= 'Z'; - when 'W' => c:= 'W'; - when 'L' => c:= 'L'; - when 'H' => c:= 'H'; - when '-' => c:= '-'; - end case; - return c; - end chr; - - - - -- converts std_logic into a string (1 to 1) - - function str(sl: std_logic) return string is - variable s: string(1 to 1); - begin - s(1) := chr(sl); - return s; - end str; - - - - -- converts std_logic_vector into a string (binary base) - -- (this also takes care of the fact that the range of - -- a string is natural while a std_logic_vector may - -- have an integer range) - - function str(slv: std_logic_vector) return string is - variable result : string (1 to slv'length); - variable r : integer; - begin - r := 1; - for i in slv'range loop - result(r) := chr(slv(i)); - r := r + 1; - end loop; - return result; - end str; - - - function str(b: boolean) return string is - - begin - if b then - return "true"; - else - return "false"; - end if; - end str; - - - -- converts an integer into a character - -- for 0 to 9 the obvious mapping is used, higher - -- values are mapped to the characters A-Z - -- (this is usefull for systems with base > 10) - -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) - - function chr(int: integer) return character is - variable c: character; - begin - case int is - when 0 => c := '0'; - when 1 => c := '1'; - when 2 => c := '2'; - when 3 => c := '3'; - when 4 => c := '4'; - when 5 => c := '5'; - when 6 => c := '6'; - when 7 => c := '7'; - when 8 => c := '8'; - when 9 => c := '9'; - when 10 => c := 'A'; - when 11 => c := 'B'; - when 12 => c := 'C'; - when 13 => c := 'D'; - when 14 => c := 'E'; - when 15 => c := 'F'; - when 16 => c := 'G'; - when 17 => c := 'H'; - when 18 => c := 'I'; - when 19 => c := 'J'; - when 20 => c := 'K'; - when 21 => c := 'L'; - when 22 => c := 'M'; - when 23 => c := 'N'; - when 24 => c := 'O'; - when 25 => c := 'P'; - when 26 => c := 'Q'; - when 27 => c := 'R'; - when 28 => c := 'S'; - when 29 => c := 'T'; - when 30 => c := 'U'; - when 31 => c := 'V'; - when 32 => c := 'W'; - when 33 => c := 'X'; - when 34 => c := 'Y'; - when 35 => c := 'Z'; - when others => c := '?'; - end case; - return c; - end chr; - - - - -- convert integer to string using specified base - -- (adapted from Steve Vogwell's posting in comp.lang.vhdl) - - function str(int: integer; base: integer) return string is - - variable temp: string(1 to 10); - variable num: integer; - variable abs_int: integer; - variable len: integer := 1; - variable power: integer := 1; - - begin - - -- bug fix for negative numbers - abs_int := abs(int); - - num := abs_int; - - while num >= base loop -- Determine how many - len := len + 1; -- characters required - num := num / base; -- to represent the - end loop ; -- number. - - for i in len downto 1 loop -- Convert the number to - temp(i) := chr(abs_int/power mod base); -- a string starting - power := power * base; -- with the right hand - end loop ; -- side. - - -- return result and add sign if required - if int < 0 then - return '-'& temp(1 to len); - else - return temp(1 to len); - end if; - - end str; - - - -- convert integer to string, using base 10 - function str(int: integer) return string is - - begin - - return str(int, 10) ; - - end str; - - - - -- converts a std_logic_vector into a hex string. - function hstr(slv: std_logic_vector) return string is - variable hexlen: integer; - variable longslv : std_logic_vector(67 downto 0) := (others => '0'); - variable hex : string(1 to 16); - variable fourbit : std_logic_vector(3 downto 0); - begin - hexlen := (slv'left+1)/4; - if (slv'left+1) mod 4 /= 0 then - hexlen := hexlen + 1; - end if; - longslv(slv'left downto 0) := slv; - for i in (hexlen -1) downto 0 loop - fourbit := longslv(((i*4)+3) downto (i*4)); - case fourbit is - when "0000" => hex(hexlen -I) := '0'; - when "0001" => hex(hexlen -I) := '1'; - when "0010" => hex(hexlen -I) := '2'; - when "0011" => hex(hexlen -I) := '3'; - when "0100" => hex(hexlen -I) := '4'; - when "0101" => hex(hexlen -I) := '5'; - when "0110" => hex(hexlen -I) := '6'; - when "0111" => hex(hexlen -I) := '7'; - when "1000" => hex(hexlen -I) := '8'; - when "1001" => hex(hexlen -I) := '9'; - when "1010" => hex(hexlen -I) := 'A'; - when "1011" => hex(hexlen -I) := 'B'; - when "1100" => hex(hexlen -I) := 'C'; - when "1101" => hex(hexlen -I) := 'D'; - when "1110" => hex(hexlen -I) := 'E'; - when "1111" => hex(hexlen -I) := 'F'; - when "ZZZZ" => hex(hexlen -I) := 'z'; - when "UUUU" => hex(hexlen -I) := 'u'; - when "XXXX" => hex(hexlen -I) := 'x'; - when others => hex(hexlen -I) := '?'; - end case; - end loop; - return hex(1 to hexlen); - end hstr; - - - - -- functions to manipulate strings - ----------------------------------- - - - -- convert a character to upper case - - function to_upper(c: character) return character is - - variable u: character; - - begin - - case c is - when 'a' => u := 'A'; - when 'b' => u := 'B'; - when 'c' => u := 'C'; - when 'd' => u := 'D'; - when 'e' => u := 'E'; - when 'f' => u := 'F'; - when 'g' => u := 'G'; - when 'h' => u := 'H'; - when 'i' => u := 'I'; - when 'j' => u := 'J'; - when 'k' => u := 'K'; - when 'l' => u := 'L'; - when 'm' => u := 'M'; - when 'n' => u := 'N'; - when 'o' => u := 'O'; - when 'p' => u := 'P'; - when 'q' => u := 'Q'; - when 'r' => u := 'R'; - when 's' => u := 'S'; - when 't' => u := 'T'; - when 'u' => u := 'U'; - when 'v' => u := 'V'; - when 'w' => u := 'W'; - when 'x' => u := 'X'; - when 'y' => u := 'Y'; - when 'z' => u := 'Z'; - when others => u := c; - end case; - - return u; - - end to_upper; - - - -- convert a character to lower case - - function to_lower(c: character) return character is - - variable l: character; - - begin - - case c is - when 'A' => l := 'a'; - when 'B' => l := 'b'; - when 'C' => l := 'c'; - when 'D' => l := 'd'; - when 'E' => l := 'e'; - when 'F' => l := 'f'; - when 'G' => l := 'g'; - when 'H' => l := 'h'; - when 'I' => l := 'i'; - when 'J' => l := 'j'; - when 'K' => l := 'k'; - when 'L' => l := 'l'; - when 'M' => l := 'm'; - when 'N' => l := 'n'; - when 'O' => l := 'o'; - when 'P' => l := 'p'; - when 'Q' => l := 'q'; - when 'R' => l := 'r'; - when 'S' => l := 's'; - when 'T' => l := 't'; - when 'U' => l := 'u'; - when 'V' => l := 'v'; - when 'W' => l := 'w'; - when 'X' => l := 'x'; - when 'Y' => l := 'y'; - when 'Z' => l := 'z'; - when others => l := c; - end case; - - return l; - - end to_lower; - - - - -- convert a string to upper case - - function to_upper(s: string) return string is - - variable uppercase: string (s'range); - - begin - - for i in s'range loop - uppercase(i):= to_upper(s(i)); - end loop; - return uppercase; - - end to_upper; - - - - -- convert a string to lower case - - function to_lower(s: string) return string is - - variable lowercase: string (s'range); - - begin - - for i in s'range loop - lowercase(i):= to_lower(s(i)); - end loop; - return lowercase; - - end to_lower; - - - --- functions to convert strings into other types - - --- converts a character into a std_logic - -function to_std_logic(c: character) return std_logic is - variable sl: std_logic; - begin - case c is - when 'U' => - sl := 'U'; - when 'X' => - sl := 'X'; - when '0' => - sl := '0'; - when '1' => - sl := '1'; - when 'Z' => - sl := 'Z'; - when 'W' => - sl := 'W'; - when 'L' => - sl := 'L'; - when 'H' => - sl := 'H'; - when '-' => - sl := '-'; - when others => - sl := 'X'; - end case; - return sl; - end to_std_logic; - - --- converts a string into std_logic_vector - -function to_std_logic_vector(s: string) return std_logic_vector is - variable slv: std_logic_vector(s'high-s'low downto 0); - variable k: integer; -begin - k := s'high-s'low; - for i in s'range loop - slv(k) := to_std_logic(s(i)); - k := k - 1; - end loop; - return slv; -end to_std_logic_vector; - - - - - - ----------------- --- file I/O -- ----------------- - - - --- read variable length string from input file - -procedure str_read(file in_file: TEXT; - res_string: out string) is - - variable l: line; - variable c: character; - variable is_string: boolean; - - begin - - readline(in_file, l); - -- clear the contents of the result string - for i in res_string'range loop - res_string(i) := ' '; - end loop; - -- read all characters of the line, up to the length - -- of the results string - for i in res_string'range loop - read(l, c, is_string); - res_string(i) := c; - if not is_string then -- found end of line - exit; - end if; - end loop; - -end str_read; - - --- print string to a file -procedure print(file out_file: TEXT; - new_string: in string) is - - variable l: line; - - begin - - write(l, new_string); - writeline(out_file, l); - -end print; - - --- print character to a file and start new line -procedure print(file out_file: TEXT; - char: in character) is - - variable l: line; - - begin - - write(l, char); - writeline(out_file, l); - -end print; - - - --- appends contents of a string to a file until line feed occurs --- (LF is considered to be the end of the string) - -procedure str_write(file out_file: TEXT; - new_string: in string) is - begin - - for i in new_string'range loop - print(out_file, new_string(i)); - if new_string(i) = LF then -- end of string - exit; - end if; - end loop; - -end str_write; - - - - -end txt_util; \ No newline at end of file -- cgit v1.2.1