ahb: ignore hrdata on an AHB error
From the AHB spec: "A slave only has to provide valid data when a transfer completes with an OKAY response. ERROR responses do not require valid read data."
This commit is contained in:
parent
6318d7d44c
commit
45a904b396
@ -49,7 +49,7 @@ class AHBFuzzMaster(aFlow: Boolean, txns: Int)(implicit p: Parameters) extends L
|
|||||||
{
|
{
|
||||||
val node = AHBIdentityNode()
|
val node = AHBIdentityNode()
|
||||||
val fuzz = LazyModule(new TLFuzzer(txns, overrideAddress = Some(fuzzAddr)))
|
val fuzz = LazyModule(new TLFuzzer(txns, overrideAddress = Some(fuzzAddr)))
|
||||||
val model = LazyModule(new TLRAMModel("AHBFuzzMaster"))
|
val model = LazyModule(new TLRAMModel("AHBFuzzMaster", ignoreErrorData=true))
|
||||||
|
|
||||||
(node
|
(node
|
||||||
:= TLToAHB(aFlow)
|
:= TLToAHB(aFlow)
|
||||||
|
@ -106,6 +106,13 @@ class AHBToTL()(implicit p: Parameters) extends LazyModule
|
|||||||
out.a.bits.mask := MaskGen(d_addr, d_size, beatBytes)
|
out.a.bits.mask := MaskGen(d_addr, d_size, beatBytes)
|
||||||
|
|
||||||
out.d.ready := d_recv // backpressure AccessAckData arriving faster than AHB beats
|
out.d.ready := d_recv // backpressure AccessAckData arriving faster than AHB beats
|
||||||
|
|
||||||
|
// NOTE: on error, we present the read result on the hreadyout LOW cycle
|
||||||
|
// This means that if you latch hrdata from an error, the result is garbage.
|
||||||
|
// To fix this would require a bus-wide register, and the AHB spec says this:
|
||||||
|
// "A slave only has to provide valid data when a transfer completes with an OKAY
|
||||||
|
// response. ERROR responses do not require valid read data."
|
||||||
|
// Therefore, we choose to accept this slight TL-AHB infidelity.
|
||||||
in.hrdata := out.d.bits.data
|
in.hrdata := out.d.bits.data
|
||||||
|
|
||||||
// In a perfect world, we'd use these signals
|
// In a perfect world, we'd use these signals
|
||||||
|
@ -22,7 +22,7 @@ import freechips.rocketchip.util._
|
|||||||
// put, get, getAck, putAck => ok: detected by getAck (it sees busy>0) impossible for FIFO
|
// put, get, getAck, putAck => ok: detected by getAck (it sees busy>0) impossible for FIFO
|
||||||
// If FIFO, the getAck should check data even if its validity was wiped
|
// If FIFO, the getAck should check data even if its validity was wiped
|
||||||
|
|
||||||
class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
class TLRAMModel(log: String = "", ignoreErrorData: Boolean = false)(implicit p: Parameters) extends LazyModule
|
||||||
{
|
{
|
||||||
val node = TLAdapterNode()
|
val node = TLAdapterNode()
|
||||||
|
|
||||||
@ -288,6 +288,8 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
|||||||
printf(", undefined (concurrent incomplete puts #%d)\n", d_inc(i) - d_dec(i))
|
printf(", undefined (concurrent incomplete puts #%d)\n", d_inc(i) - d_dec(i))
|
||||||
} .elsewhen (!d_fifo && !d_valid) {
|
} .elsewhen (!d_fifo && !d_valid) {
|
||||||
printf(", undefined (concurrent completed put)\n")
|
printf(", undefined (concurrent completed put)\n")
|
||||||
|
} .elsewhen (Bool(ignoreErrorData) && d.error) {
|
||||||
|
printf(", undefined (error result)\n")
|
||||||
} .otherwise {
|
} .otherwise {
|
||||||
printf("\n")
|
printf("\n")
|
||||||
when (shadow.value =/= got) { printf("EXPECTED: 0x%x\n", shadow.value) }
|
when (shadow.value =/= got) { printf("EXPECTED: 0x%x\n", shadow.value) }
|
||||||
@ -303,8 +305,9 @@ class TLRAMModel(log: String = "")(implicit p: Parameters) extends LazyModule
|
|||||||
when ((Cat(race.reverse) & d_mask).orR) { d_no_race := Bool(false) }
|
when ((Cat(race.reverse) & d_mask).orR) { d_no_race := Bool(false) }
|
||||||
when (d_last) {
|
when (d_last) {
|
||||||
val must_match = d_crc_valid && (d_fifo || (d_valid && d_no_race))
|
val must_match = d_crc_valid && (d_fifo || (d_valid && d_no_race))
|
||||||
|
val error = Bool(ignoreErrorData) && d.error
|
||||||
printf(log + " crc = 0x%x %d\n", d_crc, must_match.asUInt)
|
printf(log + " crc = 0x%x %d\n", d_crc, must_match.asUInt)
|
||||||
when (must_match && d_crc =/= d_crc_check) { printf("EXPECTED: 0x%x\n", d_crc_check) }
|
when (!error && must_match && d_crc =/= d_crc_check) { printf("EXPECTED: 0x%x\n", d_crc_check) }
|
||||||
assert (!must_match || d_crc === d_crc_check)
|
assert (!must_match || d_crc === d_crc_check)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user