Proposal to get declarations and structures moving along

From: Michael McNamara (mac@surefirev.com)
Date: Mon May 11 1998 - 09:38:57 PDT


        Here is the beginings of a proposal for ansi declarations and
structures

<x-html><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
  <head>
    <title>ANSI Port Declarations, and Structures for Verilog</title>
  </head>

  <body>
    <h1>ANSI Port Declarations, and Structures for Verilog</h1>
    <p>
      This proposal adds an alternate method for declaring module
      ports, as well as introducing structures to the Verilog Hardware
      Description Language.</p>
    <p>
    <hr width="10%" align=center>
    <h2> Port Declaration </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>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>module_keyword</td><td>::= <B>module</B> | <B>macromodule</b></td>
</tr>
<tr>
<td>list_of_ports</td><td>::= <B>(</B> port { <B>,</B> port } <B>)</b></td>
</tr>
<tr>
<td>port</td> <td>::= [ port_expression ]</td>
</tr>
<td></td> <td>| <B>.</B> <I>port</I>_identifier <B>(</B> [ port_expression ] <B>) </td>
<tr>
<td>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>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>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>input_declaration </td><td>::= <B>input</B> <B>[</B> range <B>]</B> list_of_port_identifiers <B>;</td></tr>
<tr><td><P>output_declaration </td><td>::= <B>output</B> <B>[</B> range <B>]</B> list_of_port_identifiers <B>; </td></tr>
<tr><td><P>inout_declaration </td><td>::= <B>inout</B> <B>[</B> range <B>]</B> list_of_port_identifiers <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> This proposal first enhances the input_declaration,
    output_declaration, and inout declaration, and would further allow
    the input_declaration, output_declaration and/or inout_declaration
    to be used as port_references, as follows:</p>

<table border=1>
<td>
<table>
<tr>
<td>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>module_keyword</td><td>::= <B>module</B> | <B>macromodule</b></td>
</tr>
<tr>
<td>list_of_ports</td><td>::= <B>(</B> port { <B>,</B> port } <B>)</b></td>
</tr>
<tr>
<td>port</td> <td>::= [ port_expression ]</td>
</tr>
<td></td> <td>| <B>.</B> <I>port</I>_identifier <B>(</B> [ port_expression ] <B>) </td>
<tr>
<td>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>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>
<tr>
<td></td><td>| <I>port</I>_identifier <B>[</B> constant_expression <B>]</B></td></tr>
<td></td><td>| input_declaration</td></tr>
<td></td><td>| output_declaration</td></tr>
<td></td><td>| inout_declaration</td></tr>
<tr><td></td><td><b>...</b></td></tr>

<tr><td>input_declaration </td><td>::= <B>input</B>[ <B>signed </B>] [ net_type ] <B>[</B> range <B>]</B> list_of_port_identifiers <B></td></tr>
<tr><td>output_declaration </td><td>::= <B>output</B>[ <B>signed </B>] [ net_type ] <B>[</B> range <B>]</B> list_of_port_identifiers <B> </td></tr>
<tr><td>output_declaration </td><td>::= <B>output</B>[ <B>signed </B>] [ reg_type ] <B>[</B> range <B>]</B> list_of_port_identifiers <B> </td></tr>
<tr><td>inout_declaration </td><td>::= <B>inout</B> [ <B>signed </B>] [ net_type ] <B>[</B> range <B>]</B> list_of_port_identifiers <B> </td></tr>
<tr>
</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);
   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 [63:0] CaptureData;
   output IL_IT_GT,
                       IL_XX_PIORD,
                       IL_XX_PIOWR,
                       IL_OM_RQ,
                       SelectResp,
                       SetRespVld,
                       ClrRespVld;
   reg [31:0] CaptureAddress;
   reg [63: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( 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 [63: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.
    </ol>
    <hr>
    <hr width="10%" align=center>
    <h2> Structures </h2>
    <hr>
    <p> Structures are very familiar to users of modern computer
    languages, yet Verilog does not support them. This proposal adds
    structures to the language, in manner consistent with Verilog's
    concept of the directionality of a data reference.</p>

    <p>Verilog does have a notion of hierarchy, and the dot (<b>.</b>)
    is reserved in the language to refer to sub elements of an
    object. At present there is no use of the dot to reference sub
    elements of signals, and hence we propose using the dot to
    references to elements of a structure.</p>
    <h3> Directions </h3>
    <p>In the Verilog language, signals are connected between modules
    via ports. These ports can be <b>input</b>, <b>output</b> or
    <b>inout</b> connections. Input ports can only be read from; the
    module cannot drive a value to these ports. Output ports can be
    driven, yet when read from will only show the resolved values of
    the local drivers; essentially these drivers are isolated from any
    external drivers of the port. Inout ports can be driven, and when
    read will show the final resolved value of all the drivers of that
    object, whether internal or external to the module.</p>

    <p>A group of signals that quite logically might be contained in a
    structure could quite conceivably have elements that are read-only
    (wire), write-only (output) and/or read-write (inout) -- at
    different times according to the module accessing the object. For
    example, consider a bus:</p>
    <xmp>
      wire [31:0] address;
      wire [63:0] data;
      wire [15:0] req;
      wire [15:0] grt;
      wire buserr;
    </xmp>
    <p>The bus arbiter module needs just read access to the <b>req</b>
    wires, and needs write access to the <b>grt</b> lines, and
    read-write access to the <b>buserror</b> line, and really no access
    to any other line.</p>

    <p>A bus master needs write access to one of the <b>req</b> lines,
    read access to the matching <b>grt</b> line, and read-write access
    to the <b>address</b>, <b>data</b> and <b>buserror</b> lines. </p>

    <p>A bus slave might need just read-write access to the
    <b>address</b>, <b>data</b> and <b>buserror</b> lines.

    <p>A bus monitor would need read access to all the bus lines.</p>

    <p>Therefore including direction in a structure declaration would
    be less than useful.</p>

    <h3>Proposal</h3>
    <p> The following syntax is proposed:
<table border=1>
<td>
<table>
<td>structure_declaration</td><td>::= <b>struct</b> <i>struct</i>_identifier <b>begin</b> struct_items <b>end</b></td></tr>
<tr><td>struct_items</td><td>::= struct_item { struct_item }
<tr><td>struct_item</td><td>::= [ <B>signed </B>] <B>[</B> range <B>]</B> list_of_struct_identifiers <B>;</b> </td></tr>
</table>
</td>
</table>
<p>
The structure definition is global, at the same scope as the module
declaration, and hence it is an error to declare two structures with
the same name.</p> <p><i><b>Note:</b> When global module declarations are fixed, we
would fix global structure declarations as well.</i></p>

<p>Structures are used in net and reg declarations as an alternate for
the <b>range</b> production, as follows:
<table border=1>
<td>
<table>
<tr><td>reg_declaration</td><td> ::= <B>reg</B> <B>[</B> range <B>]</B> list_of_register_identifiers <B>;</td></tr>
<tr><td>list_of_real_identifiers</td><td> ::= <I>real</I>_identifier { <B>,</B> <I>real</I>_identifier }</td></tr>
<tr><td>list_of_register_identifiers</td><td> ::= register_name { <B>,</B> register_name }</td></tr>
<tr><td>register_name</td><td> ::= <I>register</I>_identifier</td></tr>
<tr><td></td><td>| <I>memory</I>_identifier <B>[ </B><I>upper_limit</I>_constant_expression <B>:</B> <I>lower_limit</I>_constant_expression <B>]</b></td></tr>
<tr><td>time_declaration</td><td> ::= <B>time</B> list_of_register_identifiers <B>;</td></tr>
<tr><td>integer_declaration</td><td> ::= <B>integer</B> list_of_register_identifiers <B>;</td></tr>
<tr><td>real_declaration</td><td> ::= <B>real</B> list_of_real_identifiers <B>;</td></tr>
<tr><td>realtime_declaration</td><td> ::= <B>realtime</B> list_of_real_identifiers <B>;</td></tr>
<tr><td>event_declaration</td><td> ::= <B>event</B> <I>event</I>_identifier { <B>,</B> <I>event</I>_identifier } <B>;</td></tr>
<tr><td>net_declaration</td><td> ::=net_type [ <B>vectored</B> | <B>scalared</B> ] [ <B>signed </B>| <B>unsigned </B>] [ range ] [ delay3 ] list_of_net_identifiers <B>;</td></tr>
<tr><td></td><td>| <B>trireg</B> [ <B>vectored</B> | <B>scalared</B> ] [ <B>signed </B>| <B>unsigned </B>] [ charge_strength ] [ range ] [ delay3 ] list_of_net_identifiers <B>;</B></td></tr>
<tr><td></td><td>| net_type [ <B>vectored</B> | <B>scalared</B> ] [ <B>signed </B>| <B>unsigned </B>] [ drive_strength ] [ range ] [ delay3 ] list_of_net_decl_assignments</td></tr>
<tr><td>net_type</td><td> ::= <B>wire</B> | <B>tri</B> | <B>tri1</B> | <B>supply0</B> | <B>wand</B> | <B>triand</B> | <B>tri0</B> | <B>supply1</B> | <B>wor</B> | <B>trior</td></tr>
<tr><td>drive_strength</td><td> ::= <B>(</B> strength0 <B>,</B> strength1 <B>)</td></tr>
<tr><td><td><td>| <B>(</B> strength1 <B>,</B> strength0 <B>)</td></tr>
<tr><td><td><td>| <B>(</B> strength0 <B>,</B> <B>highz1</B> <B>)</td></tr>
<tr><td><td><td>| <B>(</B> strength1 <B>,</B> <B>highz0</B> <B>)</td></tr>
<tr><td><td><td>| <B>(</B> <B>highz0</B> <B>,</B> strength1 <B>)</td></tr>
<tr><td><td><td>| <B>(</B> <B>highz1,</B> strength0 <B>)</td></tr>
<tr><td>strength0</td><td> ::= <B>supply0</B> | <B>strong0</B> | <B>pull0</B> | <B>weak0</td></tr>
<tr><td>strength1</td><td> ::= <B>supply1</B> | <B>strong1</B> | <B>pull1</B> | <B>weak1</td></tr>
<tr><td>charge_strength</td><td> ::= <B>( small )</B> | <B>( medium )</B> | <B>( large )</td></tr>
<tr><td>delay3</td><td> ::= <B>#</B> delay_value | <B>#</B> <B>(</B>delay_value [ <B>,</B> delay_value [ <B>,</B> delay_value ] ] <B>)</td></tr>
<tr><td>delay2</td><td> ::= <B>#</B> delay_value | <B>#</B> <B>(</B>delay_value [ <B>,</B> delay_value ] <B>)</td></tr>
<tr><td>delay_value</td><td> ::= unsigned_number | <I>parameter</I>_identifier | constant_mintypmax_expression</td></tr>
<tr><td>list_of_net_identifiers</td><td> ::= <I>net</I>_identifier { <B>,</B> <I>net</I>_identifier }</td></tr>
<tr><td>list_of_net_decl_assignments</td><td> ::= net_decl_assignment { <B>,</B> net_decl_assignment }</td></tr>
<tr><td>net_decl_assignment</td><td> ::= <I>net</I>_identifier = expression</td></tr>

<tr><td>range</td><td> ::= <B>[ </B><I>msb</I>_constant_expression <B>:</B> <I>lsb</I>_constant_expression <B>]</td></tr>
<tr><td></td><td bgcolor=red>| <i>struct</i>_identifier</td></tr>
<tr><td><i>net</i>_identifier</td><td> ::= identifier</td></tr>
<tr><td></td><td bgcolor=red>| { <i>struct</i>_identifier<b>.</b>} identifier</td></tr>
<tr><td><i>reg</i>_identifier</td><td> ::= identifier</td></tr>
<tr><td></td><td bgcolor=red>| { <i>struct</i>_identifier<b>.</b>} identifier</td></tr>
</table>
</td>
</table>
<p>
Given the above additions to the BNF, one could code the bus devices as follows:
<xmp>
struct Pbus
  begin
     parameter NDEV = 4;
     wire [31:0] address;
     wire [63:0] data;
     wire [1<<NDEV:0] req;
     wire [1<<NDEV:0] grt;
     wire buserr;
  end
endstruct // Pbus

module top;
   wire Pbus thePbus;
   wire clk;
   
   pbus_monitor p_mon( .Pbus(thePbus),.clk(clk));

   pbus_arb p_arb( .Pbus(thePbus), .clk(clk));
   pbus_cpu p_cpu0( .Pbus(thePbus), .clk(clk) .id(4'd0));
   pbus_cpu p_cpu1( .Pbus(thePbus), .clk(clk) .id(4'd1));

   pbus_mem p_mem0( .Pbus(thePbus), .clk(clk) .id(4'd2));
   pbus_mem p_mem1( .Pbus(thePbus), .clk(clk) .id(4'd3));
   pbus_mem p_mem2( .Pbus(thePbus), .clk(clk) .id(4'd4));
   pbus_mem p_mem3( .Pbus(thePbus), .clk(clk) .id(4'd5));
  
endmodule
  
module pbus_monitor( input Pbus my_Pbus );
   always @(my_Pbus.buserr) begin
      $display($time,,"BUSERR!!");
   end
   ...
endmodule // pbus_monitor

module pbus_arb( input Pbus.req,
                 output reg Pbus.grt,
                 inout Pbus.buserr,
                 input clk );
   always @(clk) begin
      case(req)
        0,1,2,4,8,16,32,64 : grt = req;
        default: // left as exercise...
      endcase // case(req)
   end
   
endmodule

module pbus_cpu( output reg Pbus.req,
                 input Pbus.grt,
                 inout Pbus.buserr,
                 inout Pbus.data,
                 inout Pbus.address, // for cache invalidate logic
                 input [Pbus.NDEV:0] id,
                 input clk );
   always @(clk) begin
      case (state)
        WANT_TO_WRITE: begin
           req[id] = 1;
           state <= WAIT_FOR_WRITE_GRANT;
        end // case: WANT_TO_WRITE
        
        WANT_TO_READ: begin
           req[id] = 1;
           state <= WAIT_FOR_READ_GRANT;
        end // case: WANT_TO_READ
        
        ...
      endcase // case(state)
   end // always @ (clk)
   
endmodule // pbus_cpu
</xmp>
    <address><a href="mailto:mac@silicon-sorcery.com">Michael McNamara</a></address>
<!-- Created: Wed Apr 1 15:28:56 PST 1998 -->
<!-- hhmts start -->
Last modified: Mon May 4 09:02:53 PDT 1998
<!-- hhmts end -->
  </body>
</html>
</x-html>From ???@??? Sat May 09 16:15:11 1998
Return-Path: <owner-btf@boyd.com>
Received: (from majordomo@localhost)
        by gw.boyd.com (8.8.7/8.8.5) id OAA08993
        for btf-list; Sat, 9 May 1998 14:22:44 -0700
X-Authentication-Warning: gw.boyd.com: majordomo set sender to owner-btf@boyd.com using -f
Received: from greatdane.webnexus.com (greatdane.webnexus.com [165.227.96.3])
        by gw.boyd.com (8.8.7/8.8.5) with ESMTP id OAA08990
        for <btf@boyd.com>; Sat, 9 May 1998 14:22:32 -0700
Received: from bcarsde4 (mailgate.nortel.ca [192.58.194.74])
        by greatdane.webnexus.com (8.8.7/8.8.5/WN-1.2) with ESMTP id MAA32716
        for <btf@boyd.com>; Sat, 9 May 1998 12:05:14 -0700 (PDT)
Received: from bcarsca3 by mailgate; Sat, 9 May 1998 15:01:16 -0400
Received: from bcarsb82.bnr.ca (actually bcarsb82.ca.nortel.com) by bcarsca3;
          Sat, 9 May 1998 15:00:25 -0400
Received: by bcarsb82.bnr.ca (4.1/SMI-4.1 BNR V4.2 P1) id AA02079;
          Sat, 9 May 98 15:00:10 EDT
Date: Sat, 9 May 98 15:00:10 EDT
From: "Anders Nordstrom" <andersn@nortel.ca>
Message-Id: <9805091900.AA02079@bcarsb82.bnr.ca>
To: btf@boyd.com
Subject: BTF: Errata 45 to review before conf call May 12
Sender: owner-btf@boyd.com
Precedence: bulk
Status: RO
Dear BTF Members,

Please review this updated Errata and be prepared to vote on it on
May 12. I appologize for the short notice but I hope you can review
it anyway. As you know we do have a fairly tight schedule.

Regards
        Anders

<p><p><p><HTML>
<HEAD>
<TITLE> Errata to vote on by BTF </TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">

<HR SIZE=5 NOSHADE>

<H2> BE45 - Behavioral function definition </H2>

<TABLE BORDER COLS=2 WIDTH="50%" >
<TR>
<TD> Section: </TD><TD> 11 </TD>
</TR><TR>
<TD> Date Submitted: </TD><TD> 961217 </TD>
</TR><TR>
<TD> Requestor: </TD><TD> Steve Meyer </TD>
</TR><TR>
<TD> Status: </TD><TD> Proposal </TD>
</TR><TR>
<TD> Analyzed by: </TD><TD> Adam Krolnik & Karen Pieper </TD>
</TR>
</TABLE>

<H3> Details </H3>

I just ran into the following function that I think may be illegal
according to the IEEE P1364 standard but probably needs to be explicitly
allowed because break and continue require named blocks. The function below
does not work in Cver because it treats named blocks as task enables
since they can be disabled, and for nested named blocks the downward
chain disabling rule (section 11-1 Oct. 1995 draft) must be applied.

The problem is probably one of documentation clarity. I read section
11 page 1 (but not the remaining examples) as allowing disable of any
named block, therefore named blocks are illegal inside function definitions,
but my interpretation must be wrong since the function is part of the DA
solutions benchmarks and works on other simulators.

Also, I am not sure what the meaning of parallel blocks (fork-join)
is inside functions.

The LRM grammar, in my view correctly, does not define timing behavior
semantics inside functions (see A.2 and A.6). It allows any statement.

I assume it is illegal from outside a function to disable a named block
inside a function because that implies timing control that is explicitly
dis-allowed inside functions. Such disable is, I think, unlikely except for
debuggers that allow statement by statement tracing inside functions.
However, I read section 5.4.2 sentence 2 as allowing functions to be
interrupted in the middle (say) to execute other events because there is
no non timing control statement group atomicity condition.

I hope behavior within functions and for named blocks will be defined more
exactly in the new version of the LRM.

/Steve

Function from DA Solutions public domain bench marks das_cpu example
<PRE>
function [0:31] sign_extend;

input [0:15] D2;
reg [0:31] result;

begin
   begin
        begin : sextend
        integer i;
        begin
        for (i = 0; i < 16; i = i+1)
        begin
        result[i] = D2[0];
        result[i+16] = D2[i];
        end
        end
   end
   sign_extend = result;
end
endfunction
endmodule
</PRE>
Here is a test top level module
<PRE>
module top;
reg [0:15] D, X;
 
initial
 begin
  D = 6;
  X = sign_extend(D);
  $display("sign extend of %b is %b", D, X);
 end

-- 
Steve Meyer				Phone: (415) 296-7017
Pragmatic C Software Corp.		Fax:   (415) 781-1116
220 Montgomery St., Suite 925		email: sjmeyer@crl.com
San Francisco, CA 94104
</PRE>

Hi, Steve.

I'll add my two cents worth.

Let me preface my remarks by saying that I have only the April 1995 draft since I apparently have not been judged eligible to get 1364 mailings on a regular basis.

I don't agree with your interpretations.

I don't think that named blocks should be considered task enables. My P1364 draft seems to distinguish between named blocks and tasks. 1364 does not imply, in my opinion, that because named blocks can be disabled, then they are like task enables. You don't explain why you think that one necessarily follows from the other.

In certain respects, they are similar, but different in others.

I don't see a reason that named blocks should be illegal in functions.

I have in the past argued that functions MUST be executed atomically in order to guarantee coherent execution.

Regards,<BR> <PRE> ****************************************************************************** Shalom Bresticker email: shalom@msil.sps.mot.com Motorola Semiconductor Israel, Ltd. Tel #: +972 9 9522268 P.O.B. 2208, Herzlia 46120, ISRAEL Fax #: +972 9 9522444 ****************************************************************************** </PRE> ---------------------------------------------------------------------------

The following code is acceptable by both XL and VCS; the disable statement terminates execution of the block and the function returns the current value assigned to it.

<PRE> module test;

function f; input a,b,c; begin :block f = a|b & c; disable block; f = 'b0; end endfunction

initial begin $display("Result is %0b.", f('b1, 'b0, 'b1)); end endmodule </PRE>

<H3> Proposal </H3>

Change the last paragraph of section 11 "Disabling of named blocks and tasks" from

"The disable statement can be used within blocks and tasks to disable the particluar block or task containing the disable statement. The disable statement cannot be used to disable functions."

to:

"The disable statement can be used within blocks and tasks to disable the particluar block or task containing the disable statement. The disable statement can be used to disable named blocks within a function, but cannot be used to disable functions. In cases where a disable statement within a function disables a block or a task that called the function, the behavior is undefined."

<HR SIZE=5 NOSHADE> </BODY> </HTML>



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