[How to] Assign integer value to unpacked array slice

Hi,

I currently can’t help myself with the following situation where I have a random unpacked array inside a sequence item.

rand logic tcode_tx [8:0];

Because 3 bits of the array always need to be zero, I constrained it in the same place.

constraint c_tcode_tx {tcode_tx[8] == '{0};
                       tcode_tx[1] == '{0};
                       tcode_tx[0] == '{0};
                       }

At the point of tcode_tx randomization inside a corresponding sequence, I want to be able to assign an integer counter value to the unconstrained part, i.e. tcode_tx[7:2].

repeat (tc_req_cnt) begin
    tc_counter++;
    start_item(req_item_c);
    if(!req_item_c.randomize() with {send_tc       == 1;
                                     tcode_tx[7:2] == '{tc_counter};
                                     }) begin
    `uvm_fatal("BODY:", "req_item_c randomization failed")
    end

    `uvm_info("BODY:", req_item_c.convert2string(), UVM_MEDIUM);
    finish_item(req_item_c);
    if(tc_counter == 63) begin
        // Reached max. tc_counter value
        tc_counter = 0;
    end
end

But the assignment fails for now. Any tips on how to do it correctly?

In reply to Fipser@VA:

Could you please show the exact error message?

In reply to chr_sue:

In reply to Fipser@VA:
Could you please show the exact error message?

**** Error (suppressible): … (vlog-13174) Illegal assignment pattern. The number of elements (1) doesn’t match with the type’s width (6).**

In reply to Fipser@VA:

Your problem is here

tcode_tx[7:2] == '{tc_counter};

On the LHS you have 6 entries and on the RHS you have only 1 entry.

In reply to chr_sue:

In reply to Fipser@VA:
Your problem is here

tcode_tx[7:2] == '{tc_counter};

On the LHS you have 6 entries and on the RHS you have only 1 entry.

I know. But I don’t know how the assignment is made properly.

In reply to Fipser@VA:

What you need in your assignment pattern is a replication.
Note tcode_tx has only 1 bit to be assigned for each unpacked dimension.

In reply to Fipser@VA:

We cannot understand what your intent is. Are you looking for

tcode_tx[7] == tc_counter[5] &&
tcode_tx[6] == tc_counter[4] &&
tcode_tx[5] == tc_counter[3] &&
tcode_tx[4] == tc_counter[2] &&
tcode_tx[3] == tc_counter[1] &&
tcode_tx[2] == tc_counter[0]

Can you make code_tx a packed array? Then you could do

tcode_tx[7:2] == tc_counter;

In reply to dave_59:

In reply to Fipser@VA:
We cannot understand what your intent is. Are you looking for

tcode_tx[7] == tc_counter[5] &&
tcode_tx[6] == tc_counter[4] &&
tcode_tx[5] == tc_counter[3] &&
tcode_tx[4] == tc_counter[2] &&
tcode_tx[3] == tc_counter[1] &&
tcode_tx[2] == tc_counter[0]

Can you make code_tx a packed array? Then you could do

tcode_tx[7:2] == tc_counter;

Hi,

the code above works, thanks! Is there no other way to do it besides assigning the value bit by bit? (type casting, streaming, anything else?)

I chose tcode_tx to be an unpacked array, because the array is passed as a parameter to a task inside a driver, where the parameter can also be a queue (thus unpacked).

My intention was to increment an integer value (here: tc_counter) and with every new sequence item assign the incremented value to the slice tcode_tx[7:2], i.e. assign the int type value to a 6 bit wide slice of an unpacked array (somehow!). That’s why I reset tc_counter to 0 if it hits 63 = 6’b111111.

Even if I assigned a constant value, as I would do to initialize an unpacked array, e.g.

tcode_tx[7:2] == '{1,1,0,0,1,0}

within the randomization part, I get a compilation error.

In reply to Fipser@VA:

Why don’t you declare it as a packed array, and then cast as an unpacked array. Or you can cast it to a packed local variable and use that in your constraint.

In reply to dave_59:

In reply to Fipser@VA:
Why don’t you declare it as a packed array, and then cast as an unpacked array. Or you can cast it to a packed local variable and use that in your constraint.

Do you mean like:

logic [5:0] tc_val;
// ...
repeat (tc_req_cnt) begin
    tc_val++;
    start_item(req_item_c);
    if(!req_item_c.randomize() with {send_tc       == 1;
                                     tcode_tx[7:2] == '{tc_val[5],tc_val[4],
                                                        tc_val[3],tc_val[2],
                                                        tc_val[1],tc_val[0]
                                                        };
                                     }) begin
// ...
    finish_item(req_item_c);
    if(tc_val == 63) begin
        // Reached max. tc counter value
        tc_val = 0;
    end
end

That way, I get two error messages as follows:

**** Error: …/…/xxx.svh(62): (vopt-2936) Illegal non-integral expression in random constraint.
** Error: (vopt-2064) Compiler back-end code generation process terminated with code 2.**

Line 62 is the line within the randomize() part where the assignment tcode_tx[7:2] == … is made.