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;
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 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)|
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
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
Correctly depicting that whenever both the inputs are high, the output is also high else the output is low.