循环遍历约束中多维关联数组的较低维度的语法
Syntax for looping through lower dimension of multidimensional associative array in a constraint
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 个问题。
在constraint中,我用了(i%2),还是显示这个警告:
Warning : (vsim-3829) Non-existent associative array entry. Returning default value.
如何在约束中遍历二维关联数组的低维? foreach(slba_previous[, i])
不工作。
在双关联数组上使用 foreach
时,您需要包括所有重要索引。否则循环无法确定要循环多少次for i
。模拟器还需要处理 slba_previous[nsid]
不存在并且没有 i
索引的情况。
您需要遍历整个 slba_previous[id,i]
然后检查是否 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];
}
}
}
}
上的工作示例
警告可以通过修改class 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
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 个问题。
在constraint中,我用了(i%2),还是显示这个警告:
Warning : (vsim-3829) Non-existent associative array entry. Returning default value.
如何在约束中遍历二维关联数组的低维?
foreach(slba_previous[, i])
不工作。
在双关联数组上使用 foreach
时,您需要包括所有重要索引。否则循环无法确定要循环多少次for i
。模拟器还需要处理 slba_previous[nsid]
不存在并且没有 i
索引的情况。
您需要遍历整个 slba_previous[id,i]
然后检查是否 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];
}
}
}
}
上的工作示例
警告可以通过修改class 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