Verilog ports serve as communication channels between a design module and the outside world, much like pins on a physical chip. These ports allow signals to flow in and out of the module. In this article, we will explore the types of Verilog ports, their syntax, signed ports, and variations across different Verilog versions.


What Are Verilog Ports?

They are essential for interconnecting different modules in a design. They act as inputs or outputs for the module and enable it to communicate with other components. You can think of ports as the “pins” of a module, similar to how a physical chip communicates with external circuits.

  • Inputs: Used to receive signals from the outside world.
  • Outputs: Used to send signals to the outside world.
  • Inouts: Ports that can either send or receive signals.

Types of Verilog Ports

Verilog supports three main types of ports:

Port TypeDescription
InputThis port only receives signals from outside the module.
OutputThis port only sends signals to the outside world.
InoutThis port can both send and receive signals.

By default, Verilog treats all ports as wire types unless specified otherwise.


Verilog Port Syntax

Allows you to declare ports in different formats. Here is the syntax for the different types of ports:

  • Input Port: input [net_type] [range] list_of_names;
  • Output Port: output [net_type] [range] list_of_names;
  • Inout Port:
    verilog inout [net_type] [range] list_of_names;

In the case of inout ports, they can function as both input and output, depending on how they are used in the design.

Example Code:

Below is an example with three input ports, one output port, and one inout port:

module my_design (
    input wire clk,         // Clock signal
    input en,               // Enable signal
    input rw,               // Read/Write signal
    inout [15:0] data,      // Data bus (can be both input and output)
    output int              // Interrupt signal
);

// Design behavior

endmodule

Rules for Port Naming

  1. You cannot use the same name for multiple ports.
   input aport;         // First declaration - valid
   input aport;         // Error - already declared
   output aport;        // Error - already declared

Signed Ports in Verilog

Verilog allows you to specify whether ports should be signed or unsigned. By default, ports are considered unsigned unless explicitly stated otherwise using the signed keyword.

Example of Implicit Unsigned Ports:

module my_design ( 
    input a, 
    input b, 
    output c
);
    // a, b, and c are unsigned by default
endmodule

Example of Signed Ports

module my_design ( 
    input signed a, b,   // a and b are signed
    output signed c     // c is also signed
);
    wire signed a, b;    // a, b are signed from port declaration
    reg signed c;        // c is signed from reg declaration
endmodule

Verilog Port Declaration Variations

Verilog has evolved over the years. Let’s look at how port declaration styles changed from Verilog 1995 to Verilog 2001 and later.

Verilog 1995 Style

In Verilog 1995, port was listed in the module declaration, and the direction (input/output) was defined inside the module body. This style is more verbose.

module test (a, b, c);
    input [7:0] a;          // a is an 8-bit input
    input [7:0] b;          // b is also an 8-bit input
    output [7:0] c;         // c is an 8-bit output, default type is wire

    wire [7:0] a, b, c;     // Optional re-declaration as wire
endmodule

Verilog 2001 and Later (ANSI-C Style)

Starting in Verilog 2001, the ANSI-C style of port declaration was introduced. This allowed the type to be specified directly within the port list. It simplified the declaration process and made the code more readable.

module test (
    input [7:0] a,          // a is an 8-bit input
    input [7:0] b,          // b is an 8-bit input
    output [7:0] c          // c is an 8-bit output
);
    // Design code
endmodule

In Verilog 2001 and later, you can also specify the type of the output port as wire or reg.

Example with reg and wire

module test (
    input wire [7:0] a,     // a is a wire input
    input wire [7:0] b,     // b is a wire input
    output reg [7:0] c      // c is a reg output
);
    // Design content
endmodule

Verilog Port Declaration Rules

Here are the key rules for Verilog port declaration:

  1. Complete Port Declaration: If a port includes a net or variable type (like wire or reg), it is considered completely declared and cannot be redeclared. Example:
   module test (
       input [7:0] a,   // a is implicitly a wire
       output reg [7:0] e
   );
       wire signed [7:0] a;   // Error: a is already declared
       wire [7:0] e;          // Error: e is already declared
   endmodule
  1. Partial Declaration: If a port type is not specified in the port list, you can declare it again using wire or reg within the module body. Example:
   module test (
       input [7:0] a,       // a is implicitly a wire
       output [7:0] e       // e is implicitly a wire
   );
       reg [7:0] e;          // Okay: e can be redeclared as reg
   endmodule

Conclusion

They are fundamental for module communication, allowing signals to flow between the inside and outside of a module. Understanding the different types of port like (input, output, inout), the syntax, and the variations across different Verilog standards (1995 vs. 2001 and beyond) is essential for writing effective Verilog code. Whether you are dealing with signed port or using the newer ANSI-C style declarations, the rules and practices laid out in this article should help you design better and more efficient Verilog modules.

Scroll to Top