0
votes

Ok, so I have a problem with a ROM initialization function. Before I get into the problem let me explain a bit the nature of my problem and my code.

What I want to do is generate N number of ROMs which I have to use as an input for a module that runs a matching algorithm. My problem is that I have a file with my signatures (let's say 64 in total) which I want to load in my different ROMs depending on how many I've generated (powers of 2 in my case, e.g. 8 roms of 8 signatures each).

I figured the best way to do it is load the whole text file into an array (using a function outside of the architecture body) which I will then use (again in a function) to load the data into a smaller array which will then be my ROM.

It seemed to me that the synthesizer would then just ignore the big array since I don't actually use it in my architecture.

Problem now is that since the second array input arguments are signal dependent, the synthesizer just ignores them and ties my array to zero (line 57).

Does anyone know how else if there's a way to make this architecture synthesize-able?

library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_signed.all;
use std.textio.all;

entity signatures_rom_partial is 

generic(
        data_width : integer := 160;
        cycle_int  : integer :=32;
        rom_size   : integer := 4
        );

    port (  clk : in std_logic;
            reset : in std_logic;
            readlne: in integer range 0 to cycle_int-1;                     -- user input for array data initialization
            address: in integer range 0 to rom_size-1;                      -- address for data read
            data: out std_logic_vector(data_width-1 downto 0)               -- data output
         );
end signatures_rom_partial;

architecture rom_arch of signatures_rom_partial is

type rom_type is array (0 to cycle_int-1) of bit_vector (data_width-1 downto 0);            -- big array for all signatures, not used in arch
type test_type is array (0 to rom_size-1) of std_logic_vector (data_width-1 downto 0);      -- smaller ROMs used in arch

--Read from file function--
----------------------------------------------------------------------------------------------------------  
impure function InitRomFromFile (RomFileName : in string) return rom_type is                            --
    file RomFile : text is in RomFileName;                                                              --
    variable RomFileLine : line;                                                                        --
    variable rom : rom_type;                                                                            --
                                                                                                        --
begin                                                                                                   --
    for i in rom_type'range loop                                                                        --
        readline (RomFile, RomFileLine);                                                                --
        read (RomFileLine, rom(i));                                                                     --
    end loop;                                                                                           --
    return rom;                                                                                         --
end function;                                                                                           --
----------------------------------------------------------------------------------------------------------

--Function for smaller ROM initialization--
----------------------------------------------------------------------------------------------------------
impure function initPartRom (rom : rom_type; readlne : integer) return test_type is                     --
    variable test_array : test_type;                                                                    --
                                                                                                        --
begin                                                                                                   --
    for j in test_type'range loop                                                                       --
        test_array(j) := to_stdlogicvector(rom(j+readlne));                                             --
    end loop;                                                                                           --
    return test_array;                                                                                  --
end function;                                                                                           --
----------------------------------------------------------------------------------------------------------

constant rom        : rom_type  := InitRomFromFile("signatures_input.txt");
signal test_array   : test_type := initPartRom(rom , readlne);                      --(LINE 57) SYNTHESIZER IGNORES THESE INPUT ARGUMENTS

begin

    process(clk,reset)
    begin
        if reset='1' then
            data<=(others=>'0');
        elsif (clk'event and clk='1') then
            data <= (test_array(address));
        end if;
    end process;

end rom_arch;

Synthesis is done using Xilinx ISE, simulation is done with Modelsim in which, my creation works fine :)

Thanks for any help!

1
I would convert your "signatures" into constant strings in a VHDL package ... or write a script to process the text file into the right format, if they are generated elsewhere.user_1818839
XST supports initializing RAM from VHDL file read and ROM (as a signal) is RAM that's not written. However that wouldn't get you a smaller read only memory as the initial array value extracted from another signal. Extracting the smaller 'ROM' values from the bigger ROM array requires index arithmetic (readlne + address) if both readlne and address are signals. That index arithmetic could impact the clock period. And that makes us think of a two dimensional index.user1155120

1 Answers

2
votes

With Xilinx ISE (14.7) it is possible to synthesize ROMs and RAMs even if the initial data is read from an external file by function.

The only requirement is, that the reading function must be computable at synthesis time. This is not true for your code because readlne is not static at the point the function is called. You should change it to a generic instead of an input and assign a different value to this generic for every other ROM instance. Then it should work as intended.

A sample implementation of how to read initialization data from a text file in (Xilinx) .mem format can be found in VHDL Library PoC in the namespace PoC.mem.ocrom or PoC.mem.ocram