Here is a code from VUnit Avalon Master BFM:
entity avalon_master is
generic (
bus_handle : bus_master_t;
use_readdatavalid : boolean := true;
fixed_read_latency : natural := 1; -- (bus cycles). This parameter is ignored when use_readdatavalid is true
write_high_probability : real range 0.0 to 1.0 := 1.0;
read_high_probability : real range 0.0 to 1.0 := 1.0
);
port (
clk : in std_logic;
address : out std_logic_vector;
byteenable : out std_logic_vector;
burstcount : out std_logic_vector;
waitrequest : in std_logic;
write : out std_logic;
writedata : out std_logic_vector;
read : out std_logic;
readdata : in std_logic_vector;
readdatavalid : in std_logic
);
end entity;
There are so many ports that just say std_logic_vector without giving any bounds. This is obviously only for use in simulation actually. How is this even valid VHDL?
-
\$\begingroup\$ Which version of VHDL? 2008 and newer add capabilities that earlier versions didn't have. \$\endgroup\$user16324– user163242022年06月07日 12:39:51 +00:00Commented Jun 7, 2022 at 12:39
-
\$\begingroup\$ I am not sure but this could be VHDL 2008. It is code from the VUnit testing framework. \$\endgroup\$gyuunyuu– gyuunyuu2022年06月07日 13:15:29 +00:00Commented Jun 7, 2022 at 13:15
-
2\$\begingroup\$ Yes for all revisions of VHDL. It is similar to subprograms in this way. However, your synthesis tools may or may not like this. So I primarily use it for verification. Good news with Vivado below, however, I would still be cautious with synthesis code. \$\endgroup\$Jim Lewis– Jim Lewis2022年06月07日 13:57:30 +00:00Commented Jun 7, 2022 at 13:57
-
\$\begingroup\$ Thanks Jim, this is code for a BFM. \$\endgroup\$gyuunyuu– gyuunyuu2022年06月07日 18:41:04 +00:00Commented Jun 7, 2022 at 18:41
1 Answer 1
This unconstrained declaration is valid, but it depends on another definition outside this module. Note that no "generic" declaration is required for this simple D Flip-Flop example:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity uncon_dff is
Port ( d : in STD_LOGIC_VECTOR;
clk, rst : in STD_LOGIC;
q : out STD_LOGIC_VECTOR);
end uncon_dff;
architecture Behavioral of uncon_dff is
begin
process (clk, rst)
begin
if (rst = '1') then
q <= (others => '0');
elsif rising_edge(clk) then
q <= d;
end if;
end process;
end Behavioral;
The top level design defines the ranges of the vectors at the instantiation (from the local signals/inputs/outputs):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity top_dff is
Port ( d : in STD_LOGIC_VECTOR (7 downto 0);
clk, rst : in STD_LOGIC;
q : out STD_LOGIC_VECTOR (7 downto 0));
end top_dff;
architecture Behavioral of top_dff is
component uncon_dff is -- no range here (unconstrained)
Port ( d : in STD_LOGIC_VECTOR;
clk, rst : in STD_LOGIC;
q : out STD_LOGIC_VECTOR);
end component;
begin
dff : uncon_dff port map ( -- ranges inherited
d => d, clk => clk, rst => rst, q => q
);
end Behavioral;
Which generates the expected logic:
This was tested on Vivado using VHDL 2008. If the top level design mistakenly defines different ranges for 'd' and 'q', the synthesis fails:
[Synth 8-690] width mismatch in assignment; target has 9 bits, source has 8 bits ["/dev/shm/project_1/project_1.srcs/sources_1/new/uncon_dff.vhd":18]