矛盾软约束的行为

时间:2015-07-22 09:01:39

标签: specman e

我有一个测试用例,其行为似乎有误。我看到,在所有世代中, num_of_red_shoes 都很高,而我希望分布更均匀。这种行为的原因是什么以及如何解决?

<'
struct closet {
    kind:[SMALL,BIG];

    num_of_shoes:uint;
    num_of_red_shoes:uint;
    num_of_black_shoes:uint;
    num_of_yellow_shoes:uint;

    keep soft num_of_red_shoes < 10;
    keep soft num_of_black_shoes < 10;
    keep soft num_of_yellow_shoes < 10;

    keep num_of_yellow_shoes + num_of_black_shoes + num_of_red_shoes == num_of_shoes;

    when BIG closet {
        keep num_of_shoes in [50..100];
    };
};

extend sys {
    closets[100]:list of BIG closet;
};
'>

生成结果:

item   type        kind        num_of_sh*  num_of_re*  num_of_bl*  num_of_ye* 
---------------------------------------------------------------------------
0.     BIG closet  BIG         78          73          1           4           
1.     BIG closet  BIG         67          50          8           9           
2.     BIG closet  BIG         73          68          0           5           
3.     BIG closet  BIG         73          66          3           4           
4.     BIG closet  BIG         51          50          0           1           
5.     BIG closet  BIG         78          76          1           1           
6.     BIG closet  BIG         55          43          7           5           
7.     BIG closet  BIG         88          87          1           0           
8.     BIG closet  BIG         99          84          6           9           
9.     BIG closet  BIG         92          92          0           0           
10.    BIG closet  BIG         63          55          3           5           
11.    BIG closet  BIG         59          50          9           0           
12.    BIG closet  BIG         51          44          2           5           
13.    BIG closet  BIG         82          76          1           5           
14.    BIG closet  BIG         81          74          2           5           
15.    BIG closet  BIG         97          93          2           2           
16.    BIG closet  BIG         54          41          8           5           
17.    BIG closet  BIG         55          44          5           6           
18.    BIG closet  BIG         70          55          9           6           
19.    BIG closet  BIG         63          57          1           5  

4 个答案:

答案 0 :(得分:3)

当存在矛盾的软约束时,Specman不会随机化强制执行的软件,而是优先考虑最后写入的约束。由于柔软的红色鞋子是测试中的第一个,因此它总是被覆盖的。

如果已知软件是互斥的(这里不是这种情况),您可以使用一个简单的标志来随机选择应该保留的软件。例如代码看起来像这样:

flag:uint[0..2];

keep soft read_only(flag==0) => num_of_red_shoes < 10;
keep soft read_only(flag==1) => num_of_black_shoes < 10;
keep soft read_only(flag==2) => num_of_yellow_shoes < 10;

然而,由于这里没有预先知道预期会有多少软件(并且可能并且两个或全部三个将被满足),因此应该制定更复杂的解决方案。这是一个执行此随机化的代码:

struct closet {
    kind:[SMALL,BIG];

    num_of_shoes:uint;
    num_of_red_shoes:uint;
    num_of_black_shoes:uint;
    num_of_yellow_shoes:uint;

    //replaces the original soft constraints (if a flag is true the correlating
    //right-side implication will be enforced
    soft_flags[3]:list of bool;
    keep for each in soft_flags {
        soft it == TRUE;
    };

    //this list is used to shuffle the flags so their enforcement will be done
    //with even distribution
    soft_indices:list of uint;
    keep soft_indices.is_a_permutation({0;1;2});

    keep soft_flags[soft_indices[0]] => num_of_red_shoes < 10;
    keep soft_flags[soft_indices[1]] => num_of_black_shoes < 10;
    keep soft_flags[soft_indices[2]] => num_of_yellow_shoes < 10;

    keep num_of_yellow_shoes + num_of_black_shoes + num_of_red_shoes == num_of_shoes;
};

答案 1 :(得分:1)

我不和Cadence在一起,所以我无法给你一个明确的答案。我认为解算器会尝试尽可能少地限制它,如果找到它(在你的情况下是红鞋的那个),它只选择第一个。尝试更改顺序,看看是否有变化(如果黑色约束是第一个,我认为你总会得到更多黑鞋)。

作为一个解决方案,当你有一个大衣柜时,你可以删除软约束:

when BIG closet {
    keep num_of_red_shoes.reset_soft();
    keep num_of_black_shoes.reset_soft();
    keep num_of_yellow_shoes.reset_soft();
    keep num_of_shoes in [50..100];
};

如果你想随机选择禁用哪一个(有时超过10个红鞋,有时超过10个黑鞋等),那么你需要一个辅助领域:

when BIG closet {
    more_shoes : [ RED, BLACK, YELLOW ];

    keep more_shoes == RED => num_of_red_shoes.reset_soft();
    keep more_shoes == BLACK => num_of_black_shoes.reset_soft();
    keep more_shoes == YELLOW => num_of_yellow_shoes.reset_soft();
    keep num_of_shoes in [50..100];
};

这取决于你的意思&#34;更均匀的分布&#34;。

答案 2 :(得分:1)

无法满足BIG壁橱的所有硬性和软性限制。因此,Specman试图通过忽略一些软约束来找到解决方案。 IntelliGen约束求解器不会忽略所有软约束,但尝试在仍然使用子集时找到解。这在&#34; Specman Generation用户指南&#34; (sn_igenuser.pdf):

  

稍后加载的[S] oft约束被认为具有比先前加载的软约束更高的优先级。&#34;

在这种情况下,这意味着Specman会丢弃红鞋上的软约束,因为它可以找到一个仍然服从其他软约束的解决方案,它不会丢弃它们。

如果将所有软约束合并为一个,那么您可能会获得您希望的结果:

 keep soft ((num_of_red_shoes    < 10) and (num_of_black_shoes < 10) and
            (num_of_yellow_shoes < 10));

以后的约束优先级有一些优点:这意味着使用AOP可以添加新的软约束,它们将获得最高优先级。

答案 3 :(得分:1)

对于更多分布式值,我建议如下。 我相信你也可以遵循预期的逻辑。

var1, var2 : uint;
keep var1 in [0..30];
keep var2 in [0..30];

when BIG closet {
    keep num_of_shoes in [50..100];
    keep num_of_yellow_shoes == (num_of_shoes/3) - 15 + var1;
    keep num_of_black_shoes == (num_of_shoes - num_of_yellow_shoes)/2 - 15 + var2;
    keep num_of_red_shoes == num_of_shoes - (num_of_yellow_shoes - num_of_black_shoes);

keep gen (var1, var2) before (num_of_shoes);
    keep gen (num_of_shoes) before (num_of_yellow_shoes, num_of_black_shoes, num_of_red_shoes);
    keep gen (num_of_yellow_shoes) before (num_of_black_shoes, num_of_red_shoes);
    keep gen (num_of_black_shoes) before (num_of_red_shoes);
};