1 from nmigen
import Cat
, Memory
, Module
, Signal
, Elaboratable
2 from nmigen
.cli
import main
3 from nmigen
.cli
import verilog
, rtlil
6 class MemorySet(Elaboratable
):
7 def __init__(self
, data_size
, tag_size
, set_count
, active
):
9 input_size
= tag_size
+ data_size
# Size of the input data
10 memory_width
= input_size
+ 1 # The width of the cache memory
12 self
.data_size
= data_size
13 self
.tag_size
= tag_size
15 # XXX TODO, use rd-enable and wr-enable?
16 self
.mem
= Memory(memory_width
, set_count
)
17 self
.r
= self
.mem
.read_port()
18 self
.w
= self
.mem
.write_port()
21 self
.cset
= Signal(max=set_count
) # The set to be checked
22 self
.tag
= Signal(tag_size
) # The tag to find
23 self
.data_i
= Signal(data_size
) # Incoming data
27 self
.data_o
= Signal(data_size
) # Outgoing data (excludes tag)
29 def elaborate(self
, platform
):
31 m
.submodules
.mem
= self
.mem
32 m
.submodules
.r
= self
.r
33 m
.submodules
.w
= self
.w
38 data_start
= self
.active
+ 1
39 data_end
= data_start
+ self
.data_size
41 tag_end
= tag_start
+ self
.tag_size
43 # connect the read port address to the set/entry
45 m
.d
.comb
+= read_port
.addr
.eq(self
.cset
)
46 # Pull out active bit from data
48 m
.d
.comb
+= active_bit
.eq(data
[self
.active
])
49 # Validate given tag vs stored tag
50 tag
= data
[tag_start
:tag_end
]
51 m
.d
.comb
+= tag_valid
.eq(self
.tag
== tag
)
52 # An entry is only valid if the tags match AND
53 # is marked as a valid entry
54 m
.d
.comb
+= self
.valid
.eq(tag_valid
& active_bit
)
56 # output data: TODO, check rd-enable?
57 m
.d
.comb
+= self
.data_o
.eq(data
[data_start
:data_end
])
59 # connect the write port addr to the set/entry (only if write enabled)
60 # (which is only done on a match, see SAC.write_entry below)
62 with m
.If(write_port
.en
):
63 m
.d
.comb
+= write_port
.addr
.eq(self
.cset
)
64 m
.d
.comb
+= write_port
.data
.eq(Cat(1, self
.data_i
, self
.tag
))