diff options
| author | Jack | 2022-04-26 02:53:08 +0000 |
|---|---|---|
| committer | Jack | 2022-04-26 02:53:08 +0000 |
| commit | 3a6cc75d72cbf890bbd45a002c31d16abfc6896d (patch) | |
| tree | 298a39cbdbcd7e89953d75dbd840884f29ff7699 /src/test/scala/chiselTests/ReduceTreeSpec.scala | |
| parent | be1ac06bf20c6c3d84c8ce5b0a50e2980e546e7e (diff) | |
| parent | d5a964f6e7beea1f38f9623224fc65e2397e1fe7 (diff) | |
Merge branch '3.5.x' into 3.5-release
Diffstat (limited to 'src/test/scala/chiselTests/ReduceTreeSpec.scala')
| -rw-r--r-- | src/test/scala/chiselTests/ReduceTreeSpec.scala | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/test/scala/chiselTests/ReduceTreeSpec.scala b/src/test/scala/chiselTests/ReduceTreeSpec.scala new file mode 100644 index 00000000..3f078106 --- /dev/null +++ b/src/test/scala/chiselTests/ReduceTreeSpec.scala @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chiselTests + +import chisel3._ +import chisel3.util._ +import chisel3.testers.BasicTester + +class Arbiter[T <: Data: Manifest](n: Int, private val gen: T) extends Module { + val io = IO(new Bundle { + val in = Flipped(Vec(n, new DecoupledIO(gen))) + val out = new DecoupledIO(gen) + }) + + def arbitrateTwo(a: DecoupledIO[T], b: DecoupledIO[T]) = { + + val idleA :: idleB :: hasA :: hasB :: Nil = Enum(4) + val regData = Reg(gen) + val regState = RegInit(idleA) + val out = Wire(new DecoupledIO(gen)) + + a.ready := regState === idleA + b.ready := regState === idleB + out.valid := (regState === hasA || regState === hasB) + + switch(regState) { + is(idleA) { + when(a.valid) { + regData := a.bits + regState := hasA + }.otherwise { + regState := idleB + } + } + is(idleB) { + when(b.valid) { + regData := b.bits + regState := hasB + }.otherwise { + regState := idleA + } + } + is(hasA) { + when(out.ready) { + regState := idleB + } + } + is(hasB) { + when(out.ready) { + regState := idleA + } + } + } + + out.bits := regData.asUInt + 1.U + out + } + + io.out <> io.in.reduceTree(arbitrateTwo) +} + +class ReduceTreeBalancedTester(nodes: Int) extends BasicTester { + + val cnt = RegInit(0.U(8.W)) + val min = RegInit(99.U(8.W)) + val max = RegInit(0.U(8.W)) + + val dut = Module(new Arbiter(nodes, UInt(16.W))) + for (i <- 0 until nodes) { + dut.io.in(i).valid := true.B + dut.io.in(i).bits := 0.U + } + dut.io.out.ready := true.B + + when(dut.io.out.valid) { + val hops = dut.io.out.bits + when(hops < min) { + min := hops + } + when(hops > max) { + max := hops + } + } + + when(!(max === 0.U || min === 99.U)) { + assert(max - min <= 1.U) + } + + cnt := cnt + 1.U + when(cnt === 10.U) { + stop() + } +} + +class ReduceTreeBalancedSpec extends ChiselPropSpec { + property("Tree shall be fair and shall have a maximum difference of one hop for each node") { + + // This test will fail for 5 nodes due to an unbalanced tree. + // A fix is on the way. + for (n <- 1 to 5) { + assertTesterPasses { + new ReduceTreeBalancedTester(n) + } + } + } +} |
