- for i in range(WIDTH//8):
- lbit = i * 8;
- mbit = lbit + 8;
- with m.If(self.wr_sel[i]):
- sync += ram[self.wr_addr][lbit:mbit].eq(self.wr_data[lbit:mbit])
- with m.If(self.rd_en):
- sync += rd_data0.eq(ram[self.rd_addr])
- if TRACE:
+
+ # read data output and a latched copy. behaves like microwatt cacheram
+ rd_data0 = Signal(WIDTH)
+ rd_data0l = Signal(WIDTH)
+
+ # delay on read address/en
+ rd_delay = Signal()
+ rd_delay_addr = Signal.like(self.rd_addr)
+ sync += rd_delay_addr.eq(self.rd_addr)
+ sync += rd_delay.eq(self.rd_en)
+
+ # write port
+ comb += wrport.addr.eq(self.wr_addr)
+ comb += wrport.en.eq(self.wr_sel)
+ comb += wrport.data.eq(self.wr_data)
+
+ # read port (include a latch on the output, for microwatt compatibility)
+ comb += rdport.addr.eq(self.rd_addr)
+ comb += rdport.en.eq(self.rd_en)
+ with m.If(rd_delay):
+ comb += rd_data0.eq(rdport.data)
+ sync += rd_data0l.eq(rd_data0) # preserve latched data
+ with m.Else():
+ comb += rd_data0.eq(rd_data0l) # output latched (last-read)
+
+ if TRACE:
+ with m.If(rd_delay):