epfl-archive/cs208-ca/vhdl/controller.vhd.bak

234 lines
8.5 KiB
VHDL
Raw Normal View History

2022-04-07 18:43:21 +02:00
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
-- op = "001010") --????????????????????????????????????????
) 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 = FETCH1 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 = "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;