• System Verilog issues with part_select/ generate simple for loop in alw

    From ravichandar.a@gmail.com@21:1/5 to All on Thu Nov 1 19:05:45 2018
    Trying to write a simple N bit priority arbiter (which will prioritize req[0]>req[1]>req[2] ... req[N].

    Working code:

    assign grant_simple[0] = req_in[0];

    generate

    for (i=1; i<N; i++)
    assign grant_simple[i] = req_in[i] & (!(|req_in[i-1:0]));

    endgenerate

    But i tried without generate and using always_comb block like this.

    assign grant_simple[0] = req_in[0];

    always_comb begin

    for (int i=1; i<N; i++)
    grant_simple[i] = req_in[i] & (!(|req_in[i-1:0]));
    end //always

    This is giving me an error.

    Error-[IRIPS] Illegal range in part select design.sv, 18 The range of the part select is illegal: req_in[(i - 1):0]

    Error-[TCF-CETE] Cannot evaluate the expression design.sv, 18 "(i - 1)" Cannot evaluate the expression in left slicing expression. The expression must be compile time constant.

    I tried replacing [i-1:0] with i-:1 but i dont think it does the same thing. Looking for a clear explanation on why generate is ok with the [i-1:0] and not the for loop without generate. How to use the bit slicing in this case for system verilog. Thanks
    much.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kevin Neilson@21:1/5 to ravich...@gmail.com on Fri Nov 2 11:54:18 2018
    On Thursday, November 1, 2018 at 8:05:48 PM UTC-6, ravich...@gmail.com wrote:
    Trying to write a simple N bit priority arbiter (which will prioritize req[0]>req[1]>req[2] ... req[N].

    Working code:

    assign grant_simple[0] = req_in[0];

    generate

    for (i=1; i<N; i++)
    assign grant_simple[i] = req_in[i] & (!(|req_in[i-1:0]));

    endgenerate

    But i tried without generate and using always_comb block like this.

    assign grant_simple[0] = req_in[0];

    always_comb begin

    for (int i=1; i<N; i++)
    grant_simple[i] = req_in[i] & (!(|req_in[i-1:0]));
    end //always

    This is giving me an error.

    Error-[IRIPS] Illegal range in part select design.sv, 18 The range of the part select is illegal: req_in[(i - 1):0]

    Error-[TCF-CETE] Cannot evaluate the expression design.sv, 18 "(i - 1)" Cannot evaluate the expression in left slicing expression. The expression must be compile time constant.

    I tried replacing [i-1:0] with i-:1 but i dont think it does the same thing. Looking for a clear explanation on why generate is ok with the [i-1:0] and not the for loop without generate. How to use the bit slicing in this case for system verilog.
    Thanks much.

    Verilog usually doesn't like variable slice widths. There may be OK with the generate because the loop is only evaluated "presynthesis". You could rewrite using nested loops with the inner loop accessing only a single bit and the outer loop having a
    variable length. Cumbersome, but it works.

    Here's another style that works:

    reg [15:0] grant_simple;
    reg [15:0] req_in = 16'hF0F0;

    always@(*) begin
    reg grant_superceded_var = req_in[0]; // 1=>grant has already been superceded by previous req

    grant_simple[0] = req_in[0];
    for (int i=1; i<16; i++) begin
    grant_simple[i] = req_in[i] && !grant_superceded_var;
    grant_superceded_var = grant_superceded_var || req_in[i];
    end
    $display("grant_simple: 0x%h",grant_simple);
    end

    Result: grant_simple: 0x0010


    This is another style from the Altera Synthesis Cookbook implementing a "trailing one detector". It's not intuitive, but it works very well for large N because it uses the fast carry chain in an FPGA:

    reg [15:0] req_in = 16'hF0F0;
    wire [15:0] grant2 = req_in & ~(req_in-1); // Trailing 1 detect

    initial #10ps $display("grant2: 0x%h",grant2);

    Result: grant2: 0x0010

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From ravichandar.a@gmail.com@21:1/5 to All on Fri Nov 2 13:38:44 2018
    Your solution for adding an extra line in the for loop works fine. Thank you.

    I have a similar question as well.

    Say if i am using a generate statement in the always_ff.

    generate

    for (i ...)

    always_ff @(posedge clock, negedge reset)

    <reset condition>

    else

    <actual code>

    My question is how to deal with /seperate the reset condition from the always_ff block in the for loop? Its not very intuitive. You will get the multi driver error with the above code.

    Thanks.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kevin Neilson@21:1/5 to ravich...@gmail.com on Mon Nov 5 09:00:19 2018
    On Friday, November 2, 2018 at 2:38:47 PM UTC-6, ravich...@gmail.com wrote:
    Your solution for adding an extra line in the for loop works fine. Thank you.

    I have a similar question as well.

    Say if i am using a generate statement in the always_ff.

    generate

    for (i ...)

    always_ff @(posedge clock, negedge reset)

    <reset condition>

    else

    <actual code>

    My question is how to deal with /seperate the reset condition from the always_ff block in the for loop? Its not very intuitive. You will get the multi driver error with the above code.

    Thanks.

    You might need a little more detail. Without begin/ends, it's hard to tell what belongs to what.

    A couple of comments: putting "negedge reset" in the sensitivity list means you are using an asynchronous reset, which is not that common anymore (for FPGAs, at least). And you probably don't need a 'generate' unless you are instantiating modules in
    the loop.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)