Gate-Level Modeling

>> Introduction
>> Gate Primitives
>> Delays
>> Examples


In Verilog HDL a module can be defined using various levels of abstraction. There are four levels of abstraction in verilog. They are:

  • Behavioral or algorithmic level: This is the highest level of abstraction. A module can be implemented in terms of the design algorithm. The designer no need to have any knowledge of hardware implementation.
  • Data flow level: In this level the module is designed by specifying the data flow. Designer must how data flows between various registers of the design.
  • Gate level: The module is implemented in terms of logic gates and interconnections between these gates. Designer should know the gate-level diagram of the design.
  • Switch level: This is the lowest level of abstraction. The design is implemented using switches/transistors. Designer requires the knowledge of switch-level implementation details.
Gate-level modeling is virtually the lowest-level of abstraction, because the switch-level abstraction is rarely used. In general, gate-level modeling is used for implementing lowest level modules in a design like, full-adder, multiplexers, etc. Verilog HDL has gate primitives for all basic gates.

Gate Primitives

Gate primitives are predefined in Verilog, which are ready to use. They are instantiated like modules. There are two classes of gate primitives: Multiple input gate primitives and Single input gate primitives.
Multiple input gate primitives include and, nand, or, nor, xor, and xnor. These can have multiple inputs and a single output. They are instantiated as follows:

// Two input AND gate.
and and_1 (out, in0, in1);

// Three input NAND gate.
nand nand_1 (out, in0, in1, in2);

// Two input OR gate.
or or_1 (out, in0, in1);

// Four input NOR gate.
nor nor_1 (out, in0, in1, in2, in3);

// Five input XOR gate.
xor xor_1 (out, in0, in1, in2, in3, in4);

// Two input XNOR gate.
xnor and_1 (out, in0, in1);

Note that instance name is not mandatory for gate primitive instantiation. The truth tables of multiple input gate primitives are as follows:

Single input gate primitives include not, buf, notif1, bufif1, notif0, and bufif0. These have a single input and one or more outputs. Gate primitives notif1, bufif1, notif0, and bufif0 have a control signal. The gates propagate if only control signal is asserted, else the output will be high impedance state (z). They are instantiated as follows:

// Inverting gate.
not not_1 (out, in);

// Two output buffer gate.
buf buf_1 (out0, out1, in);

// Single output Inverting gate with active-high control signal.
notif1 notif1_1 (out, in, ctrl);

// Double output buffer gate with active-high control signal.
bufif1 bufif1_1 (out0, out1, in, ctrl);

// Single output Inverting gate with active-low control signal.
notif0 notif0_1 (out, in, ctrl);

// Single output buffer gate with active-low control signal.
bufif0 bufif1_0 (out, in, ctrl);

The truth tables are as follows:

Array of Instances:

wire [3:0] out, in0, in1;
and and_array[3:0] (out, in0, in1);

The above statement is equivalent to following bunch of statements:

and and_array0 (out[0], in0[0], in1[0]);
and and_array1 (out[1], in0[1], in1[1]);

and and_array2 (out[2], in0[2], in1[2]);
and and_array3 (out[3], in0[3], in1[3]);

>> Examples

Gate Delays:

In Verilog, a designer can specify the gate delays in a gate primitive instance. This helps the designer to get a real time behavior of the logic circuit.

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 high impedance state, from another value 1, x, or z.
  • If the gate output changes to x, the minimum of the three delays is considered.
  • If only one delay is specified, it is used for all delays.
  • If two values are specified, they are considered as rise, and fall delays.
  • If three values are specified, they are considered as rise, fall, and turn-off delays.
  • The default value of all delays is zero.
and #(5) and_1 (out, in0, in1);
// All delay values are 5 time units.

nand #(3,4,5) nand_1 (out, in0, in1);
// rise delay = 3, fall delay = 4, and turn-off delay = 5.

or #(3,4) or_1 (out, in0, in1);
// rise delay = 3, fall delay = 4, and turn-off delay = min(3,4) = 3.

There is another way of specifying delay times in verilog, Min:Typ:Max values for each delay. This helps designer to have a much better real time experience of design simulation, as in real time logic circuits the delays are not constant. The user can choose one of the delay values using +maxdelays, +typdelays, and +mindelays at run time. The typical value is the default value.

and #(4:5:6) and_1 (out, in0, in1);
// For all delay values: Min=4, Typ=5, Max=6.

nand #(3:4:5,4:5:6,5:6:7) nand_1 (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.

In the above example, if the designer chooses typical values, then rise delay = 4, fall delay = 5, turn-off delay = 6.


1. Gate level modeling of a 4x1 multiplexer.

The gate-level circuit diagram of 4x1 mux is shown below. It is used to write a module for 4x1 mux.

module 4x1_mux (out, in0, in1, in2, in3, s0, s1);

// port declarations
output out; // Output port.
input in0, in1, in2. in3; // Input ports.
input s0, s1; // Input ports: select lines.

// intermediate wires
wire inv0, inv1; // Inverter outputs.
wire a0, a1, a2, a3; // AND gates outputs.

// Inverters.
not not_0 (inv0, s0);
not not_1 (inv1, s1);

// 3-input AND gates.
and and_0 (a0, in0, inv0, inv1);
and and_1 (a1, in1, inv0, s1);
and and_2 (a2, in2, s0, inv1);
and and_3 (a3, in3, s0, s1);

// 4-input OR gate.
or or_0 (out, a0, a1, a2, a3);


2. Implementation of a full adder using half adders.

Half adder:

module half_adder (sum, carry, in0, in1);

output sum, carry;
input in0, in1;

// 2-input XOR gate.
xor xor_1 (sum, in0, in1);

// 2-input AND gate.
and and_1 (carry, in0, in1);


Full adder:

module full_adder (sum, c_out, ino, in1, c_in);

output sum, c_out;
input in0, in1, c_in;

wire s0, c0, c1;

// Half adder : port connecting by order.
half_adder ha_0 (s0, c0, in0, in1);

// Half adder : port connecting by name.
half_adder ha_1 (.sum(sum),

// 2-input XOR gate, to get c_out.
xor xor_1 (c_out, c0, c1);


<< Previous Home  Next >>   



Faisal Kabir said...

Here multiplexer is designed for 1 bit. Can any body tell me how to design 4 bit multiplexer?

Shashank S said...

Thanks a lot for the code but I think the carry-out is OR function and not XOR.

Anonymous said...

can anybody tell me how to write verilog code for 8 bit comparator and bcd adder?????

MaheKarim said...

This Page Full Live Tutorial Click Here
Full Adder, Half Adder Video/Text Tutorial Click Here

Pruthvi Simhadri said...

In the last code ie,.. full adder using half adder every thing is okay..but while calling the half adder module by a name ha_1 why you have used dots while initialising the inputs and outputs...why

Deba Sheesh said...

Great post, you have pointed out some excellent points, I as well believe this is a very superb website.
Plastic Flow Meter

 Save and Share: Digg Reddit Facebook Mixx Google YahooMyWeb blogmarks Blue Dot StumbleUpon Bumpzee Furl Sphinn Ma.gnolia MisterWong Propeller Simpy TwitThis Wikio BlinkList NewsVine