N
Niv
I have a chip with a power-on-reset (por) and a status input.
The first time the chip is powered, the chip internals are reset by
por.
However, a power "brown-out" that causes por to become active again,
but the chip stays active bexause its power rails stay up enough, must
only cause a chip reset if the status input is inactive. If the status
pin is active then the por should NOT generate an internal chip reset.
I've written a simple FSM that does this, but it relies on the FSM
starting up in s0, and not in any other state. Can this be guaranteed,
and for what chip vendors if any?
---------------------------------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.NUMERIC_STD.all;
ENTITY rst_lock IS
PORT(
-- Clock and asynchronous reset
--
clock : IN STD_LOGIC;
por_n : IN STD_LOGIC;
stat_n : IN STD_LOGIC;
chip_rst : OUT STD_LOGIC
);
END ENTITY rst_lock;
--
ARCHITECTURE rtl OF rst_lock IS
TYPE state_t IS (s0, s1, s2);
SIGNAL state : state_t;
SIGNAL next_state : state_t;
BEGIN
--------------------------------------------------------------------------------
clk_state : PROCESS(por_n, clock)
BEGIN
IF por_n = '0' THEN
IF (state = s0) OR (state = s1) THEN
state <= s0;
ELSIF (state = s2) THEN
state <= s2;
END IF;
ELSIF rising_edge(clock) THEN
state <= next_state;
END IF;
END PROCESS clk_state;
--------------------------------------------------------------------------------
assign_state : PROCESS(state, por_n, stat_n)
BEGIN
CASE state IS
WHEN s0 => IF por_n = '0' THEN -- stay in reset state
next_state <= s0;
ELSE
next_state <= s1;
END IF;
WHEN s1 => IF stat_n = '0' THEN -- Stay in passive state
next_state <= s2;
ELSE
next_state <= s1;
END IF;
WHEN s2 => IF stat_n = '0' THEN -- Stay in lockout state.
next_state <= s2;
ELSE -- (Could make this a 3
way split,
next_state <= s1; -- going to s0 if por_n =
0 AND
END IF; -- stat_n =
1).
WHEN OTHERS => next_state <= s2;
END CASE;
END PROCESS assign_state;
--------------------------------------------------------------------------------
assign_outputs : PROCESS(state)
BEGIN
CASE state IS
WHEN s0 => chip_rst <= '0';
WHEN s1 => chip_rst <= '1';
WHEN s2 => chip_rst <= '1';
WHEN OTHERS => chip_rst <= '1';
END CASE;
END PROCESS assign_outputs;
The first time the chip is powered, the chip internals are reset by
por.
However, a power "brown-out" that causes por to become active again,
but the chip stays active bexause its power rails stay up enough, must
only cause a chip reset if the status input is inactive. If the status
pin is active then the por should NOT generate an internal chip reset.
I've written a simple FSM that does this, but it relies on the FSM
starting up in s0, and not in any other state. Can this be guaranteed,
and for what chip vendors if any?
---------------------------------------------------------------------------------------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.NUMERIC_STD.all;
ENTITY rst_lock IS
PORT(
-- Clock and asynchronous reset
--
clock : IN STD_LOGIC;
por_n : IN STD_LOGIC;
stat_n : IN STD_LOGIC;
chip_rst : OUT STD_LOGIC
);
END ENTITY rst_lock;
--
ARCHITECTURE rtl OF rst_lock IS
TYPE state_t IS (s0, s1, s2);
SIGNAL state : state_t;
SIGNAL next_state : state_t;
BEGIN
--------------------------------------------------------------------------------
clk_state : PROCESS(por_n, clock)
BEGIN
IF por_n = '0' THEN
IF (state = s0) OR (state = s1) THEN
state <= s0;
ELSIF (state = s2) THEN
state <= s2;
END IF;
ELSIF rising_edge(clock) THEN
state <= next_state;
END IF;
END PROCESS clk_state;
--------------------------------------------------------------------------------
assign_state : PROCESS(state, por_n, stat_n)
BEGIN
CASE state IS
WHEN s0 => IF por_n = '0' THEN -- stay in reset state
next_state <= s0;
ELSE
next_state <= s1;
END IF;
WHEN s1 => IF stat_n = '0' THEN -- Stay in passive state
next_state <= s2;
ELSE
next_state <= s1;
END IF;
WHEN s2 => IF stat_n = '0' THEN -- Stay in lockout state.
next_state <= s2;
ELSE -- (Could make this a 3
way split,
next_state <= s1; -- going to s0 if por_n =
0 AND
END IF; -- stat_n =
1).
WHEN OTHERS => next_state <= s2;
END CASE;
END PROCESS assign_state;
--------------------------------------------------------------------------------
assign_outputs : PROCESS(state)
BEGIN
CASE state IS
WHEN s0 => chip_rst <= '0';
WHEN s1 => chip_rst <= '1';
WHEN s2 => chip_rst <= '1';
WHEN OTHERS => chip_rst <= '1';
END CASE;
END PROCESS assign_outputs;