====== 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