I'm trying to port code from DML 1.2 to DML 1.4. Here is part of code that i ported:
group rx_queue [i < NQUEUES] {
<...>
param desctype = i < 64 #? regs.SRRCTL12[i].DESCTYPE.val #: regs.SRRCTL2[i - 64].DESCTYPE.val; // error occurs here
<...>
}
Error says: error: non-constant expression: cast(i, int64 ) < 64 How can i specify parameter dependent on index value?
I tried to use if...else instead ternary operator, but it says that conditional parameters are not allowed in DML.
Index parameters in DML are a slightly magical expressions; when used from within parameters, they can evaluate to either a constant or a variable depending on where the parameter is used from. Consider the following example:
ibecomes an implicit local variable within themmethod, and inparams, indices are a bit like implicit macro parameters. When the compiler encountersxin the firstlogstatement, the param will expand toi * 4right away. In the secondlogstatement, thexparam is taken from an object indexed with the expression4 - i, so param expansion will instead insert(5 - i) * 4. In the thirdlogstatement, thexparam is taken from a constant indexed object, so it expands to2 * 4which collapses into the constant8.Most uses of
desctypewill likely happen from contexts where indices are variable, and the#?expression requires a constant boolean as condition, so this will likely give an error as soon as anyone tries to use it.I would normally advise you to switch from
#?to?in the definition of thedesctypeparam, but that fails in this particular case: DMLC will reporterror: array index out of boundson thei - 64expression. This error is much more confusing, and happens because DMLC automatically evaluates every parameter once with all zero indices, to smoke out misspelled identifiers; this will include evaluation ofSRRCTL2[i-64]which collapses intoSRRCTL2[-64]which annoys DMLC.This is arguably a compiler bug; DMLC should probably be more tolerant in this corner. (Note that even if we would remove the zero-indexed validation step from the compiler, your parameter would still give the same error message if it ever would be explicitly referenced with a constant index, like
log info: "%d", rx_queue[0].desctype).The reason why you didn't get an error in DML 1.2 is that DML 1.2 had a single ternary operator
?that unified 1.4's?and#?; when evaluated with a constant condition the dead branch would be disregarded without checking for errors. This had some strange effects in other situations, but made your particular use case work.My concrete advise would be to replace the param with a method; this makes all index variables unconditionally non-constant which avoids the problem: