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 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]; 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) 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, 7 Mar 2007 11:18:40 -0800
This archive was generated by hypermail 2.1.8 : Wed Mar 07 2007 - 11:19:18 PST