From: Daniel Benusovich Date: Tue, 23 Apr 2019 04:45:58 +0000 (-0700) Subject: Move MemorySet into separate file X-Git-Tag: div_pipeline~2148 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8ad0cbf227e66bdb24899dc4c785dc02aa760507;p=soc.git Move MemorySet into separate file --- diff --git a/TLB/src/MemorySet.py b/TLB/src/MemorySet.py new file mode 100644 index 00000000..d081dcda --- /dev/null +++ b/TLB/src/MemorySet.py @@ -0,0 +1,65 @@ +from nmigen import Cat, Memory, Module, Signal +from nmigen.cli import main +from nmigen.cli import verilog, rtlil + +class MemorySet: + def __init__(self, data_size, tag_size, set_count, active): + self.active = active + input_size = tag_size + data_size # Size of the input data + memory_width = input_size + 1 # The width of the cache memory + self.active = active + self.data_size = data_size + self.tag_size = tag_size + + # XXX TODO, use rd-enable and wr-enable? + self.mem = Memory(memory_width, set_count) + self.r = self.mem.read_port() + self.w = self.mem.write_port() + + # inputs (address) + self.cset = Signal(max=set_count) # The set to be checked + self.tag = Signal(tag_size) # The tag to find + self.data_i = Signal(data_size) # Incoming data + + # outputs + self.valid = Signal() + self.data_o = Signal(data_size) # Outgoing data (excludes tag) + + def elaborate(self, platform): + m = Module() + m.submodules.mem = self.mem + m.submodules.r = self.r + m.submodules.w = self.w + + # temporaries + active_bit = Signal() + tag_valid = Signal() + data_start = self.active + 1 + data_end = data_start + self.data_size + tag_start = data_end + tag_end = tag_start + self.tag_size + + # connect the read port address to the set/entry + read_port = self.r + m.d.comb += read_port.addr.eq(self.cset) + # Pull out active bit from data + data = read_port.data + m.d.comb += active_bit.eq(data[self.active]) + # Validate given tag vs stored tag + tag = data[tag_start:tag_end] + m.d.comb += tag_valid.eq(self.tag == tag) + # An entry is only valid if the tags match AND + # is marked as a valid entry + m.d.comb += self.valid.eq(tag_valid & active_bit) + + # output data: TODO, check rd-enable? + m.d.comb += self.data_o.eq(data[data_start:data_end]) + + # connect the write port addr to the set/entry (only if write enabled) + # (which is only done on a match, see SAC.write_entry below) + write_port = self.w + with m.If(write_port.en): + m.d.comb += write_port.addr.eq(self.cset) + m.d.comb += write_port.data.eq(Cat(1, self.data_i, self.tag)) + + return m \ No newline at end of file diff --git a/TLB/src/SetAssociativeCache.py b/TLB/src/SetAssociativeCache.py index 965f2e2a..d5bad572 100644 --- a/TLB/src/SetAssociativeCache.py +++ b/TLB/src/SetAssociativeCache.py @@ -15,6 +15,7 @@ from nmigen.cli import main from nmigen.cli import verilog, rtlil from AddressEncoder import AddressEncoder +from MemorySet import MemorySet # TODO: use a LFSR that advances continuously and picking the bottom # few bits from it to select which cache line to replace, instead of PLRU @@ -26,70 +27,6 @@ SA_NA = "00" # no action (none) SA_RD = "01" # read SA_WR = "10" # write - -class MemorySet: - def __init__(self, data_size, tag_size, set_count, active): - self.active = active - input_size = tag_size + data_size # Size of the input data - memory_width = input_size + 1 # The width of the cache memory - self.active = active - self.data_size = data_size - self.tag_size = tag_size - - # XXX TODO, use rd-enable and wr-enable? - self.mem = Memory(memory_width, set_count) - self.r = self.mem.read_port() - self.w = self.mem.write_port() - - # inputs (address) - self.cset = Signal(max=set_count) # The set to be checked - self.tag = Signal(tag_size) # The tag to find - self.data_i = Signal(data_size) # Incoming data - - # outputs - self.valid = Signal() - self.data_o = Signal(data_size) # Outgoing data (excludes tag) - - def elaborate(self, platform): - m = Module() - m.submodules.mem = self.mem - m.submodules.r = self.r - m.submodules.w = self.w - - # temporaries - active_bit = Signal() - tag_valid = Signal() - data_start = self.active + 1 - data_end = data_start + self.data_size - tag_start = data_end - tag_end = tag_start + self.tag_size - - # connect the read port address to the set/entry - read_port = self.r - m.d.comb += read_port.addr.eq(self.cset) - # Pull out active bit from data - data = read_port.data - m.d.comb += active_bit.eq(data[self.active]) - # Validate given tag vs stored tag - tag = data[tag_start:tag_end] - m.d.comb += tag_valid.eq(self.tag == tag) - # An entry is only valid if the tags match AND - # is marked as a valid entry - m.d.comb += self.valid.eq(tag_valid & active_bit) - - # output data: TODO, check rd-enable? - m.d.comb += self.data_o.eq(data[data_start:data_end]) - - # connect the write port addr to the set/entry (only if write enabled) - # (which is only done on a match, see SAC.write_entry below) - write_port = self.w - with m.If(write_port.en): - m.d.comb += write_port.addr.eq(self.cset) - m.d.comb += write_port.data.eq(Cat(1, self.data_i, self.tag)) - - return m - - class SetAssociativeCache(): """ Set Associative Cache Memory