From a73e6837d6d811d64356400f402dc7ea0a779a39 Mon Sep 17 00:00:00 2001 From: Donggyu Kim Date: Thu, 16 Oct 2014 19:27:46 -0700 Subject: [PATCH] [MIDAS] elaborate daisy chain checking in tester --- src/main/scala/DaisyShim.scala | 15 +++-- src/main/scala/DaisyTester.scala | 100 +++++++++++++++---------------- 2 files changed, 60 insertions(+), 55 deletions(-) diff --git a/src/main/scala/DaisyShim.scala b/src/main/scala/DaisyShim.scala index 8314fe70..1bcc7e46 100644 --- a/src/main/scala/DaisyShim.scala +++ b/src/main/scala/DaisyShim.scala @@ -83,7 +83,7 @@ class DaisyShim[+T <: Module](c: =>T) extends Module with DaisyShimParams with D val outputBufs = Vec.fill(outputs.length) { Reg(UInt()) } // Step counters for simulation run or stall - val debug_IDLE :: debug_STEP :: debug_SNAP1 :: debug_SNAP2 :: debug_POKE :: debug_PEEK :: Nil = Enum(UInt(), 6) + val debug_IDLE :: debug_STEP :: debug_SNAP0 :: debug_SNAP1 :: debug_SNAP2 :: debug_POKE :: debug_PEEK :: Nil = Enum(UInt(), 7) val debugState = Reg(init=debug_IDLE) val snap_IDLE :: snap_READ :: snap_MEM_CMD :: snap_MEM_WR :: Nil = Enum(UInt(), 4) val snapState = Reg(init=snap_IDLE) @@ -163,9 +163,7 @@ class DaisyShim[+T <: Module](c: =>T) extends Module with DaisyShimParams with D peekCounter := UInt(outputs.length) debugState := debug_PEEK }.elsewhen(op === SNAP) { - val addr = io.host.in.bits(hostwidth-1, opwidth) - snapMemAddr := addr - isSnap := Bool(true) + debugState := debug_SNAP0; } } } @@ -186,6 +184,15 @@ class DaisyShim[+T <: Module](c: =>T) extends Module with DaisyShimParams with D } } } + // Snapshotting initialization (set mem addr) + is(debug_SNAP0) { + io.host.in.ready := Bool(true) + when (io.host.in.fire()) { + snapMemAddr := io.host.in.bits + debugState := debug_IDLE + isSnap := Bool(true) + } + } // Snapshotring inputs and registers is(debug_SNAP1) { switch(snapState) { diff --git a/src/main/scala/DaisyTester.scala b/src/main/scala/DaisyTester.scala index 93a500b9..532e6c1e 100644 --- a/src/main/scala/DaisyTester.scala +++ b/src/main/scala/DaisyTester.scala @@ -11,13 +11,16 @@ abstract class DaisyTester[+T <: DaisyShim[Module]](c: T, isTrace: Boolean = tru val peekMap = HashMap[BigInt, BigInt]() val chainNames = ArrayBuffer[String]() val chainWidths = ArrayBuffer[Int]() - val snaps = new StringBuilder + val replay = new StringBuilder + val snapPaddr = BigInt(Integer.parseInt("40000000", 16)) + var snapData = BigInt(0) + var snapDataSize = 0 + var snapLength = 0 lazy val targetPath = c.target.getPathName(".") lazy val targetPrefix = Driver.backend.extractClassName(c.target) lazy val basedir = ensureDir(Driver.targetDir) - override def poke(data: Bits, x: BigInt) { if (inputMap contains dumpName(data)) { if (isTrace) println("* POKE " + dumpName(data) + " <- " + x + " *") @@ -51,6 +54,26 @@ abstract class DaisyTester[+T <: DaisyShim[Module]](c: T, isTrace: Boolean = tru val clk = emulatorCmd("step %d".format(n)) } + def pokeSnap(addr: BigInt) { + if (isTrace) println("Poke Snap(addr : %d)".format(addr)) + val snapOp = c.SNAP.getNode.asInstanceOf[Literal].value + // Send POKE command + while (peek(dumpName(c.io.host.in.ready)) == 0) { + takeSteps(1) + } + poke(c.io.host.in.bits, snapOp) + poke(c.io.host.in.valid, 1) + takeSteps(1) + poke(c.io.host.in.valid, 0) + while (peek(dumpName(c.io.host.in.ready)) == 0) { + takeSteps(1) + } + poke(c.io.host.in.bits, addr) + poke(c.io.host.in.valid, 1) + takeSteps(1) + poke(c.io.host.in.valid, 0) + if (isTrace) println("==========") + } def pokeAll { val pokeOp = c.POKE.getNode.asInstanceOf[Literal].value @@ -118,33 +141,15 @@ abstract class DaisyTester[+T <: DaisyShim[Module]](c: T, isTrace: Boolean = tru if (isTrace) println("==========") } - def pokeSnap(addr: Int) { - if (isTrace) println("Poke Snap(addr : %d)".format(addr)) - val snapOp = c.SNAP.getNode.asInstanceOf[Literal].value - // Send POKE command - while (peek(dumpName(c.io.host.in.ready)) == 0) { - takeSteps(1) - } - poke(c.io.host.in.bits, (addr << c.opwidth) | snapOp) - poke(c.io.host.in.valid, 1) - takeSteps(1) - poke(c.io.host.in.valid, 0) - if (isTrace) println("==========") - } - - def readDaisyChain(addr: Int) = { - if (isTrace) println("Read State Daisy Chain") - - // Read daisy chain - val res = new StringBuilder - var start = false + def readDaisyChain { + if (isTrace) println("Read Daisy Chain") var offset = 0 while (peek(dumpName(c.io.host.in.ready)) == 0) { takeSteps(1) // Mem request command if (peek(dumpName(c.io.mem.req_cmd.valid)) == 1) { poke(c.io.mem.req_cmd.ready, 1) - expect(c.io.mem.req_cmd.bits.addr, addr + offset) + expect(c.io.mem.req_cmd.bits.addr, snapPaddr + offset) expect(c.io.mem.req_cmd.bits.rw, 1) expect(c.io.mem.req_cmd.bits.tag, 0) takeSteps(1) @@ -154,23 +159,18 @@ abstract class DaisyTester[+T <: DaisyShim[Module]](c: T, isTrace: Boolean = tru // Mem request data if (peek(dumpName(c.io.mem.req_data.valid)) == 1) { poke(c.io.mem.req_data.ready, 1) - val value = peek(c.io.mem.req_data.bits.data) - val fromChain = value.toString(2).reverse.padTo(c.memwidth, '0').reverse - res append fromChain + snapData = snapData << c.memwidth | peek(c.io.mem.req_data.bits.data) takeSteps(1) poke(c.io.mem.req_data.ready, 0) } } poke(c.io.mem.req_cmd.ready, 0) poke(c.io.mem.req_data.ready, 0) - if (isTrace) println("Chain: " + res.result) - res.result + if (isTrace) println("Chain: " + snapData.toString(2)) } - def verifyDaisyChain(chain: String) { + def verifyDaisyChain { val MemRegex = """([\w\.]+)\[(\d+)\]""".r - var value = BigInt(0) - var start = 0 for ((chainName, i) <- chainNames.zipWithIndex) { val width = chainWidths(i) if (chainName != "null") { @@ -180,37 +180,35 @@ abstract class DaisyTester[+T <: DaisyShim[Module]](c: T, isTrace: Boolean = tru peek(name, idx.toInt) case _ => peek(path) - } - val end = math.min(start + width, chain.length) - val fromChain = chain.substring(start, end) - val fromSignal = value.toString(2).reverse.padTo(width, '0').reverse - expect(fromChain == fromSignal, "Snapshot %s(%s?=%s)".format(chainName, fromChain, fromSignal)) - snaps append "POKE %s %d\n".format(chainName, value) + } + val mask = snapData & ((BigInt(1) << width) - 1) + expect(mask == value, "Snapshot %s(%d?=%d)".format(chainName, mask, value)) + replay append "POKE %s %d\n".format(chainName, value) } - start += width + snapData = snapData >> width } } def addExpected { for (out <- c.outputs) { val name = targetPrefix + (dumpName(out) stripPrefix targetPath) - snaps append "EXPECT %s %d\n".format(name, peek(out)) + replay append "EXPECT %s %d\n".format(name, peek(out)) } } override def step(n: Int = 1) { val target = t + n - pokeAll - - var addr = 0 - for (i <- 0 until (c.addrwidth >> 1)) { - addr = (addr << 1) | rnd.nextInt(2) + if (t > 0) { + pokeSnap(snapPaddr) } - if (t > 0) pokeSnap(addr) + pokeAll pokeSteps(n) takeSteps(n) - if (t > 0) verifyDaisyChain(readDaisyChain(addr)) - snaps append "STEP %d\n".format(n) + if (t > 0) { + readDaisyChain + verifyDaisyChain + } + replay append "STEP %d\n".format(n) if (isTrace) println("STEP " + n + " -> " + target) peekAll @@ -244,16 +242,16 @@ abstract class DaisyTester[+T <: DaisyShim[Module]](c: T, isTrace: Boolean = tru val lines = scala.io.Source.fromFile(basedir + "/" + filename).getLines for (line <- lines) { val tokens = line split " " - chainNames += tokens.head - chainWidths += tokens.last.toInt + chainNames prepend tokens.head + chainWidths prepend tokens.last.toInt } } override def finish = { - val filename = targetPrefix + ".snaps" + val filename = targetPrefix + ".replay" val snapfile = createOutputFile(filename) try { - snapfile write snaps.result + snapfile write replay.result } finally { snapfile.close }