summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala15
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Bits.scala32
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Data.scala21
-rw-r--r--src/test/scala/chiselTests/FixedPointSpec.scala4
-rw-r--r--src/test/scala/chiselTests/FromBitsTester.scala67
5 files changed, 114 insertions, 25 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
index 26c971b3..559a55bc 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
@@ -21,6 +21,21 @@ sealed abstract class Aggregate extends Data {
pushCommand(BulkConnect(sourceInfo, this.lref, that.lref))
override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = SeqUtils.do_asUInt(this.flatten)
+ def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
+ var i = 0
+ val wire = Wire(this.chiselCloneType)
+ val bits =
+ if (that.width.known && that.width.get >= wire.width.get) {
+ that
+ } else {
+ Wire(that.cloneTypeWidth(wire.width), init = that)
+ }
+ for (x <- wire.flatten) {
+ x := x.fromBits(bits(i + x.getWidth-1, i))
+ i += x.getWidth
+ }
+ wire.asInstanceOf[this.type]
+ }
}
object Vec {
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
index c5fc10e7..e885f1ee 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
@@ -292,12 +292,6 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
pushOp(DefPrim(sourceInfo, UInt(w), ConcatOp, this.ref, that.ref))
}
- override def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
- val res = Wire(this, null).asInstanceOf[this.type]
- res := that
- res
- }
-
/** Default print as [[Decimal]] */
final def toPrintable: Printable = Decimal(this)
}
@@ -519,6 +513,14 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint")
}
}
+ def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
+ val res = Wire(this, null).asInstanceOf[this.type]
+ res := (that match {
+ case u: UInt => u
+ case _ => that.asUInt
+ })
+ res
+ }
}
// This is currently a factory because both Bits and UInt inherit it.
@@ -655,6 +657,14 @@ sealed class SInt private[core] (width: Width, lit: Option[SLit] = None)
throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint")
}
}
+ def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
+ val res = Wire(this, null).asInstanceOf[this.type]
+ res := (that match {
+ case s: SInt => s
+ case _ => that.asSInt
+ })
+ res
+ }
}
trait SIntFactory {
@@ -916,13 +926,15 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit
override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref))
override def do_asSInt(implicit sourceInfo: SourceInfo): SInt = pushOp(DefPrim(sourceInfo, SInt(this.width), AsSIntOp, ref))
- //TODO(chick): Consider "convert" as an arithmetic conversion to UInt/SInt
-
- override def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
+ def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
val res = Wire(this, null).asInstanceOf[this.type]
- res := that.asFixedPoint(this.binaryPoint)
+ res := (that match {
+ case fp: FixedPoint => fp.asSInt.asFixedPoint(this.binaryPoint)
+ case _ => that.asFixedPoint(this.binaryPoint)
+ })
res
}
+ //TODO(chick): Consider "convert" as an arithmetic conversion to UInt/SInt
}
/** Use PrivateObject to force users to specify width and binaryPoint by name
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
index 57ed0c59..6e80f045 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
@@ -238,21 +238,7 @@ abstract class Data extends HasId {
*/
def fromBits(that: Bits): this.type = macro CompileOptionsTransform.thatArg
- def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
- var i = 0
- val wire = Wire(this.chiselCloneType)
- val bits =
- if (that.width.known && that.width.get >= wire.width.get) {
- that
- } else {
- Wire(that.cloneTypeWidth(wire.width), init = that)
- }
- for (x <- wire.flatten) {
- x := bits(i + x.getWidth-1, i)
- i += x.getWidth
- }
- wire.asInstanceOf[this.type]
- }
+ def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type
/** Packs the value of this object as plain Bits.
*
@@ -337,4 +323,9 @@ sealed class Clock extends Element(Width(1)) {
def toPrintable: Printable = PString("CLOCK")
override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref))
+ override def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): this.type = {
+ val ret = Wire(this.cloneType)
+ ret := that
+ ret.asInstanceOf[this.type]
+ }
}
diff --git a/src/test/scala/chiselTests/FixedPointSpec.scala b/src/test/scala/chiselTests/FixedPointSpec.scala
index a08de073..4e6af33b 100644
--- a/src/test/scala/chiselTests/FixedPointSpec.scala
+++ b/src/test/scala/chiselTests/FixedPointSpec.scala
@@ -22,15 +22,19 @@ class FixedPointLiteralSpec extends FlatSpec with Matchers {
class FixedPointFromBitsTester extends BasicTester {
val uint = 3.U(4.W)
val sint = -3.S
+ val fp = FixedPoint.fromDouble(3.0, width = 4, binaryPoint = 0)
val fp_tpe = FixedPoint(4.W, 1.BP)
val uint_result = FixedPoint.fromDouble(1.5, width = 4, binaryPoint = 1)
val sint_result = FixedPoint.fromDouble(-1.5, width = 4, binaryPoint = 1)
+ val fp_result = FixedPoint.fromDouble(1.5, width = 4, binaryPoint = 1)
val uint2fp = fp_tpe.fromBits(uint)
val sint2fp = fp_tpe.fromBits(sint)
+ val fp2fp = fp_tpe.fromBits(fp)
assert(uint2fp === uint_result)
assert(sint2fp === sint_result)
+ assert(fp2fp === fp_result)
stop()
}
diff --git a/src/test/scala/chiselTests/FromBitsTester.scala b/src/test/scala/chiselTests/FromBitsTester.scala
new file mode 100644
index 00000000..5809b386
--- /dev/null
+++ b/src/test/scala/chiselTests/FromBitsTester.scala
@@ -0,0 +1,67 @@
+// See LICENSE for license details.
+
+package chiselTests
+
+import org.scalatest._
+
+import chisel3._
+import chisel3.testers.BasicTester
+import chisel3.util._
+import chisel3.core.DataMirror
+
+class FromBitsBundleTester extends BasicTester {
+ class MultiTypeBundle extends Bundle {
+ val u = UInt(4.W)
+ val s = SInt(4.W)
+ val fp = FixedPoint(4.W, 3.BP)
+ }
+
+ val bun = new MultiTypeBundle
+
+ val bunFromBits = bun.fromBits( ((4 << 8) + (15 << 4) + (12 << 0)).U )
+
+ assert(bunFromBits.u === 4.U)
+ assert(bunFromBits.s === -1.S)
+ assert(bunFromBits.fp === FixedPoint.fromDouble(-0.5, width=4, binaryPoint=3))
+
+ stop()
+}
+
+class FromBitsVecTester extends BasicTester {
+ val vec = Vec(4, SInt(4.W)).fromBits( ((15 << 12) + (0 << 8) + (1 << 4) + (2 << 0)).U )
+
+ assert(vec(0) === 2.S)
+ assert(vec(1) === 1.S)
+ assert(vec(2) === 0.S)
+ assert(vec(3) === -1.S)
+
+ stop()
+}
+
+class FromBitsTruncationTester extends BasicTester {
+ val truncate = UInt(3.W).fromBits( (64 + 3).U )
+ val expand = UInt(3.W).fromBits( 1.U )
+
+ assert( DataMirror.widthOf(truncate).get == 3 )
+ assert( truncate === 3.U )
+ assert( DataMirror.widthOf(expand).get == 3 )
+ assert( expand === 1.U )
+
+ stop()
+}
+
+class FromBitsSpec extends ChiselFlatSpec {
+ behavior of "fromBits"
+
+ it should "work with Bundles containing Bits Types" in {
+ assertTesterPasses{ new FromBitsBundleTester }
+ }
+
+ it should "work with Vecs containing Bits Types" in {
+ assertTesterPasses{ new FromBitsVecTester }
+ }
+
+ it should "expand and truncate UInts of different width" in {
+ assertTesterPasses{ new FromBitsTruncationTester }
+ }
+}