From d983073bec755f5f41ff8a6b31fe01e4b570e9a2 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Fri, 10 Dec 2021 15:38:44 +0100 Subject: [PATCH] ALU testbench --- alu_tb.vhdl | 348 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 261 insertions(+), 87 deletions(-) diff --git a/alu_tb.vhdl b/alu_tb.vhdl index d1d054d..487611c 100644 --- a/alu_tb.vhdl +++ b/alu_tb.vhdl @@ -3,12 +3,14 @@ use ieee.math_real.all; use ieee.numeric_std.all; use ieee.std_logic_1164.all; -entity ALU_tb is -end ALU_tb; +entity ALU is +end ALU; +architecture Structurel of ALU is -architecture Structurel of ALU_tb is - signal op1 : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(32654, 32)); + --! ######## signals for component ######## + + signal op1 : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(32654, 32)); signal op2 : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned(65877, 32)); signal cin : std_logic := '0'; signal cmd : std_logic_vector(1 downto 0) := "00"; @@ -20,94 +22,266 @@ architecture Structurel of ALU_tb is signal vdd : bit := '1'; signal vss : bit := '0'; + --! ######## functions ######## + function bit_to_integer (s : std_logic) return integer is + begin + if s = '1' then + return 1; + else + return 0; + end if; + end function; + begin + alu_0 : entity work.alu(behavioral) + port map( + op1 => op1, + op2 => op2, + res => res, + cin => cin, + cout => cout, + z => z, + n => n, + v => v, + cmd => cmd, + vdd => vdd, + vss => vss + ); + + process + + variable vres : std_logic_vector(31 downto 0); + + variable vtempcin : natural; + variable vtemp : std_logic_vector(32 downto 0); + + variable vcarry_out : std_logic; + variable vz : std_logic; + variable vv : std_logic; + + -- variables for the random number + variable seed1 : positive; + variable seed2 : positive; + variable x : real; + variable y : integer; + + begin + + vdd <= '1'; + + vss <= '0'; + + -- seeds for random number + seed1 := 1; + seed2 := 1; + + cin <= '1'; + vtempcin := 0; + wait for 1 ns; + + -- SUM + cmd <= "00"; + wait for 1 ns; + report "[test_01] addition of 32 random numbers, range between (0 to 536870911)"; + + la : for va in 0 to 31 loop + -- calcul the first random number + uniform(seed1, seed2, x); + y := integer(floor(x * 536870911.0)); + -- assign the random number to op1 + op1 <= std_logic_vector(to_unsigned(y, op1'length)); + + -- calcul the second random number + uniform(seed1, seed2, x); + y := integer(floor(x * 536870911.0)); + -- assign the random number to op2 + op2 <= std_logic_vector(to_unsigned(y, op2'length)); + wait for 1 ns; + vtemp := (std_logic_vector(unsigned("0" & op1) + unsigned("0" & op2) + to_unsigned(bit_to_integer(cin), 1))); + vres := vtemp(31 downto 0); + vcarry_out := vtemp(32); + if vres = x"0" then + vz := '1'; + else + vz := '0'; + end if; + wait for 1 ns; + assert (res = vres) report "[error] resultat of sum. vres = " & integer'image(to_integer(unsigned(vres))) & " versus res = " & integer'image(to_integer(unsigned(res))) + severity error; + assert (bit_to_integer(n) = bit_to_integer(vtemp(31))) report "[error] negative. n = " & integer'image(bit_to_integer(n)) & " versus vn = " & integer'image(bit_to_integer(vtemp(31))) + severity error; + assert (bit_to_integer(cout) = bit_to_integer(vtemp(32))) report "[error] in carry out. cout = " & integer'image(bit_to_integer(cout)) & " versus vcout = " & integer'image(bit_to_integer(vtemp(32))) + severity error; + assert (bit_to_integer(z) = bit_to_integer(vz)) report "[error] z flag. z = " & integer'image(bit_to_integer(z)) & " versus vz = " & integer'image(bit_to_integer(vz)) + severity error; + end loop la; + + report "[test_01] finished"; - ALU_ins: entity work.ALU - port map( - op1 => op1, - op2 => op2, - cin => cin, - cmd => cmd, - res => res, - cout => cout, - z => z, - n => n, - v => v, - vdd => vdd, - vss => vss - ); - - process - begin - - wait for 5 fs; - cmd <= "00"; - wait for 5 fs; - report "op1 = " & integer'image(to_integer(unsigned(op1))); - report "op2 = " & integer'image(to_integer(unsigned(op2))); - report "res = " & integer'image(to_integer(unsigned(res))); - assert z/='1'report "z"; - assert n/='1'report "n"; - assert v/='1'report "v"; - - wait for 5 fs; - - cmd <= "01"; - wait for 5 fs; - report "op1 = " & integer'image(to_integer(unsigned(op1))); - report "op2 = " & integer'image(to_integer(unsigned(op2))); - report "res = " & integer'image(to_integer(unsigned(res))); - assert z/='1'report "z"; - assert n/='1'report "n"; - assert v/='1'report "v"; - - wait for 5 fs; - - cmd <= "10"; - wait for 5 fs; - report "op1 = " & integer'image(to_integer(unsigned(op1))); - report "op2 = " & integer'image(to_integer(unsigned(op2))); - report "res = " & integer'image(to_integer(unsigned(res))); - assert z/='1'report "z"; - assert n/='1'report "n"; - assert v/='1'report "v"; - - wait for 5 fs; - - cmd <= "11"; - wait for 5 fs; - report "op1 = " & integer'image(to_integer(unsigned(op1))); - report "op2 = " & integer'image(to_integer(unsigned(op2))); - report "res = " & integer'image(to_integer(unsigned(res))); - assert z/='1'report "z"; - assert n/='1'report "n"; - assert v/='1'report "v"; - - wait for 5 fs; - cmd <= "00"; - wait for 5 fs; - report "op1 = " & integer'image(to_integer(unsigned(op1))); - report "op2 = " & integer'image(to_integer(unsigned(op2))); - report "res = " & integer'image(to_integer(unsigned(res))); - assert z/='1'report "z"; - assert n/='1'report "n"; - assert v/='1'report "v"; + cin <= '0'; + wait for 1 ns; + report "[test_02] addition of (7fff ffff) + (7fff ffff)"; + op1 <= x"7fffffff"; --(+)2147483647 + op2 <= x"7fffffff"; --(+)2147483647 + wait for 1 ns; + assert (res = x"fffffffe") report "[error] res = " & integer'image(to_integer(unsigned(res))) severity error; + assert (bit_to_integer(cout) = 0) report "cout = " & integer'image(bit_to_integer(cout)) severity error; + assert (bit_to_integer(v) = 1) report "[error] v = " & integer'image(bit_to_integer(v)) severity error; + + report "[test_02] finished"; - wait for 5 fs; - cmd <= "00"; - wait for 5 fs; - report "op1 = " & integer'image(to_integer(unsigned(op1))); - report "op2 = " & integer'image(to_integer(unsigned(op2))); - report "res = " & integer'image(to_integer(unsigned(res))); - assert z/='1'report "z"; - assert n/='1'report "n"; - assert v/='1'report "v"; + wait for 1 ns; + report "[test_03] test overflow, zero and carry in addition (ffff ffff) + (0000 0001)"; + op1 <= x"ffffffff"; + op2 <= x"00000001"; + wait for 1 ns; + assert (res = x"00000000") report "[error] res = " & integer'image(to_integer(unsigned(res))) severity error; + assert (bit_to_integer(z) = 1) report "[error] z = " & integer'image(bit_to_integer(z)) severity error; + assert (bit_to_integer(cout) = 1) report "[error] cout = " & integer'image(bit_to_integer(cout)) severity error; + assert (bit_to_integer(v) = 1) report "[error] v = " & integer'image(bit_to_integer(v)) severity error; + + report "[test_03] finished"; - wait for 50 fs; - wait; - end process; + wait for 1 ns; + report "[test_04] test addition negative number with negative result"; + op1 <= x"0000002a"; -- 42 + op2 <= x"ffffffd3"; -- -45 + wait for 1 ns; + + assert (res = x"fffffffd") report "[error] res = " & integer'image(to_integer(unsigned(res))) severity error; + assert (bit_to_integer(n) = 1) report "[error] n = " & integer'image(bit_to_integer(n)) severity error; + assert (bit_to_integer(z) = 0) report "[error] z = " & integer'image(bit_to_integer(z)) severity error; + assert (bit_to_integer(cout) = 0) report "[error] cout = " & integer'image(bit_to_integer(cout)) severity error; + assert (bit_to_integer(v) = 1) report "[error] v = " & integer'image(bit_to_integer(v)) severity error; + + report "[test_04] finished"; -end Structurel; + + -- AND + wait for 1 ns; + report "[test_05] and of 32 random numbers in a range between (0 to 536870911)"; + cmd <= "01"; + wait for 1 ns; + lb : for vb in 0 to 31 loop + + uniform(seed1, seed2, x); + y := integer(floor(x * 536870911.0)); + + op1 <= std_logic_vector(to_unsigned(y, op1'length)); + + uniform(seed1, seed2, x); + y := integer(floor(x * 536870911.0)); + + op2 <= std_logic_vector(to_unsigned(y, op2'length)); + wait for 1 ns; + vtemp := (("0" & op1) and ("0" & op2)); + vres := vtemp(31 downto 0); + vcarry_out := vtemp(32); + if vres = x"0" then + vz := '1'; + else + vz := '0'; + end if; + wait for 1 ns; + assert (res = vres) report "[error] or vres = " & integer'image(to_integer(unsigned(vres))) & " versus res = " & integer'image(to_integer(unsigned(res))) + severity error; + assert (bit_to_integer(n) = bit_to_integer(vtemp(31))) report "[error] negative. n = " & integer'image(bit_to_integer(n)) & " versus vn = " & integer'image(bit_to_integer(vtemp(32))) + severity error; + assert (bit_to_integer(cout) = bit_to_integer(vtemp(32))) report "[error] carry out. cout = " & integer'image(bit_to_integer(cout)) & " versus vcout = " & integer'image(bit_to_integer(vtemp(32))) + severity error; + assert (bit_to_integer(z) = bit_to_integer(vz)) report "[error] z flag. z = " & integer'image(bit_to_integer(z)) & " versus vz = " & integer'image(bit_to_integer(vz)) + severity error; + end loop lb; + + report "[test_05] finished"; + + + -- OR + wait for 1 ns; + report "[test_06] or of 32 random numbers in a range between (0 to 536870911)"; + cmd <= "10"; + wait for 1 ns; + lc : for vc in 0 to 31 loop + -- calcul the first random number + uniform(seed1, seed2, x); + y := integer(floor(x * 536870911.0)); + -- assign the random number to op1 + op1 <= std_logic_vector(to_unsigned(y, op1'length)); + + -- calcul the second random number + uniform(seed1, seed2, x); + y := integer(floor(x * 536870911.0)); + -- assign the random number to op2 + op2 <= std_logic_vector(to_unsigned(y, op2'length)); + wait for 1 ns; + vtemp := (("0" & op1) or ("0" & op2)); + vres := vtemp(31 downto 0); + vcarry_out := vtemp(32); + if vres = x"0" then + vz := '1'; + else + vz := '0'; + end if; + wait for 1 ns; + assert (res = vres) report "[error] or vres = " & integer'image(to_integer(unsigned(vres))) & " res = " & integer'image(to_integer(unsigned(res))) + severity error; + assert (bit_to_integer(n) = bit_to_integer(vtemp(31))) report "[error] negative. n = " & integer'image(bit_to_integer(n)) & " versus vn = " & integer'image(bit_to_integer(vtemp(32))) + severity error; + assert (bit_to_integer(cout) = bit_to_integer(vtemp(32))) report "[error] carry out. cout = " & integer'image(bit_to_integer(cout)) & " versus cout = " & integer'image(bit_to_integer(vtemp(32))) + severity error; + assert (bit_to_integer(z) = bit_to_integer(vz)) report "[error] z flag. z = " & integer'image(bit_to_integer(z)) & " versus vz = " & integer'image(bit_to_integer(vz)) + severity error; + end loop lc; + + report "[test_06] finished"; + + + -- XOR + wait for 1 ns; + report "[test_07] xor of 32 random numbers in a range between (0 to 536870911)"; + cmd <= "11"; + wait for 1 ns; + ld : for vd in 0 to 31 loop + -- calcul the first random number + uniform(seed1, seed2, x); + y := integer(floor(x * 536870911.0)); + -- assign the random number to op1 + op1 <= std_logic_vector(to_unsigned(y, op1'length)); + + -- calcul the second random number + uniform(seed1, seed2, x); + y := integer(floor(x * 536870911.0)); + -- assign the random number to op2 + op2 <= std_logic_vector(to_unsigned(y, op2'length)); + wait for 1 ns; + vtemp := (("0" & op1) xor ("0" & op2)); + vres := vtemp(31 downto 0); + vcarry_out := vtemp(32); + if vres = x"0" then + vz := '1'; + else + vz := '0'; + end if; + wait for 1 ns; + assert (res = vres) report "[error] xor. vres = " & integer'image(to_integer(unsigned(vres))) & " versus res = " & integer'image(to_integer(unsigned(res))) + severity error; + assert (bit_to_integer(n) = bit_to_integer(vtemp(31))) report "[error] negative. n = " & integer'image(bit_to_integer(n)) & " versus vn = " & integer'image(bit_to_integer(vtemp(32))) + severity error; + assert (bit_to_integer(cout) = bit_to_integer(vtemp(32))) report "[error] carry out. cout = " & integer'image(bit_to_integer(cout)) & " versus vcout = " & integer'image(bit_to_integer(vtemp(32))) + severity error; + assert (bit_to_integer(z) = bit_to_integer(vz)) report "[error] z flag. z = " & integer'image(bit_to_integer(z)) & " versus vz = " & integer'image(bit_to_integer(vz)) + severity error; + end loop ld; + + report "[test_07] finished"; + + + wait for 1 ns; + assert false report "end_of_test" severity note; + + wait; + end process; +end structurel;