yosys - 如何使用IceStorm在512x8读取模式下使用iCE40 4K Block RAM?

标签 yosys

我试图弄清楚如何在iCE40HX-8K分支板上使用Block RAM。我想以512x8的配置访问它,据我从文档中可以得知,IceStorm项目支持该配置,但是我无法使其按预期运行。

如果我理解正确,那么将READ_MODE参数设置为1初始化SB_RAM40_4K原语应该将块设置为512x8读取模式,该模式使用9位读取地址,并在每个地址读取8位数据。

这是我能想到的最简单的例子。它使用一些预初始化的存储器来设置SB_RAM40_4K并直接读取板上LED的引脚。

hx8kboard.pcf

set_io leds[0] B5
set_io leds[1] B4
set_io leds[2] A2
set_io leds[3] A1
set_io leds[4] C5
set_io leds[5] C4
set_io leds[6] B3
set_io leds[7] C3
set_io clk J3

top.v
module top (
  output [7:0] leds,
  input clk
);

//reg [8:0] raddr = 8'd0;
reg [8:0] raddr = 8'd1;

SB_RAM40_4K #(
  .INIT_0(256'h00000000000000000000000000000000000000000000000000000000_44_33_22_11),
  .WRITE_MODE(1),
  .READ_MODE(1)
) ram40_4k_512x8 (
  .RDATA(leds),
  .RADDR(raddr),
  .RCLK(clk),
  .RCLKE(1'b1),
  .RE(1'b1),
  .WADDR(8'b0),
  .WCLK(1'b0),
  .WCLKE(1'b0),
  .WDATA(8'b0),
  .WE(1'b0)
);

endmodule

raddr == 0时的LED输出
           \|/             \|/
O   O   O   O   O   O   O   O 

raddr == 1时的LED输出
       \|/ \|/         \|/ \|/
O   O   O   O   O   O   O   O 

我认为512x8模式下的地址1将是RAM中的后8位,即8'h228'b0010010。相反,我得到8'h338'b00110011。经过一些试验,这似乎是16位读取的低8位。

我不确定哪里出了问题。任何帮助了解这里发生的事情将不胜感激。谢谢!

最佳答案

这个问题不是关于Yosys或Project IceStorm的。用于SB_RAM40_4K INIT_*参数的格式与IceStorm流和Lattice iCEcube2流相同。但是,莱迪思在记录这种格式方面做得非常糟糕。否则,我只是将您指向正确的莱迪思文档.. :)

您对512x8模式感兴趣。首先,您需要知道在512x8模式下,仅使用.RDATA().WDATA()的偶数位(而不是您的代码所建议的8 LSB位!)。
.INIT_*中的数据存储为每个参数16个16位字。 .INIT_0()中最低的16位字在偶数位的addr 0处包含8位字,在其奇数位的addr 256中包含8位字。
.INIT_0()中的下一个16位单词包含单词1和257。.INIT_1()中的最低16位包含单词16和272,依此类推。

研究此类内容的最简单方法可能是读取SB_RAM40_4K中的/usr/local/share/yosys/ice40/cells_sim.v仿真模型,或者干脆让Yosys推断内存并观察yosys的工作。例如以下设计:

module test(input clk, wen, input [8:0] addr, input [7:0] wdata, output reg [7:0] rdata);
  reg [7:0] mem [0:511];
  initial mem[0] = 255;
  always @(posedge clk) begin
        if (wen) mem[addr] <= wdata;
        rdata <= mem[addr];
  end
endmodule

通过yosys -p 'synth_ice40; write_verilog' test.v运行时将产生以下输出:
(* top =  1  *)
(* src = "test.v:1" *)
module test(clk, wen, addr, wdata, rdata);
  (* src = "/usr/local/bin/../share/yosys/ice40/brams_map.v:255" *)
  (* unused_bits = "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" *)
  wire [15:0] _0_;
  (* src = "test.v:1" *)
  input [8:0] addr;
  (* src = "test.v:1" *)
  input clk;
  (* src = "test.v:1" *)
  output [7:0] rdata;
  (* src = "test.v:1" *)
  input [7:0] wdata;
  (* src = "test.v:1" *)
  input wen;
  (* src = "/usr/local/bin/../share/yosys/ice40/brams_map.v:277|/usr/local/bin/../share/yosys/ice40/brams_map.v:35" *)
  SB_RAM40_4K #(
    .INIT_0(256'bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1x1x1x1x1x1x1x1),
    .INIT_1(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_2(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_3(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_4(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_5(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_6(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_7(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_8(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_9(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_A(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_B(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_C(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_D(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_E(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .INIT_F(256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx),
    .READ_MODE(32'sd1),
    .WRITE_MODE(32'sd1)
  ) \mem.0.0.0  (
    .MASK(16'hxxxx),
    .RADDR({ 2'h0, addr }),
    .RCLK(clk),
    .RCLKE(1'h1),
    .RDATA({ _0_[15], rdata[7], _0_[13], rdata[6], _0_[11], rdata[5], _0_[9], rdata[4], _0_[7], rdata[3], _0_[5], rdata[2], _0_[3], rdata[1], _0_[1], rdata[0] }),
    .RE(1'h1),
    .WADDR({ 2'h0, addr }),
    .WCLK(clk),
    .WCLKE(wen),
    .WDATA({ 1'hx, wdata[7], 1'hx, wdata[6], 1'hx, wdata[5], 1'hx, wdata[4], 1'hx, wdata[3], 1'hx, wdata[2], 1'hx, wdata[1], 1'hx, wdata[0] }),
    .WE(1'h1)
  );
endmodule

(一直滚动到右侧,以查看为mem[0] = 255初始化生成的初始化模式。)

关于yosys - 如何使用IceStorm在512x8读取模式下使用iCE40 4K Block RAM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41499494/

相关文章:

yosys - 什么是好的 "template"Yosys 综合脚本?

yosys - Vivado 无法识别 Yosys 生成的 EDIF 文件中的单元

yosys - 如何在 Yosys 中使用多个包含同名模块的 IP 核

yosys - 了解为 iCE40 I/O block 生成的比特流

Yosys如何使用qwp命令

yosys - 如何使用 IceStorm iCE40 FPGA 流程运行综合后仿真

yosys - 带有verific的yosys正式功能是什么?

linux - iceprog - 找不到 iCE FTDI USB 设备

fpga - 莱迪思 iCE40 JTAG

verilog - Yosys 中计算的 verilog 参数