Primitive Gates

Find the library of Verilog codes for all primitive gates. /* Green color Marked lines are comments, which give an explanation for each line of code. */


Module: A module in Verilog language is assumed to be like a black box containing electronic circuit, with input and output ports.

OR gate:


There are 3 types of modelings in Verilog:

(i) Dataflow

(ii) Behavioral

(iii) Gate level or Structural.


Dataflow: Represents boolean expressions of a digital circuit.

module orgate_dat(    /* module declaration with name */
output y,             /* Port declaration */
input a, b);
assign y = a|b;   /* This is called continuous assignment. Here we put boolean expression of Digital Circuit */
endmodule           /* Syntax to end a module */

Similarly for AND: y = a&b; for XOR y = a^b;

Behavioral: Depends only on the truth table or behavior of a circuit. It doesn’t depend on the boolean expression or the circuit components.

module orgate_beh(
output reg y,  /* reg for procedural assignment. */
input a, b);
always @(a, b) /* Process statement, elements inside parenthesis are called sensitivity list. When ever those elements change, this always block will execute. */
case({b, a})  /* Normal case statement, same as c. {b, a} is concatenation operator, since case in verilog works with only single variable, so to convert two variables into one, we use concatenation.*/
0: y = 0;     /* Assignment of a variable inside always or initial block is called Procedural Assignment, so y must be a register. */

1: y = 1;
2: y = 1;
3: y = 1;
default: y = 0;

Gate Level: Shows how gates are connected in a circuit.

module orgate_dat(
output y,/* output */
input a, b);/* input */

or (y, a, b); /* Gate module instantiation */

Similarly, for

AND: and (y, a, b)

The same syntax is followed for

nand, nor, xor, xnor.

Detailed Information on Gate level Modelling is posted here: Verilog HDL: Structural Modelling (Part-1)

Testbench: To test the output and behavior of the program.

module tb_orgate;
reg a, b; // Inputs as registers
wire y; // Outputs as wires
// Instantiate the Unit Under Test (UUT)
orgate_beh uut (.y(y), .a(a), .b(b)); // dot mapping
initial begin //Stimulus
a = 0; b = 0;  // give values to inputs for every 10ns
#10 a = 1; b = 0;
#10 a = 0; b = 1;
#10 a = 1; b = 1;


AND, XOR gates also can be written.

Please comment if you have any doubts.

Content First posted: 11/06/2017,
Content Updated: 02/08/2017.

8 thoughts on “Primitive Gates

Add yours

  1. Our team felt that our first code lacks vigor towards total comprehension of the newcomers of Verilog HDL.

    Verilog introduces concept of module.A module can be an element or a collection of lower-level design blocks.It provides necessary functionality to the higher-level block through its port interface( inputs and outputs ).

    An example:
    module () ;

    <module internals …


    Behavioral or algorithmic level
    This is the highest level of abstraction provided by Verilog HDL. A module can be implemented in terms of the desired design algorithm without concern for the hardware implementation details.

    Dataflow level
    At this level the module is designed by specifying the data flow. The designer is aware of how data flows between hardware registers and how the data is processed in the design.

    The above written program concerns with only two levels of modelling. The other two levels (Gate level and Switch level) will be discussed in subsequent programs.

    Reference: Verilog HDL A guide to Digital Design and Synthesis by Samir Palnitkar


  2. module orgate_dat(
    output y,
    input a, b);
    //Declaring input and output ports inside a module for an OR gate.
    assign y = a|b;
    //The keyword assign is used for Dataflow Modelling and the operator | is used to denote bitwise OR operator for the input variables.
    // any module should be closed with an endmodule


    module orgate_beh(
    output reg y,
    input a, b);

    //Declaring input and output ports inside a module for an OR gate.
    always @(*)

    //always@ blocks are used to describe events that should happen under certain conditions.(*) is called the sensitivity list. It is used in Behavioral Modelling only.

    case({b, a})

    //A case item contains a list of one or more case item expressions, separated by comma, and the case item statement.

    0: y = 0; //case 0
    1: y = 1; //case 1
    2: y = 1; //case 2
    3: y = 1; //case 3
    default: y = 0; // syntax of case statement
    //Case statement ends with keyword endcase

    Liked by 1 person

    1. One thing to note here is that the always@(*) construct should only be used for designing combinational blocks and hence inside an always @ (*) block only blocking assignment must be used.

      The {} is a concatenation operator and hence if a=1 and b=0 then {a,b} would be 10, a case statement must be given higher preference than the if else statement, in the above example {b,a} can have 3 possible values like 0,1,2 & 3 so the case statement compares the incloming {b,a} value and performs the required operation, if {b,a} doesnot fall into any of the values listed above then it takes up the default case.

      A case statement must always be written inside an always block, the always block is a block which is executed when a particular event occurs, for example, if we write

      always @(a,b) // the statement inside the always block will get executed if any one or both a and b change.
      begin // For multiple lines statements a begin and end statement is needed, but its a good practice to
      y<=a & b; // write it

      The always block is used to model sequential circuits, consider a D FF code.

      module DFF(q,d,clk,reset); //Module name is DFF and port names are written inside parentheses
      output reg q; // q is defined as output of D FF
      input d,clk,reset; // d,clk and reset are taken as inputs

      always @(posedge clk) // The block executes for every posedge i.e. rising edge of the clock

      if(reset) // The reg in the reg q shouldn't be confused with the Digital Register, we have defined
      // q as a reg because at every posedge (rising edge) of the clock (clk) the value of q changes
      q<=0; // and hence it must be able to hold its current value until the next value arrives.
      else // As a thumb rule any output inside an always block must be defined as a reg, note that inputs
      q<=d; // cannot be defined as reg, so input reg d is invalid.


      Note that I have used q<=0; and not q=0;, the <= operator is called as the non-blocking assignment and = is called as blocking assignment, consider this.

      Here b=d will not execute until a=0; gets executed similarly c=e; will only execute after b=d; has been executed, this assignment is mostly used to model combinational circuits.

      Now for,

      Here all the above 3 statements will execute parallelly, i.e they won't wait for each other, this assignment is used mostly to model sequential circuits, note that Non-blocking assignment must be used inside an always block only.

      To simulate your Verilog codes you can, for now, visit

      Liked by 1 person

      1. It is suggested that we do commenting by /* and */ start and end comment operators, as the comments are going multiple lines….


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Powered by

Up ↑

%d bloggers like this: