In this post, we will design the AND logic gate using all the three modeling styles in Verilog. That is, using Gate Level, Dataflow, and Behavioral modeling. Notice the different approaches in the different styles to get the same end result (an AND gate). Let’s dive right in.

**Gate Level modeling**

We can design a logic circuit using basic logic gates with Gate level modeling. Verilog supports coding circuits using 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.

**Logic Circuit of the AND gate**

The AND gate is a primary logic gate where the output is equal to the product of its inputs. The output of this gate is high only if both the inputs are high else the output is low. Here’s the logical representation of the AND gate.

**Verilog code for AND gate using gate-level modeling**

The code for the AND gate would be as follows.

module AND_2(output Y, input A, B);

We start by declaring the module. `module`

, a basic building block in Verilog HDL is a keyword here to declare the module’s name. The `module`

command tells the compiler that we are creating something which has some inputs and outputs. AND_2 is the identifier. Identifiers are how we name the module. The list in parenthesis is the port list containing input and output ports. Then we write:

and(Y, A, B); endmodule;

Here `and`

is the operation performed on A, B, to get output Y. `endmodule`

terminates the module. Verilog has this functionality to describe the circuit at the gate level. The compiler understands that the `and`

operation means that it has to get a product of the inputs.

Here, you can look on the complete code:

module AND_2(output Y, input A, B); and(Y, A, B); endmodule

**Data flow modeling**

Compared to gate-level modeling, dataflow modeling is a higher level of abstraction. What this means is, you don’t really need to know the circuit design. That’s really helpful because gate-level modeling becomes very complicated for a complex circuit.

Hence dataflow modeling is a very important way of implementing the design. All you need to know is the boolean logic equation of the output of the circuit in terms of its inputs. We use continuous assignments in dataflow modeling in most of the designs. The continuous assignments are made using the keyword `assign`

. You’ll see how it works in a bit.

**Equation of the AND gate**

As we can observe from the diagram above, the boolean equation would be Y = A & B.

**Verilog code for AND gate using data-flow modeling**

We would again start by declaring the module.

module AND_2_data_flow (output Y, input A, B);

Then we use assignment statements in data flow modeling. Using

assign Y = A & B; endmodule

Just like the `and`

operation, the `&`

operator performs a binary multiplication of the inputs we write. Then `endmodule`

is used to terminate the module.

**Behavioral Modelling**

Behavioral modeling is the highest level of abstraction in the Verilog HDL. All that a designer need is the algorithm of the design, which is the basic information for any design. This level simulates the behavior of the circuits; the details are not specified. That’s helpful because the designer does not have to deal with complicated circuitry or equations. Just a simple truth table would suffice.

**AND gate’s truth table**

A |
B |
Y(A and B) |

0 | 0 | 0 |

0 | 1 | 0 |

1 | 0 | 0 |

1 | 1 | 1 |

**Equation from the truth table**

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

Y = A.B or say Y = A & B.

**Verilog code for AND gate using behavioral modeling**

Again, we begin by declaring module, setting up identifier as ` AND_2_behavioral`

, and the port list.

module AND_2_behavioral (output reg Y, input A, B);

In this case, 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. The `reg`

data object holds its value from one procedural assignment statement to the next and means it holds its value over simulation data cycles.

Then we write, always @ (A or B) begin ..... end

Using the `always`

statement, a procedural statement in Verilog, we run the program sequentially. `(A, B)`

is known as the sensitivity list or the trigger list. The sensitivity list includes all input signals used by the `always`

block. It controls 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 it.

Note that the always statement `always @(Y, A)`

could be written as `always @ *.`

` *`

would mean that the code itself has to decide on the input signals of the sensitivity list. Now, we have,

always @ (A or B) begin if (A == 1'b1 & B == 1'b1) begin Y = 1'b1; end else Y = 1'b0; end

The condition for AND gate is that if both the inputs are high, then the output is also high, else in every other condition that has to be low.

`if (A == 1'b1 & B == 1'b1)`

states that if both A and B are 1, then Y has to be 1, else 0.

Here is the full code-

module AND_2_behavioral (output reg Y, input A, B); always @ (A or B) begin if (A == 1'b1 & B == 1'b1) begin Y = 1'b1; end else Y = 1'b0; end endmodule

**RTL schematic of the AND gate**

Look at the schematic. So simple and elegant.

**Testbench of the AND 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 "AND_2_behavioral.v" module AND_2_behavioral_tb; reg A, B; wire Y; AND_2_behavioral Indtance0 (Y, A, B); initial begin A = 0; B = 0; #1 A = 0; B = 1; #1 A = 1; B = 0; #1 A = 1; B = 1; end initial begin $monitor ("%t | A = %d| B = %d| Y = %d", $time, A, B, Y); $dumpfile("dump.vcd"); $dumpvars(); end endmodule

**Simulation Waveform**

Correctly depicting that whenever both the inputs are high, the output is also high else the output is low.