add PLRU microwatt conversion
[soc.git] / src / soc / experiment / cache_ram.py
1 # TODO: replace with Memory at some point
2 from nmigen import Elaboratable, Signal, Array, Module
3
4 class CacheRam(Elaboratable):
5
6 def __init__(self, ROW_BITS=16, WIDTH = 64, TRACE=False, ADD_BUF=False):
7 self.ROW_BITS = ROW_BITS
8 self.WIDTH = WIDTH
9 self.TRACE = TRACE
10 self.ADD_BUF = ADD_BUF
11 self.rd_en = Signal()
12 self.rd_addr = Signal(ROW_BITS)
13 self.rd_data_o = Signal(WIDTH)
14 self.wr_sel = Signal(WIDTH//8)
15 self.wr_addr = Signal(ROW_BITS)
16 self.wr_data = Signal(WIDTH)
17
18 def elaborate(self, platform):
19 m = Module()
20
21 ROW_BITS = self.ROW_BITS
22 WIDTH = self.WIDTH
23 TRACE = self.TRACE
24 ADD_BUF = self.ADD_BUF
25 SIZE = 2**ROW_BITS
26
27 ram = Array(Signal(WIDTH) for i in range(SIZE))
28 #attribute ram_style of ram : signal is "block";
29
30 rd_data0 = Signal(WIDTH)
31
32 sel0 = Signal(WIDTH//8) # defaults to zero
33
34 with m.If(TRACE):
35 with m.If(self.wr_sel != sel0):
36 #Display( "write a:" & to_hstring(wr_addr) &
37 # " sel:" & to_hstring(wr_sel) &
38 # " dat:" & to_hstring(wr_data))
39 pass
40 for i in range(WIDTH//8):
41 lbit = i * 8;
42 mbit = lbit + 8;
43 with m.If(self.wr_sel[i]):
44 sync += ram[self.wr_addr][lbit:mbit].eq(wr_data(lbit:mbit]))
45 with m.If(self.rd_en):
46 if ADD_BUF:
47 sync += self.rd_data_o.eq(ram[rd_addr])
48 else:
49 comb += self.rd_data_o.eq(ram[rd_addr])
50
51 if TRACE:
52 # Display( "read a:" & to_hstring(rd_addr) &
53 #" dat:" & to_hstring(ram(to_integer(unsigned(rd_addr))));
54 pass
55
56 return m