diff options
| -rw-r--r-- | core/src/main/scala/chisel3/SeqUtils.scala | 5 | ||||
| -rw-r--r-- | src/test/scala/chiselTests/util/PriorityMuxSpec.scala | 60 |
2 files changed, 64 insertions, 1 deletions
diff --git a/core/src/main/scala/chisel3/SeqUtils.scala b/core/src/main/scala/chisel3/SeqUtils.scala index b1136120..9d975349 100644 --- a/core/src/main/scala/chisel3/SeqUtils.scala +++ b/core/src/main/scala/chisel3/SeqUtils.scala @@ -64,7 +64,10 @@ private[chisel3] object SeqUtils { if (in.size == 1) { in.head._2 } else { - Mux(in.head._1, in.head._2, priorityMux(in.tail)) + val r = in.view.reverse + r.tail.foldLeft(r.head._2) { + case (alt, (sel, elt)) => Mux(sel, elt, alt) + } } } diff --git a/src/test/scala/chiselTests/util/PriorityMuxSpec.scala b/src/test/scala/chiselTests/util/PriorityMuxSpec.scala new file mode 100644 index 00000000..32cf2431 --- /dev/null +++ b/src/test/scala/chiselTests/util/PriorityMuxSpec.scala @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chiselTests.util + +import chisel3._ +import chisel3.util.{is, switch, Counter, PriorityMux} +import chisel3.testers.BasicTester +import chisel3.stage.ChiselStage.emitChirrtl + +import chiselTests.ChiselFlatSpec + +class PriorityMuxTester extends BasicTester { + + val sel = Wire(UInt(3.W)) + sel := 0.U // default + + val elts = Seq(5.U, 6.U, 7.U) + val muxed = PriorityMux(sel, elts) + + // Priority is given to lowest order bit + val tests = Seq( + 1.U -> elts(0), + 2.U -> elts(1), + 3.U -> elts(0), + 4.U -> elts(2), + 5.U -> elts(0), + 6.U -> elts(1), + 7.U -> elts(0) + ) + val (cycle, done) = Counter(0 until tests.size + 1) + + for (((in, out), idx) <- tests.zipWithIndex) { + when(cycle === idx.U) { + sel := in + assert(muxed === out) + } + } + + when(done) { + stop() + } +} + +class PriorityMuxSpec extends ChiselFlatSpec { + behavior.of("PriorityMux") + + it should "be functionally correct" in { + assertTesterPasses(new PriorityMuxTester) + } + + it should "be stack safe" in { + emitChirrtl(new RawModule { + val n = 1 << 15 + val in = IO(Input(Vec(n, UInt(8.W)))) + val sel = IO(Input(UInt(n.W))) + val out = IO(Output(UInt(8.W))) + out := PriorityMux(sel, in) + }) + } +} |
