Download - Lecture 6 - Writing Tests
EE694v-Verification-Lect6 -1-
Lecture 6 - Writing Tests
• A difference if treating the design as a black box or if you have access to internal signals
• EE762 assignment testbenches treat student design as a black box
• Must know what you are testing
• Must test corner cases
EE694v-Verification-Lect6 -2-
Floating Point Multiplier
• Used as a EE762 assignment
Floating Point Multiplier
A B
C
latch
drive
Project Assignment #10 Floating Pt Unit DUE: Mon Mar 10 In this assignment you will use VHDL to describe the function of a floating point multiplier. The multiplier will accept IEEE Standard 754 single precision inputs and produce single precision output. It will support NaN, ±∞, ±0, normalized numbers, and denormalized numbers. The interface to the design will be:
EE694v-Verification-Lect6 -3-
The Assignment
Inputs will arrive as per the attached specification and test bench. Your design will latch inputs using the latch input signal. Your design will drive the outputs using the drive signal. After driving the output, when the drive signal again goes high, you must drive the bus back to high impedance. Use the component interface given in the testbench
STEP 1) Write the initial architecture. In the initial architecture, simply latch the input, route the A input to the output, and correctly drive the C bus. If you get this step working correctly the rest will go much easier. SIMULATE STEP 2) Write a VHDL process to do the floating point multiply. Recommendation : As you start to write your routine handle special cases first. Write the code to handle the NaNs - then simulate and check that you handle the NaNs correctly. Note that ±∞ * ±0 results in a NaN.. Then correctly handle ±∞, and verify through simulation. Then correctly handle ±0 and simulate. Finally do the cases where you actually have to multiply. You can use process(es), concurrent signal assignment, etc., as you would like.You will find the following files in ~degroat/ee762_assign fpmtb.vhdl - the test bench - the component declaration, configuration,and instantiation have been done but you can change them if you want to. fpmvectors - a list of the input stimul
EE694v-Verification-Lect6 -4-
The Assignment (2)
fpm.do - do file for listing and waveform Other NOTES for floating point multiplier. The test bench also uses a concurrent procedure call that reads the testvector file in ~degroat/ee762_assign/fpmvectors. Use of these vectors is hard coded in the concurrent procedure as are the checks and grading routine. This procedure has been compiled and is in the library assign in this directory. To provide the mapping to it you must execute the unix command qhmap assign /user2/faculty/degroat/ee762_assign/assign This provides the logical mapping such that the library clause in the test bench know where library assign is located. This must be done prior to compiling the test bench. The procedure will also do the grading of this assignment.
EE694v-Verification-Lect6 -5-
Floating Point Standard
Single Precision Floating Point FormatValue is
If e = 255 and f ≠ 0, then v is NaN regardless of s
If e = 255 and f = 0, then v = (-1)s ∞If 0 < e < 255, then v = (-1)s 2e-127 (1.f)If e = 0 and f ≠ 0, then v = (-1)s 2-126 (x.f) (denormalized numbers)(x is msb of value stored)If e = 0 and f = 0, then v = (-1)s 0 (zero)
s e (8 bits) f (23 bits)
31 30 • • • 23 22 • • • 0
EE694v-Verification-Lect6 -6-
Other Specifications
• Inputs are in IEEE 754 Single Precision• Results are in IEEE 754 Single Precision Format• Unit can latch A and B inputs from parallel busses• Must be able to handle both numerical values and
special cases– NaNs, ±inif,
– ±zero,
– ±normalized numbers, ±denormalized numbers
EE694v-Verification-Lect6 -7-
What to Check
• How to test the floating point multiplier for both timing of inputs and outputs and functional operation?
• Assume you have no knowledge of how design is going to be implemented– But you still know the specifications that it
must adhere to.
EE694v-Verification-Lect6 -8-
The Test Vectors
Must test for normal operation and boundary conditions IN GENERAL THE CLASS OF INPUTS ARE:
A input by B inputNaN NaN±∞ ±∞±0 ±0±Denorm ±Denorm±Norm ±Norm
Denorm * OtherVal = Max DenormDenorm * OtherVal = Min Norm• • •
Rounding using first guard bitRounding using 1st and 2nd guart bits
EE694v-Verification-Lect6 -9-
The Inputs – Example 1...NaN 01111111100000000000000000000001...NaN 01111111100000000000000000000001...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001.+INIF 01111111100000000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001.-INIF 11111111100000000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001....+0 00000000000000000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001....-0 10000000000000000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001....+1 00111111100000000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001....-1 10111111100000000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001...+25 01000001110010000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001...-25 11000001110010000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001..+100 01000010110010000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001.1/100 00111100001000111101011100001010...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001+DNORM 00000000001010000000000000000000...Nan 01111111100000000000000000000001...NaN 01111111100000000000000000000001-DNORM 10000000001010000000000000000000...Nan 01111111100000000000000000000001.+INIF 01111111100000000000000000000000...NaN 01111111100000000000000000000001...NaN 01111111100000000000000000000001
EE694v-Verification-Lect6 -10-
The Inputs – Example 2...+25 01000001110010000000000000000000....+0 00000000000000000000000000000000....+0 00000000000000000000000000000000...+25 01000001110010000000000000000000....-0 10000000000000000000000000000000....-0 10000000000000000000000000000000...+25 01000001110010000000000000000000....+1 00111111100000000000000000000000...+25 01000001110010000000000000000000...+25 01000001110010000000000000000000....-1 10111111100000000000000000000000...-25 11000001110010000000000000000000...+25 01000001110010000000000000000000...+25 01000001110010000000000000000000..+625 01000100000111000100000000000000...+25 01000001110010000000000000000000...-25 11000001110010000000000000000000..-625 11000100000111000100000000000000...+25 01000001110010000000000000000000..+100 01000010110010000000000000000000.+2500 01000101000111000100000000000000...+25 01000001110010000000000000000000.1/100 00111100001000111101011100001010.+0.25 00111110011111111111111111111111...+25 01000001110010000000000000000000+DNORM 00000000001010000000000000000000small1 00000001111110100000000000000000...+25 01000001110010000000000000000000-DNORM 10000000001010000000000000000000small2 10000001111110100000000000000000...-25 11000001110010000000000000000000...NaN 01111111100000000000000000000001...NaN 01111111100000000000000000000001...-25 11000001110010000000000000000000.+INIF 01111111100000000000000000000000.-INIF 11111111100000000000000000000000...-25 11000001110010000000000000000000.-INIF 11111111100000000000000000000000.+INIF 01111111100000000000000000000000...-25 11000001110010000000000000000000....+0 00000000000000000000000000000000....-0 10000000000000000000000000000000
EE694v-Verification-Lect6 -11-
Applying Inputs to Design
Inputs are read from a file and applied to the design
WHILE (NOT ENDFILE(test_data)) LOOP --get next input test vector and expected result readline(test_data,cur_line); read(cur_line,aid); read(cur_line,a_test_val); read(cur_line,bid); read(cur_line,b_test_val); readline(test_data,cur_line); read(cur_line,resid);read(cur_line,result_val); std_result_val := To_StdLogicVector(result_val); num_tests := num_tests + 1; -- run through bus cycle to send data to unit aid_sig <= "======", aid after 20 ns; bid_sig <= "======", bid after 20 ns; resid_sig <= "======", resid after 20 ns; -- drive signals on bus aval <= To_StdLogicVector(a_test_val) after 20 ns, HIGHZ after 80 ns; bval <= To_StdLogicVector(b_test_val) after 20 ns, HIGHZ after 80 ns; latch <= '0' after 20 ns, '1' after 70 ns; wait for 100 ns; drive <= '0' after 20 ns, '1' after 80 ns; exp_res <= std_result_val after 20 ns, HIGHZ after 80 ns; wait for 50 ns; ASSERT (C = std_result_val) REPORT "result does not agree with expected result" SEVERITY WARNING; IF (C /= std_result_val) THEN num_errors := num_errors + 1; err_sig <= '1', '0' after 10 ns; END IF; wait for 50 ns; END LOOP;
EE694v-Verification-Lect6 -12-
The File I/O Declarationslibrary ieee, assign; use ieee.std_logic_1164.all; use ASSIGN.fpm_test_vect.all; use STD.TEXTIO.all; entity fpm_test_bench is end fpm_test_bench; architecture my_test of fpm_test_bench is signal A,B,C : std_logic_vector (31 downto 0); signal exp_res : std_logic_vector (31 downto 0); signal latch,drive : std_ulogic := '0'; signal aid_sig, bid_sig, resid_sig : string(1 to 6) := "======"; signal err_sig : bit; signal score : integer := 0; -- Place your component declaration and configuration here component fpm PORT (A,B : IN std_logic_vector (31 downto 0); latch, drive: IN std_ulogic; C : OUT std_logic_vector (31 downto 0)); end component; for all : fpm use ENTITY work.fpm(behavioral); BEGIN -- test architecture -- Instantiate your component here fpm0: fpm PORT MAP(A,B,latch,drive,C); gen_vec(aid_sig,bid_sig,resid_sig,A,B,exp_res,C,latch,drive,err_sig,score); end my_test;
• First must set up the basic declarations
EE694v-Verification-Lect6 -13-
File I/O
• And then must also do the declarations for File I/O
• Note that the file I/O here uses the 1987 version of the language
library ieee; use ieee.std_logic_1164.all; use STD.TEXTIO.all; package fpm_test_vect is constant HIGHZ : std_logic_vector (31 downto 0) := "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; procedure gen_vec (SIGNAL aid_sig,bid_sig,resid_sig : OUT string (1 to 6); SIGNAL aval,bval,exp_res : OUT std_logic_vector (31 downto 0); SIGNAL C : IN std_logic_vector (31 downto 0); SIGNAL latch,drive : OUT std_ulogic; SIGNAL err_sig : OUT bit; SIGNAL score : OUT integer); end fpm_test_vect; package body fpm_test_vect is procedure gen_vec (SIGNAL aid_sig,bid_sig,resid_sig : OUT string (1 to 6); SIGNAL aval,bval,exp_res : OUT std_logic_vector (31 downto 0); SIGNAL C : IN std_logic_vector (31 downto 0); SIGNAL latch,drive : OUT std_ulogic; SIGNAL err_sig : OUT bit; SIGNAL score : OUT integer) is variable cur_line : LINE; file test_data: TEXT is IN "/rcc4/faculty/degroat/ee762_assign/fpmvectors"; variable a_test_val, b_test_val : bit_vector (31 downto 0); variable result_val : bit_vector (31 downto 0); variable std_result_val : std_logic_vector (31 downto 0); variable aid,bid,resid : string (1 to 6); variable num_tests,num_errors : integer := 0;
Text IO after ‘87
• The declaration of the file is the only real change from the 87 standard• Now
– FILE file_name : TEXT OPEN read_mode IS– “the_file_system_file_name’;– VARIABLE cur_line : LINE;– VARIABLE addr : bit_vector (15 downto 0);– VARIABLE data : bit_vector (7 downto 0);
• In the code– WHILE (NOT ENDFILE(file_name)) LOOP
• READLINE (file_name,curline);• READ (curline, addr);• READ (curline, data);• saddr <= addr;• sdata <= data;
– END LOOP;
EE694v-Verification-Lect6 -14-
EE694v-Verification-Lect6 -15-
Checking Results
• Timing is checked when result is expected on bus and again just prior to bus going back to high impedance.
• Busses are also checked that they go back to a value of high impedance
• When results do not match what is expected a signal called error goes to ‘1’ for 10 ns
Use of TEXT IO
• The TEXT IO procedures and functions are in PACKAGE TEXTIO within LIBRARY STD.
• So any design entity that wants to do IO using these routines must have a– USE STD.TEXTIO.ALL;
– You will find a reference in Navabi, pg 603,604.
EE694v-Verification-Lect6 -16-
TEXT IO Philosophy
• The general input/output philosophy of VHDL is one of line orientated operation.
• For Input you first read the entire line up until <cr><lf>– Same for output
• Then you read the elements off the line.– For the file here the elements were– AID A_FP_NUM BID B_FP_NUM
EE694v-Verification-Lect6 -17-
Type that can be read/written using TEXT I/O
• The data types for which support is present– Strings– Bit– Bit_vector– Integer– Real
EE694v-Verification-Lect6 -18-
Example 1
• use std.textio.all;• ENTITY textiotest IS• END textiotest;• • ARCHITECTURE first OF textiotest IS• • FILE test_vecs: TEXT is "fpmvectors";• SIGNAL a,b : bit_vector(31 downto 0);• signal aid,bid : string(1 to 6);
EE694v-Verification-Lect6 -19-
Example 1 (cont)• BEGIN --of architecture• • PROCESS• VARIABLE cur_line : LINE;• VARIABLE aidv,bidv : string(1 to 6);• VARIABLE av,bv : bit_vector(31 downto 0);• • BEGIN• FOR I in 1 to 10 LOOP• READLINE (test_vecs, cur_line);• READ (cur_line,aidv);• aid <= aidv;• READ (cur_line,av);• a <= av;• READ (cur_line,bidv);• bid <= bidv;• READ (cur_line,bv);• b <= bv;• WAIT FOR 100 ns;• END LOOP;• WAIT;• END PROCESS;• • • END first;
EE694v-Verification-Lect6 -20-
Example 2
• use std.textio.all;• ENTITY textiotest2 IS• END textiotest2;• • ARCHITECTURE first OF textiotest2 IS• FILE test_vecs: TEXT is "fpmvectors";• SIGNAL a,b,r : bit_vector(31 downto 0);• signal aid,bid,rid : string(1 to 6);• BEGIN
EE694v-Verification-Lect6 -21-
Example 2 (cont)• PROCESS• VARIABLE cur_line : LINE;• VARIABLE aidv,bidv,ridv : string(1 to 6);• VARIABLE av,bv,rv : bit_vector(31 downto 0);• • BEGIN• WHILE (NOT ENDFILE(test_vecs)) LOOP• READLINE (test_vecs, cur_line);• READ (cur_line,aidv);• aid <= aidv;• READ (cur_line,av);• a <= av;• READ (cur_line,bidv);• bid <= bidv;• READ (cur_line,bv);• b <= bv;• READLINE (test_vecs, cur_line);• READ (cur_line,ridv);• rid <= ridv;• READ (cur_line,rv);• r <= rv;• WAIT FOR 100 ns;• END LOOP;• WAIT;• END PROCESS;• • END first;
EE694v-Verification-Lect6 -22-
Test transactions are in file
• Locating you test transactions in a file allows for easy addition to the test file as you progress through the verification plan
• Allows you to incorporate new tests easily based on the results to date.
• Opens the possibility for very advanced methods– Itterative application of tests and test generation.– New tests may be generated given the response to a
set test.
EE694v-Verification-Lect6 -23-
Text IO Output
• During execution text IO can also write output to file open for output.
• An example of that is in testread.vhdl
EE694v-Verification-Lect6 -24-
Another example
• HDL code that uses TEXTIO to generate an HDL code file.• ENTITY codegen8 IS• END codegen8;• • USE STD.TEXTIO.all;• ARCHITECTURE one OF codegen8 IS• • BEGIN• --Process to automatically generate the dual Gray Code counter descriptions• -- for an 8 bit counter. It is based on the code for generation of the• -- 6 bit dual Gray Code counter with slight modification to the loop indexes.• -- This code is somewhat shorter than the code produced in the output file
EE694v-Verification-Lect6 -25-
The code - Declarations• PROCESS• --declare file • FILE cnt8file : TEXT OPEN write_mode IS "cnt8.vhdl";• • VARIABLE cur_line : LINE;• VARIABLE mytext : STRING (1 to 40);• VARIABLE mytext80 : STRING (1 to 65);• --TYPE cntvectype IS ARRAY(7 downto 0) of bit;• TYPE graycodetype IS ARRAY (0 to 255) OF bit_vector(7 downto 0);• VARIABLE graycode : graycodetype;• VARIABLE l1t1 : STRING (1 to 12) := " WHEN (""";• VARIABLE l1t2 : STRING (1 to 5) := """) =>";• VARIABLE l2t1 : STRING (1 to 22) := " next_state <= """;• VARIABLE l2t2 : STRING (1 to 2) := """;";• VARIABLE blankline : STRING (1 to 5) := " ";• VARIABLE dl2t1 : STRING (1 to 23) := " dnext_state <= """;
EE694v-Verification-Lect6 -26-
Generate 8-bit Gray Code• BEGIN• --generate up to 8 bit GRAY CODE• graycode(0) := "00000000";• graycode(1) := "00000001";• FOR i IN 0 to 1 LOOP --2 bit code - 4 entries• graycode(i+2) := graycode(1-i);• graycode(i+2) := graycode(i+2)(7 downto 2) & "1" & graycode(i+2)(0);• END LOOP;• FOR i IN 0 to 3 LOOP --3 bit code - 8 entries• graycode(i+4) := graycode(3-i);• graycode(i+4) := graycode(i+4)(7 downto 3) & "1" & graycode(i+4)(1 downto 0);• END LOOP;• FOR i IN 0 to 7 LOOP --4 bit code - 16 entries• graycode(i+8) := graycode(7-i);• graycode(i+8) := graycode(i+8)(7 downto 4) & "1" & graycode(i+8)(2 downto 0);• END LOOP;
EE694v-Verification-Lect6 -27-
The Gray Code – 5 to 8 bit• FOR i IN 0 to 15 LOOP --5 bit code - 32 entries• graycode(i+16) := graycode(15-i);• graycode(i+16) := graycode(i+16)(7 downto 5) & "1" & graycode(i+16)(3 downto 0);• END LOOP;• FOR i IN 0 to 31 LOOP --6 bit code - 64 entries• graycode(i+32) := graycode(31-i);• graycode(i+32) := graycode(i+32)(7 downto 6) & "1" & graycode(i+32)(4 downto 0);• END LOOP;• FOR i IN 0 to 63 LOOP --7 bit code - 128 entries• graycode(i+64) := graycode(63-i);• graycode(i+64) := graycode(i+64)(7) & "1" & graycode(i+64)(5 downto 0);• END LOOP;• FOR i IN 0 to 127 LOOP --8 bit code - 256 entries• graycode(i+128) := graycode(127-i);• graycode(i+128) := "1" & graycode(i+128)(6 downto 0);• END LOOP;
EE694v-Verification-Lect6 -28-
Text I/O output the state machine• mytext := "ENTITY cnt8 IS ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " PORT(clk : IN bit; ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " cnt : OUT bit_vector(7 downto 0); ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " dcnt : OUT bit_vector(7 downto 0); ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " err : OUT bit); ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := "END cnt8; ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);
EE694v-Verification-Lect6 -29-
Start output of the architecture
• mytext := "ARCHITECTURE one OF cnt8 IS ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext80 := " SIGNAL state,next_state : bit_vector(7 downto 0) :=
""00000000"";";• WRITE (cur_line,mytext80);• WRITELINE (cnt8file,cur_line);• mytext80 := " SIGNAL dstate,dnext_state : bit_vector(7 downto
0):=""11111111"";";• WRITE (cur_line,mytext80);• WRITELINE (cnt8file,cur_line);• mytext := "BEGIN ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);
EE694v-Verification-Lect6 -30-
The F/F Process• --now output the process for the latching of state• --• mytext := " --Latching logic specification ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " PROCESS ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " BEGIN ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " WAIT UNTIL clk='1' AND clk'event; ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " state <= next_state; ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " dstate <= dnext_state; ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " END PROCESS; ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• mytext := " ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);
EE694v-Verification-Lect6 -31-
To close the output file.
• At the end, after done with all code to output need to close the output file. WAIT stops execution of the PROCESS.
• mytext := "END one; ";• WRITE (cur_line,mytext);• WRITELINE (cnt8file,cur_line);• FILE_CLOSE(cnt8file);• WAIT;• END PROCESS;• • END one; --end the architecture.
EE694v-Verification-Lect6 -32-
More TEXTIO example code
• use std.textio.all;• ENTITY textiotest IS• END textiotest;• • ARCHITECTURE first OF textiotest IS• • FILE test_vecs: TEXT is "fpmvectors";• SIGNAL a,b : bit_vector(31 downto 0);• signal aid,bid : string(1 to 6);
EE694v-Verification-Lect6 -33-
Continued• BEGIN --of architecture
• PROCESS
• VARIABLE cur_line : LINE;
• VARIABLE aidv,bidv : string(1 to 6);
• VARIABLE av,bv : bit_vector(31 downto 0);
• BEGIN
• FOR I in 1 to 10 LOOP
• READLINE (test_vecs, cur_line);
• READ (cur_line,aidv);
• aid <= aidv;
• READ (cur_line,av);
• a <= av;
• READ (cur_line,bidv);
• bid <= bidv;
• READ (cur_line,bv);
• b <= bv;
• WAIT FOR 100 ns;
• END LOOP;
• WAIT;
• END PROCESS;
• END first;
EE694v-Verification-Lect6 -34-
One more time
• use std.textio.all;• ENTITY textiotest2 IS• END textiotest2;• • ARCHITECTURE first OF textiotest2 IS• FILE test_vecs: TEXT is "fpmvectors";• SIGNAL a,b,r : bit_vector(31 downto 0);• signal aid,bid,rid : string(1 to 6);• BEGIN• PROCESS• VARIABLE cur_line : LINE;• VARIABLE aidv,bidv,ridv : string(1 to 6);• VARIABLE av,bv,rv : bit_vector(31 downto 0);
EE694v-Verification-Lect6 -35-
and• BEGIN• WHILE (NOT ENDFILE(test_vecs)) LOOP• READLINE (test_vecs, cur_line);• READ (cur_line,aidv);• aid <= aidv;• READ (cur_line,av);• a <= av;• READ (cur_line,bidv);• bid <= bidv;• READ (cur_line,bv);• b <= bv;• READLINE (test_vecs, cur_line);• READ (cur_line,ridv);• rid <= ridv;• READ (cur_line,rv);• r <= rv;• WAIT FOR 100 ns;• END LOOP;• WAIT;• END PROCESS; • END first;
EE694v-Verification-Lect6 -36-