1

我正在尝试编写一个DAC macro将位列表的名称及其大小以及整数变量的名称作为输入。列表中的每个元素都应该被限制为等于变量中的每个位(都具有相同的长度),即(对于列表名称list_of_bits和变量名称foo,它们的长度是4)宏的输出应该是:

keep list_of_bits[0] == foo[0:0];
keep list_of_bits[1] == foo[1:1];
keep list_of_bits[2] == foo[2:2];
keep list_of_bits[3] == foo[3:3];

的宏代码是:

define <keep_all_bits'exp> "keep_all_bits <list_size'exp> <num'name> <list_name'name>" as computed {
    for i from 0 to (<list_size'exp> - 1) do {
        result = appendf("%s keep %s[%d] == %s[%d:%d];",result, <list_name'name>, index, <num'name>, index, index);
    };
};

我得到的错误:

 *** Error: The type of '<list_size'exp>' is 'string', while expecting a
numeric type
             ...
    for i from 0 to (<list_size'exp> - 1)  do {

为什么它解释<list_size'exp>as 字符串?谢谢您的帮助

4

2 回答 2

3

为什么不写没有宏?

keep for each in list_of_bits {
    it == foo[index:index];
};

这应该做同样的事情,但看起来更具可读性和更容易调试;生成引擎也可能会利用更简洁的约束。

于 2014-11-30T10:32:11.427 回答
3

DAC 宏中的所有宏参数都被视为字符串(重复除外,它被视为字符串列表)。关键是宏纯粹从语法上处理它的输入,并且它没有关于参数的语义信息。例如,在表达式 ( <exp>) 的情况下,宏无法在编译时实际评估表达式并计算其值,甚至无法确定其类型。这些信息是在以后的编译阶段计算出来的。

在您的情况下,我会假设大小始终是一个常数。因此,首先,您可以使用<num>代替<exp>该宏参数,并将as_a()其转换为实际数字。<exp>和之间的区别在于<num><num>它只允许常数而不是任何表达式;但它仍然被视为宏内的字符串。

另一个重要的一点:你的宏本身应该是一个<struct_member>宏而不是一个<exp>宏,因为这个结构本身是一个结构成员(即一个约束)而不是一个表达式。

还有一件事:为确保列表大小完全符合需要,为列表大小添加另一个约束。

因此,改进后的宏可以如下所示:

define <keep_all_bits'struct_member> "keep_all_bits <list_size'num> <num'name> <list_name'name>" as computed {
    result = appendf("keep %s.size() == %s;", <list_name'name>, <list_size'num>);
    for i from 0 to (<list_size'num>.as_a(int) - 1) do {
        result = appendf("%s keep %s[%d] == %s[%d:%d];",result, <list_name'name>, i, <num'name>, i, i);
    };

};

于 2014-11-30T10:17:13.613 回答