-
Notifications
You must be signed in to change notification settings - Fork 49
D.3. Backward incompatible changes, not automatically converted
A number of changes are not taken care of by the conversion script.
Many incompatibilities can be captured as errors already in DML 1.2,
by passing the --strict-dml12 argument. This can be used to
split the conversion process into smaller steps: by running with
this flag before running port-dml.py, one can
apply manual fixes one by one and validate each fix in isolation;
this means that the result of port-dml.py will contain
fewer errors.
The following incompatible changes are caught as errors or warnings
by the --strict-dml12 flag:
-
In classic DML 1.2, an unused template is allowed to instantiate a non-existing template. This is not permitted in DML 1.4.
-
In DML 1.4,
$is no longer used for object references, and top-level object scope is therefore merged with the global scope. This means that you cannot both declare a bank X (referenced as $X in 1.2, as X in 1.4) and a global constant X (referenced as X in both 1.2 and 1.4). -
When inlining a method with a constant value as an argument, the argument will no longer be considered constant in the method body if the argument was declared with a type. In classic DML 1.2, a constant is always inlined as a constant, whose type might not match with the declared type.
-
Anonymous banks (syntax:
bank { ... }) are no longer allowed. -
DML 1.2 permitted certain C keywords, e.g.
signedandregister, to be used as names of local variables. This is no longer permitted. -
Integer arithmetic works differently in DML 1.4. In short, all operands to arithmetic operands are promoted to 64 bits before performing the operation, much like 16- and 8-bit operands are promoted to 32 bits in C.
Also, many semantic irregularities and bugs in 1.2 semantics have been corrected in 1.4.
-
It is no longer permitted to use a register or field object as operand to the
!operator. In classic DML 1.2, there was a loophole that permitted this. -
In DML 1.2, you can reference a method in an
interfaceobject by casting it to a function pointer type. That is no longer permitted in DML 1.4. -
The
gotostatement has been removed from DML 1.3. We plan to re-introduce a restricted variant of the goto statement which is only allowed to jump forward, and to an enclosing scope. -
It is no longer allowed to iterate over the undocumented
vecttype in aselectstatement. In classic DML 1.2, this was permitted but had unexpected behaviour. -
If a method argument has type
const char *, it is no longer permitted to pass a string literal. -
The
!operator is stricter in 1.3; in particular, it no longer accepts a constant integer as operand. Other condition expressions, like theifcondition or&&operands, no longer accept the 0 or 1 literal; usefalseortrueinstead. -
In DML 1.4, the
sizeofandtypeofoperators require that the operand is an lvalue. -
A reference to an
implementobject can no longer be used as a value. -
In classic DML 1.2, one could write
extern X;to declare that some symbol X is externally defined as a C symbol, without providing a hint on the type of X. This is not permitted in DML 1.4. -
The undocumented
c_nameparameter no longer has an effect oninterfaceobjects. This may affect old C + DML integrations. -
A method's input parameters now belong to the method's top scope, instead of a separate scope. Thus, it is illegal to declare a variable in method's top scope which shadows a method parameter.
-
In classic DML 1.2, the
loggroup X;statement would expose the log group as an identifierXin generated C code. This is no longer done, which may affect old C + DML integrations.
The following incompatible changes are not caught
by --strict-dml12, and must be adjusted manually:
-
The API for initialization and reset has been rewritten. The most important differences:
-
When the device is initialized, all registers are reset to the new
init_valparameter, defaulting to zero. In 1.2, similar results were achieved by performing a hard reset. -
The
hard_resetandsoft_resetmethods in banks and devices, typically called to trigger a reset, are no longer available by default. The methods can be created by instantiating templates from theutility.dmllibrary (the templates are namedhresetandsreset, respectively). -
The
hard_resetandsoft_resetmethods in registers and fields also do not exist by default. They are also created when instantiatinghresetandsresettemplates. -
The
hard_reset_valueandsoft_reset_valueparameters in registers and fields are no longer recognized. Instead, the default implementations of thehard_resetandsoft_resetmethods invoke theinitmethod, effectively replacing thehard_reset_valueandsoft_reset_valueparameters withinit_val. You must now override thesoft_resetmethod explicitly in order to provide different reset values for hard and soft reset.
-
-
The API for declaring event objects has changed. Just like in DML 1.2, the event callback is defined by a method
event, and the event is posted by a methodpost. A number of things have changed since 1.2:-
Instead of defining a parameter
timebasein each event object, you must now instantiate one of six predefined templates in each event object:-
simple_time_event,simple_cycle_event -
Event without data. The
eventmethod takes no arguments, and thepostmethod only takes a single argument, the delay. -
uint64_time_event,uint64_cycle_event -
Event with integer data. The
postmethod takes an argument of typeuint64in addition to the delay argument. This argument is later passed on to theeventmethod, which takes a singleuint64argument. -
custom_time_event,custom_cycle_event -
Event with custom data. The
postmethod takes an argument of typevoid *in addition to the delay argument. This value is later passed on to theeventmethod, which takes a singlevoid *argument.
The difference between the
*_time_eventand*_cycle_eventtemplates is similar to the difference betweentimebase = "seconds"andtimebase = "cycles"in DML 1.2. I.e., when a method argument or return value represents time, then the variant of the method in a*_time_eventtemplate represents time as a floating-point number, representing (simulated) seconds, whereas the variant in a*_cycle_eventtemplate represents time as an integer, representing CPU cycles. -
-
The method
eventis abstract in all templates. In DML 1.2, there was a not-so-useful default implementation. -
The methods
next,postedandremoveare not available in thecustom_*_eventtemplates. They are available in thesimple_*_eventtemplates withoutdataarguments, and inuint64_*_eventtemplates withdataarguments of typeuint64. -
The methods
set_event_info,get_event_infoanddestroyare only recognized by thecustom_*_eventtemplates, where the methods are abstract. In the other templates, serialization and deserialization are done automatically -
The
describe_eventmethod can no longer be overridden. -
The
post_on_queuemethod is no longer available.
Example:
event simple is (simple_time_event) { method event() { log info: "hello"; } } event parameterized is (uint64_cycle_event) { method event(uint64 data) { log info: "hello %d", data; } } ... // no data args needed simple.post(1.0); assert simple.posted(); // in uint64_cycle_event, the methods posted, next // and remove check that the data argument matches parameterized.post(18, 4711); assert parameterized.next(4711) == 18; assert parameterized.next(42) < 0; -
-
The parameters
partialandoverlappingin banks are nowtrueby default. -
Some rarely used identifiers from C, in particular many C macros on the form
XYZ_INTERFACE, are no longer automatically available in DML. This will cause compile errors on migration, which can be resolved by manually adding corresponding symbol definitions to the DML file. -
Methods that can throw an exception must be annotated with the new
throwskeyword:method m(bool condition) -> (int) throws { if (condition) throw; }The
throwsannotation is required if the method contains either a throw statement or an invocation of a method with thethrowsannotation, unless all such statements are enclosed intryblocks. -
Assignment operators (
=as well as+=,*=, etc) are now separate statements, and disallowed inside expressions. These statements are allowed in some additional places, to replace common uses of assignment expressions:-
A
=statement may contain multiple target expressions (a = b = c;). The targets are assigned from right to left, like in C. -
The pre and post sections of a
forstatement may contain any assignment statement. So the following is still valid:for (i = j = 0; i < 10; i += 3, j++) { ... }
-
-
In DML 1.4, methods are no longer declared
extern, rather they areexportedusing theexportstatement. Anexportedmethod must be declared in the top scope, may not throw exceptions, and may have at most one return value. The generated C function now has extern linkage, and takes aconf_object_t *as its first argument. -
The syntax of
switchstatement is now stricter, and now requires a conventional switch structure: The switch body must be a compound statement starting with acaselabel, allcaseanddefaultstatements must reside directly in this statement, and nocasemay appear after thedefaultstatement. -
When declaring a template, a
descstring may no longer be supplied. Thus, the following is now invalid:template t "short description" { ... }This syntax used to create a parameter
descin the objects where the template is instantiated. -
The
#operator is no longer supported. It was seldom useful in DML 1.2, and its behaviour was in many ways complex and undocumented. -
It is no longer allowed to refer to objects using the names
signed,unsignedandthis. -
The expression
undefinedmay no longer be passed as argument to an inline method -
If the condition of a
whileloop is statically evaluated to false, then faulty code in the loop body can cause compile errors in DML 1.4. In DML 1.2, the loop body was silently discarded. -
gotostatements, as well as goto labels, are not allowed in DML 1.4. -
The parameter
persistentin fields is no longer supported. It was buggy in 1.2. As a replacement, checkpoint fields as separate attributes if persistence differs within a register. -
Objects of
registerorattributetype withconfiguration="pseudo", that are either read-only or write-only, have to declare this specifically by setting the new parameterreadable(orwritable) tofalse. In 1.2, DMLC used some heuristics to automatically guess the user's intent. -
The parameter
allocate_typeinattributeobjects has been removed. Three templates are available as a replacement:-
uint64_attrreplacesallocate_type="uint64" -
int64_attrreplacesallocate_type="int64" -
bool_attrreplacesallocate_type="bool" -
double_attrreplacesallocate_type="double"
For the
allocate_typevalues"uint8","uint16","uint32","int8","int16", and"int32", the corresponding 64-bit template is recommended. There is no replacement forallocate_type="string". -
-
In objects of type
attribute,registerandfield, storage is now allocated in a separate membervalinstead of the object itself. For example: when assigning a value to a register, you might changebank.reg = 4;intobank.reg.val = 4;. Note that thevalmember is not automatically created by DMLC; it is merely a naming convention used by many standard templates (type_attr for attributes, andalloc,read_write,read_onlyfor registers and fields). -
The following standard parameters have been removed:
-
Object parameters
-
logobj,indexvar -
bankparameters -
mapped_registers,unmapped_registers,numbered_registers -
registerparameters -
fields,signed -
connectparameters -
interfaces
-
-
The bank parameters
miss_bank,miss_bank_offset,miss_pattern,functionandlog_grouphave been tentatively removed; we intend to replace them with standard templates. -
In
connectobjects, thevalidateandvalidate_portmethods have been merged into one method, namedvalidate. This method has the same signature and semantics asvalidate_portin DML 1.2. -
In objects of type
attribute,registerandconnect, the methodsbefore_setandafter_setare no longer recognized. As a replacement, overridesetwith a method that performs intended logic before and after an invocation ofdefault. -
The templates
signedandnoallochave been removed, together with thesignedandallocateparameters in registers and fields. -
The parameter
offsetin registers can no longer be set toundefined. Instead, use theunmappedtemplate to denote an unmapped register. -
The templates
unimplemented,silent_unimplemented,read_unimplementedandwrite_unimplementedhave been renamed, tounimpl,silent_unimpl,read_unimplandwrite_unimpl, respectively. Also, log levels of logged messages have changed: The first message is logged on level 2 bysilent_unimpl, and level 1 by all the other templates, while subsequent messages are logged on level 3 in all templates. -
Registers that instantiate the
constanttemplate should use theinit_valparameter to declare their reset value, changed from thevalueparameter in DML 1.2.