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

In this code, I am facing 2 issues in QuestaSIM.

  1. In the constraint, I have used (i%2), still it is showing this warning:

    Warning : (vsim-3829) Non-existent associative array entry. Returning default value.

  2. How to loop through lower dimension in 2 dimensional associative array in a constraint? foreach(slba_previous[, i]) is not working.

Karan Shah
  • 1,912
  • 1
  • 29
  • 42

2 Answers2

1

When using a foreach on an double associative array, you need to include all the significant indexes. Otherwise the loop can not determine how to how many times to loop for i. The simulator also needs to handle for the case that slba_previous[nsid] doesn't exist And there for have no i to index.

You need to loop through the full slba_previous[id,i] and then check if id==nsid.

The warning is for the i+1 condition. Use the .exists() built-in function to insure the there is an existing array entry. The design may always have an even number of entries, but it looks like QuestaSIM's constraint solver is more pessimistic and and wants to consider all possibilities.

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];
      }
    }
  }
}

working example on EDA Playground

Greg
  • 18,111
  • 5
  • 46
  • 68
  • It may work fine on eda, but i am still getting above mentioned warnings in QuestaSIM – Karan Shah May 13 '15 at 05:03
  • @MaheshShah, I updated my answer with `.exists(i+1)` check which should resolve the warning. – Greg May 13 '15 at 15:46
  • Yes, this may solve the warning, but my question is why we require to use exists method, if we have used (i%2), which assures that only existed entries will be referenced (like i=0 then 0, 1, i=2 then 2, 3)?? – Karan Shah May 13 '15 at 17:18
  • In the current loop, QuestaSIM only knows that the entry for `i` exists. It is possible that `i+1` may not exists (not with the giving code, but in the scope of all things possible: future extend class, test-bench, interactive-mode, dpi/vpi, etc.). The [LRM](http://standards.ieee.org/getieee/1800/download/1800-2012.pdf) in section 18.5.8.1 says "Invalid or out-of-bounds array indices are not automatically eliminated; users must explicitly exclude these indices using predicates." So QuestaSIM is going behind the spec by identifying _potential_ design flaw from invalid indices. – Greg May 13 '15 at 18:11
  • Unfortunately, I am still getting those warnings, despite of writing exists method for (i+1) – Karan Shah May 14 '15 at 04:36
  • This issue can be solved by taking 2 different associative arrays. So in constraints, only "i" will appear. not "i+1" . Thanks a lot for helping. – Karan Shah May 14 '15 at 11:38
  • No previously I wrote "it may solve the warning", but actually warnings were still there. But I got the answer. You can check my answer below. – Karan Shah May 14 '15 at 15:42
0

Warning can be resolved, by modifying class x, as below, in which associative array is splited into 2 arrays.

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
Karan Shah
  • 1,912
  • 1
  • 29
  • 42