First cut at refactoring unittests into a top-level utility. Individual tests co-located with their DUT. No functional changes.
This commit is contained in:
parent
dfd6bfb454
commit
7dd4492abb
@ -8,9 +8,8 @@ import uncore.tilelink._
|
||||
import uncore.coherence._
|
||||
import uncore.agents._
|
||||
import uncore.devices.NTiles
|
||||
import uncore.unittests._
|
||||
import unittest._
|
||||
import junctions._
|
||||
import junctions.unittests._
|
||||
import scala.collection.mutable.LinkedHashSet
|
||||
import cde.{Parameters, Config, Dump, Knob, CDEMatchError}
|
||||
import scala.math.max
|
||||
|
@ -1,7 +1,7 @@
|
||||
package coreplex
|
||||
|
||||
import Chisel._
|
||||
import junctions.unittests.UnitTestSuite
|
||||
import unittest.UnitTestSuite
|
||||
import rocket.Tile
|
||||
import uncore.tilelink.TLId
|
||||
import cde.Parameters
|
||||
|
@ -5,6 +5,7 @@ import uncore.tilelink._
|
||||
import uncore.constants._
|
||||
import junctions._
|
||||
import rocket._
|
||||
import util.Timer
|
||||
import scala.util.Random
|
||||
import cde.{Parameters, Field}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import uncore.devices.NTiles
|
||||
import uncore.constants._
|
||||
import junctions._
|
||||
import rocket._
|
||||
import util.Timer
|
||||
import scala.util.Random
|
||||
import cde.{Parameters, Field}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import Chisel._
|
||||
import uncore.tilelink._
|
||||
import uncore.converters._
|
||||
import junctions._
|
||||
import util.Timer
|
||||
import rocket.TileId
|
||||
import cde.Parameters
|
||||
|
||||
|
@ -5,7 +5,8 @@ import uncore.tilelink._
|
||||
import uncore.constants._
|
||||
import uncore.agents._
|
||||
import uncore.util._
|
||||
import junctions.{ParameterizedBundle, HasAddrMapParameters, Timer}
|
||||
import junctions.{ParameterizedBundle, HasAddrMapParameters}
|
||||
import util.Timer
|
||||
import rocket.HellaCacheIO
|
||||
import cde.{Parameters, Field}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import uncore.constants._
|
||||
import uncore.devices.NTiles
|
||||
import junctions._
|
||||
import rocket._
|
||||
import util.{Timer, DynamicTimer}
|
||||
import scala.util.Random
|
||||
import cde.{Parameters, Field}
|
||||
|
||||
|
@ -2,35 +2,6 @@ package groundtest
|
||||
|
||||
import Chisel._
|
||||
|
||||
// =============
|
||||
// Dynamic timer
|
||||
// =============
|
||||
|
||||
// Timer with a dynamically-settable period.
|
||||
|
||||
class DynamicTimer(w: Int) extends Module {
|
||||
val io = new Bundle {
|
||||
val start = Bool(INPUT)
|
||||
val period = UInt(INPUT, w)
|
||||
val stop = Bool(INPUT)
|
||||
val timeout = Bool(OUTPUT)
|
||||
}
|
||||
|
||||
val countdown = Reg(init = UInt(0, w))
|
||||
val active = Reg(init = Bool(false))
|
||||
|
||||
when (io.start) {
|
||||
countdown := io.period
|
||||
active := Bool(true)
|
||||
} .elsewhen (io.stop || countdown === UInt(0)) {
|
||||
active := Bool(false)
|
||||
} .elsewhen (active) {
|
||||
countdown := countdown - UInt(1)
|
||||
}
|
||||
|
||||
io.timeout := countdown === UInt(0) && active
|
||||
}
|
||||
|
||||
// ============
|
||||
// LCG16 module
|
||||
// ============
|
||||
|
158
src/main/scala/junctions/MultiWidthFifo.scala
Normal file
158
src/main/scala/junctions/MultiWidthFifo.scala
Normal file
@ -0,0 +1,158 @@
|
||||
package junctions
|
||||
|
||||
import Chisel._
|
||||
import unittest.UnitTest
|
||||
|
||||
class MultiWidthFifo(inW: Int, outW: Int, n: Int) extends Module {
|
||||
val io = new Bundle {
|
||||
val in = Decoupled(Bits(width = inW)).flip
|
||||
val out = Decoupled(Bits(width = outW))
|
||||
val count = UInt(OUTPUT, log2Up(n + 1))
|
||||
}
|
||||
|
||||
if (inW == outW) {
|
||||
val q = Module(new Queue(Bits(width = inW), n))
|
||||
q.io.enq <> io.in
|
||||
io.out <> q.io.deq
|
||||
io.count := q.io.count
|
||||
} else if (inW > outW) {
|
||||
val nBeats = inW / outW
|
||||
|
||||
require(inW % outW == 0, s"MultiWidthFifo: in: $inW not divisible by out: $outW")
|
||||
require(n % nBeats == 0, s"Cannot store $n output words when output beats is $nBeats")
|
||||
|
||||
val wdata = Reg(Vec(n / nBeats, Bits(width = inW)))
|
||||
val rdata = Vec(wdata.flatMap { indat =>
|
||||
(0 until nBeats).map(i => indat(outW * (i + 1) - 1, outW * i)) })
|
||||
|
||||
val head = Reg(init = UInt(0, log2Up(n / nBeats)))
|
||||
val tail = Reg(init = UInt(0, log2Up(n)))
|
||||
val size = Reg(init = UInt(0, log2Up(n + 1)))
|
||||
|
||||
when (io.in.fire()) {
|
||||
wdata(head) := io.in.bits
|
||||
head := head + UInt(1)
|
||||
}
|
||||
|
||||
when (io.out.fire()) { tail := tail + UInt(1) }
|
||||
|
||||
size := MuxCase(size, Seq(
|
||||
(io.in.fire() && io.out.fire()) -> (size + UInt(nBeats - 1)),
|
||||
io.in.fire() -> (size + UInt(nBeats)),
|
||||
io.out.fire() -> (size - UInt(1))))
|
||||
|
||||
io.out.valid := size > UInt(0)
|
||||
io.out.bits := rdata(tail)
|
||||
io.in.ready := size < UInt(n)
|
||||
io.count := size
|
||||
} else {
|
||||
val nBeats = outW / inW
|
||||
|
||||
require(outW % inW == 0, s"MultiWidthFifo: out: $outW not divisible by in: $inW")
|
||||
|
||||
val wdata = Reg(Vec(n * nBeats, Bits(width = inW)))
|
||||
val rdata = Vec.tabulate(n) { i =>
|
||||
Cat(wdata.slice(i * nBeats, (i + 1) * nBeats).reverse)}
|
||||
|
||||
val head = Reg(init = UInt(0, log2Up(n * nBeats)))
|
||||
val tail = Reg(init = UInt(0, log2Up(n)))
|
||||
val size = Reg(init = UInt(0, log2Up(n * nBeats + 1)))
|
||||
|
||||
when (io.in.fire()) {
|
||||
wdata(head) := io.in.bits
|
||||
head := head + UInt(1)
|
||||
}
|
||||
|
||||
when (io.out.fire()) { tail := tail + UInt(1) }
|
||||
|
||||
size := MuxCase(size, Seq(
|
||||
(io.in.fire() && io.out.fire()) -> (size - UInt(nBeats - 1)),
|
||||
io.in.fire() -> (size + UInt(1)),
|
||||
io.out.fire() -> (size - UInt(nBeats))))
|
||||
|
||||
io.count := size >> UInt(log2Up(nBeats))
|
||||
io.out.valid := io.count > UInt(0)
|
||||
io.out.bits := rdata(tail)
|
||||
io.in.ready := size < UInt(n * nBeats)
|
||||
}
|
||||
}
|
||||
|
||||
class MultiWidthFifoTest extends UnitTest {
|
||||
val big2little = Module(new MultiWidthFifo(16, 8, 8))
|
||||
val little2big = Module(new MultiWidthFifo(8, 16, 4))
|
||||
|
||||
val bl_send = Reg(init = Bool(false))
|
||||
val lb_send = Reg(init = Bool(false))
|
||||
val bl_recv = Reg(init = Bool(false))
|
||||
val lb_recv = Reg(init = Bool(false))
|
||||
val bl_finished = Reg(init = Bool(false))
|
||||
val lb_finished = Reg(init = Bool(false))
|
||||
|
||||
val bl_data = Vec.tabulate(4){i => UInt((2 * i + 1) * 256 + 2 * i, 16)}
|
||||
val lb_data = Vec.tabulate(8){i => UInt(i, 8)}
|
||||
|
||||
val (bl_send_cnt, bl_send_done) = Counter(big2little.io.in.fire(), 4)
|
||||
val (lb_send_cnt, lb_send_done) = Counter(little2big.io.in.fire(), 8)
|
||||
|
||||
val (bl_recv_cnt, bl_recv_done) = Counter(big2little.io.out.fire(), 8)
|
||||
val (lb_recv_cnt, lb_recv_done) = Counter(little2big.io.out.fire(), 4)
|
||||
|
||||
big2little.io.in.valid := bl_send
|
||||
big2little.io.in.bits := bl_data(bl_send_cnt)
|
||||
big2little.io.out.ready := bl_recv
|
||||
|
||||
little2big.io.in.valid := lb_send
|
||||
little2big.io.in.bits := lb_data(lb_send_cnt)
|
||||
little2big.io.out.ready := lb_recv
|
||||
|
||||
val bl_recv_data_idx = bl_recv_cnt >> UInt(1)
|
||||
val bl_recv_data = Mux(bl_recv_cnt(0),
|
||||
bl_data(bl_recv_data_idx)(15, 8),
|
||||
bl_data(bl_recv_data_idx)(7, 0))
|
||||
|
||||
val lb_recv_data = Cat(
|
||||
lb_data(Cat(lb_recv_cnt, UInt(1, 1))),
|
||||
lb_data(Cat(lb_recv_cnt, UInt(0, 1))))
|
||||
|
||||
when (io.start) {
|
||||
bl_send := Bool(true)
|
||||
lb_send := Bool(true)
|
||||
}
|
||||
|
||||
when (bl_send_done) {
|
||||
bl_send := Bool(false)
|
||||
bl_recv := Bool(true)
|
||||
}
|
||||
|
||||
when (lb_send_done) {
|
||||
lb_send := Bool(false)
|
||||
lb_recv := Bool(true)
|
||||
}
|
||||
|
||||
when (bl_recv_done) {
|
||||
bl_recv := Bool(false)
|
||||
bl_finished := Bool(true)
|
||||
}
|
||||
|
||||
when (lb_recv_done) {
|
||||
lb_recv := Bool(false)
|
||||
lb_finished := Bool(true)
|
||||
}
|
||||
|
||||
io.finished := bl_finished && lb_finished
|
||||
|
||||
val bl_start_recv = Reg(next = bl_send_done)
|
||||
val lb_start_recv = Reg(next = lb_send_done)
|
||||
|
||||
assert(!little2big.io.out.valid || little2big.io.out.bits === lb_recv_data,
|
||||
"Little to Big data mismatch")
|
||||
assert(!big2little.io.out.valid || big2little.io.out.bits === bl_recv_data,
|
||||
"Bit to Little data mismatch")
|
||||
|
||||
assert(!lb_start_recv || little2big.io.count === UInt(4),
|
||||
"Little to Big count incorrect")
|
||||
assert(!bl_start_recv || big2little.io.count === UInt(8),
|
||||
"Big to Little count incorrect")
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package junctions.unittests
|
||||
package junctions
|
||||
|
||||
import Chisel._
|
||||
import junctions._
|
||||
import junctions.NastiConstants._
|
||||
import cde.Parameters
|
||||
|
||||
class NastiDemuxDriver(n: Int)(implicit p: Parameters) extends Module {
|
||||
@ -93,7 +91,7 @@ class NastiDemuxSlave(implicit p: Parameters) extends NastiModule()(p) {
|
||||
io.r.bits := NastiReadDataChannel(id = id, data = value)
|
||||
}
|
||||
|
||||
class NastiMemoryDemuxTest(implicit p: Parameters) extends UnitTest {
|
||||
class NastiMemoryDemuxTest(implicit p: Parameters) extends unittest.UnitTest {
|
||||
val nSlaves = 4
|
||||
|
||||
val driver = Module(new NastiDemuxDriver(nSlaves))
|
@ -1,8 +1,6 @@
|
||||
package junctions.unittests
|
||||
package junctions
|
||||
|
||||
import Chisel._
|
||||
import junctions._
|
||||
import junctions.NastiConstants._
|
||||
import cde.Parameters
|
||||
|
||||
class NastiDriver(dataWidth: Int, burstLen: Int, nBursts: Int)
|
||||
@ -76,16 +74,3 @@ class NastiDriver(dataWidth: Int, burstLen: Int, nBursts: Int)
|
||||
assert(!io.nasti.r.valid || read_data === expected_data,
|
||||
s"NastiDriver got wrong data")
|
||||
}
|
||||
|
||||
class HastiTest(implicit p: Parameters) extends UnitTest {
|
||||
val sram = Module(new HastiTestSRAM(8))
|
||||
val bus = Module(new HastiBus(Seq(a => Bool(true))))
|
||||
val conv = Module(new HastiMasterIONastiIOConverter)
|
||||
val driver = Module(new NastiDriver(32, 8, 2))
|
||||
|
||||
bus.io.slaves(0) <> sram.io
|
||||
bus.io.master <> conv.io.hasti
|
||||
conv.io.nasti <> driver.io.nasti
|
||||
io.finished := driver.io.finished
|
||||
driver.io.start := io.start
|
||||
}
|
@ -2,6 +2,7 @@ package junctions
|
||||
|
||||
import Chisel._
|
||||
import cde.{Parameters, Field}
|
||||
import unittest.UnitTest
|
||||
|
||||
object HastiConstants
|
||||
{
|
||||
@ -547,3 +548,16 @@ class HastiTestSRAM(depth: Int)(implicit p: Parameters) extends HastiModule()(p)
|
||||
io.hready := ready
|
||||
io.hresp := HRESP_OKAY
|
||||
}
|
||||
|
||||
class HastiTest(implicit p: Parameters) extends UnitTest {
|
||||
val sram = Module(new HastiTestSRAM(8))
|
||||
val bus = Module(new HastiBus(Seq(a => Bool(true))))
|
||||
val conv = Module(new HastiMasterIONastiIOConverter)
|
||||
val driver = Module(new NastiDriver(32, 8, 2))
|
||||
|
||||
bus.io.slaves(0) <> sram.io
|
||||
bus.io.master <> conv.io.hasti
|
||||
conv.io.nasti <> driver.io.nasti
|
||||
io.finished := driver.io.finished
|
||||
driver.io.start := io.start
|
||||
}
|
||||
|
@ -1,85 +0,0 @@
|
||||
package junctions.unittests
|
||||
|
||||
import Chisel._
|
||||
import junctions._
|
||||
import junctions.NastiConstants._
|
||||
|
||||
class MultiWidthFifoTest extends UnitTest {
|
||||
val big2little = Module(new MultiWidthFifo(16, 8, 8))
|
||||
val little2big = Module(new MultiWidthFifo(8, 16, 4))
|
||||
|
||||
val bl_send = Reg(init = Bool(false))
|
||||
val lb_send = Reg(init = Bool(false))
|
||||
val bl_recv = Reg(init = Bool(false))
|
||||
val lb_recv = Reg(init = Bool(false))
|
||||
val bl_finished = Reg(init = Bool(false))
|
||||
val lb_finished = Reg(init = Bool(false))
|
||||
|
||||
val bl_data = Vec.tabulate(4){i => UInt((2 * i + 1) * 256 + 2 * i, 16)}
|
||||
val lb_data = Vec.tabulate(8){i => UInt(i, 8)}
|
||||
|
||||
val (bl_send_cnt, bl_send_done) = Counter(big2little.io.in.fire(), 4)
|
||||
val (lb_send_cnt, lb_send_done) = Counter(little2big.io.in.fire(), 8)
|
||||
|
||||
val (bl_recv_cnt, bl_recv_done) = Counter(big2little.io.out.fire(), 8)
|
||||
val (lb_recv_cnt, lb_recv_done) = Counter(little2big.io.out.fire(), 4)
|
||||
|
||||
big2little.io.in.valid := bl_send
|
||||
big2little.io.in.bits := bl_data(bl_send_cnt)
|
||||
big2little.io.out.ready := bl_recv
|
||||
|
||||
little2big.io.in.valid := lb_send
|
||||
little2big.io.in.bits := lb_data(lb_send_cnt)
|
||||
little2big.io.out.ready := lb_recv
|
||||
|
||||
val bl_recv_data_idx = bl_recv_cnt >> UInt(1)
|
||||
val bl_recv_data = Mux(bl_recv_cnt(0),
|
||||
bl_data(bl_recv_data_idx)(15, 8),
|
||||
bl_data(bl_recv_data_idx)(7, 0))
|
||||
|
||||
val lb_recv_data = Cat(
|
||||
lb_data(Cat(lb_recv_cnt, UInt(1, 1))),
|
||||
lb_data(Cat(lb_recv_cnt, UInt(0, 1))))
|
||||
|
||||
when (io.start) {
|
||||
bl_send := Bool(true)
|
||||
lb_send := Bool(true)
|
||||
}
|
||||
|
||||
when (bl_send_done) {
|
||||
bl_send := Bool(false)
|
||||
bl_recv := Bool(true)
|
||||
}
|
||||
|
||||
when (lb_send_done) {
|
||||
lb_send := Bool(false)
|
||||
lb_recv := Bool(true)
|
||||
}
|
||||
|
||||
when (bl_recv_done) {
|
||||
bl_recv := Bool(false)
|
||||
bl_finished := Bool(true)
|
||||
}
|
||||
|
||||
when (lb_recv_done) {
|
||||
lb_recv := Bool(false)
|
||||
lb_finished := Bool(true)
|
||||
}
|
||||
|
||||
io.finished := bl_finished && lb_finished
|
||||
|
||||
val bl_start_recv = Reg(next = bl_send_done)
|
||||
val lb_start_recv = Reg(next = lb_send_done)
|
||||
|
||||
assert(!little2big.io.out.valid || little2big.io.out.bits === lb_recv_data,
|
||||
"Little to Big data mismatch")
|
||||
assert(!big2little.io.out.valid || big2little.io.out.bits === bl_recv_data,
|
||||
"Bit to Little data mismatch")
|
||||
|
||||
assert(!lb_start_recv || little2big.io.count === UInt(4),
|
||||
"Little to Big count incorrect")
|
||||
assert(!bl_start_recv || big2little.io.count === UInt(8),
|
||||
"Big to Little count incorrect")
|
||||
}
|
||||
|
||||
|
@ -244,128 +244,3 @@ class DecoupledHelper(val rvs: Seq[Bool]) {
|
||||
(rvs.filter(_ ne exclude) ++ includes).reduce(_ && _)
|
||||
}
|
||||
}
|
||||
|
||||
class MultiWidthFifo(inW: Int, outW: Int, n: Int) extends Module {
|
||||
val io = new Bundle {
|
||||
val in = Decoupled(Bits(width = inW)).flip
|
||||
val out = Decoupled(Bits(width = outW))
|
||||
val count = UInt(OUTPUT, log2Up(n + 1))
|
||||
}
|
||||
|
||||
if (inW == outW) {
|
||||
val q = Module(new Queue(Bits(width = inW), n))
|
||||
q.io.enq <> io.in
|
||||
io.out <> q.io.deq
|
||||
io.count := q.io.count
|
||||
} else if (inW > outW) {
|
||||
val nBeats = inW / outW
|
||||
|
||||
require(inW % outW == 0, s"MultiWidthFifo: in: $inW not divisible by out: $outW")
|
||||
require(n % nBeats == 0, s"Cannot store $n output words when output beats is $nBeats")
|
||||
|
||||
val wdata = Reg(Vec(n / nBeats, Bits(width = inW)))
|
||||
val rdata = Vec(wdata.flatMap { indat =>
|
||||
(0 until nBeats).map(i => indat(outW * (i + 1) - 1, outW * i)) })
|
||||
|
||||
val head = Reg(init = UInt(0, log2Up(n / nBeats)))
|
||||
val tail = Reg(init = UInt(0, log2Up(n)))
|
||||
val size = Reg(init = UInt(0, log2Up(n + 1)))
|
||||
|
||||
when (io.in.fire()) {
|
||||
wdata(head) := io.in.bits
|
||||
head := head + UInt(1)
|
||||
}
|
||||
|
||||
when (io.out.fire()) { tail := tail + UInt(1) }
|
||||
|
||||
size := MuxCase(size, Seq(
|
||||
(io.in.fire() && io.out.fire()) -> (size + UInt(nBeats - 1)),
|
||||
io.in.fire() -> (size + UInt(nBeats)),
|
||||
io.out.fire() -> (size - UInt(1))))
|
||||
|
||||
io.out.valid := size > UInt(0)
|
||||
io.out.bits := rdata(tail)
|
||||
io.in.ready := size < UInt(n)
|
||||
io.count := size
|
||||
} else {
|
||||
val nBeats = outW / inW
|
||||
|
||||
require(outW % inW == 0, s"MultiWidthFifo: out: $outW not divisible by in: $inW")
|
||||
|
||||
val wdata = Reg(Vec(n * nBeats, Bits(width = inW)))
|
||||
val rdata = Vec.tabulate(n) { i =>
|
||||
Cat(wdata.slice(i * nBeats, (i + 1) * nBeats).reverse)}
|
||||
|
||||
val head = Reg(init = UInt(0, log2Up(n * nBeats)))
|
||||
val tail = Reg(init = UInt(0, log2Up(n)))
|
||||
val size = Reg(init = UInt(0, log2Up(n * nBeats + 1)))
|
||||
|
||||
when (io.in.fire()) {
|
||||
wdata(head) := io.in.bits
|
||||
head := head + UInt(1)
|
||||
}
|
||||
|
||||
when (io.out.fire()) { tail := tail + UInt(1) }
|
||||
|
||||
size := MuxCase(size, Seq(
|
||||
(io.in.fire() && io.out.fire()) -> (size - UInt(nBeats - 1)),
|
||||
io.in.fire() -> (size + UInt(1)),
|
||||
io.out.fire() -> (size - UInt(nBeats))))
|
||||
|
||||
io.count := size >> UInt(log2Up(nBeats))
|
||||
io.out.valid := io.count > UInt(0)
|
||||
io.out.bits := rdata(tail)
|
||||
io.in.ready := size < UInt(n * nBeats)
|
||||
}
|
||||
}
|
||||
|
||||
// ============
|
||||
// Static timer
|
||||
// ============
|
||||
|
||||
// Timer with a statically-specified period.
|
||||
// Can take multiple inflight start-stop events with ID
|
||||
// Will continue to count down as long as at least one event is inflight
|
||||
|
||||
class Timer(initCount: Int, maxInflight: Int) extends Module {
|
||||
val io = new Bundle {
|
||||
val start = Valid(UInt(width = log2Up(maxInflight))).flip
|
||||
val stop = Valid(UInt(width = log2Up(maxInflight))).flip
|
||||
val timeout = Valid(UInt(width = log2Up(maxInflight)))
|
||||
}
|
||||
|
||||
val inflight = Reg(init = Vec.fill(maxInflight) { Bool(false) })
|
||||
val countdown = Reg(UInt(width = log2Up(initCount)))
|
||||
val active = inflight.reduce(_ || _)
|
||||
|
||||
when (active) {
|
||||
countdown := countdown - UInt(1)
|
||||
}
|
||||
|
||||
when (io.start.valid) {
|
||||
inflight(io.start.bits) := Bool(true)
|
||||
countdown := UInt(initCount - 1)
|
||||
}
|
||||
when (io.stop.valid) {
|
||||
inflight(io.stop.bits) := Bool(false)
|
||||
}
|
||||
|
||||
io.timeout.valid := countdown === UInt(0) && active
|
||||
io.timeout.bits := PriorityEncoder(inflight)
|
||||
|
||||
assert(!io.stop.valid || inflight(io.stop.bits),
|
||||
"Timer stop for transaction that's not inflight")
|
||||
}
|
||||
|
||||
object Timer {
|
||||
def apply(initCount: Int, start: Bool, stop: Bool): Bool = {
|
||||
val timer = Module(new Timer(initCount, 1))
|
||||
timer.io.start.valid := start
|
||||
timer.io.start.bits := UInt(0)
|
||||
timer.io.stop.valid := stop
|
||||
timer.io.stop.bits := UInt(0)
|
||||
timer.io.timeout.valid
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -7,9 +7,8 @@ import uncore.tilelink._
|
||||
import uncore.coherence._
|
||||
import uncore.agents._
|
||||
import uncore.devices.NTiles
|
||||
import uncore.unittests._
|
||||
import unittest._
|
||||
import junctions._
|
||||
import junctions.unittests._
|
||||
import scala.collection.mutable.LinkedHashSet
|
||||
import scala.collection.immutable.HashMap
|
||||
import cde.{Parameters, Config, Dump, Knob, CDEMatchError}
|
||||
|
@ -30,3 +30,30 @@ class SmiIOTileLinkIOConverter(val dataWidth: Int, val addrWidth: Int)
|
||||
decoupledNastiConnect(nasti2smi.io.nasti, tl2nasti.io.nasti)
|
||||
io.smi <> nasti2smi.io.smi
|
||||
}
|
||||
|
||||
class SmiConverterTest(implicit val p: Parameters) extends unittest.UnitTest
|
||||
with HasTileLinkParameters {
|
||||
val outermostParams = p.alterPartial({ case TLId => "Outermost" })
|
||||
|
||||
val smiWidth = 32
|
||||
val smiDepth = 64
|
||||
val tlDepth = (smiWidth * smiDepth) / tlDataBits
|
||||
|
||||
val smimem = Module(new SmiMem(smiWidth, smiDepth))
|
||||
val conv = Module(new SmiIOTileLinkIOConverter(
|
||||
smiWidth, log2Up(smiDepth))(outermostParams))
|
||||
val driver = Module(new DriverSet(
|
||||
(driverParams: Parameters) => {
|
||||
implicit val p = driverParams
|
||||
Seq(
|
||||
Module(new PutSweepDriver(tlDepth)),
|
||||
Module(new PutMaskDriver(smiWidth / 8)),
|
||||
Module(new PutBlockSweepDriver(tlDepth / tlDataBeats)),
|
||||
Module(new GetMultiWidthDriver))
|
||||
})(outermostParams))
|
||||
|
||||
conv.io.tl <> driver.io.mem
|
||||
smimem.io <> conv.io.smi
|
||||
driver.io.start := io.start
|
||||
io.finished := driver.io.finished
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package uncore.devices
|
||||
|
||||
import Chisel._
|
||||
import cde.{Parameters, Field}
|
||||
import unittest.UnitTest
|
||||
import junctions._
|
||||
import uncore.tilelink._
|
||||
import uncore.util._
|
||||
@ -159,3 +160,24 @@ class TileLinkTestRAM(depth: Int)(implicit val p: Parameters) extends Module
|
||||
ram(acq_addr) := (old_data & ~wmask) | (result & wmask)
|
||||
}
|
||||
}
|
||||
|
||||
class TileLinkRAMTest(implicit val p: Parameters)
|
||||
extends UnitTest with HasTileLinkParameters {
|
||||
|
||||
val depth = 2 * tlDataBeats
|
||||
val ram = Module(new TileLinkTestRAM(depth))
|
||||
val driver = Module(new DriverSet(
|
||||
(driverParams: Parameters) => {
|
||||
implicit val p = driverParams
|
||||
Seq(
|
||||
Module(new PutSweepDriver(depth)),
|
||||
Module(new PutMaskDriver),
|
||||
Module(new PutAtomicDriver),
|
||||
Module(new PutBlockSweepDriver(depth / tlDataBeats)),
|
||||
Module(new PrefetchDriver),
|
||||
Module(new GetMultiWidthDriver))
|
||||
}))
|
||||
ram.io <> driver.io.mem
|
||||
driver.io.start := io.start
|
||||
io.finished := driver.io.finished
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package uncore.devices
|
||||
|
||||
import Chisel._
|
||||
import unittest.UnitTest
|
||||
import junctions._
|
||||
import uncore.tilelink._
|
||||
import uncore.util._
|
||||
@ -41,6 +42,26 @@ class ROMSlave(contents: Seq[Byte])(implicit val p: Parameters) extends Module
|
||||
data = rdata)
|
||||
}
|
||||
|
||||
class ROMSlaveTest(implicit p: Parameters) extends UnitTest {
|
||||
implicit val testName = "ROMSlaveTest"
|
||||
val romdata = Seq(
|
||||
BigInt("01234567deadbeef", 16),
|
||||
BigInt("ab32fee8d00dfeed", 16))
|
||||
val rombytes = romdata.map(_.toByteArray.reverse).flatten
|
||||
val rom = Module(new ROMSlave(rombytes))
|
||||
val driver = Module(new DriverSet(
|
||||
(driverParams: Parameters) => {
|
||||
implicit val p = driverParams
|
||||
Seq(
|
||||
Module(new GetMultiWidthDriver),
|
||||
Module(new GetSweepDriver(romdata)),
|
||||
Module(new GetBlockSweepDriver(romdata)))
|
||||
}))
|
||||
rom.io <> driver.io.mem
|
||||
driver.io.start := io.start
|
||||
io.finished := driver.io.finished
|
||||
}
|
||||
|
||||
class NastiROM(contents: Seq[Byte])(implicit p: Parameters) extends Module {
|
||||
val io = new NastiIO().flip
|
||||
val ar = Queue(io.ar, 1)
|
||||
|
@ -1,8 +1,7 @@
|
||||
package uncore.unittests
|
||||
package uncore.tilelink
|
||||
|
||||
import Chisel._
|
||||
import junctions._
|
||||
import uncore.tilelink._
|
||||
import uncore.constants._
|
||||
import uncore.util._
|
||||
import cde.Parameters
|
@ -3,7 +3,7 @@ package uncore.tilelink2
|
||||
|
||||
import Chisel._
|
||||
import chisel3.util.LFSR16
|
||||
import junctions.unittests._
|
||||
import unittest._
|
||||
|
||||
class IDMapGenerator(numIds: Int) extends Module {
|
||||
val w = log2Up(numIds)
|
||||
|
@ -1,86 +0,0 @@
|
||||
package uncore.unittests
|
||||
|
||||
import Chisel._
|
||||
import junctions._
|
||||
import junctions.unittests._
|
||||
import uncore.devices._
|
||||
import uncore.tilelink._
|
||||
import uncore.converters._
|
||||
import cde.Parameters
|
||||
|
||||
class SmiConverterTest(implicit val p: Parameters) extends UnitTest
|
||||
with HasTileLinkParameters {
|
||||
val outermostParams = p.alterPartial({ case TLId => "Outermost" })
|
||||
|
||||
val smiWidth = 32
|
||||
val smiDepth = 64
|
||||
val tlDepth = (smiWidth * smiDepth) / tlDataBits
|
||||
|
||||
val smimem = Module(new SmiMem(smiWidth, smiDepth))
|
||||
val conv = Module(new SmiIOTileLinkIOConverter(
|
||||
smiWidth, log2Up(smiDepth))(outermostParams))
|
||||
val driver = Module(new DriverSet(
|
||||
(driverParams: Parameters) => {
|
||||
implicit val p = driverParams
|
||||
Seq(
|
||||
Module(new PutSweepDriver(tlDepth)),
|
||||
Module(new PutMaskDriver(smiWidth / 8)),
|
||||
Module(new PutBlockSweepDriver(tlDepth / tlDataBeats)),
|
||||
Module(new GetMultiWidthDriver))
|
||||
})(outermostParams))
|
||||
|
||||
conv.io.tl <> driver.io.mem
|
||||
smimem.io <> conv.io.smi
|
||||
driver.io.start := io.start
|
||||
io.finished := driver.io.finished
|
||||
}
|
||||
|
||||
class ROMSlaveTest(implicit p: Parameters) extends UnitTest {
|
||||
implicit val testName = "ROMSlaveTest"
|
||||
val romdata = Seq(
|
||||
BigInt("01234567deadbeef", 16),
|
||||
BigInt("ab32fee8d00dfeed", 16))
|
||||
val rombytes = romdata.map(_.toByteArray.reverse).flatten
|
||||
val rom = Module(new ROMSlave(rombytes))
|
||||
val driver = Module(new DriverSet(
|
||||
(driverParams: Parameters) => {
|
||||
implicit val p = driverParams
|
||||
Seq(
|
||||
Module(new GetMultiWidthDriver),
|
||||
Module(new GetSweepDriver(romdata)),
|
||||
Module(new GetBlockSweepDriver(romdata)))
|
||||
}))
|
||||
rom.io <> driver.io.mem
|
||||
driver.io.start := io.start
|
||||
io.finished := driver.io.finished
|
||||
}
|
||||
|
||||
class TileLinkRAMTest(implicit val p: Parameters)
|
||||
extends UnitTest with HasTileLinkParameters {
|
||||
|
||||
val depth = 2 * tlDataBeats
|
||||
val ram = Module(new TileLinkTestRAM(depth))
|
||||
val driver = Module(new DriverSet(
|
||||
(driverParams: Parameters) => {
|
||||
implicit val p = driverParams
|
||||
Seq(
|
||||
Module(new PutSweepDriver(depth)),
|
||||
Module(new PutMaskDriver),
|
||||
Module(new PutAtomicDriver),
|
||||
Module(new PutBlockSweepDriver(depth / tlDataBeats)),
|
||||
Module(new PrefetchDriver),
|
||||
Module(new GetMultiWidthDriver))
|
||||
}))
|
||||
ram.io <> driver.io.mem
|
||||
driver.io.start := io.start
|
||||
io.finished := driver.io.finished
|
||||
}
|
||||
|
||||
object UncoreUnitTests {
|
||||
def apply(implicit p: Parameters): Seq[UnitTest] =
|
||||
Seq(
|
||||
Module(new SmiConverterTest),
|
||||
Module(new ROMSlaveTest),
|
||||
Module(new TileLinkRAMTest),
|
||||
Module(new uncore.tilelink2.TLFuzzRAMTest))
|
||||
}
|
21
src/main/scala/unittest/TempListOfTests.scala
Normal file
21
src/main/scala/unittest/TempListOfTests.scala
Normal file
@ -0,0 +1,21 @@
|
||||
package unittest
|
||||
|
||||
import Chisel._
|
||||
import cde.Parameters
|
||||
|
||||
object JunctionsUnitTests {
|
||||
def apply(implicit p: Parameters): Seq[UnitTest] =
|
||||
Seq(
|
||||
Module(new junctions.MultiWidthFifoTest),
|
||||
Module(new junctions.NastiMemoryDemuxTest),
|
||||
Module(new junctions.HastiTest))
|
||||
}
|
||||
|
||||
object UncoreUnitTests {
|
||||
def apply(implicit p: Parameters): Seq[UnitTest] =
|
||||
Seq(
|
||||
Module(new uncore.converters.SmiConverterTest),
|
||||
Module(new uncore.devices.ROMSlaveTest),
|
||||
Module(new uncore.devices.TileLinkRAMTest),
|
||||
Module(new uncore.tilelink2.TLFuzzRAMTest))
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package junctions.unittests
|
||||
package unittest
|
||||
|
||||
import Chisel._
|
||||
import junctions._
|
||||
import cde.{Field, Parameters}
|
||||
import util.Timer
|
||||
|
||||
trait HasUnitTestIO {
|
||||
val io = new Bundle {
|
||||
@ -56,11 +56,3 @@ class UnitTestSuite(implicit p: Parameters) extends Module {
|
||||
|
||||
assert(!timer.io.timeout.valid, "UnitTest timed out")
|
||||
}
|
||||
|
||||
object JunctionsUnitTests {
|
||||
def apply(implicit p: Parameters): Seq[UnitTest] =
|
||||
Seq(
|
||||
Module(new MultiWidthFifoTest),
|
||||
Module(new NastiMemoryDemuxTest),
|
||||
Module(new HastiTest))
|
||||
}
|
74
src/main/scala/util/Timer.scala
Normal file
74
src/main/scala/util/Timer.scala
Normal file
@ -0,0 +1,74 @@
|
||||
/// See LICENSE for license details.
|
||||
package util
|
||||
|
||||
import Chisel._
|
||||
|
||||
/** Timer with a statically-specified period.
|
||||
* Can take multiple inflight start-stop events with ID
|
||||
* Will continue to count down as long as at least one event is inflight
|
||||
*/
|
||||
class Timer(initCount: Int, maxInflight: Int) extends Module {
|
||||
val io = new Bundle {
|
||||
val start = Valid(UInt(width = log2Up(maxInflight))).flip
|
||||
val stop = Valid(UInt(width = log2Up(maxInflight))).flip
|
||||
val timeout = Valid(UInt(width = log2Up(maxInflight)))
|
||||
}
|
||||
|
||||
val inflight = Reg(init = Vec.fill(maxInflight) { Bool(false) })
|
||||
val countdown = Reg(UInt(width = log2Up(initCount)))
|
||||
val active = inflight.reduce(_ || _)
|
||||
|
||||
when (active) {
|
||||
countdown := countdown - UInt(1)
|
||||
}
|
||||
|
||||
when (io.start.valid) {
|
||||
inflight(io.start.bits) := Bool(true)
|
||||
countdown := UInt(initCount - 1)
|
||||
}
|
||||
when (io.stop.valid) {
|
||||
inflight(io.stop.bits) := Bool(false)
|
||||
}
|
||||
|
||||
io.timeout.valid := countdown === UInt(0) && active
|
||||
io.timeout.bits := PriorityEncoder(inflight)
|
||||
|
||||
assert(!io.stop.valid || inflight(io.stop.bits),
|
||||
"Timer stop for transaction that's not inflight")
|
||||
}
|
||||
|
||||
object Timer {
|
||||
def apply(initCount: Int, start: Bool, stop: Bool): Bool = {
|
||||
val timer = Module(new Timer(initCount, 1))
|
||||
timer.io.start.valid := start
|
||||
timer.io.start.bits := UInt(0)
|
||||
timer.io.stop.valid := stop
|
||||
timer.io.stop.bits := UInt(0)
|
||||
timer.io.timeout.valid
|
||||
}
|
||||
}
|
||||
|
||||
/** Timer with a statically-specified period. */
|
||||
class DynamicTimer(w: Int) extends Module {
|
||||
val io = new Bundle {
|
||||
val start = Bool(INPUT)
|
||||
val period = UInt(INPUT, w)
|
||||
val stop = Bool(INPUT)
|
||||
val timeout = Bool(OUTPUT)
|
||||
}
|
||||
|
||||
val countdown = Reg(init = UInt(0, w))
|
||||
val active = Reg(init = Bool(false))
|
||||
|
||||
when (io.start) {
|
||||
countdown := io.period
|
||||
active := Bool(true)
|
||||
} .elsewhen (io.stop || countdown === UInt(0)) {
|
||||
active := Bool(false)
|
||||
} .elsewhen (active) {
|
||||
countdown := countdown - UInt(1)
|
||||
}
|
||||
|
||||
io.timeout := countdown === UInt(0) && active
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user