我需要同时产生几个布尔

时间:2019-01-08 11:29:09

标签: specman

我有:

struct MyStruct {
     !Ipv4En : bool;
     !Ipv6En : bool;
     keep Ipv4En == TRUE or Ipv6En == TRUE;

     MyMethod() is {
         gen Ipv4En;
         gen Ipv6En;
     };
 };

我总是将Ipv4En设为TRUE,因为这两个布尔不是一起生成的。 我生成MyStruct时无法生成它们。 如何一起生成它们?

同时我打了补丁(不喜欢解决方案): 我已经删除了!在定义中。

temp : MyStruct;
gen temp;

Ipv4En = temp.Ipv4En;
Ipv6En = temp.Ipv6En;

1 个答案:

答案 0 :(得分:0)

由于gen动作只需要一个gen-item,因此您必须将要求解的两个变量组合在一起。您可以通过定义新的struct来完成此操作:

struct IpVersionInfo {
  Ipv4En: bool;
  Ipv6En: bool;

  keep Ipv4En == TRUE or Ipv6En == TRUE;
};

您无需为启用启用两个变量,而使用这种新的struct类型的单个变量:

struct MyStruct {
    !ipVersionInfo: IpVersionInfo;

    MyMethod() is {
        gen ipVersionInfo;
    };
};

如果运行几次迭代,您会发现可以达到所有组合:

extend sys {

    run() is also {
        for i from 1 to 20 {
            var s: MyStruct = new;
            s.MyMethod();
            outf(
                    "Ipv4En = %s, Ipv6En = %s\n",
                    s.ipVersionInfo.Ipv4En,
                    s.ipVersionInfo.Ipv6En);
        };
    };

};

不过,这需要更改API,因此您需要更新所有引用了Ipv4EnIpv6En的代码。

除了将struct中的两个字段分组外,还有其他解决问题的方法。另一个示例是定义一个enum,其中包含您的法律案件的值:

type ip_version_info_e: [ V4, V6, BOTH ];

像以前一样,您可以在struct中使用这种类型的变量:

struct MyStruct {
    !ip_version_info: ip_version_info_e;

    MyMethod() is {
        gen ip_version_info;
    };
};

如果运行新代码的几次迭代,您会发现它也可以达到所有可能的组合:

extend sys {

    run() is also {
        for i from 1 to 20 {
            var s: MyStruct = new;
            s.MyMethod();
            outf(
                    "Ipv4En = %s, Ipv6En = %s\n",
                    s.ip_version_info in [ V4, BOTH ],
                    s.ip_version_info in [ V6, BOTH ]);
        };
    };

};

无论您决定如何解决此问题,都应该对使用MyStruct的任何客户端代码隐藏内部实现。请注意,根据我们选择处理IP版本设置的方式,上面的out语句看起来有所不同。您应该定义以下两种方法,而不是让客户端代码在MyStruct内部看起来太深:

isIpv4Enabled(): bool;
isIpv6Enabled(): bool;

如果我们将两个布尔变量分组在struct中,则这两种方法的实现是:

struct MyStruct {
    // ...

    isIpv4Enabled(): bool is {
        result = ipVersionInfo.Ipv4En;
    };

    isIpv6Enabled(): bool is {
        result = ipVersionInfo.Ipv6En;
    };
};

在我们定义enum的情况下,我们有:

struct MyStruct {
    // ...

    isIpv4Enabled(): bool is {
        result = ip_version_info in [ V4, BOTH ];
    };

    isIpv6Enabled(): bool is {
        result = ip_version_info in [ V6, BOTH ];
    };
};

但是,在两种情况下,用于打印的客户端代码都是相同的:

extend sys {

    run() is also {
        for i from 1 to 20 {
            var s: MyStruct = new;
            s.MyMethod();
            outf(
                    "Ipv4En = %s, Ipv6En = %s\n",
                    s.isIpv4Enabled(),
                    s.isIpv4Enabled());
        };
    };

};

这是一个主要优势。这样一来,您将来就可以自由更改MyStruct的实现,而不必接触使用它的任何其他代码。