Passing Generics to Record Port Types - vhdl

I did recently start to use records for my port definitions, especially if I want to group signals that belong to a certain interface. However, the problem I'm facing here is that I cannot pass, say the width of a std_logic_vector, to the entity by means of a generic. So what I basically want to do is the following:
library ieee;
use ieee.std_logic_1164.all;
use work.math_pkg.all;
package fifo_pkg is
type fifo_in_type is record
data_in : std_logic_vector(DATA_WIDTH_??- 1 downto 0);
rd : std_logic;
wr : std_logic;
end record;
type fifo_out_type is record
data_out : std_logic_vector(DATA_WIDTH_?? - 1 downto 0);
empty : std_logic;
full : std_logic;
end record;
component fifo is
generic
(
MIN_DEPTH : integer;
DATA_WIDTH : integer
);
port
(
clk : in std_logic;
res_n : in std_logic;
i : in fifo_in_type;
o : out fifo_out_type
);
end component fifo;
end fifo_pkg;
So the ideal solutions would be when i can use the same generic in my record as i did in the entity. (So that DATA_WIDTH is the same as DATA_WIDTH_??). I know that this should work somehow with vhdl 2008, however my quartus II 11sp1 does not support generics in records.
Is there an elegant way to achieve that kind of "generic passing" that is synthesizable? I know that one could just store a constant in the package, but then I cannot use the same fifo package to instantiate several fifo's with different widths.
Thanks a million,
T

Can you use type generics with Quartus?
Then you leave the type completely unspecified, so that you can create a FIFO of integers or any other data type:
package fifo_pkg is
generic (type element_type);
type fifo_in_type is record
data_in : element_type;
rd : std_logic;
wr : std_logic;
end record;
type fifo_out_type is record
data_out : element_type;
empty : std_logic;
full : std_logic;
end record;
component fifo is
generic
(
MIN_DEPTH : integer;
DATA_WIDTH : integer
);
port
(
clk : in std_logic;
res_n : in std_logic;
i : in fifo_in_type;
o : out fifo_out_type
);
end component fifo;
end fifo_pkg;
Then when you want to use it:
package wide_fifo_pkg is new fifo_pkg
generic map (type => std_logic_vector(31 downto 0));
and then you can use fifo_in_type and fifo_out_type:
signal i : fifo_in_type;
If you have more than one FIFO in a design unit you can create several versions of the package and use the package prefix to get the right type:
package narrow_fifo_pkg is new fifo_pkg
generic map (type => std_logic_vector(3 downto 0));
signal i32 : wide_fifo_pkg.fifo_in_type;
signal i4 : narrow_fifo_pkg.fifo_in_type;
Another VHDL 2008 option: you can have an unconstrained record type:
type fifo_in_type is record
data_in : std_logic_vector;
rd : std_logic;
wr : std_logic;
end record;
which you can then create subtypes of for your various uses:
subtype fifo1_data_type is fifo_in_type(data_in(31 downto 0));
subtype fifo2_data_type is fifo_in_type(data_in(15 downto 0));
No idea if Quartus supports either of those options - please let us know!

Generics in packages is supported in Xilinx's Vivado toolset currently. Ref their document UG901, the section titled "Generics in Packages" for details and a code sample. Need to make sure the source code properties are set up for VHDL-2008, as explained elsewhere in the same document.

Related

Creating VHDL Multiplexer with variable width and number of inputs

I am trying to create a bus/dataflow multiplexer with variable width and number of inputs, and use it as an IP Module in block design with Vivado. So far I have successfully managed to create a 2to1 mux with variable width:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity mux is
Generic ( NUM_BITS : integer);
Port (
SEL : in STD_LOGIC;
A : in STD_LOGIC_VECTOR(NUM_BITS-1 downto 0);
B : in STD_LOGIC_VECTOR(NUM_BITS-1 downto 0);
X : out STD_LOGIC_VECTOR(NUM_BITS-1 downto 0));
end mux;
architecture Behavioral of mux is
begin
X <= A when (SEL = '0') else B;
end Behavioral;
This works. I am able to drop this into the Block Design tool in Vivado, and I am able to customize the block and change the value of "NUM_BITS".
Customizable IP Mux in Block Design
I have almost successfully created a variable input mux with fixed width:
use IEEE.STD_LOGIC_1164.ALL;
package my_pkg is
-- Generic ( NUM_BITS : integer);
type inputs is array(natural range<>) of STD_LOGIC_VECTOR(8 downto 0);
end my_pkg;
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL;
use work.my_pkg.all;
entity mux is
Generic ( SEL_WIDTH : integer);
Port (
SEL : in STD_LOGIC_VECTOR(SEL_WIDTH-1 downto 0);
INPUT : in inputs(0 downto 2**SEL_WIDTH-1);
OUTPUT : out STD_LOGIC_VECTOR(8 downto 0));
end mux;
architecture Behavioral of mux is
begin
OUTPUT <= INPUT(to_integer(unsigned(SEL)));
end Behavioral;
However, I am not able to drop this into the block design tool because port type needs to be std_logic_vector in order to be recognized by the block design tool.
Block Design Error
I have seen some other posts addressing similar issues:
Using array of std_logic_vector as a port type, with both ranges using a generic - unable to use the provided examples in block design tool
Use generic parameter as port array length - used this to create the code in second portion
But neither of these helped me achieve what I would like.
I would like to combine these two into one multiplexer with BOTH variable inputs and width.
I am using Xilinx Vivado 2020.1

Passing generic to generic package to set port in VHDL

I’m looking at a generic package example in eda playground (https://www.edaplayground.com/x/6Mpm) and I’m trying to do something similar. I’m trying to get an integer from the top level through the generic field in the entity, and then pass the generic value on to the generic package to set the size of a part of a record. This record type is then to be used in the port of the entity where the generic came from.
Is this possible or do I have to hard code the number in the package declaration as in the example? Trying to declare the package in the entity gives me error proclaiming that the port can’t see the record type. Declaring the package normally as in the example mean that the package can’t see the generics in the entity.
I have been meaning to use a constant package to circumvent the “problem”, but I’m wondering if it is possible to do this using generics and a generic package without hard coding the numbers. This is so that I don’t have to remember to change the constant package when I’m reusing the module.
Package:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- pps_control_generic_pkg
package pps_control_generic_pkg is
generic(
-- Size of register. Max 32. Default 32
g_reg_size : integer := 32
);
type t_apb3_pif2core is record
rw_config : std_logic_vector(g_register_size-1 downto 0);
rw_config_we : std_logic;
end record;
type t_apb3_core2pif is record
rw_config : std_logic_vector(g_register_size-1 downto 0);
end record;
end package pps_control_generic_pkg;
Code
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- Trying to declare this correctly
-----------------------------------------------------------
package pps_control_pkg is new work.pps_control_generic_pkg
generic map(
g_reg_size => g_reg_size
);
use work.pps_control_pkg.all;
-----------------------------------------------------------
entity pps_control_core is
generic(
-- Size of register. Default 32
g_register_size : integer := 32;
);
port(
csi_sys_clk : in std_logic;
rsi_sys_reset : in std_logic;
-- Interface to access register
p2c : in t_apb3_pif2core;
c2p : out t_apb3_core2pif;
pps_in : in std_logic;
pps_out : out std_logic;
pps_en_n : out std_logic
);
end entity;
architecture rtl of pps_control_core is
...
begin
...
end rtl;
An unconstrained composite element of a record type provided with a record constraint works. Credit goes to Tricky for mentioning the solution and user1155120 for typing it out.
library ieee;
use ieee.std_logic_1164.all;
package pps_control_generic_pkg is
type t_apb3_pif2core is record
rw_config : std_logic_vector;
rw_config_we : std_logic;
end record;
type t_apb3_core2pif is record
rw_config : std_logic_vector;
end record;
end package pps_control_generic_pkg;
library ieee;
use ieee.std_logic_1164.all;
use work.pps_control_pkg.all;
entity pps_control_core is
generic(
g_register_size : integer := 32;
);
port(
csi_sys_clk : in std_logic;
rsi_sys_reset : in std_logic;
p2c : in t_apb3_pif2core
(arw_config(g_register_size-1 downto 0));
c2p : out t_apb3_core2pif
(aro_config(g_register_size-1 downto 0));
pps_in : in std_logic; --! External pps signal
pps_out : out std_logic; --! Outputted pulse
pps_en_n : out std_logic --! Enable pps signal to instrument
);
end entity;

VHDL Error when converting std_logic_vector into unsigned integer

I want to convert a 16-bit std_logic_vector into an integer to use it in a process realising a Moore machine.
entity steuerung is
port (
Clk : in std_logic;
Reset : in std_logic;
AktPos : in std_logic_vector(15 downto 0);
Notaus : in std_logic;
Betrieb : in std_logic;
HPR : in std_logic;
HPL : in std_logic;
ESR : in std_logic;
ESL : in std_logic;
CntClr : out std_logic;
LedR : out std_logic;
LedG : out std_logic;
M_An : out std_logic;
M_Li : out std_logic;
M_Re : out std_logic;
State : out std_logic_vector(5 downto 0)
);
end steuerung;
architecture BEHAVE of steuerung is
begin
process (Reset, Clk, Notaus, Betrieb, AktPos, ESR, ESL) is
type zustand is (steht, links, rechts, neuUnten, neuOben, alarm);
variable zustands_vektor : zustand;
variable ausgabe_vektor : std_logic_vector(5 downto 0);
variable cnt : integer range 0 to 65535 := conv_integer(unsigned(AktPos));
But I'm getting a few errors concerning the last line of code.
The console tells me the following:
"no declaration for "unsigned"
no overloaded function found matching 'conv_integer'"
and also a few errors in the std_logic_arith library (which I definitely included, although not seen in the code)
What have I done wrong?
Your code and your question has many issues ... Here is a list of things to fix:
Use English identifiers for documentation reasons, so others then natives like me can read and understand your question and your code. Moreover you are mixing Germany and English identifiers in the same file.
Add the full code, so we can see the surrounding context. It's needed to investigate and explain your mistakes.
std_logic_arith is a package, not a library. IEEE would be a VHDL library.
Don't use package std_logic_arith. use package numeric_std instead.
When using package numeric_std, an unsigned value is converted to integer with to_integer:
cnt := to_integer(unsigned(AktPos));
The signals: Reset, Notaus, Betrieb, AktPos, ESR, and ESL don't belong to the sensitivity list of a clocked process.
The initial value assignment for your variable is executed only once. Probably, this isn't what you want to achieve, right?
Type zustand is an enumeration type. Thus, the variable zustands_vektor uses wrong naming for an object containing a scalar discrete value. A vector is an array.
In general, using variables in VHDL is nothing for starters. Most likely, you want to use signals. VHDL is a hardware description language not a programming language, where you use variables for daily problem solving.

Quartus Prime VHDL component instantiation compile error

I am having an issue when trying to compile the following code:
----------------
----------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity adder_top is
Port ( a_in : in STD_LOGIC_VECTOR (3 downto 0);
b_in : in STD_LOGIC_VECTOR (3 downto 0);
clk : in STD_LOGIC;
clk_en : in STD_LOGIC;
carry_in : in STD_LOGIC;
carry_out : out STD_LOGIC;
c_out : out STD_LOGIC_VECTOR (3 downto 0));
end adder_top;
architecture Behavioral of adder_top is
COMPONENT c_addsub_0
PORT (
A : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
CLK : IN STD_LOGIC;
C_IN : IN STD_LOGIC;
CE : IN STD_LOGIC;
C_OUT : OUT STD_LOGIC;
S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT c_addsub_0;
begin
inst_1 : COMPONENT c_addsub_0
port map
(
A => a_in,
B => b_in,
CLK => clk,
C_IN => carry_in,
CE => clk_en,
C_OUT => carry_out,
S => c_out
);
end Behavioral;
---------------------------
---------------------------
I receive the following error code when trying to compile:
Error (12006): Node instance "inst_1" instantiates undefined entity
"c_addsub_0". Ensure that required library paths are specified
correctly, define the specified entity, or change the instantiation.
If this entity represents Intel FPGA or third-party IP, generate the
synthesis files for the IP.
I am entirely unsure why I am receiving this error. Any help would be greatly appreciated.
The synthesis tool (Quartus) used to analyze and elaborate (a.k.a. compile) your design is complaining that it has not found an entity to bind the component c_addsub_0 with. You need to point the tool, in a tool defined way, to a library that contains the desired entity.
If you intended c_addsub_0 to be a block that you created then maybe it did not analyze into the work library as expected (unexpected syntax errors), or the library path to the work library is not established correctly (unlikely for a synthesis tool). If you wrote c_addsub_0 then it may be easier to use direct entity instantiation -- it saves the hassle of writing the component declaration and keep it in sync with the instance and the entity in another file. For example:
inst_1 : ENTITY work.c_addsub_0(<arch_name>)
port map
(
A => a_in,
B => b_in,
CLK => clk,
C_IN => carry_in,
CE => clk_en,
C_OUT => carry_out,
S => c_out
);
If the c_addsub_0 block is meant to be unbound through elaboration, as a black box until place-and-route, then you need to tell Quartus by decorating the instance with the appropriate syn_black_box attribute.
architecture Behavioral of adder_top is
COMPONENT c_addsub_0
PORT (
A : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
B : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
CLK : IN STD_LOGIC;
C_IN : IN STD_LOGIC;
CE : IN STD_LOGIC;
C_OUT : OUT STD_LOGIC;
S : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT c_addsub_0;
attribute syn_black_box : boolean;
attribute syn_black_box of c_addsub_0: component is true;
begin
...
It then knows to synthesize a black box representation in the post synthesis netlist for that component. You then need to insure the Quartus back end can find a netlist for the given component in a netlist library path somewhere.
VHDL provides for a variety of ways to create hierarchy with incredibly precise control over binding, signal connections, naming/renaming of blocks and other features which are rarely used in ordinary designs. Unless your synthesis tool only supports one style of instantiation using component declarations or you need a black box, then I would stick with direct entity instantiation.
P.S.: Your use clause use ieee.std_logic_unsigned; should be use synopsys.std_logic_unsigned; -- The IEEE standards body never approved the std_logic_unsigned package. Though, if analyzing with the 1076-2008 standard, it is allowed now to analyze anything you want into the IEEE library. That permits defacto vendor, but not formally standardized, packages to be used without modification of your source code. Only the STD library is now actually a standard. Just be aware that Mentor Graphics and Synopsys versions of this package are different so your code may not achieve the portability that use of the standards based numeric_std package will achieve.

Vivado 2016.3 unconstrained array of record with unconstrained std_logic_vector

I am experimenting to synthesise some VHDL 2008 code in Vivado 2016.3 (the same situation is in 2016.4)
The idea is to be able to have unconstrained array in record and at the same time have unconstrained array of these records.
Relevant code:
(axi_pkg.vhd)
-- axi_pkg.vhd
-- Author: Bruno Kremel (CERN BE-RF-FB)
-- Date: 2016-01-23
-- Description: AXI4 Package
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.misc_pkg.all;
package axi_pkg is
type axis_in is record
tdata : std_logic_vector;
tvalid : std_logic;
tlast : std_logic;
tuser : std_logic_vector;
end record;
type axis_out is record
tready : std_logic;
end record;
type axis_in_vector is array (natural range <>) of axis_in;
type axis_out_vector is array (natural range <>) of axis_out;
end package;
(axis_reg.vhd)
-- axis_reg.vhd
-- Author: Bruno Kremel (CERN BE-RF-FB)
-- Date: 2016-11-22
-- Description: AXI4 Stream register
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.misc_pkg.all;
use work.axi_pkg.all;
entity axis_reg is
generic (
DATA_TYPE : string := "signed"
);
port (
aresetn : in std_logic;
aclk : in std_logic;
-- Input stream
in_axis_in : in axis_in;
in_axis_out : out axis_out;
-- Output stream
out_axis_in : out axis_in;
out_axis_out : in axis_out
);
end entity axis_reg;
architecture basic of axis_reg is
constant OUT_DATA_W :natural := out_axis_in.tdata'length;
constant IN_DATA_W :natural := in_axis_in.tdata'length;
signal in_tdata_conv : std_logic_vector(OUT_DATA_W-1 downto 0);
signal in_tuser_conv : std_logic_vector(OUT_DATA_W/8-1 downto 0);
signal in_tdata_shd : std_logic_vector(IN_DATA_W-1 downto 0);
signal in_tuser_shd : std_logic_vector(IN_DATA_W/8-1 downto 0);
begin
gen_signed: if DATA_TYPE = "signed" generate
in_tdata_conv <= std_logic_vector(resize(signed(in_tdata_shd), OUT_DATA_W));
in_tuser_conv <= std_logic_vector(resize(signed(in_tuser_shd), OUT_DATA_W/8));
end generate;
gen_unsigned: if DATA_TYPE = "unsigned" generate
in_tdata_conv <= std_logic_vector(resize(unsigned(in_tdata_shd), OUT_DATA_W));
in_tuser_conv <= std_logic_vector(resize(unsigned(in_tuser_shd), OUT_DATA_W/8));
end generate;
reg_ctrl_inst : entity work.axis_reg_ctrl
port map (
aresetn => aresetn,
aclk => aclk,
next_tdata => in_tdata_conv,
next_tuser => in_tuser_conv,
next_update => open,
in_tvalid => in_axis_in.tvalid,
in_tready => in_axis_out.tready,
in_tlast => in_axis_in.tlast,
out_tdata => out_axis_in.tdata,
out_tvalid => out_axis_in.tvalid,
out_tready => out_axis_out.tready,
out_tlast => out_axis_in.tlast,
out_tuser => out_axis_in.tuser
);
end architecture;
(test_entity.vhd)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi_pkg.all;
entity test_entity is
port (
aresetn : std_logic;
aclk : std_logic;
-- Input stream
in_axis_in : in axis_in_vector;
in_axis_out : out axis_out_vector;
-- Output stream
out_axis_in : out axis_in_vector;
out_axis_out : in axis_out_vector
);
end entity;
architecture test of test_entity is
begin
gen_reg : for i in 0 to in_axis_in'length-1 generate
begin
reg_i : entity work.axis_reg
generic map (
DATA_TYPE => "signed"
)
port map (aresetn => aresetn,
aclk => aclk,
in_axis_in => in_axis_in(i),
in_axis_out => in_axis_out(i),
out_axis_in => out_axis_in(i),
out_axis_out => out_axis_out(i));
end generate;
end architecture;
And finally test_entity_top.vhd which basically constraints the sizes for synthesis:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi_pkg.all;
entity test_entity_top is
end entity;
architecture test of test_entity_top is
constant SIZE : natural := 10;
constant DATA_W : natural := 16;
signal test_axis_in : axis_in(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
signal test_axis_out : axis_out;
signal in_axis_in : axis_in_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
signal in_axis_out : axis_out_vector(SIZE-1 downto 0);
signal out_axis_in : axis_in_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
signal out_axis_out : axis_out_vector(SIZE-1 downto 0);
signal aresetn : std_logic;
signal aclk : std_logic;
begin
tst : entity work.test_entity
port map (aresetn => aresetn,
aclk => aclk,
in_axis_in => in_axis_in,
in_axis_out => in_axis_out,
out_axis_in => out_axis_in,
out_axis_out => out_axis_out
);
end architecture;
This all nicely compiles in ModelSim. But Vivado is reluctant to sythesise it... With this error:
ERROR: [Synth 8-2190] illegal syntax for subtype indication [/home/bkremel/test_vivado/test_entity_top.vhd:15]
ERROR: [Synth 8-2235] indexed name prefix type axis_in_vector expects 1 dimensions [/home/bkremel/test_vivado/test_entity_top.vhd:15]
ERROR: [Synth 8-2190] illegal syntax for subtype indication [/home/bkremel/test_vivado/test_entity_top.vhd:18]
ERROR: [Synth 8-2235] indexed name prefix type axis_in_vector expects 1 dimensions [/home/bkremel/test_vivado/test_entity_top.vhd:18]
ERROR: [Synth 8-1031] in_axis_in is not declared [/home/bkremel/test_vivado/test_entity_top.vhd:28]
ERROR: [Synth 8-1031] out_axis_in is not declared [/home/bkremel/test_vivado/test_entity_top.vhd:30]
ERROR: [Synth 8-1568] actual of formal out port out_axis_in cannot be an expression [/home/bkremel/test_vivado/test_entity_top.vhd:30]
INFO: [Synth 8-2810] unit test ignored due to previous errors [/home/bkremel/test_vivado/test_entity_top.vhd:9]
Which indicate it does actually accept the syntax of record constraint:
signal test_axis_in : axis_in(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
While it does not like:
signal in_axis_in : axis_in_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
What would you suggest to use intead of unconstrained arrays and records?
The thing is that my design quite often changes the bit size of the stream.. So using generic packages would be quite inelegant (especially this register is nice example when in one file you have the bus with different sizes of data bus)
So far I have used one dimensional slv without records with manual indexing using functions/procedures, but that is quite messy to maintain...
I also add edaplayground example of relevant code https://www.edaplayground.com/x/eiC (to demonstrate that it works in simulator)...
Edit:
What is interesting is, that it actually synthesise if I do following:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi_pkg.all;
entity test_entity_top is
end entity;
architecture test of test_entity_top is
constant SIZE : natural := 4;
constant DATA_W : natural := 16;
subtype axis_in_constr is axis_in(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
subtype axis_out_constr is axis_out;
signal ch0, ch1, ch2, ch3 : axis_in_constr;
signal out0, out1, out2, out3 : axis_in_constr;
signal in_axis_in : axis_in_vector := (ch0, ch1, ch2, ch3);
signal out_axis_in : axis_in_vector := (out0, out1, out2, out3);
signal in_axis_out : axis_out_vector(SIZE-1 downto 0);
signal out_axis_out : axis_out_vector(SIZE-1 downto 0);
signal aresetn : std_logic;
signal aclk : std_logic;
begin
tst : entity work.test_entity
port map (aresetn => aresetn,
aclk => aclk,
in_axis_in => in_axis_in,
in_axis_out => in_axis_out,
out_axis_in => out_axis_in,
out_axis_out => out_axis_out
);
end architecture;
So that means that the array of records with unconstrained array is actually supported, but the direct constraint syntax is not.
Any ideas how to define it less elaboratively? Although it's not big deal to define top-level like this.. Still I would not mind to avoid it, it looks a bit hacky...
Thanks
Bruno
With Xilinx SR we had come to working example of desired behaviour, so I post it here as it works in Vivado as well as ModelSim/Edaplayground.
-- axi_pkg.vhd
-- Author: Bruno Kremel (CERN BE-RF-FB)
-- Date: 2016-01-23
-- Description: AXI4 Package
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package axi_pkg is
type axis_downstream is record
tdata : std_logic_vector;
tvalid : std_logic;
tlast : std_logic;
tuser : std_logic_vector;
end record;
type axis_upstream is record
tready : std_logic;
end record;
type axis_downstream_vector is array (natural range <>) of axis_downstream;
type axis_upstream_vector is array (natural range <>) of axis_upstream;
end package;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.axi_pkg.all;
entity test_entity_top is
end entity;
architecture test of test_entity_top is
constant SIZE : natural := 4;
constant DATA_W : natural := 16;
signal axis_downstream : axis_downstream_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0),
tuser(DATA_W/8-1 downto 0));
signal axis_upstream : axis_upstream_vector(SIZE-1 downto 0);
begin
assert axis_downstream'length = SIZE
report "SIZE is not correct"
severity failure;
assert axis_downstream(0).tdata'length = DATA_W
report "TDATA width is not correct"
severity failure;
assert axis_downstream(0).tuser'length = (DATA_W/8)
report "TUSER width is not correct"
severity failure;
end architecture;
The problem is that not all files were marked as 2008 in Vivado (my fault). But I post this minimal example so that it nicely fit the question.
Also Edaplayground link: https://www.edaplayground.com/x/3sKr

Resources