【问题标题】:Initializing ROM from array using functions, Synthesis ERROR (VHDL)使用函数、综合错误 (VHDL) 从数组初始化 ROM
【发布时间】:2015-11-21 06:14:28
【问题描述】:

好的,所以我的 ROM 初始化函数有问题。 在我进入这个问题之前,让我解释一下我的问题和我的代码的性质。

我想做的是生成 N 个 ROM,我必须将它们用作运行匹配算法的模块的输入。 我的问题是我有一个带有我的签名的文件(比如说总共 64 个),我想根据我生成的数量(在我的情况下为 2 的幂,例如 8 个 rom,每个 8 个签名)加载到不同的 ROM 中)。

我认为最好的方法是将整个文本文件加载到一个数组中(使用架构主体之外的函数),然后我将使用它(再次在函数中)将数据加载到一个较小的数组中然后将成为我的 ROM。

在我看来,合成器会忽略大数组,因为我实际上并没有在我的架构中使用它。

现在的问题是,由于第二个数组输入参数依赖于信号,合成器只是忽略它们并将我的数组绑定到零(第 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 进行仿真,我的创作工作正常 :)

感谢您的帮助!

【问题讨论】:

  • 我会将您的“签名”转换为 VHDL 包中的常量字符串...或者编写脚本将文本文件处理为正确的格式(如果它们是在其他地方生成的)。
  • XST 支持从 VHDL 文件读取初始化 RAM,ROM(作为信号)是未写入的 RAM。但是,作为从另一个信号中提取的初始数组值,这不会为您提供更小的只读内存。如果 readlne 和 address 都是信号,则从较大的 ROM 数组中提取较小的“ROM”值需要索引算术(readlne + address)。该索引算法可能会影响时钟周期。这让我们想到了二维索引。

标签: function initialization vhdl rom xilinx-ise


【解决方案1】:

使用 Xilinx ISE (14.7),即使初始数据是通过函数从外部文件读取的,也可以合成 ROM 和 RAM。

唯一的要求是,读取函数在合成时必须是可计算的。这不适用于您的代码,因为 readlne 在调用函数时不是静态的。您应该将其更改为泛型而不是输入,并为每个其他 ROM 实例为此泛型分配不同的值。然后它应该按预期工作。

如何从 (Xilinx) .mem 格式的文本文件中读取初始化数据的示例实现可以在命名空间 PoC.mem.ocromPoC.mem.ocram 中的 VHDL Library PoC 中找到

【讨论】:

  • 感谢您对 ISE 的说明,不太确定初始化是如何工作的。现在的问题是,为泛型分配不同的值可能是一种解决方案,但我的问题是我确实根据我选择的并行度(泛型值)在更高级别的模块中生成 ROM。因此,我认为“线值”必须是某种输入。还有其他方法可以绕过吗?
  • @Nailtha 如果readlne 需要是一个信号,那么你必须将它包含在读出语句中,并且总是像这样从整个ROM 中读取data &lt;= (rom(address+readlne)); 当然,这需要大量的 BlockRAM。在这种情况下,使用双端口功能可以节省一半。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多