1

的背景

这个 LUT 需要 32 的宽度和 256 的深度。

所以我有一个由 IP 核创建的 LUT。现在我想自己实例化它以使其在 sim 中工作(这也有助于我自己学习所有参数)。我已经为 FIFO 做了很多次,但之前从未创建过 LUT,所以请检查我所做的是否正确。我只想创建一个值的 LUT 并能够将它们读回。我为此使用了一块 RAM。

我在两台不同的电脑上试过:

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 : RAMB18E1 -- Simple Duel Port mode, 512 deep
generic map(
    INIT_FILE => "lut.coe",
    RAM_MODE => "SDP"
    )
port map
    (
    addrardaddr => addr_lut,
    addrbwraddr => "00000000000000",
    clkardclk => clk_i,
    clkbwrclk => clk_i,
    diadi => X"0000",
    dibdi => X"0000",
    dipadip => "00",
    dipbdip => "00",
    doado => data_lut_b,
    dobdo => data_lut_a,
    enarden => '1',
    enbwren => '0',
    regceb => '0',
    regcearegce => '1',
    rstramarstram => rst_i,
    rstramb => rst_i,
    rstregarstreg => rst_i ,
    rstregb => rst_i,
    wea => "00",
    webwe =>  X"0"   
    );
4

2 回答 2

2

严重地。扔掉IP核和COE文件。((如果这是您的数据唯一的地方,请不要把它扔掉!)

Subtype Data_Word is std_logic_vector(31 downto 0);
Type Lut_Type is Array(0 to 255) of Data_Word;
Constant Lut : Lut_Type := (
 0 => X"00000001",
 1 => X"00000002",
...
17 => X"DEADBEEF",
others => (others => 'X') );

当然用你自己的系数代替。对于加分,使用脚本甚至 C 或 VHDL 程序来读取 COE 文件并编写上述 VHDL 块。

任务完成。

它可合成、可模拟,并可移植到其他 FPGA。

(IMO 可移植性问题是大多数供应商 IP 内核的真正原因。但对于复杂的内核,如 PCIe 或 DDR 内存接口,我会例外。)

于 2015-07-30T19:02:21.620 回答
2

Xilinx 工具有一种简单快捷的方法可以直接在 VHDL 中读取 *.mem 或 *.hex 文件。文件内容可在仿真和综合中用作 BlockRAM 初始化。

Xilinx在第 124 页的UG901中提供了一个编码示例:

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)。

例如,可以在PoC.mem.ocrom.sp中找到更高级的实现。这个实现也适用于 Altera 的 sltsyncrams,它 csn 读取 *.mif 文件。

于 2015-07-30T22:13:06.187 回答