diff --git a/Makefile b/Makefile index c610ea4..d46a5c7 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,10 @@ PARTS = alu all: $(PARTS) -%: %.vhd tb_%.vhd +%: *.vhd tb_%.vhdl $(CHDL) -a $(FLAGS) $^ - $(CHDL) -e $(FLAGS) $@ - $(CHDL) -r $(FLAGS) $@ --wave=$@.ghw --stop-time=$(STOP) + $(CHDL) -e $(FLAGS) $@_tb + $(CHDL) -r $(FLAGS) $@_tb --wave=$@.ghw --stop-time=$(STOP) clean: find . -name '*.o' -exec rm -r {} \; diff --git a/alu.vhd b/alu.vhd index a6dc6e9..ca5bb6f 100644 --- a/alu.vhd +++ b/alu.vhd @@ -18,21 +18,32 @@ end ALU; -- Architecture Logic of ALU: Asynchronous calculation architecture Logic of ALU is - + signal parity : std_logic := '0'; + signal count : std_logic_vector(7 downto 0) := (others => '0'); begin + + set_parity : process(operand1(0), operand1(1), operand1(2), operand1(3), + operand1(4), operand1(5), operand1(6), operand1(7)) + begin + parity <= operand1(7) xor operand1(6) xor operand1(5) xor operand1(4) xor operand1(3) xor operand1(2) xor operand1(1) xor operand1(0); + end process set_parity; + + set_count : process(all) + begin + count <= std_logic_vector(unsigned(count)); + end process set_count; + + -- Process Calculate - Calculate : process (all) + Calculate : process (operand1, operand2, operator, parity) begin case operator is - when "000000" => result <= not operand1; -- Not op1 - when "000100" => - for i in operand1'range loop - result(i) <= operand1(i) xor operand2(i); - end loop; -- Par op1 - when "001000" => result <= (others => '0'); -- Cnt op1 - when "001101" => result <= operand1 and operand2; -- And op1 - when "010001" => result <= operand1 or operand2; -- Or op1 - when "010101" => result <= operand1 xor operand2; -- Xor op1 + when "000000" => result <= operand1 xor "11111111"; -- Not op1 + when "000100" => result <= "0000000" & parity; -- Par op1 + when "001000" => result <= (others => '0'); -- Cnt op1 + when "001101" => result <= operand1 and operand2; -- And op1 + when "010001" => result <= operand1 or operand2; -- Or op1 + when "010101" => result <= operand1 xor operand2; -- Xor op1 when "011001" => result <= operand2; -- Mov op1 when "011101" => result <= std_logic_vector(to_stdlogicvector(to_bitvector(operand1) sll to_integer(unsigned(operand2)))); -- Sl op1 when "100001" => result <= std_logic_vector(to_stdlogicvector(to_bitvector(operand1) srl to_integer(unsigned(operand2)))); -- Sr op1 diff --git a/tb_alu.vhd b/tb_alu.vhd deleted file mode 100644 index 262c42c..0000000 --- a/tb_alu.vhd +++ /dev/null @@ -1,75 +0,0 @@ --- tb_alu.vhd --- Date: Sun Mar 3 09:47:29 2024 --- Author: Yannick Reiß --- E-Mail: yannick.reiss@nickr.eu -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -library std; -use std.textio.all; - -library work; - -entity alu_tb is -end alu_tb; - -architecture Testbench of alu_tb is - - signal clk : std_logic; - constant clk_period : time := 10 ns; - signal operator : std_logic_vector(5 downto 0) := (others => '0'); - signal operand1 : std_logic_vector(7 downto 0) := (others => '0'); - signal operand2 : std_logic_vector(7 downto 0) := (others => '0'); - signal result : std_logic_vector(7 downto 0) := (others => '0'); -begin - - uut : entity work.alu(Logic) - port map ( - operator => operator, - operand1 => operand1, - operand2 => operand2, - result => result - ); - - clk_process : process - begin - clk <= '0'; - wait for clk_period/2; - clk <= '1'; - wait for clk_period/2; - end process; - - testing : process - variable lineBuffer : line; - begin - wait until rising_edge(clk); - write(lineBuffer, string'("Starting the simulator")); - writeline(output, lineBuffer); - - -- Testcases - for i in 1 to 20 loop - operand1 <= std_logic_vector(to_unsigned(i, 8)); - operand2 <= std_logic_vector(to_unsigned(20 - i, 8)); - operator <= "001101"; - wait for 10 ns; - - -- Not - if not (result = not operand1) then - write(lineBuffer, string'("Error on Not")); - writeline(output, lineBuffer); - end if; - - -- Parity - operator <= "000100"; - wait for 10 ns; - - end loop; - - write(lineBuffer, string'("end of simulator")); - writeline(output, lineBuffer); - - wait; - end process; - -end Testbench; diff --git a/tb_alu.vhdl b/tb_alu.vhdl new file mode 100644 index 0000000..640c030 --- /dev/null +++ b/tb_alu.vhdl @@ -0,0 +1,192 @@ +-- tb_alu.vhdl +-- Date: Sun Mar 3 09:47:29 2024 +-- Author: Yannick Reiß +-- E-Mail: yannick.reiss@nickr.eu +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +library std; +use std.textio.all; + +library work; + +entity alu_tb is +end alu_tb; + +architecture Testbench of alu_tb is + + signal clk : std_logic; + constant clk_period : time := 10 ns; + signal operator : std_logic_vector(5 downto 0) := "111111"; + signal operand1 : std_logic_vector(7 downto 0) := (others => '0'); + signal operand2 : std_logic_vector(7 downto 0) := (others => '0'); + signal target : std_logic_vector(7 downto 0) := (others => '0'); + signal test_result : std_logic := '0'; + signal result : std_logic_vector(7 downto 0) := (others => '0'); +begin + + uut : entity work.alu(Logic) + port map ( + operator => operator, + operand1 => operand1, + operand2 => operand2, + result => result + ); + + clk_process : process + begin + clk <= '0'; + wait for clk_period/2; + clk <= '1'; + wait for clk_period/2; + end process; + + testing : process + variable lineBuffer : line; + begin + wait until rising_edge(clk); + write(lineBuffer, string'("Starting the simulator")); + writeline(output, lineBuffer); + + -- Testcases + operand1 <= std_logic_vector(to_unsigned(3, 8)); + operand2 <= std_logic_vector(to_unsigned(20, 8)); + + -- Not + wait for 5 ns; + operator <= "000000"; + target <= operand1 xor "11111111"; + wait for 5 ns; + if not (target = result) then + write(lineBuffer, string'("Error on Not")); + writeline(output, lineBuffer); + end if; + + -- Parity + wait for 5 ns; + operator <= "000100"; + target <= "00000000"; + wait for 5 ns; + if not (unsigned(result) = unsigned(target)) then + write(lineBuffer, string'("Error on Parity")); + writeline(output, lineBuffer); + end if; + + -- Count + wait for 5 ns; + operator <= "001000"; + target <= "00000010"; + wait for 5 ns; + if not (unsigned(result) = 1) then + write(lineBuffer, string'("Error on Count")); + writeline(output, lineBuffer); + end if; + + -- And + wait for 5 ns; + operator <= "001101"; + target <= operand1 and operand2; + wait for 5 ns; + if not (result = target) then + write(lineBuffer, string'("Error on And")); + writeline(output, lineBuffer); + end if; + + -- Or + wait for 5 ns; + operator <= "010001"; + wait for 5 ns; + if not (result = (operand1 or operand2)) then + write(lineBuffer, string'("Error on Or")); + writeline(output, lineBuffer); + end if; + + -- Xor + wait for 5 ns; + operator <= "010101"; + wait for 5 ns; + if not (result = (operand1 xor operand2)) then + write(lineBuffer, string'("Error on Xor")); + writeline(output, lineBuffer); + end if; + + -- Move + wait for 5 ns; + operator <= "011001"; + wait for 5 ns; + if not (result = operand2) then + write(lineBuffer, string'("Error on Move")); + writeline(output, lineBuffer); + end if; + + -- Shift left + wait for 5 ns; + operator <= "011101"; + wait for 5 ns; + if not (result = std_logic_vector(to_stdlogicvector(to_bitvector(operand1) sll to_integer(unsigned(operand2))))) then + write(lineBuffer, string'("Error on Shift left")); + writeline(output, lineBuffer); + end if; + + -- Shift right + wait for 5 ns; + operator <= "100001"; + wait for 5 ns; + if not (result = std_logic_vector(to_stdlogicvector(to_bitvector(operand1) srl to_integer(unsigned(operand2))))) then + write(lineBuffer, string'("Error on Shift right")); + writeline(output, lineBuffer); + end if; + + -- Add + wait for 5 ns; + operator <= "000010"; + wait for 5 ns; + if not (result = std_logic_vector(unsigned(operand1) + unsigned(operand2))) then + write(lineBuffer, string'("Error on Add")); + writeline(output, lineBuffer); + end if; + + -- Sub + wait for 5 ns; + operator <= "000110"; + wait for 5 ns; + if not (result = std_logic_vector(signed(operand1) - signed(operand2))) then + write(lineBuffer, string'("Error on Sub")); + writeline(output, lineBuffer); + end if; + + -- Seq + wait for 5 ns; + operator <= "000011"; + wait for 5 ns; + if not (result = "00000000") then + write(lineBuffer, string'("Error on Set if Equal")); + writeline(output, lineBuffer); + end if; + + -- Slt + wait for 5 ns; + operator <= "000111"; + wait for 5 ns; + if not (result = "00000001") then + write(lineBuffer, string'("Error on Set if Lower")); + writeline(output, lineBuffer); + end if; + + -- Sltu + wait for 5 ns; + operator <= "001011"; + wait for 5 ns; + if not (result = "00000001") then + write(lineBuffer, string'("Error on Set if lower unsigned")); + writeline(output, lineBuffer); + end if; + + write(lineBuffer, string'("End of simulator")); + writeline(output, lineBuffer); + + wait; + end process; + +end Testbench;