Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
View
45 migen/actorlib/dma_lasmi.py
@@ -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()
@@ -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
@@ -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)
@@ -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)
]
View
29 migen/bus/lasmibus.py
@@ -5,10 +5,11 @@
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
@@ -16,7 +17,9 @@ def __init__(self, aw, dw, nbanks, read_latency, write_latency):
("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)]
@@ -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)]
###
@@ -60,16 +64,20 @@ 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 += [
@@ -77,10 +85,13 @@ def __init__(self, controllers, nmasters, cba_shift):
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
View
14 migen/bus/wishbone2lasmi.py
@@ -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)
@@ -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),
@@ -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),
View
38 migen/genlib/fifo.py
@@ -1,5 +1,6 @@
from migen.fhdl.std import *
from migen.genlib.cdc import NoRetiming, MultiReg, GrayCounter
+from migen.genlib.record import layout_len, Record
def _inc(signal, modulo):
if modulo == 2**flen(signal):
@@ -12,17 +13,28 @@ def _inc(signal, modulo):
)
class _FIFOInterface:
- def __init__(self, width, depth):
- self.din = Signal(width)
+ def __init__(self, width_or_layout, depth):
self.we = Signal()
self.writable = Signal() # not full
- self.dout = Signal(width)
self.re = Signal()
self.readable = Signal() # not empty
+ if isinstance(width_or_layout, list):
+ self.din = Record(width_or_layout)
+ self.dout = Record(width_or_layout)
+ self.din_bits = self.din.raw_bits()
+ self.dout_bits = self.dout.raw_bits()
+ self.width = layout_len(width_or_layout)
+ else:
+ self.din = Signal(width_or_layout)
+ self.dout = Signal(width_or_layout)
+ self.din_bits = self.din
+ self.dout_bits = self.dout
+ self.width = width_or_layout
+
class SyncFIFO(Module, _FIFOInterface):
- def __init__(self, width, depth):
- _FIFOInterface.__init__(self, width, depth)
+ def __init__(self, width_or_layout, depth):
+ _FIFOInterface.__init__(self, width_or_layout, depth)
###
@@ -36,14 +48,14 @@ def __init__(self, width, depth):
level = Signal(max=depth+1)
produce = Signal(max=depth)
consume = Signal(max=depth)
- storage = Memory(width, depth)
+ storage = Memory(self.width, depth)
self.specials += storage
wrport = storage.get_port(write_capable=True)
self.specials += wrport
self.comb += [
wrport.adr.eq(produce),
- wrport.dat_w.eq(self.din),
+ wrport.dat_w.eq(self.din_bits),
wrport.we.eq(do_write)
]
self.sync += If(do_write, _inc(produce, depth))
@@ -52,7 +64,7 @@ def __init__(self, width, depth):
self.specials += rdport
self.comb += [
rdport.adr.eq(consume),
- self.dout.eq(rdport.dat_r)
+ self.dout_bits.eq(rdport.dat_r)
]
self.sync += If(do_read, _inc(consume, depth))
@@ -69,8 +81,8 @@ def __init__(self, width, depth):
]
class AsyncFIFO(Module, _FIFOInterface):
- def __init__(self, width, depth):
- _FIFOInterface.__init__(self, width, depth)
+ def __init__(self, width_or_layout, depth):
+ _FIFOInterface.__init__(self, width_or_layout, depth)
###
@@ -102,18 +114,18 @@ def __init__(self, width, depth):
self.readable.eq(consume.q != produce_rdomain)
]
- storage = Memory(width, depth)
+ storage = Memory(self.width, depth)
self.specials += storage
wrport = storage.get_port(write_capable=True, clock_domain="write")
self.specials += wrport
self.comb += [
wrport.adr.eq(produce.q_binary[:-1]),
- wrport.dat_w.eq(self.din),
+ wrport.dat_w.eq(self.din_bits),
wrport.we.eq(produce.ce)
]
rdport = storage.get_port(clock_domain="read")
self.specials += rdport
self.comb += [
rdport.adr.eq(consume.q_binary[:-1]),
- self.dout.eq(rdport.dat_r)
+ self.dout_bits.eq(rdport.dat_r)
]

No commit comments for this range

Something went wrong with that request. Please try again.