From 4b88a5dd45337fa88178fe17324eef3661daf1b3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 1 Sep 2016 10:21:57 -0700 Subject: Move connection implicits from Module constructor to connection methods. Eliminate builder compileOptions. --- .../src/main/scala/chisel3/core/Aggregate.scala | 23 ++++++++++++-------- .../src/main/scala/chisel3/core/BiConnect.scala | 23 ++++++++++---------- .../src/main/scala/chisel3/core/Binding.scala | 6 +++--- .../src/main/scala/chisel3/core/Bits.scala | 1 + .../src/main/scala/chisel3/core/Data.scala | 19 ++++++++-------- .../src/main/scala/chisel3/core/Mem.scala | 1 + .../src/main/scala/chisel3/core/MonoConnect.scala | 23 +++++++++++--------- .../src/main/scala/chisel3/core/Reg.scala | 14 ++++++------ .../src/main/scala/chisel3/internal/Builder.scala | 11 +++------- src/main/scala/chisel3/Driver.scala | 4 ++-- src/main/scala/chisel3/util/Counter.scala | 1 + src/main/scala/chisel3/util/LFSR.scala | 1 + src/main/scala/chisel3/util/Reg.scala | 1 + src/test/scala/chiselTests/BlackBox.scala | 1 + .../scala/chiselTests/CompileOptionsTest.scala | 25 ++++++++++++++++------ src/test/scala/chiselTests/Counter.scala | 1 + src/test/scala/chiselTests/MultiAssign.scala | 1 + src/test/scala/chiselTests/Reg.scala | 1 + src/test/scala/chiselTests/TesterDriverSpec.scala | 1 + src/test/scala/chiselTests/Vec.scala | 1 + src/test/scala/chiselTests/When.scala | 1 + 21 files changed, 95 insertions(+), 65 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 5d294ea9..c579d424 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -10,6 +10,7 @@ import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, VecTransform, SourceInfoTransform} +import chisel3.Strict.CompileOptions /** An abstract class for data types that solely consist of (are an aggregate * of) other Data objects. @@ -51,10 +52,12 @@ object Vec { val width = elts.map(_.width).reduce(_ max _) // If an element has a direction associated with it, use the bulk connect operator. val vec = Wire(new Vec(elts.head.cloneTypeWidth(width), elts.length)) - def doConnect(sink: T, source: T) = if (elts.head.flatten.exists(_.firrtlDirection != Direction.Unspecified)) { - sink bulkConnect source - } else { - sink connect source + def doConnect(sink: T, source: T) = { + if (elts.head.flatten.exists(_.firrtlDirection != Direction.Unspecified)) { + sink bulkConnect source + } else { + sink connect source + } } for ((v, e) <- vec zip elts) { doConnect(v, e) @@ -138,27 +141,27 @@ sealed class Vec[T <: Data] private (gen: T, val length: Int) * * @note the length of this Vec must match the length of the input Seq */ - def <> (that: Seq[T])(implicit sourceInfo: SourceInfo): Unit = { + def <> (that: Seq[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: ExplicitCompileOptions): Unit = { require(this.length == that.length) for ((a, b) <- this zip that) a <> b } // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data - def <> (that: Vec[T])(implicit sourceInfo: SourceInfo): Unit = this bulkConnect that.asInstanceOf[Data] + def <> (that: Vec[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: ExplicitCompileOptions): Unit = this bulkConnect that.asInstanceOf[Data] /** Strong bulk connect, assigning elements in this Vec from elements in a Seq. * * @note the length of this Vec must match the length of the input Seq */ - def := (that: Seq[T])(implicit sourceInfo: SourceInfo): Unit = { + def := (that: Seq[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: ExplicitCompileOptions): Unit = { require(this.length == that.length) for ((a, b) <- this zip that) a := b } // TODO: eliminate once assign(Seq) isn't ambiguous with assign(Data) since Vec extends Seq and Data - def := (that: Vec[T])(implicit sourceInfo: SourceInfo): Unit = this connect that + def := (that: Vec[T])(implicit sourceInfo: SourceInfo, moduleCompileOptions: ExplicitCompileOptions): Unit = this connect that /** Creates a dynamically indexed read or write accessor into the array. */ @@ -184,7 +187,9 @@ sealed class Vec[T <: Data] private (gen: T, val length: Int) def read(idx: UInt): T = apply(idx) @deprecated("Use Vec.apply instead", "chisel3") - def write(idx: UInt, data: T): Unit = apply(idx).:=(data)(DeprecatedSourceInfo) + def write(idx: UInt, data: T): Unit = { + apply(idx).:=(data)(DeprecatedSourceInfo, chisel3.Strict.CompileOptions) + } override def cloneType: this.type = { Vec(length, gen).asInstanceOf[this.type] diff --git a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala index 969e5654..b0be1c38 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/BiConnect.scala @@ -2,10 +2,11 @@ package chisel3.core -import chisel3.internal.Builder.{compileOptions, pushCommand} +import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.Connect import scala.language.experimental.macros import chisel3.internal.sourceinfo._ +import chisel3.internal.ExplicitCompileOptions /** * BiConnect.connect executes a bidirectional connection element-wise. @@ -49,11 +50,11 @@ 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, left: Data, right: Data, context_mod: Module): Unit = + def connect(sourceInfo: SourceInfo, connectCompileOptions: ExplicitCompileOptions, left: Data, right: Data, context_mod: Module): Unit = (left, right) match { // Handle element case (root case) case (left_e: Element, right_e: Element) => { - elemConnect(sourceInfo, left_e, right_e, context_mod) + elemConnect(sourceInfo, connectCompileOptions, left_e, right_e, context_mod) // TODO(twigg): Verify the element-level classes are connectable } // Handle Vec case @@ -61,7 +62,7 @@ object BiConnect { if(left_v.length != right_v.length) { throw MismatchedVecException } for(idx <- 0 until left_v.length) { try { - connect(sourceInfo, left_v(idx), right_v(idx), context_mod) + connect(sourceInfo, connectCompileOptions, left_v(idx), right_v(idx), context_mod) } catch { case BiConnectException(message) => throw BiConnectException(s"($idx)$message") } @@ -72,7 +73,7 @@ object BiConnect { // Verify right has no extra fields that left doesn't have for((field, right_sub) <- right_b.elements) { if(!left_b.elements.isDefinedAt(field)) { - if (compileOptions.connectFieldsMustMatch || context_mod.compileOptions.connectFieldsMustMatch) { + if (connectCompileOptions.connectFieldsMustMatch) { throw MissingLeftFieldException(field) } } @@ -81,9 +82,9 @@ object BiConnect { for((field, left_sub) <- left_b.elements) { try { right_b.elements.get(field) match { - case Some(right_sub) => connect(sourceInfo, left_sub, right_sub, context_mod) + case Some(right_sub) => connect(sourceInfo, connectCompileOptions, left_sub, right_sub, context_mod) case None => { - if (compileOptions.connectFieldsMustMatch || context_mod.compileOptions.connectFieldsMustMatch) { + if (connectCompileOptions.connectFieldsMustMatch) { throw MissingRightFieldException(field) } } @@ -109,7 +110,7 @@ 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, left: Element, right: Element, context_mod: Module): Unit = { + def elemConnect(implicit sourceInfo: SourceInfo, connectCompileOptions: ExplicitCompileOptions, left: Element, right: Element, context_mod: Module): 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 @@ -169,7 +170,7 @@ object BiConnect { case (None, Some(Input)) => issueConnectR2L(left, right) case (Some(Input), Some(Input)) => { - if (compileOptions.dontAssumeDirectionality || context_mod.compileOptions.dontAssumeDirectionality) { + if (connectCompileOptions.dontAssumeDirectionality) { throw BothDriversException } else { (left.binding, right.binding) match { @@ -181,7 +182,7 @@ object BiConnect { } } case (Some(Output), Some(Output)) => { - if (compileOptions.dontAssumeDirectionality || context_mod.compileOptions.dontAssumeDirectionality) { + if (connectCompileOptions.dontAssumeDirectionality) { throw BothDriversException } else { (left.binding, right.binding) match { @@ -193,7 +194,7 @@ object BiConnect { } } case (None, None) => { - if (compileOptions.dontAssumeDirectionality || context_mod.compileOptions.dontAssumeDirectionality) { + if (connectCompileOptions.dontAssumeDirectionality) { throw UnknownDriverException } else { issueConnectR2L(left, right) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala index b36794f1..5378f3ae 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Binding.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Binding.scala @@ -1,6 +1,6 @@ package chisel3.core -import chisel3.internal.Builder.{compileOptions, forcedModule} +import chisel3.internal.Builder.{forcedModule} /** * The purpose of a Binding is to indicate what type of hardware 'entity' a @@ -91,7 +91,7 @@ object Binding { element.binding = binder(unbound) } // If autoIOWrap is enabled and we're rebinding a PortBinding, just ignore the rebinding. - case portBound @ PortBinding(_, _) if (!(compileOptions.requireIOWrap || forcedModule.compileOptions.requireIOWrap)&& binder.isInstanceOf[PortBinder]) => + case portBound @ PortBinding(_, _) if (!(forcedModule.compileOptions.requireIOWrap) && binder.isInstanceOf[PortBinder]) => case binding => throw AlreadyBoundException(binding.toString) } ) @@ -145,7 +145,7 @@ object Binding { case binding => // The following kludge is an attempt to provide backward compatibility // It should be done at at higher level. - if ((compileOptions.requireIOWrap || forcedModule.compileOptions.requireIOWrap || !elementOfIO(element))) + if ((forcedModule.compileOptions.requireIOWrap || !elementOfIO(element))) throw NotSynthesizableException else Binding.bind(element, PortBinder(element._parent.get), "Error: IO") diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index c2621251..6fdec340 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -10,6 +10,7 @@ import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, SourceInfoTransform, SourceInfoWhiteboxTransform, UIntTransform, MuxTransform} import chisel3.internal.firrtl.PrimOp._ +import chisel3.Strict.CompileOptions /** Element is a leaf data type: it cannot contain other Data objects. Example * uses are for representing primitive data types, like integers and bits. diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index ce7b58b4..bda06790 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -8,6 +8,7 @@ import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, UnlocatableSourceInfo, WireTransform, SourceInfoTransform} +import chisel3.Strict.CompileOptions sealed abstract class Direction(name: String) { override def toString: String = name @@ -124,11 +125,11 @@ abstract class Data extends HasId { private[core] def badConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit = throwException(s"cannot connect ${this} and ${that}") - private[chisel3] def connect(that: Data)(implicit sourceInfo: SourceInfo): Unit = { + private[chisel3] def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: ExplicitCompileOptions): Unit = { Binding.checkSynthesizable(this, s"'this' ($this)") Binding.checkSynthesizable(that, s"'that' ($that)") try { - MonoConnect.connect(sourceInfo, this, that, Builder.forcedModule) + MonoConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.forcedModule) } catch { case MonoConnect.MonoConnectException(message) => throwException( @@ -136,11 +137,11 @@ abstract class Data extends HasId { ) } } - private[chisel3] def bulkConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit = { + private[chisel3] def bulkConnect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: ExplicitCompileOptions): Unit = { Binding.checkSynthesizable(this, s"'this' ($this)") Binding.checkSynthesizable(that, s"'that' ($that)") try { - BiConnect.connect(sourceInfo, this, that, Builder.forcedModule) + BiConnect.connect(sourceInfo, connectCompileOptions, this, that, Builder.forcedModule) } catch { case BiConnect.BiConnectException(message) => throwException( @@ -165,8 +166,8 @@ abstract class Data extends HasId { } clone } - final def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = this connect that - final def <> (that: Data)(implicit sourceInfo: SourceInfo): Unit = this bulkConnect that + final def := (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: ExplicitCompileOptions): Unit = this.connect(that)(sourceInfo, connectionCompileOptions) + final def <> (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: ExplicitCompileOptions): Unit = this.bulkConnect(that)(sourceInfo, connectionCompileOptions) def litArg(): Option[LitArg] = None def litValue(): BigInt = litArg.get.num def isLit(): Boolean = litArg.isDefined @@ -254,7 +255,7 @@ object Wire { do_apply(t, init)(UnlocatableSourceInfo) def do_apply[T <: Data](t: T, init: T)(implicit sourceInfo: SourceInfo): T = { - val x = Reg.makeType(t, null.asInstanceOf[T], init) + val x = Reg.makeType(chisel3.Strict.CompileOptions, t, null.asInstanceOf[T], init) // Bind each element of x to being a Wire Binding.bind(x, WireBinder(Builder.forcedModule), "Error: t") @@ -288,8 +289,8 @@ sealed class Clock extends Element(Width(1)) { private[core] def cloneTypeWidth(width: Width): this.type = cloneType private[chisel3] def toType = "Clock" - override def connect (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match { - case _: Clock => super.connect(that)(sourceInfo) + override def connect (that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: ExplicitCompileOptions): Unit = that match { + case _: Clock => super.connect(that)(sourceInfo, connectCompileOptions) case _ => super.badConnect(that)(sourceInfo) } } diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala index 931a0489..327e119e 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala @@ -8,6 +8,7 @@ import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, UnlocatableSourceInfo, MemTransform} +import chisel3.Strict.CompileOptions object Mem { @deprecated("Mem argument order should be size, t; this will be removed by the official release", "chisel3") diff --git a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala index 41754827..1925171b 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/MonoConnect.scala @@ -1,9 +1,12 @@ +// See LICENSE for license details. + package chisel3.core -import chisel3.internal.Builder.{compileOptions, pushCommand} +import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.Connect import scala.language.experimental.macros import chisel3.internal.sourceinfo.{DeprecatedSourceInfo, SourceInfo, SourceInfoTransform, UnlocatableSourceInfo, WireTransform} +import chisel3.internal.ExplicitCompileOptions /** * MonoConnect.connect executes a mono-directional connection element-wise. @@ -53,11 +56,11 @@ object MonoConnect { * 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, sink: Data, source: Data, context_mod: Module): Unit = + def connect(sourceInfo: SourceInfo, connectCompileOptions: ExplicitCompileOptions, sink: Data, source: Data, context_mod: Module): Unit = (sink, source) match { // Handle element case (root case) case (sink_e: Element, source_e: Element) => { - elemConnect(sourceInfo, sink_e, source_e, context_mod) + elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) // TODO(twigg): Verify the element-level classes are connectable } // Handle Vec case @@ -65,7 +68,7 @@ object MonoConnect { if(sink_v.length != source_v.length) { throw MismatchedVecException } for(idx <- 0 until sink_v.length) { try { - connect(sourceInfo, sink_v(idx), source_v(idx), context_mod) + connect(sourceInfo, connectCompileOptions, sink_v(idx), source_v(idx), context_mod) } catch { case MonoConnectException(message) => throw MonoConnectException(s"($idx)$message") } @@ -77,9 +80,9 @@ object MonoConnect { for((field, sink_sub) <- sink_b.elements) { try { source_b.elements.get(field) match { - case Some(source_sub) => connect(sourceInfo, sink_sub, source_sub, context_mod) + case Some(source_sub) => connect(sourceInfo, connectCompileOptions, sink_sub, source_sub, context_mod) case None => { - if (compileOptions.connectFieldsMustMatch || context_mod.compileOptions.connectFieldsMustMatch) { + if (connectCompileOptions.connectFieldsMustMatch) { throw MissingFieldException(field) } } @@ -100,7 +103,7 @@ object MonoConnect { // This function checks if element-level connection operation allowed. // Then it either issues it or throws the appropriate exception. - def elemConnect(implicit sourceInfo: SourceInfo, sink: Element, source: Element, context_mod: Module): Unit = { + def elemConnect(implicit sourceInfo: SourceInfo, connectCompileOptions: ExplicitCompileOptions, sink: Element, source: Element, context_mod: Module): Unit = { import Direction.{Input, Output} // Using extensively so import these // If source has no location, assume in context module // This can occur if is a literal, unbound will error previously @@ -134,13 +137,13 @@ object MonoConnect { case (Some(Output), Some(Output)) => issueConnect(sink, source) case (Some(Output), Some(Input)) => issueConnect(sink, source) case (_, None) => { - if (!(compileOptions.dontAssumeDirectionality || context_mod.compileOptions.dontAssumeDirectionality)) { + if (!(connectCompileOptions.dontAssumeDirectionality)) { issueConnect(sink, source) } else { throw UnreadableSourceException } } - case (Some(Input), Some(Output)) if (!(compileOptions.dontTryConnectionsSwapped || context_mod.compileOptions.dontTryConnectionsSwapped)) => issueConnect(source, sink) + case (Some(Input), Some(Output)) if (!(connectCompileOptions.dontTryConnectionsSwapped)) => issueConnect(source, sink) case (Some(Input), _) => throw UnwritableSinkException } } @@ -172,7 +175,7 @@ object MonoConnect { case (Some(Input), Some(Output)) => issueConnect(sink, source) case (Some(Output), _) => throw UnwritableSinkException case (_, None) => { - if (!(compileOptions.dontAssumeDirectionality || context_mod.compileOptions.dontAssumeDirectionality)) { + if (!(connectCompileOptions.dontAssumeDirectionality)) { issueConnect(sink, source) } else { throw UnreadableSourceException diff --git a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala index 36c88245..d147a81d 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala @@ -8,9 +8,9 @@ import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{SourceInfo, UnlocatableSourceInfo} object Reg { - private[core] def makeType[T <: Data](t: T = null, next: T = null, init: T = null): T = { + private[core] def makeType[T <: Data](compileOptions: ExplicitCompileOptions, t: T = null, next: T = null, init: T = null): T = { if (t ne null) { - if (Builder.compileOptions.declaredTypeMustBeUnbound || Builder.forcedModule.compileOptions.declaredTypeMustBeUnbound) { + if (compileOptions.declaredTypeMustBeUnbound) { Binding.checkUnbound(t, s"t ($t) must be unbound Type. Try using cloneType?") } t.chiselCloneType @@ -40,18 +40,18 @@ object Reg { * is a valid value. In those cases, you can either use the outType only Reg * constructor or pass in `null.asInstanceOf[T]`. */ - def apply[T <: Data](t: T = null, next: T = null, init: T = null): T = + def apply[T <: Data](t: T = null, next: T = null, init: T = null)(implicit sourceInfo: SourceInfo, compileOptions: ExplicitCompileOptions): T = // Scala macros can't (yet) handle named or default arguments. - do_apply(t, next, init)(UnlocatableSourceInfo) + do_apply(t, next, init)(sourceInfo, compileOptions) /** Creates a register without initialization (reset is ignored). Value does * not change unless assigned to (using the := operator). * * @param outType: data type for the register */ - def apply[T <: Data](outType: T): T = Reg[T](outType, null.asInstanceOf[T], null.asInstanceOf[T]) + def apply[T <: Data](outType: T)(implicit sourceInfo: SourceInfo, compileOptions: ExplicitCompileOptions): T = Reg[T](outType, null.asInstanceOf[T], null.asInstanceOf[T])(sourceInfo, compileOptions) - def do_apply[T <: Data](t: T, next: T, init: T)(implicit sourceInfo: SourceInfo): T = { + def do_apply[T <: Data](t: T, next: T, init: T)(implicit sourceInfo: SourceInfo, compileOptions: ExplicitCompileOptions = chisel3.Strict.CompileOptions): T = { // TODO: write this in a way that doesn't need nulls (bad Scala style), // null.asInstanceOf[T], and two constructors. Using Option types are an // option, but introduces cumbersome syntax (wrap everything in a Some()). @@ -59,7 +59,7 @@ object Reg { // but Scala's type inferencer and implicit insertion isn't smart enough // to resolve all use cases. If the type inferencer / implicit resolution // system improves, this may be changed. - val x = makeType(t, next, init) + val x = makeType(compileOptions, t, next, init) val clock = Node(x._parent.get.clock) // TODO multi-clock // Bind each element of x to being a Reg diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 0376e067..8d376810 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -129,16 +129,12 @@ private[chisel3] trait HasId extends InstanceId { } } -private[chisel3] class DynamicContext(moduleCompileOptions: Option[ExplicitCompileOptions] = None) { +private[chisel3] class DynamicContext() { val idGen = new IdGen val globalNamespace = new Namespace(None, Set()) val components = ArrayBuffer[Component]() var currentModule: Option[Module] = None val errors = new ErrorLog - val compileOptions = moduleCompileOptions match { - case Some(options: ExplicitCompileOptions) => options - case None => chisel3.NotStrict.CompileOptions - } } private[chisel3] object Builder { @@ -150,7 +146,6 @@ private[chisel3] object Builder { def idGen: IdGen = dynamicContext.idGen def globalNamespace: Namespace = dynamicContext.globalNamespace def components: ArrayBuffer[Component] = dynamicContext.components - def compileOptions = dynamicContext.compileOptions def currentModule: Option[Module] = dynamicContext.currentModule def currentModule_=(target: Option[Module]): Unit = { @@ -179,8 +174,8 @@ private[chisel3] object Builder { def errors: ErrorLog = dynamicContext.errors def error(m: => String): Unit = errors.error(m) - def build[T <: Module](f: => T, moduleCompileOptions: Option[ExplicitCompileOptions] = None): Circuit = { - dynamicContextVar.withValue(Some(new DynamicContext(moduleCompileOptions))) { + def build[T <: Module](f: => T): Circuit = { + dynamicContextVar.withValue(Some(new DynamicContext())) { errors.info("Elaborating design...") val mod = f mod.forceName(mod.name, globalNamespace) diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index f9f79f35..5e0a3a0f 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -108,9 +108,9 @@ object Driver extends BackendCompilationUtilities { * @param gen a function that creates a Module hierarchy * @return the resulting Chisel IR in the form of a Circuit (TODO: Should be FIRRTL IR) */ - def elaborate[T <: Module](gen: () => T, moduleCompileOptions: Option[ExplicitCompileOptions] = None): Circuit = Builder.build(Module(gen()), moduleCompileOptions) + def elaborate[T <: Module](gen: () => T): Circuit = Builder.build(Module(gen())) - def emit[T <: Module](gen: () => T, moduleCompileOptions: Option[ExplicitCompileOptions] = None): String = Emitter.emit(elaborate(gen, moduleCompileOptions)) + def emit[T <: Module](gen: () => T): String = Emitter.emit(elaborate(gen)) def emit[T <: Module](ir: Circuit): String = Emitter.emit(ir) diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 1c95190b..441f5c5b 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -3,6 +3,7 @@ package chisel3.util import chisel3._ +import chisel3.Strict.CompileOptions /** A counter module * @param n number of counts before the counter resets (or one more than the diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala index a30c276f..7146af7e 100644 --- a/src/main/scala/chisel3/util/LFSR.scala +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -6,6 +6,7 @@ package chisel3.util import chisel3._ +import chisel3.Strict.CompileOptions // scalastyle:off magic.number /** linear feedback shift register diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 37c28b14..8a9c54a2 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -6,6 +6,7 @@ package chisel3.util import chisel3._ +import chisel3.Strict.CompileOptions object RegNext { diff --git a/src/test/scala/chiselTests/BlackBox.scala b/src/test/scala/chiselTests/BlackBox.scala index c1154883..b26b7d77 100644 --- a/src/test/scala/chiselTests/BlackBox.scala +++ b/src/test/scala/chiselTests/BlackBox.scala @@ -8,6 +8,7 @@ import org.scalatest._ import chisel3._ import chisel3.testers.BasicTester import chisel3.util._ +import chisel3.Strict.CompileOptions class BlackBoxInverter extends BlackBox { val io = IO(new Bundle() { diff --git a/src/test/scala/chiselTests/CompileOptionsTest.scala b/src/test/scala/chiselTests/CompileOptionsTest.scala index 70843c3e..f835ab0d 100644 --- a/src/test/scala/chiselTests/CompileOptionsTest.scala +++ b/src/test/scala/chiselTests/CompileOptionsTest.scala @@ -13,6 +13,16 @@ class CompileOptionsSpec extends ChiselFlatSpec { abstract class StrictModule extends Module()(chisel3.Strict.CompileOptions) abstract class NotStrictModule extends Module()(chisel3.NotStrict.CompileOptions) + // Generate a set of options that do not have requireIOWrap enabled, in order to + // ensure its definition comes from the implicit options passed to the Module constructor. + object StrictWithoutIOWrap extends ExplicitCompileOptions { + val connectFieldsMustMatch = true + val declaredTypeMustBeUnbound = true + val requireIOWrap = false + val dontTryConnectionsSwapped = true + val dontAssumeDirectionality = true + } + class SmallBundle extends Bundle { val f1 = UInt(width = 4) val f2 = UInt(width = 5) @@ -199,7 +209,7 @@ class CompileOptionsSpec extends ChiselFlatSpec { } "A Module with wrapped IO when compiled with explicit Strict.CompileOption " should "not throw an exception" in { - + implicit val strictWithoutIOWrap = StrictWithoutIOWrap class RequireIOWrapModule extends StrictModule { val io = IO(new Bundle { val in = UInt(width = 32).asInput @@ -207,11 +217,13 @@ class CompileOptionsSpec extends ChiselFlatSpec { }) io.out := io.in(1) } - elaborate { new RequireIOWrapModule() } + elaborate { + new RequireIOWrapModule() + } } "A Module with unwrapped IO when compiled with explicit NotStrict.CompileOption " should "not throw an exception" in { - + implicit val strictWithoutIOWrap = StrictWithoutIOWrap class RequireIOWrapModule extends NotStrictModule { val io = new Bundle { val in = UInt(width = 32).asInput @@ -219,12 +231,14 @@ class CompileOptionsSpec extends ChiselFlatSpec { } io.out := io.in(1) } - elaborate { new RequireIOWrapModule() } + elaborate { + new RequireIOWrapModule() + } } "A Module with unwrapped IO when compiled with explicit Strict.CompileOption " should "throw an exception" in { a [BindingException] should be thrownBy { - + implicit val strictWithoutIOWrap = StrictWithoutIOWrap class RequireIOWrapModule extends StrictModule { val io = new Bundle { val in = UInt(width = 32).asInput @@ -256,7 +270,6 @@ class CompileOptionsSpec extends ChiselFlatSpec { val in = UInt(width = 32).asInput val out = Bool().asOutput } - io.out := io.in(1) } elaborate { new NotIOWrapModule() diff --git a/src/test/scala/chiselTests/Counter.scala b/src/test/scala/chiselTests/Counter.scala index 69d8a44a..46ab6dfc 100644 --- a/src/test/scala/chiselTests/Counter.scala +++ b/src/test/scala/chiselTests/Counter.scala @@ -8,6 +8,7 @@ import org.scalatest.prop._ import chisel3._ import chisel3.testers.BasicTester import chisel3.util._ +import chisel3.Strict.CompileOptions class CountTester(max: Int) extends BasicTester { val cnt = Counter(max) diff --git a/src/test/scala/chiselTests/MultiAssign.scala b/src/test/scala/chiselTests/MultiAssign.scala index fa4c4898..8fc1d0cb 100644 --- a/src/test/scala/chiselTests/MultiAssign.scala +++ b/src/test/scala/chiselTests/MultiAssign.scala @@ -7,6 +7,7 @@ import org.scalatest._ import chisel3._ import chisel3.testers.BasicTester import chisel3.util._ +import chisel3.Strict.CompileOptions class LastAssignTester() extends BasicTester { val cnt = Counter(2) diff --git a/src/test/scala/chiselTests/Reg.scala b/src/test/scala/chiselTests/Reg.scala index a9086223..741393b0 100644 --- a/src/test/scala/chiselTests/Reg.scala +++ b/src/test/scala/chiselTests/Reg.scala @@ -6,6 +6,7 @@ import org.scalatest._ import chisel3._ import chisel3.core.DataMirror import chisel3.testers.BasicTester +import chisel3.Strict.CompileOptions class RegSpec extends ChiselFlatSpec { "A Reg" should "throw an exception if not given any parameters" in { diff --git a/src/test/scala/chiselTests/TesterDriverSpec.scala b/src/test/scala/chiselTests/TesterDriverSpec.scala index 23eed15f..6dc075d7 100644 --- a/src/test/scala/chiselTests/TesterDriverSpec.scala +++ b/src/test/scala/chiselTests/TesterDriverSpec.scala @@ -5,6 +5,7 @@ package chiselTests import chisel3._ import chisel3.testers.BasicTester import chisel3.util._ +import chisel3.Strict.CompileOptions /** Extend BasicTester with a simple circuit and finish method. TesterDriver will call the * finish method after the FinishTester's constructor has completed, which will alter the diff --git a/src/test/scala/chiselTests/Vec.scala b/src/test/scala/chiselTests/Vec.scala index e8bd66bd..abe483a4 100644 --- a/src/test/scala/chiselTests/Vec.scala +++ b/src/test/scala/chiselTests/Vec.scala @@ -8,6 +8,7 @@ import org.scalatest.prop._ import chisel3._ import chisel3.testers.BasicTester import chisel3.util._ +import chisel3.Strict.CompileOptions class ValueTester(w: Int, values: List[Int]) extends BasicTester { val v = Vec(values.map(UInt(_, width = w))) // TODO: does this need a Wire? Why no error? diff --git a/src/test/scala/chiselTests/When.scala b/src/test/scala/chiselTests/When.scala index 07ab3444..1920b30e 100644 --- a/src/test/scala/chiselTests/When.scala +++ b/src/test/scala/chiselTests/When.scala @@ -7,6 +7,7 @@ import org.scalatest._ import chisel3._ import chisel3.testers.BasicTester import chisel3.util._ +import chisel3.Strict.CompileOptions class WhenTester() extends BasicTester { val cnt = Counter(4) -- cgit v1.2.3