使用函数从数组初始化 ROM,综合错误 (VHDL)
Initializing ROM from array using functions, Synthesis ERROR (VHDL)
好的,所以我有一个 ROM 初始化函数的问题。
在我进入问题之前,让我解释一下我的问题的性质和我的代码。
我想要做的是生成 N 个 ROM,我必须将它们用作运行匹配算法的模块的输入。
我的问题是我有一个带有我的签名的文件(假设总共有 64 个),我想根据我生成的数量加载到不同的 ROM 中(在我的例子中是 2 的幂,例如 8 个 ROM,每个 8 个签名).
我认为最好的方法是将整个文本文件加载到一个数组中(使用体系结构主体外部的函数),然后我将使用它(再次在函数中)将数据加载到一个较小的数组,这将成为我的 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 完成的,我的作品在其中运行良好:)
感谢您的帮助!
使用 Xilinx ISE (14.7),即使通过函数从外部文件读取初始数据,也可以合成 ROM 和 RAM。
唯一的要求是,读取函数在综合时必须是可计算的。这对您的代码而言并非如此,因为 readlne
在调用函数时不是静态的。您应该将其更改为泛型而不是输入,并为每个其他 ROM 实例为该泛型分配不同的值。然后它应该按预期工作。
如何从 (Xilinx) .mem
格式的文本文件中读取初始化数据的示例实现可以在 VHDL Library PoC in the namespace PoC.mem.ocrom or PoC.mem.ocram
中找到
好的,所以我有一个 ROM 初始化函数的问题。 在我进入问题之前,让我解释一下我的问题的性质和我的代码。
我想要做的是生成 N 个 ROM,我必须将它们用作运行匹配算法的模块的输入。 我的问题是我有一个带有我的签名的文件(假设总共有 64 个),我想根据我生成的数量加载到不同的 ROM 中(在我的例子中是 2 的幂,例如 8 个 ROM,每个 8 个签名).
我认为最好的方法是将整个文本文件加载到一个数组中(使用体系结构主体外部的函数),然后我将使用它(再次在函数中)将数据加载到一个较小的数组,这将成为我的 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 完成的,我的作品在其中运行良好:)
感谢您的帮助!
使用 Xilinx ISE (14.7),即使通过函数从外部文件读取初始数据,也可以合成 ROM 和 RAM。
唯一的要求是,读取函数在综合时必须是可计算的。这对您的代码而言并非如此,因为 readlne
在调用函数时不是静态的。您应该将其更改为泛型而不是输入,并为每个其他 ROM 实例为该泛型分配不同的值。然后它应该按预期工作。
如何从 (Xilinx) .mem
格式的文本文件中读取初始化数据的示例实现可以在 VHDL Library PoC in the namespace PoC.mem.ocrom or PoC.mem.ocram