Forfun8

How to compile
ghdl -a forfun8.vhd

ghdl -e forfun8

ghdl -r forfun8 --wave=out.ghw

How to view waveforms
gtkwave out.vcd

How does it work & look like
This is a round-robin state machine that cycles through 3 states (check_a, check_b, check_c). In each check state it checks if the corresponding request is active (req_a, req_b, req_c) and when necessary, it branches to handle the request in the corresponding handling state (handle_a, handle_b, handle_c).

Specifically, if req_a is active while in check_a state, then the request is handled by branching to handle_a state. When handling is finished, the original checking cycle is resumed where it was interrupted.



forfun8.vhd
--- -- VHDL for fun 8 -- -- Round-robin state machine -- -- Copyright: Daniel Tisza, 2014, GPLv3 or later --- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;

-- Describe the I/O of this "chip" entity forfun8 is end forfun8;

-- Describe the contents of this "chip" architecture rtl of forfun8 is

-- State machine constants and signals type state_type is (		check_a, check_b, check_c,		handle_a, handle_b, handle_c	); signal state : state_type; -- Request inputs signal req_a : std_logic; signal req_b : std_logic; signal req_c : std_logic; -- Testbench signals signal finished : std_logic; signal clk : std_logic; signal reset : std_logic;

begin

---	-- State machine ---	stm_proc : process(reset,clk) begin if (reset='1') then -- Reset state state <= check_a; else -- Rising edge of the clock if rising_edge(clk) then -- Default actions state <= state; -- Decode state case state is					when check_a => -- Default is to continue checking next slot state <= check_b; if (req_a='1') then state <= handle_a; else end if; when check_b => -- Default is to continue checking next slot state <= check_c; if (req_b='1') then state <= handle_b; else end if; when check_c => -- Default is to continue checking next slot state <= check_a; if (req_c='1') then state <= handle_c; else end if; when handle_a => -- Continue checking following slot state <= check_b; when handle_b => -- Continue checking following slot state <= check_c; when handle_c => -- Continue checking following slot state <= check_a; end case; else end if; end if; end process; -- Test bench part

-- Generate reset pulse for global reset testbench_requests_proc : process begin req_a <= '0'; req_b <= '0'; req_c <= '0'; wait for 12 us; req_a <= '1'; wait for 1 us; req_c <= '1'; wait; end process;

-- Generate reset pulse for global reset testbench_reset_proc : process begin reset <= '1'; wait for 4.5 us; reset <= '0'; wait; end process;

-- Generate finished signal testbench_finish_proc : process begin -- Initial finished state finished <= '0'; -- Set finished after a delay wait for 50 us; finished <= '1'; -- Wait a while after finishing wait for 3 us; wait; end process; -- Generate clock signal testbench_clock_proc : process begin -- Initial clock signal state clk <= '0'; clockloop : loop -- Clock ticks wait for 1 us; clk <= not(clk); -- Exit loop when finished if (finished='1') then exit; else end if; end loop clockloop; wait; end process; end architecture;