X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fpost_alu_tb.vhd;h=cf1da2df4aefb9798dafa5d4f82d7cf21adb8107;hb=add09426c37207967bc917a7ada78a05f7c47eb2;hp=39b3b024851d56f2a48a2cd8b802853ddf05bfad;hpb=9d219935f2877488b4e8acd7b6dc5a1d436baf87;p=hwmod.git diff --git a/src/post_alu_tb.vhd b/src/post_alu_tb.vhd index 39b3b02..cf1da2d 100644 --- a/src/post_alu_tb.vhd +++ b/src/post_alu_tb.vhd @@ -7,34 +7,26 @@ entity post_alu_tb is end entity post_alu_tb; architecture sim of post_alu_tb is + -- TODO: braucht man hier wirklich eine andere entity definition? component alu is port ( sys_clk : in std_logic; sys_res_n : in std_logic; - \opcode.NOP\ : in std_logic; - \opcode.SUB\ : in std_logic; - \opcode.ADD\ : in std_logic; - \opcode.MUL\ : in std_logic; - \opcode.DIV\ : in std_logic; - \opcode.DONE\ : 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); + opM : out std_logic_vector(31 downto 0); do_calc : in std_logic; - calc_done : out std_logic + calc_done : out std_logic; + calc_error : out std_logic ); end component alu; - signal sys_clk, sys_res_n, do_calc, calc_done : std_logic; + signal sys_clk, sys_res_n, do_calc, calc_done, calc_error : std_logic; signal opcode : alu_ops; - signal \opcode.NOP\ : std_logic; - signal \opcode.SUB\ : std_logic; - signal \opcode.ADD\ : std_logic; - signal \opcode.MUL\ : std_logic; - signal \opcode.DIV\ : std_logic; - signal \opcode.DONE\ : std_logic; - signal op1, op2, op3 : std_logic_vector(31 downto 0); + signal op1, op2, op3, opM : std_logic_vector((CBITS-1) downto 0); signal stop : boolean := false; begin inst : alu @@ -47,12 +39,9 @@ begin op1 => op1, op2 => op2, op3 => op3, - \opcode.NOP\ => \opcode.NOP\, - \opcode.SUB\ => \opcode.SUB\, - \opcode.ADD\ => \opcode.ADD\, - \opcode.MUL\ => \opcode.MUL\, - \opcode.DIV\ => \opcode.DIV\, - \opcode.DONE\ => \opcode.DONE\ + opM => opM, + opcode => opcode, + calc_error => calc_error ); process @@ -71,56 +60,100 @@ begin o1 : cinteger; o : alu_ops; o2 : cinteger; + om : cinteger; expected : cinteger; + errcase : boolean; end record alu_testv; -- ggf. groesse des arrays erhoehen - type alu_testv_array is array (natural range 0 to 20) of alu_testv; + type alu_testv_array is array (natural range 0 to 65) of alu_testv; variable testmatrix : alu_testv_array := - ( 0 => (-5, DIV, 3, -1), - 1 => (7, ADD, 3, 10), - 2 => (7, SUB, 1, 6), - 3 => (7, DIV, 1, 7), - 4 => (7, DIV, 3, 2), - 5 => (7, ADD, 1, 8), - 6 => (7, MUL, 3, 21), - 7 => (-7, MUL, 3, -21), - 8 => (268435456, MUL, -2, -536870912), - 9 => (268435456, MUL, 2**5, 0), -- um fuenf nach links shiften - 10 => (268435456 + 5, MUL, 2**5, 160), -- = 5 * (2^5) - 11 => (100, DIV, 10, 10), - 12 => (100, DIV, 51, 1), - 13 => (100, DIV, 49, 2), - 14 => (153156, DIV, 3543, 43), - 15 => (-153156, DIV, 3543, -43), - 16 => (153156, DIV, -3543, -43), - 17 => (-153156, DIV, -3543, 43), - others => (0, ADD, 0, 0) + ( 0 => (-5, ALU_DIV, 3, 2, -1, false), + 1 => (7, ALU_ADD, 3, 0, 10, false), + 2 => (7, ALU_SUB, 1, 0, 6, false), + 3 => (7, ALU_DIV, 1, 0, 7, false), + 4 => (7, ALU_DIV, 3, 1, 2, false), + 5 => (7, ALU_ADD, 1, 0, 8, false), + 6 => (7, ALU_MUL, 3, 0, 21, false), + 7 => (-7, ALU_MUL, 3, 0, -21, false), + 8 => (268435456, ALU_MUL, -2, 0, -536870912, false), + 9 => (268435456, ALU_MUL, 2**5, 0, 0, false), -- um fuenf nach links shiften + 10 => (268435456 + 5, ALU_MUL, 2**5, 0, 160, false), -- = 5 * (2^5) + 11 => (100, ALU_DIV, 10, 0, 10, false), + 12 => (100, ALU_DIV, 51, 49, 1, false), + 13 => (100, ALU_DIV, 49, 2, 2, false), + 14 => (153156, ALU_DIV, 3543, 807, 43, false), + 15 => (-153156, ALU_DIV, 3543, 807, -43, false), + 16 => (153156, ALU_DIV, -3543, 807, -43, false), + 17 => (-153156, ALU_DIV, -3543, 807, 43, false), + -- add: sign and under-/overflow check + 18 => (2147483647, ALU_ADD, -1, 0, 2147483646, false), + 19 => (2147483647, ALU_ADD, 1, 0, 0, true), + 20 => (-2147483645, ALU_ADD, -100, 0, 0, true), + 21 => (7, ALU_ADD, 1, 0, 8, false), + 22 => (7, ALU_ADD, -1, 0, 6, false), + 23 => (-7, ALU_ADD, 1, 0, -6, false), + 24 => (-7, ALU_ADD, -1, 0, -8, false), + -- sub: sign and under-/overflow check + 25 => (-7, ALU_SUB, 1, 0, -8, false), + 26 => (-7, ALU_SUB, -1, 0, -6, false), + 27 => (7, ALU_SUB, 1, 0, 6, false), + 28 => (7, ALU_SUB, -1, 0, 8, false), + 29 => (-2147483645, ALU_SUB, 1000, 0, 0, true), + 30 => (2147483645, ALU_SUB, -1000, 0, 0, true), + 31 => (-1000, ALU_SUB, 2147483645, 0, 0, true), + 32 => (1000, ALU_SUB, -2147483645, 0, 0, true), + -- mul: sign and under-/overflow check + 33 => (3, ALU_MUL, 2, 0, 6, false), + 34 => (3, ALU_MUL, -2, 0, -6, false), + 35 => (-3, ALU_MUL, 2, 0, -6, false), + 36 => (-3, ALU_MUL, -2, 0, 6, false), + 37 => (90000, ALU_MUL, 100000, 0, 0, true), + 38 => (90000, ALU_MUL, -100000, 0, 0, true), + 39 => (-90000, ALU_MUL, 100000, 0, 0, true), + 40 => (-90000, ALU_MUL, -100000, 0, 0, true), + -- div: overflow check und division durch null + 41 => (-2147483648, ALU_DIV, -1, 0, 0, true), + 42 => (-2147483648, ALU_DIV, 0, 0, 0, true), + 43 => (-4, ALU_DIV, 2, 0, -2, false), + -- div/mod: + 44 => (1234, ALU_DIV, 3, 1, 411, false), + 45 => (1, ALU_DIV, 10, 1, 0, false), + 46 => (2, ALU_DIV, 10, 2, 0, false), + 47 => (3, ALU_DIV, 10, 3, 0, false), + 48 => (4, ALU_DIV, 10, 4, 0, false), + 49 => (5, ALU_DIV, 10, 5, 0, false), + 50 => (6, ALU_DIV, 10, 6, 0, false), + 51 => (7, ALU_DIV, 10, 7, 0, false), + 52 => (8, ALU_DIV, 10, 8, 0, false), + 53 => (9, ALU_DIV, 10, 9, 0, false), + 54 => (0, ALU_DIV, 10, 0, 0, false), + 55 => (10, ALU_DIV, 10, 0, 1, false), + 56 => (5134123, ALU_DIV, 358015, 121913, 14, false), + -- extra + 60 => (5, ALU_SUB, -2147483648, 0, 0, true), + 61 => (-2147483647, ALU_SUB, 1, 0, -2147483648, false), + 62 => (-2147483647, ALU_ADD, -1, 0, -2147483648, false), + 63 => (-2147483648, ALU_DIV, 10, 8, -214748364, false), + others => (0, ALU_ADD, 0, 0, 0, false) ); - + variable checkall : boolean := true; begin + -- init & reset sys_res_n <= '0'; - wait for 50 ns; + 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 - wait for 100 ns; - \opcode.NOP\ <= '0'; - \opcode.SUB\ <= '0'; - \opcode.ADD\ <= '0'; - \opcode.MUL\ <= '0'; - \opcode.DIV\ <= '0'; - \opcode.DONE\ <= '0'; + icwait(sys_clk, 10); op1 <= std_logic_vector(to_signed(testmatrix(i).o1,CBITS)); - case testmatrix(i).o is - when NOP => \opcode.NOP\ <= '1'; - when SUB => \opcode.SUB\ <= '1'; - when ADD => \opcode.ADD\ <= '1'; - when MUL => \opcode.MUL\ <= '1'; - when DIV => \opcode.DIV\ <= '1'; - when DONE => \opcode.DONE\ <= '1'; - end case; + opcode <= testmatrix(i).o; op2 <= std_logic_vector(to_signed(testmatrix(i).o2,CBITS)); -- berechnung kann los gehen @@ -128,21 +161,42 @@ begin -- 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) & - " " & alu_ops'image(opcode) & - " " & cinteger'image(testmatrix(i).o2) & - "/= " & integer'image(to_integer(signed(op3))) & - " -- erwartet: " & cinteger'image(testmatrix(i).expected); + if testmatrix(i).errcase then + if (calc_error = '0') then + assert(false) report "sollte ein error sein"; + 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); + checkall := false; + else + assert(false) report "testfall war ein error (passt)"; + end if; + else + if not((op3 = std_logic_vector(to_signed(testmatrix(i).expected,CBITS))) and (opcode /= ALU_DIV or opM = std_logic_vector(to_signed(testmatrix(i).om,CBITS)))) then + assert(false) 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); + checkall := false; + end if; + end if; - wait for 5 ns; + icwait(sys_clk, 2); -- ack it! do_calc <= '0'; end loop; - assert false + if checkall then report "alle testfaelle der ALU waren erfolgreich!"; + else + report "einige testfaelle schlugen fehl"; + end if; stop <= true; wait; end process;