1 # TODO: replace with Memory at some point
2 from nmigen
import Elaboratable
, Signal
, Array
, Module
, Memory
3 from nmutil
.util
import Display
6 class CacheRam(Elaboratable
):
8 def __init__(self
, ROW_BITS
=16, WIDTH
= 64, TRACE
=True, ADD_BUF
=False,
10 self
.ram_num
= ram_num
# for debug reporting
11 self
.ROW_BITS
= ROW_BITS
14 self
.ADD_BUF
= ADD_BUF
16 self
.rd_addr
= Signal(ROW_BITS
)
17 self
.rd_data_o
= Signal(WIDTH
)
18 self
.wr_sel
= Signal(WIDTH
//8)
19 self
.wr_addr
= Signal(ROW_BITS
)
20 self
.wr_data
= Signal(WIDTH
)
22 def elaborate(self
, platform
):
24 comb
, sync
= m
.d
.comb
, m
.d
.sync
26 ROW_BITS
= self
.ROW_BITS
29 ADD_BUF
= self
.ADD_BUF
32 # set up the Cache RAM Memory and create one read and one write port
33 # the read port is *not* transparent (does not pass write-thru-read)
34 #attribute ram_style of ram : signal is "block";
35 ram
= Memory(depth
=SIZE
, width
=WIDTH
)
36 m
.submodules
.rdport
= rdport
= ram
.read_port(transparent
=False)
37 m
.submodules
.wrport
= wrport
= ram
.write_port(granularity
=8)
40 with m
.If(self
.wr_sel
.bool()):
41 sync
+= Display( "write ramno %d a: %%x "
42 "sel: %%x dat: %%x" % self
.ram_num
,
44 self
.wr_sel
, self
.wr_data
)
46 # read data output and a latched copy. behaves like microwatt cacheram
47 rd_data0
= Signal(WIDTH
)
48 rd_data0l
= Signal(WIDTH
)
50 # delay on read address/en
52 rd_delay_addr
= Signal
.like(self
.rd_addr
)
53 sync
+= rd_delay_addr
.eq(self
.rd_addr
)
54 sync
+= rd_delay
.eq(self
.rd_en
)
57 comb
+= wrport
.addr
.eq(self
.wr_addr
)
58 comb
+= wrport
.en
.eq(self
.wr_sel
)
59 comb
+= wrport
.data
.eq(self
.wr_data
)
61 # read port (include a latch on the output, for microwatt compatibility)
62 comb
+= rdport
.addr
.eq(self
.rd_addr
)
63 comb
+= rdport
.en
.eq(self
.rd_en
)
65 comb
+= rd_data0
.eq(rdport
.data
)
66 sync
+= rd_data0l
.eq(rd_data0
) # preserve latched data
68 comb
+= rd_data0
.eq(rd_data0l
) # output latched (last-read)
72 sync
+= Display("read ramno %d a: %%x dat: %%x" % self
.ram_num
,
73 rd_delay_addr
, rd_data0
)
76 # extra delay requested?
78 sync
+= self
.rd_data_o
.eq(rd_data0
)
80 comb
+= self
.rd_data_o
.eq(rd_data0
)