-- Albert Coba 1727 -- Shawn Nematbakhsh 8551 -- cs161 proj2: Datapath: -- a MIPS control -- these are the individual components in our datapath, -- taken from as1 -- 2 to 1 mux with 32 bit output library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity Mux2 is port( rst : in std_logic; clk : in std_logic; sel : in std_logic; -- selects in1 or in2 in1 : in std_logic_vector(31 downto 0); -- inputs in2 : in std_logic_vector(31 downto 0); output : out std_logic_vector(31 downto 0)); -- one output end Mux2; architecture bhv of Mux2 is begin process(rst,sel,in1,in2) begin if(rst='1') then -- out zero on reset output<="00000000000000000000000000000000"; else case sel is when '0' => output <= in1; -- out an input depending on select when '1' => output <= in2; when others => end case; end if; end process; end bhv; -- 2 to 1 mux with 5 bit output library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity Mux2_5 is port( rst : in std_logic; clk : in std_logic; sel : in std_logic; in1 : in std_logic_vector(4 downto 0); -- same as above, with 5 bit in/out in2 : in std_logic_vector(4 downto 0); output : out std_logic_vector(4 downto 0)); end Mux2_5; architecture bhv of Mux2_5 is begin process(rst,sel,in1,in2) begin if(rst='1') then output<="00000"; else case sel is when '0' => output <= in1; -- out the correct input when '1' => output <= in2; when others => end case; end if; end process; end bhv; -- 4 to 1 mux with 32 bit output library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity Mux4 is port( rst : in std_logic; clk : in std_logic; sel : in std_logic_vector(1 downto 0); -- 2 bit selector picks from 4 inputs in1 : in std_logic_vector(31 downto 0); in2 : in std_logic_vector(31 downto 0); in3 : in std_logic_vector(31 downto 0); in4 : in std_logic_vector(31 downto 0); output : out std_logic_vector(31 downto 0)); end Mux4; architecture bhv of Mux4 is begin process(rst,sel,in1,in2,in3,in4) begin if(rst='1') then output<="00000000000000000000000000000000"; else case sel is when "00" => output <= in1; -- output correct in when "01" => output <= in2; when "10" => output <= in3; when "11" => output <= in4; when others => end case; end if; end process; end bhv; -- instruction register library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity IR is port( rst : in std_logic; clk : in std_logic; MemData : in std_logic_vector(31 downto 0); -- input data IRWrite : in std_logic; -- writes when asserted output : out std_logic_vector(31 downto 0)); end IR; architecture bhv of IR is signal INSTR : std_logic_vector(31 downto 0); -- keeps data begin process(clk,rst) begin if(rst='1') then INSTR <= "00000000000000000000000000000000"; -- set to zero output <= "00000000000000000000000000000000"; -- on reset elsif(clk'event and clk='1') then if(IRWrite='1') then -- write on write INSTR <= MemData; output <= MemData; end if; end if; end process; end bhv; -- 32 entry register file library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity Register32 is port( rst : in std_logic; clk : in std_logic; RegWrite : in std_logic; -- write signal ReadReg1 : in std_logic_vector(4 downto 0); -- reg to read from ReadReg2 : in std_logic_vector(4 downto 0); -- second read port WriteReg : in std_logic_vector(4 downto 0); -- reg to write to WriteData: in std_logic_vector(31 downto 0); -- data to write ReadData1 : out std_logic_vector(31 downto 0); -- the output of the two ReadData2 : out std_logic_vector(31 downto 0)); -- read ports end Register32; architecture bhv of Register32 is type Reg32Type is array (0 to 31) of std_logic_vector (31 downto 0); -- stores data signal REGS : Reg32Type; begin process(clk,rst,ReadReg1,ReadReg2) -- async reads, sync writes begin if(rst = '1') then for i in 0 to 31 loop REGS(i)<="00000000000000000000000000000000"; end loop; -- zero everything on reset ReadData1 <= "00000000000000000000000000000000"; ReadData2 <= "00000000000000000000000000000000"; else if(clk'event and clk='1') then -- write if flagged if(RegWrite='1') then REGS(conv_integer(WriteReg)) <= WriteData; end if; end if; ReadData1 <= REGS(conv_integer(ReadReg1)); -- read the correct reg ReadData2 <= REGS(conv_integer(ReadReg2)); end if; end process; end bhv; -- 1 entry register file, for storing temporary output for another clock cycle library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity Register1 is port( rst : in std_logic; clk : in std_logic; DataIn : in std_logic_vector(31 downto 0); -- data in, kept for DataOut: out std_logic_vector(31 downto 0)); -- one cycle end Register1; architecture bhv of Register1 is signal Reg:std_logic_vector(31 downto 0); -- stores data for one cycle begin process(rst,clk) begin if(rst='1') then DataOut <= "00000000000000000000000000000000"; Reg <= "00000000000000000000000000000000"; elsif(clk'event and clk='1') then Reg<=DataIn; DataOut<=DataIn; -- out the temporary signal end if; end process; end bhv; -- ALU library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity ALU is port( rst : in std_logic; clk : in std_logic; ctrl: in std_logic_vector(2 downto 0); -- 3 control bits in1 : in std_logic_vector(31 downto 0); -- inputs in2 : in std_logic_vector(31 downto 0); output : out std_logic_vector(31 downto 0); zero : out std_logic); -- outs one if output is zero end ALU; architecture bhv of ALU is begin process(rst,ctrl,in1,in2) begin if(rst = '1') then output <= "00000000000000000000000000000000"; zero <= '1'; else case ctrl is when "000" => output <= in1 AND in2; -- and if(in1 = "00000000000000000000000000000000" OR in2 = "00000000000000000000000000000000") then zero <= '1'; else zero <= '0'; end if; when "001" => output <= in1 OR in2; -- or if(in1 = "00000000000000000000000000000000" AND in2 = "00000000000000000000000000000000") then zero <= '1'; else zero <= '0'; end if; when "010" => output <= in1 + in2; -- add if(in1 + in2 = "00000000000000000000000000000000") then zero <= '1'; else zero <= '0'; end if; when "110" => output <= in1 - in2; -- sub if(in1 - in2 = "00000000000000000000000000000000") then zero <= '1'; else zero <= '0'; end if; when "111" => if(in1 < in2) then -- lt output <= "00000000000000000000000000000001"; zero <= '0'; else output <= "00000000000000000000000000000000"; zero <= '1'; end if; when others => end case; end if; end process; end bhv; -- sign extender, 16 bits to 32 bits library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity SignExtender is port( rst : in std_logic; clk : in std_logic; input: in std_logic_vector(15 downto 0); -- 16 bits --> 32 bits output : out std_logic_vector(31 downto 0)); end SignExtender; architecture bhv of SignExtender is begin process(rst,input) begin if(rst='1') then output <= "00000000000000000000000000000000"; else if(input(15)='1') then -- pad with ones if negative for i in 31 downto 16 loop output(i)<='1'; end loop; else for i in 31 downto 16 loop output(i)<='0'; -- zeros if positive end loop; end if; for i in 15 downto 0 loop output(i)<=input(i); -- set output end loop; end if; end process; end bhv; -- shifter. shifts two to the left library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity Shift32 is port( clk: in std_logic; rst: in std_logic; input: in std_logic_vector(31 downto 0); output: out std_logic_vector(31 downto 0)); end Shift32; architecture bhv of Shift32 is begin process(clk, input) begin if(rst = '1')then output <= "00000000000000000000000000000000"; else output(31 downto 2) <= input(29 downto 0); output(1 downto 0) <= "00"; -- shift end if; end process; end bhv; -- same as above but with 26 bit input and 28 bit output library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity Shift28 is port( rst: in std_logic; clk: in std_logic; input: in std_logic_vector(25 downto 0); output: out std_logic_vector(27 downto 0)); end Shift28; architecture bhv of Shift28 is begin process(rst,input) begin if(rst='1') then output <= "0000000000000000000000000000"; else output(27 downto 2) <= input(25 downto 0); output(1 downto 0) <= "00"; -- shift end if; end process; end bhv; library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.std_logic_unsigned.all; entity Memory is port( rst : in std_logic; clk : in std_logic; rd : in std_logic; wr : in std_logic; addr : in std_logic_vector (31 downto 0); in_data : in std_logic_vector (31 downto 0); out_data : out std_logic_vector (31 downto 0)); end Memory; architecture bhv of Memory is type MEM_TYPE is array (0 to 255) of std_logic_vector (31 downto 0); signal MEMORY : MEM_TYPE; begin process( clk, rst ) begin if ( rst = '1') then for i in 0 to 255 loop MEMORY(i) <= "00000000000000000000000000000000"; end loop; MEMORY(0) <= "00001000000000000000000000001010"; -- j 10 MEMORY(10) <= "10001100000010100000000010000000"; -- lw r10, 128(r0) MEMORY(11) <= "00000001010010100110000000100000"; -- add r12, r10, r10 MEMORY(12) <= "00000001100010100101100000100100"; -- and r11, r12, r10 MEMORY(13) <= "10101100000010110000000010000100"; -- sw r11, 132(r0) MEMORY(14) <= "10001100000011010000000010000100"; -- lw r13, 132(r0) MEMORY(15) <= "00010001011010111111111111111010"; -- beq r11, r11, -6 if r11 = r11 -- data MEMORY(32) <= "00000000000000000000000000000111"; elsif (clk'event and clk = '1') then if (conv_integer("00" & addr (7 downto 2)) < 255) then if (wr = '1') then MEMORY(conv_integer("00" & addr (7 downto 2))) <= in_data; end if; end if; end if; end process; process (rst, rd, addr) begin if (rst = '1') then out_data <= "00000000000000000000000000000000"; elsif (rd = '1' and conv_integer("00" & addr (7 downto 2)) < 255) then out_data <= MEMORY(conv_integer("00" & addr (7 downto 2))); end if; end process; end bhv;