summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman2018-05-24 11:46:32 -0700
committerGitHub2018-05-24 11:46:32 -0700
commitbffc8b9e851af88128f1c683e67634ebde25c14b (patch)
tree487471aab617aea14c47d3fea71d2cb2950c128f
parentf10c95aa4ea2e1a7484a9e1629b006322ee0e753 (diff)
Fix UIntToOH for output widths larger than 2^(input width) (#823)
* Add test for UIntToOH * Pad UIntToOH inputs to support oversized output widthds * Optimize Bits.pad in case of known widths * Add missing import and fix test in OneHotMuxSpec
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Bits.scala6
-rw-r--r--src/main/scala/chisel3/util/OneHot.scala3
-rw-r--r--src/test/scala/chiselTests/OneHotMuxSpec.scala12
3 files changed, 17 insertions, 4 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
index 51f5f5ec..b3091db3 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
@@ -190,8 +190,10 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
*/
final def pad(that: Int): this.type = macro SourceInfoTransform.thatArg
- def do_pad(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type =
- binop(sourceInfo, cloneTypeWidth(this.width max Width(that)), PadOp, that)
+ def do_pad(that: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = this.width match {
+ case KnownWidth(w) if w >= that => this
+ case _ => binop(sourceInfo, cloneTypeWidth(this.width max Width(that)), PadOp, that)
+ }
/** Returns this wire bitwise-inverted. */
final def unary_~ (): Bits = macro SourceInfoWhiteboxTransform.noArg
diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala
index 9a911c41..8a0bb9fc 100644
--- a/src/main/scala/chisel3/util/OneHot.scala
+++ b/src/main/scala/chisel3/util/OneHot.scala
@@ -46,7 +46,8 @@ object UIntToOH {
def apply(in: UInt, width: Int): UInt = width match {
case 0 => 0.U(0.W)
case _ =>
- val shiftAmount = in((log2Ceil(width) - 1) max 0, 0)
+ val shiftAmountWidth = log2Ceil(width)
+ val shiftAmount = in.pad(shiftAmountWidth)((shiftAmountWidth - 1) max 0, 0)
(1.U << shiftAmount)(width - 1, 0)
}
}
diff --git a/src/test/scala/chiselTests/OneHotMuxSpec.scala b/src/test/scala/chiselTests/OneHotMuxSpec.scala
index 9495703d..e12d7913 100644
--- a/src/test/scala/chiselTests/OneHotMuxSpec.scala
+++ b/src/test/scala/chiselTests/OneHotMuxSpec.scala
@@ -5,7 +5,7 @@ package chiselTests
import Chisel.testers.BasicTester
import chisel3._
import chisel3.experimental.FixedPoint
-import chisel3.util.Mux1H
+import chisel3.util.{Mux1H, UIntToOH}
import org.scalatest._
//scalastyle:off magic.number
@@ -40,6 +40,9 @@ class OneHotMuxSpec extends FreeSpec with Matchers with ChiselRunners {
assertTesterPasses(new DifferentBundleOneHotTester)
}
}
+ "UIntToOH with output width greater than 2^(input width)" in {
+ assertTesterPasses(new UIntToOHTester)
+ }
}
class SimpleOneHotTester extends BasicTester {
@@ -283,4 +286,11 @@ class DifferentBundleOneHotTester extends BasicTester {
stop()
}
+class UIntToOHTester extends BasicTester {
+ val out = UIntToOH(1.U, 3)
+
+ require(out.getWidth == 3)
+ assert(out === 2.U)
+ stop()
+}