SyncReadMem 生成的 verilog 与 Rocketchip 发出的 verilog

SyncReadMem generated verilog vs. Rocketchip emitted verilog

我正在使用SyncReadMem() for sram behavioral simulation. With the generated Verilog by verilator,我希望用商业sram编译器编译verilog来代替它,这样我就可以对包括sram在内的整个设计进行综合。

但是,我注意到 SyncReadMem() 发出的 verilog 与 sram emitted in rocketchip 不同 IOs。我想知道我们如何像 rocketchip 一样生成一些 sram verilog,使用 chisel mem API 像 SyncReadMem()?

您可以使用 Scala FIRRTL 编译器的“替换顺序内存”传递来黑盒化内存。这正是 Rocket Chip 正在发生的事情。

请注意,这仅限于只有当存储器具有单个读取端口和单个写入端口并且读取延迟为 1 和写入延迟为 1 时才有效。

例如,考虑以下 1r1w(一次读取,一次写入)SyncReadMem

import chisel3._ 

class Foo extends MultiIOModule {
  val read = IO(new Bundle {
    val en = Input(Bool())
    val addr = Input(UInt(8.W))
    val data = Output(UInt(1.W))
  })
  val write = IO(new Bundle{
    val en = Input(Bool())
    val addr = Input(UInt(8.W))
    val data = Input(UInt(1.W))
  })
  val bar = SyncReadMem(256, UInt(1.W))
  
  read.data := bar.read(read.addr, read.en)
  when (write.en) {
    bar.write(write.addr, write.data)
  }
}

如果您通过对 运行 的请求进行编译,替换顺序内存通过:

(new ChiselStage)
  .emitVerilog(new Foo, Array("--repl-seq-mem", "-c:Foo:-o:Foo.mem.conf"))

那里使用的参数是 -c:<circuit>,其中 <circuit> 是你想要 运行 的电路的名称,-o:<mem-conf-file> 是要生成的文件的名称它将包含被黑盒化的记忆的信息(例如,名称、宽度和深度)。

您最终在一个名为 bar_ext:

的新模块 bar 中将内存黑盒化
module bar(
  input  [7:0] R0_addr,
  input        R0_en,
  input        R0_clk,
  output       R0_data,
  input  [7:0] W0_addr,
  input        W0_en,
  input        W0_clk,
  input        W0_data
);
  wire [7:0] bar_ext_R0_addr;
  wire  bar_ext_R0_en;
  wire  bar_ext_R0_clk;
  wire  bar_ext_R0_data;
  wire [7:0] bar_ext_W0_addr;
  wire  bar_ext_W0_en;
  wire  bar_ext_W0_clk;
  wire  bar_ext_W0_data;
  bar_ext bar_ext (
    .R0_addr(bar_ext_R0_addr),
    .R0_en(bar_ext_R0_en),
    .R0_clk(bar_ext_R0_clk),
    .R0_data(bar_ext_R0_data),
    .W0_addr(bar_ext_W0_addr),
    .W0_en(bar_ext_W0_en),
    .W0_clk(bar_ext_W0_clk),
    .W0_data(bar_ext_W0_data)
  );
  assign bar_ext_R0_clk = R0_clk;
  assign bar_ext_R0_en = R0_en;
  assign bar_ext_R0_addr = R0_addr;
  assign R0_data = bar_ext_R0_data;
  assign bar_ext_W0_clk = W0_clk;
  assign bar_ext_W0_en = W0_en;
  assign bar_ext_W0_addr = W0_addr;
  assign bar_ext_W0_data = W0_data;
endmodule

然后您可以 运行 内存编译器来使用内存配置文件中的信息并删除输出以代替 bar_ext