136 lines
3.3 KiB
Markdown
136 lines
3.3 KiB
Markdown
Modules are the building block through which Verilog is built.
|
|
|
|
Each module can be thought of as a black box with a series of inputs, and a series of outputs. Changing the input changes the outputs.
|
|
|
|
Module definitions are started with the `module` keyword, and closed with the `endmodule` keyword.
|
|
|
|
## Syntax
|
|
The general syntax of a module is as follows:
|
|
```verilog
|
|
// This line is referred to as the *module header*
|
|
module <name> ([port_list]);
|
|
// Contents of the module
|
|
endmodule
|
|
|
|
// The port list is optional
|
|
module <name>;
|
|
// Contents
|
|
endmodule
|
|
```
|
|
|
|
Below is an example of the structure of a half adder module:
|
|
```verilog
|
|
module half_adder(
|
|
input a,
|
|
input b,
|
|
output sum_bit,
|
|
output carry_bit
|
|
);
|
|
// ------- snip ------------
|
|
endmodule
|
|
```
|
|
|
|
## Ports
|
|
Ports are a set of signals that act as input and outputs for a particular module.
|
|
|
|
There are 3 kinds of ports:
|
|
- `input`: Input ports can only receive values from the outside. `input` ports cannot be written to.
|
|
- `output`: Output ports can be written to, but not read from.
|
|
- `inout`: Inout ports can send *and* receive values.
|
|
|
|
Ports can be declared in the port list, or in the module body. Ports declared in the port list can optionally omit their type and only declare a name, to be specified within the body of the module:
|
|
```verilog
|
|
module half_adder(
|
|
a,
|
|
b,
|
|
sum_bit,
|
|
carry_bit
|
|
);
|
|
input a;
|
|
input b;
|
|
output sum_bit;
|
|
output carry_bit;
|
|
// ----------- snip -----------
|
|
endmodule
|
|
```
|
|
|
|
The full type of a port can also be defined within the portlist:
|
|
```verilog
|
|
```verilog
|
|
module half_adder(
|
|
input wire a,
|
|
input wire b,
|
|
output wire sum_bit,
|
|
output wire carry_bit
|
|
);
|
|
input a;
|
|
input b;
|
|
output sum_bit;
|
|
output carry_bit;
|
|
// ----------- snip -----------
|
|
endmodule
|
|
```
|
|
|
|
### Port types
|
|
If no type is defined, ports are implicitly defined as *nets* of type `wire`.
|
|
|
|
> In verilog, the term *net* refers to network, and it refers to a connection that joins two or more devices together.
|
|
|
|
Ports can be a vector type:
|
|
```verilog
|
|
module test(a, b, c);
|
|
input [7:0] a;
|
|
input [7:0] b;
|
|
output [7:0] c;
|
|
// -------- snip ---------
|
|
endmodule
|
|
```
|
|
|
|
# Instantiation
|
|
Larger designs can be built by using multiple smaller modules.
|
|
|
|
Modules can be *instantiated* within other modules and ports, and these *instances* can be connected with other signals.
|
|
|
|
These port connections can be defined by an *ordered list*, or by *name*.
|
|
|
|
### By Ordered List
|
|
```verilog
|
|
module submodule (input x, y, z, output o);
|
|
// ------- snip -------
|
|
endmodule
|
|
|
|
module parent;
|
|
wire a, b, c;
|
|
wire o;
|
|
// Similar to C, the type of the module is first, followed by
|
|
// the name of the module instance.
|
|
submodule foo (a, b, c, o);
|
|
endmodule
|
|
```
|
|
|
|
### By Name
|
|
Ports can also be joined by explicitly defining the name.
|
|
|
|
Syntactically, this is done with a dot (`.`), followed by the port name defined by the design, followed by the signal name to connect, wrapped in parenthesis (`.x(a)`).
|
|
```verilog
|
|
module submodule (input x, y, z, output o);
|
|
// ------------snip-----------------
|
|
endmodule
|
|
|
|
module parent;
|
|
wire a, b, c;
|
|
wire o;
|
|
submodule foo (
|
|
.x(a),
|
|
.y(b),
|
|
.z(c),
|
|
.o(o)
|
|
);
|
|
```
|
|
|
|
Because association is done by name, the order of definition does not matter.
|
|
|
|
### Unconnected ports
|
|
Ports that are not connected to any wire by the parent module will have a value of high impedance, and is considered unknown/undefined.
|
|
|