We are converting our register_alias template from DML 1.2 to DML 1.4. After a few iterations, we were able to get this to work with the help of some helpful compiler warnings.
Here is what we got:
template register_alias {
param target default undefined;
param allocate = false;
is (_set, _get, register);
method read_register(uint64 enabled_bytes, void* aux) -> (uint64) {
local uint64 val;
val = target.read_register(enabled_bytes, aux);
log info: "register_alias read_register()";
return val;
}
method write_register(uint64 value, uint64 enabled_bytes, void *aux) {
log info: "register_alias write_register()";
target.write_register(value, enabled_bytes, aux);
}
method get() -> (uint64) {
local uint64 val;
log info: "register_alias get()";
val = target.get();
return val;
}
method set(uint64 val) {
log info: "register_alias set()";
target.set(val);
}
}
This works, but we wonder why we need to have the following in the template?
is (_set, _get, register);
We thought that when applying a template, it inherits the attributes of the objects on which the template is applied to i.e. in this case the register itself which I believe also uses the _set, _get and register templates.
I assume you got
_set/_getfrom the hints given byEAMBINH. They are not documented (as the leading underscores also hints), and thus unsupported/subject to change. If you explore dml-builtins, you'll see that theregistertemplate instantiatessetandget, which in turn instantiate_setand_get, respectively. So,is register;is in fact sufficient, and a safer choice.To answer your question, these templates are needed to resolve overrides: E.g., a bare
registerobject comes with one implementation ofread_register, through the builtinregistertemplate, and if you instantiateregister_aliasin the register there will be two conflicting implementations of the method. Theis registerdeclaration tells DML that the declaration fromregister_aliastakes precedence. The crucial thing here is that withoutis register, theregister_aliastemplate itself has no relation toregisterobjects, it can just as well be applied to e.g.groupobjects. This means that the method declarations inside theregister_aliastemplate do not have a relation to the declarations in theregistertemplate, which results in an ambiguity.For formal details, please see the Default Methods section of the reference manual.
The reason why this isn't needed in DML 1.2, is that non-default implementations were given precedence over default implementations in some situations. This usually worked OK when there was only one level of overrides, but could give confusing results with multiple levels of overrides. In DML 1.4, the only semantics of the
defaultannotation on a method is that overrides are permitted; this is more regular compared to DML 1.2, and also consistent with how other OO languages tend to work.