Инициализация ПЗУ из массива с использованием функций Synthesis ERROR (VHDL)

Итак, у меня проблема с функцией инициализации ПЗУ. Прежде чем я перейду к проблеме, позвольте мне немного объяснить природу моей проблемы и моего кода.

Что я хочу сделать, так это сгенерировать N ПЗУ, которые я должен использовать в качестве входных данных для модуля, выполняющего алгоритм сопоставления. Моя проблема в том, что у меня есть файл с моими подписями (скажем, всего 64), который я хочу загрузить в свои разные ПЗУ в зависимости от того, сколько я сгенерировал (степени 2 в моем случае, например, 8 ромов по 8 подписей каждый ).

Я решил, что лучший способ сделать это - загрузить весь текстовый файл в массив (используя функцию вне тела архитектуры), которую я затем буду использовать (снова в функции) для загрузки данных в меньший массив, который затем будет мой ПЗУ.

Мне казалось, что тогда синтезатор просто проигнорирует большой массив, так как я фактически не использую его в своей архитектуре.

Теперь проблема в том, что, поскольку входные аргументы второго массива зависят от сигнала, синтезатор просто игнорирует их и привязывает мой массив к нулю (строка 57).

Кто-нибудь знает, как еще, если есть способ сделать эту архитектуру синтезируемой?

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;

Синтез выполняется с помощью Xilinx ISE, симуляция выполняется с помощью Modelsim, в котором мое творение работает нормально :)

Спасибо за любую помощь!


person Nailtha    schedule 20.11.2015    source источник
comment
Я бы преобразовал ваши подписи в постоянные строки в пакете VHDL... или написал скрипт для обработки текстового файла в нужный формат, если они генерируются где-то еще.   -  person user_1818839    schedule 20.11.2015
comment
XST поддерживает инициализацию ОЗУ из прочитанного файла VHDL, а ПЗУ (как сигнал) — это ОЗУ, которое не записывается. Однако это не даст вам меньше памяти только для чтения, поскольку начальное значение массива извлечено из другого сигнала. Извлечение меньших значений 'ROM' из большего массива ROM требует индексной арифметики (readlne + address), если и readlne, и адрес являются сигналами. Эта индексная арифметика может повлиять на тактовый период. И это заставляет нас думать о двумерном индексе.   -  person    schedule 21.11.2015


Ответы (1)


С Xilinx ISE (14.7) можно синтезировать ПЗУ и ОЗУ, даже если исходные данные считываются из внешнего файла функцией.

Единственное требование состоит в том, что функция чтения должна быть вычислимой во время синтеза. Это неверно для вашего кода, потому что readlne не является статическим в момент вызова функции. Вы должны изменить его на универсальный вместо ввода и присвоить этому общему значению другое значение для каждого другого экземпляра ПЗУ. Тогда он должен работать, как задумано.

Пример реализации чтения данных инициализации из текстового файла в формате (Xilinx) .mem можно найти в библиотеке VHDL. PoC в пространстве имен PoC.mem.ocrom или PoC.mem.ocram

person Martin Zabel    schedule 20.11.2015
comment
Спасибо за пояснение по поводу ISE, не совсем понял, как работает инициализация. Дело в том, что назначение другого значения универсальному может быть решением, но моя проблема в том, что я генерирую ПЗУ в модуле более высокого уровня в зависимости от выбранного параллелизма (общее значение). Таким образом, я думаю, что значение строки должно быть каким-то вводом. Есть ли другой способ обойти это? - person Nailtha; 21.11.2015
comment
@Nailtha Если readlne должен быть сигналом, то вы должны включить его в оператор чтения и всегда читать из всего ПЗУ, как это data <= (rom(address+readlne)); Конечно, для этого потребуется много BlockRAM. В этом случае используйте функцию двух портов, чтобы сохранить половину из них. - person Martin Zabel; 21.11.2015