How to create random dynamic 2D arrays in SystemVerilog?

To trying to generate 2d array, I implement as the below. But I faced randomize fail.

assert(pkt.randomize());
|
ncsim: *W,SVRNDF (./test1_packet.sv,49|20): The randomize method call failed.

First data.size is constrained by width. then generate array in height size.
I can’t figure out the problem.

class frame_packet;
  rand int width;
  rand int height;
  rand int data[][];

  constraint size_con {
    width   inside {[8:2048]};
    height  inside {[8:1592]};
    data.size == width;
    foreach(data[i])
      data[i].size == height;
    
  }
endclass

module test;

initial begin
  frame_packet pkt;
  pkt = new();
  assert(pkt.randomize());
  foreach(pkt.data[i,j]) begin
    $display("len:%0d, data[%0d]=%0d",i, i, pkt.data[i][j]);
  end
end

endmodule

How do I generate the 2d array in Systemverilog?

In reply to UVM_LOVE:

Have you tried using data[width] instead of data[i] in the constraint?

In reply to Shashank Gurijala:

I got the same error.

class frame_packet;
  rand int width;
  rand int height;
  rand int data[][];

  constraint size_con {
    width   inside {[8:2048]};
    height  inside {[8:1592]};
    data.size == width;
    foreach(data[width])
        data[width].size == height;

  }
endclass

module test;

initial begin
  frame_packet pkt;
  pkt = new();
  assert(pkt.randomize());
  foreach(pkt.data[i,j]) begin
    $display("data=%0d", pkt.data[i][j]);
  end
end

endmodule

In reply to UVM_LOVE:

Try displaying the array elements with %0p instead of individual elements

In reply to UVM_LOVE:

Hi ,
You are not wrong. Height is getting randomized before width gets the value . It’s a tool dependency issue, I reckon. Because, when I ran your code on eda-playground I was not getting any type of error.
Still, I changed a few things. You can try this on your tool and let me know if it worked or not.


class frame_packet;
  rand int width;
  rand int height;
  rand int data[][];
 
  constraint size_con {
    width   inside {[8:10]};
    height  inside {[8:15]};
    data.size == width;
    foreach(data[i])
    { data[i].size == height;
     foreach(data[i][j])
     data[i][j] inside{[45:70]};}
  }
      
      constraint seq{solve width before height;}
endclass
 
module test;
 
initial begin
  frame_packet pkt;
  pkt = new();
  assert(pkt.randomize());
  foreach(pkt.data[i,j]) begin
    $display("data[%0d][%0d]=%0d",i, j, pkt.data[i][j]);
  end
end
 
endmodule

In reply to Shubhabrata:

Your code still I got the same error message


 assert(pkt.randomize());
                     |
ncsim: *W,SVRNDF (./test1_packet.sv,54|21): The randomize method call failed.
Observed simulation time : 0 FS + 0
ncsim: *W,RNDOCS: These constraints contribute to the set of conflicting constraints:

    height  inside {[8:15]}; (./test1_packet.sv,38)
    foreach(data[i]) (./test1_packet.sv,40)
ncsim: *W,RNDOCS: These variables contribute to the set of conflicting constraints:

rand variables:
       height [./test1_packet.sv, 33]

ncsim: *E,ASRTST (./test1_packet.sv,54): (time 0 FS) Assertion test.unmblk1.__assert_1 has failed 

I also check the your code working well in the EDAPLAYGROUND.
I think this problem is in tool side.

Could you guide me any alternative way?

In reply to Shubhabrata:

This is working as well even one 1D array.

class packet;
    rand int unsigned len;
    rand int  data[];

    constraint size_con {
        len < 2000;
        data.size == len;
    }
endclass: packet

module test;

initial begin
  packet pkt;
  pkt = new();
  pkt.randomize();
  foreach(pkt.data[i]) begin
    $display("len:%0d, data[%0d]=%0d",i, i, pkt.data[i]);
  end
end

endmodule

But how do I constraint the data of inside array?

len:877, data[877]=-90
len:878, data[878]=98
len:879, data[879]=122
len:880, data[880]=42
len:881, data[881]=-19

In reply to UVM_LOVE:

Could you explain what you mean by inside array?

In reply to Shubhabrata:


class frame_packet;
  rand int width;
  rand int height;
  rand int data[][];
 
  constraint size_con {
    width inside {[0:10]};
    height inside {[0:10]};
    data.size() == width ;
    foreach(data[i]) {
     data[i].size()  == height;// inside {[0:10]};
    }
  }

endclass
 
module test;
 
initial begin
  frame_packet pkt;
  pkt = new();
  assert(pkt.randomize());

    for(int i=0; i<10; i++)
    for(int j=0; j<10; j++) 
    $display("data[%0d][%0d]=%0d",i,j,  pkt.data[i][j]);



end

endmodule

I meant data array’s value randomized with no constraint.
How do I make constrainted random data into the 2D data array?

In reply to UVM_LOVE:

Yes, you can. Just go through my code again. I have already mentioned this. I used a nested foreach loop.



module DA;
  int DA1[][];
  initial begin
    DA1 = new[2];
    foreach(DA1[i]) DA1[i]=new[3];
    foreach(DA1[i,j]) begin
      DA1[i][j]=$urandom_range(10,20);
    end
    foreach(DA1[i,j])
    $display("\DA1[%0d,%0d] = %0d",i,j, DA1[i][j]);
  end
  
endmodule




In reply to amir_sharfu:


module DA;
int DA1[][];
initial begin
DA1 = new[2];
foreach(DA1[i]) DA1[i]=new[3];
foreach(DA1[i,j]) begin
DA1[i][j]=$urandom_range(10,20);
end
foreach(DA1[i,j])
$display("\DA1[%0d,%0d] = %0d",i,j, DA1[i][j]);
end
endmodule

Thanks But If I check the dimension of DA1. it has 3. I though it has 2.
Could you let me know why DA1 has 3 Dimensions?

module DA;
  int DA1[][];
  initial begin
      DA1 = new[2];
    foreach(DA1[i])
      DA1[i] = new[3];

    foreach(DA1[i,j]) begin
      DA1[i][j] = $urandom_range(10,20);
    end

    foreach(DA1[i,j])
      $display("\DA1[%0d, %0d] = %0d", i,j, DA1[i][j]);


    $display("dimension:%0d", $dimensions(DA1));
  end

endmodule

In reply to UVM_LOVE:

1 for packed one and 2 for unpacked ones.