The general form of an object declaration is "type name extras desc { ... }" or "type name extras desc;", where type is an object type such as bank, name is an identifier naming the object, and extras is optional special notation which depends on the object type. desc is an optional string constant giving a very short summary of the object. Ending the declaration with a semicolon is equivalent to ending with an empty pair of braces. The body (the section within the braces) may contain parameter declarations, methods, data fields, and object declarations.
For example, a register object may be declared as
register r0 @ 0x0100 "general-purpose register 0";where the "@ offset" notation is particular for the register object type; see below for details.
An object declaration with a desc section, on the form
type name ... desc { ... }is equivalent to defining the parameter desc, as in
type name ... { parameter desc = desc; ... }In the following sections, we will leave out desc from the object declarations, since it is always optional. Another parameter, documentation (for which there is no short-hand), may also be defined for each object, and is used to give a more detailed description. See Section 5.1.1 for details.)
If two object declarations with the same name occur within the same containing object, and they specify the same object type, then the declarations are concatenated; e.g.,
bank b { register r size 4 { ...body1... } ... register r @ 0x0100 { ...body2... } ... }is equivalent to
bank b { register r size 4 @ 0x0100 { ...body1... ...body2... } ... }However, it is an error if the object types should differ.
Some object types (register, group, attribute, and connect) may be used in arrays. The general form of an object array declaration is
type name [size] extras { ... }where size is the number of elements in the array. The size must be a compile time constant. For instance,
register regs[16] size 2 { parameter offset = 0x0100 + 2 * $i; ... }or written more compactly
register regs[16] size 2 @ 0x0100 + 2 * $i;defines an array named regs of 16 registers (numbered from 0 to 15) of 2 bytes each, whose offsets start at 0x0100. There is also a special syntax "type name [variable in 0..max] ...", where max = size - 1. See Section 5.1.2 for details about arrays and index parameters.
The following sections give further details on declarations for object types that have special conventions.
The general form of a bank declaration is
bank name { ... }where name may be omitted. The elements (e.g., registers) of a bank that has no name belong to the namespace of the parent object, i.e., the device. There is at most one such anonymous bank object per device; multiple "bank { ... }" declarations are concatenated.
The general form of a register declaration is
register name size n @ d is (templates) { ... }
Each of the "size n", "@ d", and "is (templates)" sections is optional, but if present, they must be specified in the above order.
register name size n ... { ... }is equivalent to
register name ... { parameter size = n; ... }
register name ... @ d ... { ... }is equivalent to
register name ... { parameter offset = d; ... }
register name ... is (t1,...,tN) { ... }is equivalent to
register name ... { is t1; ... is tN; ... }
The general form of a field declaration is
field name [highbit:lowbit] is (templates) { ... }or simply
field name [bit] ... { ... }specifying a range of bits of the containing register, where the syntax [bit] is short for [bit:bit]. Both the "[...]" and the is (templates) sections are optional; in fact, the "[...]" syntax is merely a much more convenient way of defining the (required) field parameters lsb and msb (cf. Section 5.1.7).
field name [high:low] is (t1,...,tN) { ... }is equivalent to
field name [high:low] { is t1; ... is tN; ... }
For a range of two or more bits, the first (leftmost) number always indicates the most significant bit, regardless of the bit numbering scheme used in the file. This corresponds to how bit fields are usually visualized, with the most significant bit to the left.
The bits of a register are always numbered from zero to n - 1, where n is the width of the register. If the default little-endian bit numbering is used, the least significant bit has index zero, and the most significant bit has index n - 1. In this case, a 32-bit register with two fields corresponding to the high and low half-words may be declared as
register HL size 4 ... { field H [31:16]; field L [15:0]; }
If instead big-endian bit numbering is selected in the file, e.g., with a "bitorder be32;" declaration, the most significant bit has index zero, and the least significant bit has the highest index. In that case, the register above may be written as
register HL size 4 ... { field H [0:15]; field L [16:31]; }This is useful when modeling a system where the documentation uses big-endian bit numbering, so it can be compared directly to the model.
Note that for a bit field declaration, only the "endianism" selected by a bitorder declaration in the file has any effect; the base width is always that of the containing register, so in a 16-bit register, big-endian bit 0 corresponds to little-endian bit 15, but in a 32-bit register, big-endian bit 0 corresponds to little-endian bit 31.