Om de juiste werking van de ALU te verifiëren, wordt er opnieuw gebruikt gemaakt van een testbench. Het is een goed idee om tijdens het ontwikkelen van de ALU meteen de functionaliteit te testen. Hiervoor kunnen er heel gericht bepaalde instructies ingesteld worden. Bijvoorbeeld:
Om 12 + 3 te doen weet je dat inputs de volgende moeten zijn:
De uitgangen van de ALU moeten de volgende zijn:
Op deze manier kan je stapsgewijs de testbench opbouwen. Geef hierbij extra aandacht aan de randgevallen. Als jouw implementatie 12 + 3 correct kan berekenen, is de kans groot dat 13 + 3 ook wel zal lukken. De randgevallen zijn het echter wel waard om expliciet te testen. Kan jouw ALU 0xFFFFFFFF + 0xFFFFFFFF correct berekenen? Of -1 - (-1)?
PSTIM: process
begin
operand1 <= x"0000000C";
operand2 <= x"00000003";
ALUOp <= "100";
arith_logic_b <= '0';
signed_unsigned_b <= '0';
wait for 2 ns;
-- check outputs
if result /= x"0000000F" then
bad_checks := bad_checks + 1;
else
good_checks := good_checks + 1;
end if;
if equal /= '0' then
bad_checks := bad_checks + 1;
else
good_checks := good_checks + 1;
end if;
if x_lt_y_u /= '0' then
bad_checks := bad_checks + 1;
else
good_checks := good_checks + 1;
end if;
if x_lt_y_s /= '0' then
bad_checks := bad_checks + 1;
else
good_checks := good_checks + 1;
end if;
wait for 2 ns;
wait;
end process;
Wanneer je denkt alle implementaties gedaan te hebben, kan je een grotere testbench los laten op jouw design. Een voorbeeld hiervan kan je hier downloaden. Deze testbench is, zoals je misschien al vermoedde, gegenereerd. Voor de verbetering van de opdracht wordt een soortgelijke testbench gebruikt.
...
operand1 <= x"8ffb9e07"; -- 2415631879
operand2 <= x"fdcea5ee"; -- 4258178542
ALUOp <= "000";
arith_logic_b <= '0';
signed_unsigned_b <= '0';
wait for 2 ns;
-- check outputs
if result /= x"8dca8406" then
bad_checks := bad_checks + 1;
else
good_checks := good_checks + 1;
end if;
if equal /= '0' then
bad_checks := bad_checks + 1;
else
good_checks := good_checks + 1;
end if;
if x_lt_y_u /= '1' then
bad_checks := bad_checks + 1;
else
good_checks := good_checks + 1;
end if;
if x_lt_y_s /= '1' then
bad_checks := bad_checks + 1;
else
good_checks := good_checks + 1;
end if;
wait for 2 ns;
...
report "DISCH_GRADING (good, bad, total): " & integer'image(good_checks) & " " & integer'image(bad_checks) & " " & integer'image(good_checks + bad_checks) & "" severity note;
...
Deze aangeleverde testbench controleert ook of de uitgang gelijk is aan de “juiste” uitgang. Hiervoor moet het resultaat kloppen, maar ook de relevante flags.
Na 2 ns wordt elke uitgange vergeleken en wordt ofwel de good_checks teller ofwel de bad_checks teller verhoogd. Op het einde van de testbench worden deze tellers en hun som in de console geprint om een overzicht te krijgen.
Voor de verbetering van deze taak wordt een soortgelijke testbench gebruikt. Er wordt enkel gekeken naar de rapportering.