Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 8c03cb049156
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 29ed3918cce9
Choose a head ref
  • 2 commits
  • 2 files changed
  • 2 contributors

Commits on Apr 18, 2014

  1. Copy the full SHA
    86f852a View commit details
  2. Copy the full SHA
    29ed391 View commit details
Showing with 54 additions and 20 deletions.
  1. +52 −19 migen/bus/wishbone2lasmi.py
  2. +2 −1 migen/fhdl/structure.py
71 changes: 52 additions & 19 deletions migen/bus/wishbone2lasmi.py
Original file line number Diff line number Diff line change
@@ -6,29 +6,29 @@

# cachesize (in 32-bit words) is the size of the data store, must be a power of 2
class WB2LASMI(Module):
def __init__(self, cachesize, lasmim, wbm=None):
if wbm is None:
wbm = wishbone.Interface()
self.wishbone = wbm
def __init__(self, cachesize, lasmim):
self.wishbone = wishbone.Interface()

###

data_width = flen(self.wishbone.dat_r)
if lasmim.dw < data_width:
raise ValueError("LASMI data width must be >= {dw}".format(dw=data_width))
if (lasmim.dw % data_width) != 0:
if lasmim.dw > data_width and (lasmim.dw % data_width) != 0:
raise ValueError("LASMI data width must be a multiple of {dw}".format(dw=data_width))
if lasmim.dw < data_width and (data_width % lasmim.dw) != 0:
raise ValueError("WISHBONE data width must be a multiple of {dw}".format(dw=lasmim.dw))

# Split address:
# TAG | LINE NUMBER | LINE OFFSET
offsetbits = log2_int(lasmim.dw//data_width)
offsetbits = log2_int(max(lasmim.dw//data_width, 1))
addressbits = lasmim.aw + offsetbits
linebits = log2_int(cachesize) - offsetbits
tagbits = addressbits - linebits
wordbits = data_width//lasmim.dw
adr_offset, adr_line, adr_tag = split(self.wishbone.adr, offsetbits, linebits, tagbits)
word = Signal(wordbits) if wordbits else None

# Data memory
data_mem = Memory(lasmim.dw, 2**linebits)
data_mem = Memory(lasmim.dw*2**wordbits, 2**linebits)
data_port = data_mem.get_port(write_capable=True, we_granularity=8)
self.specials += data_mem, data_port

@@ -43,16 +43,16 @@ def __init__(self, cachesize, lasmim, wbm=None):
self.comb += [
data_port.adr.eq(adr_line),
If(write_from_lasmi,
data_port.dat_w.eq(lasmim.dat_r),
data_port.we.eq(Replicate(1, lasmim.dw//8))
displacer(lasmim.dat_r, word, data_port.dat_w),
displacer(Replicate(1, lasmim.dw//8), word, data_port.we)
).Else(
data_port.dat_w.eq(Replicate(self.wishbone.dat_w, lasmim.dw//data_width)),
data_port.dat_w.eq(Replicate(self.wishbone.dat_w, max(lasmim.dw//data_width, 1))),
If(self.wishbone.cyc & self.wishbone.stb & self.wishbone.we & self.wishbone.ack,
displacer(self.wishbone.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True)
)
),
If(write_to_lasmi,
lasmim.dat_w.eq(data_port.dat_r),
chooser(data_port.dat_r, word, lasmim.dat_w),
lasmim.dat_we.eq(2**(lasmim.dw//8)-1)
),
chooser(data_port.dat_r, adr_offset_r, self.wishbone.dat_r, reverse=True)
@@ -73,13 +73,34 @@ def __init__(self, cachesize, lasmim, wbm=None):

self.comb += [
tag_port.adr.eq(adr_line),
tag_di.tag.eq(adr_tag),
lasmim.adr.eq(Cat(adr_line, tag_do.tag))
tag_di.tag.eq(adr_tag)
]

if word is not None:
self.comb += lasmim.adr.eq(Cat(word, adr_line, tag_do.tag))
else:
self.comb += lasmim.adr.eq(Cat(adr_line, tag_do.tag))

# Lasmim word computation, word_clr and word_inc will be simplified
# at synthesis when wordbits=0
word_clr = Signal()
word_inc = Signal()
if word is not None:
self.sync += \
If(word_clr,
word.eq(0),
).Elif(word_inc,
word.eq(word+1)
)

def word_is_last(word):
if word is not None:
return word == 2**wordbits-1
else:
return 1

# Control FSM
assert(lasmim.write_latency >= 1 and lasmim.read_latency >= 1)
fsm = FSM()
fsm = FSM(reset_state="IDLE")
self.submodules += fsm

fsm.delayed_enter("EVICT_DATAD", "EVICT_DATA", lasmim.write_latency-1)
@@ -89,6 +110,7 @@ def __init__(self, cachesize, lasmim, wbm=None):
If(self.wishbone.cyc & self.wishbone.stb, NextState("TEST_HIT"))
)
fsm.act("TEST_HIT",
word_clr.eq(1),
If(tag_do.tag == adr_tag,
self.wishbone.ack.eq(1),
If(self.wishbone.we,
@@ -115,12 +137,18 @@ def __init__(self, cachesize, lasmim, wbm=None):
)
fsm.act("EVICT_DATA",
write_to_lasmi.eq(1),
NextState("REFILL_WRTAG")
word_inc.eq(1),
If(word_is_last(word),
NextState("REFILL_WRTAG"),
).Else(
NextState("EVICT_REQUEST")
)
)

fsm.act("REFILL_WRTAG",
# Write the tag first to set the LASMI address
tag_port.we.eq(1),
word_clr.eq(1),
NextState("REFILL_REQUEST")
)
fsm.act("REFILL_REQUEST",
@@ -132,5 +160,10 @@ def __init__(self, cachesize, lasmim, wbm=None):
)
fsm.act("REFILL_DATA",
write_from_lasmi.eq(1),
NextState("TEST_HIT")
word_inc.eq(1),
If(word_is_last(word),
NextState("TEST_HIT"),
).Else(
NextState("REFILL_REQUEST")
)
)
3 changes: 2 additions & 1 deletion migen/fhdl/structure.py
Original file line number Diff line number Diff line change
@@ -262,7 +262,8 @@ def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_over
self.nbits, self.signed = bits_sign
else:
self.nbits, self.signed = bits_sign, False
assert(isinstance(self.nbits, int))
if not isinstance(self.nbits, int) or self.nbits <= 0:
raise ValueError("Signal width must be a strictly positive integer")

self.variable = variable # deprecated
self.reset = reset