Diferență între revizuiri ale paginii „Applications 6”
(Nu s-au afișat 6 versiuni intermediare efectuate de același utilizator) | |||
Linia 2: | Linia 2: | ||
=== D flip-flop === | === D flip-flop === | ||
− | * ''' | + | * '''dff1''' module with behavioral description of the D flip-flop |
− | * ''' | + | * '''dff1_tb''' testbench with stimuli for '''d''' and '''clk''' |
[[Fișier: dreg1.png]] | [[Fișier: dreg1.png]] | ||
Linia 14: | Linia 14: | ||
* any sequential variable is of '''reg''' type | * any sequential variable is of '''reg''' type | ||
* all assignments for sequential variables are '''nonblocking assignments''', i.e. they use the <syntaxhighlight lang="Verilog" inline><=</syntaxhighlight> operator | * all assignments for sequential variables are '''nonblocking assignments''', i.e. they use the <syntaxhighlight lang="Verilog" inline><=</syntaxhighlight> operator | ||
+ | |||
=== clock generation in testbench === | === clock generation in testbench === | ||
Linia 19: | Linia 20: | ||
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
initial begin | initial begin | ||
− | clk = 0; | + | clk = 0; // initialization at time 0 |
forever #10 clk = ~clk; // toggle the clock at each 10 simulation steps | forever #10 clk = ~clk; // toggle the clock at each 10 simulation steps | ||
end | end | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | '''Attention!''' | ||
+ | * the logic complementation operator is <syntaxhighlight lang="Verilog" inline>~</syntaxhighlight>, which is different from the arithmetic minus operator <syntaxhighlight lang="Verilog" inline>-</syntaxhighlight>. If you wrongly assign <syntaxhighlight lang="Verilog" inline>clk = -clk</syntaxhighlight>, '''clk''' will stay forever at '''0''' because -'''0''' = '''0'''. | ||
+ | |||
For the '''d''' input generate the following sequence in testbench: | For the '''d''' input generate the following sequence in testbench: | ||
Linia 29: | Linia 34: | ||
See how the output '''q''' reacts or not to changes of the input '''d'''. | See how the output '''q''' reacts or not to changes of the input '''d'''. | ||
+ | |||
+ | '''Attention!''' | ||
+ | * the stimuli are generated in other initial processes, separate from the initial process that is used only for clock generation (which loops forever, and cannot go beyond the '''forever''' statement) | ||
+ | * because the clock is continuously generated, the simulation doesn't stop by itself. It may be stopped from simulation menu buttons (the red stop button or the break button). A more practical approach (that restricts from the beginning the waveform to the area of interest) is to stop the simulation from the testbench through the <syntaxhighlight lang="Verilog" inline>$stop</syntaxhighlight> sistem task added with a convenient delay after the last stimulus change: | ||
+ | |||
+ | <syntaxhighlight lang="Verilog"> | ||
+ | initial begin | ||
+ | // code to generate various stimuli (data, control signals etc) | ||
+ | #10 $stop; | ||
+ | end | ||
+ | </syntaxhighlight> | ||
== Exercise 2 == | == Exercise 2 == | ||
Linia 44: | Linia 60: | ||
[[Fișier: reg4wave.png]] | [[Fișier: reg4wave.png]] | ||
+ | |||
=== structural description with flip-flops === | === structural description with flip-flops === | ||
− | * add ''' | + | * add '''dff1''' file to this project |
− | * change the description of '''reg4''' to a structural one, with 4 instances of ''' | + | * change the description of '''reg4''' to a structural one, with 4 instances of '''dff1''', connected as in the schematics below: |
* rerun the testbench | * rerun the testbench | ||
[[Fișier: reg4.png]] | [[Fișier: reg4.png]] | ||
+ | |||
== Exercise 3 == | == Exercise 3 == | ||
Linia 57: | Linia 75: | ||
* '''shiftr4''' module described structurally as in the schematics below. It is basically the '''reg4''' module, but with the D flip-flops connected in a shift chain. | * '''shiftr4''' module described structurally as in the schematics below. It is basically the '''reg4''' module, but with the D flip-flops connected in a shift chain. | ||
− | * ''' | + | * '''dff1''' is added (copied) to this project |
* '''shiftr4_tb''' testbench with '''clk''' generation and a (random) bit sequence for '''si''' (serial input) | * '''shiftr4_tb''' testbench with '''clk''' generation and a (random) bit sequence for '''si''' (serial input) | ||
[[Fișier: shiftr4.png]] | [[Fișier: shiftr4.png]] | ||
+ | |||
=== reset === | === reset === | ||
Linia 72: | Linia 91: | ||
[[Fișier: shiftr4rst.png]] | [[Fișier: shiftr4rst.png]] | ||
+ | |||
+ | * add to the '''dff1''' module an input for '''rst''', and change its description such that to react to a synchronous reset which is active low (when '''rst''' is '''0''') | ||
+ | * add to the '''shiftr4''' module an input for '''rst''' and connect it to the corresponding inputs of the '''dff1''' instances | ||
+ | * add a separate '''initial''' process in the testbench to generate a reset pulse as in the drawing: | ||
+ | |||
+ | [[Fișier: shiftr4rstwave.png]] | ||
For any sequential process with reset (active '''1''' in the examples below) the template is: | For any sequential process with reset (active '''1''' in the examples below) the template is: | ||
Linia 91: | Linia 116: | ||
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
− | always @(posedge clk, posedge rst) begin | + | always @(posedge clk, posedge rst) begin // the reset signal appears in the sensitivity list, therefore the always process reacts immediately to it |
if(rst) begin | if(rst) begin | ||
// initialize sequential variables | // initialize sequential variables | ||
Linia 101: | Linia 126: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | * change the '''dff1''' description such that it reacts to an asynchronous reset which is active low, recompile, restart simulation and see how the output waveform is affected | |
+ | * shorten the length of the reset pulse, such that there is no any active clock edge during the reset as in the waveform below. Rerun and see that the asynchronous reset takes effect. | ||
+ | * change back to the synchronous reset. Rerun and see that the reset pulse has no effect because no active clock edge catches it. | ||
+ | |||
+ | [[Fișier: shiftr4rstwave1.png]] | ||
+ | |||
+ | '''Attention!''' | ||
+ | * the reset branch must be the first branch in the sequential always process (as in the templates above) | ||
+ | * be sure that the reset active value is checked. <syntaxhighlight lang="Verilog" inline>if(rst)</syntaxhighlight> if it is active high (when '''1'''), or <syntaxhighlight lang="Verilog" inline>if(~rst)</syntaxhighlight> if it is active low (when '''0''') | ||
− | |||
− | |||
=== nonblocking versus blocking assignments === | === nonblocking versus blocking assignments === | ||
+ | * change the '''shiftr4''' description to a behavioral one. Use a single '''always''' process to control all output bits individually | ||
* compare in simulation these two behavioral descriptions of the '''shiftr4''' module: | * compare in simulation these two behavioral descriptions of the '''shiftr4''' module: | ||
+ | # the correct description with nonblocking assignments | ||
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
q[3] <= si | q[3] <= si | ||
Linia 116: | Linia 149: | ||
q[0] <= q[1] | q[0] <= q[1] | ||
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | # the wrong description with blocking assignments | |
<syntaxhighlight lang="Verilog"> | <syntaxhighlight lang="Verilog"> | ||
q[3] = si | q[3] = si | ||
Linia 123: | Linia 156: | ||
q[0] = q[1] | q[0] = q[1] | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | === a simpler behavioral description === | ||
+ | |||
+ | * change the '''shiftr4''' behavioral description such that all bits are shifted at once in a single statement that uses the concatenation operator: | ||
+ | |||
+ | <syntaxhighlight lang="Verilog">q <= {si,q[3:1]} // the new value is the old value shifted one bit to the right and with si bit appended to its left</syntaxhighlight> |
Versiunea curentă din 7 aprilie 2019 16:14
Exercise 1
D flip-flop
- dff1 module with behavioral description of the D flip-flop
- dff1_tb testbench with stimuli for d and clk
the output takes the value of the input, q <= d
, but only at discrete moments of time,
when the control signal clk changes from 0 to 1, always @(posedge clk)
.
Attention!
- behavioral sequential descriptions use only always processes
- any sequential variable is of reg type
- all assignments for sequential variables are nonblocking assignments, i.e. they use the
<=
operator
clock generation in testbench
initial begin
clk = 0; // initialization at time 0
forever #10 clk = ~clk; // toggle the clock at each 10 simulation steps
end
Attention!
- the logic complementation operator is
~
, which is different from the arithmetic minus operator-
. If you wrongly assignclk = -clk
, clk will stay forever at 0 because -0 = 0.
For the d input generate the following sequence in testbench:
See how the output q reacts or not to changes of the input d.
Attention!
- the stimuli are generated in other initial processes, separate from the initial process that is used only for clock generation (which loops forever, and cannot go beyond the forever statement)
- because the clock is continuously generated, the simulation doesn't stop by itself. It may be stopped from simulation menu buttons (the red stop button or the break button). A more practical approach (that restricts from the beginning the waveform to the area of interest) is to stop the simulation from the testbench through the
$stop
sistem task added with a convenient delay after the last stimulus change:
initial begin
// code to generate various stimuli (data, control signals etc)
#10 $stop;
end
Exercise 2
4 bit D register
- reg4 module
- reg4_tb testbench with stimuli for d and clk
The behavioral description is identical with that of the D flip-flop of Exercise 1 (the D flip-flop being nothing else than a 1 bit D register). However, the interface differs in terms of the widths for d input and q output.
For the d input generate the following sequence in testbench:
structural description with flip-flops
- add dff1 file to this project
- change the description of reg4 to a structural one, with 4 instances of dff1, connected as in the schematics below:
- rerun the testbench
Exercise 3
4 bit shift left register
- shiftr4 module described structurally as in the schematics below. It is basically the reg4 module, but with the D flip-flops connected in a shift chain.
- dff1 is added (copied) to this project
- shiftr4_tb testbench with clk generation and a (random) bit sequence for si (serial input)
reset
Almost always a sequential circuit needs to start from a valid configuration, usually the initial one (for example with all bits zero). Without a proper reset the shift register will start in a random configuration, and its outputs will be meaningless untill the first input bit is shifted till the rightmost position, which takes 4 clock cycles. In simulation the outputs will be undefined until the first input bit reaches them.
The reset is active for a short time after power up (at the beginning of the simulation). The active value may be 1 or 0.
Also, the reset may be synchronous or asynchronous. The synchronous reset takes effect only at the first active clock edge after the reset is applied (therefore, the syncronous reset pulse must last at least one clock cycle). The asynchronous reset has immediate effect.
- add to the dff1 module an input for rst, and change its description such that to react to a synchronous reset which is active low (when rst is 0)
- add to the shiftr4 module an input for rst and connect it to the corresponding inputs of the dff1 instances
- add a separate initial process in the testbench to generate a reset pulse as in the drawing:
For any sequential process with reset (active 1 in the examples below) the template is:
- for synchronous reset
always @(posedge clk) begin
if(rst) begin
// initialize sequential variables
end
else begin
// sequential variables normal control
end
end
- for asynchronous reset
always @(posedge clk, posedge rst) begin // the reset signal appears in the sensitivity list, therefore the always process reacts immediately to it
if(rst) begin
// initialize sequential variables
end
else begin
// sequential variables normal control
end
end
- change the dff1 description such that it reacts to an asynchronous reset which is active low, recompile, restart simulation and see how the output waveform is affected
- shorten the length of the reset pulse, such that there is no any active clock edge during the reset as in the waveform below. Rerun and see that the asynchronous reset takes effect.
- change back to the synchronous reset. Rerun and see that the reset pulse has no effect because no active clock edge catches it.
Attention!
- the reset branch must be the first branch in the sequential always process (as in the templates above)
- be sure that the reset active value is checked.
if(rst)
if it is active high (when 1), orif(~rst)
if it is active low (when 0)
nonblocking versus blocking assignments
- change the shiftr4 description to a behavioral one. Use a single always process to control all output bits individually
- compare in simulation these two behavioral descriptions of the shiftr4 module:
- the correct description with nonblocking assignments
q[3] <= si
q[2] <= q[3]
q[1] <= q[2]
q[0] <= q[1]
- the wrong description with blocking assignments
q[3] = si
q[2] = q[3]
q[1] = q[2]
q[0] = q[1]
a simpler behavioral description
- change the shiftr4 behavioral description such that all bits are shifted at once in a single statement that uses the concatenation operator:
q <= {si,q[3:1]} // the new value is the old value shifted one bit to the right and with si bit appended to its left