# VHDL: A function to determine array length

SOLVED!!! I'll leeave the questions, see below for the solution.

In a VHDL project, I want to initialized an array that have a certain dimension, and I want this dimension is derived by a function. Here is a minimal implementation that show what I want to do:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

use work.arrayout_type.all;

entity minimal is
Port (
a : in std_logic;
b : out std_logic
);
end minimal;

architecture Behavioral of minimal is
variable dimension : integer;
type array_intern is array (dimension-1 downto 0) of std_logic_vector(M+N-1 downto 0);

begin

end Behavioral;


Here is the package (I edited the message and I included the two separate package in a unique package) :

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

package arrayout_type is
constant N : integer := 8; -- first member is N bit long
constant M : integer :=4; -- second member is M bit long
-- declaration of a TYPE of an array of M element, each element is a signal that is the output of the M shifters and the M-1 adders
type array_out is array (M-1 downto 0) of std_logic_vector(M+N-1 downto 0);

end arrayout_type;

package body arrayout_type is
-- calcluate the number of internal signal for the adders. Function body.
function calc_adder_length (x : integer) return integer is
variable number : integer;
variable accumulator : integer;
begin
number := x;
accumulator :=x;
while(number > 1) loop
if(number mod 2 /= 0) then
number := number/2+1;
else
number := number/2;
end if;
accumulator := accumulator + number;
end loop;
accumulator := accumulator +1; -- finalization.
return accumulator;

end arrayout_type;


The problem is, of course, that I cannot call the program in the architecture body before the "begin". But at the same time I cannot declare the array_intern in the architeture after the "begin". So I don't know how to do.

• How can you tell that "none of them worked". What was the error, what did you expect? – andrsmllr Apr 13 '16 at 10:04
• Both arguments to the function (actuals for formals M,N) must be known when the design is elaborated at the latest. They cannot be determined at run time. But you haven't given us enough to tell fi that's what you're trynig to do. Add a MCVE to your question... – Brian Drummond Apr 13 '16 at 11:32
• Ok, I edited with MCVE, hope now is better. I collapsed the two package in a unique package; to avoid confusion, the becuase the "M" is used 2 times for different purpouses, I renamed the "M" inside the function as "x". During the modification I noticed that I dind't use the "N" inside the function, so I dropped it. – Daniele Apr 13 '16 at 13:11
• sorry for the double post. Brian, I think that what I want to do is not performed at run time. Because I set the value of "M", so automaticly I set the value of "dimension", trough the function. M is a costant, so even dimension is a costant. If I can create the array with M, I should be able to create the array with dimension. – Daniele Apr 13 '16 at 13:24
• If you want to answer your own question, you can do this by posting a separate answer instead of including the solution in the question. – Martin Zabel Apr 13 '16 at 15:57

SOLUTION: I found the solution to my problem in this another question: https://stackoverflow.com/questions/20072851/how-to-use-a-constant-calculated-from-generic-parameter-in-a-port-declaration-in

So, applying the solution to my code, the "minimal.vhd" become :

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

use work.arrayout_type.all;

entity minimal is
Port (
a : in std_logic;
b : out std_logic
);
end minimal;

architecture Behavioral of minimal is
type array_intern is array (calc_adder_length(M)-1 downto 0) of std_logic_vector(M+N-1 downto 0);

begin

end Behavioral;


That is syntetizable.

Hope it can be usefull for someone, and thanks to the author of the solution in the linked question