# 15.3  Registers

The language includes the integer and fixed-point register class templates of Algorithmic C [algc], which may be instantiated as follows:

• ac_int<n, false> and ac_int<n, true>: unsigned and signed integer types of width , where may be any positive integer;

• ac_fixed<n, m, false> and ac_fixed<n, m, true>: unsigned and signed fixed-point register types of width with integer bits, where may be any positive integer and is any integer.

By convention, we use the names ui, si, ufi, and sfi for the types ac_int<n, false> and ac_int<n, true>, ac_fixed<n, m, false>, and ac_fixed<n, m, true>, respectively. These types are expected to be declared as needed at the beginning of a program, as in the following examples:
  typedef ac_int<96,false> ui96;
typedef ac_int<48,true> si48;
typedef ac_fixed<64,4,false> uf64i4;
typedef ac_fixed<32,16,false> uf32i16;


A register is associated with two values, a raw value, which is a bit vector of the same width as the register, and an integer or rational interpreted value. The interpreted value is derived from the raw value according to the register's type as follows:

• ui (unsigned integer): The interpreted value is the same as the raw value, an integer in the interval .

• si (signed integer): A signed version of ui, with the leading bit interpreted as the sign. Thus, the represented range is the interval of integers .

• ufi (unsigned fixed-point): Interpreted with an implicit binary point following the most signficant bits. The represented values are rational numbers of the form , where is an integer and .

• sfi (signed fixed-point): A signed version of ufi, representing rational numbers of the form , where .
The interpretation of register values is formalized by the following functions:

Definition 15.3.1   (ui, si, uf, sf) Let and with and let be a bit vector of width .

(a) ;

(b) ;

(c) ;

(d) .

Note that while the width of a register must be positive, there is no restriction on the number of integer bits of a fixed-point register. If , then the interpreted value is an integer with trailing zeroes; if , then the interpreted value is a fraction with leading zeroes.

The Algorithmic C register types include a "bit select" operator and "bit slice" methods. Bit selection is independent of the register type (signed vs. unsigned, integer vsfixed-point) and uses the familiar syntax. Thus, a bit of a register may be extracted or assigned in the natural way. The syntax of bit slices is less straightforward. The slice extraction method slc requires a constant template parameter indicating the width of the slice and a variable argument that represents the base index. Thus,

x.slc<4>(n)

determines the slice of x of width 4 based at bit n, which the pretty-printer renders as
x[n+3,n].

The value of this method is an integer register (independent of whether the register is integer or fixed-point) with ther same width parameter as the method and the same sign parameter as the operand. Thus, the numerical value of a slice is a signed or unsigned integer according to the type of the register from which it is extracted.

A bit slice is modified by a method of two arguments, the base index and an integer register containing the value to be written. The width of the slice is not specified explicitly, but rather is inferred from the type of the second argument. For example, the assignment

x.set_slc(n, ui4(6))

replaces the slice of x of width 4 based at index n with the value 6 (binary 0110), and is pretty-printed as
x[n+3:n] = 6.


David Russinoff 2017-08-01