Applications 3: Diferență între versiuni

De la WikiLabs
Jump to navigationJump to search
Fără descriere a modificării
Fără descriere a modificării
Linia 2: Linia 2:


Structural descriptions, logic gates, verilog gate primitives.
Structural descriptions, logic gates, verilog gate primitives.
Exhaustive verification. Loop statements in testbenches.


== Exercise 1 ==
== Exercise 1 ==
gate-level description of the 1-bit half adder
=== Half adder - gate-level description ===
 
The half-adder is the simplest, 1-bit, adder. It implements the addition of two bits.
 
{| class="wikitable" style="text-align: center;
! scope="col"| a
! scope="col"| b
! scope="col"| c
|-
|0 ||0 || 0 0
|-
|0 ||1 || 0 1
|-
|1 ||0 || 0 1
|-
|1 ||1 || 1 0
|}


[[Fișier: app2_sum.png]]
[[Fișier: app2_sum.png]]
[[Fișier: half_adder.png]]


Use data flow description (a simpler kind of behavioral description that uses logic expressions).
Use data flow description (a simpler kind of behavioral description that uses logic expressions).
Linia 25: Linia 42:
|}
|}


One '''assign''' instruction for each output. Concurrent assignments.
One '''assign''' instruction for each output. Concurrent assignments (in simulation they are evaluated in parallel, mimicking the parallelism of the real circuits)


<syntaxhighlight lang="Verilog">
<syntaxhighlight lang="Verilog">
Linia 32: Linia 49:
</syntaxhighlight>
</syntaxhighlight>


Use gate-level description (a structural description with gate primitives).
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.
 
<syntaxhighlight lang="Verilog">
initial begin
    {a, b} = 0;
    repeat (4) #1 {a, b} = {a, b} + 1;
end
</syntaxhighlight>
 
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'''.
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.
Except for the '''not''' gate, all other primitive gates may have 2, 3 or more inputs.


They are all instantiated using the same template: ''gate primitive'' myGate'''('''''outputWire, inputWire1, inputWire2 ...''''')''' as in the following examples:
All gate primitives are instantiated using the same template: ''gatePrimitiveType'' myGate'''('''''outputConnection, inputConnection1, inputConnection2 ...''''')''' as in the following examples:


<syntaxhighlight lang="Verilog" inline>not g1(dout, din);</syntaxhighlight>  is a '''not''' gate with dout at output and din connected at its input.
<syntaxhighlight lang="Verilog" inline>not g1(dout, din);</syntaxhighlight>  is a '''not''' gate with dout at output and din connected at its input.
Linia 43: Linia 81:


<syntaxhighlight lang="Verilog" inline>nand g3(dout, d1, d2, d3, d4);</syntaxhighlight>  is a '''nand''' gate with dout at output and for inputs, connected to d1, d2, d3 and d4.
<syntaxhighlight lang="Verilog" inline>nand g3(dout, d1, d2, d3, d4);</syntaxhighlight>  is a '''nand''' gate with dout at output and for inputs, connected to d1, d2, d3 and d4.
[[Fișier: half_adder.png]]


Using gate primitives, a possible structural description of the half-adder may be:
Using gate primitives, a possible structural description of the half-adder may be:
Linia 51: Linia 91:
</syntaxhighlight>
</syntaxhighlight>


Write a simple testbench for the half-adder and simulate both descriptions, data-flow and gate-level with primitives.
Recompile the design file (from the simulator), and restart simulation.


== Exercise 2 ==
== Exercise 3 ==
2 to 1 multiplexer, behavioral description
=== 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:


{| class="wikitable" style="text-align: center;
! scope="col"| s
! scope="col"| c
|-
|0 ||'''in0'''
|-
|1 ||'''in1'''
|}
[[Fișier: Mux2.png]]
[[Fișier: Mux2.png]]


Linia 76: Linia 126:
</syntaxhighlight>
</syntaxhighlight>


== Exercise 3 ==
Write a testbench using a '''for''' statement to generate all input combinations. Its template is:
The same 2 to 1 multiplexer, described at the gate level
 
'''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.
 
<syntaxhighlight lang="Verilog">
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]]
[[Fișier: Mux2a.png]]


== Exercise 4 ==
Recompile the design file (from the simulator), and restart simulation.
4 to 1 multiplexer
 
== Exercise 5 ==
=== 4 to 1 multiplexer - behavioral description ===


[[Fișier: mux4.png]]
[[Fișier: mux4.png]]
Linia 104: Linia 175:
endcase  
endcase  
</syntaxhighlight>
</syntaxhighlight>
== Exercise 6 ==
=== 4 to 1 multiplexer - structural description ===
[[Fișier: mux4a.png]]
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!

Versiunea de la data 5 martie 2019 10:19

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 />
&nbsp;&nbsp;''value1'' ''':''' ''instruction block 1''<br />
&nbsp;&nbsp;''value2'' ''':''' ''instruction block 2''<br />
&nbsp;&nbsp; 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!