--*******************Microprocessor Project ********************-- --Ahmad Dar Khalil 1120443 -- Mohammad modallal 1120174 -- Ehab Amriah 1120871 --*********** Build ALU entity ***********-- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_signed.all; use ieee.std_logic_arith.all ; use ieee.numeric_std.all; entity ALU IS port(a,b :in std_logic_vector(31 downto 0):=X"00000004"; opcode:in std_logic_vector(5 downto 0); result:out std_logic_vector(31 downto 0)); end entity ALU; --**************************** Architecture of ALU *****************************-- architecture ALU of ALU is signal ave : integer ; begin --(1+3+4=8) ave <= (conv_integer(a) + conv_integer(b))/2; result <= a+b when opcode="000001" -- addition -- subtraction else a-b when opcode="000110" else abs(a) when opcode="001101" --absolute value else -a when opcode="001000" -- to get -a else a when opcode="000111" -- max element between a,b and a > b else b when opcode="000111" and (a < b or a = b) else a when opcode="000100" and a < b -- min element between a,b else b when opcode="000100" and (a > b or a = b) else conv_std_logic_vector(ave, 32) when opcode="001011" --average else not a when opcode="001111" -- 2's complement else a or b when opcode="000011" -- or operation else a and b when opcode="000101" -- and operation else a xor b when opcode="000010" ; -- xor operation end architecture ALU; --*************************** Test Bench of ALU ******************************** -- test banch for ALU that takes all possible values of opcode . library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_signed.all; use ieee.std_logic_arith.all ; use ieee.numeric_std.all; entity testalu is end ; architecture testalu of testalu is signal a,b,result : std_logic_vector(31 downto 0 ) ; signal op : std_logic_vector(5 downto 0); begin g1: entity work.ALU(ALU) port map (a,b,op , result) ; -- we take all the possibilites to check all the parts of code a <= X"00000004" , X"00000009" after 10 ns , X"FFFFFFF1" after 20 ns, X"00000001" after 30 ns , X"00000007" after 40 ns, X"00000011" after 50 ns, X"00000000" after 60 ns, X"00011100" after 70 ns, X"00000111" after 80 ns, X"11000000" after 90 ns; b <= X"00000005" , X"00000008" after 10 ns , X"FFFFFFF0" after 20 ns, X"00000001" after 30 ns, X"00000009" after 40 ns, X"00000001" after 50 ns, X"00000001" after 60 ns, X"00000110" after 70 ns, X"01000001"after 80 ns, X"10011000" after 90 ns; op <= "000001" , "000110" after 10ns , "001101" after 20ns ,"001000" after 30ns,"000111" after 40ns ,"000100" after 50ns,"001111" after 60ns , "000011" after 70 ns, "000101" after 80 ns, "000010" after 90 ns; end ; --*************************************** register file ***********************-- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all ; use ieee.numeric_std.all; entity reg_file is port( address1 , address2 , address3 : in std_logic_vector(4 downto 0 ) ; input : in std_logic_vector(31 downto 0 ) ; clk , enable: in std_logic ; output1 , output2 : out std_logic_vector(31 downto 0 ) ) ; end entity reg_file ; architecture reg_file of reg_file is type memory is array(0 to 31) of std_logic_vector(31 downto 0) ; -- initialization of the file register signal ram_data : memory := ( conv_std_logic_vector(0, 32), conv_std_logic_vector(5986, 32), conv_std_logic_vector(12250, 32), conv_std_logic_vector(482, 32), conv_std_logic_vector(14246, 32), conv_std_logic_vector(5424, 32), conv_std_logic_vector(1848, 32), conv_std_logic_vector(5260, 32), conv_std_logic_vector(16170, 32), conv_std_logic_vector(4766, 32), conv_std_logic_vector(4298, 32), conv_std_logic_vector(610, 32), conv_std_logic_vector(1510, 32), conv_std_logic_vector(9794, 32), conv_std_logic_vector(7456, 32), conv_std_logic_vector(5580, 32), conv_std_logic_vector(9300, 32), conv_std_logic_vector(12314, 32), conv_std_logic_vector(12806, 32), conv_std_logic_vector(10478, 32), conv_std_logic_vector(11556, 32), conv_std_logic_vector(6778, 32), conv_std_logic_vector(8430, 32), conv_std_logic_vector(5700, 32), conv_std_logic_vector(13422, 32), conv_std_logic_vector(11224, 32), conv_std_logic_vector(1990, 32), conv_std_logic_vector(922, 32), conv_std_logic_vector(6020, 32), conv_std_logic_vector(15768, 32), conv_std_logic_vector(5624, 32), conv_std_logic_vector(0, 32) ) ; begin process(clk , enable) begin if(rising_edge(clk)) then -- only work on positive edge of the clock if(enable = '1') then --when the enable 1 it is work , otherwise it will ignore the input output1 <= ram_data(conv_integer(address1)); output2 <= ram_data(conv_integer(address2)); ram_data(conv_integer(address3)) <=input ; end if ; end if ; end process ; end architecture reg_file ; -- ********** testbench of ram memory(file register) ***********************-- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all ; use ieee.numeric_std.all; entity test_mem is end entity test_mem ; architecture test_mem of test_mem is signal address1 , address2 , address3 : std_logic_vector(4 downto 0 ) ; signal input : std_logic_vector(31 downto 0 ) ; signal clk : std_logic :='0' ; signal enable : std_logic :='1'; signal output1 , output2 : std_logic_vector(31 downto 0 ) ; begin clk <= not clk after 5 ns ; g : entity work.reg_file(reg_file) port map (address1 , address2 , address3 ,input , clk ,enable, output1 , output2) ; address1 <= "00100" , "11111" after 10 ns , "11111" after 20 ns , "11100" after 30 ns; address2 <= "00000" , "01111" after 10 ns , "01001" after 20 ns; address3 <= "01001" , "11111" after 10 ns , "10101" after 30 ns; input <= X"88888888" ,X"FFFFFFFF" after 12 ns , X"00000000"after 30ns ; enable <='0' after 30 ns ; end architecture test_mem ; --************************** microprocessor ***********************------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all ; use ieee.numeric_std.all; entity microprocessor is port(instruction :in std_logic_vector(31 downto 0); clk:in std_logic ; outp : out std_logic_vector(31 downto 0 ) ); end entity microprocessor; architecture microprocessor of microprocessor is signal result: std_logic_vector(31 downto 0 ) ; signal register1: std_logic_vector(31 downto 0 ) ; signal output1 , output2 : std_logic_vector(31 downto 0 ) ; signal enable : std_logic :='1'; begin -- check the cases that contait invalid opcode enable <= '0' when instruction(5 downto 0 ) = "000000" or instruction(5 downto 0 ) = "001001" or instruction(5 downto 0 ) = "001100" or instruction(5 downto 0 ) = "001010" or instruction(5 downto 0 ) = "001110" else '1'; -- we need one register file as memoty g1: entity work.reg_file(reg_file)port map(address1 =>register1(10 downto 6),address2 =>register1(15 downto 11) , address3 =>register1(20 downto 16) , clk=>clk ,output1 =>output1 , output2 => output2 ,input=>result , enable =>enable); --ALU to make the operation according the entered opcode g2:entity work.ALU(ALU) port map (opcode =>register1(5 downto 0),a=>output1,b=>output2 , result => result) ; outp <= result ; process (clk) begin -- this is actualy insted of define new entity called register .... and work like it ecxactly . if (rising_edge(clk)) then register1(20 downto 6) <= instruction (20 downto 6); register1(5 downto 0) <= instruction (5 downto 0) after 10ns; end if; end process; end architecture microprocessor; --********************** testbench of microprocessor ***********************-- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all ; use ieee.numeric_std.all; entity test_micro is end entity test_micro; architecture test_micro of test_micro is signal inst , result :std_logic_vector(31 downto 0 ) := X"00000844"; signal clk : std_logic :='1'; begin g: entity work.microprocessor(microprocessor) port map(instruction =>inst , outp =>result , clk =>clk) ; inst <= X"00001841", -- address1 + address3 X"00001881" after 30 ns, -- address2 + address3 X"00000886" after 50 ns , -- address2 - address1 X"00001844" after 70 ns, -- min(address1 , address3) X"00000900" after 90 ns, -- max(address1 , address4 ) X"00000902" after 110 ns; -- address1 XOR address4 clk <= not clk after 5 ns ; end architecture test_micro; --******************************** find minimum *************************-- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all ; use ieee.numeric_std.all; entity find_min is end entity find_min; architecture find_min of find_min is signal inst , result :std_logic_vector(31 downto 0 ) := X"00000844"; signal clk : std_logic :='1'; begin -- take one instant od microprocessor g: entity work.microprocessor(microprocessor) port map(instruction =>inst , outp =>result , clk =>clk) ; clk <= not clk after 5 ns ; process begin --generate all machine instructions that we need for i in 1 to 30 loop wait for 40 ns ; inst <= X"0000"&conv_std_logic_vector(0, 5)&conv_std_logic_vector(i, 5)&"000100"; end loop ; wait ; end process ; end architecture find_min;