CMPUT329 - Fall 2003 Topic 6: Testbenches Paras Mehta and José Nelson Amaral CMPUT 329 - Computer Organization and Architecture II 1 Why Use Testbenches? ● Manually Driven Simulation ● ● specify inputs and observe outputs advantage ● ● allows testing without downloading to device disadvantage ● can only test a few combinations of input CMPUT 329 - Computer Organization and Architecture II 2 Why Use Testbenches? ● Testbenches ● ● a programmed thorough test of design advantages ● ● ● test design without downloading to board can program a test of all inputs as well automatically check expected behaviour disadvantages ● ● cannot test all functionality (e.g. keyboard) cannot determine/resolve timing issues CMPUT 329 - Computer Organization and Architecture II 3 Testbench Structure ● ● ● Testbench is self-contained Internal signals are directly manipulated Elements: ● ● ● ● entity contains no ports declare, instantiate testing components process for supplying input process for checking output CMPUT 329 - Computer Organization and Architecture II 4 Testbench Structure Testbench clk reset input_1 input_2 ... input_n Unit Under Test output_1 output_2 ... output_n Manipulated by Testbench Checked by Testbench CMPUT 329 - Computer Organization and Architecture II 5 Testbench Structure ● Basic signals are clock, reset, and termination: architecture behaviour of testbench is signal clk, rst : std_logic; signal done : boolean; constant clk_period : time := 5 ns; begin ...... done clk rst <= <=<= '1', '0' true when when rst =condition '1' else else false; '0' notafter clk after time;clk_period when not done ... else '0'; Reset: Condition Clk: indicates simulation is over. e.g: • brief timeactive not period pulseduring for hasreset elapsed reset of all • oscillates signals iterations in the completed until design done • end of input file reached end architecture; CMPUT 329 - Computer Organization and Architecture II 6 Manipulating Input ● Input set as normal signal assignment operand1 ALU operand2 alu_result input: process() begin operand1 <= “000”; operand2 <= “101”; opcode <= “100”; end process; opcode CMPUT 329 - Computer Organization and Architecture II 7 Checking Output ● Output read as a normal signal read ● Checking done with assert-report-severity Syntax: assert condition report debug-string severity note | warning | error | failure; CMPUT 329 - Computer Organization and Architecture II 8 Checking Output ● Output read as a normal signal read ● Checking done with assert-report-severity Falling edge allows signal to be checked verify: process(output) begin if clk'event and clk = '0' then if (opcode = AND_OP) assert (alu_result = operand1 and operand2) report “Output is incorrect” severity error; end if; end if; end process; CMPUT 329 - Computer Organization and Architecture II 9 File Input ● ● Using assert to check behaviour implies writing correct behaviour twice Instead, write expected behaviour in file: Testbench Unit Under Test Output Assert Expected Output CMPUT 329 - Computer Organization and Architecture II 10 File Input ● Require file and line variables: InputProcess: process (clk) file input : text is “input.txt”; std.textio.all; variable line_in: line; variable op1_in, op2_in : ieee.std_logic_textio.all; std_logic_vector(3 downto 0); begin readline(file, line) if clk'event and clk='1' then if not endfile(input) then read(line, variable) readline(input, line_in); read(line_in, op1_in); hread(line, variable) read(line_in, op2_in); operand1 <= op1_in; operand2 <= op2_in; end if; CMPUT 329 end - Computer if; 11 Organization and Architecture end process; II File Input ● Require file and line variables: operand1 ALU operand2 opcode CheckProcess: process (clkt) file output1 : text is “output.txt”; variable line_in: line; alu_result variable o_exp : std_logic; begin if clk'event and clk='0' then if not endfile(output1) then readline(output1, line_in); read(line_in, o_exp); assert (o_exp = alu_result) report “Output incorrect” severity error; end if; if; CMPUT 329 end - Computer 12 Organization and Architecture end process; II Debug Output ● Lines can also be used to write to std_out: operand1 ALU operand2 opcode CheckProcess: process(clk) variable line_out: line; begin alu_result if clk'event and clk = '1' then write(line_out, string'(“At time ”)); write(line_out, now); write(line_out, string'(“, output is ”)); write(line_out, alu_result; writeline(output, line_out); end if; end process; CMPUT 329 - Computer Organization and Architecture II 13