1
class ns_data_struct;
  rand bit [63:0] ns_size = 64'h0000_0000_0000_0800;
endclass : ns_data_struct

class conf;
  ns_data_struct ns_data[];

  function new();
    ns_data = new[5];
    foreach (ns_data[i])
      ns_data[i] = new();
  endfunction
endclass : conf

class x;
  randc bit [63:0] slba;
  randc bit [63:0] nlb;
  bit [63:0] slba_previous [bit [31:0]][bit [63:0]];
  conf cfg;
  bit [31:0] nsid = 'h1;
  bit [63:0] num [bit [31:0]];

  constraint slba_nlb_inside_ns_c
  {
    slba inside {[1:cfg.ns_data[nsid-1].ns_size]};
    nlb inside {[0:(cfg.ns_data[nsid-1].ns_size - slba)]};
  }

  constraint slba_nlb_non_overlapping_c
  {
    foreach(slba_previous[nsid, i])
    {
      if(!(i%2))
      {
        slba < slba_previous[nsid][i] -> (slba + nlb) < slba_previous[nsid]  [i];
        slba > slba_previous[nsid][i] -> slba > slba_previous[nsid][i+1]; //  <-- Warning Here
        slba > slba_previous[nsid][i+1] -> (slba + nlb) >   slba_previous[nsid][i+1]; //  <-- Warning Here
        slba < slba_previous[nsid][i+1] -> slba < slba_previous[nsid][i]; //  <-- Warning Here
      }
    }
  }

  function void post_randomize();
    num[nsid] = (num.exists(nsid))?(num[nsid]):0;

    slba_previous[nsid][num[nsid]++] = slba;
    slba_previous[nsid][num[nsid]++] = (slba + nlb);

    $display("\nslba_previous - %p\n", slba_previous);
  endfunction

  function new (input conf _cfg);
    this.cfg = _cfg;
  endfunction: new
endclass : x

program p1;
  conf c;
  x t;

  initial
  begin
    c = new;
    t = new(c);
    t.nsid = 3;
    for(int i=0; i<15; i++)
    begin
      if(!t.randomize())
        $display("ERROR : Starting LBA & NLB Provider Randomization  Failed");
      $display("@%0t : KARAN, Starting LBA - %0h %0d", $time, t.slba, t.slba);
      $display("@%0t : KARAN, Number of LBA - %0h %0d", $time, t.nlb,  t.nlb);
    end
  end
endprogram

在这段代码中,我在 QuestaSIM 中面临 2 个问题。

  1. 在约束中,我使用了 (i%2),但它仍然显示此警告:

    警告:(vsim-3829)不存在的关联数组条目。返回默认值。

  2. 如何在约束中循环遍历二维关联数组中的低维?foreach(slba_previous[, i])不管用。

4

2 回答 2

1

在双关联数组上使用 aforeach时,您需要包含所有重要索引。否则循环无法确定要循环多少次i。模拟器还需要处理slba_previous[nsid]不存在的情况并且没有i索引。

您需要循环完整slba_previous[id,i]然后检查 if id==nsid

警告是针对i+1情况的。使用.exists()内置函数确保存在现有数组条目。该设计可能总是有偶数个条目,但看起来 QuestaSIM 的约束求解器更悲观,并且想要考虑所有可能性。

constraint slba_nlb_non_overlapping_c
{
  foreach(slba_previous[id,i])
  {
    if(id==nsid && (i%2)==0)
    {
      slba < slba_previous[id][i] -> (slba + nlb) < slba_previous[id][i];
      if (slba_previous[id].exists(i+1))
      {
        slba > slba_previous[id][i] -> slba > slba_previous[id][i+1];
        slba > slba_previous[id][i+1] -> (slba + nlb) > slba_previous[id][i+1];
        slba < slba_previous[id][i+1] -> slba < slba_previous[id][i];
      }
    }
  }
}

EDA Playground上的工作示例

于 2015-05-12T18:58:09.173 回答
0

警告可以通过修改类 x 来解决,如下所示,其中关联数组被拆分为 2 个数组。

class x;
  randc bit [63:0] slba;
  randc bit [63:0] nlb;
  bit [63:0] slba_previous_low [bit [31:0]][bit [63:0]];
  bit [63:0] slba_previous_high [bit [31:0]][bit [63:0]];
  conf cfg;
  bit [31:0] nsid = 'h1;
  bit [63:0] num [bit [31:0]];

  constraint slba_nlb_inside_ns_c
  {
    slba inside {[1:cfg.ns_data[nsid-1].ns_size]};
    nlb inside {[0:(cfg.ns_data[nsid-1].ns_size - slba)]};
  }

  constraint slba_nlb_non_overlapping_c
  {
    foreach(slba_previous_low[id, i])
    {
      if(id == nsid)
      {
        slba < slba_previous_low[id][i] -> (slba + nlb) < slba_previous_low[id]  [i];
        slba > slba_previous_low[id][i] -> slba > slba_previous_high[id][i];
        slba > slba_previous_high[id][i] -> (slba + nlb) >   slba_previous_high[id][i];
        slba < slba_previous_high[id][i] -> slba < slba_previous_low[id][i];
      }
    }
  }

  function void post_randomize();
    num[nsid] = (num.exists(nsid))?(num[nsid]):0;

    slba_previous_low[nsid][num[nsid]] = slba;
    slba_previous_high[nsid][num[nsid]] = (slba + nlb);

    num[nsid]++;

    $display("\nslba_previous_low - %p\n", slba_previous_low);
    $display("\nslba_previous_high - %p\n", slba_previous_high);
  endfunction

  function new (input conf _cfg);
    this.cfg = _cfg;
  endfunction: new
endclass : x
于 2015-05-14T11:37:15.920 回答