1
0

tilelink: fix AtomicAutomata bug wrt early source reuse

The new fuzzer already found it's first victim.
This commit is contained in:
Wesley W. Terpstra 2017-07-26 12:52:29 -07:00
parent 6550ae2e31
commit d096d5d1c4

View File

@ -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 // 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_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_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)) 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_ackd = out.d.bits.opcode === TLMessages.AccessAckData
val d_ack = out.d.bits.opcode === TLMessages.AccessAck 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) => (d_cam_sel zip cam_d) foreach { case (en, r) =>
when (en && d_ackd) { when (en && d_ackd) {
r.data := out.d.bits.data 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_drop = d_first && d_ackd && d_cam_sel_any
val d_replace = d_ack && d_cam_sel_match.reduce(_ || _) val d_replace = d_first && d_ack && d_cam_sel_match.reduce(_ || _)
in.d.valid := out.d.valid && !d_drop in.d.valid := out.d.valid && !d_drop
out.d.ready := in.d.ready || d_drop out.d.ready := in.d.ready || d_drop