summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rw-r--r--build.sbt36
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala43
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Bits.scala234
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Data.scala2
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Module.scala12
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/Builder.scala12
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala47
-rw-r--r--src/main/scala/chisel3/Driver.scala4
-rw-r--r--src/main/scala/chisel3/package.scala7
-rw-r--r--src/main/scala/chisel3/util/BitPat.scala1
-rw-r--r--src/main/scala/chisel3/util/Decoupled.scala2
-rw-r--r--src/test/scala/chiselTests/BundleWire.scala28
-rw-r--r--src/test/scala/chiselTests/FixedPointSpec.scala41
-rw-r--r--src/test/scala/chiselTests/Vec.scala6
15 files changed, 410 insertions, 68 deletions
diff --git a/README.md b/README.md
index 7b9454c3..983f2b68 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,8 @@
Chisel3 is a new FIRRTL based chisel.
It is currently in ALPHA VERSION, so many Chisel features may change in the coming months.
-*TODO: A better description, perhaps lifted off Chisel2's README*
+Please visit the [Wiki](https://github.com/ucb-bar/chisel3/wiki) for a more
+detailed description.
## Chisel2 Migration
For those moving from Chisel2, there were some backwards incompatible changes
diff --git a/build.sbt b/build.sbt
index 04dc25ed..4ad1cf77 100644
--- a/build.sbt
+++ b/build.sbt
@@ -64,25 +64,25 @@ lazy val chiselSettings = Seq (
Resolver.sonatypeRepo("releases")
),
- libraryDependencies ++= (Seq("firrtl").map {
- dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) }),
-
-
-/* Bumping "com.novocode" % "junit-interface" % "0.11", causes DelayTest testSeqReadBundle to fail
- * in subtly disturbing ways on Linux (but not on Mac):
- * - some fields in the generated .h file are re-named,
- * - an additional field is added
- * - the generated .cpp file has additional differences:
- * - different temps in clock_lo
- * - missing assignments
- * - change of assignment order
- * - use of "Tx" vs. "Tx.values"
- */
- libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.5" % "test",
- libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
- libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.12.4" % "test",
- libraryDependencies += "com.github.scopt" %% "scopt" % "3.4.0",
+ libraryDependencies ++= Seq(
+ "org.scalatest" %% "scalatest" % "2.2.5" % "test",
+ "org.scala-lang" % "scala-reflect" % scalaVersion.value,
+ "org.scalacheck" %% "scalacheck" % "1.12.4" % "test",
+ "com.github.scopt" %% "scopt" % "3.4.0"
+ ),
+ // Since we want to examine the classpath to determine if a dependency on firrtl is required,
+ // this has to be a Task setting.
+ // Fortunately, allDependencies is a Task Setting, so we can modify that.
+ allDependencies := {
+ allDependencies.value ++ Seq("firrtl").collect {
+ // If we have an unmanaged jar file on the classpath, assume we're to use that,
+ case dep: String if !(unmanagedClasspath in Compile).value.toString.contains(s"$dep.jar") =>
+ // otherwise let sbt fetch the appropriate version.
+ "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep))
+ }
+ },
+
// Tests from other projects may still run concurrently.
parallelExecution in Test := true,
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
index 9d8a9061..677fa43e 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
@@ -19,6 +19,8 @@ sealed abstract class Aggregate extends Data {
private[core] def width: Width = flatten.map(_.width).reduce(_ + _)
private[core] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit =
pushCommand(BulkConnect(sourceInfo, this.lref, that.lref))
+
+ override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = SeqUtils.do_asUInt(this.flatten)
}
object Vec {
@@ -351,24 +353,10 @@ class Bundle extends Aggregate {
/** Returns a field's contained user-defined Bundle element if it appears to
* be one, otherwise returns None.
*/
- private def getBundleField(m: java.lang.reflect.Method): Option[Data] = {
- if (isBundleField(m) &&
- (classOf[Data].isAssignableFrom(m.getReturnType) ||
- classOf[Option[_]].isAssignableFrom(m.getReturnType))) {
- m.invoke(this) match {
- case d: Data =>
- Some(d)
- case o: Option[_] =>
- o.getOrElse(None) match {
- case d: Data =>
- Some(d)
- case _ => None
- }
- case _ => None
- }
- } else {
- None
- }
+ private def getBundleField(m: java.lang.reflect.Method): Option[Data] = m.invoke(this) match {
+ case d: Data => Some(d)
+ case Some(d: Data) => Some(d)
+ case _ => None
}
/** Returns a list of elements in this Bundle.
@@ -376,15 +364,14 @@ class Bundle extends Aggregate {
private[core] lazy val namedElts = {
val nameMap = LinkedHashMap[String, Data]()
val seen = HashSet[Data]()
- for (m <- getClass.getMethods.sortWith(_.getName < _.getName)) {
- getBundleField(m) match {
- case Some(d) =>
- if (nameMap contains m.getName) {
- require(nameMap(m.getName) eq d)
- } else if (!seen(d)) {
- nameMap(m.getName) = d; seen += d
- }
- case None =>
+ for (m <- getPublicFields(classOf[Bundle])) {
+ getBundleField(m) foreach { d =>
+ if (nameMap contains m.getName) {
+ require(nameMap(m.getName) eq d)
+ } else if (!seen(d)) {
+ nameMap(m.getName) = d
+ seen += d
+ }
}
}
ArrayBuffer(nameMap.toSeq:_*) sortWith {case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn))}
@@ -397,8 +384,6 @@ class Bundle extends Aggregate {
s"{${namedElts.reverse.map(e => eltPort(e._2)).mkString(", ")}}"
}
private[chisel3] lazy val flatten = namedElts.flatMap(_._2.flatten)
- private[core] def addElt(name: String, elt: Data): Unit =
- namedElts += name -> elt
private[chisel3] override def _onModuleClose: Unit = // scalastyle:ignore method.name
for ((name, elt) <- namedElts) { elt.setRef(this, _namespace.name(name)) }
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
index 741f6aee..7ee11b92 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
@@ -250,6 +250,18 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
def do_asSInt(implicit sourceInfo: SourceInfo): SInt
+ /** Reinterpret cast as a FixedPoint.
+ *
+ * @note value not guaranteed to be preserved: for example, an UInt of width
+ * 3 and value 7 (0b111) would become a FixedInt with value -1, the interpretation
+ * of the number is also affected by the specified binary point. Caution advised
+ */
+ final def asFixedPoint(that: BinaryPoint): FixedPoint = macro SourceInfoTransform.thatArg
+
+ def do_asFixedPoint(that: BinaryPoint)(implicit sourceInfo: SourceInfo): FixedPoint = {
+ throwException(s"Cannot call .asFixedPoint on $this")
+ }
+
/** Reinterpret cast to Bits. */
@deprecated("Use asUInt, which does the same thing but returns a more concrete type", "chisel3")
final def asBits(): Bits = macro SourceInfoTransform.noArg
@@ -282,9 +294,6 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
pushOp(DefPrim(sourceInfo, UInt(w), ConcatOp, this.ref, that.ref))
}
- @deprecated("Use asUInt, which does the same thing but makes the reinterpret cast more explicit", "chisel3")
- override def toBits: UInt = do_asUInt(DeprecatedSourceInfo)
-
override def do_fromBits(that: Bits)(implicit sourceInfo: SourceInfo): this.type = {
val res = Wire(this, null).asInstanceOf[this.type]
res := that
@@ -463,6 +472,7 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
override def do_<= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessEqOp, that)
override def do_>= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterEqOp, that)
+ @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3")
final def != (that: UInt): Bool = macro SourceInfoTransform.thatArg
final def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg
final def === (that: UInt): Bool = macro SourceInfoTransform.thatArg
@@ -510,6 +520,15 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
override def do_asSInt(implicit sourceInfo: SourceInfo): SInt =
pushOp(DefPrim(sourceInfo, SInt(width), AsSIntOp, ref))
override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = this
+ override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo): FixedPoint = {
+ binaryPoint match {
+ case KnownBinaryPoint(value) =>
+ val iLit = ILit(value)
+ pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref, iLit))
+ case _ =>
+ throwException(s"cannot call $this.asFixedPoint(binaryPoint=$binaryPoint), you must specify a known binaryPoint")
+ }
+ }
}
// This is currently a factory because both Bits and UInt inherit it.
@@ -658,6 +677,7 @@ sealed class SInt private (width: Width, lit: Option[SLit] = None)
override def do_<= (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessEqOp, that)
override def do_>= (that: SInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterEqOp, that)
+ @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3")
final def != (that: SInt): Bool = macro SourceInfoTransform.thatArg
final def =/= (that: SInt): Bool = macro SourceInfoTransform.thatArg
final def === (that: SInt): Bool = macro SourceInfoTransform.thatArg
@@ -685,6 +705,9 @@ sealed class SInt private (width: Width, lit: Option[SLit] = None)
override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = pushOp(DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref))
override def do_asSInt(implicit sourceInfo: SourceInfo): SInt = this
+ override def do_asFixedPoint(binaryPoint: BinaryPoint)(implicit sourceInfo: SourceInfo): FixedPoint = {
+ pushOp(DefPrim(sourceInfo, FixedPoint(width, binaryPoint), AsFixedPointOp, ref))
+ }
}
object SInt {
@@ -853,3 +876,208 @@ object Mux {
}
}
+//scalastyle:off number.of.methods
+/**
+ * A sealed class representing a fixed point number that has a bit width and a binary point
+ * The width and binary point may be inferred.
+ *
+ * IMPORTANT: The API provided here is experimental and may change in the future.
+ *
+ * @param width bit width of the fixed point number
+ * @param binaryPoint the position of the binary point with respect to the right most bit of the width
+ * currently this should be positive but it is hoped to soon support negative points
+ * and thus use this field as a simple exponent
+ * @param lit
+ */
+sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit: Option[FPLit] = None)
+ extends Bits(width, lit) with Num[FixedPoint] {
+ private[core] override def cloneTypeWidth(w: Width): this.type =
+ new FixedPoint(w, binaryPoint).asInstanceOf[this.type]
+ private[chisel3] def toType = s"Fixed$width$binaryPoint"
+
+ def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match {
+ case _: FixedPoint => this connect that
+ case _ => this badConnect that
+ }
+
+ private[chisel3] def fromInt(value: BigInt, width: Int): this.type = {
+ throwException(s"Don't use $this.fromInt($value, $width): Use literal constructors instead")
+ }
+
+ final def unary_- (): FixedPoint = macro SourceInfoTransform.noArg
+ final def unary_-% (): FixedPoint = macro SourceInfoTransform.noArg
+
+ def unary_- (implicit sourceInfo: SourceInfo): FixedPoint = FixedPoint.fromBigInt(0) - this
+ def unary_-% (implicit sourceInfo: SourceInfo): FixedPoint = FixedPoint.fromBigInt(0) -% this
+
+ /** add (default - no growth) operator */
+ override def do_+ (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ this +% that
+ /** subtract (default - no growth) operator */
+ override def do_- (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ this -% that
+ override def do_* (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint(this.width + that.width, this.binaryPoint + that.binaryPoint), TimesOp, that)
+ override def do_/ (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ throwException(s"division is illegal on FixedPoint types")
+ override def do_% (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ throwException(s"mod is illegal on FixedPoint types")
+
+ final def * (that: UInt): FixedPoint = macro SourceInfoTransform.thatArg
+ def do_* (that: UInt)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that)
+
+ final def * (that: SInt): FixedPoint = macro SourceInfoTransform.thatArg
+ def do_* (that: SInt)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint(this.width + that.width, binaryPoint), TimesOp, that)
+
+ /** add (width +1) operator */
+ final def +& (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
+ /** add (no growth) operator */
+ final def +% (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
+ /** subtract (width +1) operator */
+ final def -& (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
+ /** subtract (no growth) operator */
+ final def -% (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
+
+ def do_+& (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint((this.width max that.width) + 1, this.binaryPoint max that.binaryPoint), AddOp, that)
+ def do_+% (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ (this +& that).tail(1).asFixedPoint(this.binaryPoint max that.binaryPoint)
+ def do_-& (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint((this.width max that.width) + 1, this.binaryPoint max that.binaryPoint), SubOp, that)
+ def do_-% (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ (this -& that).tail(1).asFixedPoint(this.binaryPoint max that.binaryPoint)
+
+ final def & (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
+ final def | (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
+ final def ^ (that: FixedPoint): FixedPoint = macro SourceInfoTransform.thatArg
+
+ def do_& (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ throwException(s"And is illegal between $this and $that")
+ def do_| (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ throwException(s"Or is illegal between $this and $that")
+ def do_^ (that: FixedPoint)(implicit sourceInfo: SourceInfo): FixedPoint =
+ throwException(s"Xor is illegal between $this and $that")
+
+ final def setBinaryPoint(that: Int): FixedPoint = macro SourceInfoTransform.thatArg
+
+ def do_setBinaryPoint(that: Int)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint(this.width, KnownBinaryPoint(that)), SetBinaryPoint, that)
+
+ /** Returns this wire bitwise-inverted. */
+ def do_unary_~ (implicit sourceInfo: SourceInfo): FixedPoint =
+ throwException(s"Not is illegal on $this")
+
+ // TODO(chick): Consider comparison with UInt and SInt
+ override def do_< (that: FixedPoint)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessOp, that)
+ override def do_> (that: FixedPoint)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterOp, that)
+ override def do_<= (that: FixedPoint)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessEqOp, that)
+ override def do_>= (that: FixedPoint)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, GreaterEqOp, that)
+
+ final def != (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg
+ final def =/= (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg
+ final def === (that: FixedPoint): Bool = macro SourceInfoTransform.thatArg
+
+ def do_!= (that: FixedPoint)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, NotEqualOp, that)
+ def do_=/= (that: FixedPoint)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, NotEqualOp, that)
+ def do_=== (that: FixedPoint)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, EqualOp, that)
+
+ final def abs(): UInt = macro SourceInfoTransform.noArg
+
+ def do_abs(implicit sourceInfo: SourceInfo): UInt = {
+ Mux(this < FixedPoint.fromBigInt(0), (FixedPoint.fromBigInt(0)-this).asUInt, this.asUInt)
+ }
+
+ override def do_<< (that: Int)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint(this.width + that, this.binaryPoint), ShiftLeftOp, that)
+ override def do_<< (that: BigInt)(implicit sourceInfo: SourceInfo): FixedPoint =
+ this << that.toInt
+ override def do_<< (that: UInt)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint(this.width.dynamicShiftLeft(that.width), this.binaryPoint), DynamicShiftLeftOp, that)
+ override def do_>> (that: Int)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint(this.width.shiftRight(that), this.binaryPoint), ShiftRightOp, that)
+ override def do_>> (that: BigInt)(implicit sourceInfo: SourceInfo): FixedPoint =
+ this >> that.toInt
+ override def do_>> (that: UInt)(implicit sourceInfo: SourceInfo): FixedPoint =
+ binop(sourceInfo, FixedPoint(this.width, this.binaryPoint), DynamicShiftRightOp, that)
+
+ 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
+}
+
+/** Use PrivateObject to force users to specify width and binaryPoint by name
+ */
+sealed trait PrivateType
+private case object PrivateObject extends PrivateType
+
+/**
+ * Factory and convenience methods for the FixedPoint class
+ * IMPORTANT: The API provided here is experimental and may change in the future.
+ */
+object FixedPoint {
+ /** Create an FixedPoint type with inferred width. */
+ def apply(): FixedPoint = apply(Width(), BinaryPoint())
+
+ /** Create an FixedPoint type or port with fixed width. */
+ def apply(width: Int, binaryPoint: Int): FixedPoint = apply(Width(width), BinaryPoint(binaryPoint))
+ /** Create an FixedPoint port with inferred width. */
+ def apply(dir: Direction): FixedPoint = apply(dir, Width(), BinaryPoint())
+
+ /** Create an FixedPoint literal with inferred width from BigInt.
+ * Use PrivateObject to force users to specify width and binaryPoint by name
+ */
+ def fromBigInt(value: BigInt, width: Int = -1, binaryPoint: Int = 0): FixedPoint =
+ if(width == -1) {
+ apply(value, Width(), BinaryPoint(binaryPoint))
+ }
+ else {
+ apply(value, Width(width), BinaryPoint(binaryPoint))
+ }
+ /** Create an FixedPoint literal with inferred width from Double.
+ * Use PrivateObject to force users to specify width and binaryPoint by name
+ */
+ def fromDouble(value: Double, dummy: PrivateType = PrivateObject,
+ width: Int = -1, binaryPoint: Int = 0): FixedPoint = {
+ fromBigInt(
+ toBigInt(value, binaryPoint), width = width, binaryPoint = binaryPoint
+ )
+ }
+
+ /** Create an FixedPoint type with specified width and binary position. */
+ def apply(width: Width, binaryPoint: BinaryPoint): FixedPoint = new FixedPoint(width, binaryPoint)
+ /** Create an FixedPoint port with specified width and binary position. */
+ def apply(dir: Direction, width: Width, binaryPoint: BinaryPoint): FixedPoint = new FixedPoint(width, binaryPoint)
+ def apply(value: BigInt, width: Width, binaryPoint: BinaryPoint): FixedPoint = {
+ val lit = FPLit(value, width, binaryPoint)
+ val newLiteral = new FixedPoint(lit.width, lit.binaryPoint, Some(lit))
+ newLiteral.binding = LitBinding()
+ newLiteral
+ }
+
+ /**
+ * How to create a bigint from a double with a specific binaryPoint
+ * @param x a double value
+ * @param binaryPoint a binaryPoint that you would like to use
+ * @return
+ */
+ def toBigInt(x: Double, binaryPoint : Int): BigInt = {
+ val multiplier = math.pow(2,binaryPoint )
+ val result = BigInt(math.round(x * multiplier))
+ result
+ }
+
+ /**
+ * converts a bigInt with the given binaryPoint into the double representation
+ * @param i a bigint
+ * @param binaryPoint the implied binaryPoint of @i
+ * @return
+ */
+ def toDouble(i: BigInt, binaryPoint : Int): Double = {
+ val multiplier = math.pow(2,binaryPoint )
+ val result = i.toDouble / multiplier
+ result
+ }
+
+}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
index bd2e9065..86858e5d 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
@@ -254,7 +254,7 @@ abstract class Data extends HasId {
*
* This performs the inverse operation of fromBits(Bits).
*/
- @deprecated("Use asUInt, which does the same thing but makes the reinterpret cast more explicit", "chisel3")
+ @deprecated("Best alternative, .toUInt() or if Bits really needed, .toUInt().toBits()", "chisel3")
def toBits(): UInt = SeqUtils.do_asUInt(this.flatten)(DeprecatedSourceInfo)
/** Reinterpret cast to UInt.
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
index 55522b4a..c700dc1b 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
@@ -162,15 +162,6 @@ extends HasId {
port.setRef(ModuleIO(this, _namespace.name(name)))
}
- // Suggest names to nodes using runtime reflection
- def getValNames(c: Class[_]): Set[String] = {
- if (c == classOf[Module]) Set()
- else getValNames(c.getSuperclass) ++ c.getDeclaredFields.map(_.getName)
- }
- val valNames = getValNames(this.getClass)
- def isPublicVal(m: java.lang.reflect.Method) =
- m.getParameterTypes.isEmpty && valNames.contains(m.getName)
-
/** Recursively suggests names to supported "container" classes
* Arbitrary nestings of supported classes are allowed so long as the
* innermost element is of type HasId
@@ -189,8 +180,7 @@ extends HasId {
}
case _ => // Do nothing
}
- val methods = getClass.getMethods.sortWith(_.getName > _.getName)
- for (m <- methods if isPublicVal(m)) {
+ for (m <- getPublicFields(classOf[Module])) {
nameRecursively(m.getName, m.invoke(this))
}
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala
index 12cc840e..b4b0e028 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala
@@ -127,6 +127,18 @@ private[chisel3] trait HasId extends InstanceId {
case Some(p) => p.modName
case None => throwException(s"$instanceName doesn't have a parent")
}
+
+ private[chisel3] def getPublicFields(rootClass: Class[_]): Seq[java.lang.reflect.Method] = {
+ // Suggest names to nodes using runtime reflection
+ def getValNames(c: Class[_]): Set[String] = {
+ if (c == rootClass) Set()
+ else getValNames(c.getSuperclass) ++ c.getDeclaredFields.map(_.getName)
+ }
+ val valNames = getValNames(this.getClass)
+ def isPublicVal(m: java.lang.reflect.Method) =
+ m.getParameterTypes.isEmpty && valNames.contains(m.getName)
+ this.getClass.getMethods.sortWith(_.getName < _.getName).filter(isPublicVal(_))
+ }
}
private[chisel3] class DynamicContext() {
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
index 0641686c..0f866c27 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -42,6 +42,8 @@ object PrimOp {
val ConvertOp = PrimOp("cvt")
val AsUIntOp = PrimOp("asUInt")
val AsSIntOp = PrimOp("asSInt")
+ val AsFixedPointOp = PrimOp("asFixedPoint")
+ val SetBinaryPoint = PrimOp("bpset")
val AsClockOp = PrimOp("asClock")
}
@@ -85,6 +87,14 @@ case class SLit(n: BigInt, w: Width) extends LitArg(n, w) {
def minWidth: Int = 1 + n.bitLength
}
+case class FPLit(n: BigInt, w: Width, binaryPoint: BinaryPoint) extends LitArg(n, w) {
+ def name: String = {
+ val unsigned = if (n < 0) (BigInt(1) << width.get) + n else n
+ s"asFixedPoint(${ULit(unsigned, width).name}, ${binaryPoint.asInstanceOf[KnownBinaryPoint].value})"
+ }
+ def minWidth: Int = 1 + n.bitLength
+}
+
case class Ref(name: String) extends Arg
case class ModuleIO(mod: Module, name: String) extends Arg {
override def fullName(ctx: Component): String =
@@ -136,6 +146,43 @@ sealed case class KnownWidth(value: Int) extends Width {
override def toString: String = s"<${value.toString}>"
}
+object BinaryPoint {
+ def apply(x: Int): BinaryPoint = KnownBinaryPoint(x)
+ def apply(): BinaryPoint = UnknownBinaryPoint
+}
+
+sealed abstract class BinaryPoint {
+ type W = Int
+ def max(that: BinaryPoint): BinaryPoint = this.op(that, _ max _)
+ def + (that: BinaryPoint): BinaryPoint = this.op(that, _ + _)
+ def + (that: Int): BinaryPoint = this.op(this, (a, b) => a + that)
+ def shiftRight(that: Int): BinaryPoint = this.op(this, (a, b) => 0 max (a - that))
+ def dynamicShiftLeft(that: BinaryPoint): BinaryPoint =
+ this.op(that, (a, b) => a + (1 << b) - 1)
+
+ def known: Boolean
+ def get: W
+ protected def op(that: BinaryPoint, f: (W, W) => W): BinaryPoint
+}
+
+case object UnknownBinaryPoint extends BinaryPoint {
+ def known: Boolean = false
+ def get: Int = None.get
+ def op(that: BinaryPoint, f: (W, W) => W): BinaryPoint = this
+ override def toString: String = ""
+}
+
+sealed case class KnownBinaryPoint(value: Int) extends BinaryPoint {
+ def known: Boolean = true
+ def get: Int = value
+ def op(that: BinaryPoint, f: (W, W) => W): BinaryPoint = that match {
+ case KnownBinaryPoint(x) => KnownBinaryPoint(f(value, x))
+ case _ => that
+ }
+ override def toString: String = s"<<${value.toString}>>"
+}
+
+
sealed abstract class MemPortDirection(name: String) {
override def toString: String = name
}
diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala
index dbd9b464..a0713379 100644
--- a/src/main/scala/chisel3/Driver.scala
+++ b/src/main/scala/chisel3/Driver.scala
@@ -119,13 +119,13 @@ trait BackendCompilationUtilities {
"-Wno-WIDTH",
"-Wno-STMTDLY",
"--trace",
- "-O2",
+ "-O0",
"--top-module", topModule,
"+define+TOP_TYPE=V" + dutFile,
s"+define+PRINTF_COND=!$topModule.reset",
s"+define+STOP_COND=!$topModule.reset",
"-CFLAGS",
- s"""-Wno-undefined-bool-conversion -O2 -DTOP_TYPE=V$dutFile -include V$dutFile.h""",
+ s"""-Wno-undefined-bool-conversion -O0 -DTOP_TYPE=V$dutFile -include V$dutFile.h""",
"-Mdir", dir.toString,
"--exe", cppHarness.toString)
System.out.println(s"${command.mkString(" ")}") // scalastyle:ignore regex
diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala
index 0a57b7de..e0364868 100644
--- a/src/main/scala/chisel3/package.scala
+++ b/src/main/scala/chisel3/package.scala
@@ -37,6 +37,8 @@ package object chisel3 { // scalastyle:ignore package.object.name
val UInt = chisel3.core.UInt
type SInt = chisel3.core.SInt
val SInt = chisel3.core.SInt
+ type FixedPoint = chisel3.core.FixedPoint
+ val FixedPoint = chisel3.core.FixedPoint
type Bool = chisel3.core.Bool
val Bool = chisel3.core.Bool
val Mux = chisel3.core.Mux
@@ -150,8 +152,13 @@ package object chisel3 { // scalastyle:ignore package.object.name
def B: Bool = Bool(x) // scalastyle:ignore method.name
}
+ implicit class fromDoubleToLiteral(val x: Double) extends AnyVal {
+ def F(binaryPoint: Int): FixedPoint = FixedPoint.fromDouble(x, binaryPoint = binaryPoint)
+ }
+
implicit class fromUIntToBitPatComparable(val x: UInt) extends AnyVal {
final def === (that: BitPat): Bool = macro SourceInfoTransform.thatArg
+ @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3")
final def != (that: BitPat): Bool = macro SourceInfoTransform.thatArg
final def =/= (that: BitPat): Bool = macro SourceInfoTransform.thatArg
diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala
index 972010a6..e58258c7 100644
--- a/src/main/scala/chisel3/util/BitPat.scala
+++ b/src/main/scala/chisel3/util/BitPat.scala
@@ -82,6 +82,7 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) {
def getWidth: Int = width
def === (that: UInt): Bool = macro SourceInfoTransform.thatArg
def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg
+ @deprecated("Use '=/=', which avoids potential precedence problems", "chisel3")
def != (that: UInt): Bool = macro SourceInfoTransform.thatArg
def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = value.asUInt === (that & mask.asUInt) // scalastyle:ignore method.name
diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala
index a0cbf4f7..c9d57759 100644
--- a/src/main/scala/chisel3/util/Decoupled.scala
+++ b/src/main/scala/chisel3/util/Decoupled.scala
@@ -145,6 +145,8 @@ class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle
val deq = EnqIO(gen)
/** The current amount of data in the queue */
val count = Output(UInt.width(log2Up(entries + 1)))
+
+ override def cloneType = new QueueIO(gen, entries).asInstanceOf[this.type]
}
/** A hardware module implementing a Queue
diff --git a/src/test/scala/chiselTests/BundleWire.scala b/src/test/scala/chiselTests/BundleWire.scala
index 53d46e93..5b38ff6e 100644
--- a/src/test/scala/chiselTests/BundleWire.scala
+++ b/src/test/scala/chiselTests/BundleWire.scala
@@ -24,6 +24,27 @@ class BundleWire(n: Int) extends Module {
}
}
+class BundleToUnitTester extends BasicTester {
+ val bundle1 = Wire(new Bundle {
+ val a = UInt(width = 4)
+ val b = UInt(width = 4)
+ })
+ val bundle2 = Wire(new Bundle {
+ val a = UInt(width = 2)
+ val b = UInt(width = 6)
+ })
+
+ // 0b00011011 split as 0001 1011 and as 00 011011
+ bundle1.a := 1.U
+ bundle1.b := 11.U
+ bundle2.a := 0.U
+ bundle2.b := 27.U
+
+ assert(bundle1.asUInt() === bundle2.asUInt())
+
+ stop()
+}
+
class BundleWireTester(n: Int, x: Int, y: Int) extends BasicTester {
val dut = Module(new BundleWire(n))
dut.io.in.x := UInt(x)
@@ -43,3 +64,10 @@ class BundleWireSpec extends ChiselPropSpec {
}
}
}
+
+class BundleToUIntSpec extends ChiselPropSpec {
+ property("Bundles with same data but different, underlying elements should compare as UInt") {
+ assertTesterPasses( new BundleToUnitTester )
+ }
+}
+
diff --git a/src/test/scala/chiselTests/FixedPointSpec.scala b/src/test/scala/chiselTests/FixedPointSpec.scala
new file mode 100644
index 00000000..69015e42
--- /dev/null
+++ b/src/test/scala/chiselTests/FixedPointSpec.scala
@@ -0,0 +1,41 @@
+// See LICENSE for license details.
+
+package chiselTests
+
+import chisel3._
+import chisel3.testers.BasicTester
+import org.scalatest._
+
+//scalastyle:off magic.number
+class FixedPointSpec extends FlatSpec with Matchers {
+ behavior of "fixed point utilities"
+
+ they should "allow conversion between doubles and the bigints needed to represent them" in {
+ val initialDouble = 0.125
+ val bigInt = FixedPoint.toBigInt(initialDouble, 4)
+ val finalDouble = FixedPoint.toDouble(bigInt, 4)
+
+ initialDouble should be(finalDouble)
+ }
+}
+
+class SBP extends Module {
+ val io = IO(new Bundle {
+ val in = Input(FixedPoint(6, 2))
+ val out = Output(FixedPoint(4, 0))
+ })
+ io.out := io.in.setBinaryPoint(0)
+}
+class SBPTester extends BasicTester {
+ val dut = Module(new SBP)
+ dut.io.in := FixedPoint.fromDouble(3.75, binaryPoint = 2)
+
+ assert(dut.io.out === FixedPoint.fromDouble(3.0, binaryPoint = 0))
+
+ stop()
+}
+class SBPSpec extends ChiselPropSpec {
+ property("should allow set binary point") {
+ assertTesterPasses { new SBPTester }
+ }
+}
diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala
index c5447610..0d5a2188 100644
--- a/src/test/scala/chiselTests/Vec.scala
+++ b/src/test/scala/chiselTests/Vec.scala
@@ -23,9 +23,9 @@ class TabulateTester(n: Int) extends BasicTester {
val x = Vec(Array.tabulate(n){ i => UInt(i * 2) })
val u = Vec.tabulate(n)(i => UInt(i*2))
- assert(v.toBits === x.toBits)
- assert(v.toBits === u.toBits)
- assert(x.toBits === u.toBits)
+ assert(v.asUInt() === x.asUInt())
+ assert(v.asUInt() === u.asUInt())
+ assert(x.asUInt() === u.asUInt())
stop()
}