VHDL Reset
In most HW systems you need a way to do a system reset, but you obviously don’t want your reset line to miss fire and kill your system. Also, you don’t want to deal with multiple resets due to bouncing. And depending on your operating environment, you may need to protect your resets from SEI’s from radiation or whatever.
Below details a simple solution to debounce and enforce a minimum reset hold time in your code.
——
I use Generics in my entity so I can set the sys clk rate and the minimum width for the reset pulse easily:
entity rst_detect isgeneric(clk_rate_mhz : integer := 20000000;min_width_us : integer := 10000);port(clk : in std_logic;rst_in : in std_logic;rst_out : out std_logic);end entity
architecture rtl of por_detect is
– to get the minimum ticks for a valid por,
– find the ticks per 1MHz (or 1us) and then
– multiply by the min us value
constant MIN_TICKS : integer := integer(ceil(real((clk_rate_mhz/1000000)*min_width_us)));
– min bit width of the counter for to count to min_ticks
constant COUNTER_WID : integer := integer(ceil(log2(real(MIN_TICKS))));
constant MAX_COUNT : integer := integer((2**COUNTER_WID) – 1);
signal count : std_logic_vector(COUNTER_WID – 1 downto 0) := (others => ’0′);
–start and stop counter vals
signal s_count : std_logic_vector(COUNTER_WID – 1 downto 0);
type por_state_t is (POR_IDLE, POR_WAIT, POR_OUTPUT);
signal por_state : por_state_t := POR_IDLE;
begin
counter : process(clk) begin
if(rising_edge(clk)) then
count <= count + 1;
end if;
end process;
por_det : process(clk) begin
if(rising_edge(clk)) then
case por_state is
when POR_IDLE =>
por_out <= ’0′;
if(por_in = ’1′) then
s_count <= count;
por_state <= POR_WAIT;
else
por_state <= POR_IDLE;
end if;
when POR_WAIT =>
if(por_in = ’0′) then
por_state <= POR_IDLE;
else
if(count > s_count) then
if(count – s_count >= MIN_TICKS) then
por_out <= ’1′;
por_state <= POR_OUTPUT;
else
por_state <= POR_WAIT;
end if;
else
if((MAX_COUNT – s_count) + count >= MIN_TICKS) then
por_out <= ’1′;
por_state <= POR_OUTPUT;
else
por_state <= POR_WAIT;
end if;
end if;
end if;
when POR_OUTPUT =>
if(por_in = ’0′) then
por_out <= ’0′;
por_state <= POR_IDLE;
else
por_state <= POR_OUTPUT;
end if;
when others =>
por_out <= ’0′;
por_state <= POR_IDLE;
end case;
end if;
end process;end architecture rtl