soc/interconnect/wishbone: Cosmetic cleanup on Cache.
This commit is contained in:
parent
e06045c576
commit
5cd1a57080
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue