Applications 3
Behavioral descriptions, continuous assignment, conditional instructions, use of blocks always for describing combinational circuits.
Structural descriptions, logic gates, verilog gate primitives.
Exhaustive verification. Loop statements in testbenches.
Exercise 1
Half adder - gate-level description
The half-adder is the simplest, 1-bit, adder. It implements the addition of two bits.
a | b | c |
---|---|---|
0 | 0 | 0 0 |
0 | 1 | 0 1 |
1 | 0 | 0 1 |
1 | 1 | 1 0 |
Use data flow description (a simpler kind of behavioral description that uses logic expressions). Logic expressions employ only logic operators.
operator | function |
---|---|
~ | not |
& | and |
| | or |
^ | xor |
One assign instruction for each output. Concurrent assignments (in simulation they are evaluated in parallel, mimicking the parallelism of the real circuits)
assign c[0] = a ^ b;
assign c[1] = a & b;
An exahaustive test is a test that generates all possible combinations of values for the inputs of the dut. Write a testbench for the half-adder that uses a repeat statement to generate all input combinations, and a concatenation operator that makes possible to update two or more variables at the same time.
initial begin
{a, b} = 0;
repeat (4) #1 {a, b} = {a, b} + 1;
end
Some remarks:
- There is no increment operator in verilog.
- Adding 1 to 3 on 2 bits turns around to 0.
- A delay may precede a statement.
Exercise 2
1-bit half adder - structural description
Work on the same project as that of Exercise 1. You need only to modify the description of the half-adder module.
Gate-level description = a structural description that uses only logic gates.
Verilog gate primitives: not, and, nand, or, nor, xor and xnor. Except for the not gate, all other primitive gates may have 2, 3 or more inputs.
All gate primitives are instantiated using the same template: gatePrimitiveType myGate(outputConnection, inputConnection1, inputConnection2 ...) as in the following examples:
not g1(dout, din);
is a not gate with dout at output and din connected at its input.
nand g2(dout, d1, d2);
is a nand gate with dout at output and two wires, d1 and d2, connected to its inputs.
nand g3(dout, d1, d2, d3, d4);
is a nand gate with dout at output and for inputs, connected to d1, d2, d3 and d4.
Using gate primitives, a possible structural description of the half-adder may be:
xor g1(c[0], a, b);
and g2(c[1], a, b);
Recompile the design file (from the simulator), and restart simulation.
Exercise 3
2 to 1 multiplexer, behavioral description
The simplest selection logic circuit. It selects between two inputs, in0 and in1, based on the value of the selection input, s:
s | c |
---|---|
0 | in0 |
1 | in1 |
always block. Used for behavioral descriptions. Template:
always @(sensitivity list) begin
block of instructions
end
For combinational circuits the safest way to declare the sensitivity list is to use the wildcard (*). It stands for all variables that appear on RHS expressions and in evaluation expressions.
always @(*) begin
if(s)
c = in[1];
else
c = in[0];
end
Write a testbench using a for statement to generate all input combinations. Its template is:
for(initial_assignment; expression; step_assignment) block of statements;
The foor loop is repeated until the expression evaluates true. The simplest for statement uses an integer index that is incremented at the end of each iteration. The for loop below generates all combinations from 000 to 111 for tree logic variables, s, a and b.
initial begin
{s, a, b} = 0;
for(index = 0; index < 8; index = index + 1) begin
#1 {s, a, b} = {s, a, b} + 1;
end
end
== Exercise 4 ==
=== 2 to 1 multiplexer - gate-level description ===
Work on the same project as that of Exercise 3. You need only to modify the description of the 2 to 1 multiplexer module.
Implement the 2 to 1 multiplexer using only verilog gate primitives. For simulation you may reuse the testbench from Exercise 3 (copy its file into the directory of this project and set it as the testbench). Change the type of the multiplexer's instance in the testbench, if it is different from Exercise 3.
[[Fișier: Mux2a.png]]
Recompile the design file (from the simulator), and restart simulation.
== Exercise 5 ==
=== 4 to 1 multiplexer - behavioral description ===
[[Fișier: mux4.png]]
'''case''' instruction. Selects between multiple cases. Template
'''case('''''selectVariable''''')'''<br />
''value1'' ''':''' ''instruction block 1''<br />
''value2'' ''':''' ''instruction block 2''<br />
a.s.o.<br />
'''endcase'''
''value1'', ''value2'' a.s.o. are integer values of the ''selectVariable''
<syntaxhighlight lang="Verilog">
case(s)
0: c = in[0];
1: c = in[1];
2: c = in[2];
3: c = in[3];
endcase
Exercise 6
4 to 1 multiplexer - structural description
Implement the 4 to 1 multiplexer using three instances of the 2 to 1 multiplexer (add to the project the file of that module either from Exercise 3, or Exercise 4) and a primitive gate.
Be careful to distinctly name each instance and each internal wire!