end entity beh_alu_tb;
architecture sim of beh_alu_tb is
- component alu is
- port
- (
- sys_clk : in std_logic;
- sys_res_n : in std_logic;
- opcode : in alu_ops;
- op1 : in csigned;
- op2 : in csigned;
- op3 : out csigned;
- 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 sys_clk, sys_res_n, do_calc, calc_done, calc_error : std_logic;
signal opcode : alu_ops;
- signal op1, op2, op3 : csigned;
+ signal op1, op2, op3, opM : csigned;
signal stop : boolean := false;
begin
inst : alu
- port map
- (
+ port map (
sys_clk => sys_clk,
sys_res_n => sys_res_n,
do_calc => do_calc,
op1 => op1,
op2 => op2,
op3 => op3,
- opcode => opcode
+ opM => opM,
+ opcode => opcode,
+ calc_error => calc_error
);
process
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, 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)
+ ( 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),
+ 64 => (-214748364, ALU_DIV, 10, 4, -21474836, false),
+ 65 => (1, ALU_DIV, -2147483648, 1, 0, false),
+ others => (0, ALU_ADD, 0, 0, 0, false)
);
-
+ variable checkall : boolean := true;
begin
-- init & reset
sys_res_n <= '0';
op1 <= (others => '0');
op2 <= (others => '0');
- wait for 300 ns;
+ icwait(sys_clk, 30);
sys_res_n <= '1';
for i in testmatrix'range loop
- wait for 100 ns;
+ icwait(sys_clk, 10);
op1 <= to_signed(testmatrix(i).o1,CBITS);
opcode <= testmatrix(i).o;
op2 <= to_signed(testmatrix(i).o2,CBITS);
-- warten auf die alu einheit
wait on calc_done;
+ icwait(sys_clk, 1);
- assert op3 = 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(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 = 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(op3)) &
+ " ( " & integer'image(to_integer(opM)) & " ) " &
+ " -- erwartet: " & cinteger'image(testmatrix(i).expected) &
+ " ( " & cinteger'image(testmatrix(i).om) & " ) ";
+ checkall := false;
+ else
+ assert(false) report "testfall war ein error (passt)";
+ end if;
+ else
+ if not((op3 = to_signed(testmatrix(i).expected,CBITS)) and (opcode /= ALU_DIV or opM = 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(op3)) &
+ " ( " & integer'image(to_integer(opM)) & " ) " &
+ " -- erwartet: " & cinteger'image(testmatrix(i).expected) &
+ " ( " & cinteger'image(testmatrix(i).om) & " ) ";
- wait for 5 ns;
+ checkall := false;
+ end if;
+ end if;
+
+ 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;