library ieee; use ieee.std_logic_1164.all; entity controller is port( clk : in std_logic; reset_n : in std_logic; -- instruction opcode op : in std_logic_vector(5 downto 0); opx : in std_logic_vector(5 downto 0); -- activates branch condition branch_op : out std_logic; -- immediate value sign extention imm_signed : out std_logic; -- instruction register enable ir_en : out std_logic; -- PC control signals pc_add_imm : out std_logic; pc_en : out std_logic; pc_sel_a : out std_logic; pc_sel_imm : out std_logic; -- register file enable rf_wren : out std_logic; -- multiplexers selections sel_addr : out std_logic; sel_b : out std_logic; sel_mem : out std_logic; sel_pc : out std_logic; sel_ra : out std_logic; sel_rC : out std_logic; -- write memory output read : out std_logic; write : out std_logic; -- alu op op_alu : out std_logic_vector(5 downto 0) ); end controller; architecture synth of controller is type state is (FETCH1, FETCH2, DECODE, R_OP, STORE, BREAK, LOAD1, I_OP, LOAD2, BRANCH, CALL,CALLR, JMP, JMPI, UI_OP, RI_OP); signal s_cur : state; signal s_next : state; begin --FSM masuta controls fsm_ctrl : process(clk, reset_n) is begin if(reset_n = '0') then s_cur <= FETCH1; elsif(rising_edge(clk)) then s_cur <= s_next; end if; end process; --control states s_next <= FETCH2 when s_cur = FETCH1 else DECODE when s_cur = FETCH2 else BREAK when s_cur = BREAK else LOAD2 when s_cur = LOAD1 else FETCH1 when (s_cur = LOAD2 or s_cur = STORE or s_cur = R_OP or s_cur = I_OP or s_cur = RI_OP or s_cur = UI_OP or s_cur = BRANCH or s_cur = CALL or s_cur = CALLR or s_cur = JMP or s_cur = JMPI) else R_OP when (s_cur = DECODE and op = "111010" and (opx = "011011" or --srl opx = "110001" or --add opx = "111001" or --sub opx = "001000" or --cmple opx = "010000" or --cmpgt opx = "000110" or --nor opx = "001110" or --and opx = "010110" or --or opx = "011110" or --xnor opx = "010011" or --sll opx = "111011" or --sra opx = "011000" or --cmpne opx = "100000" or --cmpeq opx = "101000" or --cmpleu opx = "110000" or --cmpgtu opx = "000011" or --rol opx = "001011") --ror ) else I_OP when (s_cur = DECODE and (op = "000100" or --addi op = "001000" or --cmplei op = "010000" or --cmpgti op = "011000" or --cmpnei op = "100000") --cmpeqi ) else UI_OP when (s_cur = DECODE and (op = "001100" or --andi op = "010100" or --ori op = "011100" or --xnori op = "101000" or --cmpleui op = "110000") --cmpgtui ) else RI_OP when (s_cur = DECODE and op = "111010" and (opx = "010010" or --slli opx = "011010" or --srli opx = "111010" or --srai opx = "000010") --roli ) else LOAD1 when (s_cur = DECODE and op = "010111") else --ldw STORE when (s_cur = DECODE and op = "010101") else --stw BRANCH when (s_cur = DECODE and (op = "000110" or --br op = "001110" or --ble op = "010110" or --bgt op = "011110" or --bne op = "100110" or --beq op = "101110" or --bleu op = "110110") --bgtu ) else CALL when (s_cur = DECODE and op = "000000") else --call CALLR when (s_cur = DECODE and opx = "011101") else --callr JMP when (s_cur = DECODE and (opx = "001101" or --jmp opx = "000101") --ret ) else JMPI when (s_cur = DECODE and op = "000001") else --jmpi BREAK when (s_cur = DECODE and op = "111010" and opx = "110100"); --break --====== All state handlers =======-- pc_add_imm <= '1' when (s_cur = BRANCH) else '0'; pc_sel_a <= '1' when (s_cur = JMP or s_cur = CALLR) else'0'; pc_sel_imm <= '1' when (s_cur = CALL or s_cur = JMPI) else '0'; sel_pc <= '1' when (s_cur = CALL or s_cur = CALLR) else '0'; branch_op <= '1' when s_cur = BRANCH else '0'; pc_en <= '1' when (s_cur = FETCH2 or s_cur = CALL or s_cur = CALLR or s_cur = JMP or s_cur = JMPI) else '0'; read <= '1' when (s_cur = FETCH1 or s_cur = LOAD1) else '0'; write <= '1' when (s_cur = STORE) else '0'; ir_en <= '1' when (s_cur = FETCH2) else '0'; rf_wren <= '1' when (s_cur = R_OP or s_cur = RI_OP or s_cur = I_OP or s_cur = UI_OP or s_cur = CALL or s_cur = CALLR or s_cur = LOAD2) else '0'; sel_rC <= '1' when (s_cur = R_OP or s_cur = RI_OP or s_cur = CALLR) else '0'; sel_b <= '1' when (s_cur = R_OP or s_cur = BRANCH) else '0'; sel_ra <= '1' when (s_cur = CALL or s_cur = CALLR) else '0'; sel_addr <= '1' when (s_cur = LOAD1 or s_cur = STORE) else '0'; sel_mem <= '1' when s_cur = LOAD2 else '0'; imm_signed <= '1' when (s_cur = I_OP or s_cur = LOAD1 or s_cur = STORE) else '0'; -- Alu state op_alu <= "000000" when (op = "000100" or --addi op = "010111" or --ldw op = "010101" --stw ) else --rA + (signed)imm "000110" when (op = "111010" and opx = "110001" --add ) else --rA + rB "001111" when (op = "111010" and opx = "111001" --sub ) else --rA - rB "100001" when (op = "111010" and opx = "001110" --and ) else --rA & rB "100001" when (op = "001100" --andi ) else --rA & (unsigned)imm "100010" when (op = "111010" and opx = "010110" --or ) else --rA | rB "101010" when (op = "010100" --ori ) else --rA | (unsigned)imm "100011" when (op = "111010" and opx = "011110" --xnor ) else --rA xnor rB "100011" when (op = "011100" --xnori ) else --rA xnor (unsigned)imm "100000" when (op = "111010" and opx = "000110" --nor ) else --rA nor rB "111011" when (op = "111010" and opx = "011010" --srli ) else --(unsigned)rA >> imm "110011" when (op = "111010" and opx = "011011" --srl ) else --(unsigned)rA >> rB "111010" when (op = "111010" and opx = "010010" --slli ) else --(unsigned)rA << imm "110010" when (op = "111010" and opx = "010011" --sll ) else --(unsigned)rA << rB "111111" when (op = "111010" and opx = "111010" --srai ) else --(signed)rA >> imm "110111" when (op = "111010" and opx = "111011" --sra ) else --(signed)rA >> rB "011001" when (op = "001110" or --ble op = "001000" or --cmplei (op = "111010" and opx = "001000") --cmple ) else -- rA <= rB , rA <= (signed)imm "011010" when (op = "010110" or --bgt op = "010000" or --cmpgti (op = "111010" and opx = "010000") --cmpgt ) else -- rA > rB , rA > (signed)imm "011011" when (op = "011110" or --bne op = "011000" or --cmpnei (op = "111010" and opx = "011000") --cmpne ) else -- rA != rB , rA != (signed)imm "011100" when (op = "100110" or --beq op = "000110" or --br op = "100000" or --cmpeqi (op = "111010" and opx = "100000") --cmpeq ) else --rA = rB , rA = (signed)imm "011101" when (op = "101110" or --bleu op = "101000" or --cmpleui (op = "111010" and opx = "101000") --cmpleu ) else --(unsigned)rA <= (unsigned)rB , (unsigned)rA <= (unsigned)imm "011110" when (op = "110110" or --bgtu op = "110000" or --cmpgtui (op = "111010" and opx = "110000") --cmpgtu ) else --(unsigned)rA > (unsigned)rB , (unsigned)rA > (unsigned)imm "110000" when (op = "111010" and opx = "000011" --rol ) else --rA rol rB "111000" when (op = "111010" and opx = "000010" --roli ) else --rA rol imm "110001" when (op = "111010" and opx = "001011" --ror ) else --rA ror rB "000000"; --DEFAULT end synth;