axi4: add a Delayer for unit tests
This commit is contained in:
parent
1902ba063a
commit
bfc0ba679a
83
src/main/scala/amba/axi4/Delayer.scala
Normal file
83
src/main/scala/amba/axi4/Delayer.scala
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
|
||||||
|
package freechips.rocketchip.amba.axi4
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
import chisel3.util.IrrevocableIO
|
||||||
|
import freechips.rocketchip.config.Parameters
|
||||||
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.tilelink.LFSRNoiseMaker
|
||||||
|
|
||||||
|
// q is the probability to delay a request
|
||||||
|
class AXI4Delayer(q: Double)(implicit p: Parameters) extends LazyModule
|
||||||
|
{
|
||||||
|
val node = AXI4AdapterNode()
|
||||||
|
require (0.0 <= q && q < 1)
|
||||||
|
|
||||||
|
lazy val module = new LazyModuleImp(this) {
|
||||||
|
def feed[T <: Data](sink: IrrevocableIO[T], source: IrrevocableIO[T], noise: T) {
|
||||||
|
// irrevocable requires that we not lower valid
|
||||||
|
val hold = RegInit(Bool(false))
|
||||||
|
when (sink.valid) { hold := Bool(true) }
|
||||||
|
when (sink.fire()) { hold := Bool(false) }
|
||||||
|
|
||||||
|
val allow = hold || UInt((q * 65535.0).toInt) <= LFSRNoiseMaker(16, source.valid)
|
||||||
|
sink.valid := source.valid && allow
|
||||||
|
source.ready := sink.ready && allow
|
||||||
|
sink.bits := source.bits
|
||||||
|
when (!sink.valid) { sink.bits := noise }
|
||||||
|
}
|
||||||
|
|
||||||
|
def anoise[T <: AXI4BundleA](bits: T) {
|
||||||
|
bits.id := LFSRNoiseMaker(bits.params.idBits)
|
||||||
|
bits.addr := LFSRNoiseMaker(bits.params.addrBits)
|
||||||
|
bits.len := LFSRNoiseMaker(bits.params.lenBits)
|
||||||
|
bits.size := LFSRNoiseMaker(bits.params.sizeBits)
|
||||||
|
bits.burst := LFSRNoiseMaker(bits.params.burstBits)
|
||||||
|
bits.lock := LFSRNoiseMaker(bits.params.lockBits)
|
||||||
|
bits.cache := LFSRNoiseMaker(bits.params.cacheBits)
|
||||||
|
bits.prot := LFSRNoiseMaker(bits.params.protBits)
|
||||||
|
bits.qos := LFSRNoiseMaker(bits.params.qosBits)
|
||||||
|
if (bits.params.userBits > 0)
|
||||||
|
bits.user.get := LFSRNoiseMaker(bits.params.userBits)
|
||||||
|
}
|
||||||
|
|
||||||
|
(node.in zip node.out) foreach { case ((in, _), (out, _)) =>
|
||||||
|
val arnoise = Wire(in.ar.bits)
|
||||||
|
val awnoise = Wire(in.aw.bits)
|
||||||
|
val wnoise = Wire(in.w .bits)
|
||||||
|
val rnoise = Wire(in.r .bits)
|
||||||
|
val bnoise = Wire(in.b .bits)
|
||||||
|
|
||||||
|
anoise(arnoise)
|
||||||
|
anoise(awnoise)
|
||||||
|
|
||||||
|
wnoise.data := LFSRNoiseMaker(wnoise.params.dataBits)
|
||||||
|
wnoise.strb := LFSRNoiseMaker(wnoise.params.dataBits/8)
|
||||||
|
wnoise.last := LFSRNoiseMaker(1)(0)
|
||||||
|
|
||||||
|
rnoise.id := LFSRNoiseMaker(rnoise.params.idBits)
|
||||||
|
rnoise.data := LFSRNoiseMaker(rnoise.params.dataBits)
|
||||||
|
rnoise.resp := LFSRNoiseMaker(rnoise.params.respBits)
|
||||||
|
rnoise.last := LFSRNoiseMaker(1)(0)
|
||||||
|
if (rnoise.params.userBits > 0)
|
||||||
|
rnoise.user.get := LFSRNoiseMaker(rnoise.params.userBits)
|
||||||
|
|
||||||
|
bnoise.id := LFSRNoiseMaker(bnoise.params.idBits)
|
||||||
|
bnoise.resp := LFSRNoiseMaker(bnoise.params.respBits)
|
||||||
|
if (bnoise.params.userBits > 0)
|
||||||
|
bnoise.user.get := LFSRNoiseMaker(bnoise.params.userBits)
|
||||||
|
|
||||||
|
feed(out.ar, in.ar, arnoise)
|
||||||
|
feed(out.aw, in.aw, awnoise)
|
||||||
|
feed(out.w, in.w, wnoise)
|
||||||
|
feed(in.b, out.b, bnoise)
|
||||||
|
feed(in.r, out.r, rnoise)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object AXI4Delayer
|
||||||
|
{
|
||||||
|
def apply(q: Double)(implicit p: Parameters): AXI4Node = LazyModule(new AXI4Delayer(q)).node
|
||||||
|
}
|
@ -22,8 +22,8 @@ object AXI4Imp extends SimpleNodeImp[AXI4MasterPortParameters, AXI4SlavePortPara
|
|||||||
case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends SourceNode(AXI4Imp)(portParams)
|
case class AXI4MasterNode(portParams: Seq[AXI4MasterPortParameters])(implicit valName: ValName) extends SourceNode(AXI4Imp)(portParams)
|
||||||
case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends SinkNode(AXI4Imp)(portParams)
|
case class AXI4SlaveNode(portParams: Seq[AXI4SlavePortParameters])(implicit valName: ValName) extends SinkNode(AXI4Imp)(portParams)
|
||||||
case class AXI4AdapterNode(
|
case class AXI4AdapterNode(
|
||||||
masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters,
|
masterFn: AXI4MasterPortParameters => AXI4MasterPortParameters = { m => m },
|
||||||
slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters,
|
slaveFn: AXI4SlavePortParameters => AXI4SlavePortParameters = { s => s },
|
||||||
numPorts: Range.Inclusive = 0 to 999)(
|
numPorts: Range.Inclusive = 0 to 999)(
|
||||||
implicit valName: ValName)
|
implicit valName: ValName)
|
||||||
extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts)
|
extends AdapterNode(AXI4Imp)(masterFn, slaveFn, numPorts)
|
||||||
|
Loading…
Reference in New Issue
Block a user