More topics in Verilog course

Gate level modeling in Verilog

Designing circuits using basic logic gates is known as gate-level modeling. A digital circuit is implemented using logic gates and interconnections between these gates. The primitives (The most basic commands of a language) defined in Verilog have been set keeping the user requirements in mind making it easy to design bigger blocks. For example, for implementing AND gate or logic, the primitive is simply and(Yd, A, B).

Gate level modeling also takes care of gate delays, which is not possible in a higher level of abstraction like behavioral modeling.

Gate delay is time required for output of a logic gate to get to 50% of its final value when the input of the logic gate gets to 50% of its final value. You can consider it to be the time it takes for a logic gate to be active. Gate delays are highly unwanted in most scenarios. Ideally, you want a logic gate that just fires up instantly. However, there are cases where gate delays are useful. (Read more

However, the designer should know the gate-level diagram of the circuit. In general, gate-level modeling is used for implementing lowest level modules in a design like full-adder, multiplexers, and other digital circuits.

In this post, we will take an in-depth look at the theory behind gate-level modeling in Verilog. First, we view the logic values and ‘strengths.’ Then we talk about gate primitives. We will also have a look at the gate delays and, finally, see the subtle difference between gate-level modeling and switch-level modeling.

Logic values

A logic value is a state in which a data-type or a signal line in a chip can be present. In Verilog, there are four logic values, which means that a signal line can take one of the four values shown in the table below:

Logic Value Description
0 low
1 high
X Unknown logic
Z High impedance state

These values are either assigned in the hardware description or the output of a block.

Strengths

Usually, in chip design, multiple signal paths are combined into one to save space. In this scenario, the logic values need to be assigned a higher value to facilitate this. Thus we have strength values. These strength values assign a relative value to logic values. Strengths are used to resolve which value should appear on a net or gate output. The types of strengths are mentioned below:

supply, strong, pull, weak, highz strengths, large, medium, and small strengths.

Their value orders the strengths. The supply strength is the strongest, and the highz strength is the weakest strength level. Strength values can be displayed by system tasks ($display, $monitor – by using the %v characters).

Strength Level Signal Strength Name Specification
0 High Impedance highz0 highz1
1 (Weakest) Small Capacitance small
2 Medium Capacitance medium
3 Weak Drive weak0 weak1
4 Large Capacitance large
5 Pull Drive pull0 pull1
6 Strong Pull strong0 strong1
7 (Strongest) Supply drive supply0 supply1

If two or more drivers drive a signal, then it will have the value of the strongest driver.

Gate primitives

Gate primitives are predefined modules in Verilog. There are two classes of gate primitives:

Single input gate primitives

Single input gate primitives have a single input and one or more outputs. The gate primitives notif1, bufif1, notif0, and bufif0 also have a control signal. The gates propagate only if the control signal is asserted, else the output is high impedance state (z).

not, buf gates

These gates have only one scalar input but may have multiple outputs.

buf stands for a buffer that transfers the input value to the output without any change.

not stands for an inverter that inverts the input signal. So a 0 at its input will produce a 1 and vice versa. Let’s view the implementation.

module buf_not_gates (input a, b, output c, d);
  buf (c, a, b);   // c is the output, a and b are inputs
  not (d, a, b);  // d is the output, a and b are inputs
endmodule

module buf_not_gates_tb;
  reg a, b;
  wire c, d;
  buf_not_gates Instance0 (a, b, c,d);
  initial begin
    a = 0; b = 0;
 #1 a = 0; b = 1; 
 #1 a = 1; b = 0;
 #1 a = 1; b = 1;
  end
  initial begin
    $monitor ("T=%t| a=%b |b=%b| c(buf)=%b |d(not)=%b", $time, a, b, c, d);
  end
endmodule

bufif/notif gates

bufif and notif primitives are buffers and inverters, respectively, with an added control signal to enable the output. The gates have a valid output only if the control signal is enabled else the output will be in high impedance state.

These gates are available in two flavors.

One with the normal polarity of control indicated by a 1 like bufif1 and notif1 and second with the inverted polarity of control indicated by a 0 like bufif0 and notif0.

bufif verilog tri-state buffer logic instantiation
Instantiation of different cases of tristate buffer (bufif) primitives
module bufif_notif_gates (output c, d, input a, b);
  bufif (c, a, b);   // c is the output, a and b are inputs
  notif (d, a, b);  // d is the output, a and b are inputs
endmodule

module bufif_notif_gates_tb;
  reg a, b;
  wire c, d;
  bufif_notif_gates Instance0 (c, d, a, b);
  initial begin
    a = 0; b = 0;
 #1 a = 0; b = 1; 
 #1 a = 1; b = 0;
 #1 a = 1; b = 1;
  end
  initial begin
    $monitor ("T=%t| a=%b |b=%b| c(bufif)=%b |d(notif)=%b", $time, a, b, c, d);
  end
endmodule

Multiple input gate primitives

Multiple input gate primitives include AND, OR, NOR, XOR, and XNOR. They may have multiple inputs and a single output.

AND/OR/XOR gates

Both primitives we introduce here, an AND, OR, and an XOR gate, need multiple scalar inputs and produce a single scalar output. The first terminal in the argument list to these primitives is the output that is changed as any of the inputs shift. Here is the implementation to get a clear picture of the behavior of inputs and outputs.

module and_or_xor_gates (output c, d, e, input a, b);
  and (c, a, b);   // c is the output, a and b are inputs
  or  (d, a, b);  // d is the output, a and b are inputs
  xor (e, a, b);   // e is the output, a and b are inputs
endmodule

module and_or_xor_gates_tb;
reg a, b;
wire c, d, e;
and_or_xor_gates Instance0 (c, d, e, a, b);
 initial begin
      a = 0; b = 0;
   #1 a = 0; b = 1; 
   #1 a = 1; b = 0;
   #1 a = 1; b = 1;
 end
 initial begin
   $monitor ("T=%t |a=%b |b=%b |c(and)=%b |d(or)=%b |e(xor)=%b", $time, a, b, c, d, e);
 end
endmodule

NAND/NOR/XNOR gates

The inverse of all the above gates are nandnor and xnor. The same design from above is reused only that the primitives are interchanged with their inverse versions.

module nand_nor_xnor_gates (output c, d, e, input a, b);
 nand (c, a, b); // c is the output, a and b are inputs 
 nor (d, a, b); // d is the output, a and b are inputs 
 xnor (e, a, b); // e is the output, a and b are inputs
endmodule 

module nand_nor_xnor_gates_tb;
reg a, b;
wire c, d, e;
nand_nor_xnor_gates Instance0 (c, d, e, a, b);
  initial begin
    a = 0; b = 0;
 #1 a = 0; b = 1; 
 #1 a = 1; b = 0;
 #1 a = 1; b = 1;
end
  initial begin
    $monitor ("T=%t |a=%b |b=%b |c(nand)=%b |d(nor)=%b |e(xnor)=%b", $time, a, b, c, d, e);
  end
endmodule

All these gates may also have more than two inputs.

module all_gates (output x1, y1, z1, x2, y2, z2 , input a, b, c, d);
  and (x1, a, b, c, d);   // x1 is the output, a, b, c, d are inputs
  or  (y1, a, b, c, d);  // y1 is the output, a, b, c, d are inputs
  xor (z1, a, b, c, d);   // z1 is the output, a, b, c, d are inputs
  nand (x2, a, b, c, d); // x2 is the output, a, b, c, d are inputs
  nor (y2, a, b, c, d); // y2 is the output, a, b, c, d are inputs 
  xnor (z2, a, b, c, d); // z2 is the output, a, b, c, d are inputs
endmodule

Gate Delays

In Verilog, the gate delays may be defined by a designer in a primitive instance. This allows the engineer to get the logic circuit to function in real-time.

Rise delay

It is equal to the time taken by a gate output transition to 1, from another value 0, x, or z.

Fall delay

It is equal to the time taken by a gate output transition to 0, from another value 1, x, or z.

Turn off delay

It is equal to the time taken by a gate output transition to a high impedance state, from another value 1, x, or z.

Syntax –

primitive_gate #(rise delay, fall delay, turn-off delay) gate_instatiation (outputs, inputs);

Some syntax rules to be kept in mind are –

  • If all the three values are specified then, they are considered as rise, fall, and turn-off delays.
  • If two values are specified then, they are considered as rise and fall delays.
  • If only one delay is specified then, it is used for all delays.

Lets us see some examples which can be used in Verilog –

and #(2) and_gate_2 (out, in0, in1);       // all delay values are 2-time units
nand #(3,4,5) nand_gate_2 (out, in0, in1); // rise delay = 3, fall delay = 4, and turn-off delay = 5.
or #(3,4) or_gate_2 (out, in0, in1);       // rise delay = 3, fall delay = 4, and turn-off delay = min(3,4) = 3.

Verilog empowers us to control the delays more extensively in the form of min: typ: max values for each delay. Only one of the min/typ/max values can be used in the entire simulation run. It is specified at the start of the simulation and depends on the simulator used. To distinguish precisely, analyze the following example –

nand #(3:4:5,4:5:6,5:6:7) nand_gate_2 (out, in0, in1); // rise delay: min=3, typ=4, max=5, fall delay: min=4, typ=5, max=6, turn-off delay: min=5, typ=6, max=7.

Here, the typical value is the default value. In the above example, if the designer chooses min values, then rise delay = 3, fall delay = 4, turn-off delay = 5.

This helps the designer to have a much better real-time experience of design simulation, as in real-time logic circuits, the delays are not constant.

Difference between gate-level modeling and switch level modeling

Gate Level

Switch Level

The module is implemented in terms of logic gates and interconnections between these gates. The designer should know the gate-level diagram of the design. The design is specified as wiring between logic gates. Gate level is typically not used as it requires working out the interconnects, and it is not practical for large examples. This is the lowest level of abstraction. The design is described in terms of switching (modeling a transistor). The designer requires knowledge of transistors, like NMOS and PMOS, etc. It is not that useful in general logic design as compared to behavioral modeling.

About The Writer

CLOSE

Leave a Reply

Your email address will not be published. Required fields are marked *