rendered paste bodylibrary ieee;
use ieee.std_logic_1164.all;
entity controller is
port (
CLK: IN STD_LOGIC;
OPCODE: IN STD_LOGIC_VECTOR (3 downto 0);
ZERO: IN STD_LOGIC;
nReset: IN STD_LOGIC;
RT: IN STD_LOGIC_VECTOR(3 downto 0);
ALUOp: OUT STD_LOGIC_VECTOR(3 downto 0);
ALUselA: OUT STD_LOGIC_VECTOR(1 downto 0);
ALUselB: OUT STD_LOGIC_VECTOR(2 downto 0);
RegWE: OUT STD_LOGIC;
RFWE: OUT STD_LOGIC;
RegWSrc: OUT STD_LOGIC_VECTOR(1 downto 0);
Reg1Src: OUT STD_LOGIC;
MDRWE: OUT STD_LOGIC;
Reg2Src: OUT STD_LOGIC;
iMemWait: in STD_LOGIC;
dMemWait: in STD_LOGIC;
IRWE: OUT STD_LOGIC;
imemRead: OUT STD_LOGIC;
dmemRead: OUT STD_LOGIC;
dmemWrite:OUT STD_LOGIC;
PCWE: OUT STD_LOGIC;
PCSel: OUT STD_LOGIC_VECTOR(1 downto 0);
Halt: OUT STD_LOGIC;
exSel: OUT STD_LOGIC_VECTOR(1 downto 0);
AWE: OUT STD_LOGIC;
BWE: OUT STD_LOGIC;
ALUoutWE: OUT STD_LOGIC
-- AND OTHER WE for other registers.
);
end controller;
architecture behavioral of controller is
type state_type is (fetch, decode, haltstate, exec, mem, writeback);
signal state, next_state: state_type;
begin
state_logic : process(state,iMemWait, dMemWait, OPCODE, RT, ZERO)
begin
ALUop <= "0000";
ALUselA <= "00";
ALUselB <= "000";
RegWE <= '0';
RFWE <= '0';
RegWSrc <= "00";
Reg1Src <= '0';
Reg2Src <= '0';
IRWE <= '0';
imemRead <= '0';
dmemRead <= '0';
dmemWrite <= '0';
PCWE <= '0';
PCSel <= "00";
AWE <= '0';
BWE <= '0';
Halt <= '0';
exSel <= "00";
ALUoutWE <= '0';
MDRWE <= '0';
case state is
when fetch =>
imemRead <= '1';
IRWE <= '1';
ALUop <= "0010";
ALUselB <= "010";
ALUselA <= "00";
PCsel <= "01";
if imemWait = '1' then
next_state <= fetch;
else
PCWE <= '1';
AWE <= '1';
BWE <= '1';
--imemRead <= '0';
next_state <= decode;
end if;
when decode =>
if OPCODE = x"C" then --LDI
exSel <= "11"; -- sets to zero extend offset
ALUselB <= "011"; --extended
ALUselA <= "00"; --Doesnt matter
RegWSrc <= "11"; --taken from extended imm, 11?
RFWE <= '1';
next_state <= fetch;
elsif OPCODE = x"B" then --LUI
exSel <= "00";
ALUop <= "0000"; --OR
ALUselB <= "011"; --extended
ALUselA <= "10";--01? --rdat 16bit
Reg1Src <= '1'; --rD
RegWSrc <= "01"; --rdat of aluout
ALUoutWE <= '1';
AWE <= '1';
BWE <= '1';
next_state <= exec;
elsif OPCODE = x"8" then --LDW, need mem
RegWSrc <= "00";
Reg1Src <= '0';
exSel <= "01";
ALUop <= "0010";
ALUselA <= "01";
ALUselB <= "011";
AWE <= '1';
BWE <= '1';
ALUoutWE <= '1';
next_state <= exec;
elsif OPCODE = x"A" then --STW
AWE <= '1';
BWE <= '1';
Reg2Src <= '1';
Reg1Src <= '0';
exSel <= "01";--"11";
ALUoutWE <= '1';
ALUselA <= "01";
ALUselB <= "011";
ALUop <= "0010";
next_state <= exec;
elsif (OPCODE = x"F") and RT = x"F" then
next_state <= haltstate;
elsif (OPCODE = x"F") and RT = x"0" then --Jump
RegWSrc <= "10";
RFWE <= '1'; --AWE should already have RS clocked into it
ALUSelA <= "01"; --sets to r
AWE <= '1';
next_state <= exec;
elsif (OPCODE = x"F") and RT = x"2" then --NOT
--rd <= not RS, xor with FFFF
AWE <= '1';
next_state <= exec;
elsif (OPCODE = x"E") then --BR
RegWSrc <= "10"; --writing npc to rd
RFWE <= '1'; --$rd <= $npc
ALUSelA <= "00"; --sets PC to A
exSel <= "10"; --????
ALUoutWE <= '1';
ALUSelB <= "011";
ALUop <= x"2";
PCSel <= "01";
PCWE <= '1';
next_state <= fetch;
elsif (OPCODE = x"D") or (OPCODE = x"9") then --BZ or BNZ
exSel <= "10";
ALUselA <= "00"; --00
ALUselB <= "011"; --011
ALUoutWE <= '1';
ALUop <= x"2";
Reg1Src <= '1';
AWE <= '1'; --add pc+extension and store in case
next_state <= exec;
BWE <= '1';
else
if (OPCODE = x"0" or OPCODE = x"1" or OPCODE = x"2" or
OPCODE = x"3" or OPCODE = x"4" or OPCODE = x"5" or
OPCODE = x"6" or OPCODE = x"7") then
--Do ALU Op
ALUop <= OPCODE;
Reg1Src <= '0';
Reg2Src <= '0';
AWE <= '1';
BWE <= '1';
next_state <= exec;
else next_state <= fetch;
end if;
end if;
when exec =>
if OPCODE = x"A" then --STW
ALUselA <= "01";
ALUselB <= "011";
ALUop <= "0010";
ALUoutWE <= '1';
--dMemWrite <= '1'; --may need to move down a state
next_state <= mem;
exSel <= "01";
elsif OPCODE = x"8" then --LDW
ALUoutWE <= '1';
ALUselA <= "01"; --added
exSel <= "01";
ALUselB <= "011"; --added 011?
ALUop <= "0010";
--dMemRead <= '1';
next_state <= mem; --without this data showsup
elsif OPCODE = x"B" then
ALUoutWE <= '1';
ALUselA <= "10";
ALUselB <= "011";
ALUop <= "0000";
exSel <= "00";
next_state<=writeback;
elsif (OPCODE = x"F") and RT = x"2" then --NOT
--OUTPUT is at aluout, write to rd
ALUSelB <= "100"; --FFFF
ALUSelA <= "01";
ALUop <= "0100"; --x"4";
ALUoutWE <= '1'; --clock output for RDRegWSrc <= "01";
--RFWE <= '1';
--RegWSrc <= "01";
next_state <= writeback;
elsif (OPCODE = x"F") and RT = x"0" then --Jump
ALUselA <= "01";
PCSel <= "00";
PCWE <= '1';
next_state <= fetch;
elsif (OPCODE = x"D") then --BZ
ALUSelA <= "01";
ALUSelB <= "001";
ALUop <= x"2"; --add rd + 0 to test
if ZERO = '1' then
--ALUoutWE <= '1'; --testing
PCWE <= '1';
PCsel <= "10";
--ALUoutWE <= '0'; --to test for state
next_state <= fetch;
else
--AWE <= '1';
PCsel <= "00";
PCWE <= '0';
--PCsel <= "10";
--PCWE <= '1';
next_state <= fetch;
next_state <= fetch;
end if;
elsif (OPCODE = x"9") then --BNZ
ALUSelA <= "01";
ALUSelB <= "001";
ALUop <= x"2";
if ZERO = '0' then
--Reg1Src <= '0';
--AWE <= '0';
PCWE <= '1';
PCsel <= "10"; --10
next_state <= fetch;
else
PCsel <= "00";
PCWE <= '0';
next_state <= fetch;
end if;
next_state <= fetch;
else
--finish ALUop
AlUSelA <= "01";
ALUSelB <= "000";
ALUop <= OPCODE;
ALUoutWE <= '1'; --writes alu output
next_state <= mem;
end if;
when mem =>
if dMemWait = '1' then
if OPCODE = x"8" then
dMemRead <= '1';
next_state <= mem;
end if;
if OPCODE = x"A" then
dMemWrite <= '1';
next_state <= mem;
end if;
next_state <= mem;
else
if OPCODE = "1100" then --LDI
RFWE <= '1';
next_state <= fetch;
elsif OPCODE = x"B" then --LUI
RFWE <= '1';
next_state <= fetch;
elsif OPCODE = x"8"then --LDW
--RFWE <='1';
--MDRWE <= '1';
-- ALUop <= "0010";
dMemRead <= '1';
--ALUoutWE <= '1';
MDRWE <= '1';
next_state <= writeback;
elsif OPCODE = x"A" then --STW
-- MDRWE <= '1';
--dMemWrite <= '1';
dMemWrite <= '1';
next_state <= fetch;
elsif (OPCODE = x"D") or (OPCODE = x"9") then --BNZ or BZ
if ZERO = '1' then
ALUSelA <= "00"; --sets PC to A
exSel <= "11"; --????
ALUSelB <= "011";
ALUop <= x"2";
PCSel <= "01";
PCWE <= '1';
next_state <= fetch;
else
next_state <= fetch;
end if;
else
--ALUop Finish
RegWSrc <= "01";
RFWE <= '1';
next_state <= fetch;
end if;
-- next_state <= fetch;
end if;
when writeback =>
if dMemWait = '1' then
if OPCODE = x"8" then
dMemRead <= '1';
MDRWE <= '1';
next_state <= writeback;
end if;
if OPCODE = x"A" then
dMemWrite <= '1';
next_state <= writeback;
end if;
next_state <= writeback;
else
if OPCODE = x"8" then
RFWE <= '1';
next_state <= fetch;
--MDRWE <= '1';
end if;
if OPCODE = x"A" then
next_state <= fetch;
end if;
if OPCODE = x"B" then
RegWSrc <= "01";
RFWE <= '1';
--ALUoutWE <= '1';
next_state <= fetch;
end if;
if (OPCODE = x"F") and RT = x"2" then
RFWE <= '1';
RegWSrc <= "01";
next_state <= fetch;
end if;
--RFWE <= '1';
--MDRWE <= '1';
next_state <= fetch;
end if;
--RFWE <= '1';
--next_state <= fetch;
when haltstate =>
Halt <= '1';
next_state <= haltstate;
--when others =>
-- next_state <= fetch;
end case;
end process state_logic;
state_register : process(CLK, nReset)
begin
if (nReset = '0') then
state <= fetch;
elsif (rising_edge(clk)) then
state <= next_state;
end if;
end process state_register;
end behavioral;