From d4aa41345d292e023166a318f128ef8e774ea7e2 Mon Sep 17 00:00:00 2001 From: Martin Schoeberl Date: Mon, 12 Dec 2022 22:42:00 -0800 Subject: [PATCH] s4noc: finihs the Wishbone wrapper plus test --- src/main/scala/soc/CpuInterfaceRV.scala | 2 ++ src/main/scala/wishbone/S4NoCTopWB.scala | 4 +-- ...oneHelper.scala => WishboneIOHelper.scala} | 31 +++++++++++++++++-- src/test/scala/wishbone/WishboneNoCTest.scala | 16 ++++++---- src/test/scala/wishbone/WishboneTest.scala | 7 ++++- 5 files changed, 49 insertions(+), 11 deletions(-) rename src/test/scala/wishbone/{WishboneHelper.scala => WishboneIOHelper.scala} (56%) diff --git a/src/main/scala/soc/CpuInterfaceRV.scala b/src/main/scala/soc/CpuInterfaceRV.scala index cb412dc..616b7e2 100644 --- a/src/main/scala/soc/CpuInterfaceRV.scala +++ b/src/main/scala/soc/CpuInterfaceRV.scala @@ -51,6 +51,7 @@ class CpuInterfaceRV[T <: Data](private val addrWidth: Int, private val dt: T, s def idleReaction() = { when (cp.wr) { + // printf("Write %d to %d\n", cp.wrData, cp.address) when (cp.address === 2.U) { txDestReg := cp.wrData ackReg := true.B @@ -65,6 +66,7 @@ class CpuInterfaceRV[T <: Data](private val addrWidth: Int, private val dt: T, s } } when (cp.rd) { + // printf("Read from %d\n", cp.address) when (cp.address === 0.U) { stateReg := readStatus ackReg := true.B diff --git a/src/main/scala/wishbone/S4NoCTopWB.scala b/src/main/scala/wishbone/S4NoCTopWB.scala index 89b077b..0f16737 100644 --- a/src/main/scala/wishbone/S4NoCTopWB.scala +++ b/src/main/scala/wishbone/S4NoCTopWB.scala @@ -15,10 +15,10 @@ import s4noc.{Config, S4NoCTop} class S4NoCTopWB(conf: Config) extends Module { val io = IO(new Bundle { - val wbPorts = Vec(conf.n, new WishboneIO(4)) + val wbPorts = Vec(conf.n, Flipped(new WishboneIO(4))) }) - val s4noc = new S4NoCTop(conf) + val s4noc = Module(new S4NoCTop(conf)) for (i <- 0 until conf.n) { val wb = Module(new Wrapper(4)) wb.cpuIf.cpuPort <> s4noc.io.cpuPorts(i) diff --git a/src/test/scala/wishbone/WishboneHelper.scala b/src/test/scala/wishbone/WishboneIOHelper.scala similarity index 56% rename from src/test/scala/wishbone/WishboneHelper.scala rename to src/test/scala/wishbone/WishboneIOHelper.scala index cabd74b..1deb9c3 100644 --- a/src/test/scala/wishbone/WishboneHelper.scala +++ b/src/test/scala/wishbone/WishboneIOHelper.scala @@ -3,7 +3,7 @@ package wishbone import chisel3._ import chiseltest._ -class WishboneHelper(wb: WishboneIO, clock: Clock) { +class WishboneIOHelper(wb: WishboneIO, clock: Clock) { private var clockCnt = 0 @@ -25,11 +25,12 @@ class WishboneHelper(wb: WishboneIO, clock: Clock) { clockCnt += 1 time += 1 } - assert(time != timeOut, s"time out on read after $time cycles") + assert(time != timeOut, s"WB: time out on read after $time cycles") } } def read(addr: Int): BigInt = { + // println(s"TB read $addr") wb.addr.poke(addr.U) wb.we.poke(false.B) wb.stb.poke(true.B) @@ -43,14 +44,40 @@ class WishboneHelper(wb: WishboneIO, clock: Clock) { } def write(addr: Int, data: BigInt) = { + // println(s"TB write, addr=$addr data=$data") wb.addr.poke(addr.U) wb.we.poke(true.B) wb.stb.poke(true.B) wb.cyc.poke(true.B) + wb.wrData.poke(data.U) clockCnt += 1 clock.step() wb.we.poke(false.B) waitForAck() wb.cyc.poke(false.B) } + + def setDest(n: Int) = write(2<<2, n) + + def getSender() = read(2<<2) + + // send and receive without status check, may block + def send(data: BigInt) = write(1<<2, data) + + def receive = read(1<<2) + + // The following functions use the IO mapping with status bits add address 0 and data at address 1 + def txRdy = (read(0) & 0x01) != 0 + + def rxAvail = (read(0) & 0x02) != 0 + + def sndWithCheck(data: BigInt) = { + while (!txRdy) {} + send(data) + } + + def rcvWithCheck() = { + while (!rxAvail) {} + receive + } } diff --git a/src/test/scala/wishbone/WishboneNoCTest.scala b/src/test/scala/wishbone/WishboneNoCTest.scala index 8465674..7184315 100644 --- a/src/test/scala/wishbone/WishboneNoCTest.scala +++ b/src/test/scala/wishbone/WishboneNoCTest.scala @@ -4,14 +4,18 @@ package wishbone import chiseltest._ import org.scalatest.flatspec.AnyFlatSpec +import s4noc._ + class WishboneNoCTest extends AnyFlatSpec with ChiselScalatestTester { - behavior of "The Wishbone wrapped S4NOC" + behavior of "NoC Tester" - it should "work with the example device" in { - test(new Hello()) { - d => { - def step() = d.clock.step() - } + "S4NoC in Wishbone" should "have a simple test" in { + test(new S4NoCTopWB(Config(4, 2, 2, 2, 32))) { d => + val helpSnd = new WishboneIOHelper(d.io.wbPorts(0), d.clock) + val helpRcv = new WishboneIOHelper(d.io.wbPorts(3), d.clock) + helpSnd.setDest(3) + helpSnd.send(BigInt("cafebabe", 16)) + assert(helpRcv.receive == BigInt("cafebabe", 16)) } } } \ No newline at end of file diff --git a/src/test/scala/wishbone/WishboneTest.scala b/src/test/scala/wishbone/WishboneTest.scala index 6f3bdce..c9370f9 100644 --- a/src/test/scala/wishbone/WishboneTest.scala +++ b/src/test/scala/wishbone/WishboneTest.scala @@ -70,6 +70,11 @@ class WishboneTest extends AnyFlatSpec with ChiselScalatestTester { step() p.ack.expect(true.B) p.rdData.expect(42.U) + + val wbh = new WishboneIOHelper(d.io.port, d.clock) + wbh.write(0, 0xcafe) + assert(wbh.read(0) == 0xcafe) + } } } @@ -77,7 +82,7 @@ class WishboneTest extends AnyFlatSpec with ChiselScalatestTester { it should "the lock should work" in { test(new WBHardwareLock()) { d => { - val wbh = new WishboneHelper(d.io.port, d.clock) + val wbh = new WishboneIOHelper(d.io.port, d.clock) // grab the lock assert(wbh.read(0) == 1)