Non-constant indexing for a logic statement in sys

2019-02-21 05:54发布

问题:

I am trying to create a for loop that assigns different values to a logic array given the iteration of the loop.

So, for instance, let's say I am trying to instantiate two different bricks, both with a width of 10 and height of 5. Let's also say that each of these values are 10 bits. For two bricks, I have the code:

logic[19:0] Brick_Width;
logic[19:0] Brick_Height;

Where the first brick's width and height will be assigned into the most significant 10 bits and the second's in the least significant 10 bits.

This is the code that I currently have for this:

int i = 19;
initial
begin
 for(i=19; i>=0; i=i-10)
 begin
  assign Brick_Width[i:i-9] = 10;
  assign Brick_Height[i:i-9] = 5;
 end
end

However, I get an error saying that "i" is not a constant. Any ideas on how I can go about doing this?

回答1:

Commonly used range-select using : operator must have a constant. Your intent can be accomplished by what is known as bit-select operators.

Referring to example from LRM 1800-2012, section 11.5 as below:

logic [31: 0] a_vect;
logic [0 :31] b_vect;
logic [63: 0] dword;
integer sel;
a_vect[ 0 +: 8] // == a_vect[ 7 : 0]
a_vect[15 -: 8] // == a_vect[15 : 8]
b_vect[ 0 +: 8] // == b_vect[0 : 7]
b_vect[15 -: 8] // == b_vect[8 :15]
dword[8*sel +: 8] // variable part-select with fixed width

The +: and -: operators must be used for bit-slicing or part select as in your case. Here, you want to select a part from i to i-9, so the -: operator must be used. Like Brick_Height[i-:9]=...

For example,

x +: Y, the start position is x and count up from x by Y. Y is necessarily a constant.
x -: Y, the start position is x and count down from x by Y. Y is necessarily a constant.

One more thing, assign statement inside initial block, makes it continuous procedural assignment. The bit-select won't work in that case. To accomplish that, either simply remove assign statement. as follows:

for(i=19; i>=0; i=i-10)
 begin
    Brick_Width[i-:9] = 10; // no assign, rest all the stuff is same
    Brick_Height[i-:9] = 5;
 end

Or use a generate block, if continuous driving is the intent.

genvar i;
generate
for(i=19; i>=0; i=i-10)
begin
    assign Brick_Width[i-:9] = 10;
    assign Brick_Height[i-:9] = 5;
end
endgenerate

More information on bit-select can be found at this link.

SIDE NOTE:

Referring to following phrase in your question:

For two bricks, I have the code:

You must have and array like logic[9:0] Brick [2].