diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index 2068e1e1..37ad9047 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -74,6 +74,7 @@ class BasePlatformConfig extends Config( case RTCPeriod => 100 // gives 10 MHz RTC assuming 1 GHz uncore clock case BuildExampleTop => (p: Parameters) => uncore.tilelink2.LazyModule(new ExampleTop(p)) + case SimMemLatency => 0 case _ => throw new CDEMatchError } } diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index bb69e697..15fe6c7c 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -8,6 +8,7 @@ import rocket.Util._ import junctions._ case object BuildExampleTop extends Field[Parameters => ExampleTop] +case object SimMemLatency extends Field[Int] class TestHarness(implicit val p: Parameters) extends Module with HasAddrMapParameters { val io = new Bundle { @@ -33,8 +34,14 @@ class TestHarness(implicit val p: Parameters) extends Module with HasAddrMapPara if (dut.io.mem_axi.nonEmpty) { val memSize = addrMap("mem").size require(memSize % dut.io.mem_axi.size == 0) - for (axi <- dut.io.mem_axi) - Module(new SimAXIMem(memSize / dut.io.mem_axi.size)).io.axi <> axi + for (axi <- dut.io.mem_axi) { + val mem = Module(new SimAXIMem(memSize / dut.io.mem_axi.size)) + mem.io.axi.ar <> axi.ar + mem.io.axi.aw <> axi.aw + mem.io.axi.w <> axi.w + axi.r <> LatencyPipe(mem.io.axi.r, p(SimMemLatency)) + axi.b <> LatencyPipe(mem.io.axi.b, p(SimMemLatency)) + } } if (!p(IncludeJtagDTM)) { @@ -65,7 +72,7 @@ class TestHarness(implicit val p: Parameters) extends Module with HasAddrMapPara } -class SimAXIMem(size: BigInt)(implicit p: Parameters) extends Module { +class SimAXIMem(size: BigInt)(implicit p: Parameters) extends NastiModule()(p) { val io = new Bundle { val axi = new NastiIO().flip } @@ -82,8 +89,8 @@ class SimAXIMem(size: BigInt)(implicit p: Parameters) extends Module { } val w = io.axi.w.bits - require((size * 8) % w.data.getWidth == 0) - val depth = (size * 8) / w.data.getWidth + require((size * 8) % nastiXDataBits == 0) + val depth = (size * 8) / nastiXDataBits val mem = Mem(depth.toInt, w.data) val wValid = Reg(init = Bool(false)) @@ -102,7 +109,7 @@ class SimAXIMem(size: BigInt)(implicit p: Parameters) extends Module { bValid := true } - def row = mem((aw.addr >> log2Ceil(w.data.getWidth/8))(log2Ceil(depth)-1, 0)) + def row = mem((aw.addr >> log2Ceil(nastiXDataBits/8))(log2Ceil(depth)-1, 0)) val mask = FillInterleaved(8, w.strb) val newData = mask & w.data | ~mask & row row := newData @@ -114,7 +121,7 @@ class SimAXIMem(size: BigInt)(implicit p: Parameters) extends Module { io.axi.r.valid := rValid io.axi.r.bits.id := ar.id - io.axi.r.bits.data := mem((ar.addr >> log2Ceil(w.data.getWidth/8))(log2Ceil(depth)-1, 0)) + io.axi.r.bits.data := mem((ar.addr >> log2Ceil(nastiXDataBits/8))(log2Ceil(depth)-1, 0)) io.axi.r.bits.resp := UInt(0) io.axi.r.bits.last := ar.len === UInt(0) } @@ -167,3 +174,11 @@ class JTAGVPI(implicit val p: Parameters) extends BlackBox { tbsuccess := Bool(false) } } + +object LatencyPipe { + def doN[T](n: Int, func: T => T, in: T): T = + (0 until n).foldLeft(in)((last, _) => func(last)) + + def apply[T <: Data](in: DecoupledIO[T], latency: Int): DecoupledIO[T] = + doN(latency, (last: DecoupledIO[T]) => Queue(last, 1, pipe=true), in) +}