sync += has_top_r.eq(0)
# Do we have a cycle ?
- with m.If(master.cyc & master.stb):
+ with m.If(master.cyc & master.stb & ~master.ack):
# Stall master until we are done, we are't (yet) pipelining
# this, it's all slow IOs.
sync += master.stall.eq(1)
sync += slave.stb.eq(0)
# And ack & unstall upstream
- sync += master.ack.eq(1)
- if hasattr(master , "stall"):
- sync += master.stall.eq(0)
-
- # Wait for next one
- m.next = "IDLE"
+ # but only if upstream is ready
+ with m.If(master.stb):
+ sync += master.ack.eq(1)
+ if hasattr(master , "stall"):
+ sync += master.stall.eq(0)
+
+ # Wait for next one
+ m.next = "IDLE"
+ with m.Else():
+ # Wait for upstream to become ready
+ m.next = "WAIT_ACK_MASTER_STALL"
with m.State("WAIT_ACK_TOP"):
# If we aren't stalled by the device, clear stb
sync += slave.cyc.eq(0)
sync += slave.stb.eq(0)
- # And ack & unstall upstream
+ # And ack & unstall upstream,
+ # but only if upstream is ready
+ with m.If(master.stb):
+ sync += master.ack.eq(1)
+ if hasattr(master, "stall"):
+ sync += master.stall.eq(0)
+
+ # Wait for next one
+ m.next = "IDLE"
+ with m.Else():
+ # Wait for upstream to become ready
+ m.next = "WAIT_ACK_MASTER_STALL"
+
+ with m.State("WAIT_ACK_MASTER_STALL"):
+ with m.If(master.stb):
+ # Ack & unstall upstream
sync += master.ack.eq(1)
if hasattr(master, "stall"):
sync += master.stall.eq(0)