Search code examples
vhdlramxilinxvivado

Dynamic Arrray Size in VHDL


I want to use dynamic range of array , so using "N" for converting an incoming vector signal to integer. Using the specifc incoming port "Size" gives me an error, while fixed vector produces perfect output.

architecture EXAMPLE of Computation is

signal size :std_logic_vector (7 downto 0);

process (ACLK, SLAVE_ARESETN) is

variable N: integer:=conv_integer  ("00000111") ;  ---WORKING

--variable N: integer:=conv_integer  (size) ; -- Not working
type memory is array (N downto 0 ) of std_logic_vector (31 downto 0 ); 

variable RAM :memory; 

Only reason to do this type of coding is send as much data as possible to FPGA .As I need to send Data from DDR to Custom IP via DMA in vivado may be more than 100 MB. so kindly guide me if I am trying to implement in wrong way as stated above.


Solution

  • You can't do that in VHDL. What kind of hardware would be generated by your code? If you don't know, the synthesizer won't either.

    The way to do this kind of thing is to set N to the largest value you want to support, and use size in your logic to control your logic appropriately. It's difficult to give more pointers without more information, but as an example, you could use a counter to address your ram, and have it reset when it's greater than size.

    Update

    Here's a counter example. You have to make sure that size doesn't change while operating or it will fall into an unknown state. A real design should have reset states to ensure correct behaviour.

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    
    entity example is
    port (
        clk : std_logic;
        rst : in std_logic;
        size : in unsigned(7 downto 0);
        wr : in std_logic;
        din : in std_logic_vector(31 downto 0)
    );
    end entity;
    
    architecture rtl of example is
        signal counter : unsigned(7 downto 0);
    
        type ram_t is array(0 to 255) of std_logic_vector(31 downto 0);
        signal ram : ram_t;
    begin
    
        RAM_WR: process(clk)
        begin
            if rising_edge(clk) then
                if rst = '1' then
                    counter <= (others => '0');
                else
                    if wr = '1' then
                        ram(to_integer(counter)) <= din;
    
                        if counter = size then
                            counter <= (others => '0');
                        else
                            counter <= counter + 1;
                        end if;
                    end if;
                end if;
            end if;
        end process RAM_WR;
    
    end architecture rtl;