From: Stephan B. <boe...@ph...> - 2012-03-24 00:11:09
|
I had good results with constructs like this: wire [width-1:0] insel[0..inputs]; wire [width-1:0] mux = insel[0]; assign insel[inputs]=0; generate for (g=0; g<inputs; g=g+1) assign insel[g] = rr_state[0] ? c_data >> (g*width) : insel[g+1]; endgenerate Guy Hutchison <ghu...@gm...> writes: > 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: >> -----BEGIN PGP SIGNED MESSAGE----- >> Hash: SHA1 >> >> >> >> 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 >>>>> _______________________________________________ >> >> >> - -- >> 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/ >> >> iEYEARECAAYFAk9tApgACgkQrPt1Sc2b3ikKKwCfRjlS5duvb7qATrYZeWWn7iOo >> bhkAoNl1TyTu7R+WrkFhv2tw95XRX1ey >> =EMgA >> -----END PGP SIGNATURE----- >> >> ------------------------------------------------------------------------------ >> 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 -- Dr. Stephan Böttcher Tel: +49-431-880-2508 Christian-Albrechts-Universität zu Kiel Inst. f. Exp. u. Angew. Physik, Abt. Extraterrestrische Physik Leibnizstr. 11, 24118 Kiel, Germany |