diff --git a/doc/rtl_fsm_example.vhd b/doc/rtl_fsm_example.vhd new file mode 100644 index 0000000000000000000000000000000000000000..cc2b7bf8a7a75db5f64c84ef025d24d31794ea45 --- /dev/null +++ b/doc/rtl_fsm_example.vhd @@ -0,0 +1,93 @@ +LIBRARY IEEE; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; + +ENTITY fsm_example IS +GENERIC ( + g_nof_inputs : NATURAL := 6 +); +PORT ( + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; + -- Inputs + buf_busy : IN STD_LOGIC; + reg_record_all_rw : IN STD_LOGIC; + reg_record_enable_rw : IN STD_LOGIC; + reg_dump_enables_rw : IN STD_LOGIC_VECTOR(g_nof_inputs-1 DOWNTO 0); + -- Outputs + record_all : OUT STD_LOGIC; + record_enable : OUT STD_LOGIC; + dump_enables : OUT STD_LOGIC_VECTOR(g_nof_inputs-1 DOWNTO 0) +); +END fsm_example; + +ARCHITECTURE rtl OF fsm_example IS + + -- FSM states + TYPE t_fsm IS (s_idle, s_recording, s_dumping); + + -- RTL state registers + TYPE t_state IS RECORD + fsm : t_fsm; + -- other RTL state, not used in this example with only a FSM + END RECORD; + + CONSTANT c_state_rst : t_state := (fsm => s_idle); -- reset values + + SIGNAL q : t_state; -- stored state with latency one + SIGNAL d : t_state; -- zero latency state + +BEGIN + + -- p_state + q <= d WHEN rising_edge(dp_clk); + + p_comb : PROCESS(dp_rst, q, buf_busy, reg_record_all_rw, reg_record_enable_rw, reg_dump_enables_rw) + VARIABLE v : t_state; + BEGIN + -- Default + v := q; -- keep values + + -- Other RTL functionality + -- . not used in this example with only a FSM + + -- FSM + CASE q.fsm IS + WHEN s_idle => + record_all <= reg_record_all_rw; + record_enable <= '0'; + dump_enables <= (OTHERS => '0'); + IF reg_record_enable_rw = '1' AND buf_busy = '0' THEN + v.fsm := s_recording; + END IF; + IF UNSIGNED(reg_dump_enables_rw) > 0 AND buf_busy = '0' THEN + v.fsm := s_recording; + dump_enables <= reg_dump_enables_rw; + END IF; + WHEN s_recording => + IF reg_record_enable_rw = '1' THEN + record_enable <= '1'; + ELSE + v.fsm := s_idle; + record_enable <= '0'; + END IF; + WHEN s_dumping => + IF UNSIGNED(reg_dump_enables_rw) = 0 THEN + v.fsm := s_idle; + dump_enables <= (OTHERS => '0'); + END IF; + WHEN OTHERS => + -- try to recover from undefined FSM state + v.fsm := s_idle; + END CASE; + + -- Reset (synchronous) + IF dp_rst = '1' THEN + v := c_state_rst; + END IF; + + -- Result + d <= v; + END PROCESS; + +END rtl;