tilelink: fix AtomicAutomata bug wrt early source reuse
The new fuzzer already found it's first victim.
This commit is contained in:
parent
6550ae2e31
commit
d096d5d1c4
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user