我正在使用SyncReadMem()进行静态随机存取存储器行为模拟。有了generated Verilog by verilator,我希望用一个商业的编译verilog的静态随机存取存储器编译器来取代它,这样我就可以对整个设计进行综合,包括静态随机存取存储器。
然而,我注意到SyncReadMem()发出的verilog并不像sram emitted in rocketchip那样具有统一的IOs。我想知道如何使用像SyncReadMem()这样的chisel mem API来生成一些像rocketchip那样的sram verilog?
发布于 2021-02-25 01:59:53
您可以使用Scala FIRRTL编译器的"Replace Sequential Memories“传递来对内存进行黑箱操作。这正是火箭芯片正在发生的事情。
注意,这仅限于当存储器具有单个读取端口和单个写入端口并且具有读取等待时间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)
}
}如果您使用请求来编译此代码,以运行replace顺序内存传递:
(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的输出。
https://stackoverflow.com/questions/66344890
复制相似问题