soc/interconnect/wishbone: Cosmetic cleanup on Cache.

This commit is contained in:
Florent Kermarrec 2024-09-09 18:16:40 +02:00
parent e06045c576
commit 5cd1a57080
1 changed files with 28 additions and 20 deletions

View File

@ -641,8 +641,8 @@ class Wishbone2CSR(LiteXModule):
class Cache(LiteXModule): class Cache(LiteXModule):
"""Cache """Cache
This module is a write-back wishbone cache that can be used as a L2 cache. This module is a write-back wishbone cache that can be used as a L2 cache. Cachesize (in 32-bit
Cachesize (in 32-bit words) is the size of the data store and must be a power of 2 words) is the size of the data store and must be a power of 2.
""" """
def __init__(self, cachesize, master, slave, reverse=True): def __init__(self, cachesize, master, slave, reverse=True):
self.master = master self.master = master
@ -650,25 +650,29 @@ class Cache(LiteXModule):
# # # # # #
# Parameters.
# -----------
dw_from = len(master.dat_r) dw_from = len(master.dat_r)
dw_to = len(slave.dat_r) dw_to = len(slave.dat_r)
if dw_to > dw_from and (dw_to % dw_from) != 0: if dw_to > dw_from and (dw_to % dw_from) != 0:
raise ValueError("Slave data width must be a multiple of {dw}".format(dw=dw_from)) raise ValueError("Slave data width must be a multiple of {dw}".format(dw=dw_from))
if dw_to < dw_from and (dw_from % dw_to) != 0: if dw_to < dw_from and (dw_from % dw_to) != 0:
raise ValueError("Master data width must be a multiple of {dw}".format(dw=dw_to)) raise ValueError("Master data width must be a multiple of {dw}".format(dw=dw_to))
# Split address: # Address Split.
# TAG | LINE NUMBER | LINE OFFSET # --------------
offsetbits = log2_int(max(dw_to//dw_from, 1)) # TAG | LINE NUMBER | LINE OFFSET.
addressbits = len(slave.adr) + offsetbits offsetbits = log2_int(max(dw_to//dw_from, 1))
linebits = log2_int(cachesize) - offsetbits addressbits = len(slave.adr) + offsetbits
tagbits = addressbits - linebits linebits = log2_int(cachesize) - offsetbits
wordbits = log2_int(max(dw_from//dw_to, 1)) tagbits = addressbits - linebits
wordbits = log2_int(max(dw_from//dw_to, 1))
adr_offset, adr_line, adr_tag = split(master.adr, offsetbits, linebits, tagbits) adr_offset, adr_line, adr_tag = split(master.adr, offsetbits, linebits, tagbits)
word = Signal(wordbits) if wordbits else None word = Signal(wordbits) if wordbits else None
# Data memory # Data Memory.
data_mem = Memory(dw_to*2**wordbits, 2**linebits) # ------------
data_mem = Memory(dw_to*2**wordbits, 2**linebits)
data_port = data_mem.get_port(write_capable=True, we_granularity=8) data_port = data_mem.get_port(write_capable=True, we_granularity=8)
self.specials += data_mem, data_port self.specials += data_mem, data_port
@ -696,10 +700,11 @@ class Cache(LiteXModule):
] ]
# Tag memory # Tag memory.
# -----------
tag_layout = [("tag", tagbits), ("dirty", 1)] tag_layout = [("tag", tagbits), ("dirty", 1)]
tag_mem = Memory(layout_len(tag_layout), 2**linebits) tag_mem = Memory(layout_len(tag_layout), 2**linebits)
tag_port = tag_mem.get_port(write_capable=True) tag_port = tag_mem.get_port(write_capable=True)
self.specials += tag_mem, tag_port self.specials += tag_mem, tag_port
tag_do = Record(tag_layout) tag_do = Record(tag_layout)
tag_di = Record(tag_layout) tag_di = Record(tag_layout)
@ -717,17 +722,19 @@ class Cache(LiteXModule):
else: else:
self.comb += slave.adr.eq(Cat(adr_line, tag_do.tag)) self.comb += slave.adr.eq(Cat(adr_line, tag_do.tag))
# slave word computation, word_clr and word_inc will be simplified # Slave word compute.
# at synthesis when wordbits=0 # -------------------
# word_clr and word_inc will be simplified at synthesis when wordbits=0.
word_clr = Signal() word_clr = Signal()
word_inc = Signal() word_inc = Signal()
if word is not None: if word is not None:
self.sync += \ self.sync += [
If(word_clr, If(word_clr,
word.eq(0), word.eq(0),
).Elif(word_inc, ).Elif(word_inc,
word.eq(word+1) word.eq(word+1)
) )
]
def word_is_last(word): def word_is_last(word):
if word is not None: if word is not None:
@ -735,7 +742,8 @@ class Cache(LiteXModule):
else: else:
return 1 return 1
# Control FSM # FSM.
# ----
self.fsm = fsm = FSM(reset_state="IDLE") self.fsm = fsm = FSM(reset_state="IDLE")
fsm.act("IDLE", fsm.act("IDLE",
If(master.cyc & master.stb, If(master.cyc & master.stb,