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
    Commented 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
    Commented 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
    Commented Jun 7, 2022 at 13:57
  • \$\begingroup\$ Thanks Jim, this is code for a BFM. \$\endgroup\$
    – gyuunyuu
    Commented 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;

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
    process (clk, rst)
        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;

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;


    dff : uncon_dff port map ( -- ranges inherited
        d => d, clk => clk, rst => rst, q => q  

end Behavioral;

Which generates the expected logic:

enter image description here

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]


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.