icache.py move icache_miss CLR_TAG FSM state into method icache_miss_clr_tag() to...
[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 comb, sync = m.d.comb, m.d.sync
21
22 ROW_BITS = self.ROW_BITS
23 WIDTH = self.WIDTH
24 TRACE = self.TRACE
25 ADD_BUF = self.ADD_BUF
26 SIZE = 2**ROW_BITS
27
28 ram = Array(Signal(WIDTH) for i in range(SIZE))
29 #attribute ram_style of ram : signal is "block";
30
31 rd_data0 = Signal(WIDTH)
32
33 sel0 = Signal(WIDTH//8) # defaults to zero
34
35 with m.If(TRACE):
36 with m.If(self.wr_sel != sel0):
37 #Display( "write a:" & to_hstring(wr_addr) &
38 # " sel:" & to_hstring(wr_sel) &
39 # " dat:" & to_hstring(wr_data))
40 pass
41 for i in range(WIDTH//8):
42 lbit = i * 8;
43 mbit = lbit + 8;
44 with m.If(self.wr_sel[i]):
45 sync += ram[self.wr_addr][lbit:mbit].eq(self.wr_data[lbit:mbit])
46 with m.If(self.rd_en):
47 if ADD_BUF:
48 sync += self.rd_data_o.eq(ram[self.rd_addr])
49 else:
50 comb += self.rd_data_o.eq(ram[self.rd_addr])
51
52 if TRACE:
53 # Display( "read a:" & to_hstring(rd_addr) &
54 #" dat:" & to_hstring(ram(to_integer(unsigned(rd_addr))));
55 pass
56
57 return m