Apparently, Icarus requires that bit select index within generate statements be constants. That seems like a bug in and of itself. However, in the context where I'm getting the error, the bit index IS a constant, in so far as that the index is a fixed function of the genvar value.
Here's an example of the error:
project.v:63: error: Index of dc[self] needs to be constant in this context.
project.v:63: : Index expression is: self
project.v:63: : Context scope is: top.hookup[0]
Here's a bit of the code causing the error:
genvar i;
generate for (i=0; i<64; i=i+1) begin: hookup
integer x = i[1:0]+1;
integer y = i[3:2]+1;
integer z = i[5:4]+1;
integer self = x*7 + y*4*7 + z*16*7;
...
Delay #(d2mm, e2mm) c0 (c[self], dc[self]); // <--- LINE 63
...
So, to begin with, I see no good reason why the bit select should be constant. And secondly, the compiler should realize that it IS a constant when it optimizes the expressions.
Actually this is not a constant select. Yes it is driven by variables that have constant initializations, but variables are most definitely not constants. If you wanted constants you would need to use parameters instead of integers.
I'm not certain we have enough code to figure out the context, but I'll see what I can figure out given the code you provided and the error message. It would be nice if you could provide a working example of the problem. As a minimum how is Delay, c and dc defined? It's interesting to note that only dc is getting the warning when both c and dc have variable bit selects. Have you tried this using the latest development from git? I'm not certain it would make a difference, but we did make some improvements in the handling of R-value bit and part selects. Does this same basic construct work outside a generate block?
I'll may have more questions when I have some time later today to look at the source code.
I'm monkeying around with it to try to find a good example. (I rewrote the code that created the original error, so I have to construct a new example.) If the integer expression is straight-forward like "integer k=i+1", then it works fine. If it's more complex, then I get errors. Consider the following code:
module test;
wire [0:11] somebits;
genvar i;
generate for (i=0; i<10; i=i+1) begin
integer j = i[1:0];
integer k = j+i; // THIS IS LINE 10
othermodule o(somebits[k], somebits[i]);
end
endgenerate
endmodule
module othermodule(
input x, output y);
assign y = x;
endmodule
Because I did a part select on i, I get this error on the following line:
bugtest.v:10: error: The RHS expression must be constant.
bugtest.v:10 : This expression violates the rule: (<select+=+j[31:0][(0)+:33]>)+(33'sd0)
I can't actually make sense of this error, because there's no select on line 10. Maybe your optimizer has propagated j by subbing i[1:0]. I considered that Icarus doesn't handle part selects in this context. I tried replacing i[1:0] with i&3, but that didn't help. Then I replaced it with just "i", so the assignments are:
integer j = i;
integer k = j+i;
And I still get an error. Then, I replaced it with this:
integer j = i;
integer k = i+i; // Changed from j+i to i+i
And the error went away! So, Icarus can handle one level of math between the genvar and a bit select, but not more than one level.
Finally, I tried replacing "integer" with "parameter", and I got this error:
bugtest.v:9: parameter declarations are not permitted in generate blocks
bugtest.v:10: parameter declarations are not permitted in generate blocks
In case you're interested, what I was trying to do is simulate a 3D mesh network. I have 64 nodes ("processor" and router), connected as a 4x4x4 cube. And what I wanted to do was instantiate the nodes and the wires in between them. What I ended up doing instead (which turns out to be easier to navigate in a waveform viewer) is defining a "Row" module, that connects nodes, then a Plane module that connects rows, etc. What I was trying to do before involved a big generate in the top-level that had to do some math to figure out the north, south, east, west, etc. connections for each node and those connections were represented by indexes into a wire [0:66*3-1].
BTW, this is the version I'm using:
Icarus Verilog version 0.9.1 (v0_9_1)
I'll look into compiling from git a bit later.
This is purely a guess, but if I assume that dc is a net and the second argument to Delay is an output then this is exactly what I would expect. A continuous assignment is used to connect module ports and the L-value of a continuous assignment must be a constant bit select (1364-2005 page 179 (Port connection rules) and page 68).
The Delay block starts like this:
module Delay(
input in,
output reg out);
Basically, all it does is assign in to out with a wire delay.
dc is a net. It's a wire indexed from bus. Same for c, which is driven by something else.
I can see why driving an indexed net must have a constant index. What's missing, I guess, is a way to make Icarus able to calculate constants from other constants. Apparently, it's able to do that through one level of indirection, but not two.
This sounds more like a comp.lang.verilog questions. I believe that Icarus is working correctly. A genvar is basically a variable parameter so it is a constant. An integer value no mater what you do can never be a constant value. Line 10 is failing because you are using the sum of an integer plus a constant as an initialization value (which isn't constant).
I believe the odd select message is to show that the value is being extended to 33 bits. I agree this could generate a more user friendly message.
The i + i example works because you are adding two constants and that is a constant value.
Yep parameters can not be declared inside a generate block.
Icarus does not allow one level of indirection the genvar i is a constant.
My suggestion would be to create a macro with an argument to represent the calculation you are trying to implement. If we supported constant functions you could use that, but we don't so a macro is the next best things. The compiler should squash all this to a single value.
I'll wait for confirmation, but I'm fairly certain there are no bugs in Icarus related to this report.
FYI 0.9.2 is the latest released stable version.
I don't want to unnecessarily belabor this. But there is one statement you make that bothers me.
You say this works because i is a constant:
[a] integer k = i+i;
Except that k is not a constant here, based on your explanation. Thus, using k in a bit select should fail. But it doesn't. So somehow, the const-ness of i is being propagated to k.
On the other hand, I can't make this work:
[b] integer j = i;
[b] integer k = j+i;
If an assignment of a constant to an integer does not propagate const-ness, then [a] should fail, but it does not. If const-ness DOES propagate, then [b] should succeed, but it does not. Const-ness should either be transitive, or it should not be. But we have one case where it is transitive [a], and one case where it is not [b]. Based on what I observe, it appears that in [b], const-ness must propagate from i to j, but it does not propagate from j to k. How is it that const+const is const in one case, but not in the other?
This is an inconsistency.
Now, maybe it's bonus that [a] works at all. Actually, I'm worried it may be a bug. It may APPEAR to work, when in fact, Icarus silently does something wrong.
I don't see the discontinuity. For case [a] integer k is given an initial value which is the constant i+ i. k itself should never be constant and should never propagate a constant value. It's possible that the place you are using k supports variable bit selects. I'm guessing you are also getting confused about the integer self declaration. It should also have an error message, but it's possible that the previous bit select message was blocking it. Taking just the simple integer code and running it with both the latest V0.9 and development from git will produce warnings about the self initialization not being constant. Using the following define works as expected:
`define SELF(arg) ((arg[1:0]+1) + (arg[3:2]+1)*4 + (arg[5:4]+1)*16)*7
integer self = `SELF(i);
This should also work for the constant bit select (dc[`SELF(i)]).
You need to determine if the context where you are using k as the bit select index actually supports variable bit selects or not. I'm guessing it does and that is confusing you. I don't see this in the code you supplied so I can't comment more.
Have you had time to look at this? I would really like to determine if this is a bug in Icarus or not.. Also did you try this on any other simulators?
I'm marking this invalid. I can find nothing wrong with Icarus. If you can create an example that shows Icarus misbehaving please reopen this report. For now I'm going to close it.