View Course Path

Verilog Code for NOT gate – All modeling styles

In this post, we will learn to describe NOT logic gate using three modeling styles in Verilog, namely Gate Level, Dataflow, and Behavioral modeling.

Gate level modeling relates to describing the circuit in terms of basic logic gates. The gates are wired according to the circuit. Gate level modeling is easier to understand at first glance as it relates directly to the circuit. The dataflow design comprises describing the circuit in terms of movement of data, and it is another lower level of abstraction. The third type of modeling is the behavioral modeling, where we describe the design in terms of high-level abstraction, the core behavior of the circuit.

Gate Level modeling

Hardware design at this level is intuitive for a user with a basic knowledge of digital logic design because it is possible to see a one-to-one correspondence between the logic circuit diagram and the Verilog description. A logic circuit can be designed by the use of logic gates. Verilog supports basic logic gates as predefined primitives. These primitives are instantiated like modules except that they are predefined in Verilog and do not need a module definition. All logic circuits can be designed by using basic gates.

Logic Circuit of the NOT gate

NOT gate is a basic gate. It has one input and one output. The output of the NOT gate is high if the input is low and vice-versa. Here’s the logical representation of the NOT gate.

Verilog code for NOT gate using gate-level modeling

We begin the hardware description for the NOT gate as follows:

module NOT_gate_level(output Y, input A);

In Verilog HDL, we define the module using module, a basic building block. NOT_gate_level is the identifier here. The list in parenthesis contains input and output ports, called the port list. As Verilog has primitives, we can then write:

    not(Y, A);

Verilog has this feature to describe the gate-level circuit. Here, not is the operation carried out on A to obtain output Y. endmodule terminates the module.

Here is the complete code for your convenience:

module NOT_gate_level(output Y, input A);
    not (Y, A);

Data flow level

For small circuits, the gate-level modeling approach works because the number of gates is limited, and the designer can instantiate and connect every gate individually. Also, gate-level modeling is very intuitive to the designer.

However, the designer can not design when the number of gates is large. Hence we have dataflow modeling, where we implement the function at a level of abstraction higher than the gate level.

Verilog allows us to design the circuit in terms of the data flow between registers and the way data is processed rather than an instantiation of a gate. The approach of data flow allows us to concentrate on optimizing the circuit in terms of dataflow.

Equation of the NOT gate

The boolean equation of a NOT gate is Y = A’.

Verilog code for NOT gate using dataflow modeling

We would again start by declaring the module. The way it goes is as follows-

module NOT_data_flow (output Y, input A);

module is a keyword, NOT_data_flow is the identifier, (output Y, input A) is the port list. Then we have semicolon to end the statement.

Next is the assignment statement in data flow modeling.

    assign Y = ~A;

The ~ operator performs the NOT operation on the input we provide. endmodule  is used to terminate the module.

You may look over the entire description here.

module NOT_data_flow (output Y, input A);
    assign Y = ~A;

Behavioral Modeling

As the complexity of any digital circuit increases, it becomes crucial to make trade-offs of various architectures and algorithms. A chip designer needs to focus on optimum architecture and algorithms to implement. Hence, we can use a higher algorithmic level where we do not think in terms of the logic gates or data flow. Verilog provides the ability to describe design functionality in an algorithm manner, or we can say in terms of the behavior of the circuit. This behavior of the circuit can be understanding using its truth table.

Truth Table for NOT gate

A Y(A Complement)
0 1
1 0

Equation from the truth table

Simply by minimization, (or you may arrive by k-maps), we can state that:

Y = A’ or say Y = A Complement.

Verilog code for NOT gate using behavioral modeling

We begin by declaring module, setting up identifier as  NOT_2_behavioral, and the port list.

module NOT_behavioral (output reg Y, input A);

The port list includes the output and input ports. When our level of abstraction is behavioral level, then we use reg datatype in the output ports. In Verilog, a reg is just a variable, not a hardware register. All the assignments in an always block must be assigned to a reg variable. If the always block assigns a value to the reg variable for all possible executions, then the reg variable is not a hardware register. These types of data objects hold the value from one procedural assignment statement to the next. Then, we write,

always @ (A) begin.....end

An always block is a behavioral block which contains a list of expressions which are evaluated sequentially. This list is called the sensitivity list or trigger list. Here, (A, B) is the sensitivity list or the trigger list. It includes all signals used by the always block. It changes when the statements in the always block are to be evaluated. @ is a part of the syntax, used before the sensitivity list. In Verilog, begin  embarks and end concludes any block which contains more than one statement in itself.

The description in an always block can be very abstract similar to C. Therefore we have,

always @ (A) begin
   if (A == 1'b0) begin
       Y = 1'b1;
  else if (A == 1'b1) begin
       Y = 1'b0;

The condition for the NOT gate is that if the input is low, the output is high and vice-versa.

if (A == 1'b0) states that if  A is 0, Y = 1'b1; then Y has to be 1. == is the symbol for testing logical equality, 1’b1 conveys that the number is of 1 bit in the binary number system, and its value is 1. Here is the full code:

module NOT_behavioral (output reg Y, input A);
always @ (A) begin
    if (A == 1'b0 ) begin
        Y = 1'b1;
    else if (A == 1'b1) begin
       Y = 1'b0;

RTL schematic of NOT gate


Testbench of the NOT gate using Verilog

The file to be included and the name of the module changes, but the basic structure of the testbench remains the same in all the three modeling styles.

`include "NOT_behavioral.v"
module NOT_behavioral_tb;
reg A;wire Y;
NOT_behavioral Instance0 (Y, A);
initial begin
     A = 0;
  #1 A = 1;
  #1 A = 0;
 endinitial begin
    $monitor ("%t | A = %d| Y = %d", $time, A, Y);

Simulation Waveform

By observing the waveforms, we can derive that whenever the input A is low, then the output is high, else the output is low.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.