Reputation: 27
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?
Upvotes: 0
Views: 109
Reputation: 898
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;
}
}
Upvotes: 1