Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
ucbjrl committed May 3, 2017
2 parents 1d79f72 + 989fbd5 commit e019a65
Show file tree
Hide file tree
Showing 55 changed files with 1,484 additions and 713 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This will walk you through installing Chisel and its dependencies:
- [sbt](http://www.scala-sbt.org/), which is the preferred Scala build system
and what Chisel uses.
- [Firrtl](https://github.com/ucb-bar/firrtl), which compiles Chisel's IR down
to Verilog. Separate installation of Firrtl is no longer required.
to Verilog. If you're building from the release branch of chisel3, separate installation of Firrtl is no longer required: the required jar will be automatically downloaed by sbt. If you're building chisel3 from the master branch, you'll need to follow the directions on the [firrtl project](https://github.com/ucb-bar/firrtl) to publish a local copy of the required jar.
- [Verilator](http://www.veripool.org/wiki/verilator), which compiles Verilog
down to C++ for simulation. The included unit testing infrastructure uses
this.
Expand Down Expand Up @@ -80,7 +80,7 @@ This will walk you through installing Chisel and its dependencies:
1. Install sbt:

```
brew cask install sbt
brew install sbt
```
1. Install Verilator:

Expand Down
45 changes: 24 additions & 21 deletions chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ sealed abstract class Aggregate extends Data {
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(getElements.map(_.asUInt()))
override def do_asUInt(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
SeqUtils.do_asUInt(flatten.map(_.asUInt()))
}
private[core] override def connectFromBits(that: Bits)(implicit sourceInfo: SourceInfo,
compileOptions: CompileOptions): Unit = {
var i = 0
val bits = Wire(UInt(this.width), init=that) // handles width padding
for (x <- getElements) {
for (x <- flatten) {
x.connectFromBits(bits(i + x.getWidth - 1, i))
i += x.getWidth
}
Expand Down Expand Up @@ -132,7 +132,7 @@ object Vec {
apply(Seq.fill(n)(gen))

/** Truncate an index to implement modulo-power-of-2 addressing. */
private[core] def truncateIndex(idx: UInt, n: Int)(implicit sourceInfo: SourceInfo): UInt = {
private[core] def truncateIndex(idx: UInt, n: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt = {
val w = BigInt(n-1).bitLength
if (n <= 1) 0.U
else if (idx.width.known && idx.width.get <= w) idx
Expand Down Expand Up @@ -223,10 +223,12 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)

/** Creates a dynamically indexed read or write accessor into the array.
*/
def apply(idx: UInt): T = {
Binding.checkSynthesizable(idx ,s"'idx' ($idx)")
override def apply(p: UInt): T = macro CompileOptionsTransform.pArg

def do_apply(p: UInt)(implicit compileOptions: CompileOptions): T = {
Binding.checkSynthesizable(p ,s"'p' ($p)")
val port = gen
val i = Vec.truncateIndex(idx, length)(UnlocatableSourceInfo)
val i = Vec.truncateIndex(p, length)(UnlocatableSourceInfo, compileOptions)
port.setRef(this, i)

// Bind each element of port to being whatever the base type is
Expand All @@ -243,11 +245,11 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
def apply(idx: Int): T = self(idx)

@deprecated("Use Vec.apply instead", "chisel3")
def read(idx: UInt): T = apply(idx)
def read(idx: UInt)(implicit compileOptions: CompileOptions): T = do_apply(idx)(compileOptions)

@deprecated("Use Vec.apply instead", "chisel3")
def write(idx: UInt, data: T): Unit = {
apply(idx).:=(data)(DeprecatedSourceInfo, chisel3.core.ExplicitCompileOptions.NotStrict)
def write(idx: UInt, data: T)(implicit compileOptions: CompileOptions): Unit = {
do_apply(idx)(compileOptions).:=(data)(DeprecatedSourceInfo, compileOptions)
}

override def cloneType: this.type = {
Expand Down Expand Up @@ -277,45 +279,47 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int)
* operations.
*/
trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId {
def apply(idx: UInt): T
def apply(p: UInt): T = macro CompileOptionsTransform.pArg

def do_apply(p: UInt)(implicit compileOptions: CompileOptions): T

// 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
def read(idx: UInt)(implicit compileOptions: CompileOptions): T

@deprecated("Use Vec.apply instead", "chisel3")
def write(idx: UInt, data: T): Unit
def write(idx: UInt, data: T)(implicit compileOptions: CompileOptions): Unit

/** Outputs true if p outputs true for every element.
*/
def forall(p: T => Bool): Bool = macro SourceInfoTransform.pArg

def do_forall(p: T => Bool)(implicit sourceInfo: SourceInfo): Bool =
def do_forall(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
(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 =
def do_exists(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool =
(this map p).fold(false.B)(_ || _)

/** Outputs true if the vector contains at least one element equal to x (using
* the === operator).
*/
def contains(x: T)(implicit ev: T <:< UInt): Bool = macro VecTransform.contains

def do_contains(x: T)(implicit sourceInfo: SourceInfo, ev: T <:< UInt): Bool =
def do_contains(x: T)(implicit sourceInfo: SourceInfo, ev: T <:< UInt, compileOptions: CompileOptions): Bool =
this.exists(_ === x)

/** Outputs the number of elements for which p is true.
*/
def count(p: T => Bool): UInt = macro SourceInfoTransform.pArg

def do_count(p: T => Bool)(implicit sourceInfo: SourceInfo): UInt =
def do_count(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
SeqUtils.count(this map p)

/** Helper function that appends an index (literal value) to each element,
Expand All @@ -325,14 +329,14 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId {

/** Outputs the index of the first element for which p outputs true.
*/
def indexWhere(p: T => Bool): UInt = macro CompileOptionsTransform.pArg
def indexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg

def do_indexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
SeqUtils.priorityMux(indexWhereHelper(p))

/** Outputs the index of the last element for which p outputs true.
*/
def lastIndexWhere(p: T => Bool): UInt = macro CompileOptionsTransform.pArg
def lastIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg

def do_lastIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
SeqUtils.priorityMux(indexWhereHelper(p).reverse)
Expand All @@ -347,7 +351,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId {
* true is NOT checked (useful in cases where the condition doesn't always
* hold, but the results are not used in those cases)
*/
def onlyIndexWhere(p: T => Bool): UInt = macro CompileOptionsTransform.pArg
def onlyIndexWhere(p: T => Bool): UInt = macro SourceInfoTransform.pArg

def do_onlyIndexWhere(p: T => Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
SeqUtils.oneHotMux(indexWhereHelper(p))
Expand Down Expand Up @@ -501,7 +505,6 @@ class Bundle extends Record {
* be one, otherwise returns None.
*/
private def getBundleField(m: java.lang.reflect.Method): Option[Data] = m.invoke(this) match {
case v: Vec[_] if v.isEmpty => None
case d: Data => Some(d)
case Some(d: Data) => Some(d)
case _ => None
Expand Down
18 changes: 9 additions & 9 deletions chiselFrontend/src/main/scala/chisel3/core/Assert.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,26 @@ object assert { // scalastyle:ignore object.name
* that
*/
// Macros currently can't take default arguments, so we need two functions to emulate defaults.
def apply(cond: Bool, message: String, data: Bits*)(implicit sourceInfo: SourceInfo): Unit = macro apply_impl_msg_data
def apply(cond: Bool)(implicit sourceInfo: SourceInfo): Unit = macro apply_impl
def apply(cond: Bool, message: String, data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = macro apply_impl_msg_data
def apply(cond: Bool)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = macro apply_impl

def apply_impl_msg_data(c: Context)(cond: c.Tree, message: c.Tree, data: c.Tree*)(sourceInfo: c.Tree): c.Tree = {
def apply_impl_msg_data(c: Context)(cond: c.Tree, message: c.Tree, data: c.Tree*)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = {
import c.universe._
val p = c.enclosingPosition
val condStr = s"${p.source.file.name}:${p.line} ${p.lineContent.trim}"
val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("apply_impl_do"))
q"$apply_impl_do($cond, $condStr, _root_.scala.Some($message), ..$data)($sourceInfo)"
q"$apply_impl_do($cond, $condStr, _root_.scala.Some($message), ..$data)($sourceInfo, $compileOptions)"
}

def apply_impl(c: Context)(cond: c.Tree)(sourceInfo: c.Tree): c.Tree = {
def apply_impl(c: Context)(cond: c.Tree)(sourceInfo: c.Tree, compileOptions: c.Tree): c.Tree = {
import c.universe._
val p = c.enclosingPosition
val condStr = s"${p.source.file.name}:${p.line} ${p.lineContent.trim}"
val apply_impl_do = symbolOf[this.type].asClass.module.info.member(TermName("apply_impl_do"))
q"$apply_impl_do($cond, $condStr, _root_.scala.None)($sourceInfo)"
q"$apply_impl_do($cond, $condStr, _root_.scala.None)($sourceInfo, $compileOptions)"
}

def apply_impl_do(cond: Bool, line: String, message: Option[String], data: Bits*)(implicit sourceInfo: SourceInfo) {
def apply_impl_do(cond: Bool, line: String, message: Option[String], data: Bits*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) {
when (!(cond || Builder.forcedReset)) {
val fmt = message match {
case Some(str) => s"Assertion failed: $str\n at $line\n"
Expand All @@ -76,14 +76,14 @@ object assert { // scalastyle:ignore object.name

object stop { // scalastyle:ignore object.name
/** Terminate execution with a failure code. */
def apply(code: Int)(implicit sourceInfo: SourceInfo): Unit = {
def apply(code: Int)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = {
when (!Builder.forcedReset) {
pushCommand(Stop(sourceInfo, Node(Builder.forcedClock), code))
}
}

/** Terminate execution, indicating success. */
def apply()(implicit sourceInfo: SourceInfo): Unit = {
def apply()(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Unit = {
stop(0)
}
}
4 changes: 2 additions & 2 deletions chiselFrontend/src/main/scala/chisel3/core/Attach.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ object attach { // scalastyle:ignore object.name
AttachException(": Conditional attach is not allowed!")

// Actual implementation
private[core] def impl(elts: Seq[Analog], contextModule: Module)(implicit sourceInfo: SourceInfo): Unit = {
private[core] def impl(elts: Seq[Analog], contextModule: UserModule)(implicit sourceInfo: SourceInfo): Unit = {
if (Builder.whenDepth != 0) throw ConditionalAttachException

// TODO Check that references are valid and can be attached
Expand All @@ -35,7 +35,7 @@ object attach { // scalastyle:ignore object.name
*/
def apply(elts: Analog*)(implicit sourceInfo: SourceInfo): Unit = {
try {
impl(elts, Builder.forcedModule)
impl(elts, Builder.forcedUserModule)
} catch {
case AttachException(message) =>
throwException(elts.mkString("Attaching (", ", ", s") failed @$message"))
Expand Down
11 changes: 6 additions & 5 deletions chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ object BiConnect {
* during the recursive decent and then rethrow them with extra information added.
* This gives the user a 'path' to where in the connections things went wrong.
*/
def connect(sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Data, right: Data, context_mod: Module): Unit =
def connect(sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Data, right: Data, context_mod: UserModule): Unit =
(left, right) match {
// Handle element case (root case)
case (left_a: Analog, right_a: Analog) =>
Expand All @@ -73,6 +73,7 @@ object BiConnect {
if(left_v.length != right_v.length) { throw MismatchedVecException }
for(idx <- 0 until left_v.length) {
try {
implicit val compileOptions = connectCompileOptions
connect(sourceInfo, connectCompileOptions, left_v(idx), right_v(idx), context_mod)
} catch {
case BiConnectException(message) => throw BiConnectException(s"($idx)$message")
Expand Down Expand Up @@ -121,12 +122,12 @@ object BiConnect {

// This function checks if element-level connection operation allowed.
// Then it either issues it or throws the appropriate exception.
def elemConnect(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Element, right: Element, context_mod: Module): Unit = {
def elemConnect(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, left: Element, right: Element, context_mod: UserModule): Unit = {
import Direction.{Input, Output} // Using extensively so import these
// If left or right have no location, assume in context module
// This can occur if one of them is a literal, unbound will error previously
val left_mod: Module = left.binding.location.getOrElse(context_mod)
val right_mod: Module = right.binding.location.getOrElse(context_mod)
val left_mod: BaseModule = left.binding.location.getOrElse(context_mod)
val right_mod: BaseModule = right.binding.location.getOrElse(context_mod)

val left_direction: Option[Direction] = left.binding.direction
val right_direction: Option[Direction] = right.binding.direction
Expand Down Expand Up @@ -250,7 +251,7 @@ object BiConnect {

// This function checks if analog element-level attaching is allowed
// Then it either issues it or throws the appropriate exception.
def analogAttach(implicit sourceInfo: SourceInfo, left: Analog, right: Analog, contextModule: Module): Unit = {
def analogAttach(implicit sourceInfo: SourceInfo, left: Analog, right: Analog, contextModule: UserModule): Unit = {
// Error if left or right is BICONNECTED in the current module already
for (elt <- left :: right :: Nil) {
elt.biConnectLocs.get(contextModule) match {
Expand Down
10 changes: 5 additions & 5 deletions chiselFrontend/src/main/scala/chisel3/core/Binder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,24 @@ case object LitBinder extends Binder[LitBinding] {
def apply(in: UnboundBinding) = LitBinding()
}

case class MemoryPortBinder(enclosure: Module) extends Binder[MemoryPortBinding] {
case class MemoryPortBinder(enclosure: UserModule) extends Binder[MemoryPortBinding] {
def apply(in: UnboundBinding) = MemoryPortBinding(enclosure)
}

case class OpBinder(enclosure: Module) extends Binder[OpBinding] {
case class OpBinder(enclosure: UserModule) extends Binder[OpBinding] {
def apply(in: UnboundBinding) = OpBinding(enclosure)
}

// Notice how PortBinder uses the direction of the UnboundNode
case class PortBinder(enclosure: Module) extends Binder[PortBinding] {
case class PortBinder(enclosure: BaseModule) extends Binder[PortBinding] {
def apply(in: UnboundBinding) = PortBinding(enclosure, in.direction)
}

case class RegBinder(enclosure: Module) extends Binder[RegBinding] {
case class RegBinder(enclosure: UserModule) extends Binder[RegBinding] {
def apply(in: UnboundBinding) = RegBinding(enclosure)
}

case class WireBinder(enclosure: Module) extends Binder[WireBinding] {
case class WireBinder(enclosure: UserModule) extends Binder[WireBinding] {
def apply(in: UnboundBinding) = WireBinding(enclosure)
}

Loading

0 comments on commit e019a65

Please sign in to comment.