1

I'm trying to write a DAC macro that gets as input the name of list of bits and its size, and the name of integer variable. Every element in the list should be constrained to be equal to every bit in the variable (both of the same length), i.e. (for list name list_of_bits and variable name foo and their length is 4) the macro's output should be:

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];

My macro's code is:

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);
    };
};

The error I get:

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

Why it interprets the <list_size'exp> as string? Thank you for your help

Halona
  • 1,475
  • 1
  • 15
  • 26

2 Answers2

3

All macro arguments in DAC macros are considered strings (except repetitions, which are considered lists of strings). The point is that a macro treats its input purely syntactically, and it has no semantic information about the arguments. For example, in case of an expression (<exp>) the macro is unable to actually evaluate the expression and compute its value at compilation time, or even to figure out its type. This information is figured out at later compilation phases.

In your case, I would assume that the size is always a constant. So, first of all, you can use <num> instead of <exp> for that macro argument, and use as_a() to convert it to the actual number. The difference between <exp> and <num> is that <num> allows only constant numbers and not any expressions; but it's still treated as a string inside the macro.

Another important point: your macro itself should be a <struct_member> macro rather than an <exp> macro, because this construct itself is a struct member (namely, a constraint) and not an expression.

And one more thing: to ensure that the list size will be exactly as needed, add another constraint for the list size.

So, the improved macro can look like this:

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);
    };

};

Yuri Tsoglin
  • 963
  • 4
  • 7
3

Why not write is without macro?

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

This should do the same, but look more readable and easier to debug; also the generation engine might take some advantage of more concise constraint.

Rodion Melnikov
  • 338
  • 1
  • 4
  • 1
    Hi Rodion, there is some bug in Specman and when I've used this way the constrains did not work (the code is compiled and running successfully, but the values of list and the variable's bits are different) – Halona Nov 30 '14 at 10:38
  • 1
    Did you try to trace/debug it? This form of constraint is pretty basic, chances are that there is some reason why the values are different, like some later assignment, it might prevent your macro from working as you expect too. And if it's really a Specman bug, worth reporting it to Specman support, so it will be hopefully fixed soon. – Rodion Melnikov Nov 30 '14 at 11:09
  • Great! However your initial question on and Yuri's answer still makes perfect sense. – Rodion Melnikov Nov 30 '14 at 15:42