library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity ctlr is port (clk, st, eq, lt : in std_logic; lc, s, clp, lp, up, en, c0, lr, lir : out std_logic; sel : out std_logic_vector(2 downto 0); opc : in std_logic_vector(3 downto 0)); end ctlr; architecture behav of ctlr is type state is (INIT, WT, F, F2, EX, SHOW, ADD, SUB, MPY, LDI, BRA, BRF); signal new_state : state; type mem is array (0 to 7) of std_logic_vector(11 downto 0); begin --state transition process process is variable current_state : state := INIT; begin if clk = '1' then case current_state is when INIT => if st = '1' then current_state := WT; end if; when WT => current_state := F; when F => current_state := F2; when F2 => current_state := EX; when EX => if opc = "0000" then current_state := SHOW; elsif opc = "0001" then current_state := ADD; elsif opc = "0010" then current_state := SUB; elsif opc = "0011" then current_state := MPY; elsif opc = "0100" then current_state := LDI; elsif (opc = "0101" and eq = '1') then current_state := BRA; elsif (opc = "0110" and lt = '1') then current_state := BRA; elsif (to_integer(opc) > 6) then current_state := INIT; else current_state := BRF; end if; when SHOW => if st = '1' then current_state := BRF; end if; when ADD|SUB|MPY|LDI|BRA|BRF => current_state := F; end case; new_state <= current_state; end if; wait on clk; end process; --asserted output list process is variable CM : mem; variable CM_idx : integer; variable CW : std_logic_vector (11 downto 0); begin -- CM contents CM(0) := "000010000000"; --SHOW: en CM(1) := "001001110010"; --ADD: up, lc, s, lr, sel = 010 CM(2) := "001001111011"; --SUB: up, lc, s, lr, c0, sel = 011 CM(3) := "001001110111"; --MPY: up, lc, s, lr, sel = 111 CM(4) := "001001010000"; --LDI: up, lc, lr, sel = 000 CM(5) := "010000000000"; --BEQ: lp, sel = 000 CM(6) := "010000000000"; --BLT: lp, sel = 000 case new_state is when INIT => CW := "000000000000"; --resetting control points when WT => CW := "100000000000"; --PC <- 0 when F => CW := "000000000000"; --resetting control points when F2 => CW := "000100000000"; --IR <- d0 when EX => CW := "000000000000"; --resetting control points --CM_idx := to_integer(opc); --CW := CM(CM_idx); when BRF => CW := "001000000000"; -- PC <- PC + 1 when SHOW => CW := CM(0); when ADD => CW := CM(1); when SUB => CW := CM(2); when MPY => CW := CM(3); when LDI => CW := CM(4); when BRA => CW := CM(5); --when SHOW|ADD|SUB|MPY|LDI|BRA => -- clp <= CW(11); -- lp <= CW(10); -- up <= CW(9); -- lir <= CW(8); -- en <= CW(7); -- lc <= CW(6); -- s <= CW(5); -- lr <= CW(4); -- c0 <= CW(3); -- sel <= CW(2 downto 0); end case; clp <= CW(11); lp <= CW(10); up <= CW(9); lir <= CW(8); en <= CW(7); lc <= CW(6); s <= CW(5); lr <= CW(4); c0 <= CW(3); sel <= CW(2 downto 0); wait on new_state; end process; end behav;