Run the Simulation Again What Is the Value of Tb alu result for This Instruction
9. Testbenches¶
9.1. Introduction¶
In previous chapters, we generated the simulation waveforms using modelsim, by providing the input signal values manually; if the number of input signals are very large and/or nosotros accept to perform simulation several times, then this process can be quite complex, fourth dimension consuming and irritating. Suppose input is of ten chip, and we want to test all the possible values of input i.e. \(two^{10}-1\), then information technology is impossible to do it manually. In such cases, testbenches are very useful; likewise, the tested designs are more reliable and prefer by the clients as well. Farther, with the aid of testbenches, we can generate results in the form of csv (comma separated file), which can be used by other softwares for further analysis e.1000. Python, Excel and Matlab etc.
Since testbenches are used for simulation purpose only (not for synthesis), therefore total range of Verilog constructs can be used e.g. keywords 'for', 'display' and 'monitor' etc. can be used for writing testbenches.
Important
Modelsim-project is created in this chapter for simulations, which allows the relative path to the files with respect to project directory as shown in Section 9.3.i. Simulation tin be run without creating the projection, but we need to provide the total path of the files as shown in Line 25 of List 9.four.
Lastly, mixed modeling is non supported past Altera-Modelsim-starter version, i.e. Verilog designs with VHDL and vice-versa can non be compiled in this version of Modelsim. For mixed modeling, nosotros can use Agile-HDL software equally discussed in Affiliate Department 2.
9.two. Testbench for combinational circuits¶
In this section, various testbenches for combinational circuits are shown, whereas testbenches for sequential circuits are discussed in adjacent section. For simplicity of the codes and better understanding, a elementary half adder circuit is tested using diverse simulation methods.
nine.2.1. Half adder¶
Listing ix.one shows the Verilog code for the half adder which is tested using different methods,
ane 2 3 4 5 six 7 8 9 x 11 12 | // half_adder.v module half_adder ( input wire a , b , output wire sum , carry ); assign sum = a ^ b ; assign acquit = a & b ; endmodule |
9.3. Testbench with 'initial block'¶
Note that, testbenches are written in carve up Verilog files as shown in Listing nine.2. Simplest way to write a testbench, is to invoke the 'design for testing' in the testbench and provide all the input values within the 'initial cake', as explained below,
Caption Listing 9.2
In this listing, a testbench with proper name 'half_adder_tb' is divers at Line five. Annotation that, ports of the testbench is e'er empty i.e. no inputs or outputs are defined in the definition (see Line five). Then 4 signals are defined i.east. a, b, sum and carry (Lines 7-eight); these signals are then connected to bodily one-half adder design using structural modeling (see Line 13). Lastly, different values are assigned to input signals e.grand. 'a' and 'b' at lines xviii and 19 respectively.
Notation
'Initial block' is used at Line fifteen, which is executed merely once, and terminated when the concluding line of the block executed i.e. Line 32. Hence, when we press run-all push button in Fig. 9.i, then simulation terminated after threescore ns (i.due east. does non run forever).
In Line 19, value of 'b' is 0, then information technology changes to '1' at Line 23, after a delay of 'period' divers at Line 20. The value of menstruation is '20 (Line 11) * timescale (Line 3) = 20 ns'. In this list all the combinations of inputs are defined manually i.e. 00, 01, 10 and 11; and the results are shown in Fig. 9.1, as well corresponding outputs i.due east. sum and carry are shown in the figure.
Note
To generate the waveform, first compile the 'half_adder.v and and so 'half_adder_tb.v' (or compile both the file simultaneously.). So simulate the half_adder_tb.v file. Finally, click on 'run all' push button (which volition run the simulation to maximum time i.e. fourscore ns)and and so click and then 'zoom full' button (to fit the waveform on the screen), as shown in Fig. 9.i.
i 2 3 4 5 6 7 8 nine 10 xi 12 13 xiv 15 16 17 xviii nineteen twenty 21 22 23 24 25 26 27 28 29 30 31 32 33 34 // half_adder_tb.v `timescale 1 ns / 10 ps // time-unit = i ns, precision = ten ps module half_adder_tb ; reg a , b ; wire sum , bear ; // duration for each flake = twenty * timescale = twenty * ane ns = 20ns localparam catamenia = 20 ; half_adder UUT (. a ( a ), . b ( b ), . sum ( sum ), . carry ( behave )); initial // initial cake executes only one time brainstorm // values for a and b a = 0 ; b = 0 ; # menses ; // wait for period a = 0 ; b = 1 ; # period ; a = 1 ; b = 0 ; # period ; a = ane ; b = 1 ; # catamenia ; finish endmodule
Testbench with 'e'er' block
In List 9.iii, 'always' statement is used in the testbench; which includes the input values forth with the corresponding output values. If the specified outputs are not matched with the output generated past one-half-adder, then errors will be displayed.
Note
- In the testbenches, the 'ever' statement can be written with or without the sensitivity list every bit shown in List 9.iii.
- Unlike 'initial' cake, the 'e'er' block executes forever (if not terminated using 'stop' keyword). The statements inside the 'always' block execute sequentially; and after the execution of last statement, the execution begins once more from the first argument of the 'e'er' block.
Explanation Listing nine.3
The listing is same equally previous Listing ix.2, but 'always cake' is used instead of 'initial cake', therefore we tin provide the sensitive list to the design (Line 28) and proceeds more than control over the testing. A continuous clock is generated in Lines 19-26 by not defining the sensitive list to e'er-block (Line 19). This clock is used past Line 28. Also, some letters are as well displayed if the result of the design does not lucifer with the desire outcomes (Lines 35-36). In this way, we can find errors just by reading the concluding (see Fig. 9.2), instead of visualizing the whole waveform, which can be very difficult if the results are too long (see Fig. 9.3). Besides, Lines 35-36 tin be added in 'initial-block' of :numref:`verilog_half_adder_tb_v` too.
i 2 3 4 5 vi seven eight 9 10 xi 12 13 14 15 sixteen 17 18 xix 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 lx 61 62 63 64 // half_adder_procedural_tb.v `timescale i ns / ten ps // time-unit of measurement = 1 ns, precision = ten ps module half_adder_procedural_tb ; reg a , b ; wire sum , behave ; // duration for each bit = xx * timescale = 20 * one ns = 20ns localparam period = twenty ; half_adder UUT (. a ( a ), . b ( b ), . sum ( sum ), . carry ( carry )); reg clk ; // note that sensitive list is omitted in always block // therefore always-block run forever // clock catamenia = 2 ns always begin clk = one 'b1 ; # 20 ; // high for 20 * timescale = twenty ns clk = ane 'b0 ; # 20 ; // low for 20 * timescale = 20 ns end always @( posedge clk ) begin // values for a and b a = 0 ; b = 0 ; # period ; // wait for menstruum // display bulletin if output not matched if ( sum != 0 || carry != 0 ) $display ( "exam failed for input combination 00" ); a = 0 ; b = ane ; # period ; // expect for period if ( sum != one || deport != 0 ) $display ( "examination failed for input combination 01" ); a = 1 ; b = 0 ; # period ; // wait for period if ( sum != ane || conduct != 0 ) $display ( "test failed for input combination 10" ); a = one ; b = one ; # period ; // look for flow if ( sum != 0 || comport != 1 ) $display ( "test failed for input combination xi" ); a = 0 ; b = 1 ; # period ; // wait for catamenia if ( sum != one || carry != 1 ) $brandish ( "examination failed for input combination 01" ); $terminate ; // end of simulation end endmodule
9.3.1. Read data from file¶
In this section, data is read from file 'read_file_ex.txt' and displayed in simulation results. Date stored in the file is shown in Fig. nine.four.
Explanation Listing nine.iv
In the listing, 'integer i (Line 16)' is used in the 'for loop (Line 28)' to read all the lines of file 'read_file_ex.txt'. Data can be saved in 'binary' or 'hexadecimal format'. Since data is saved in 'binary format', therefor 'readmemb' (Line 23) is used to read it. For 'hexadecimal format', we demand to use keyword 'readmemh'. Read comments for further details of the listing. Information read by the listing is displayed in Fig. 9.five.
1 two 3 4 five 6 seven eight 9 ten 11 12 13 14 fifteen 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 // read_file_ex.5 // notation that, we demand to create Modelsim project to run this file, // or provide full path to the input-file i.east. adder_data.txt `timescale 1 ns / 10 ps // time-unit = 1 ns, precision = 10 ps module read_file_ex ; reg a , b ; // sum_expected, carry_expected are merged together for understanding reg [ one : 0 ] sum_carry_expected ; // [3:0] = 4 bit data // [0:5] = 6 rows in the file adder_data.txt reg [ 3 : 0 ] read_data [ 0 : 5 ]; integer i ; initial brainstorm // readmemb = read the binary values from the file // other pick is 'readmemh' for reading hex values // create Modelsim projection to use relative path with respect to project directory $readmemb ( "input_output_files/adder_data.txt" , read_data ); // or provide the compelete path equally below // $readmemb("D:/Testbences/input_output_files/adder_data.txt", read_data); // total number of lines in adder_data.txt = 6 for ( i = 0 ; i < 6 ; i = i + ane ) brainstorm // 0_1_0_1 and 0101 are read in the same mode, i.e. //a=0, b=1, sum_expected=0, carry_expected=0 for above line; // but utilise of underscore makes the values more readable. { a , b , sum_carry_expected } = read_data [ i ]; // apply this or below // {a, b, sum_carry_expected[0], sum_carry_expected[1]} = read_data[i]; # 20 ; // look for xx clock cycle end end endmodule
ix.iii.2. Write data to file¶
In this part, unlike types of values are defined in List nine.v and and then stored in the file.
Caption Listing 9.5
To write the information to the file, first we demand to define an 'integer' as shown in Line 14, which will work as buffer for open-file (run across Line 28). Then data is written in the files using 'fdisplay' command, and remainder of the code is aforementioned as Listing 9.4.
one 2 three 4 five vi 7 8 9 10 11 12 13 14 xv sixteen 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 twoscore 41 42 43 // write_file_ex.v // note that, we demand to create Modelsim project to run this file, // or provide full path to the input-file i.e. adder_data.txt `timescale i ns / 10 ps // time-unit of measurement = one ns, precision = ten ps module write_file_ex ; reg a , b , sum_expected , carry_expected ; // [3:0] = iv bit information // [0:5] = vi rows in the file adder_data.txt reg [ 3 : 0 ] read_data [ 0 : 5 ]; integer write_data ; integer i ; initial begin // readmemb = read the binary values from the file // other option is 'readmemh' for reading hex values // create Modelsim projection to employ relative path with respect to projection directory $readmemb ( "input_output_files/adder_data.txt" , read_data ); // or provide the compelete path equally beneath // $readmemb("D:/Testbences/input_output_files/adder_data.txt", read_data); // write data : provide full path or create project as above write_data = $fopen ( "input_output_files/write_file_ex.txt" ); for ( i = 0 ; i < six ; i = i + 1 ) begin { a , b , sum_expected , carry_expected } = read_data [ i ]; # 20 ; // write data to file using 'fdisplay' $fdisplay ( write_data , "%b_%b_%b_%b" , a , b , sum_expected , carry_expected ); end $fclose ( write_data ); // shut the file end endmodule
ix.4. Testbench for sequential designs¶
In previous sections, we read the lines from one file and then saved those line in other file using 'for loop'. As well, we saw apply of 'initial' and 'always' blocks. In this department, we volition combine all the techniques together to salvage the results of Mod-1000 counter, which is an example of 'sequential design'. The Mod-g counter is discussed in Listing 6.4. Testbench for this listing is shown in List 9.6 and the waveforms are illustrated in Fig. ix.vii.
Explanation Listing ix.6
In the testbench following operations are performed,
- Simulation information is saved on the terminal and saved in a file. Note that, 'monitor/fmonitor' keyword can exist used in the 'initial' cake, which tin can runway the changes in the signals as shown in Lines 98-108 and the output is shown in Fig. ix.viii. In the figure nosotros tin can see that the 'error' message is displayed two time (just the error is at one place only), as 'monitor' command checks for the transition in the indicate too.
- If nosotros desire to runway but final results, then 'display/fdisplay' command tin can exist used within the always cake as shown in Lines 110-124 (Uncomment these lines and comment Lines 98-108). Output is show in Fig. 9.ix. Note that, it is very easy to look for errors in the concluding/csv file as compare to finding it in the waveforms.
- Simulation is stopped after a fixed number of clock-bike using 'if statement' at Line 76-84. This method can exist extended to stop the simulation after sure status is reached.
Note
Notice the apply of 'negedge' in the code at Lines 89 and 117, to compare the result saved in file 'mod_m_counter_desired.txt' (Fig. 9.10) with consequence obtained by 'modMCounter.5' (Line 32). For more details, please read the comments in the lawmaking.
1 ii 3 4 5 6 7 eight 9 10 11 12 13 14 fifteen 16 17 xviii 19 xx 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 lx 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 eighty 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 // modMCounter_tb.five // note that the counter starts the count from 1 after reset (non from 0), // therefore file "mod_m_counter_desired.txt" starts with 1 (not from 0), // likewise one entry in the file is incorrect i.e. Line 10, where 'i' is written // instead of 'a'. `timescale 1 ns / 10 ps // fourth dimension-unit = 1 ns, precision = x ps module modMCounter_tb ; localparam Chiliad = 12 , N = 4 , menstruum = xx ; reg clk , reset ; wire complete_tick ; // desired_count is read from file // count is count provided by modMCounter.v wire [ N - ane : 0 ] count ; reg [ N - 1 : 0 ] desired_count ; reg [ 39 : 0 ] error_msg ; // message = error // [3:0] = iv bit data // [0:G-one] = 12 rows in the file mod_m_counter_desired.txt reg [ 3 : 0 ] read_data [ 0 : Thousand - 1 ]; integer counter_data ; // for saving counter-data on file integer i = 0 , j = 0 , total_cycle = M ; // used for ending the simulation later on K cycle // unit under examination modMCounter #(. Grand ( Thou ), . N ( N )) UUT (. clk ( clk ), . reset ( reset ), . complete_tick ( complete_tick ), . count ( count )); // read the data from file always @( posedge clk ) begin $readmemh ( "input_output_files/mod_m_counter_desired.txt" , read_data ); if ( reset ) desired_count = 0 ; else begin desired_count = read_data [ j ]; j = j + 1 ; end stop // open up csv-file for writing initial begin counter_data = $fopen ( "input_output_files/counter_output.csv" ); // open file end // note that sensitive list is omitted in e'er block // therefore e'er-block run forever // clock menstruation = ii ns always brainstorm clk = one 'b1 ; # 20 ; // high for 20 * timescale = 20 ns clk = i 'b0 ; # xx ; // depression for 20 * timescale = 20 ns terminate // reset initial begin reset = 1 ; #( period ); reset = 0 ; terminate // finish the simulation total_cycle and close the file // i.e. store just total_cycle values in file always @( posedge clk ) begin if ( total_cycle == i ) begin $terminate ; $fclose ( counter_data ); // close the file finish i = i + ane ; stop // notation that, the comparison is made at negative border, // when all the transition are settled. // if we use 'posedge', then outcome volition not exist in correct form always @( negedge clk ) begin if ( desired_count == count ) error_msg = " " ; else error_msg = "mistake" ; end // print the values on last and file initial begin // write on terminal $brandish ( " time, desired_count, count, complete_tick, error_msg" ); // monitors checks and print the transitions $monitor ( "%6d, %10b, %7x, %5b, %15s" , $time , desired_count , count , complete_tick , error_msg ); // write on the file $fdisplay ( counter_data , "time, desired_count, count, complete_tick, error_msg" ); $fmonitor ( counter_data , "%d,%b,%x,%b,%south" , $time , desired_count , count , complete_tick , error_msg ); end // // print the values on final and file // // header line // initial // begin // $fdisplay(counter_data,"time,desired_count,count,complete_tick,error_msg"); // end // // negative edge is used here, as mistake values are updated on negedge // always @(negedge clk) // begin // // write on terminal // $display("%6d, %10b, %7x, %5b, %15s", $time, desired_count, count, complete_tick, error_msg); // // write on the file // $fdisplay(counter_data, "%d, %d, %x, %b, %s", $time, desired_count, count, complete_tick, error_msg); // end endmodule
9.5. Conclusion¶
In this chapter, we learn to write testbenches with different styles for combinational circuits and sequential circuits. Nosotros saw the methods past which inputs tin can be read from the file and the outputs tin exist written in the file. Simulation results and expected results are compared and saved in the csv file and displayed as simulation waveforms; which demonstrated that locating the errors in csv files is easier than the simulation waveforms.
Source: https://verilogguide.readthedocs.io/en/latest/verilog/testbench.html
0 Response to "Run the Simulation Again What Is the Value of Tb alu result for This Instruction"
Post a Comment