Bits assignment w/o loop

hi,

  1. I am trying to assign a lot of bits in one assignment in order to avoid loops.
    don’t know why it is not compiling…

data_to_shift = new [Msg_LengthBYTE_WIDTH];
fcu2dq_expected_bus [mapper_ID][BYTE_WIDTH
shift_offset +: Msg_Length*BYTE_WIDTH] = {data_to_shift};//this giving me the ERROR:

0.00 VCS ERROR: TCF-CETE (fc): Cannot evaluate the expression fcu_scoreboard_c.sv, 376 “(Msg_Length * $unit::BYTE_WIDTH)” Cannot evaluate the expression in width of indexed part-select. The expression must be compile time constant.

// if I assign bit by bit in foreach loop it works:

foreach (data_to_shift[i])
fcu2dq_expected_bus [mapper_ID][BYTE_WIDTH*shift_offset+i] = data_to_shift[i];

  1. I am also facing a problem when trying to concatenate two arrays like so:
    data_to_shift = {payload,MC_byte};

I get that the data_to_shift array shrinks to the size of 2: data_to_shift is 0x01 instead of Msg_Length*BYTE_WIDTH like was set in new func.

thanks, very much, Kobi.

In reply to kobiyonai:

Hi Kobi,

  1. The error “…Cannot evaluate the expression in width of indexed part-select. The expression must be compile time constant” is given because in Verilog and SystemVerilog “The size of the part select or slice(selection of one or more contiguous elements of an array) must be constant, but the position can be variable” - from SystemVerilog IEEE 1800-2012 standard, Chapter “Indexing and slicing of arrays”. So, I think that in your case Msg_Length*BYTE_WIDTH, which is the size of the part-select you want to access from the array, has a variable value at compile time and not a constant one.

  2. Here I need more details about payload and MC_byte arrays. In SystemVerilog IEEE 1800-2012 standard, Chapter “Array assignment” is mentioned that “When a dynamic array or queue is assigned to a fixed-size array, the size of the source array cannot be determined until run time. An attempt to copy a dynamic array or queue into a fixed-size array target having a different number of elements shall result in a run-time error and no operation shall be performed”.

Thank you,
Claudia Iancu

In reply to Claudia Iancu:

  1. ok, now I get it… I guess there’s not a lot I can do about it.
  2. here the destination array is a dynamic and the two others are static. this is my function, I would like to use one-time assignment instead of foreach loop. I think the problem is because is need a dynamic bit-vector and not an array, does such exist?

task automatic shift_stage (ref bit [(LLFC_PAYLOAD_SIZE)-1:0] llfc_payload, ref bit [BYTE_WIDTH-1:0] MC_byte, int mapper_ID, int shift_offset, int Msg_Length);
//veriable-depended size array - dynamic
bit data_to_shift;

data_to_shift = new [Msg_Length*BYTE_WIDTH];
// first byte of data_to_shift is MC, the others are UC
foreach (data_to_shift[i])
begin
if (i<BYTE_WIDTH)
data_to_shift[i] = MC_byte[i];
else
data_to_shift[i] = llfc_payload [i-BYTE_WIDTH];
end
endtask // shift_stage

In reply to kobiyonai:

In your case:
data_to_shift is an unpacked array
llfc_paylod and MC_byte are packed arrays

In this operation:
data_to_shift = {llfc_paylod, MC_byte}

you are initializing data_to_shift with 2 elements/numbers. You can read more about packed and unpacked arrays in SystemVerilog IEEE 1800-2012 standard, Chapter “Packed and unpacked arrays”.

If I understood correctly, you want to put the bits of MC_byte and llfc_paylod into data_to_shift using one-time assignment instead of foreach loop. You can use bit-stream operator like this:
data_to_shift = {<<{llfc_paylod, MC_byte}

Also, you need to pay attention to the MSB (most significant bit) and LSB(least significant bit) order.