Vhdl 为ModelSim/QuestaSim实例化LUT并使用.coe初始化 背景
此LUT需要32的宽度和256的深度 所以我有一个由IP核心创建的LUT。现在我想自己实例化它,让它在sim卡中工作(这也帮助我自己学习所有参数)。我已经为FIFO做了很多次了,但以前从未创建过LUT,所以请检查我所做的看起来是否正确。我只想创建一个LUT的值,并能够读回它们。我用了一块RAM来做这个 我在两台不同的计算机上试用过:Vhdl 为ModelSim/QuestaSim实例化LUT并使用.coe初始化 背景,vhdl,ram,xilinx,lookup-tables,vivado,Vhdl,Ram,Xilinx,Lookup Tables,Vivado,此LUT需要32的宽度和256的深度 所以我有一个由IP核心创建的LUT。现在我想自己实例化它,让它在sim卡中工作(这也帮助我自己学习所有参数)。我已经为FIFO做了很多次了,但以前从未创建过LUT,所以请检查我所做的看起来是否正确。我只想创建一个LUT的值,并能够读回它们。我用了一块RAM来做这个 我在两台不同的计算机上试用过: QuestaSim-64 10.2c_5 ModelSim SE-64 10.1b 问题 所以我可以编译代码。当我试图打开它时: vsim work.top 它
QuestaSim-64 10.2c_5
ModelSim SE-64 10.1b
问题
所以我可以编译代码。当我试图打开它时:
vsim work.top
它打开IDE并冻结在以下位置:
# Loading unisim.rb36_internal_vhdl(rb36_internal_vhdl_v)#1
如果我删除:
INIT_FILE => "lut.coe",
然后就可以装了。所以我知道那条线会毁了它
LUT:
我有一个LUT,你觉得这对吗?是否有其他方法可以用.coe文件实例化LUT
lut : RAMB36E1
generic map(
INIT_FILE => "lut.coe",
READ_WIDTH_A => 36
)
port map
(
addrardaddr => addr_lut,
addrbwraddr => X"0000",
cascadeina => '0',
cascadeinb => '0',
clkardclk => clk_i,
clkbwrclk => clk_i,
diadi => X"00000000",
dibdi => X"00000000",
dipadip => X"0",
dipbdip => X"0",
doado => data_lut,
enarden => '1',
enbwren => '0',
injectdbiterr => '0',
injectsbiterr => '0' ,
regceb => '0',
regcearegce => '1',
rstramarstram => rst_i,
rstramb => rst_i,
rstregarstreg => rst_i ,
rstregb => rst_i,
wea => X"0",
webwe => X"00"
);
尝试将上述内容替换为18kb RAM,出现相同错误:
# Loading unisim.rb18_internal_vhdl(rb18_internal_vhdl_v)#2
LUT:
真的。扔掉IP核心和COE文件。((如果这是您的数据所在的唯一位置,请不要将其扔掉!) 当然,替换你自己的系数。为了获得额外的分数,可以使用脚本,甚至是C或VHDL程序来读取COE文件并编写上面的VHDL代码块 工作完成了 它是可合成、可模拟的,并且可移植到其他FPGA
(在我看来,可移植性问题是大多数供应商的IP核的真正原因。但我将对复杂的核心(如PCIe或DDR内存接口)例外。)严肃地说。扔掉IP核和COE文件。((如果你的数据只放在那个地方,不要真的扔掉它!) 当然,替换你自己的系数。为了获得额外的分数,可以使用脚本,甚至是C或VHDL程序来读取COE文件并编写上面的VHDL代码块 工作完成了 它是可合成、可模拟的,并且可移植到其他FPGA
(在我看来,可移植性问题是大多数供应商IP核的真正原因。但我将为复杂的核心(如PCIe或DDR内存接口)提供一个例外。)Xilinx工具有一种简单快捷的方法,可以直接在VHDL中读取*.mem或*.hex文件。文件内容可以在模拟和合成中用作块RAM初始化 Xilinx提供了第124页中的编码示例:
type RamType is array(0 to 7) of bit_vector(31 downto 0);
impure function InitRamFromFile (RamFileName : in string) return RamType is
FILE RamFile : text is in RamFileName;
variable RamFileLine : line;
variable RAM : RamType;
begin
for I in RamType'range loop
readline (RamFile, RamFileLine);
read (RamFileLine, RAM(I));
end loop;
return RAM;
end function;
signal RAM : RamType := InitRamFromFile("rams_20c.data");
该示例适用于RAM,但当您移除写入端口并用常量替换信号时,它可以很容易地转换为ROM(LUT)
例如,可以在中找到更高级的实现。此实现还可与Altera的sltsyncrams一起使用,后者可以读取*.mif文件。Xilinx工具有一种简单快捷的方法,可以直接在VHDL中读取*.mem或*.hex文件。文件内容可以在模拟和合成中用作块RAM初始化 Xilinx提供了第124页中的编码示例:
type RamType is array(0 to 7) of bit_vector(31 downto 0);
impure function InitRamFromFile (RamFileName : in string) return RamType is
FILE RamFile : text is in RamFileName;
variable RamFileLine : line;
variable RAM : RamType;
begin
for I in RamType'range loop
readline (RamFile, RamFileLine);
read (RamFileLine, RAM(I));
end loop;
return RAM;
end function;
signal RAM : RamType := InitRamFromFile("rams_20c.data");
该示例适用于RAM,但当您移除写入端口并用常量替换信号时,它可以很容易地转换为ROM(LUT)
例如,可以在中找到一个更高级的实现。该实现还可以与Altera的sltsyncrams一起使用,csn读取*.mif文件。这实际上是我扔掉了IP核,但我想我仍然可以回收.coe文件。谢谢,明天早上我的大脑不那么灵活的时候我会看看这个。我想我可以用上面的method-工具仍然会生成一个RAMB块,这是正常的。如果它出于某种原因拒绝,(a)检查您的管道-您需要在其地址或输出上注册一个寄存器(BRAM是同步的),并且(b)有一个属性(类似于Lut的
属性RAMSTYLE是“BRAM”;
)在文档中,这应该是强制的。我不记得该属性是必需的,但很高兴知道。这实际上是我扔掉了IP核心,但我认为我仍然可以回收.coe文件。谢谢,明天早上我的大脑不太灵活时,我会看一看这个。我猜使用上述方法-工具仍然会生成一个RAMB blockIt通常会这样做。如果它出于某种原因拒绝,(a)检查您的管道-您需要在其地址或输出上注册一个寄存器(BRAM是同步的),并且(b)有一个属性(类似于属性,Lut的RAMSTYLE是“BRAM”;
)在文档中,这应该是强制的。我不记得该属性是必需的,但很高兴知道。设备特定原语的使用非常严格。如果可能,我建议使用通用描述。此解决方案也可以由模拟器使用,而无需供应商特定的原语支持。设备特定原语的使用imitives是非常严格的。如果可能的话,我建议使用通用描述。这个解决方案也可以由模拟器使用,而不需要特定于供应商的原语支持。谢谢,这是一个非常好的替代答案。虽然我写了一个简短的脚本,生成上面的LUT,我将首先试用。如果可行,我将稍后试用因为它看起来更通用一些=我忘了提到*.mem文件格式是什么样子的:n行代表n个内存字,因此每个内存字1行;每个内存字都用十六进制ASCII字符编码。使用这个答案的一个好方法是调整函数直接读取.coe文件,跳过不需要的行,然后提取coeffic来自有用行的IENT。@fiz可以随意扩展ocrom以读取新的文件格式:)干杯,因为.coe文件目前已修复,我只是从中提取了一些值,但如果我需要,我将尝试在未来的设计中使用它=)谢谢,这是一个非常好的替代答案。虽然我写了一个简短的脚本来生成上面的LUT,但我将首先尝试。如果可以的话,我稍后会尝试一下,因为它看起来更通用一些=我忘了提到*.mem文件格式的样子:n行代表n个内存字,因此每个内存字1行;每个内存字都用十六进制ASCII字符编码。使用此答案的一个好方法是调整函数以直接读取.coe文件
type RamType is array(0 to 7) of bit_vector(31 downto 0);
impure function InitRamFromFile (RamFileName : in string) return RamType is
FILE RamFile : text is in RamFileName;
variable RamFileLine : line;
variable RAM : RamType;
begin
for I in RamType'range loop
readline (RamFile, RamFileLine);
read (RamFileLine, RAM(I));
end loop;
return RAM;
end function;
signal RAM : RamType := InitRamFromFile("rams_20c.data");