## Proposal Details

• Date Proposed: 2016-10-17
• Date Last Updated: 2016-10-18
• Priority:
• Complexity: Low to Medium, I think
• Focus: General Language
Remark : This proposal results from the split of the enhanced integers proposal.

### Current Situation

Currently when we want to access the bit representation of a VHDL object, we are forced to use conversion functions that simulate the access to the bit representation, but it isn't, in my eyes, an optimal solution. Because conversion functions will create a new VHDL object and the synthesis tools have to figure out that it is supposed to be the bit representation of the former object in order not to synthesize it. As we know that each VDHL object has by nature a binary representation, why not to make it accessible ? Also creating conversion functions is extra work and they won't necessarily show the real bit representation (e.g. the conversion function of a FSM could show a binary encoding while it might be a gray encoding in the reality).

On the other hand, it is true that we want to use integers, enumerations, arrays, records, etc as ideal objects and the strong typing philosophy of VHDL wouldn't allow to do on objects operations that aren't conforming to their nature (e.g. binary operations on integers), which is a good thing in my eyes. Whenever possible, we want to use the objects as they were intended to, but sometimes we need an access to their bit representation. It will be like allowing 2 possible views for an object, and let the user use which one is relevant for each case. Here is a picture (taken from wikipedia) to better explain the idea :

A represents the ideal object, while B represents the real object that also have a logical representation. In other words B includes all the characteristics of A, while having some extra characteristics. Currently in VHDL we can only access A, and are forced to do conversions to simulate the access to the B part outside A. It's a bit of a pity because in the reality we are dealing with B and not A, although we want to only access the A part of B whenever possible. While it is certainly OK for high level languages not to allow access to the logical representation of objects, this isn't the case (in my eyes) with VHDL as low level programming is unavoidable while interfacing external entities.

Therefore it would make sense to me to consider every VHDL object as a B object that has 2 possible views : the A part which will be accessible as usual and the B part outside A that will be accessible thanks to some extra attributes.

Remark : This proposal will address the issues reported by the IntegerOperators proposal, while not going against VHDL strong typing philosophy.

### Requirement

• Properties will be an optional (to be written) proposal that will allow the users the define their own encoding.

### Implementation details

The 'Bits, 'Size and 'Encoding attributes will be added to every types and objects. When declaring a type or an object, its size and/or encoding could be specified. The 'Encoding attribute will allow to choose one encoding belonging to the predefined encodings supported by the tools. Thanks to the 'Bits attribute, it will be possible to access the binary value of an object and read or write it. This binary value will be of type Bit_Vector.

#### Modification of predefined attributes

With current VHDL, it is possible to create and set user attributes. However in our case we need to be able to set predefined attributes ('Encoding and 'Size), and to my knowledge, there isn't such a mechanism in current VHDL. Therefore, here is a suggested implementation :

`signal A : Integer with Encoding => Twos_Complement, Size => 12;`

So here is the generic form :

`<object_type> <object_name> : <type> with <attribute_1> => <value>, <attribute_2> => <value>, (...), <attribute_n> => <value>;`

It will also be possible to define attributes after the declarative part like this :

```signal B : Integer;
for B'Encoding use Twos_Complement;
for B'Size use 14;```

#### General rules

1. If the 'Size or the 'Encoding aren't specified, the tools are free to choose the size, respectively the encoding of a given object.
2. Not all possible encodings are to be supported by the tools, on the contrary, they are free to choose which encodings they support, unless otherwise stated (but currently there is nothing such). Tools will likely support only 2s-complement integers. In contrast, they will likely support more than one encoding for FSM signals. It is conceivable that most of the synthesis tools will, for objects other than FSM, implement only one possible encoding, thus the only choice the user could have will be choosing the default encoding either implicitly or explicitly. Explicitly choosing the default encoding will be useful to safely do binary operations on the object.
3. The size of an object must be at least the minimum size needed to fit the object in. If its above the minimum needed size, then the tools are free in regards with the layout of the data (or should we add more specifications with that ?).
4. If there is a bit vector object/expression assigned to the 'Bits attribute of an object, then the object size must exactly match the size of the assigned bit vector object/expression. Likewise if the 'Bits attribute is used to set a bit vector either directly or inside an expression, the object size must be such that there won't be a mismatch with the size of the assigned bit vector. Therefore, in the code example with integers, both B and C size definitions could have been avoided, as their size will match A length according to this rule.
5. If by following rule (4), rule (3) cannot be fullfilled or if an explicitely defined size prevents rule (4) to be fullfilled, then an error will be thrown.
6. In regards to rule (4), a conflict will happen in the following case : C <= A'Bits; D <= A'Bits, where A size isn't explicitly specified and where C and D are bit vectors of different lengths. Then an error will be thrown because it isn't possible to make A size match both C length and D length. This problem could be fixed by resizing A'Bits in one of the 2 statements.
7. As shown in the example with strings, objects of different encodings are compatible because as long as we stay in the higher-level, bit-representation is irrelevant.

### Code Examples

Here are written code examples for bit representation access of objects of several types. At first glance, it seems to me that the most frequent uses cases will be with integers and reals (need of a new proposal), while the other cases should be used once in a while.

#### Integers

```signal A : Bit_Vector (3 downto 0);
signal B, C : Integer with Encoding => Twos_Complement, Size => A'Length;
signal D : Integer;
(...)
A <= B'Bits; -- Reading of the 'Bits attribute
C'Bits <= A Xor "0110"; -- Binary operation on the bit representation of an integer via the 'Bits attribute
D'Bits <= A; -- When accessing the 'Bits attribute of objects whose encoding isn't explicitly specified, should an error be thrown, or at least a warning ?```

#### Enumerates

Currently it is possible to use tool dependant attributes to specify the encoding of a FSM. But we still can't access to the bits of a FSM signal, which could be indeed useful for debugging purpose.

```type FSM_1 is (Start, Stop, Idle, Initialize) with Encoding => Gray;
My_FSM : FSM_1;
type FSM_2 is (Start, Stop, Idle);
for FSM_2 use (Start => "00", Stop => "10", Idle => "11");
(...)
Logical_Analyzer <= My_FSM'Bits;```

#### Arrays

```subtype Integer_16 is Integer with Size => 16;
type Integer_Array is array (Natural range 0 to 3) of Integer_16;
signal My_Array : Integer_Array;
signal A : Bit_Vector (My_Array'Size - 1 downto 0);
(...)
A <= My_Array'Bits;```

#### Records

```type Operation_Type is record
Mnemonic : String (1 to 10);
Op_Code : Bit_Vector (3 downto 0);
Op1, Op2, Res : Reg_Name;
end record;
signal Operation : Operation_Type;
signal A : Bit_Vector (Operation'Size - 1 downto 0);
(...)
A <= Operation'Bits;```

#### Real numbers

Here, contrarly to the others examples, the encoding will have an influence on the precision of the encoded numbers. They will also need extra attributes in order to specify the decimal and fractional part of fixed point real numbers, and the mantissa and exponent part of floating point real numbers. They could be addressed in another proposal as it would be beyond the goals of this proposal.

#### Strings

```signal A : String (1 to 16) with Encoding => Latin9;
signal B : String (1 to 16) with Encoding => UTF8;
signal C : Bit_Vector (A'Size - 1 downto 0);
(...)
A'Bits <= C;
-- We will probably not see UTF8 <-> Latin9 conversions in a design, but this example is only to demonstrate the principle
B <= A; -- Fine because as we are working on the higher-level, bit-representation is irrelevant here.```

### Open questions

• When accessing the 'Bits field of objects whose encoding isn't explicitly specified, should an error be thrown, or at least a warning ?
• Should we change the syntax for attribute definitions so that it uses a sliced notation like this ? :
`signal A : Integer with (Encoding => Twos_Complement, Size => 12);`

## Use Cases

• Connection with external entities (which require data in their binary representation form).
• Binary operations on the bit representation of objects.
• Seamless assignements of signals of different encodings will be theorically possible (like in the code example with strings).

## Arguments FOR

• Remove the requirement of a conversion fonction from/to bit vector.
• Allow objects to be fully specified : not only their behavior (high-level) but also their binary representation (low-level), while still keeping a good separation between the high and the low level.
• Choosing a different encoding for an object will be easy (as long as the tools support alternative encodings).
• Addresses the issues reported by IntegerOperators, while extending the same principles to any types.