In this tutorial, you will learn how to write an alternate version of the full adder using Verilog, a hardware description language (HDL). This may be your first experience with Verilog, which allows you to describe designs using text rather than schematics. This tutorial will only cover very simple Verilog combinational logic modules that use only assign statements. Later you will learn more Verilog, but the way you use Verilog modules in Active-HDL will remain the same.
You will find that there are many tools and options that have been left out of this tutorial for the sake of simplicity. You may want to experiment with Active-HDL on your own. This will make you more proficient with Active-HDL, and you may find different methods that better suit your style, while still achieving the same design goals.
This is a very simple introduction to Verilog that will allow you to define simple combinational blocks using Verilog. Figure 1 shows a simple schematic description of a 2-1 multiplexer along with the corresponding Verilog description of the multiplexer.
A Verilog module is defined by the module()/endmodule statements. A module definition is similar to a procedure definition in an ordinary programming language in that it defines a set of inputs and outputs and the functionality of the module. It is different since modules are not called like procedures; rather, they are “instantiated” or used in higher-level modules. Each input and output is listed in the module header, and then defined as an input or output by the input/output declarations. In this example, the inputs are A, B and S and the output is out.
Assign statements are used to define signal values as Boolean expressions. In this example, out is defined by the function AS’ + BS, but must be written in Verilog using the AND operator ( “&” ), OR operator (“|”), the XOR operator (“^”) and the NOT operator (“~”). It is important to remember that an assignment statement is identical to the corresponding schematic with gates wired to the inputs and outputs to define the Boolean function. In fact, assign statements are known as “continuous assignments” because, unlike assignment statements in a regular programming language, they are executed continuously, just like the corresponding gates in a schematic.
// This is a simple
Verilog implementation of the multiplexer function
module mux2 (A, B, S, out);
input A, B, S;
output
out;
assign out = (A & ~S) | (B & S);
endmodule
Figure 1 – Verilog for a 2-1 multiplexer
Figure 2 shows a slightly more complex module that uses busses and wires. The inputs A and B are 2-bit busses and are declared as a vector of bits. Note the declaration for busses in Verilog which differs from the declaration of an array in C or Java. Note especially the numbering from high-order bit to low-order bit.
Temporary signals, in this case the inverted inputs, which are used only inside the module are declared using the “wire” declaration. Inputs and outputs are just special wires; in fact, you will see redundant wire declarations in the Verilog files that Aldec generates.
// This is a simple Verilog implementation for a 2-bit
comparator
module compare2bit (A, B, EQ, GT);
input [1:0] A, B;
output EQ, GT;
wire [1:0] A_B, B_B; // Inverted signals for A and B
assign A_B[0] = ~A[0];
assign A_B[1] = ~A[1];
assign B_B[0] = ~B[0];
assign B_B[1] = ~B[1];
assign EQ = (A[1] & A[0] & B[1] &
B[0]) |
(A[1] & A_B[0] & B[1] & B_B[0])
|
(A_B[1] & A[0] & B_B[1] & B[0])
|
(A_B[1] & A_B[0] & B_B[1] &
B_B[0]);
assign GT = (A[1] & B_B[1]) | (A[0] &
B_B[1] & B_B[0]) | (A[1] & A[0] & B_B[0]);
endmodule
Figure 2 – Verilog for a 2-bit comparator
Verilog is a lot more powerful than we have shown here. For example, there are easier ways to specify the comparator function, but we will wait until later to introduce these concepts. For now, think of Verilog as an easy alternative to drawing a schematic. A few lines of code are often faster than creating the schematic by hand.
We will now create a simple Verilog module for a full-adder. It will implement exactly the same functionality as the full-adder schematic, but do so using Boolean expressions rather than gates.
Figure 3
Figure 4
Figure 5
Figure 6
7. To verify your Verilog module follow the procedure described in Tutorial #2 for test fixtures but now replace the schematic version of the full adder with your new Verilog module. First, Open the Symbols Toolbox and find the name of your design to expand your design’s part list. You should see a “Units without symbols” list. Expand it and find the name of your Verilog full adder. Select it, and notice that a block symbol appears in the bottom window of the Symbols Toolbox. Add this part to your test schematic by dragging the symbol from the bottom window. Notice that this component no longer appears in the “Units without symbols” list after it has been added to the schematic once. Now, simply disconnect the schematic-based full adder from the test fixture, and connect your new Verilog-based module. Test away.
Concluding Remarks
We have shown you how to make a Verilog module using the Wizard. You can also create an empty Verilog file and write the Verilog yourself, or copy an old Verilog file and edit it to be what you want. You can use whichever method is most convenient for you. Finally, you can edit the symbol that Aldec makes for you using the Symbol Editor. This allows you to move the pins around, change the size, and add text. For example, all the symbols in the lib370 library have been edited.