Closed MartinC45 closed 5 months ago
The generated code of the entity uses the types t_array_elem0 / t_array_elem1/t_array_elem2, which do not exist in the associated package.
Yeah, it's a known issue, but was held up to find a solution for embedded generics parameters, especially in ports. The main issue arises if we have an embedded generic that sets an array's element length on a port. VHDL has a limitation that does not enable us to compile it as easily as Verilog does:
class Foo(arg: Int <> CONST) extends RTDesign:
val x = UInt(arg) X 8 <> IN
It's illegal in VHDL to do array(0 to 7) of unsigned(arg-1 downto 0)
, so not sure what's the best course of action here. I could just inline the parameters for VHDL. It hurts the generality of it, but that's a VHDL limitation 🤷
I am also wondering what multidimensional arrays would look like. Either type
is array (natural range <>, natural range <>, ...) of and indexed as e.g. arr(0, 0, ...)
Multi-dimentional arrays in DFHDL would look like val x = UInt(8) X (5,5,5) <> VAR
x(0,0,0)
. The Scala type representation of it actually already exists, but nothing in the frontend API. It's currently on the backburner since usually it's just as fine to write UInt(8) X 5 X 5 X 5
.
It's illegal in VHDL to do
array(0 to 7) of unsigned(arg-1 downto 0)
, so not sure what's the best course of action here. I could just inline the parameters for VHDL. It hurts the generality of it, but that's a VHDL limitation 🤷
In VHDL2008, it should be working (1). So the problem is VHDL93 really, where arrays (and everything else) can only be constrained at the outermost level. While it might be possible to have a workaround in some cases, like flattening an array of std_logic_vectors (e.g. std_logic_vector(width * depth - 1 downto 0)), I'd argue it probably is best, to define the generics in the package and constrain things there (2). I think that doing so also aligns with the expectations of someone using VHDL93. The generic constraining the outermost level, e.g. widthArr in (1), could be kept in the entity (3).
What do you think?
(1)
-- package
library ieee;
use ieee.std_logic_1164.all;
package array_port_package is
type t_array is array(natural range <>) of std_logic_vector;
end package;
-- entity
entity array_port is
generic (
widthSLV : integer := 32;
widthArr : integer := 8
);
port (
arrP : in t_array(0 to widthArr - 1)(widthSLV-1 downto 0);
out_a : out std_logic
);
end entity;
(2)
library ieee;
use ieee.std_logic_1164.all;
package array_port_package is
constant instancename_entityname_genericname : integer := 32;
type t_array_etc is array (natural range 0 to instancename_entityname_genericname) of std_logic_vector(instancename_entityname_genericname-1 downto 0);
end package;
(3)
-- package
library ieee;
use ieee.std_logic_1164.all;
package array_port_package is
constant array_port_widthSLV : integer := 32;
type t_array is array(natural range <>) of std_logic_vector(widthSLV-1 downto 0);
end package;
-- entity
entity array_port is
generic (
widthArr : integer := 8
);
port (
arrP : in t_array(0 to widthArr - 1);
out_a : out std_logic
);
end entity;
Description
The generated code of the entity uses the types t_array_elem0 / t_array_elem1/t_array_elem2, which do not exist in the associated package.
I am also wondering what multidimensional arrays would look like. Either
type \<name> is array (natural range \<>, natural range \<>, ...) of \<element_type> and indexed as e.g. arr(0, 0, ...) or type \<name1> is array (natural range \<>) of \<element_type> type \<name2> is array (natural range \<>) of \<name1>
and indexed as e.g. arr(0)(0)...
Example
Output
If c and d are indexed as in the VHDL code it would require the latter variant of multidimensional arrays above.