参数化的uvm序列项可调整大小

时间:2019-03-12 22:30:32

标签: system-verilog verification uvm

我遇到了一个问题,但对解决该问题没有任何想法。我有一个包含名为data的数组的类。此动态数组可以具有参数化的打包宽度-例如8、16或32位。

class MyItem#(int WIDTH=8) extends uvm_sequence_item;

  bit[WIDTH-1:0] data[];

endclass

问题是,当我要实例化MyItem的对象时,需要为其提供参数。但是,WIDTH参数取决于其他一些设置,并且出于示例的目的,让我们假设可以在8,16到32之间随机生成。

class MySequence extends uvm_sequence;

  rand int width;
  constraint c_width {width inside {8, 16, 32}; }

  task body();
    MyItem#(width) req = MyItem#(width)::type_id::create("item"); // <--- THIS IS NOT ALLOWED
  endtask

endclass

因此,我不得不想出一种方法来解决此问题。一种方法是在MyItem内具有所有不同宽度的句柄,然后使用我需要的宽度。可以起到以下作用的

class MyItem extends uvm_sequence_item;
  bit[ 7:0] data_08[];
  bit[15:0] data_16[];
  bit[23:0] data_24[];
endclass

这将允许我根据包装尺寸使用手柄。但这有点hacky,我宁愿避免这种情况,因为我必须继续检查WIDTH参数并分别访问data_08,data_16或data_24,这会使代码the肿。

另一种选择是只使用MAX_WIDTH参数,并填充位。

class MyItem extends uvm_sequence_item;
  bit[MAX_WIDTH:0] data[];
endclass

但是对于非常大的阵列,这是浪费内存,效率不高。

我想出的但不起作用的最终解决方案是创建一个名为MyItemBase的基类,然后Item从此扩展。所以现在我可以(或者应该应该能够)像obj_handle.data

那样访问数据
class MyItemBase extends uvm_sequence_item;
  bit data[];
endclass

class MyItem#(WIDTH) extends MyItemBase;
  bit[WIDTH-1:0] data[];
endclass

这允许我做的是按顺序使用以下代码:

  rand int width;
  constraint c_width {width inside {8, 16, 32}; }

  task body();
    MyItemBase req
    case(width)
      8:  req = MyItem#(8)::type_id::create("item");
      16: req = MyItem#(8)::type_id::create("item");
      32: req = MyItem#(8)::type_id::create("item");
      default: //
    endcase

    // Now I should be able to use req.data
    req.data = new[32];
    foreach(req.data[i]) req.data[i] = $urandom();
    foreach(req.data[i]) $display("data[%0d] = %0x",  i, data[i]);
  endtask

endclass

您可能已经猜到了,这没有用。我的数据数组只有一点点宽度,我想它是从基类中获取的,所以多态性对变量的作用不像对函数的作用(除非我在这里遗漏了一些关键)。

现在,除非我将类型转换为派生类型,否则MyItemBase类中的数据只有一位版本会导致编译错误。这会带来一些额外的复杂性,我觉得我在解决一个简单的问题上不知所措。

任何人都可以给我有关如何构建此结构的建议吗? 谢谢

1 个答案:

答案 0 :(得分:2)

我建议创建一个二维动态数组。由于您似乎正在使用字节宽度,因此可以:

bit[7:0] data[][];

那么第二维可以用

构造
   foreach(data[I]) data[I]= new[width/8];

如果需要使用压缩数组,则可以声明一个最大宽度的局部变量,然后将数据字节从该局部变量传输到该局部变量;

bit [MAX_WIDTH-1:0] temp;
...
temp = {<<{data[I]}};