I have a record type(REC
) which contains an element of type VECTOR
which is an unconstrained 2d array of STD_LOGIC
:
package TEST is
type VECTOR is array (NATURAL range <>, NATURAL range <>) of STD_LOGIC;
type REC is record
data : VECTOR;
end record REC;
function con(
a : REC;
b : REC)
return REC;
end package TEST;
When declaring the body of the con
function I want to specify the size of the REC.data
array like so:
package body TEST is
function con(
a : REC;
b : REC)
return REC is variable r : REC(
data(a.data'length(1) + b.data'length(1) - 1 downto 0, a.data'length(2) - 1 downto 0));
begin
-- . . . do things
end function con;
end package body TEST;
but in the line where I attempt to set the size of data it Vivado throws the following error:
Sliced name is allowed only on single-dimensional arrays
Does this mean I cannot have an unconstrained 2d arraign in a record or is there a different method for defining the size of it in the con
function ?
---- EDIT ----
Since I now understand that it is not possible to use 2d arrays in this context what method should I use to create a function which:
user1155120 I don't think I fully understand what you are trying to say. Are you saying my code is not
a minimal reproducible example, because except for me forgetting to include the STD_LOGIC library
the code reproduces the problem when I paste it into Vivado, and it is about as minimal as I can get it.
Or are you saying that the code you linked as this works works for you, because at least in my
Vivado it still throws the same error ? – Mercury 4 hours ago
The original comment was meant for Tricky. There's a missing return statement in the function con
which would prevent use in an example.
It isn't clear if record constraints (a -2008 feature) are supported in Vivado Simulator. In Vivado Synthesis Guide UG901 2020.1 we see all sorts of wonderful uses of record types from everything to inferring ram to record elements of record types. Xilinx has been busy.
It'd seems odd if unconstrained elements in record type declarations were supported but not record constraints (they're pretty much a package deal, pun aside). Note the comment called it a -2008 feature.
A record constraint is limited to supply the constraint of an element or subelement that is of an unconstrained type (typically arrays). VHDL has always been capable of supplying multi-dimensional array constraints. The language of the standard is particular based on the flexibility of the syntax.
This code is VHDL -2008 compliant and provides your record constraint:
library ieee; -- ADDED for MCVe
use ieee.std_logic_1164.all; -- ADDED
package TEST is
type VECTOR is array (NATURAL range <>, NATURAL range <>) of STD_LOGIC;
type REC is record
data: VECTOR;
end record REC;
function con (a: REC; b: REC) return REC;
end package TEST;
package body TEST is
function con (a: REC; b: REC) return REC is
variable r:
REC ( -- record constraint:
data (
natural range a.data'length(1) + b.data'length(1) - 1 downto 0,
natural range a.data'length(2) - 1 downto 0
)
);
begin
-- . . . do things
return r; -- ADDED required return statement
end function con;
end package body TEST;
You'll note the changes to the record constraint from yours is the addition of natural range
before each range of the element data constraint.
From IEEE Std 1076-2008 5.3.3 Record types:
record_constraint ::=
( record_element_constraint { , record_element_constraint } )record_element_constraint ::= record_element_simple_name element_constraint
From 6.3 Subtype declarations:
element_constraint ::=
array_constraint
| record_constraint
Here the element data is an array so an array_constraint is appropriate.
From 5.3.2 Array types, 5.3.2.1:
array_constraint ::=
index_constraint [ array_element_constraint ]
| ( open ) [ array_element_constraint ]
Because element data array elements are scalar (enumeration type STD_LOGIC) we follow index_constraint.
index_constraint ::= ( discrete_range { , discrete_range } )
discrete_range ::= discrete_subtype_indication | range
The code shown above uses a discrete subtype indication for the index ranges of the element data dimensions and successfully analyzes (compiles).
From 5.2.2 Scalar types, 5.2.2.1:
range ::=
range_attribute_name
| simple_expression direction simple_expressiondirection ::= to | downto
The constraint in the question uses a range with simple expressions and direction.
So why did it produce the error message about multi-dimensional slices?
In 9. Expressions, 9.1 the BNF, simple_expression -> term -> factor -> primary -> name.
In 8. Names, 8.1 name -> slice_name, only multi-dimensional slices are not allowed semantically in 8.5 Slice names who's BNF tells us it's syntactically valid:
slice_name ::= prefix ( discrete_range )
The prefix of a slice shall be appropriate for a one-dimensional array object. The base type of this array type is the type of the slice.
and semantically the prefix data
is not appropriate for a one-dimensional array object.
These comments provide bit more context for the problem although it isn't clear which version the record constraint you used in the reported eventual success:
@Mercury when you add a (VHDL) file to Vivado, it's by default set to use VHDL 93, but not 2008. Go
to the property Window and change the file type from VHDL to VHDL 2008. I'm not sure why it
prints the wrong error message in your case. (Vivado likes to confuse users with wrong error messages
...). Anyhow, it should have reported your feature is only supported in 2008 mode. – Paebbels 3 hours
ago
@Paebbels Thank you, that fixed the problem, maybe add it as a sub note to your response so I can
mark it as accepted answer. You just saved me hours of frustration. And I'm already getting familiar with
Vivado's shenanigans, my Favorit one of which is "ERROR close to ..." which has to be one of the most
useless error messages I have experience in a long time :) – Mercury 3 hours ago
As far as detecting -2008 source, there are no -1993 syntax errors and no -2008 new reserved word, delimiters, separators or graphics characters in either the primary unit or the secondary.
That leaves you at the mercy of semantic analysis which failed. You could also note the unconstrained record element wasn't reported during analysis of the package declaration. It occurred during evaluation of the variable r
. All declared objects are required to be constrained. VHDL doesn't have a recital of all features, semantics can be restrictive as well. It's legal in places to have unconstrained elements and objects.
Associating semantics rules found in the text of the standard with an textual element of the particular declaration or statement can be tough and the squeaky wheel gets the lubricant. Record constraints are relatively new to VHDL implementations.
The problem appears to have been one of tool familiarity.