我想在Chisel中创建一个真正的双端口RAM,并在Vivado 2018.3中合成Verilog代码。这是我的凿子代码:
class DoublePortsRAM extends Module {
val io = IO(new Bundle {
val addr1 = Input(UInt(10.W))
val dataIn1 = Input(UInt(32.W))
val en1 = Input(Bool())
val we1 = Input(Bool())
val dataOut1 = Output(UInt(32.W))
val clk2 = Input(Clock())
val reset2 = Input(Bool())
val addr2 = Input(UInt(10.W))
val dataIn2 = Input(UInt(32.W))
val en2 = Input(Bool())
val we2 = Input(Bool())
val dataOut2 = Output(UInt(32.W))
})
val syncRAM = SyncReadMem(1024, UInt(32.W))
when(io.en1) {
when(io.we1) {
syncRAM.write(io.addr1, io.dataIn1)
io.dataOut1 := DontCare
} .otherwise {
io.dataOut1 := syncRAM.read(io.addr1)
}
} .otherwise {
io.dataOut1 := DontCare
}
withClockAndReset(io.clk2, io.reset2) {
when(io.en2) {
when(io.we2) {
syncRAM.write(io.addr2, io.dataIn2)
io.dataOut2 := DontCare
} .otherwise {
io.dataOut2 := syncRAM.read(io.addr2)
}
} .otherwise {
io.dataOut2 := DontCare
}
}
}
编译后,一些类似Verilog的代码:
always @(posedge clock) begin
...
if (_GEN_36) begin
syncRAM__T_1_addr_pipe_0 <= io_addr1;
end
end
...
assign syncRAM__T_1_addr = syncRAM__T_1_addr_pipe_0;
assign syncRAM__T_1_data = syncRAM[syncRAM__T_1_addr];
assign io_dataOut1 = syncRAM__T_1_data;
...
但是,Vivado报告无法推断RAM的模式。我必须手动修改以下代码:
always @(posedge clock) begin
...
if (_GEN_36) begin
syncRAM__T_1_addr_pipe_0 <= syncRAM[io_addr1];
end
end
...
assign io_dataOut1 = syncRAM__T_1_addr_pipe_0;
...
换句话说,同步读取RAM不应使用寄存器来存储读取地址。相反,可以存储读取数据。此外,Vivado可以在不修改Verilog的情况下合成单端口RAM。怎么了?