From: Stephen W. <st...@ic...> - 2012-03-23 23:39:33
|
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 When you are indexing a scope (i.e. a generated block in your case) the index must be constant. Sorry, them's the rules. I think in your first example you were not using a generate block at all but a behavioral for-loop that your synthesizer was able to unroll. It seems that Verilator is not as clever as your synthesizer. On 03/23/2012 04:29 PM, Guy Hutchison wrote: > Good catch by all replies, changing this to: generate for (g=0; > g<inputs; g=g+1) begin : breakout wire [width-1:0] insel; if > (g==0) assign insel = (rr_state[0]) ? c_data[width-1:0] : > {width{1'b0}}; else assign insel = (rr_state[g]) ? c_data >> > (g*width) : breakout[g-1].insel; end endgenerate assign p_data = > breakout[inputs-1].insel; > > Fixes the access-zero problem, as zero is the special case. > > As to why I am using this goofy structure, it is because building > a parameterized mux is a little painful if you have to have > constant bit selects, so I'm forced in to more odd constructions. > > On 3/23/12, Stephen Williams <st...@ic...> wrote: > > > There is no breakout[0]. When g==1, your generated assign will be: > > assign insel = (rr_state[1]) ? c_data >> (1*width) : > breakout[0].insel; > > but since breakout[0] is not generated, the reference to > (breakout[0].insel) fails. > > On 03/23/2012 03:45 PM, Guy Hutchison wrote: >>>> But if I recode it as follows: >>>> >>>> genvar g; >>>> >>>> wire [width-1:0] insel0; assign insel0 = (rr_state[0]) ? >>>> c_data[width-1:0] : {width{1'b0}}; assign p_srdy = |(rr_state >>>> & c_srdy); >>>> >>>> generate for (g=1; g<inputs; g=g+1) begin : breakout wire >>>> [width-1:0] insel; assign insel = (rr_state[g]) ? c_data >> >>>> (g*width) : breakout[g-1].insel; end endgenerate assign >>>> p_data = breakout[inputs-1].insel; >>>> >>>> then I get the error: error: Unable to bind wire/reg/memory >>>> `breakout[(g)-('sd1)].insel' in >>>> `env_top.bridge.control0.fib_arb.breakout[1] >>>> >>>> At this point everything is clearly constant, although >>>> icarus complains as above and Verilator complains that it >>>> can't shift by a non-constant value (width is a parameter). >>>> >>>> BTW, this whole rathole was triggered by Verilator >>>> complaining about the original syntax I have for this being >>>> unoptimizable due to a for loop. >>>> >>>> On 3/23/12, Martin Whitaker >>>> <mai...@ma...> wrote: >>>>> I think it's a LRM question. From section 12.5 of the >>>>> standard >>>>> >>>>> "Names in a hierarchical path name that refer to instance >>>>> arrays or loop generate blocks may be followed immediately >>>>> by a constant expression in square brackets." >>>>> >>>>> Constant expressions are defined in annex A (formal syntax) >>>>> and are defined to be one or more constant primaries >>>>> (combined by appropriate operators). A constant primary is >>>>> defined as >>>>> >>>>> constant_primary ::= number | parameter_identifier [ [ >>>>> constant_range_expression ] ] | specparam_identifier [ [ >>>>> constant_range_expression ] ] | constant_concatenation | >>>>> constant_multiple_concatenation | constant_function_call | >>>>> constant_system_function_call | ( >>>>> constant_mintypmax_expression ) | string >>>>> >>>>> 'j' in your code must be a hierarchical identifier >>>>> (otherwise you couldn't use it as a loop variable), so is >>>>> not a valid constant primary. >>>>> >>>>> So what you have written is not legal Verilog - even if a >>>>> synthesis tool accepts it. >>>>> >>>>> >>>>> Guy Hutchison wrote: >>>>>> Not sure if this is an Icarus question or an LRM >>>>>> question, but while refactoring some code with generate >>>>>> statements I ran across this error message: >>>>>> >>>>>> sd_rrmux.v:151: error: Scope index expression is not >>>>>> constant: j >>>>>> >>>>>> The code that caused the error was: generate for (i=0; >>>>>> i<inputs; i=i+1) begin : grid_assign wire [width-1:0] >>>>>> temp; assign temp = c_data>> (i*width); //assign >>>>>> rr_mux_grid[i] = c_data>> (i*width); end endgenerate >>>>>> always @* begin p_data = 0; p_srdy = 0; for (j=0; >>>>>> j<inputs; j=j+1) if (rr_state[j]) begin //p_data = >>>>>> rr_mux_grid[j]; p_data = grid_assign[j].temp; p_srdy = >>>>>> c_srdy[j]; end end >>>>>> >>>>>> A synthesis tool has no problem figuring out that j is >>>>>> constant within the begin-end scope listed here; why is >>>>>> it not "constant" for picking up a scope reference? This >>>>>> also fails within a generate loop using a genvar as the >>>>>> index var. >>>>>> >>>>>> ------------------------------------------------------------------------------ >>>>>> >>>>>> > >>>>>> This SF email is sponsosred by: >>>>>> Try Windows Azure free for 90 days Click Here >>>>>> http://p.sf.net/sfu/sfd2d-msazure >>>>>> _______________________________________________ > > >> >> ------------------------------------------------------------------------------ >> >> This SF email is sponsosred by: >> Try Windows Azure free for 90 days Click Here >> http://p.sf.net/sfu/sfd2d-msazure >> _______________________________________________ Iverilog-devel >> mailing list Ive...@li... >> https://lists.sourceforge.net/lists/listinfo/iverilog-devel >> > > ------------------------------------------------------------------------------ > > This SF email is sponsosred by: > Try Windows Azure free for 90 days Click Here > http://p.sf.net/sfu/sfd2d-msazure > _______________________________________________ Iverilog-devel > mailing list Ive...@li... > https://lists.sourceforge.net/lists/listinfo/iverilog-devel > - -- Steve Williams "The woods are lovely, dark and deep. steve at icarus.com But I have promises to keep, http://www.icarus.com and lines to code before I sleep, http://www.picturel.com And lines to code before I sleep." -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.16 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk9tCaoACgkQrPt1Sc2b3im/3wCgq2uzoGn1aok3DFAW1pCoJBLd uu0AoJmNtOKp0PIJO7h6KrYIJLlyAb8C =ukKr -----END PGP SIGNATURE----- |