Verilog Port Expressions

From Verific Design Automation FAQ
Revision as of 10:59, 10 February 2023 by Hoa (Talk | contribs)

Jump to: navigation, search

Q1: Why are the ports in original Verilog RTL file renamed to p1, p2, ... in the output netlist?

Verilog RTL file:

// Example of port expressions
module test (datain[0], datain[0] /* same net into multiple port expression */,
             datain[2:1]  /* part-select port expression */,
             /* empty port expression - nothing between the two commas */,
             {datain[2], datain[1], datain[1]} /* concatenation in port expression */,
             dataout[3], {dataout[2:0]}, /* another empty port expression due to the extra comma */
            );
    input [2:0] datain;
    output [3:0] dataout;
endmodule
 

The items enclosed in the () after the module name are not "port names," rather, they are "port expressions." Verilog defines that the port expressions of a module CANNOT be accessed by name (only by order). This means you cannot rely on the port names to be one thing or another.

Verific chooses to not adjust any particular naming scheme for complex port expressions, which also allows us to error out if named port instantiation occurs where the language disallows it.

The original port expression of the renamed port is saved as attribute " orig_port_name" attached to the port.

    key: " orig_port_name", value: port expression
 

Q2: Are "empty" ports Verilog-legal?

The Verilog example at the top of the page contains two "empty" port expressions (nothing between two commas or an extra comma at the end of the port expression list). This is legal as shown below:

In BNF section A.1.2 of IEEE 1800-2017 LRM:

module_nonansi_header ::=
    { attribute_instance } module_keyword [ lifetime ] module_identifier
    { package_import_declaration } [ parameter_port_list ] list_of_ports ;
    
list_of_ports ::= ( port { , port } )
    
port ::=
      [ port_expression ]
    | . port_identifier ( [ port_expression ] )
 

"port_expression" is optional because it is enclosed within [].

In section 23.2.2.1 of the same LRM on "Non-ANSI style port declarations":

The port expression is optional because ports can be defined that do not connect to anything internal to the module.

For the example above, the netlist output from Verific is (note the leading space character of the attribute " orig_port_name"):

//
// Verific Verilog Description of module test
//

module test (p1, p2, p3, , p7, p11, p12, ) /* verific  language=verilog,  cell_name=test */ ;   // test.sv(2)
    input p1 /* verific  orig_port_name=datain[0] */ ;
    input p2 /* verific  orig_port_name=datain[0] */ ;
    input [1:0]p3 /* verific  orig_port_name=datain[2] datain[1] */ ;
    input [2:0]p7 /* verific  orig_port_name=datain[2] datain[1] datain[1] */ ;
    output p11 /* verific  orig_port_name=dataout[3] */ ;
    output [2:0]p12 /* verific  orig_port_name=dataout[2] dataout[1] dataout[0] */ ;
    // Printing the identifier types 
    // datain   :   input [2:0] reg : nets: datain(bus)
    // dataout   :   output [3:0] reg : nets: dataout(bus)
    
    
    assign p1 = p2 /* verific  orig_port_name=datain[0] */ ;
    assign p3[1] = p7[2] /* verific  orig_port_name=datain[2] */ ;
    assign p3[0] = p7[0] /* verific  orig_port_name=datain[1] */ ;
    assign p7[1] = p7[0] /* verific  orig_port_name=datain[1] */ ;
    
endmodule