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 attrs
={'syn_ramstyle': "block_ram"})
37 m
.submodules
.rdport
= rdport
= ram
.read_port(transparent
=False)
38 m
.submodules
.wrport
= wrport
= ram
.write_port(granularity
=8)
41 with m
.If(self
.wr_sel
.bool()):
42 sync
+= Display( "write ramno %d a: %%x "
43 "sel: %%x dat: %%x" % self
.ram_num
,
45 self
.wr_sel
, self
.wr_data
)
47 # read data output and a latched copy. behaves like microwatt cacheram
48 rd_data0
= Signal(WIDTH
)
49 rd_data0l
= Signal(WIDTH
)
51 # delay on read address/en
53 rd_delay_addr
= Signal
.like(self
.rd_addr
)
54 sync
+= rd_delay_addr
.eq(self
.rd_addr
)
55 sync
+= rd_delay
.eq(self
.rd_en
)
58 comb
+= wrport
.addr
.eq(self
.wr_addr
)
59 comb
+= wrport
.en
.eq(self
.wr_sel
)
60 comb
+= wrport
.data
.eq(self
.wr_data
)
62 # read port (include a latch on the output, for microwatt compatibility)
63 comb
+= rdport
.addr
.eq(self
.rd_addr
)
64 comb
+= rdport
.en
.eq(self
.rd_en
)
66 comb
+= rd_data0
.eq(rdport
.data
)
67 sync
+= rd_data0l
.eq(rd_data0
) # preserve latched data
69 comb
+= rd_data0
.eq(rd_data0l
) # output latched (last-read)
73 sync
+= Display("read ramno %d a: %%x dat: %%x" % self
.ram_num
,
74 rd_delay_addr
, rd_data0
)
77 # extra delay requested?
79 sync
+= self
.rd_data_o
.eq(rd_data0
)
81 comb
+= self
.rd_data_o
.eq(rd_data0
)