diff --git a/src/main/scala/tilelink/AtomicAutomata.scala b/src/main/scala/tilelink/AtomicAutomata.scala index de2604a9..201f0569 100644 --- a/src/main/scala/tilelink/AtomicAutomata.scala +++ b/src/main/scala/tilelink/AtomicAutomata.scala @@ -190,6 +190,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc } // We need to deal with a potential D response in the same cycle as the A request + val d_first = edgeOut.first(out.d) val d_cam_sel_raw = cam_a.map(_.bits.source === in.d.bits.source) val d_cam_sel_match = (d_cam_sel_raw zip cam_dmatch) map { case (a,b) => a&&b } val d_cam_data = Mux1H(d_cam_sel_match, cam_d.map(_.data)) @@ -200,7 +201,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc val d_ackd = out.d.bits.opcode === TLMessages.AccessAckData val d_ack = out.d.bits.opcode === TLMessages.AccessAck - when (out.d.fire()) { + when (out.d.fire() && d_first) { (d_cam_sel zip cam_d) foreach { case (en, r) => when (en && d_ackd) { r.data := out.d.bits.data @@ -214,8 +215,8 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc } } - val d_drop = d_ackd && d_cam_sel_any - val d_replace = d_ack && d_cam_sel_match.reduce(_ || _) + val d_drop = d_first && d_ackd && d_cam_sel_any + val d_replace = d_first && d_ack && d_cam_sel_match.reduce(_ || _) in.d.valid := out.d.valid && !d_drop out.d.ready := in.d.ready || d_drop