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.
Each port consists of 3 main components:
- Port direction
- Port data type
- Port signal name
There are 3 directions which can be used in the port list:
- Input – This is used for the input ports and
inputis 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.
inoutis the keyword used for this.
Not all data types can be used as a port. Some of the data types like,
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
b is invalid.
Port name can be any valid identifier in Verilog.
There are 2 ways in which port list can be declared.
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
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
inputports can only have
- 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
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
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.
Try this code in EDA Playground
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
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.
Try this code in EDA Playground
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