Non-contiguous Subtypes

R

Rob Gaddi

Guest
Random question while it's on my mind. So, there's VHDL support for
declaring contiguous subtypes.

subtype t_index is integer range 0 to 7;

Is there any syntax for declaring discontiguous subtypes? Something like:

subtype t_axi_datawidth is integer (8, 16, 32, 64, 128, 256, 512, 1024);

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 
On Thursday, April 2, 2015 at 9:51:15 AM UTC+13, Rob Gaddi wrote:
Random question while it's on my mind. So, there's VHDL support for
declaring contiguous subtypes.

subtype t_index is integer range 0 to 7;

Is there any syntax for declaring discontiguous subtypes? Something like:

subtype t_axi_datawidth is integer (8, 16, 32, 64, 128, 256, 512, 1024);

No.

IEEE Std 1076-2008 5.2 Scalar types, 5.2.1 General:

Scalar types consist of enumeration types, integer types, physical types, and floating-point types. Enumeration types and integer types are called discrete types. Integer types, floating-point types, and physical types are called numeric types. All scalar types are ordered; that is, all relational operators are predefined for their values. Each value of a discrete or physical type has a position number that is an integer value.

--

It's that position number which is used for numeric operations.

5.2.3 Integer types, 5.2.3.1 General:

An integer type definition defines an integer type whose set of values includes those of the specified range.

Integer_type_definition ::= range_constraint

--

Back to 5.2.1:

range_constraint ::= range range

range ::=
range_attribute_name
| simple_expression direction simple_expression

direction ::= to | downto

--

Only constrained range

Back to 5.2.3.1:

Integer literals are the literals of an anonymous predefined type that is called universal_integer in this standard. Other integer types have no literals. However, for each integer type there exists an implicit conversion that converts a value of type universal_integer into the corresponding value (if any) of the integer type (see 9.3.6).

The position number of an integer value is the corresponding value of the type universal_integer.

--

So we have two aspects to a type, position and value. For integer types position is given as a universal_integer, convertible to the integer type, and it's position is also tied to universal_integer.

While you're proposed subtype is discrete, arithmetic operation results can't be expressed in it inclusively, for instance any two of it's values added together don't result in a value of the proposed subtype.

5.2.3.1:

The same arithmetic operators are predefined for all integer types (see 9.2). It is an error if the execution of such an operation (in particular, an implicit conversion) cannot deliver the correct result (that is, if the value corresponding to the mathematical result is not a value of the integer type).
--

Notice you can't use your subtype values as an enumeration type, an enumeration literal is either an identifier or a character literal (5.2.2.1).

You could create an enumeration type and use it as an index into a constant array of integer values:
entity axiwidth is
end entity;

architecture foo of axiwidth is

type axi_datawidth is ( AXI_WIDTH8, AXI_WIDTH16, AXI_WIDTH32,
AXI_WIDTH64, AXI_WIDTH128, AXI_WIDTH256,
AXI_WIDTH_512, AXI_WIDTH1024);

type axi_values is array (axi_datawidth) of positive;

constant axi_datawidth_value: axi_values := ( 8, 16, 32, 64,
128, 256, 512, 1024);

signal a: integer := axi_datawidth_value(AXI_WIDTH16);
begin
RESULT:
assert FALSE
report "a = " & integer'image(a)
severity NOTE;
end architecture;

And if you wanted to access them by position of the axi_datawidth type you could convert position to value by using axi_datawidth'VAL.
 

Welcome to EDABoard.com

Sponsor

Back
Top