====== Declarations ======
This section discusses all possible //declarations// that are allowed
in an Arx [[component|component]] descripition. Declarations can be
made in the first part of a component description, before the
occerrence of keyword ''begin''.
There are two categories of declarations in Arx:
* Line-style declarations
* Section-style declarations
//Line-style declarations// are characterized by the occurence of a
keyword related to the declaration for each declared item. There are
three type of line-style declarations:
* Generic-type declarations
* Generic declarations
* I/O declarations
In the code, they should occur in the order given above.
//Section-style declarations// are characterized by a single keyword
indicating the declaration type followed by one or more items of the
declared type. The following section-style declarations exist:
* Constant declaration
* Type declaration
* Register declaration
* Variable declaration
There is no imposed order on the declaration as long as the principle
of //define before use// is respected. It is possible to have multiple
sections of the same type, e.g. a section of constant declarations
followed by register declarations in which the constants are used and
then a second section of constant declarations and a section of
variable declarations in which reference is made to the second section
of constants.
Below, each type of declaration is discussed in a separate section.
===== Generic Declaration =====
Generics create the possibility to parameterize a hardware
description. Typical paramters are word lengths, memory depths, etc.
A generic declaration has the following form:
: generic =
The following line of Arx code contains an example of a generic
declaration:
word_length: generic integer = 8
The page on [[instantiation]] explains how generics can be used in
hierarchical hardware descriptions.
==== Known Issue ====
The current version of Arx does not support negative constants for
.
===== Generic-Type Declaration =====
//Generic types// take the concept of parameterizability a step
further and make it possible to change data types in a component at
instantiation time. One can say that the use of generic types enhances
Arx with [[wp>Type_polymorphism| type polymorphism]].
The syntax for a generic type declaration is:
: generic type =
The following line of Arx code contains an example of a generic type
declaration:
T_IO: generic type = bitvector(8)
The page on [[instantiation]] explains how generic types can be used in
hierarchical hardware descriptions and how they can be combined with
generics. An example of polymorphic instantiation is provided there.
===== I/O Declaration =====
The I/O declaration specifies the signals with which a component
interfaces with the external world. An I/O signal is either an
//input// or an //output//. Bidrectional signals are not supported. An
I/O declaration has the following form:
:
The two possible values for are ''in'' for an input signal
and ''out'' for an output signal. can be any allowed type (see
the page on [[datatypes|data types]]),
including the type name of a generic type.
The following lines of Arx code contain a few examples of I/O
declarations:
data_in: in bitvector(8)
clear: in bit
data_out: out bitvector(8)
Examples of I/O declarations in the context of entire component
descriptions can be found on the pages explaining
[[component|components]] and [[instantiation]].
===== Constant Declaration =====
//Constants// are mechanism to assign a symbolic name to entities the
value of which can be computed at compile time. As opposed to
generics, their values cannot be directly changed at instantiation
time. They can be changed indirectly, though, when the value of a
constant is an expression that depends on a generic.
A section of constant declarations has the following syntax:
constant
+{ : = }+
So, can be an expression that evaluates to a constant at
compile time. The Arx code below shows an example of a
constant-declaration section (where ''word_length'' is supposed to be a generic):
constant
height: integer = 648
width : integer = 2*height
hwl : integer = word_length/2
===== Type Declaration =====
Types that are only relevant locally inside a component can be defined
in the //type-declaration// section of the declarations. They assign a
symbolic name to a type and make it possible to use this symbolic name
for the types of local signals. In this way, they
keep component descriptions flexible. If data types inside a
description need to be modified, it is sufficient to revise the type
declarations.
As opposed to
the declarations mentioned above, the keyword ''type'' needs to be
used to indicate the start of the type-declaration section.
The following syntax is used:
type
+{ : }+
The code fragment below shows a set of type declarations that could be
used for intermediate types in a chain of additions where the result
is each time one bit wider than the input (''word_length'' is supposed
to be a generic or a constant):
type
T_in : signed(word_length)
T_in_p1: signed(word_length+1)
T_in_p2: signed(word_length+2)
===== Register Declaration =====
//Register signals//, i.e. signals that keep their value from one
clock cyle to the next (see also the explanation of
[[rtl|register-transfer level]] modeling), are declared in a
//register-declaration// section which has the following syntax:
register
+{ *{, }* : = }+
It is mandatory that all registers receive a reset value which should
be provided after the equal sign (''='').
Here is an example of a register-declaration section (''T1'' and ''T2'' are
supposed to be generic or locally declared types):
register
a, b: T1 = 0
c : T2 = 511
p, q: boolean = true
===== Variable Declaration =====
As opposed to //register signals//, //variable signals// are
memoryless.
They correspond to wires in hardware and are found in the
//combinational-logic// part of the
[[rtl|register-transfer level]] model. Their declaration is very similar
to the one of registers, except for the fact that no reset value
should be provided:
variable
+{ +{, }* : }+
If the above example declared variables instead of registers, it would
look like this:
variable
a, b: T1
c : T2
p, q: boolean