summaryrefslogtreecommitdiff
path: root/chiselFrontend/src
diff options
context:
space:
mode:
authorJim Lawson2016-12-02 12:51:03 -0800
committerGitHub2016-12-02 12:51:03 -0800
commitd3ec37edd39799e8cf039e5caed915c00dff7eeb (patch)
tree03329ddc11ca15b9d6c7f832354a9cba20c87843 /chiselFrontend/src
parent1b53d893816d349f5ea18fa0ed13325b9f1b6917 (diff)
parenteba224e524b249207b47a3b378458c61c9b66e2c (diff)
Merge branch 'master' into exceptionfix
Diffstat (limited to 'chiselFrontend/src')
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala16
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Binding.scala7
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Bits.scala174
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala18
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Data.scala2
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Mem.scala2
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/Module.scala37
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala6
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/When.scala4
-rw-r--r--chiselFrontend/src/main/scala/chisel3/core/package.scala110
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/Builder.scala14
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala16
-rw-r--r--chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala58
13 files changed, 287 insertions, 177 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
index 68fe0bb5..26c971b3 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
@@ -123,10 +123,10 @@ object Vec {
/** Truncate an index to implement modulo-power-of-2 addressing. */
private[core] def truncateIndex(idx: UInt, n: Int)(implicit sourceInfo: SourceInfo): UInt = {
val w = BigInt(n-1).bitLength
- if (n <= 1) UInt(0)
+ if (n <= 1) 0.U
else if (idx.width.known && idx.width.get <= w) idx
else if (idx.width.known) idx(w-1,0)
- else (idx | UInt(0, w))(w-1,0)
+ else (idx | 0.U(w.W))(w-1,0)
}
}
@@ -225,7 +225,7 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
private[chisel3] lazy val flatten: IndexedSeq[Bits] =
(0 until length).flatMap(i => this.apply(i).flatten)
- for ((elt, i) <- self zipWithIndex)
+ for ((elt, i) <- self.zipWithIndex)
elt.setRef(this, i)
/** Default "pretty-print" implementation
@@ -249,7 +249,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId {
// IndexedSeq has its own hashCode/equals that we must not use
override def hashCode: Int = super[HasId].hashCode
override def equals(that: Any): Boolean = super[HasId].equals(that)
-
+
@deprecated("Use Vec.apply instead", "chisel3")
def read(idx: UInt): T
@@ -261,14 +261,14 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId {
def forall(p: T => Bool): Bool = macro SourceInfoTransform.pArg
def do_forall(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool =
- (this map p).fold(Bool(true))(_ && _)
+ (this map p).fold(true.B)(_ && _)
/** Outputs true if p outputs true for at least one element.
*/
def exists(p: T => Bool): Bool = macro SourceInfoTransform.pArg
def do_exists(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool =
- (this map p).fold(Bool(false))(_ || _)
+ (this map p).fold(false.B)(_ || _)
/** Outputs true if the vector contains at least one element equal to x (using
* the === operator).
@@ -288,7 +288,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId {
/** Helper function that appends an index (literal value) to each element,
* useful for hardware generators which output an index.
*/
- private def indexWhereHelper(p: T => Bool) = this map p zip (0 until length).map(i => UInt(i))
+ private def indexWhereHelper(p: T => Bool) = this map p zip (0 until length).map(i => i.asUInt)
/** Outputs the index of the first element for which p outputs true.
*/
@@ -388,7 +388,7 @@ class Bundle extends Aggregate {
private[chisel3] lazy val flatten = namedElts.flatMap(_._2.flatten)
private[chisel3] override def _onModuleClose: Unit = // scalastyle:ignore method.name
for ((name, elt) <- namedElts) { elt.setRef(this, _namespace.name(name)) }
-
+
private[chisel3] final def allElements: Seq[Element] = namedElts.flatMap(_._2.allElements)
override def cloneType : this.type = {
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala
index 467cb4eb..3dfde7c2 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala
@@ -140,10 +140,9 @@ object Binding {
}
}
- /** Diagnose a binding error caused by a missing IO() wrapper.
- * @param element the element triggering the binding error.
- * @return true if the element is a member of the module's io but ioDefined is false.
- */
+ // Diagnose a binding error caused by a missing IO() wrapper.
+ // element is the element triggering the binding error.
+ // Returns true if the element is a member of the module's io but ioDefined is false.
def isMissingIOWrapper(element: Element): Boolean = {
element._parent match {
case None => false
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
index 4a09c70e..035ac213 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala
@@ -54,8 +54,6 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
// Arguments for: self-checking code (can't do arithmetic on bits)
// Arguments against: generates down to a FIRRTL UInt anyways
- private[chisel3] def fromInt(x: BigInt, w: Int): this.type
-
private[chisel3] def flatten: IndexedSeq[Bits] = IndexedSeq(this)
def cloneType: this.type = cloneTypeWidth(width)
@@ -92,7 +90,7 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
Builder.error(s"Negative bit indices are illegal (got $x)")
}
if (isLit()) {
- Bool(((litValue() >> x.toInt) & 1) == 1)
+ (((litValue() >> x.toInt) & 1) == 1).asBool
} else {
Binding.checkSynthesizable(this, s"'this' ($this)")
pushOp(DefPrim(sourceInfo, Bool(), BitsExtractOp, this.ref, ILit(x), ILit(x)))
@@ -134,7 +132,7 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
}
val w = x - y + 1
if (isLit()) {
- UInt((litValue >> y) & ((BigInt(1) << w) - 1), w)
+ ((litValue >> y) & ((BigInt(1) << w) - 1)).asUInt(w.W)
} else {
Binding.checkSynthesizable(this, s"'this' ($this)")
pushOp(DefPrim(sourceInfo, UInt(Width(w)), BitsExtractOp, this.ref, ILit(x), ILit(y)))
@@ -304,11 +302,6 @@ sealed abstract class Bits(width: Width, override val litArg: Option[LitArg])
final def toPrintable: Printable = Decimal(this)
}
-/** Provides a set of operations to create UInt types and literals.
- * Identical in functionality to the UInt companion object.
- */
-object Bits extends UIntFactory
-
// REVIEW TODO: Further discussion needed on what Num actually is.
/** Abstract trait defining operations available on numeric-like wire data
* types.
@@ -407,15 +400,12 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
new UInt(w).asInstanceOf[this.type]
private[chisel3] def toType = s"UInt$width"
- override private[chisel3] def fromInt(value: BigInt, width: Int): this.type =
- UInt(value, width).asInstanceOf[this.type]
-
// TODO: refactor to share documentation with Num or add independent scaladoc
final def unary_- (): UInt = macro SourceInfoTransform.noArg
final def unary_-% (): UInt = macro SourceInfoTransform.noArg
- def do_unary_- (implicit sourceInfo: SourceInfo) : UInt = UInt(0) - this
- def do_unary_-% (implicit sourceInfo: SourceInfo): UInt = UInt(0) -% this
+ def do_unary_- (implicit sourceInfo: SourceInfo) : UInt = 0.U - this
+ def do_unary_-% (implicit sourceInfo: SourceInfo): UInt = 0.U -% this
override def do_+ (that: UInt)(implicit sourceInfo: SourceInfo): UInt = this +% that
override def do_- (that: UInt)(implicit sourceInfo: SourceInfo): UInt = this -% that
@@ -463,8 +453,8 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
final def andR(): Bool = macro SourceInfoTransform.noArg
final def xorR(): Bool = macro SourceInfoTransform.noArg
- def do_orR(implicit sourceInfo: SourceInfo): Bool = this != UInt(0)
- def do_andR(implicit sourceInfo: SourceInfo): Bool = ~this === UInt(0)
+ def do_orR(implicit sourceInfo: SourceInfo): Bool = this != 0.U
+ def do_andR(implicit sourceInfo: SourceInfo): Bool = ~this === 0.U
def do_xorR(implicit sourceInfo: SourceInfo): Bool = redop(sourceInfo, XorReduceOp)
override def do_< (that: UInt)(implicit sourceInfo: SourceInfo): Bool = compop(sourceInfo, LessOp, that)
@@ -483,7 +473,7 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
final def unary_! () : Bool = macro SourceInfoTransform.noArg
- def do_unary_! (implicit sourceInfo: SourceInfo) : Bool = this === UInt(0, 1)
+ def do_unary_! (implicit sourceInfo: SourceInfo) : Bool = this === 0.U(1.W)
override def do_<< (that: Int)(implicit sourceInfo: SourceInfo): UInt =
binop(sourceInfo, UInt(this.width + that), ShiftLeftOp, that)
@@ -501,7 +491,7 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
final def bitSet(off: UInt, dat: Bool): UInt = macro UIntTransform.bitset
def do_bitSet(off: UInt, dat: Bool)(implicit sourceInfo: SourceInfo): UInt = {
- val bit = UInt(1, 1) << off
+ val bit = 1.U(1.W) << off
Mux(dat, this | bit, ~(~this | bit))
}
@@ -532,31 +522,14 @@ sealed class UInt private[core] (width: Width, lit: Option[ULit] = None)
}
// This is currently a factory because both Bits and UInt inherit it.
-private[core] sealed trait UIntFactory {
+trait UIntFactory {
/** Create a UInt type with inferred width. */
def apply(): UInt = apply(Width())
/** Create a UInt port with specified width. */
def apply(width: Width): UInt = new UInt(width)
- /** Create a UInt with a specified width - compatibility with Chisel2. */
- def width(width: Int): UInt = apply(Width(width))
- /** Create a UInt port with specified width. */
- def width(width: Width): UInt = new UInt(width)
- /** Create a UInt literal with fixed width. */
- def apply(value: BigInt, width: Int): UInt = Lit(value, Width(width))
- /** Create a UInt literal with inferred width. */
- def apply(n: String): UInt = Lit(n)
- /** Create a UInt literal with fixed width. */
- def apply(n: String, width: Int): UInt = Lit(parse(n), width)
- /** Create a UInt literal with specified width. */
- def apply(value: BigInt, width: Width): UInt = Lit(value, width)
- def Lit(value: BigInt, width: Int): UInt = Lit(value, Width(width))
- /** Create a UInt literal with inferred width. */
- def Lit(value: BigInt): UInt = Lit(value, Width())
- def Lit(n: String): UInt = Lit(parse(n), parsedWidth(n))
- /** Create a UInt literal with fixed width. */
- def Lit(n: String, width: Int): UInt = Lit(parse(n), width)
+
/** Create a UInt literal with specified width. */
- def Lit(value: BigInt, width: Width): UInt = {
+ protected[chisel3] def Lit(value: BigInt, width: Width): UInt = {
val lit = ULit(value, width)
val result = new UInt(lit.width, Some(lit))
// Bind result to being an Literal
@@ -564,63 +537,31 @@ private[core] sealed trait UIntFactory {
result
}
- /** Create a UInt with a specified width - compatibility with Chisel2. */
- // NOTE: This resolves UInt(width = 32)
- def apply(dir: Option[Direction] = None, width: Int): UInt = apply(Width(width))
- /** Create a UInt literal with inferred width.- compatibility with Chisel2. */
- def apply(value: BigInt): UInt = apply(value, Width())
- /** Create a UInt with a specified direction and width - compatibility with Chisel2. */
- def apply(dir: Direction, width: Int): UInt = apply(dir, Width(width))
- /** Create a UInt with a specified direction, but unspecified width - compatibility with Chisel2. */
- def apply(dir: Direction): UInt = apply(dir, Width())
- def apply(dir: Direction, wWidth: Width): UInt = {
- val result = apply(wWidth)
- dir match {
- case Direction.Input => Input(result)
- case Direction.Output => Output(result)
- case Direction.Unspecified => result
- }
+ /** Create a UInt with the specified range */
+ def apply(range: Range): UInt = {
+ apply(range.getWidth)
}
-
- private def parse(n: String) = {
- val (base, num) = n.splitAt(1)
- val radix = base match {
- case "x" | "h" => 16
- case "d" => 10
- case "o" => 8
- case "b" => 2
- case _ => Builder.error(s"Invalid base $base"); 2
- }
- BigInt(num.filterNot(_ == '_'), radix)
+ /** Create a UInt with the specified range */
+ def apply(range: (NumericBound[Int], NumericBound[Int])): UInt = {
+ apply(KnownUIntRange(range._1, range._2))
}
-
- private def parsedWidth(n: String) =
- if (n(0) == 'b') {
- Width(n.length-1)
- } else if (n(0) == 'h') {
- Width((n.length-1) * 4)
- } else {
- Width()
- }
}
object UInt extends UIntFactory
+object Bits extends UIntFactory
-sealed class SInt private (width: Width, lit: Option[SLit] = None)
+sealed class SInt private[core] (width: Width, lit: Option[SLit] = None)
extends Bits(width, lit) with Num[SInt] {
private[core] override def cloneTypeWidth(w: Width): this.type =
new SInt(w).asInstanceOf[this.type]
private[chisel3] def toType = s"SInt$width"
- override private[chisel3] def fromInt(value: BigInt, width: Int): this.type =
- SInt(value, width).asInstanceOf[this.type]
-
final def unary_- (): SInt = macro SourceInfoTransform.noArg
final def unary_-% (): SInt = macro SourceInfoTransform.noArg
- def unary_- (implicit sourceInfo: SourceInfo): SInt = SInt(0) - this
- def unary_-% (implicit sourceInfo: SourceInfo): SInt = SInt(0) -% this
+ def unary_- (implicit sourceInfo: SourceInfo): SInt = 0.S - this
+ def unary_-% (implicit sourceInfo: SourceInfo): SInt = 0.S -% this
/** add (default - no growth) operator */
override def do_+ (that: SInt)(implicit sourceInfo: SourceInfo): SInt =
@@ -688,7 +629,7 @@ sealed class SInt private (width: Width, lit: Option[SLit] = None)
final def abs(): UInt = macro SourceInfoTransform.noArg
- def do_abs(implicit sourceInfo: SourceInfo): UInt = Mux(this < SInt(0), (-this).asUInt, this.asUInt)
+ def do_abs(implicit sourceInfo: SourceInfo): UInt = Mux(this < 0.S, (-this).asUInt, this.asUInt)
override def do_<< (that: Int)(implicit sourceInfo: SourceInfo): SInt =
binop(sourceInfo, SInt(this.width + that), ShiftLeftOp, that)
@@ -710,66 +651,43 @@ sealed class SInt private (width: Width, lit: Option[SLit] = None)
}
}
-object SInt {
+trait SIntFactory {
/** Create an SInt type with inferred width. */
def apply(): SInt = apply(Width())
/** Create a SInt type or port with fixed width. */
def apply(width: Width): SInt = new SInt(width)
- /** Create a SInt type or port with fixed width. */
- def width(width: Int): SInt = apply(Width(width))
- /** Create an SInt type with specified width. */
- def width(width: Width): SInt = new SInt(width)
-
- /** Create an SInt literal with inferred width. */
- def apply(value: BigInt): SInt = Lit(value)
- /** Create an SInt literal with fixed width. */
- def apply(value: BigInt, width: Int): SInt = Lit(value, width)
- /** Create an SInt literal with specified width. */
- def apply(value: BigInt, width: Width): SInt = Lit(value, width)
+ /** Create a SInt with the specified range */
+ def apply(range: Range): SInt = {
+ apply(range.getWidth)
+ }
+ /** Create a SInt with the specified range */
+ def apply(range: (NumericBound[Int], NumericBound[Int])): SInt = {
+ apply(KnownSIntRange(range._1, range._2))
+ }
- def Lit(value: BigInt): SInt = Lit(value, Width())
- def Lit(value: BigInt, width: Int): SInt = Lit(value, Width(width))
/** Create an SInt literal with specified width. */
- def Lit(value: BigInt, width: Width): SInt = {
-
+ protected[chisel3] def Lit(value: BigInt, width: Width): SInt = {
val lit = SLit(value, width)
val result = new SInt(lit.width, Some(lit))
// Bind result to being an Literal
result.binding = LitBinding()
result
}
- /** Create a SInt with a specified width - compatibility with Chisel2. */
- def apply(dir: Option[Direction] = None, width: Int): SInt = apply(Width(width))
- /** Create a SInt with a specified direction and width - compatibility with Chisel2. */
- def apply(dir: Direction, width: Int): SInt = apply(dir, Width(width))
- /** Create a SInt with a specified direction, but unspecified width - compatibility with Chisel2. */
- def apply(dir: Direction): SInt = apply(dir, Width())
- def apply(dir: Direction, wWidth: Width): SInt = {
- val result = apply(wWidth)
- dir match {
- case Direction.Input => Input(result)
- case Direction.Output => Output(result)
- case Direction.Unspecified => result
- }
- }
}
+object SInt extends SIntFactory
+
// REVIEW TODO: Why does this extend UInt and not Bits? Does defining airth
// operations on a Bool make sense?
/** A data type for booleans, defined as a single bit indicating true or false.
*/
-sealed class Bool(lit: Option[ULit] = None) extends UInt(Width(1), lit) {
+sealed class Bool(lit: Option[ULit] = None) extends UInt(1.W, lit) {
private[core] override def cloneTypeWidth(w: Width): this.type = {
require(!w.known || w.get == 1)
new Bool().asInstanceOf[this.type]
}
- override private[chisel3] def fromInt(value: BigInt, width: Int): this.type = {
- require((value == 0 || value == 1) && width == 1)
- Bool(value == 1).asInstanceOf[this.type]
- }
-
// REVIEW TODO: Why does this need to exist and have different conventions
// than Bits?
final def & (that: Bool): Bool = macro SourceInfoTransform.thatArg
@@ -805,31 +723,23 @@ sealed class Bool(lit: Option[ULit] = None) extends UInt(Width(1), lit) {
def do_asClock(implicit sourceInfo: SourceInfo): Clock = pushOp(DefPrim(sourceInfo, Clock(), AsClockOp, ref))
}
-object Bool {
+trait BoolFactory {
/** Creates an empty Bool.
*/
def apply(): Bool = new Bool()
/** Creates Bool literal.
*/
- def apply(x: Boolean): Bool = Lit(x)
- def Lit(x: Boolean): Bool = {
+ protected[chisel3] def Lit(x: Boolean): Bool = {
val result = new Bool(Some(ULit(if (x) 1 else 0, Width(1))))
// Bind result to being an Literal
result.binding = LitBinding()
result
}
- /** Create a UInt with a specified direction and width - compatibility with Chisel2. */
- def apply(dir: Direction): Bool = {
- val result = apply()
- dir match {
- case Direction.Input => Input(result)
- case Direction.Output => Output(result)
- case Direction.Unspecified => result
- }
- }
}
+object Bool extends BoolFactory
+
object Mux {
/** Creates a mux, whose output is one of the inputs depending on the
* value of the condition.
@@ -839,7 +749,7 @@ object Mux {
* @param alt the value chosen when `cond` is false
* @example
* {{{
- * val muxOut = Mux(data_in === UInt(3), UInt(3, 4), UInt(0, 4))
+ * val muxOut = Mux(data_in === 3.U, 3.U(4.W), 0.U(4.W))
* }}}
*/
def apply[T <: Data](cond: Bool, con: T, alt: T): T = macro MuxTransform.apply[T]
@@ -900,10 +810,6 @@ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit
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
diff --git a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala b/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
index 7fe429fa..85a57111 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/BlackBox.scala
@@ -3,11 +3,20 @@
package chisel3.core
import chisel3.internal.Builder.pushCommand
-import chisel3.internal.firrtl.{ModuleIO, DefInvalid}
+import chisel3.internal.firrtl._
+import chisel3.internal.throwException
import chisel3.internal.sourceinfo.SourceInfo
// TODO: remove this once we have CompileOptions threaded through the macro system.
import chisel3.core.ExplicitCompileOptions.NotStrict
+/** Parameters for BlackBoxes */
+sealed abstract class Param
+case class IntParam(value: BigInt) extends Param
+case class DoubleParam(value: Double) extends Param
+case class StringParam(value: String) extends Param
+/** Unquoted String */
+case class RawParam(value: String) extends Param
+
/** Defines a black box, which is a module that can be referenced from within
* Chisel, but is not defined in the emitted Verilog. Useful for connecting
* to RTL modules defined outside Chisel.
@@ -16,12 +25,9 @@ import chisel3.core.ExplicitCompileOptions.NotStrict
* {{{
* ... to be written once a spec is finalized ...
* }}}
+ * @note The parameters API is experimental and may change
*/
-// REVIEW TODO: make Verilog parameters part of the constructor interface?
-abstract class BlackBox extends Module {
- // Don't bother taking override_clock|reset, clock/reset locked out anyway
- // TODO: actually implement this.
- def setVerilogParameters(s: String): Unit = {}
+abstract class BlackBox(val params: Map[String, Param] = Map.empty[String, Param]) extends Module {
// The body of a BlackBox is empty, the real logic happens in firrtl/Emitter.scala
// Bypass standard clock, reset, io port declaration by flattening io
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
index 2f18e726..57ed0c59 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala
@@ -258,7 +258,7 @@ abstract class Data extends HasId {
*
* This performs the inverse operation of fromBits(Bits).
*/
- @deprecated("Best alternative, .toUInt() or if Bits really needed, .toUInt().toBits()", "chisel3")
+ @deprecated("Best alternative, .asUInt()", "chisel3")
def toBits(): UInt = SeqUtils.do_asUInt(this.flatten)(DeprecatedSourceInfo)
/** Reinterpret cast to UInt.
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
index a43b19fe..1863e921 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala
@@ -40,7 +40,7 @@ sealed abstract class MemBase[T <: Data](t: T, val length: Int) extends HasId wi
*/
def apply(idx: Int): T = {
require(idx >= 0 && idx < length)
- apply(UInt(idx))
+ apply(idx.asUInt)
}
/** Creates a read/write accessor into the memory with dynamic addressing.
diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
index c3353d85..bd406529 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala
@@ -25,12 +25,32 @@ object Module {
// module de-duplication in FIRRTL emission.
val childSourceInfo = UnlocatableSourceInfo
+ if (Builder.readyForModuleConstr) {
+ throwException("Error: Called Module() twice without instantiating a Module." +
+ sourceInfo.makeMessage(" See " + _))
+ }
+ Builder.readyForModuleConstr = true
val parent: Option[Module] = Builder.currentModule
- val m = bc.setRefs() // This will set currentModule!
+
+ val m = bc.setRefs() // This will set currentModule and unset readyForModuleConstr!!!
m._commands.prepend(DefInvalid(childSourceInfo, m.io.ref)) // init module outputs
+
+ if (Builder.readyForModuleConstr) {
+ throwException("Error: attempted to instantiate a Module, but nothing happened. " +
+ "This is probably due to rewrapping a Module instance with Module()." +
+ sourceInfo.makeMessage(" See " + _))
+ }
Builder.currentModule = parent // Back to parent!
+
val ports = m.computePorts
- val component = Component(m, m.name, ports, m._commands)
+ // Blackbox inherits from Module so we have to match on it first TODO fix
+ val component = m match {
+ case bb: BlackBox =>
+ DefBlackBox(bb, bb.name, ports, bb.params)
+ case mod: Module =>
+ mod._commands.prepend(DefInvalid(childSourceInfo, mod.io.ref)) // init module outputs
+ DefModule(mod, mod.name, ports, mod._commands)
+ }
m._component = Some(component)
Builder.components += component
// Avoid referencing 'parent' in top module
@@ -93,6 +113,10 @@ extends HasId {
private[chisel3] val _commands = ArrayBuffer[Command]()
private[core] val _ids = ArrayBuffer[HasId]()
Builder.currentModule = Some(this)
+ if (!Builder.readyForModuleConstr) {
+ throwException("Error: attempted to instantiate a Module without wrapping it in Module().")
+ }
+ readyForModuleConstr = false
/** Desired name of this module. */
def desiredName = this.getClass.getName.split('.').last
@@ -100,18 +124,9 @@ extends HasId {
/** Legalized name of this module. */
final val name = Builder.globalNamespace.name(desiredName)
- /** FIRRTL Module name */
- private var _modName: Option[String] = None
- private[chisel3] def setModName(name: String) = _modName = Some(name)
- def modName = _modName match {
- case Some(name) => name
- case None => throwException("modName should be called after circuit elaboration")
- }
-
/** Keep component for signal names */
private[chisel3] var _component: Option[Component] = None
-
/** Signal name (for simulation). */
override def instanceName =
if (_parent == None) name else _component match {
diff --git a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala b/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala
index 558dea7a..e435860e 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/SeqUtils.scala
@@ -25,12 +25,12 @@ private[chisel3] object SeqUtils {
}
}
- /** Outputs the number of elements that === Bool(true).
+ /** Outputs the number of elements that === true.B.
*/
def count(in: Seq[Bool]): UInt = macro SourceInfoTransform.inArg
def do_count(in: Seq[Bool])(implicit sourceInfo: SourceInfo): UInt = in.size match {
- case 0 => UInt(0)
+ case 0 => 0.U
case 1 => in.head
case n => count(in take n/2) +& count(in drop n/2)
}
@@ -57,7 +57,7 @@ private[chisel3] object SeqUtils {
if (in.tail.isEmpty) {
in.head._2
} else {
- val masked = for ((s, i) <- in) yield Mux(s, i.asUInt, UInt(0))
+ val masked = for ((s, i) <- in) yield Mux(s, i.asUInt, 0.U)
val width = in.map(_._2.width).reduce(_ max _)
in.head._2.cloneTypeWidth(width).fromBits(masked.reduceLeft(_|_))
}
diff --git a/chiselFrontend/src/main/scala/chisel3/core/When.scala b/chiselFrontend/src/main/scala/chisel3/core/When.scala
index 196e7903..7501ebb1 100644
--- a/chiselFrontend/src/main/scala/chisel3/core/When.scala
+++ b/chiselFrontend/src/main/scala/chisel3/core/When.scala
@@ -18,9 +18,9 @@ object when { // scalastyle:ignore object.name
*
* @example
* {{{
- * when ( myData === UInt(3) ) {
+ * when ( myData === 3.U ) {
* // Some logic to run when myData equals 3.
- * } .elsewhen ( myData === UInt(1) ) {
+ * } .elsewhen ( myData === 1.U ) {
* // Some logic to run when myData equals 1.
* } .otherwise {
* // Some logic to run when myData is neither 3 nor 1.
diff --git a/chiselFrontend/src/main/scala/chisel3/core/package.scala b/chiselFrontend/src/main/scala/chisel3/core/package.scala
new file mode 100644
index 00000000..1d5817ae
--- /dev/null
+++ b/chiselFrontend/src/main/scala/chisel3/core/package.scala
@@ -0,0 +1,110 @@
+package chisel3 {
+ import internal.Builder
+
+ package object core {
+ import internal.firrtl.Width
+
+ /**
+ * These implicit classes allow one to convert scala.Int|scala.BigInt to
+ * Chisel.UInt|Chisel.SInt by calling .asUInt|.asSInt on them, respectively.
+ * The versions .asUInt(width)|.asSInt(width) are also available to explicitly
+ * mark a width for the new literal.
+ *
+ * Also provides .asBool to scala.Boolean and .asUInt to String
+ *
+ * Note that, for stylistic reasons, one should avoid extracting immediately
+ * after this call using apply, ie. 0.asUInt(1)(0) due to potential for
+ * confusion (the 1 is a bit length and the 0 is a bit extraction position).
+ * Prefer storing the result and then extracting from it.
+ *
+ * Implementation note: the empty parameter list (like `U()`) is necessary to prevent
+ * interpreting calls that have a non-Width parameter as a chained apply, otherwise things like
+ * `0.asUInt(16)` (instead of `16.W`) compile without error and produce undesired results.
+ */
+ implicit class fromBigIntToLiteral(val bigint: BigInt) {
+ /** Int to UInt conversion, recommended style for constants.
+ */
+ def U(): UInt = UInt.Lit(bigint, Width()) // scalastyle:ignore method.name
+ /** Int to SInt conversion, recommended style for constants.
+ */
+ def S(): SInt = SInt.Lit(bigint, Width()) // scalastyle:ignore method.name
+ /** Int to UInt conversion with specified width, recommended style for constants.
+ */
+ def U(width: Width): UInt = UInt.Lit(bigint, width) // scalastyle:ignore method.name
+ /** Int to SInt conversion with specified width, recommended style for constants.
+ */
+ def S(width: Width): SInt = SInt.Lit(bigint, width) // scalastyle:ignore method.name
+
+ /** Int to UInt conversion, recommended style for variables.
+ */
+ def asUInt(): UInt = UInt.Lit(bigint, Width())
+ /** Int to SInt conversion, recommended style for variables.
+ */
+ def asSInt(): SInt = SInt.Lit(bigint, Width())
+ /** Int to UInt conversion with specified width, recommended style for variables.
+ */
+ def asUInt(width: Width): UInt = UInt.Lit(bigint, width)
+ /** Int to SInt conversion with specified width, recommended style for variables.
+ */
+ def asSInt(width: Width): SInt = SInt.Lit(bigint, width)
+ }
+
+ implicit class fromIntToLiteral(val int: Int) extends fromBigIntToLiteral(int)
+ implicit class fromLongToLiteral(val long: Long) extends fromBigIntToLiteral(long)
+
+ implicit class fromStringToLiteral(val str: String) {
+ /** String to UInt parse, recommended style for constants.
+ */
+ def U(): UInt = UInt.Lit(parse(str), parsedWidth(str)) // scalastyle:ignore method.name
+ /** String to UInt parse with specified width, recommended style for constants.
+ */
+ def U(width: Width): UInt = UInt.Lit(parse(str), width) // scalastyle:ignore method.name
+
+ /** String to UInt parse, recommended style for variables.
+ */
+ def asUInt(): UInt = UInt.Lit(parse(str), parsedWidth(str))
+ /** String to UInt parse with specified width, recommended style for variables.
+ */
+ def asUInt(width: Width): UInt = UInt.Lit(parse(str), width)
+
+ protected def parse(n: String) = {
+ val (base, num) = n.splitAt(1)
+ val radix = base match {
+ case "x" | "h" => 16
+ case "d" => 10
+ case "o" => 8
+ case "b" => 2
+ case _ => Builder.error(s"Invalid base $base"); 2
+ }
+ BigInt(num.filterNot(_ == '_'), radix)
+ }
+
+ protected def parsedWidth(n: String) =
+ if (n(0) == 'b') {
+ Width(n.length-1)
+ } else if (n(0) == 'h') {
+ Width((n.length-1) * 4)
+ } else {
+ Width()
+ }
+ }
+
+ implicit class fromBooleanToLiteral(val boolean: Boolean) {
+ /** Boolean to Bool conversion, recommended style for constants.
+ */
+ def B(): Bool = Bool.Lit(boolean) // scalastyle:ignore method.name
+
+ /** Boolean to Bool conversion, recommended style for variables.
+ */
+ def asBool(): Bool = Bool.Lit(boolean)
+ }
+
+ implicit class fromDoubleToLiteral(val double: Double) {
+ def F(binaryPoint: Int): FixedPoint = FixedPoint.fromDouble(double, binaryPoint = binaryPoint)
+ }
+
+ implicit class fromIntToWidth(val int: Int) {
+ def W: Width = Width(int) // scalastyle:ignore method.name
+ }
+ }
+}
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala
index 381626c5..828f1583 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala
@@ -124,7 +124,7 @@ private[chisel3] trait HasId extends InstanceId {
case None => throwException(s"$instanceName doesn't have a parent")
}
def parentModName = _parent match {
- case Some(p) => p.modName
+ case Some(p) => p.name
case None => throwException(s"$instanceName doesn't have a parent")
}
@@ -146,6 +146,9 @@ private[chisel3] class DynamicContext() {
val globalNamespace = new Namespace(None, Set())
val components = ArrayBuffer[Component]()
var currentModule: Option[Module] = None
+ // Set by object Module.apply before calling class Module constructor
+ // Used to distinguish between no Module() wrapping, multiple wrappings, and rewrapping
+ var readyForModuleConstr: Boolean = false
val errors = new ErrorLog
}
@@ -170,11 +173,18 @@ private[chisel3] object Builder {
// A bare api call is, e.g. calling Wire() from the scala console).
)
}
+ def readyForModuleConstr: Boolean = dynamicContext.readyForModuleConstr
+ def readyForModuleConstr_=(target: Boolean): Unit = {
+ dynamicContext.readyForModuleConstr = target
+ }
// TODO(twigg): Ideally, binding checks and new bindings would all occur here
// However, rest of frontend can't support this yet.
def pushCommand[T <: Command](c: T): T = {
- forcedModule._commands += c
+ forcedModule match {
+ case _: BlackBox => throwException("Cannot add hardware to a BlackBox")
+ case m => m._commands += c
+ }
c
}
def pushOp[T <: Data](cmd: DefPrim[T]): T = {
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala
index 5e3bf33e..f1130db4 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala
@@ -19,9 +19,17 @@ import scala.reflect.macros.blackbox.Context
/** Abstract base class for generalized source information.
*/
-sealed trait SourceInfo
+sealed trait SourceInfo {
+ /** A prettier toString
+ *
+ * Make a useful message if SourceInfo is available, nothing otherwise
+ */
+ def makeMessage(f: String => String): String
+}
-sealed trait NoSourceInfo extends SourceInfo
+sealed trait NoSourceInfo extends SourceInfo {
+ def makeMessage(f: String => String): String = ""
+}
/** For when source info can't be generated because of a technical limitation, like for Reg because
* Scala macros don't support named or default arguments.
@@ -34,7 +42,9 @@ case object DeprecatedSourceInfo extends NoSourceInfo
/** For FIRRTL lines from a Scala source line.
*/
-case class SourceLine(filename: String, line: Int, col: Int) extends SourceInfo
+case class SourceLine(filename: String, line: Int, col: Int) extends SourceInfo {
+ def makeMessage(f: String => String): String = f(s"@[$filename $line:$col]")
+}
/** Provides a macro that returns the source information at the invocation point.
*/
diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
index 0f866c27..699cc13c 100644
--- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
+++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala
@@ -64,7 +64,7 @@ abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg {
protected def minWidth: Int
if (forcedWidth) {
require(widthArg.get >= minWidth,
- s"The literal value ${num} was elaborated with a specificed width of ${widthArg.get} bits, but at least ${minWidth} bits are required.")
+ s"The literal value ${num} was elaborated with a specified width of ${widthArg.get} bits, but at least ${minWidth} bits are required.")
}
}
@@ -109,6 +109,54 @@ case class Index(imm: Arg, value: Arg) extends Arg {
override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[${value.fullName(ctx)}]"
}
+sealed trait Bound
+sealed trait NumericBound[T] extends Bound {
+ val value: T
+}
+sealed case class Open[T](value: T) extends NumericBound[T]
+sealed case class Closed[T](value: T) extends NumericBound[T]
+
+sealed trait Range {
+ val min: Bound
+ val max: Bound
+ def getWidth: Width
+}
+
+sealed trait KnownIntRange extends Range {
+ val min: NumericBound[Int]
+ val max: NumericBound[Int]
+
+ require( (min, max) match {
+ case (Open(low_val), Open(high_val)) => low_val < high_val - 1
+ case (Closed(low_val), Open(high_val)) => low_val < high_val
+ case (Open(low_val), Closed(high_val)) => low_val < high_val
+ case (Closed(low_val), Closed(high_val)) => low_val <= high_val
+ })
+}
+
+sealed case class KnownUIntRange(min: NumericBound[Int], max: NumericBound[Int]) extends KnownIntRange {
+ require (min.value >= 0)
+
+ def getWidth: Width = max match {
+ case Open(v) => Width(BigInt(v - 1).bitLength.max(1))
+ case Closed(v) => Width(BigInt(v).bitLength.max(1))
+ }
+}
+
+sealed case class KnownSIntRange(min: NumericBound[Int], max: NumericBound[Int]) extends KnownIntRange {
+
+ val maxWidth = max match {
+ case Open(v) => Width(BigInt(v - 1).bitLength + 1)
+ case Closed(v) => Width(BigInt(v).bitLength + 1)
+ }
+ val minWidth = min match {
+ case Open(v) => Width(BigInt(v + 1).bitLength + 1)
+ case Closed(v) => Width(BigInt(v).bitLength + 1)
+ }
+ def getWidth: Width = maxWidth.max(minWidth)
+
+}
+
object Width {
def apply(x: Int): Width = KnownWidth(x)
def apply(): Width = UnknownWidth()
@@ -215,8 +263,14 @@ case class Connect(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command
case class BulkConnect(sourceInfo: SourceInfo, loc1: Node, loc2: Node) extends Command
case class ConnectInit(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command
case class Stop(sourceInfo: SourceInfo, clock: Arg, ret: Int) extends Command
-case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Arg
case class Port(id: Data, dir: Direction)
case class Printf(sourceInfo: SourceInfo, clock: Arg, pable: Printable) extends Command
+abstract class Component extends Arg {
+ def id: Module
+ def name: String
+ def ports: Seq[Port]
+}
+case class DefModule(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Component
+case class DefBlackBox(id: Module, name: String, ports: Seq[Port], params: Map[String, Param]) extends Component
case class Circuit(name: String, components: Seq[Component])