Verilog Module Instantiations are a key technique when building complex designs in Verilog, enabling the creation of hierarchical structures by combining multiple modules. This process involves instantiating modules within one another and connecting their ports to signals in the parent module. There are two main methods for establishing these connections: Port Connection by Ordered List and Port Connection by Name, each offering unique advantages for modular design and clarity.
Let’s explore both methods in detail, along with handling Unconnected or Floating Ports.
Port Connection by Ordered List in Verilog Module Instantiations
In Verilog, one way to connect ports is by using an ordered list. This means that the ports in the instantiated module are linked to signals in the parent module based on their order in the module declaration.
Example of Ordered List Connection |Verilog Module Instantiations
Consider the following design:
module mydesign (
input x, y, z, // x is at position 1, y at 2, z at 3
output o // o is at position 4
);
endmodule
module tb_top;
wire [1:0] a;
wire b, c;
// Port connection by order:
// a[0] connects to x, b connects to y, a[1] connects to z, and c connects to o
mydesign d0 (a[0], b, a[1], c);
endmodule
In the example above:
a[0]
connects tox
because it is the first port.b
connects toy
(second position).a[1]
connects toz
(third position).c
connects too
(fourth position).
Drawbacks of Ordered List Connection in Verilog Module Instantiations
- Inconvenient when adding new ports: If a new port is added or if the order changes, it can break the connections.
- Not flexible: The ports must always be connected in the same order as in the module declaration.
Port Connection by Name
A more flexible and readable method for connecting ports is by explicitly naming each port in the instantiation. This method avoids confusion, as the connection is based on the port names rather than their order in the module declaration.
Example of Named Port Connection
module design_top;
wire [1:0] a;
wire b, c;
// Port connection by name:
// x is connected to a[0], y to b, z to a[1], and o to c
mydesign d0 (
.x(a[0]), // x connected to a[0]
.y(b), // y connected to b
.z(a[1]), // z connected to a[1]
.o(c) // o connected to c
);
endmodule
In this example, the connection order doesn’t matter. The port names (such as .x
, .y
, .z
, .o
) explicitly match the signal names inside the parent module. This method is preferred for large designs.
Advantages of Named Port Connection in Verilog Module Instantiations
- Order doesn’t matter: You can connect ports in any order.
- Easier to debug: Errors are easier to track because each connection is named and isolated.
- Improved readability: The code is clear about which signals are connected to which ports.
Common Errors in Named Connection in Verilog Module Instantiations
- Multiple connections to the same port: You cannot connect the same port more than once. For example:
module design_top;
mydesign d0 (
.x(a[0]),
.z(a[1]), // z at second position is okay because of explicit connection
.y(a[1]), // Error: x is already connected to a[0], you can't connect it again
.o(c)
);
endmodule
Unconnected/Floating Ports
In some cases, a port might not be connected to anything in the parent module. These are known as unconnected ports or floating ports. When a port is left unconnected, it will have a high-impedance value (Z
).
Example of Unconnected Ports
module design_top;
mydesign d0 (
.y(a[1]),
.z(a[1]),
.o() // Unconnected output; will be high impedance (Z)
);
endmodule
In this example:
- The input port
x
is not connected, so it will beZ
(high impedance). - The output port
o
is also left unconnected, so it will also beZ
.
Floating Ports in Simulation
Unconnected ports in simulations will typically show up as hZ
in waveforms, represented by an orange line in the middle of the waveform.
Example: Shift Register with Unconnected Ports
Consider this example of a shift register where some output ports are left unconnected:
module shift_reg (
input d,
input clk,
input rstn,
output q
);
wire [2:0] q_net;
// D flip-flops with some unconnected outputs
dff u0 (.d(d), .clk(clk), .rstn(rstn), .q(q_net[0]));
dff u1 (.d(q_net[0]), .clk(clk), .rstn(rstn), .q()); // q is unconnected
dff u2 (.d(q_net[1]), .clk(clk), .rstn(rstn), .q()); // q is unconnected
dff u3 (.d(q_net[2]), .clk(clk), .rstn(rstn), .q(q));
endmodule
In this shift register example:
- The output ports from
u1
andu2
are unconnected and will beZ
. - The signal
q
fromu3
is connected to the final output.
Key Points About Floating Ports:
- Unconnected ports are high-impedance (
Z
), both in synthesis and simulation. - In synthesis, unconnected ports might be treated as grounded or left unconnected.
- Always verify connections to avoid high-impedance states in critical signals.
Port Type Rules in Verilog
Case #1: Inputs Are Implicitly Wires
Inputs are automatically considered wires in Verilog, so you don’t need to specify the type:
module des0_1 (input wire clk, ...); // "clk" is implicitly a wire
module des0_2 (input clk, ...); // "clk" is implicitly a wire
Case #2: Inputs Cannot Be Reg
You cannot declare input ports as reg
because they are continuously driven by external signals:
module des1 (input reg clk, ...); // Illegal: Inputs cannot be reg
Case #3: Connecting Ports of Different Widths
When connecting ports of different widths, the smaller width will prevail:
module des2 (output [3:0] data, ...); // 4-bit output
module des3 (input [7:0] data, ...); // 8-bit input
module top;
wire [7:0] net;
des2 u0 (.data(net)); // Only the lower 4 bits of "net" are connected
des3 u1 (.data(net)); // 8-bit connection is possible
endmodule
Case #4: Outputs Cannot Connect to Reg in Parent Module
Outputs from modules should not connect to reg
signals in the parent module:
module top_0;
reg [3:0] data_reg;
des2 u0 (.data(data_reg)); // Illegal: Output can't be connected to a reg
endmodule
Conclusion
In Verilog, module instantiation and port connection are fundamental for designing complex systems. Ordered list connections are simple but less flexible, while named connections offer better readability and debugging. When designing modules, always consider the best method for connecting ports based on the complexity and scale of your design. Additionally, be mindful of unconnected ports, as they can cause unexpected behavior during simulation and synthesis.