user3822607
user3822607

Reputation: 69

Vhdl: unconstrained arrays and size instaniation

I am attempting to pass an array size ( integer ArraySize) from a Top-level file to a component, but get the error:

[Synth 8-561] range expression could not be resolved to a constant [/UnconArray.vhd":39]

I am wondering if there is a way to do this. Also, if a unconstrained array has to be defined as a constant, then what's the point?

UnconstrainedTest.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity UnconstrainedTest is
  Port ( clk  : in std_logic;
         reset: in std_logic;
         LED0 : out std_logic := '0';
         LED1 : out std_logic := '0'
        );

end UnconstrainedTest;

architecture Behavioral of UnconstrainedTest is

 component UnconArray is
 port( clk_1 : in std_logic; 
          ArraySize : in integer;
          LED_0 : out std_logic
      ); 

 end component;

begin

 A1: UnconArray port map (
                  clk_1 => clk,
                  ArraySize => 12,
                  LED_0 => LED0
                  );

 A2: UnconArray port map (
                  clk_1 => clk,
                  ArraySize => 8,
                  LED_0 => LED1
                  );
                  
end Behavioral;

The component UnconArray.vhd

begin

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;


entity UnconArray is

--  generic (depth : integer := 2);

  Port ( clk_1     : in std_logic;
         ArraySize : in integer;
         LED_0     : out std_logic
        );
end UnconArray;

architecture Behavioral of UnconArray is

 type Array_type is array (integer range <>) of integer;
 signal MyUnconArray : Array_type (0 to ArraySize);
-- type Array_type is array (0 to ArraySize) of integer;
-- signal MyUnconArray : Array_type;

begin

MyUnconArray <= (1, 2, 3); 

    process (clk_1)
      begin
       if rising_edge(clk_1) then   
          if ( MyUnconArray(0) = 1 )then
              LED_0 <= '1';
           else
              LED_0 <= '0';
           end if;
       end if;
    end process;


end Behavioral;

Upvotes: 0

Views: 5304

Answers (1)

johnfpga
johnfpga

Reputation: 56

You have to use a constant size for your arrays as you are writing a model of actual hardware in VHDL. The signal is like a wire on a circuit board - you can't add or remove them dynamically.

If you wanted to use this code you would have to use a generic (which is a local constant) to declare the size of the vector. You've actually already commented this out in your code but it should look this:

entity UnconArray is
    generic (
        depth : integer := 2
    );
    port ( 
        clk_1 : in std_logic;
        LED_0 : out std_logic
    );
end UnconArray;

architecture Behavioral of UnconArray is

    type Array_type is array (integer range <>) of integer;
    signal MyUnconArray : Array_type (0 to depth);

    ...

Then when you instantiate the component:

A1: UnconArray 
    generic map (
        depth => 2    
    )
    port map (
        clk_1 => clk,
        LED_0 => LED0
    );

However, if you don't set the depth generic to 3 you will get still get errors as you are treating it as a fixed size when you assign data. You also only use element 0 so the rest of the array will be removed during synthesis minimisation.

The point of unconstrained arrays is that you can set the size of them when declaring signals which potentially reduces the number of types you need to declare.

For example, suppose you wanted to use 2 different integer arrays in your code with a different number of elements in them. You can either declare 2 constrained array types with different sizes or 1 unconstrained array.

Upvotes: 2

Related Questions