From the course: Learning Verilog for FPGA Development

Verilog modules

- [Instructor] Modules are the building blocks of Verilog. They are similar to object constructors in traditional programming languages because you use them to create new instances of the object or module. Typically Verilog modules contain the following elements: The hardware, that implements the internal circuitry of the module. A list of ports, which act as inputs output or bidirectional pins. The internal connections required to implement the module. These may be simple wires, busses or even registers. Some parts of the code may include sequential lines of code and even delays. And finally, since this is a modular structure, Verilog modules typically instantiate other modules that may come from some other source files in your project or from a library provided by an IP vendor. Let's see an example of a Verilog module, describing a full adder. This is a circuit that takes in, three one bit numbers as inputs to produce their two bit addition as outputs. It's a popular building block of a ripple adder. As you can see in this schematic, this module includes one or gate and two instances of another module, the half adder. Now let's look at the code to get you familiar with the syntax in a Verilog module. In Verilog, the code of a module is enclosed between a declaration line and the end module keyword. The declaration line looks very much like a function or method declaration in C or Java but it ends with a semicolon. This line starts with the module keyword, followed by the module name. This one is called full adder. Next we have the ports list, which is a list of all the terminals that connect our module to the outside. These ports can have one of three types, input output or in-out for bidirectional ports. In this example we have three inputs, A, B, and Cin and two outputs, S and Cout. In the next line, we are declaring three wires named P, G and H. These will be useful to interconnect the three elements inside the module. The next two lines instantiate the two half adders. Although these modules are very simple with only two gates, they are implemented in another piece of code and we will simply create two instances. To instantiate a module, you first need to specify the name of the module, followed by the name of the instance and then assign the lines you want to connect to the ports in the module. Keep looking at the schematic to make sense of the following connections in the code. The first half adder is named ha1 and it takes A and B as its inputs. Its sum output is connected to the wire P and it's curry output is connected to the wire G. The second half adder is named ha2 and it takes P and Cin as inputs. Its sum output is connected to the output S and its curry output is connected to the wire H. Finally we have the or gate. Notice that naming gates is optional. This gate is unnamed and it takes G and H as inputs while its output goes to the output port Cout. Finally, let me tell you about a convention for writing the declaration and instantiation of modules in Verilog. This is how the full adder declaration looks when following this convention. Notice that it's the same code as the one-line declaration we just saw. The convention goes like this, in the port list, each port should occupy its own line of text. Yes, it makes the code lengthier in lines of code but it's considered more readable. Now this is just a convention, it's not mandatory but you're pretty much expected to follow it and you'll see it used throughout the course.

Contents