Previous Contents

7   Variables

variable-definition   ::=   (private) ? variable ident = vardef
vardef   ::=   var-registers (, var-attribute) * : type-expr
var-registers   ::=   var-regs (, var-regs) ?
var-regs   ::=   (rw) ? register-bits
register-bits   ::=   ident
  | ident[integer-ranges]
  | ident(exprs)
  | ident(exprs)[integer-ranges]
  | register-bits # register-bits
var-attribute   ::=   volatile
  | (rw) ? trigger
  | (rw) ? trigger for trigexpr-paren
  | (rw) ? trigger except trigexpr-paren
  | (rw) ? serial-spec

trigexpr-paren
  ::=   trigexpr
  | (trigexpr (, trigexpr) *)
trigexpr   ::=   integer-range
  | ident
  | boolean-literal

A variable object provides an abstract interface to concrete register values and specifies the semantics of the data stored in registers. A variable definition has two optional parts: the read part and the write part. If a variable definition does not have a read (write) part, the register is said to be write-only (read-only), otherwise it is referred to be read-write. The read part of a variable definition contains the specification of four components: register-bits, serialization, volatile and trigger. The write part specifies three components: register-bits, serialization and trigger. The type specification is shared for both the read and write parts.

Visibility

A variable object is introduced by the variable keyword, followed by the identifier name of the variable being defined, and optionally preceded by the private keyword. When a variable is declared as private, its definition is not exported in the generated interface and must be used at least once within the devil program where its definition occurs. As an example, private variables are often declared to model indexes and used in pre-actions of indexed-registers.



Register-bits

The register-bits component specifies which bit of which register must be concatenated in order to obtain the bit-string that forms a device variable. The register-bits component is recursively defined as follows: (1) a register identifier name denotes all its bits; (2) a register identifier name followed by an integer range listed between square brackets denotes all bits which have a position number that appear in the list; (3) the expression rb1 # rb2 denotes the concatenation (from left to right) of the bits specified by rb1 and rb2. Note that the bit number 0 of register reg is the less significant bit. One or two register-bits must be provided in a variable definition. The read or write part of a variable is defined if and only if a read or write register-bits definition is provided. If only one register-bits is provided, without a modifier, its definition is used for both the read and write parts.

Volatile

The volatile attribute is only attached to the read part of a variable definition. When a variable is declared as volatile, each read operation may produce a different value. If the volatile attribute is not provided, it defaults to non volatile.

Trigger

The trigger attribute is introduced by the trigger keyword, optionally preceded by a read or write modifier. When a variable is declared as trigger, each access to this variable triggers an action or a set of actions inside the device. For example, writing twice the same value does not produce the same result that one write operation. As a consequence, two trigger variables that map bits of the same register have to be grouped in a structure. When the trigger attribute is used for the write part of a variable definition, some specific values can sometimes cancel the trigger effect. These values can be specified by using the attributes trigger for and trigger except. If no trigger attribute is provided, it defaults to non trigger. If the trigger attribute is preceded by the read or write modifier, its definition applies only to the read or write part of the variable definition.

Trigger for ...

When the trigger keyword is followed by the for keyword and a list of expressions, the variable is declared as trigger only for values that match the specified list of expressions.

Trigger except ...

When the trigger keyword is followed by the except keyword and then by a list of expressions, the variable is declared as trigger only for values that do not match the specified list of expressions. Since all Devil types are finite, the set of values that cancel the trigger effect of a variable is also finite.

7.1   Structures

structure-definition   ::=   structure ident = structdef
structdef   ::=   { (variable-definition;) + } (structure-attributes) ?
structure-attributes   ::=   structure-attribute (, structure-attribute) ?
structure-attribute   ::=   (rw) ? serial-spec

A structure is a collection of variable definitions.



When more than one register is used for defining variables contained in the structure, the serialized as expression has to be provided. When a structure is read or written, the serial construction specifies in which order read or write operations are executed. When bits of a register are mapped to variables defined in the same structure, only one read or write operation is executed for this register.



7.2   Serialization

serial-spec   ::=   serialized as serial-desc
serial-desc   ::=   ident
  | { serial-def (; serial-def) * }
serial-def   ::=   ident
  | if (expr) serial-desc (else serial-desc) ?

The serialized as construct is used to specify in which order registers of a variable or a structure have to be accessed. The serialized keyword is optionally preceded by a read or write modifier, in which case its definition is restricted to the read or write part of the variable or structure being defined. If no modifier is specified, the same serial definition is used for both the read and write part. If no serial definition is provided, one is deduced from the variable or structure definition. Identifiers used in the rules serial-desc   ::=   ident and serial-def   ::=   ident must refer to register names.

Sequence

The serial description r1; r2 specifies that register r1 must be accessed first, followed by an access to register r2.

Conditional

The serial description if (expr) s1 else s2 specifies conditionnal definitions (depending on runtime values of given variables) of register sequences.

7.3   Variable Extensions

When all bits of a register are mapped to a single variable and when this register can be expressed with a parameterized register, one can write: instead of This two constructions are strictly equivalent. A similar case is when all bits (of a register) that can be mapped are mapped to a single variable. As illustrated previously, it is possible to insert a parameterized register application in a variable definition, but it is also possible to extract bits of this defined register with the [...] construct. The Devil code below illustrates this construction:





Previous Contents