From cb5fe764812a850c6087aa35d6a12c98d3ce6fc4 Mon Sep 17 00:00:00 2001 From: Schuyler Eldridge Date: Mon, 19 Oct 2020 12:35:26 -0400 Subject: [PATCH] Enable Cat of Zero Element Vec (#1623) * Return 0.U for asUInt of a zero-element Seq Add a condition to SeqUtils.asUInt to have it return an unspecified width 0.U when applied to an empty sequence. This enables the ability to do a Cat of a zero-element sequence. Signed-off-by: Schuyler Eldridge * Test elaboration of Cat on zero-element Seq Signed-off-by: Schuyler Eldridge (cherry picked from commit ac641fb183e3a8866e6bd72123801cfb04a0c893) --- .../src/main/scala/chisel3/SeqUtils.scala | 5 ++- src/main/scala/chisel3/util/Cat.scala | 1 + src/test/scala/chiselTests/util/CatSpec.scala | 34 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/test/scala/chiselTests/util/CatSpec.scala diff --git a/chiselFrontend/src/main/scala/chisel3/SeqUtils.scala b/chiselFrontend/src/main/scala/chisel3/SeqUtils.scala index 28f753b1b68..e780eb2e554 100644 --- a/chiselFrontend/src/main/scala/chisel3/SeqUtils.scala +++ b/chiselFrontend/src/main/scala/chisel3/SeqUtils.scala @@ -16,12 +16,15 @@ private[chisel3] object SeqUtils { * in the sequence forms the most significant bits. * * Equivalent to r(n-1) ## ... ## r(1) ## r(0). + * @note This returns a `0.U` if applied to a zero-element `Vec`. */ def asUInt[T <: Bits](in: Seq[T]): UInt = macro SourceInfoTransform.inArg /** @group SourceInfoTransformMacros */ def do_asUInt[T <: Bits](in: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = { - if (in.tail.isEmpty) { + if (in.isEmpty) { + 0.U + } else if (in.tail.isEmpty) { in.head.asUInt } else { val left = asUInt(in.slice(0, in.length/2)) diff --git a/src/main/scala/chisel3/util/Cat.scala b/src/main/scala/chisel3/util/Cat.scala index ee01c6e64e9..f26e96bb0fa 100644 --- a/src/main/scala/chisel3/util/Cat.scala +++ b/src/main/scala/chisel3/util/Cat.scala @@ -25,6 +25,7 @@ object Cat { * in the sequence forms the least significant bits. * * Equivalent to r(0) ## r(1) ## ... ## r(n-1). + * @note This returns a `0.U` if applied to a zero-element `Vec`. */ def apply[T <: Bits](r: Seq[T]): UInt = SeqUtils.asUInt(r.reverse) } diff --git a/src/test/scala/chiselTests/util/CatSpec.scala b/src/test/scala/chiselTests/util/CatSpec.scala new file mode 100644 index 00000000000..eb94a420c50 --- /dev/null +++ b/src/test/scala/chiselTests/util/CatSpec.scala @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 + +package chiselTests.util + +import chisel3._ +import chisel3.stage.ChiselGeneratorAnnotation +import chisel3.util.Cat + +import chiselTests.ChiselFlatSpec + +object CatSpec { + + class JackIsATypeSystemGod extends MultiIOModule { + val in = IO(Input (Vec(0, UInt(8.W)))) + val out = IO(Output(UInt(8.W))) + + out := Cat(in) + } + +} + +class CatSpec extends ChiselFlatSpec { + + import CatSpec._ + + behavior of "util.Cat" + + it should "not fail to elaborate a zero-element Vec" in { + + ChiselGeneratorAnnotation(() => new JackIsATypeSystemGod).elaborate + + } + +}