I'm trying to generate the verilog for a memory with a synchronous read with the following chisel
val my_mem = Mem(Bits(width=64), 4096, seqRead=true)
val read_data = Reg(Bits(width=64))
when(io.re) {
read_data := my_mem(io.addr)
}
io.ret_data := read_data
However, this generates verilog with this
wire[63:0] T1;
reg [63:0] read_data;
assign T1 = my_mem[io_addr];
always @(posedge clk) begin
if(io_re) begin
read_data <= T1;
end
What I am doing wrong to get chisel to generate verilog that has the memory read inside the always block?
The Chisel manual state the proper way to create a synchronous memory is to register the ADDRESS, not the read data. Although slightly unintuitive, with register re-timing, it is conceptually the same thing.
val my_mem = Mem(Bits(width=64), 4096, seqRead=true)
val reg_raddr = Reg(UInt())
val rdata = my_mem(reg_raddr)
when (io.re) { reg_raddr := io.addr }
Which generates this:
assign io_out = T0;
assign T0 = my_mem[reg_raddr];
always @(posedge clk) begin
if(io_re) begin
reg_raddr <= io_addr;
end
end
The data read is not in the always block, but I don't believe that is necessary for the synthesis tools to pick up that you want a synchronous memory.