From 7dcff5d14b48235a39696c73245ff19576117d26 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Fri, 4 Oct 2024 23:16:20 -0700 Subject: [PATCH] Make it legal to extract zero bits from a zero-width UInt (#4445) (cherry picked from commit 4f392323e9160440961b9f06e383d3f2742d2f3e) --- core/src/main/scala/chisel3/Bits.scala | 13 ++++++++----- src/test/scala/chiselTests/UIntOps.scala | 11 +++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/chisel3/Bits.scala b/core/src/main/scala/chisel3/Bits.scala index 58719c2d0ff..c8087a1eab6 100644 --- a/core/src/main/scala/chisel3/Bits.scala +++ b/core/src/main/scala/chisel3/Bits.scala @@ -224,11 +224,14 @@ sealed abstract class Bits(private[chisel3] val width: Width) extends Element wi }.getOrElse { requireIsHardware(this, "bits to be sliced") - widthOption match { - case Some(w) if w == 0 => Builder.error(s"Cannot extract from zero-width") - case Some(w) if y >= w => Builder.error(s"High and low indices $x and $y are both out of range [0, ${w - 1}]") - case Some(w) if x >= w => Builder.error(s"High index $x is out of range [0, ${w - 1}]") - case _ => + // Illegal zero-width extractions are already caught, any at this point are legal. + if (resultWidth != 0) { + widthOption match { + case Some(w) if w == 0 => Builder.error(s"Cannot extract from zero-width") + case Some(w) if y >= w => Builder.error(s"High and low indices $x and $y are both out of range [0, ${w - 1}]") + case Some(w) if x >= w => Builder.error(s"High index $x is out of range [0, ${w - 1}]") + case _ => + } } // FIRRTL does not yet support empty extraction so we must return the zero-width wire here: diff --git a/src/test/scala/chiselTests/UIntOps.scala b/src/test/scala/chiselTests/UIntOps.scala index 7920815c219..1fc1760ea0f 100644 --- a/src/test/scala/chiselTests/UIntOps.scala +++ b/src/test/scala/chiselTests/UIntOps.scala @@ -535,4 +535,15 @@ class UIntOpsSpec extends ChiselPropSpec with Matchers with Utils { 5.U(8.W).pad(16).litValue should be(5) 5.U(8.W).pad(16).getWidth should be(16) } + + property("It should be legal to extract zero bits from a zero-width UInt") { + val chirrtl = ChiselStage.emitCHIRRTL(new RawModule { + val in = IO(Input(UInt(0.W))) + val out1, out2 = IO(Output(UInt(8.W))) + out1 := in.take(0) + out2 := in(-1, 0) + }) + chirrtl should include("connect out1, UInt<0>(0h0)") + chirrtl should include("connect out2, UInt<0>(0h0)") + } }