- 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 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, in0, in1);
and and_array1 (out, in0, in1);
and and_array2 (out, in0, in1);
and and_array3 (out, in0, in1);
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.
// 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.
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.
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);
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 >>|