Casting from unpacked array to packed array

I want to cast unpacked 2D array to packed array.

It seems casting from unpacked to packed can be made easily when I read LRM[*].
So, I have tried to use casting instead of copying one-by-one. But I cannot do that easily. What is the good way to do this?

I want to cast from “vec_unpack” to “vec_pack”, which are different shape.
I do not care some data might be truncated if destination is smaller than source(although
in this example, no truncation happened).

logic [255:0][7:0] vec_pack; // unpacked
logic [31:0] vec_unpack [10]; // packed

Below is what I tried only to fail:

logic [255:0][7:0] vec_pack; // unpacked
logic [31:0] vec_unpack [10]; // packed

vec_pack = vec_unpack ; // compile ERROR(1)
vec_pack = ‘{ vec_unpack } ; // compile ERROR(2)
vec_pack = 320’{ vec_unpack } ; // compile ERROR(3)

Obviously, following code works fine:

logic [255:0][7:0] vec_pack; // unpacked
logic [31:0] vec_unpack [10]; // packed

// OK
for(int i=0; i<10; i++) begin
{vec_pack[i*4+3],
vec_pack[i*4+2],
vec_pack[i*4+1],
vec_pack[i*4]} = vec_unpack[i] ;
end

[*] LRM(1800-2009 page91):
When unpacked data are converted to the packed representation, the order of the data in the packed representation is such that the first field in the structure occupies the MSBs. The effect is the same as a concatenation of the data items (struct fields or array elements) in order. The type of the elements in an unpacked structure or array shall be valid for a packed representation in order to be cast to any other type, whether packed or unpacked.

Thank you, in advance, for your cooperation.

vec_pack = 320’( vec_unpack) ; // note ()'s instead of {}'s

works for me, although it does not match the functionality of your for loop. When you declare an unpacked range of [10], that is equivalent to [0:9]. You might want to try:

logic [31:0] vec_unpack [9:0];

Bitstream casts require all bits to be preserved, no padding or truncation. When you do 320’{vec_unpack}, that casts vec_unpack to a packed array of the same size, then it is assigned to another packed array, and standard Verilog rules apply (right justify bits, then pad or truncate).

You may also want to look at the streaming operator to manipulate the bit patterns.

vec_pack={>>32{vec_unpack}};

In reply to dave_59:

Thank you for the advice.

vec_pack = 320’( vec_unpack) ; // note ()'s instead of {}'s
I tried the code but this fails for both VCS(Synopsys) and IES(Cadence) saying that:
(For Cadence, this expression has not yet implemented)

[VCS(2011.03)]
Error-[ICO] Illegal cast operation
tb_cast.sv, 21
Typecast fails because the use of width casting used with unpacked objects:
320’(vec_unpack).

[IES(10.2)]
vec_pack = 320’( vec_unpack);
|
ncvlog: *E,SCNOIN (tb_cast.sv,21|33): As a temporary implementation restriction, the source data type in a static cast must be an integral, real or class data type.
module worklib.tb:sv
errors: 1, warnings: 0


For the bitstream operation, I can run with VCS( but IES does not support this operation!!):

      vec_pack = { >> {vec_unpack}};
                    |

ncvlog: *E,ILLPRI (tb_cast.sv,20|24): illegal expression primary [4.2(IEEE)].
module worklib.tb:sv
errors: 1, warnings: 0


For incorrect indexing in code, thank you for the correction.
I agree with you.

Regards.

In reply to tsb_matumoto:

It works in Questa, you should try it. :)

Another thing to try that should work in all simulators is cast to an intermediate packed type.

typedef logic [319:0] logic320_t;
...
vec_pack = logic320_t'(vec_unpack);

In reply to dave_59:

Thank you for the advice.

I found Cadence has not support streaming opearator yet, by asking customer support.
(Currently my project chooses IES so takes some time for setting upQuesta…).

I can understand the grammatically correct way of casting unpacked array to poacked.
And, this time, I also realized that Questa would be a best choice when I work on SystemVerilog.

Thank you very much.
Best regards.

hi Dave, I have an unpacked array like
bit [15:0]data;
and a packed array bit [15:0]data1;

i want to sent the unpack data serially, like 16bit data[0] from LSB to MSB, and then data[1],data[2] simillarly in a loop,

I wrote like

foreach(data[i])
repeat(16)
data1=data[i]<<1;

Do you have any other idea to execute this???