Verilog Ports
While declaring a Verilog module, port list needs to be also declared if we want our module to connect with another modules. The port list consists of various nets and variables, along with the direction.
Components of port
Each port consists of 3 main components:
- Port direction
- Port data type
- Port signal name
Port Direction
There are 3 directions which can be used in the port list:
- Input – This is used for the input ports and
input
is the keyword used to make an input port. - Output – This is used for output port.
- InOut – This is used if the port is bidirectional, i.e., it can act as both input and output.
inout
is the keyword used for this.
Port Data type
Not all data types can be used as a port. Some of the data types like, real
, event
cannot be used with the port. Ports can be made signed or unsigned using signed
keyword before the data type.
module port_decl(
input event a, // Invalid
real b, // Invalid
output reg [5:0] out // Valid
);
initial begin
$display ("a = %d", a);
end
endmodule
In the above example, the port declaration for a
and b
is invalid.
Port name
Port name can be any valid identifier in Verilog.
Port List Declaration
There are 2 ways in which port list can be declared.
Method One (Verilog 1996)
This method is more popular in old versions of Verilog, but in newer versions Verilog introduced a new way to declare a port list based on ANSCI C style. But the old way of declaration is still supported in recent versions and thus can also be used.
In this method, only the port name is used in the port list. The data type and the direction of the ports can be declared later in the body of the module. Also, in this method, the input ports cannot be declared as reg
, it can only have a net
data type.
module method_1(a, b, c);
// Declaring the direction and data type
// inside module
input a;
output b;
inout c;
// Can be redeclared to specify the data type of port.
reg [3:0] a; // Invalid
reg [3:0] b;
// By default the data type is wire.
// thus for b & c data type is wire
endmodule
Method two (Verilog 2001)
This method is based on ANSCI C, i.e., the way in which we declare the function arguments in C language. In this method, the port direction and data types are mentioned with the port name. If the direction and data type is not mentioned, the direction and data type of previous port is used for this port also. The ports declared using this method, cannot be redeclared in the module body.
module method_2(
input reg[3:0] a,
output b,
inout c
);
// Port cannot be redeclared inside the module
reg [7:0] b; // Invalid
endmodule
Keys points to remember while declaring Verilog port list:
input
ports can only havenet
data type.- In newer ANSCI C style port list declaration ports cannot be redeclared again inside module.
- New and old style of port declaration cannot be mixed
- Default data type of any port is
net
.
Referencing ports (Port Connection)
When we instantiate, a module having ports, we need to connect it to other modules or the top modules using the ports. There are 2 ways to connect the ports with the signals:
- Port connection by Order
- Port connection by name
Port connection by Order
In this connection, the signals which is declared inside the parent module should match the ports according to the position of the port in port list. This type of connection is prone to error, as signal can be easily connected to the wrong port.
module test_des(
input wire[3:0] a,
output reg[1:0] b
);
always @(a)
b = a[2:1];
endmodule
module tb_top;
reg [3:0] sig_a;
wire [1:0] out;
// Port list order is important
test_des dut(sig_a, out); // valid - will have correct functionality
test_des dut2(out, sig_a); // Invalid - will cause error
initial begin
sig_a = 4'b0110;
end
endmodule
Try this code in EDA PlaygroundPort connection by Name
In this connection, the name of the ports is used to connect the signal with the specific port. This type of connection is not prone to error as order of the ports are important in this case. .port_name(signal_name)
is the syntax to use port connection by name.
module test_des(
input wire[3:0] a,
output reg[1:0] b
);
always @(a)
b = a[2:1];
endmodule
module tb_top;
reg [3:0] sig_a;
wire [1:0] out;
// Port list order doesnot matter
test_des dut(.a(sig_a), .b(out)); // valid - will have correct functionality
test_des dut2(.b(out), .a(sig_a)); // valid - will have correct functionality
initial begin
sig_a = 4'b0110;
end
endmodule
Try this code in EDA Playground