Skip to content

Commit

Permalink
lasmi: separate request and data ack to support bankmachine FIFOs (bu…
Browse files Browse the repository at this point in the history
…ggy/incomplete)
  • Loading branch information
Sebastien Bourdeauducq committed Jun 17, 2013
1 parent 5cd0019 commit d6f7b4c
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 38 deletions.
45 changes: 20 additions & 25 deletions migen/actorlib/dma_lasmi.py
Expand Up @@ -11,8 +11,7 @@ def __init__(self, lasmim, fifo_depth=None):
###

if fifo_depth is None:
fifo_depth = lasmim.read_latency + 2
assert(fifo_depth >= lasmim.read_latency)
fifo_depth = lasmim.req_queue_size + lasmim.read_latency + 2

# request issuance
request_enable = Signal()
Expand All @@ -22,8 +21,8 @@ def __init__(self, lasmim, fifo_depth=None):
lasmim.we.eq(0),
lasmim.stb.eq(self.address.stb & request_enable),
lasmim.adr.eq(self.address.payload.a),
self.address.ack.eq(lasmim.ack),
request_issued.eq(lasmim.stb & lasmim.ack)
self.address.ack.eq(lasmim.req_ack),
request_issued.eq(lasmim.stb & lasmim.req_ack)
]

# FIFO reservation level counter
Expand All @@ -44,7 +43,7 @@ def __init__(self, lasmim, fifo_depth=None):
]

# data available
data_available = request_issued
data_available = lasmim.dat_ack
for i in range(lasmim.read_latency):
new_data_available = Signal()
self.sync += new_data_available.eq(data_available)
Expand All @@ -66,42 +65,38 @@ def __init__(self, lasmim, fifo_depth=None):


class Writer(Module):
def __init__(self, lasmim):
def __init__(self, lasmim, fifo_depth=None):
self.address_data = Sink([("a", lasmim.aw), ("d", lasmim.dw)])
self.busy = Signal()

###

if fifo_depth is None:
fifo_depth = lasmim.req_queue_size + lasmim.read_latency + 2

fifo = SyncFIFO(lasmim.dw, fifo_depth)
self.submodules += fifo

self.comb += [
lasmim.we.eq(1),
lasmim.stb.eq(self.address_data.stb),
lasmim.stb.eq(fifo.writable & self.address_data.stb),
lasmim.adr.eq(self.address_data.payload.a),
self.address_data.ack.eq(lasmim.ack)
]

busy_expr = 0
data_valid = Signal()
data = Signal(lasmim.dw)
self.comb += [
data_valid.eq(lasmim.stb & lasmim.ack),
data.eq(self.address_data.payload.d)
self.address_data.ack.eq(fifo.writable & lasmim.req_ack),
fifo.we.eq(self.address_data.stb & lasmim.req_ack),
fifo.din.eq(self.address_data.payload.d)
]

data_valid = lasmim.dat_ack
for i in range(lasmim.write_latency):
new_data_valid = Signal()
new_data = Signal(lasmim.dw)
self.sync += [
new_data_valid.eq(data_valid),
new_data.eq(data)
]
busy_expr = busy_expr | new_data_valid
self.sync += new_data_valid.eq(data_valid),
data_valid = new_data_valid
data = new_data

self.comb += [
fifo.re.eq(data_valid),
If(data_valid,
lasmim.dat_we.eq(2**(lasmim.dw//8)-1),
lasmim.dat_w.eq(data)
lasmim.dat_w.eq(fifo.dout)
),
self.busy.eq(busy_expr)
self.busy.eq(fifo.readable)
]
29 changes: 20 additions & 9 deletions migen/bus/lasmibus.py
Expand Up @@ -5,18 +5,21 @@
from migen.genlib.misc import optree

class Interface(Record):
def __init__(self, aw, dw, nbanks, read_latency, write_latency):
def __init__(self, aw, dw, nbanks, req_queue_size, read_latency, write_latency):
self.aw = aw
self.dw = dw
self.nbanks = nbanks
self.req_queue_size = req_queue_size
self.read_latency = read_latency
self.write_latency = write_latency

bank_layout = [
("adr", aw, DIR_M_TO_S),
("we", 1, DIR_M_TO_S),
("stb", 1, DIR_M_TO_S),
("ack", 1, DIR_S_TO_M)
("req_ack", 1, DIR_S_TO_M),
("dat_ack", 1, DIR_S_TO_M),
("lock", 1, DIR_S_TO_M)
]
if nbanks > 1:
layout = [("bank"+str(i), bank_layout) for i in range(nbanks)]
Expand All @@ -43,12 +46,13 @@ def __init__(self, controllers, nmasters, cba_shift):
rca_bits = _getattr_all(controllers, "aw")
dw = _getattr_all(controllers, "dw")
nbanks = _getattr_all(controllers, "nbanks")
req_queue_size = _getattr_all(controllers, "req_queue_size")
read_latency = _getattr_all(controllers, "read_latency")
write_latency = _getattr_all(controllers, "write_latency")

bank_bits = log2_int(nbanks, False)
controller_bits = log2_int(ncontrollers, False)
self.masters = [Interface(rca_bits + bank_bits + controller_bits, dw, 1, read_latency, write_latency)
self.masters = [Interface(rca_bits + bank_bits + controller_bits, dw, 1, req_queue_size, read_latency, write_latency)
for i in range(nmasters)]

###
Expand All @@ -60,27 +64,34 @@ def __init__(self, controllers, nmasters, cba_shift):
controller_selected = [ca == nc for ca in m_ca]
else:
controller_selected = [1]*nmasters
master_acks = [0]*nmasters
master_req_acks = [0]*nmasters
master_dat_acks = [0]*nmasters
for nb in range(nbanks):
bank = getattr(controller, "bank"+str(nb))

# arbitrate
rr = roundrobin.RoundRobin(nmasters, roundrobin.SP_WITHDRAW)
rr = roundrobin.RoundRobin(nmasters, roundrobin.SP_CE)
self.submodules += rr
bank_selected = [cs & (ba == nb) for cs, ba in zip(controller_selected, m_ba)]
bank_requested = [bs & master.stb for bs, master in zip(bank_selected, self.masters)]
self.comb += rr.request.eq(Cat(*bank_requested)),
self.comb += [
rr.request.eq(Cat(*bank_requested)),
rr.ce.eq(~bank.stb & ~bank.lock)
]

# route requests
self.comb += [
bank.adr.eq(Array(m_rca)[rr.grant]),
bank.we.eq(Array(self.masters)[rr.grant].we),
bank.stb.eq(Array(bank_requested)[rr.grant])
]
master_acks = [master_ack | ((rr.grant == nm) & bank.ack)
for nm, master_ack in enumerate(master_acks)]
master_req_acks = [master_req_ack | ((rr.grant == nm) & Array(bank_selected)[rr.grant] & bank.req_ack)
for nm, master_req_ack in enumerate(master_req_acks)]
master_dat_acks = [master_dat_ack | ((rr.grant == nm) & bank.dat_ack)
for nm, master_dat_ack in enumerate(master_dat_acks)]

self.comb += [master.ack.eq(master_ack) for master, master_ack in zip(self.masters, master_acks)]
self.comb += [master.req_ack.eq(master_req_ack) for master, master_req_ack in zip(self.masters, master_req_acks)]
self.comb += [master.dat_ack.eq(master_dat_ack) for master, master_dat_ack in zip(self.masters, master_dat_acks)]

# route data writes
controller_selected_wl = controller_selected
Expand Down
14 changes: 10 additions & 4 deletions migen/bus/wishbone2lasmi.py
Expand Up @@ -72,8 +72,8 @@ def __init__(self, cachesize, lasmim):
# Control FSM
assert(lasmim.write_latency >= 1 and lasmim.read_latency >= 1)
fsm = FSM("IDLE", "TEST_HIT",
"EVICT_REQUEST", "EVICT_DATA",
"REFILL_WRTAG", "REFILL_REQUEST", "REFILL_DATA",
"EVICT_REQUEST", "EVICT_WAIT_DATA_ACK", "EVICT_DATA",
"REFILL_WRTAG", "REFILL_REQUEST", "REFILL_WAIT_DATA_ACK", "REFILL_DATA",
delayed_enters=[
("EVICT_DATAD", "EVICT_DATA", lasmim.write_latency-1),
("REFILL_DATAD", "REFILL_DATA", lasmim.read_latency-1)
Expand Down Expand Up @@ -103,7 +103,10 @@ def __init__(self, cachesize, lasmim):
fsm.act(fsm.EVICT_REQUEST,
lasmim.stb.eq(1),
lasmim.we.eq(1),
If(lasmim.ack, fsm.next_state(fsm.EVICT_DATAD))
If(lasmim.req_ack, fsm.next_state(fsm.EVICT_WAIT_DATA_ACK))
)
fsm.act(fsm.EVICT_WAIT_DATA_ACK,
If(lasmim.dat_ack, fsm.next_state(fsm.EVICT_DATAD))
)
fsm.act(fsm.EVICT_DATA,
write_to_lasmi.eq(1),
Expand All @@ -117,7 +120,10 @@ def __init__(self, cachesize, lasmim):
)
fsm.act(fsm.REFILL_REQUEST,
lasmim.stb.eq(1),
If(lasmim.ack, fsm.next_state(fsm.REFILL_DATAD))
If(lasmim.req_ack, fsm.next_state(fsm.REFILL_WAIT_DATA_ACK))
)
fsm.act(fsm.REFILL_WAIT_DATA_ACK,
If(lasmim.dat_ack, fsm.next_state(fsm.REFILL_DATAD))
)
fsm.act(fsm.REFILL_DATA,
write_from_lasmi.eq(1),
Expand Down

0 comments on commit d6f7b4c

Please sign in to comment.