我正在尝试执行以下操作:
unit parent {
sons: list of sons is instance;
grands: list of grands is instance;
keep sons.size() == 4;
keep grands.size() == 4;
};
unit sons {
grands:list of grands is instance;
keep grands == get_enclosing_unit(parent).grands.all( .id > 3 );
//this is not working
keep for each in grands {
it.parent_age == 70;
};
};
unit grands {
id: uint;
parent_age:uint;
};
extend sys {
p : parent is instance;
run() is also {
print p;
for each (s) in p.sons {
print s;
};
for each (g) in p.grands {
print g;
};
};
};
换句话说,我希望儿子列表指向父母列表的一部分,但仍然能够从子单元/结构中约束(不工作部分)重量列表。
使用9.20上的PGen约束引擎,上面的代码产生:
Starting the test ...
Running the test ...
p = parent-@0: parent e_path: sys.p
hdl_path:
---------------------------------------------- @tmp
0 sons: (4 items)
1 grands: (4 items)
s = sons-@1: sons e_path: sys.p.sons[0]
hdl_path:
---------------------------------------------- @tmp
0 grands: (empty)
s = sons-@2: sons e_path: sys.p.sons[1]
hdl_path:
---------------------------------------------- @tmp
0 grands: (empty)
s = sons-@3: sons e_path: sys.p.sons[2]
hdl_path:
---------------------------------------------- @tmp
0 grands: (empty)
s = sons-@4: sons e_path: sys.p.sons[3]
hdl_path:
---------------------------------------------- @tmp
0 grands: (empty)
g = grands-@5: grands e_path: sys.p.grands[0]
hdl_path:
---------------------------------------------- @tmp
0 id: 4107502109
1 parent_age: 3829340118
g = grands-@6: grands e_path: sys.p.grands[1]
hdl_path:
---------------------------------------------- @tmp
0 id: 3657005019
1 parent_age: 2354335776
g = grands-@7: grands e_path: sys.p.grands[2]
hdl_path:
---------------------------------------------- @tmp
0 id: 3238917208
1 parent_age: 336300761
g = grands-@8: grands e_path: sys.p.grands[3]
hdl_path:
---------------------------------------------- @tmp
0 id: 1416976666
1 parent_age: 2212224392
使用Specman 9.20上的IntelliGen约束引擎,上面的代码产生:
Starting the test ...
Running the test ...
p = parent-@0: parent e_path: sys.p
hdl_path:
---------------------------------------------- @tmp
0 sons: (4 items)
1 grands: (4 items)
s = sons-@1: sons e_path: sys.p.sons[0]
hdl_path:
---------------------------------------------- @tmp
0 grands: (4 items)
s = sons-@2: sons e_path: sys.p.sons[1]
hdl_path:
---------------------------------------------- @tmp
0 grands: (4 items)
s = sons-@3: sons e_path: sys.p.sons[2]
hdl_path:
---------------------------------------------- @tmp
0 grands: (4 items)
s = sons-@4: sons e_path: sys.p.sons[3]
hdl_path:
---------------------------------------------- @tmp
0 grands: (4 items)
g = grands-@5: grands e_path: sys.p.grands[0]
hdl_path:
---------------------------------------------- @tmp
0 id: 619055518
1 parent_age: 4122406610
g = grands-@6: grands e_path: sys.p.grands[1]
hdl_path:
---------------------------------------------- @tmp
0 id: 2908565159
1 parent_age: 1741309063
g = grands-@7: grands e_path: sys.p.grands[2]
hdl_path:
---------------------------------------------- @tmp
0 id: 3091108084
1 parent_age: 1231835435
g = grands-@8: grands e_path: sys.p.grands[3]
hdl_path:
---------------------------------------------- @tmp
0 id: 1717477430
1 parent_age: 937745175
No actual running requested.
Checking the test ...
Checking is complete - 0 DUT errors, 0 DUT warnings.
答案 0 :(得分:1)
我认为你有生成订单冲突:
sons.grands
列表已填充,具体取决于grands.id
字段,这意味着您必须先生成grands
列表。grands.parent_age
取决于sons
parent_age == 70
约束,这意味着您必须先生成sons
列表。解决此代码问题的最简单,最直接的方式(我知道你给的是一个愚蠢的例子)是:
extend parent {
keep for each (g) in grands {
( g.id > 3 ) => g.parent_age == 70;
};
};
经过更多测试后,我很确定它是一个与方法调用结合的约束排序问题。除非您在不进行方法调用的情况下设置这些指针,否则Specman生成器不会遵循sons'
grand
列表约束的约束。
<'
unit parent {
sons: list of sons is instance; // <-- swapped these two lines
grands: list of grands is instance; // <-- to do constraint ordering in IntelliGen
// even though Cadence says you don't need
// to
keep for each (s) in sons {
s.grands == grands; -- .all( .id > 3 ); -- removed the 'all' and 'get_enclosing_unit' invocation
};
keep sons.size() == 4;
keep grands.size() == 4;
};
unit sons {
grands:list of grands is instance;
--keep grands == get_enclosing_unit(parent).grands.all( .id > 3 );
//this is not working
keep for each in grands {
it.parent_age == 70;
};
};
unit grands {
id: uint;
parent_age:uint;
};
extend sys {
p : parent is instance;
run() is also {
print p;
for each (s) in p.sons {
print s;
};
for each (g) in p.grands {
print g;
};
};
};
'>
使用 IntelliGen (不适用于PGen):
Starting the test ...
Running the test ...
p = parent-@0: parent e_path: sys.p
hdl_path:
---------------------------------------------- @tmp
0 sons: (4 items)
1 grands: (26 items)
s = sons-@1: sons e_path: sys.p.sons[0]
hdl_path:
---------------------------------------------- @tmp
0 grands: (26 items)
s = sons-@2: sons e_path: sys.p.sons[1]
hdl_path:
---------------------------------------------- @tmp
0 grands: (26 items)
s = sons-@3: sons e_path: sys.p.sons[2]
hdl_path:
---------------------------------------------- @tmp
0 grands: (26 items)
s = sons-@4: sons e_path: sys.p.sons[3]
hdl_path:
---------------------------------------------- @tmp
0 grands: (26 items)
g = grands-@5: grands e_path: sys.p.sons[3].grands[0]
hdl_path:
---------------------------------------------- @tmp
0 id: 4093923439
1 parent_age: 70
[snip]
您可能需要直接使用pre_generate()/post_generate()
。您还可以查看他们开源(here)的思科csco_config
软件包。我们使用该包在我们的环境中进行奇怪的约束和约束传播。但是,大多数约束是自上而下的,而你的例子似乎是关于同伴相互修改的。
另一个设计说明。 5个级别的列表相互约束是一个维护问题。理想情况下,每个级别最多只能了解其子列表及其父列表。提供一个字段,然后将该字段向下波动到较低级别将使每个级别不必知道所有其他级别。但是,我知道有理由违反设计准则: - )