Diferență între revizuiri ale paginii „Applications 1”
Linia 6: | Linia 6: | ||
For simple designs with few outputs that are easy to check visually on simulation waveforms, the testbench may be reduced to a DUT and the signals generation part. | For simple designs with few outputs that are easy to check visually on simulation waveforms, the testbench may be reduced to a DUT and the signals generation part. | ||
+ | |||
+ | == Exercise 1 == | ||
+ | === One bit signal generation === | ||
+ | |||
+ | Already a classical, the first program in any programming language tutorial displays the "Hello World" message. | ||
+ | Your very first Vivado project will instead generate a very simple signal, a single pulse. | ||
+ | |||
+ | [[Fișier:Dic_lab1_one_pulse.png]] | ||
+ | |||
+ | The simplest way to generate a signal in a testbench is to use a sequence of assignments that change the signal's value at predetermined steps of the simulation. | ||
+ | The sequence of assignments is enclosed in a verilog procedural block. The initial procedural block starts its execution from the very beginning of simulation (hence its name, initial), | ||
+ | and runs through its statements to the last one, after which it finishes. | ||
+ | |||
+ | <syntaxhighlight lang="Verilog"> | ||
+ | module waveform1; // module declaration. The testbench module is named waveform1 and has no ports (its generated signal is internal). | ||
+ | |||
+ | reg a; // signal declaration. Signal named a is a variable of type reg. The default size is one bit. | ||
+ | |||
+ | initial begin // start of an initial procedural block | ||
+ | a = 0; // a is set to 0 at the beginning of simulation | ||
+ | #10 a = 1; // after 10 simulation steps, a is set to 1 | ||
+ | #10 a = 0; // after other 10 simulation steps, a is reset to 0. The delays are cumulative, therefore this change occurs after 20 simulation steps from the beginning. | ||
+ | #20 $stop; // $stop is a system function to stop the simulation. All system functions are prefixed by the dollar symbol, '''$'''. | ||
+ | end // ends the procedural block | ||
+ | |||
+ | endmodule // end of module description | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | The verilog simulation advances in discrete steps. By default each step is counted as a 1 ns interval. | ||
+ | Any verilog statement may be preceded by a delay. The delay tells the simulator how many simulation steps should pass until the statement is executed. The delay is an integer number prefixed by the special hash symbol '''#'''''delay_value'' | ||
+ | |||
+ | == Exercise 2 == | ||
+ | === Two one-bit signals generation === | ||
+ | |||
+ | [[Fișier:Dic_lab1_two_pulse.png]] | ||
+ | |||
+ | |||
+ | <syntaxhighlight lang="Verilog"> | ||
+ | module waveform1; | ||
+ | |||
+ | reg a; // first signal declaration | ||
+ | reg b; // second signal declaration | ||
+ | |||
+ | initial begin // initial procedural block for the generation of a | ||
+ | a = 0; | ||
+ | #10 a = 1; | ||
+ | #10 a = 0; | ||
+ | #20 $stop; // Only one call is needed to stop the simulation | ||
+ | end | ||
+ | |||
+ | initial begin // initial procedural block for the generation of b | ||
+ | b = 0; | ||
+ | #5 b = 1; | ||
+ | #10 b = 0; | ||
+ | end | ||
+ | |||
+ | endmodule | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Each verilog procedural block is treated as a thread by Vivado simulator. All procedural blocks are seen as parallel threads. When one thread finishes its execution, other threads may still have statements to execute. The initial block for generation of b executes its last statement at step 15. However the simulation goes forward (there are still statements in the other initial block to be executed). The stop should be called from the initial procedural block that is last to finish. Alternatively, you may use an independent initial block to stop the simulation, employing a delay that covers all steps of the simulation. | ||
+ | |||
+ | <syntaxhighlight lang="Verilog"> | ||
+ | initial #40 $stop; | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''Note''': When a procedural block has only one statement you may leave off the '''begin''' and end '''keywords'''. Otherwise, the '''begin''' and '''end''' keywords should be employed to enclose the sequence of statements of that procedural block. | ||
+ | |||
+ | == Exercise 3 == | ||
+ | === Two one-bit signals generation === | ||
+ | |||
+ | Two different may be generated using the same procedural block. You should be careful to sequence and delay the assignments for different signals such that to achieve the desired waveform. Remember that delays are cumulative. | ||
+ | |||
+ | <syntaxhighlight lang="Verilog"> | ||
+ | module waveform1; | ||
+ | |||
+ | reg a, b; // two variables of the same type (and width) may be declared in one declaration statement (not recommended) | ||
+ | |||
+ | initial begin | ||
+ | a = 0; // a is set to 0 at the beginning of simulation | ||
+ | b = 0; // b is set to 0 at the beginning of simulation | ||
+ | #5 b = 1; // after 5 simulation steps, b is set to 1 (at simulation step 5) | ||
+ | #5 a = 1; // after other 5 steps, the other variable is set to 1 (at simulation step 10) | ||
+ | // more statements to change a and b as desired << COMPLETE THE MISSING CODE | ||
+ | #20 $stop; | ||
+ | end | ||
+ | |||
+ | endmodule | ||
+ | </syntaxhighlight> |
Versiunea de la data 27 februarie 2022 22:27
The Testbench Module
The testbench is a module used only in simulation for testing another module. It encloses the tested module (named DUT - Device Under Test) and generates the signals for the inputs of the DUT. Additionally the testbench may automatically check the correctness of the DUT outputs, and may report or log the values of various DUT signals and the events of the simulation. Simple testbenches generate all signals and do all checks and reports using verilog statements, but more complex testbenches may instantiate helper modules designed for various test functions and operations (signal drivers/generators, output checkers, scoreboards a.s.o.).
For simple designs with few outputs that are easy to check visually on simulation waveforms, the testbench may be reduced to a DUT and the signals generation part.
Exercise 1
One bit signal generation
Already a classical, the first program in any programming language tutorial displays the "Hello World" message. Your very first Vivado project will instead generate a very simple signal, a single pulse.
The simplest way to generate a signal in a testbench is to use a sequence of assignments that change the signal's value at predetermined steps of the simulation. The sequence of assignments is enclosed in a verilog procedural block. The initial procedural block starts its execution from the very beginning of simulation (hence its name, initial), and runs through its statements to the last one, after which it finishes.
module waveform1; // module declaration. The testbench module is named waveform1 and has no ports (its generated signal is internal).
reg a; // signal declaration. Signal named a is a variable of type reg. The default size is one bit.
initial begin // start of an initial procedural block
a = 0; // a is set to 0 at the beginning of simulation
#10 a = 1; // after 10 simulation steps, a is set to 1
#10 a = 0; // after other 10 simulation steps, a is reset to 0. The delays are cumulative, therefore this change occurs after 20 simulation steps from the beginning.
#20 $stop; // $stop is a system function to stop the simulation. All system functions are prefixed by the dollar symbol, '''$'''.
end // ends the procedural block
endmodule // end of module description
The verilog simulation advances in discrete steps. By default each step is counted as a 1 ns interval. Any verilog statement may be preceded by a delay. The delay tells the simulator how many simulation steps should pass until the statement is executed. The delay is an integer number prefixed by the special hash symbol #delay_value
Exercise 2
Two one-bit signals generation
module waveform1;
reg a; // first signal declaration
reg b; // second signal declaration
initial begin // initial procedural block for the generation of a
a = 0;
#10 a = 1;
#10 a = 0;
#20 $stop; // Only one call is needed to stop the simulation
end
initial begin // initial procedural block for the generation of b
b = 0;
#5 b = 1;
#10 b = 0;
end
endmodule
Each verilog procedural block is treated as a thread by Vivado simulator. All procedural blocks are seen as parallel threads. When one thread finishes its execution, other threads may still have statements to execute. The initial block for generation of b executes its last statement at step 15. However the simulation goes forward (there are still statements in the other initial block to be executed). The stop should be called from the initial procedural block that is last to finish. Alternatively, you may use an independent initial block to stop the simulation, employing a delay that covers all steps of the simulation.
initial #40 $stop;
Note: When a procedural block has only one statement you may leave off the begin and end keywords. Otherwise, the begin and end keywords should be employed to enclose the sequence of statements of that procedural block.
Exercise 3
Two one-bit signals generation
Two different may be generated using the same procedural block. You should be careful to sequence and delay the assignments for different signals such that to achieve the desired waveform. Remember that delays are cumulative.
module waveform1;
reg a, b; // two variables of the same type (and width) may be declared in one declaration statement (not recommended)
initial begin
a = 0; // a is set to 0 at the beginning of simulation
b = 0; // b is set to 0 at the beginning of simulation
#5 b = 1; // after 5 simulation steps, b is set to 1 (at simulation step 5)
#5 a = 1; // after other 5 steps, the other variable is set to 1 (at simulation step 10)
// more statements to change a and b as desired << COMPLETE THE MISSING CODE
#20 $stop;
end
endmodule