All pastes #763111 Raw Edit

Mine

public text v1 · immutable
·published 2007-11-06 04:33 UTC
rendered paste body
library 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;