Port Proposal in HTML

From: Michael McNamara (mac@surefirev.com)
Date: Fri Jan 08 1999 - 18:33:17 PST


Here is the port proposal in HTML:

Please get feedback to me soon as I'd like to send this to the next
VSG meeting.

I also need a champion for the proposal at the meeting, as I will be
in Japan at the EDA Techno Fair.

<p><x-html><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
  <head>
    <title>ANSI Port Declarations</title>
  </head>

  <body>
    <h1>ANSI Port Declarations</h1>
    <p>
      This proposal adds an alternate method for declaring module,
      task and function ports to the Verilog Hardware Description
      Language.</p>
    <p>
    <hr width="10%" align=center>
    <h2> Port Declarations </h2>
    <hr>
    <p>
      At present, the Verilog language requires that the ports of a
      module be listed, by name, in parenthetical list just after the
      module name. Further, it is required that each port be again
      declared somewhere in the module as one of an <b>input</b>,
      <b>output</b> or <b>inout</b>. Optionally the port may again be
      declared as a <b>wire</b> (the default) or as a <b>reg</b>.
    </p>
<table border=1>
<td>
<table>
<tr>
<td valign="top">module_declaration </td><td>::= module_keyword <I>module</I>_identifier [ list_of_ports ] <B>;</B>&#9;{ module_item } <B>endmodule</b> </td>
</tr>
<tr>
<td valign="top">module_keyword</td><td>::= <B>module</B> | <B>macromodule</b></td>
</tr>
<tr>
<td valign="top">list_of_ports</td><td>::= <B>(</B> port { <B>,</B> port } <B>)</b></td>
</tr>
<tr>
<td valign="top">port</td> <td>::= [ port_expression ]</td>
</tr>
<td></td> <td>| <B>.</B> <I>port</I>_identifier <B>(</B> [ port_expression ] <B>) </td>
<tr>
<td valign="top">port_expression</td><td>::= port_reference </td>
</tr>
<tr>
<td></td><td>| <B>{</B> port_reference { <B>,</B> port_reference } <B>}</B></td>
</tr>
<tr>
<td valign="top">port_reference</td><td>::= <I>port</I>_identifier </td>
</tr>
<tr>
<td></td><td>| <I>port</I>_identifier <B>[</B> constant_expression <B>]</B></td></tr>
<tr>
<td></td><td>| <I>port</I>_identifier <B>[</B> <I>msb</I>_constant_expression <B>:</B> <I>lsb</I>_constant_expression <B>]</td></tr>
</table>
</td>
</table>
    <p>And then as a module item we have:</p>
<table border=1>
<td>
<table>
<tr>
<td>module_item</td><td>::= module_item_declaration</td>
</tr>
<tr>
<tr><td valign="top">module_item_declaration</td><td>::= parameter_declaration</td></tr>
<tr><td></td><td>| input_declaration</td></tr>
<tr><td></td><td>| output_declaration</td></tr>
<tr><td></td><td>| inout_declaration</td></tr>
<tr><td></td><td>| net_declaration</td></tr>
<tr><td></td><td>| reg_declaration</td></tr>
<tr><td></td><td><b>...</b></td></tr>

<tr><td valign="top">input_declaration </td><td>::= <B>input</B> <B>[</B> range <B>]</B> list_of_port_identifiers <B>;</b></td></tr>
<tr><td valign="top"><P>output_declaration </td><td>::= <B>output</B> <B>[</B> range <B>]</B> list_of_port_identifiers <B>;</b> </td></tr>
<tr><td valign="top"><P>inout_declaration </td><td>::= <B>inout</B> <B>[</B> range <B>]</B> list_of_port_identifiers <B>;</b> </td></tr>

</table>
</td>
</table>
    <p> Of course this is very similar to the original C Programming
    Language, (affectionately known as K&R C), which was enhanced by
    simpler port declarations in ANSI C.
    </p>

    <p> Further, at present declarations of tasks and functions do not
    support a parenthetical list of ports. Instead the inputs, locals,
    and in the case of tasks, outputs and inouts of the tasks must be
    listed after the task or function name declaration.</p>

<table border=1>
<td>
<table>
<tr>
<td valign="top">function_declaration</td><td>::= <b>function</b> [range_or_type] <i>function</i>_identifier ; <br>function_item_declaration {function_item_declaration} <br>statement<br> <b>endfunction</b></td>
</tr>
<tr>
<tr><td valign="top">function_item_declaration</td><td>::= block_item_declaration</td></tr>
<tr><td></td><td>| input_declaration</td></tr>

<td valign="top">task_declaration</td><td>::= <b>task</b> <i>task</i>_identifier ;<br>task_item_declaration {task_item_declaration}<br> statement<br> <b>endtask</b></td>
</tr>
<tr>
<tr><td valign="top">task_item_declaration</td><td>::= block_item_declaration</td></tr>
<tr><td></td><td>| input_declaration</td></tr>
<tr><td></td><td>| output_declaration</td></tr>
<tr><td></td><td>| inout_declaration</td></tr>
</table>
</table>

    <p> After some discussion in the Verilog-1364 Behavioral Task
    Force, and later in the entire Verilog-1364 working group,
    consensus emerged supporting an extension to the Verilog language
    closely following that of ANSI C's enhancement to K&R C, as
    follows.</p>

    <p> For module, task and function declarations, users can either
    continue to use the existing syntax, or they can use the new
    parenthetical port declaration production.</p>
    
    <p> This proposal does the following, with the BNF below:
      <ol type="1">

        <li> enhances the <b>input_declaration</b>,
        <b>output_declaration</b>, and <b>inout_declaration</b> to
        allow specification of net or reg type and signedness.

        <li> allows <b>input_declaration</b>s,
        <b>output_declaration</b>s and <b>inout_declaration</b>s to be
        used as port_references.

        <li> introduces a <b>function_port_list</b> and
        <b>task_port_list</b> that can be used as an alternative to
        the current function and task declaration syntax.
        
        <li> introduces a <b>parameter__port_list</b> that can be used
        to define parameters of modules where the parameters are used
        to size the width of input, output and inout ports.

        <li> introduces the semantic restriction that a module, task
        or function declaration must either use the existing 1364-1995
        port declaration syntax, or the new syntax; but may not mix
        both styles in the same declaration. A given design may use
        modules, tasks and functions, where some are declaraed in the
        old syntax, and some in the new syntax.
    </ol>

<table border=1>
<td>
<table>
<tr>
<td valign="top">module_declaration </td><td>::= module_keyword <I>module</I>_identifier <font color="red"> [ parameter_port_list ] </font> [ list_of_ports ] <B>;</B>&#9;{ module_item } <B>endmodule</b> </td>
</tr>
<tr>
<td valign="top">module_keyword</td><td>::= <B>module</B> | <B>macromodule</b></td>
</tr>
<tr>
<td valign="top"><font color="red">parameter_port_list</font></td><td><font color="red">::= <B># (</B> parameter_declaration { parameter_declaration } <B>)</b></font></td>
</tr>
<tr>
<td valign="top">list_of_ports</td><td>::= <B>(</B> port { <B>,</B> port } <B>)</b></td>
</tr>
<tr>
<td valign="top">port</td> <td>::= [ port_expression ]</td>
</tr>
<td></td> <td>| <B>.</B> <I>port</I>_identifier <B>(</B> [ port_expression ] <B>) </td>
<tr>
<td valign="top">port_expression</td><td>::= port_reference </td>
</tr>
<tr>
<td></td><td>| <B>{</B> port_reference { <B>,</B> port_reference } <B>}</B></td>
</tr>
<tr>
<td valign="top">port_reference</td><td>::= <I>port</I>_identifier </td>
</tr>
<tr>
<td></td><td>| <I>port</I>_identifier <B>[</B> constant_expression <B>]</B></td></tr>
<tr>
<td></td><td>| <I>port</I>_identifier <B>[</B> <I>msb</I>_constant_expression <B>:</B> <I>lsb</I>_constant_expression <B>]</b></td></tr>
<tr>
<td></td><td>| <I>port</I>_identifier <B>[</B> constant_expression <B>]</B></td></tr>
<td></td><td><font color="red">| input_declaration</font></td></tr>
<td></td><td><font color="red">| output_declaration</font></td></tr>
<td></td><td><font color="red">| inout_declaration</font></td></tr>
<tr><td></td><td><b>...</b></td></tr>

<tr><td valign="top">input_declaration </td><td>::= <B>input</B> <font color="red">[ <B>signed </B>] [ net_type ] </font> <B>[</B> range <B>]</B> list_of_port_identifiers <B></td></tr>
<tr><td valign="top">output_declaration </td><td>::= <B>output</B> <font color="red">[ <B>signed </B>] [ net_type ] </font> <B>[</B> range <B>]</B> list_of_port_identifiers <B> </td></tr>
<tr><td valign="top">output_declaration </td><td>::= <B>output</B> <font color="red">[ <B>signed </B>] [ reg_type ] </font> <B>[</B> range <B>]</B> list_of_port_identifiers <B> </td></tr>
<tr><td valign="top">inout_declaration </td><td>::= <B>inout</B> <font color="red">[ <B>signed </B>] [ net_type ] </font><B>[</B> range <B>]</B> list_of_port_identifiers <B> </td></tr>
<tr>
<tr>
<tr>
<td valign="top">function_declaration</td><td>::= <b>function</b> [range_or_type] <i>function</i>_identifier ; <br>function_item_declaration {function_item_declaration} <br>statement<br> <b>endfunction</b></td>
</tr>
<tr><td valign="top"></td><td><font color="red"> | <b>function</b> [range_or_type] <i>function</i>_identifier ( function_port_list ) ; <br>block_item_declaration {block_item_declaration} <br>statement<br> <b>endfunction</b></font></td>
</tr>
<tr>
<tr><td valign="top">function_item_declaration</td><td>::= block_item_declaration</td></tr>
<tr><td></td><td>| input_declaration</td></tr>
<tr><td valign="top"><font color="red">function_port_list</td><td><font color="red">::= input_declaration { input_declaration } <br></td></tr>
<tr>
<td valign="top">task_declaration</td><td>::= <b>task</b> <i>task</i>_identifier ;<br>task_item_declaration {task_item_declaration}<br> statement<br> <b>endtask</b></td>
</tr>
<tr>
<td valign="top"></td><td><font color="red"> | <b>task</b> <i>task</i>_identifier ( task_port_list ) ;<br>block_item_declaration {block_item_declaration}<br> statement<br> <b>endtask</b></font></td>
</tr>
<tr>
<tr><td valign="top">task_item_declaration</td><td>::= block_item_declaration</td></tr>
<tr><td></td><td>| input_declaration</td></tr>
<tr><td></td><td>| output_declaration</td></tr>
<tr><td></td><td>| inout_declaration</td></tr>
<font color="red">
<tr><td valign="top"><font color="red">task_port_list</td><td><font color="red">::= task_port_item { task_port_item } </td></tr>
<tr><td valign="top"><font color="red">task_port_item</td><td><font color="red">::= input_declaration</td></tr>
<tr><td></td><td><font color="red">| output_declaration</td></tr>
<tr><td></td><td><font color="red">| inout_declaration</td></tr>
</font>
</table>
</td>
</table>
<p> Note that a separate proposal is adding the keyword <b>signed</b>
to the language; and the optional keyword signed is merely included
here to show that should signed constructs be introduced, it would be
legal to include the declaration in the port_reference production</p>
<p>Given this syntax, the following two module declarations are
equivalent:<p> <table border=1><td>
<xmp>
module acc_fsm( CLK, RST, IT_IL_RQ, IT_RQ_VLD, RdMsg,
                WrMsg, AccessOK, XX_IL_PIODONE, OM_IL_GT,
                RespVld, IL_IT_GT, CaptureAddress, CaptureData,
                IL_XX_PIORD, IL_XX_PIOWR, IL_OM_RQ,
                SelectResp, SetRespVld, ClrRespVld);
   parameter DATAWIDTH=64;
   input CLK, RST;
   input IT_IL_RQ,
                       IT_RQ_VLD,
                       RdMsg,
                       WrMsg,
                       AccessOK,
                       XX_IL_PIODONE;
   input OM_IL_GT,
                       RespVld;
   output [31:0] CaptureAddress;
   output [DATAWIDTH-1:0] CaptureData;
   output IL_IT_GT,
                       IL_XX_PIORD,
                       IL_XX_PIOWR,
                       IL_OM_RQ,
                       SelectResp,
                       SetRespVld,
                       ClrRespVld;
   reg [31:0] CaptureAddress;
   reg [DATAWIDTH-1:0] CaptureData,
   reg [2:0] LE_NxtState,
                       LE_State;
   reg IL_IT_GT,
                       IL_XX_PIORD;
   reg IL_XX_PIOWR,
                       IL_OM_RQ,
                       SelectResp,
                       SetRespVld,
                       ClrRespVld;
</xmp>
</td></table>
    <p>and</p>
<table border=1><td>
<xmp>
module acc_fsm #( parameter DATAWIDTH=64)
                 ( input wire CLK, RST, IT_IL_RQ, IT_RQ_VLD, RdMsg,
                              WrMsg, AccessOK, XX_IL_PIODONE,
                              OM_IL_GT, RespVld;
                   output reg [31:0] CaptureAddress;
                   output reg [DATAWIDTH-1:0] CaptureData;
                   output reg IL_IT_GT, IL_XX_PIORD, IL_XX_PIOWR,
                              IL_OM_RQ, SelectResp, SetRespVld, ClrRespVld;
                 );
   reg [ 2 : 0] LE_NxtState,
                       LE_State;
</xmp>
</td></table>

<p> Things to note:
      <ol>
      <li> The second module declaration is much more compact.(38
      words instead of 70). Also note that this is a <b>small</b>
      example; many datapath modules contain as many as a thousand
      ports, each which may need to be declared three times.

      <li> The second module declaration is much easier to reuse:
      changing the width of the CaptureAddress bus to 48 bits requires
      modifying one location, instead of two, which potentially are
      many lines apart.

      <li> With the second module declaration local variables are
      clearly distinct from port variables.
        
      <li> With the second module declaration global analysis can
      examine just the port list in order to determine all necessary
      information about the input output characteristics of a module.

      <li> Declaring the modifiable parameter declarations in a
      separate list, with the list enclosed in '#(' and )' looks just
      like the module instance parameter override syntax. This also
      encapsulates and focuses attention the interface nature of these
      parameters.

      <li> Overall, the new module declaration centers the information
      that a user of this module must look at to successfully
      interface to the module in one place, at the top of the module.
      The details of the implementation are listed later. Hence Verilog
      becomes more object oriented.

      <li> There has been some suggestion that using constant
      functions in module i/o declarations to define widths would
      require that the definition of the constant function precede the
      use; however private discussion has cleared this up. The value
      of the parameters at the point of the 'call' to the constant
      function are all that is needed to determine its value. An
      exaple is useful:

<table border=1><td>
<xmp>
module acc_fsm #( parameter DATAWIDTH=8, TSIZE=cf_tsize(DATAWIDTH) )
                 ( input wire CLK, RST,
                   output reg [TSIZE-1:0] CaptureDataOut;
                   input wire [TSIZE-1:0] CaptureDataIn;
                 );
   reg [ 2 : 0] LE_NxtState,
                       LE_State;

  parameter B=DATAWIDTH*2;

  function [31:0] cf_tsize(input [31:0] w);
  cf_tsize = w**B;
  endfunction
endmodule
</xmp>
</td></table>

The parameter B is not yet defined at the location that TSIZE is
assigned the value of the constant function cf_tsize, and hence this
usage is illegal. The fix would be to move the definition of the
parameter B into the parameter port list.

    </ol>
    <hr>
    <address><a href="mailto:mac@surefirev.com">Michael
    McNamara</a></address> <!-- Created: Wed Apr 1 15:28:56 PST 1998
    --> <!-- hhmts start --> Last modified: Fri Jan 8 18:16:27 PST
    1999 <!-- hhmts end -->
  </body>
</html>
</x-html>



This archive was generated by hypermail 2.1.4 : Mon Jul 08 2002 - 12:53:24 PDT and
sponsored by Boyd Technology, Inc.