library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.gen_pkg.all; entity post_alu_tb is end entity post_alu_tb; architecture sim of post_alu_tb is component alu is port ( sys_clk : in std_logic; sys_res_n : in std_logic; opcode : in alu_ops; op1 : in std_logic_vector(31 downto 0); op2 : in std_logic_vector(31 downto 0); op3 : out std_logic_vector(31 downto 0); do_calc : in std_logic; calc_done : out std_logic ); end component alu; signal sys_clk, sys_res_n, do_calc, calc_done : std_logic; signal opcode : alu_ops; signal op1, op2, op3 : std_logic_vector(31 downto 0); signal stop : boolean := false; begin inst : alu port map ( sys_clk => sys_clk, sys_res_n => sys_res_n, do_calc => do_calc, calc_done => calc_done, op1 => op1, op2 => op2, op3 => op3, opcode => opcode ); process begin sys_clk <= '0'; wait for 15 ns; sys_clk <= '1'; wait for 15 ns; if stop = true then wait; end if; end process; process type alu_testv is record o1 : cinteger; o : alu_ops; o2 : cinteger; expected : cinteger; end record alu_testv; -- ggf. groesse des arrays erhoehen type alu_testv_array is array (natural range 0 to 20) of alu_testv; variable testmatrix : alu_testv_array := ( 0 => (-5, ALU_DIV, 3, -1), 1 => (7, ALU_ADD, 3, 10), 2 => (7, ALU_SUB, 1, 6), 3 => (7, ALU_DIV, 1, 7), 4 => (7, ALU_DIV, 3, 2), 5 => (7, ALU_ADD, 1, 8), 6 => (7, ALU_MUL, 3, 21), 7 => (-7, ALU_MUL, 3, -21), 8 => (268435456, ALU_MUL, -2, -536870912), 9 => (268435456, ALU_MUL, 2**5, 0), -- um fuenf nach links shiften 10 => (268435456 + 5, ALU_MUL, 2**5, 160), -- = 5 * (2^5) 11 => (100, ALU_DIV, 10, 10), 12 => (100, ALU_DIV, 51, 1), 13 => (100, ALU_DIV, 49, 2), 14 => (153156, ALU_DIV, 3543, 43), 15 => (-153156, ALU_DIV, 3543, -43), 16 => (153156, ALU_DIV, -3543, -43), 17 => (-153156, ALU_DIV, -3543, 43), others => (0, ALU_ADD, 0, 0) ); variable checkall : boolean := true; begin -- init & reset sys_res_n <= '0'; do_calc <= '0'; opcode <= ALU_NOP; op1 <= (others => '0'); op2 <= (others => '0'); icwait(sys_clk, 30); sys_res_n <= '1'; for i in testmatrix'range loop icwait(sys_clk, 10); op1 <= std_logic_vector(to_signed(testmatrix(i).o1,CBITS)); opcode <= testmatrix(i).o; op2 <= std_logic_vector(to_signed(testmatrix(i).o2,CBITS)); -- berechnung kann los gehen do_calc <= '1'; -- warten auf die alu einheit wait on calc_done; icwait(sys_clk, 1); assert op3 = std_logic_vector(to_signed(testmatrix(i).expected,CBITS)) report "" & cinteger'image(testmatrix(i).o1) & " " & integer'image(to_integer(signed(opcode))) & " " & cinteger'image(testmatrix(i).o2) & "/= " & integer'image(to_integer(signed(op3))) & " -- erwartet: " & cinteger'image(testmatrix(i).expected); if op3 /= std_logic_vector(to_signed(testmatrix(i).expected,CBITS)) then checkall := false; end if; icwait(sys_clk, 2); -- ack it! do_calc <= '0'; end loop; if checkall then report "alle testfaelle der ALU waren erfolgreich!"; else report "nicht alle testfaelle der ALU waren erfolgreich!"; end if; stop <= true; wait; end process; end architecture sim;