System Verilog issues with part_select/ generate simple for

Guest
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 = req_in & (!(|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 = req_in & (!(|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.
 
On Thursday, November 1, 2018 at 8:05:48 PM UTC-6, ravich...@gmail.com wrote:
.

Working code:

assign grant_simple[0] = req_in[0];

generate

for (i=1; i<N; i++)
assign grant_simple = req_in & (!(|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 = req_in & (!(|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 = req_in && !grant_superceded_var;
grant_superceded_var = grant_superceded_var || req_in;
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
 
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.
 
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.
 

Welcome to EDABoard.com

Sponsor

Back
Top