Forum Discussion
Altera_Forum
Honored Contributor
10 years agodwh:
Good suggestion. Before you got back, I found a way that worked, but it was way more complicated. I used an array for each generic entry, and used an 'index' generic to select which item of all the other ones. Each generic was stored in the package, in an array of integers. I though I had something functional, I found several forums externally claiming it was not possible. Your version is way more usable. Here's what I have so far... The Generics...
use work.mem_init_config.all;
entity mem is
generic(
--hardware
mem_bit_size : integer := 2**17;--131072 bits
mem_byte_width : integer := 8;
mem_init : std_logic_vector := mem_init_func(0, 2**17, 8)--must match last 2 arguments with last above 2 generics
--the first is an 'index', selecting wich initialization used in the package
);
The function in the mem_init_config package body...
function mem_init_func(
index : in integer;
mem_bit_size : in integer;
mem_byte_width : in integer
) return std_logic_vector is
type mem_t is array(mem_bit_size / mem_byte_width - 1 downto 0) of std_logic_vector(mem_byte_width - 1 downto 0);
variable mem_contents : mem_t;
variable mem_word : std_logic_vector(mem_byte_width - 1 downto 0);
variable mem_vector : std_logic_vector(mem_bit_size - 1 downto 0);
begin
case index is
when 0 =>
mem_contents := (others => (others => '0'));
--return mem0_contents;
when 1 =>
mem_contents := (others => (others => '1'));
--return mem1_contents;
when 2 =>
mem_word := (others => '0');
for i in 0 to mem_bit_size / mem_byte_width - 1 loop
mem_contents(i) := mem_word;
mem_word := std_logic_vector(unsigned(mem_word) + 1);
end loop;
--return mem_contents;
when others =>--last one
mem_word := (others => '0');
for i in 0 to mem_bit_size / mem_byte_width - 1 loop
mem_contents(i) := mem_word;
mem_word := std_logic_vector(unsigned(mem_word) + 1);
end loop;
--return mem_contents;
end case;
--convert byte format to vector version
for i in 0 to mem_bit_size / mem_byte_width - 1 loop
for j in 0 to mem_byte_width - 1 loop
mem_vector(i * mem_byte_width + j) := mem_contents(i)(j);
end loop;
end loop;
return mem_vector;
end function;
I used an all '1' bits, all '0' bits, count up bytes, and count down bytes for simulation. I had to convert it to a std_logic_vector in the function so the last generic would accept it, and convert it back to the memory format in the memory .vhd file, so I wouldn't have define the mem_t type in the package and pass it on to the entity, keep in mind the mem_t type is different depending of the other generic settings. The single entity generates the 131072 bits (55% of my FPGA, can't make more). I have tested it in a higher level entity making 4 different sized and I have some strange errors reaching 16384 bits on one of them so I have some homework. I also have to make sure it can run as a symbol on the block_diagram/schematic. Thank you for the good information, now I know it's possible. David K.