Re: [sv-bc] part selects on arbitrary expressions

From: Greg Jaxon <Greg.Jaxon_at_.....>
Date: Wed Mar 07 2007 - 12:06:06 PST
Michael (Mac) McNamara wrote:
> Yulik, the problem is that as defined, the width of the stuff inside a
> parenthesis _is_ affected by stuff outside.  So your desire to instead
> get the "original" type as is requires a change to the language.

The propagation of widths and signedness occurs long after the expression
has been parsed.  Once it has been parsed, the left operand of a select
lies "below" it (i.e. leafward) in the parse tree.  Such locations are /not/
context-determined.  Adding selects of arbitrary expressions would not
require any change to existing practice in this regard.

The problem of moving expressions from one source site to another and
preserving their meaning is utterly hopeless in Verilog - because this
language extension increases the "self-determined" space, I regard it
as healthier than many of the alternatives proposed for this feature.

>   The
> change isn't per se breaking backwards compatibility, because currently
> no standard compliant code does (a&b)[i].  However, constructing the
> wording in the manual so that
> 
> assign y = x + (r&s);
> 
> retains the sign, size, and type coercion of r and s by x and y, while 
> 
> assign y = x + (r&s)[5:3];

Not a problem.  The same mechanism which prevents  assign y = x + s[5:3]
from coercing s before extracting the [5:3} part will halt the width
coercion of (r&s)[5:3].

But now that you've raised this point, let's be clear that the signedness
coercions would ALSO stop at the selection node.

> 
> does not will be a real challenge, especially in the very situations
> where the expression is even more complex stretching over a few lines,
> and hence where not requiring assigning through a temp is most valuable.
> 
> So:
> 
> reg [127:0] x,y;
> reg signed [31:0] r,s;
> integer i,j,k;
> 
> ...
> assign y = x + (r+s)[63:0]; 
> 
> have r and s extended to be 128 bits wide due to the "x +" part of the
> expression, so selection of bits 
> 63 through 0 is legal, and would return known bits (the top bits would
> have the sign extended & overflow results of the addition)

What?!

I simply don't see what arithmetic fidelity is preserved by such a
madhouse of width coercions.  This view is also inconsistent with
the treatment of  assign y = x + s[63:0];  Unless I am horribly mistaken,
s is not first extended to 128 bits and then truncated.  If I /am/
wrong about this, I need to know immediately so I can correct our
implementation pronto.


> 
> where as
> 
> assign y = x + {r+s}[63:0]; would return unknown bits in the top 32
> bits, and any overflow of the addition would be lost.
> 
> If one wanted to retain the overflow bit, one would do:
> 
> assign y = x + {r+s+33'b0};
> 
> Now, looking at your example, you seem to be desiring to use neither the
> {} nor the () as a scope and anchor for the [].  You are hoping to just
> do a bare [] from the function call, or other entity:
> 
> assign x = y & func()[50];
> 
> As I believe has been pointed out, this runs into problems where:
> 
> reg [31:0] a1 [1023:0] [3:0];
> reg [31:0] al [1023:0];
> 
> ...
> 
> b = a1[3][2][1]; // select the fourth bank, select from that the 3rd
> word, and select from that the second bit.
> b = al[3][2][1]; // select the fourth word, select from that the 3rd
> bit, and select from that the 2nd bit (an out of range select, returning
> x
> 
> 
> Today the second one is illegal, and is caught by tools.  With this
> change the second one is legal, and silently returns an x, and the typo
> of '1' vs. 'l' makes them difficult to find via examination.
> 
> If we require at least a parenthesis, you would need to have:
> 
> assign x = y & (func())[50];
> 
> and
> 
> b = (al[3][2])[1];
> 
> in order to allow this typo to elude the parser. 
> 
> 
> -----Original Message-----
> From: owner-sv-bc@eda.org [mailto:owner-sv-bc@eda.org] On Behalf Of
> Feldman, Yulik
> Sent: Wednesday, March 07, 2007 6:41 AM
> To: Jonathan Bromley; Bresticker, Shalom; sv-bc@eda.org
> Subject: RE: [sv-bc] part selects on arbitrary expressions
> 
> Hi Jonathan,
> 
> I didn't suggest normalizing all sub-types to [N-1:0]. I suggested
> leaving the "original" type as is. So to select the leftmost bit of the
> return value of the function in your example, I would want to write
> something like func()[50].p[5][20], which I think is clear both
> syntactically and semantically. The type of first operand of the part
> select (the func()) would be the original "Thing".
> 
> The "normalized" [N-1:0] type is only necessary for expressions that are
> operators (with the possible exception of the conditional operator). For
> expressions like "a", "(a)", "func()" or "smth[5][25]", the type should
> match the type of the corresponding declaration, or, in case of the part
> select, should match a corresponding "slice" of the selected type
> (without "normalization").
> 
> --Yulik.
> 
> -----Original Message-----
> From: Jonathan Bromley [mailto:jonathan.bromley@doulos.com]
> Sent: Wednesday, March 07, 2007 4:13 PM
> To: Feldman, Yulik; Bresticker, Shalom; sv-bc@server.eda.org
> Subject: RE: [sv-bc] part selects on arbitrary expressions
> 
> [Shalom]
> From those points of view, using concatenations, i.e., allowing
> bit-selects and part-selects of concatenations, is much less ambiguous.
> It is only a partial solution, in that it would only deal with 1-D
> arrays [Yulik] ...For me, a solution that will not account for complex
> data types will not be really a solution.
> 
> As Mike McNamara has wisely suggested, you could reasonably use
> concatenation braces {} to imply flattening of a self-determined
> expression so that its outermost subscript range is of the form [N-1:0],
> although it's important to note that this would represent a subtle
> change of the data type of the expression.  But Yulik seems to want to
> similarly flatten
> *all* subscript ranges, right the way down through the whole structure
> of the expression.  
> 
> I find this completely unacceptable unless we have some new syntax to do
> this subscript-normalisation explicitly.  For example, we could borrow
> the style of bitstream operators and do this (only an example, I'm not
> advocating this specific syntax):
> 
>   {[]{ expression }}
> 
> where the [] "operator" is taken to mean "create a primary having the
> same data type as expression, but with all its subscript ranges
> normalised to [N-1:0]".  You could then do arbitrary subscripting and
> selection like this...
> 
>   typedef struct 
>     logic [20:21] p[5:7];
>     byte q;
>   Thing [50:48];
> 
>   function Thing func(...) ... endfunction
> 
> Given those declarations, the expression
> 
>   {[]{ func(...) }} [2].p[2][1]
> 
> would now reliably represent the extreme leftmost bit of the struct
> returned by func().
> 
> Without some completely new syntax, slicing and selection on expressions
> is always going to be a mess and it must be rejected.
> --
> Jonathan Bromley, Consultant
> 
> DOULOS - Developing Design Know-how
> VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services
> 
> Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24
> 1AW, UK
> Tel: +44 (0)1425 471223                   Email:
> jonathan.bromley@doulos.com
> Fax: +44 (0)1425 471573                           Web:
> http://www.doulos.com
> 
> The contents of this message may contain personal views which are not
> the views of Doulos Ltd., unless specifically stated.
> 
> --
> This message has been scanned for viruses and dangerous content by
> MailScanner, and is believed to be clean.
> 
> 
> 


-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Wed Mar 7 12:07:13 2007

This archive was generated by hypermail 2.1.8 : Wed Mar 07 2007 - 12:07:31 PST