Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
709,96 KB
Nội dung
Chapter Fourteen 332 PACKAGE count_types IS SUBTYPE bit8 is INTEGER RANGE 0 to 255; END count_types; LIBRARY IEEE; USE IEEE.std_logic_1164.all; USE work.count_types.all; ENTITY count IS PORT (clk : IN std_logic; ld : IN std_logic; up_dwn : IN std_logic; clk_en : IN std_logic; din : IN bit8; qout : INOUT bit8); END count; ARCHITECTURE synthesis OF count IS SIGNAL count_val : bit8; BEGIN PROCESS(ld, up_dwn, din, qout) BEGIN IF ld = ‘1’ THEN count_val <= din; ELSIF up_dwn = ‘1’ THEN IF (qout >= 255) THEN count_val <= 0; ELSE count_val <= count_val + 1; END IF; ELSE IF (qout <= 0) THEN count_val <= 255; ELSE count_val <= count_val - 1; END IF; END IF; END PROCESS; PROCESS BEGIN WAIT UNTIL clk’EVENT AND clk = ‘1’; IF clk_en = ‘1’ THEN qout <= count_val; END IF; END PROCESS; END synthesis; Package count_types contains the type declaration for the 8-bit signal type used in the counter. The counter is loadable, counts up and down, and contains a clock enable. The counter is implemented as two processes: a 333 CPU: RTL Simulation combinational process and a sequential process. The combinational process calculates the next state of the counter, and the sequential process keeps track of the current state of the counter and updates the next state of the counter on a rising edge of the clk input. We use the counter to dis- cuss a number of different types of testbenches. Stimulus Only The stimulus only testbench contains the stimulus driver and DUT blocks of a testbench. The verification process is left to the designer. This type of testbench is useful at the beginning of a design project when no known good vectors exist, or for a quick check of an entity. Following is an example stimulus only testbench: ENTITY testbench IS END; STIMULUS ONLY testbench for 8-bit loadable counter reads from file “counter.txt” LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE std.textio.ALL; USE ieee.std_logic_textio.all; USE WORK.count_types.all; ARCHITECTURE stimonly OF testbench IS component declaration for counter COMPONENT count PORT (clk : IN std_logic; ld : IN std_logic; up_dwn : IN std_logic; clk_en : IN std_logic; din : IN bit8; qout : INOUT bit8); END COMPONENT; SIGNAL clk, ld, up_dwn, clk_en : std_logic; SIGNAL qout, din : bit8; BEGIN instantiate the component uut: count PORT MAP(clk => clk, ld => ld, up_dwn => up_dwn, Chapter Fourteen 334 clk_en => clk_en, din => din, qout => qout); provide stimulus and check the result test: PROCESS VARIABLE tmpclk, tmpld, tmpup_dwn, tmpclk_en : std_logic; VARIABLE tmpdin : integer; FILE vector_file : text IS IN “counter.txt”; VARIABLE l : line; VARIABLE vector_time : time; VARIABLE r : real; VARIABLE good_number, good_val : boolean; VARIABLE space : character; BEGIN WHILE NOT endfile(vector_file) LOOP readline(vector_file, l); read the time from the beginning of the line skip the line if it doesn’t start with a number read(l, r, good => good_number); NEXT WHEN NOT good_number; vector_time := r * 1 ns; convert real number to time IF (now < vector_time) THEN wait until the vector time WAIT FOR vector_time - now; END IF; read(l, space); skip a space read clk value read(l, tmpclk, good_val); assert good_val REPORT “bad clk value “; read ld value read(l,tmpld, good_val); assert good_val REPORT “bad ld value “; read up_dwn value read(l,tmpup_dwn, good_val); assert good_val REPORT “bad up_dwn value “; read clk_en value read(l,tmpclk_en, good_val); assert good_val REPORT “bad clk_en value “; read(l, space); skip a space 335 CPU: RTL Simulation read din value read(l, tmpdin, good_val); assert good_val REPORT “bad din value “; clk <= tmpclk; ld <= tmpld; up_dwn <= tmpup_dwn; clk_en <= tmpclk_en; din <= tmpdin; END LOOP; ASSERT false REPORT “Test complete”; WAIT; END PROCESS; END; The beginning of the testbench declares entity testbench as an entity with no ports. This is completely legal as the testbench is the topmost en- tity and does not interract with any other entities. Next is the architecture declaration. The architecture uses a number of packages including IEEE standard packages and counter. The next section in the model declares the component for the DUT (Device Under Test), the counter. The ports and types on this component should match the DUT. Next, the local interconnect signals are declared. After the archi- tecture declaration section, the DUT component is instantiated and con- nected to the local interconnect signals. A process called test is declared which contains the stimulus generation capability. First, a number of local variables are declared to receive data from the TextIO procedures used to read the stimulus information from a file. TextIO can only assign to variable objects not signals; therefore, local variables are assigned by the TextIO procedures, and these variables are assigned to the internal interconnect signals. Inside the process is a single while loop that reads data from the stimulus file until an end-of-file condition is reached. Each pass through the loop reads another line from the file and reads the appropriate data from that line. The first data read from the line is the time that this vector is to be applied. The process checks to make sure that the value read is a valid number. If not, the line is discarded because it does not represent a valid stimulus line. This allows comment lines to be inserted in the vector files. If a valid number was not read, the process skips this iteration through the loop and goes to the next iteration using the next clause. If the value read was a good number, then the vector is assumed to be valid. The process reads each data value from the vector and applies the values to the locally declared variables. Chapter Fourteen 336 In the counter example, the first value read is the clk signal. The Tex- tIO statement reads a STD_LOGIC value from line l and assigns the value read to variable tmpclk. Later, the tmpclk variable is assigned to the signal clk. The process continues to read a line, read a time value, wait until that time value occurs, read all vector values, and apply vector values until the end of the file is reached. When the end of the file is reached, the loop terminates, an assertion message is written to standard output, and the process waits forever. The WAIT statement after the assertion at the end of the loop doesn’t have a termination condition and, therefore, waits forever, effectively stopping execution of this process. The TEXTIO readline statement inside the while loop reads a vector line from a vector file. Following is an example vector file: vector file for counter time clk ld up_dwn clk_en din 10 0001 0 20 1101 50 30 0001 0 40 1001 0 50 0001 0 60 1001 0 70 0001 0 80 1001 0 90 0001 0 100 1101 10 110 0001 0 120 1001 0 130 0001 0 140 1001 0 150 0001 0 160 1001 0 The first two lines of the vector file do not start with valid numbers and are treated as comment lines. Comment lines can be embedded anywhere in the file. Comments can also be placed at the end of a vector because any data after the last field of the vector are ignored. Each vector line starts with a time value and then contains a string of values to be assigned to the DUT at that time. Spaces can be embedded between vector values if a corresponding read function exists in the while loop to skip the space. For the stimulus only testbench, the test process reads a vector from the file and applies the stimulus to the DUT. The stimulus only testbench does not check the output results of the DUT in reaction to the applied stimulus. The stimulus only testbench is most useful for a quick check of a piece of a design that is easy for the designer to verify manually or for 337 CPU: RTL Simulation early in the design process when no known good results exist to verify against. When the results are verified, these results become the known good results to verify future versions or minor changes to the design. Full Testbench A full testbench is very similar to a stimulus only testbench except that the full testbench also includes the capability to check the output of the DUT. The full testbench applies the stimulus to the design and then examines the outputs of the design to see if the output results of the DUT match known good results. Following is a full testbench for the counter: ENTITY testbench IS END; FULL TESTBENCH testbench for counter reads from file “counter.txt” LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE std.textio.ALL; USE ieee.std_logic_textio.all; USE WORK.count_types.all; ARCHITECTURE full OF testbench IS component declaration for counter COMPONENT count PORT (clk : IN std_logic; ld : IN std_logic; up_dwn : IN std_logic; clk_en : IN std_logic; din : IN bit8; qout : INOUT bit8); END COMPONENT; SIGNAL clk, ld, up_dwn, clk_en : std_logic; SIGNAL qout, din : bit8; BEGIN instantiate the component uut: count PORT MAP(clk => clk, ld => ld, Chapter Fourteen 338 up_dwn => up_dwn, clk_en => clk_en, din => din, qout => qout); provide stimulus and check the result test: PROCESS VARIABLE tmpclk, tmpld, tmpup_dwn, tmpclk_en : std_logic; VARIABLE tmpqout, tmpdin : bit8; FILE vector_file : text IS IN “counter.txt”; VARIABLE l : line; VARIABLE vector_time : time; VARIABLE r : real; VARIABLE good_number, good_val : boolean; VARIABLE space : character; BEGIN WHILE NOT endfile(vector_file) LOOP readline(vector_file, l); read the time from the beginning of the line skip the line if it doesn’t start with a number read(l, r, good => good_number); NEXT WHEN NOT good_number; vector_time := r * 1 ns; convert real number to time IF (now < vector_time) THEN wait until the vector time WAIT FOR vector_time - now; END IF; read(l, space); skip a space read clk value read(l, tmpclk, good_val); assert good_val REPORT “bad clk value”; read ld value read(l, tmpld, good_val); assert good_val REPORT “bad ld value”; read up_dwn value read(l, tmpup_dwn, good_val); assert good_val REPORT “bad up_dwn value”; read clk_en value read(l, tmpclk_en, good_val); assert good_val REPORT “bad clk_en value”; 339 CPU: RTL Simulation read(l, space); skip a space read din value read(l, tmpdin, good_val); assert good_val REPORT “bad din value”; read(l, space); skip a space the difference in the file is below read good output value read(l, tmpqout, good_val); assert good_val REPORT “bad qout value”; Compare outputs assert tmpqout = qout REPORT “vector mismatch”; clk <= tmpclk; ld <= tmpld; up_dwn <= tmpup_dwn; clk_en <= tmpclk_en; din <= tmpdin; END LOOP; ASSERT false REPORT “Test complete”; WAIT; END PROCESS; END full; The full testbench looks exactly the same as the stimulus only test- bench for most of the file. The full testbench has a top-level entity with no ports, an architecture that instantiates the DUT, and a while loop that reads a vector file. The differences are in the while loop itself. The first part of the while loop is exactly the same. The process reads a time value and waits for that time value to occur. The full testbench is different in that, not only does the full testbench read the input values, but it also reads the output values and then performs a compare operation between the output values from the DUT versus the values read from the file. If a mismatch is found, an assertion message is generated to let the designer know that the output results did not match the known good results. The full testbench also reads from a vector file to get the stimulus for the design and the expected results. The vector file contains a time value, the input values, and the expected output values. Following is the full testbench vector file: vector file for counter time clk ld up_dwn clk_en din dout 0 0001 0 0 10 1001 0 255 Chapter Fourteen 340 20 0101 10 255 30 1001 0 10 40 0001 0 10 50 1001 0 8 60 0001 0 8 70 1001 0 7 80 0001 0 7 90 1001 0 6 100 0101 100 100 110 1001 0 100 120 0001 0 100 130 1001 0 98 140 0001 0 98 150 1001 0 97 160 0001 0 97 Notice that the vector file looks nearly the same as the stimulus only vector file except for the extra columns for the expected results. The full testbench can be used to verify that a DUT matches a specifi- cation. To do so, the specification must include a set of known good results that the testbench can match against. The full testbench can also be used to verify that a small change or optimization still matches the known good results. A designer may find a small error during verification that only requires a small localized change to the design. The designer can make the change and rerun the testbench to make sure that the change did not affect the rest of the design, and that the design still functions properly. Testbenches can also be used to sign off designs. After the design matches the testbench results, the design is ready to be put into production, or be signed off. The stimulus only and full testbench are only a couple examples of the many ways that a testbench can be written. Another example is the simulator-specific testbench. Simulator Specific The simulator-specific testbench is written specifically for one brand of simulator. Most simulators include a command language that allows the designer to control the simulator. The designer can compile designs, load designs, create libraries, set breakpoints, run the simulation, and lots of other tasks using the simulator command language. Most of these sim- ulators also allow the designer to set signals to new values. Using com- mand languages, the designer can write a testbench. Following is an ex- ample of a simulator-specific testbench: 341 CPU: RTL Simulation setup the clock force -repeat 20 clk 0 0, 1 10 log the results to a file list * setup initial signal conditions force ld 0 force up_dwn 0 force clk_en 1 force din 16#00 run the simulation run 100 set next signal conditions force ld 1 force up_dwn 0 force clk_en 1 force din 16#AA run the simulation run 200 set next signal conditions force ld 1 force up_dwn 0 force clk_en 1 force din 16#55 run the simulation run 200 write list data.out quit -f The command language used for this testbench is the Model Technology ModelSim command language. This simulator has a very rich command language that allows the designer to perform all of the necessary operations to compile designs, load designs, debug designs, save designs, and so on. The ModelSim simulator also has the capability to generate repeating clock sig- nals to drive the design. The first command in the testbench file creates a repeating clock for signal clk. The clock repeats every 20 time units and is set to a ‘0’ value at time 0 and a ‘1’ value at time 10. The next command (list *) allows the designer to write all the signal values to an output file. The * specifies that all signals be written to the file. The next few commands in the file set up stimulus values on the counter input signals. The force command sets the signal to a value until it is [...]... : 11 1 16 1 1 1 28 1 16 1 37 11 1 16 1 1 1 28 1 48 3 LCs GND LCs GND VCC Memory Bits shift LCs GND 366 Chapter Fifteen Number of nets : Number of instances : Number of references to this view: 1 98 61 0 total accumulated area: DELAY Number Number Number Number Number Number Number of of of of of of of flex10 GND : LCs : Memory Bits : TRIs : VCC : SHIFT : accumulated instances : 8 x 8 3 98 512 16 1 1 443... Utilization for EP20K200EFC 484 *********************************************** Resource Used Avail Utilization IOs 37 376 9 .84 % LCs 3 98 8320 4. 78% Memory Bits 512 106496 0. 48% Info, Command 'report_area' finished successfully The last step in the synthesis process is to write out a gate-level description for the optimized design For this example the output format... ******************************************************* Cell Library References Total Area GND apex20e 1 x 1 1 GND 364 Chapter Fifteen Figure 15 -8 Optimize Design TRI VCC alu apex20e apex20e work 16 x 1 x 1 x apex20_lcell_normal comp control apex20e work work 33 x 1 x 1 x 1 1 1 156 1 26 1 08 1 1 384 16 1 1 156 33 26 1 08 1 1 384 TRIs VCC GND LCs LCs LCs LCs GND VCC Memory Bits CPU Design: Synthesis Results 365 Figure 15-9 Report Area... std_logic; up_dwn : std_logic; clk_en : std_logic; din : bit8; qout : bit8; END RECORD; TYPE vec_array is array(0 to 8) of stim_vec; VARIABLE stim_array : vec_array := ( (0 ns, ‘0’, ‘0’, ‘1’, 10, 10), (20 ns, ‘1’, ‘0’, ‘1’, 100, 2), (30 ns, ‘0’, ‘0’, ‘1’, 0, 0), (100 ns, ‘1’, ‘0’, ‘1’, 55, 8) , (110 ns, ‘0’, ‘0’, ‘1’, 0, 0), (150 ns, ‘1’, ‘0’, ‘1’, 150, 58) , (160 ns, ‘0’, ‘0’, ‘1’, 0, 151), CPU: RTL Simulation... EP20K200EFC 484 package because this design will be targeted to that device The speed grade determines how fast the device will operate In this example we use the fastest device, the 2X speed grade These settings are shown in Figure 15-2 Finally the target technology is loaded into the synthesis tool by selecting the Load Library button Our next step is to read the VHDL files into the synthesis tool by selecting... description The VHDL design description is optimized and mapped to a programmable logic device As opposed to an ASIC device, these devices can be programmed by designers at their desks, and most can be reprogrammed to fix errors later A synthesis tool is used to read in the VHDL description and map the description to the target programmable logic device The synthesis tool reads all the VHDL source files,... Instruction 354 Figure 14 -8 Branch Instruction execution Figure 14-9 The Source Array Chapter Fourteen CPU: RTL Simulation 355 at 16 Figure 14-10 shows the destination array before the copy operation has completed The destination array starts at location 48 and ends at location 63 The destination array is shown after two copy operations have been performed Notice that location 48 has the first value,... ld, up_dwn => up_dwn, clk_en => clk_en, din => din, qout => qout); generate . 255 30 1001 0 10 40 0001 0 10 50 1001 0 8 60 0001 0 8 70 1001 0 7 80 0001 0 7 90 1001 0 6 100 0101 100 100 110 1001 0 100 120 0001 0 100 130 1001 0 98 140 0001 0 98 150 1001 0 97 160 0001 0 97 Notice. std_logic; clk_en : IN std_logic; din : IN bit8; qout : INOUT bit8); END COMPONENT; SIGNAL clk, ld, up_dwn, clk_en : std_logic; SIGNAL qout, din : bit8; BEGIN instantiate the component uut: count. std_logic; clk_en : IN std_logic; din : IN bit8; qout : INOUT bit8); END COMPONENT; SIGNAL clk, ld, up_dwn, clk_en : std_logic; SIGNAL qout, din : bit8; BEGIN instantiate the component uut: count PORT