280 likes | 506 Views
Lecture 11 Chap 13: Test Benches. Instructors: Fu-Chiung Cheng ( 鄭福炯 ) Associate Professor Computer Science & Engineering Tatung University. Test Benches. Most hardware description languages: Circuit description and test waveforms are described in different ways.
E N D
Lecture 11Chap 13: Test Benches Instructors: Fu-Chiung Cheng (鄭福炯) Associate Professor Computer Science & Engineering Tatung University
Test Benches • Most hardware description languages: • Circuit description and test waveforms are described • in different ways. • VHDL: the language itself can be used to express the • testing waveforms. (called test benches.) • Test benches: a VHDL model that generates waveforms • with which to test a circuit (VHDL) model. • Test benches is used only in simulation, • not for synthesized.
Test Benches • A synthesizable model should be extensively tested in • simulation before synthesis to ensure correctness. • WYSISYG: what you simulate is what you get. • Any errors in the design will be faithfully synthesized • as errors in the final circuit. • (Testing is very important…) • Diagnosing errors in synthesizer-generated netlists is • almost impossible. • Because test benches are not synthesized, the full scope • of VHDL language is available for writing them.
Combinational Test Benches • How to write a test bench for combinational circuits. • (use testing a MUX (2x1 multiplexer) as an example) • 1. Define an empty entity: • entity mux_test is • end; • 2. Create an architecture • with the under-test component instance. • 3. Produce test patterns: • 4. Write a process to test the circuit by applying • the test patterns: Gen inputs mux
Combinational Test Benches 2. Create an architecture with the under-test component instance. library ieee; use ieee.std_logic_1164.all; architecture test_bench of mux_test is component mux; port (in0,in1,sel:in std_logic; z: out std_logic; end component; for all: mux use work.mux; signal in0, in1, sel, z:std_logic; begin CUT: mux port map(in0,in1,sel,z); end;
Combinational Test Benches 3. Produce test patterns: type sample is record in0: std_logic; in1: std_logic; sel: std_logic; end; type sample_array is array (natural range <>) of sample; constant test_data: sample_array := ( (‘0’,’0’,’0’), (‘0’,’0’,’1’), (‘0’,’1’,’0’), (‘0’,’1’,’1’), (‘1’,’0’,’0’), (‘1’,’0’,’1’), (‘1’,’1’,’0’), (‘1’,’1’,’1’) );
Combinational Test Benches 4. Write a process to test the circuit by applying the test patterns: process begin for i in test_data’range loop in0 <=test_data(i).in0; in1 <=test_data(i).in1; sel <=test_data(i).sel; wait for 10ns; end loop; wait; end process;
entity mux_test is end; library ieee; use ieee.std_logic_1164.all; architecture test_bench of mux_test is type sample is record in0: std_logic; in1: std_logic; sel: std_logic; end; type sample_array is array (natural range <>) of sample; constant test_data: sample_array := ( (‘0’,’0’,’0’), (‘0’,’0’,’1’), (‘0’,’1’,’0’), (‘0’,’1’,’1’), (‘1’,’0’,’0’), (‘1’,’0’,’1’), (‘1’,’1’,’0’), (‘1’,’1’,’1’) );
component mux; port (in0,in1,sel:in std_logic; z: out std_logic; end component; for all: mux use work.mux; signal in0, in1, sel, z:std_logic; begin process for i in test_data’range loop in0 <=test_data(i).in0; in1 <=test_data(i).in1; sel <=test_data(i).sel; wait for 10 ns; end loop; wait; end process; CUT: mux port map(in0,in1,sel,z); end;
Combinational Test Benches: verifying responses • Check the correctness through outputs • Response data: • type sample is record • in0: std_logic; • in1: std_logic; • sel: std_logic; • z: std_logic; • end; • constant test_data: sample_array := • ( (‘0’,’0’,’0’,’0’), (‘0’,’0’,’1’,’0’), (‘0’,’1’,’0’,’0’), (‘0’,’1’,’1’,’1’), • (‘1’,’0’,’0’,’1’), (‘1’,’0’,’1’,’0’), (‘1’,’1’,’0’,’1’), (‘1’,’1’,’1’,’1’) • );
Combinational Test Benches: verifying responses • Check the correctness through outputs • Response data: • type sample is record • in0: std_logic; • in1: std_logic; • sel: std_logic; • z: std_logic; • end; • constant test_data: sample_array := • ( (‘0’,’0’,’0’,’0’), (‘0’,’0’,’1’,’0’), (‘0’,’1’,’0’,’0’), (‘0’,’1’,’1’,’1’), • (‘1’,’0’,’0’,’1’), (‘1’,’0’,’1’,’0’), (‘1’,’1’,’0’,’1’), (‘1’,’1’,’1’,’1’) • );
Combinational Test Benches: verifying responses • Check the response • process • for i in test_data’range loop • in0 <=test_data(i).in0; • in1 <=test_data(i).in1; • sel <=test_data(i).sel; • wait for 10ns; • assert z = test_data(i).z • report “output z is wrong!” • severity error; • end loop; • wait; • end process;
Test Benches: Clock & Reset • A simple clocked circuit:
Test Benches: Clock & Reset • under-test component instance: • library ieee; • use ieee.std_logic_1164.all; • architecture test_bench of Dmux_test is • component Dmux; • port (in0,in1,sel,ck:in std_logic; z: out std_logic; • end component; • for all: Dmux use work.Dmux; • signal in0, in1, sel, ck, z:std_logic; • begin • CUT: Dmux port map(in0,in1,sel, ck, z); • end;
Test Benches: Clock & Reset • Check the response • process • for i in test_data’range loop • in0 <=test_data(i).in0; • in1 <=test_data(i).in1; • sel <=test_data(i).sel; • ck <=‘0’; wait for 5 ns; • ck <=‘1’; wait for 5 ns; • assert z = test_data(i).z • report “output z is wrong!” • severity error; • end loop; • wait; • end process;
Test Bench: count_ones architecture behavior of count_ones is process (vec) variable result: unsigned(4 downto 0); begin result := to_unsigned(0, result’length)); for i in vec’range loop next when vec(i) = ‘0’; result = result +1; end loop count <= result; end process; end;
Test Bench: count_ones • input and output of count_ones is vectors: • Vec: std_logic_vector(15 downto 0); • count: std_logic_vector(4 downto 0);
Test Bench: count_ones • under-test component instance: • library ieee; • use ieee.std_logic_1164.all; • architecture test_bench of count_ones_test is • component count_ones • port (vec:in std_logic_vector(15 downto 0); • count: out std_logic_vector(4 downto 0); • end component; • for all: count_ones use work.count_ones; • signal vec: std_logic_vector(15 downto 0); • signal count: std_logic_vector(4 downto 0); • begin • CUT: count_ones port map(vec, count); • end;
Test Bench: count_ones • Check the correctness through outputs • Response data: • type sample is record • vec:in std_logic_vector(15 downto 0); • count: out std_logic_vector(4 downto 0); • end; • type sample_array is array (natural range <>) of sample; • constant test_data: sample_array := • ( (“0000000000000000”, “00000”), • (“0000000000001111”, “00100”), • …. • );
Test Bench: count_ones • Response data with Hexadecimal: • type sample is record • vec:in std_logic_vector(15 downto 0); • count: out std_logic_vector(4 downto 0); • end; • type sample_array is array (natural range <>) of sample; • constant test_data: sample_array := • ( (X“0000”, “00000”), • (X“000F”, “00100”), • …. • );
Test Bench: count_ones • Response data with Hexadecimal input, integer output: • type sample is record • vec:in std_logic_vector(15 downto 0); • count: out integer; • end; • type sample_array is array (natural range <>) of sample; • constant test_data: sample_array := • ( (X“0000”, 0), • (X“000F”, 4), • …. • );
Test Bench: count_ones • Check the response • process • for i in test_data’range loop • vec <=test_data(i).vec; • wait for 10ns; • assert count = to_unsigned(test_data(i).count, • count’length) • report “output count is wrong!” • severity error; • end loop; • wait; • end process;
Test Bench: Don’t care • Many circuits do not generate valid outputs on very • clock cycle. • Example: pipeline • Test benches need to ignore the invalid outputs and • check only valid outputs. • 1. Use extra field to indicates an valid or invalid output • the field’s type is boolean. • 2. Use don’t care.
Test Bench: invalid output • Circuit to be tested: • 1-bit register in the 3rd pipeline stage • library ieee; • use ieee.std_logic_1164.all; • entity delay3 is • port (d, ck: in std_logic, q: out std_logic); • end; • Sample record: • type sample is record • d: std_logic; • q: std_logic; • valid: boolean; • end record;
Test Bench: invalid output • Test patten: • constant test_data: sample_array:= • ( • (‘1’,’0’,false), • (‘0’,’0’,false), • (‘1’,’1’,true), • … ); • test statement: • if test_data(i).valid then • assert test_data(i).q = q • report “q is wrong”; • severity error; • end if;
Test Bench: don’t care output • Test patten: • constant test_data: sample_array:= • ( • (‘1’,’-’), • (‘0’,’-’), • (‘1’,’1’), • … ); • test statement: • assert std_match(test_data(i).q, q) • report “q is wrong”; • severity error;
Print Response values • It is useful to print out the expected and actual values. • A function converting std_logic to string: • function toString(arg:std_logic) return string is • begin • case arg is • when ‘U’ return “U”; when ‘X’ return “X”; • when ‘0’ return “0”; when ‘1’ return “1”; • when ‘W’ return “W”; when ‘L’ return “L”; • when ‘H’ return “H”; when ‘Z’ return “Z”; • when ‘-’ return “-”; • end case; • end;
Print Response values • The assertion statement: • assert test_data(i).q = q; • report “q:expected =“ & toString(test_data(i).q) & • “, actural =“ & toString(q) • severity error; • See page 291-297 for predefined conversion functions.