Logo

Verilog Ports

01 Sep 2021
4 mins

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:

  1. Input – This is used for the input ports and input is the keyword used to make an input port.
  2. Output – This is used for output port.
  3. 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:

  1. input ports can only have net data type.
  2. In newer ANSCI C style port list declaration ports cannot be redeclared again inside module.
  3. New and old style of port declaration cannot be mixed
  4. 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:

  1. Port connection by Order
  2. 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 Playground

Port 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