When trying to use in each statements like the following I get an unknown identifier error.
dml 1.4;
param MACRO = true;
#if (MACRO){
in each bank {
in each register {
param something = 1;
}
}
}
At compile time this errors out with the following message:
/modules/test-device/test-device.dml:179:6: error: unknown identifier: 'MACRO'
Despite the MACRO value being defined in the same file.
I know conditional in each statements are not allowed under DML and there is even an specific error for it: "conditional 'in each' is not allowed [ECONDINEACH]"
But I am getting a different error and the following snippet works with no problem:
dml 1.4;
#if (dml_1_2){
in each bank {
in each register {
param something = 1;
}
}
}
So why am I getting a different error and Is there a way to get around this?
As you mentioned, some statements like in each, but also others like typedef, template, import etc are generally disallowed directly inside an #if. There is a long-standing DML feature request to soften this restriction; in particular, this was critically needed during the DML 1.2 to DML 1.4 migration. The restriction was partially softened by adding a hack that permits top-level #if statements with forbidden statements, as long as the condition only refers to some known constants (true, false and dml_1_2).
Technically, this workaround is implemented by considering top-level #if statements as completely separate constructs depending on whether the body contains forbidden statements. If it does, the condition is evaluated in a special variable scope that only contains the three symbols true, false and dml_1_2. This explains why the error message changes from conditional 'in each' is not allowed into unknown identifier.
In your concrete #if (MACRO) example, I don't know a valid way to express that; however, in similar situations you can often solve the problem by making sure the in each statement appears in a subobject of the #if statement; e.g., if you have:
bank regs {
#if (MACRO) {
// compile error: 'in each' directly inside '#if'
in each register {
param something = 1;
}
}
}
then you can change it to:
#if (MACRO) {
bank regs {
// ok: 'in each' in a subobject of the '#if'
in each register {
param something = 1;
}
}
}
Another approach that sometimes is applicable, is if the MACRO param relates to the choice of code generator for bank skeletons; e.g., if you generate DML code for bank skeletons from IPXACT using two different frameworks, say X and Y, and MACRO determines which of these frameworks was used, then chances are that each of these frameworks instantiates a common template, say x_register vs y_register, on all generated registers, or a common template x_bank vs y_bank on all banks. If you can identify such a template, then you can write:
in each (x_register, register) {
// applied to all registers generated by the X framework
param something = 1;
}
or:
in each x_bank {
in each register {
param something = 1;
}
}