Most digital designs are done at a higher level of abstraction like RTL, although at times it becomes intuitive to build smaller deterministic circuits at a lower level by using combinational elements like and and or. Modeling done at this level is usually called gate level modeling as it involves gates and has a one to one relation between a hardware schematic and the Verilog code.
Verilog supports a few basic logic gates known as primitives as they can be instantiated like modules since they are already predefined. Other complex behavior can be defined under Verilog User Defined Primitives.
Gate Types | Syntax | Description |
---|---|---|
and | and u0(out, i1, i2, …) | Performs AND operation on two or more inputs |
or | or u0(out, i1, i2, …) | Performs OR operation on two or more inputs |
xor | xor u0(out, i1, i2, …) | Performs XOR operation on two or more inputs |
nand | nand u0(out, i1, i2, …) | Performs NAND operation on two or more inputs |
nor | nor u0(out, i1, i2, …) | Performs NOR operation on two or more inputs |
xnor | xnor u0(out, i1, i2, …) | Performs XNOR operation on two or more inputs |
buf | buf u0(out, in) | The buffer (buf) passes input to the output as it is. It has only one scalar input and one or more scalar outputs. |
not | not u0(out, in) | The not passes input to the output as an inverted version. It has only one scalar input and one or more scalar outputs. |
bufif1 | bufif1 u0(out, in, control) | It is the same as buf with additional control over the buf gate and drives input signal only when a control signal is 1. |
notif1 | notif1 u0(out, in, control) | It is the same as not having additional control over the not gate and drives input signal only when a control signal is 1. |
bufif0 | bufif0 u0(out, in, control) | It is the same as buf with additional inverted control over the buf gate and drives input signal only when a control signal is 0 |
notif0 | notif0 u0(out, in, control) | It is the same as not with additional inverted control over the not gate and drives input signal only when a control signal is 0. |
And/Or/Xor Gates
These primitives implement an AND and an OR gate which takes many scalar inputs and provide a single scalar output. The first terminal in the list of arguments to these primitives is the output which gets updated whenever any of the inputs change.

module gates ( input a, b,
output c, d, e);
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 tb;
reg a, b;
wire c, d, e;
integer i;
gates u0 ( .a(a), .b(b), .c(c), .d(d), .e(e));
initial begin
{a, b} = 0;
$monitor ("[T=%0t a=%0b b=%0b c(and)=%0b d(or)=%0b e(xor)=%0b", $time, a, b, c, d, e);
for (i = 0; i < 10; i = i+1) begin
#1 a <= $random;
b <= $random;
end
end
endmodule
ncsim> run [T=0 a=0 b=0 c(and)=0 d(or)=0 e(xor)=0 [T=1 a=0 b=1 c(and)=0 d(or)=1 e(xor)=1 [T=2 a=1 b=1 c(and)=1 d(or)=1 e(xor)=0 [T=4 a=1 b=0 c(and)=0 d(or)=1 e(xor)=1 [T=5 a=1 b=1 c(and)=1 d(or)=1 e(xor)=0 [T=6 a=0 b=1 c(and)=0 d(or)=1 e(xor)=1 [T=7 a=1 b=0 c(and)=0 d(or)=1 e(xor)=1 [T=10 a=1 b=1 c(and)=1 d(or)=1 e(xor)=0 ncsim: *W,RNQUIE: Simulation is complete.
Nand/Nor/Xnor Gates
The inverse of all the above gates are also available in the forms of nand
, nor
and xnor
. The same design from above is reused with the exception that the primitives are switched with their inverse versions.

module gates ( input a, b,
output c, d, e);
// Use nand, nor, xnor instead of and, or and xor
// in this example
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 tb;
reg a, b;
wire c, d, e;
integer i;
gates u0 ( .a(a), .b(b), .c(c), .d(d), .e(e));
initial begin
{a, b} = 0;
$monitor ("[T=%0t a=%0b b=%0b c(nand)=%0b d(nor)=%0b e(xnor)=%0b", $time, a, b, c, d, e);
for (i = 0; i < 10; i = i+1) begin
#1 a <= $random;
b <= $random;
end
end
endmodule
ncsim> run [T=0 a=0 b=0 c(nand)=1 d(nor)=1 e(xnor)=1 [T=1 a=0 b=1 c(nand)=1 d(nor)=0 e(xnor)=0 [T=2 a=1 b=1 c(nand)=0 d(nor)=0 e(xnor)=1 [T=4 a=1 b=0 c(nand)=1 d(nor)=0 e(xnor)=0 [T=5 a=1 b=1 c(nand)=0 d(nor)=0 e(xnor)=1 [T=6 a=0 b=1 c(nand)=1 d(nor)=0 e(xnor)=0 [T=7 a=1 b=0 c(nand)=1 d(nor)=0 e(xnor)=0 [T=10 a=1 b=1 c(nand)=0 d(nor)=0 e(xnor)=1 ncsim: *W,RNQUIE: Simulation is complete.
These gates can have more than two inputs.
module gates ( input a, b, c, d,
output x, y, z);
and (x, a, b, c, d); // x is the output, a, b, c, d are inputs
or (y, a, b, c, d); // y is the output, a, b, c, d are inputs
nor (z, a, b, c, d); // z is the output, a, b, c, d are inputs
endmodule
module tb;
reg a, b, c, d;
wire x, y, z;
integer i;
gates u0 ( .a(a), .b(b), .c(c), .d(d), .x(x), .y(y), .z(z));
initial begin
{a, b, c, d} = 0;
$monitor ("[T=%0t a=%0b b=%0b c=%0b d=%0b x=%0b y=%0b x=%0b", $time, a, b, c, d, x, y, z);
for (i = 0; i < 10; i = i+1) begin
#1 a <= $random;
b <= $random;
c <= $random;
d <= $random;
end
end
endmodule
ncsim> run [T=0 a=0 b=0 c=0 d=0 x=0 y=0 x=1 [T=1 a=0 b=1 c=1 d=1 x=0 y=1 x=0 [T=2 a=1 b=1 c=1 d=0 x=0 y=1 x=0 [T=3 a=1 b=1 c=0 d=1 x=0 y=1 x=0 [T=4 a=1 b=0 c=1 d=0 x=0 y=1 x=0 [T=5 a=1 b=0 c=1 d=1 x=0 y=1 x=0 [T=6 a=0 b=1 c=0 d=0 x=0 y=1 x=0 [T=7 a=0 b=1 c=0 d=1 x=0 y=1 x=0 [T=8 a=1 b=1 c=1 d=0 x=0 y=1 x=0 [T=9 a=0 b=0 c=0 d=1 x=0 y=1 x=0 [T=10 a=0 b=1 c=1 d=1 x=0 y=1 x=0 ncsim: *W,RNQUIE: Simulation is complete.
Buf/Not Gates
These gates have only one scalar input and one or more outputs. buf
stands for a buffer and simply transfer the value from input to the output without any change in polarity. not
stands for an inverter which inverts the polarity of the signal at its input. So a 0 at its input will yield a 1 and vice versa.

module gates ( input a,
output c, d);
buf (c, a); // c is the output, a is input
not (d, a); // d is the output, a is input
endmodule
module tb;
reg a;
wire c, d;
integer i;
gates u0 ( .a(a), .c(c), .d(d));
initial begin
a = 0;
$monitor ("[T=%0t a=%0b c(buf)=%0b d(not)=%0b", $time, a, c, d);
for (i = 0; i < 10; i = i+1) begin
#1 a <= $random;
end
end
endmodule
xcelium> run [T=0 a=0 c(buf)=0 d(not)=1 [T=2 a=1 c(buf)=1 d(not)=0 [T=8 a=0 c(buf)=0 d(not)=1 [T=9 a=1 c(buf)=1 d(not)=0 xmsim: *W,RNQUIE: Simulation is complete.
The last terminal in the port list connects to the input of the gate and all other terminals connect to the output port of the gate. Here is an example of a multiple output buffer, although it is rarely used.
module gates ( input a,
output c, d);
not (c, d, a); // c,d is the output, a is input
endmodule
xcelium> run [T=0 a=0 c=1 d=1 [T=2 a=1 c=0 d=0 [T=8 a=0 c=1 d=1 [T=9 a=1 c=0 d=0 xmsim: *W,RNQUIE: Simulation is complete.
Bufif/Notif
Buffers and Inverters with an additional control signal to enable the output is available through bufif
and notif
primitives. These gates have a valid output only if the control signal is enabled else the output will be in high impedance. There are two versions of these, one with normal polarity of control indicated by a 1 like bufif1
and notif1
and second with inverted polarity of control indicated by a 0 like bufif0
and notif0
.

