diff options
| author | Aditya Naik | 2024-05-03 10:59:45 -0700 |
|---|---|---|
| committer | Aditya Naik | 2024-05-03 10:59:45 -0700 |
| commit | 878d488a7c8e0d6973de58b3164022c6a102e449 (patch) | |
| tree | cd081bbcbe3f797f80b10c2d8153da0069750e51 /core/src/main/scala/chisel3/internal | |
| parent | 8200c0cdf1d471453946d5ae24bc99757b2ef02d (diff) | |
Get cleanup to compile
Diffstat (limited to 'core/src/main/scala/chisel3/internal')
6 files changed, 48 insertions, 799 deletions
diff --git a/core/src/main/scala/chisel3/internal/BiConnect.scala b/core/src/main/scala/chisel3/internal/BiConnect.scala index 74376598..82835052 100644 --- a/core/src/main/scala/chisel3/internal/BiConnect.scala +++ b/core/src/main/scala/chisel3/internal/BiConnect.scala @@ -3,7 +3,6 @@ package chisel3.internal import chisel3._ -import chisel3.experimental.dataview.{isView, reify, reifyToAggregate} import chisel3.experimental.{attach, Analog, BaseModule} import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.{Connect, Converter, DefInvalid} @@ -79,7 +78,7 @@ private[chisel3] object BiConnect { connectCompileOptions: CompileOptions, left: Data, right: Data, - context_mod: RawModule + context_mod: BaseModule ): Unit = { (left, right) match { // Handle element case (root case) @@ -109,27 +108,12 @@ private[chisel3] object BiConnect { throw MismatchedVecException } - val leftReified: Option[Aggregate] = if (isView(left_v)) reifyToAggregate(left_v) else Some(left_v) - val rightReified: Option[Aggregate] = if (isView(right_v)) reifyToAggregate(right_v) else Some(right_v) - - if ( - leftReified.nonEmpty && rightReified.nonEmpty && canBulkConnectAggregates( - leftReified.get, - rightReified.get, - sourceInfo, - connectCompileOptions, - context_mod - ) - ) { - pushCommand(Connect(sourceInfo, leftReified.get.lref, rightReified.get.lref)) - } else { - 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") - } + 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") } } } @@ -166,24 +150,7 @@ private[chisel3] object BiConnect { !MonoConnect.canBeSink(left_r, context_mod) || !MonoConnect.canBeSource(right_r, context_mod) val (newLeft, newRight) = if (flipConnection) (right_r, left_r) else (left_r, right_r) - val leftReified: Option[Aggregate] = if (isView(newLeft)) reifyToAggregate(newLeft) else Some(newLeft) - val rightReified: Option[Aggregate] = if (isView(newRight)) reifyToAggregate(newRight) else Some(newRight) - - if ( - leftReified.nonEmpty && rightReified.nonEmpty && canBulkConnectAggregates( - leftReified.get, - rightReified.get, - sourceInfo, - connectCompileOptions, - context_mod - ) - ) { - pushCommand(Connect(sourceInfo, leftReified.get.lref, rightReified.get.lref)) - } else if (!emitStrictConnects) { - newLeft.legacyConnect(newRight)(sourceInfo) - } else { - recordConnect(sourceInfo, connectCompileOptions, left_r, right_r, context_mod) - } + recordConnect(sourceInfo, connectCompileOptions, left_r, right_r, context_mod) // Handle Records connected to DontCare case (left_r: Record, DontCare) => @@ -224,7 +191,7 @@ private[chisel3] object BiConnect { connectCompileOptions: CompileOptions, left_r: Record, right_r: Record, - context_mod: RawModule + context_mod: BaseModule ): Unit = { // Verify right has no extra fields that left doesn't have @@ -270,7 +237,7 @@ private[chisel3] object BiConnect { source: Aggregate, sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, - context_mod: RawModule + context_mod: BaseModule ): Boolean = { // check that the aggregates have the same types @@ -304,13 +271,7 @@ private[chisel3] object BiConnect { case _ => true } - // do not bulk connect the 'io' pseudo-bundle of a BlackBox since it will be decomposed in FIRRTL - def blackBoxCheck = Seq(source, sink).map(_._parent).forall { - case Some(_: BlackBox) => false - case _ => true - } - - typeCheck && contextCheck && bindingCheck && flow_check && sourceNotLiteralCheck && blackBoxCheck + typeCheck && contextCheck && bindingCheck && flow_check && sourceNotLiteralCheck } // These functions (finally) issue the connection operation @@ -344,11 +305,11 @@ private[chisel3] object BiConnect { connectCompileOptions: CompileOptions, _left: Element, _right: Element, - context_mod: RawModule + context_mod: BaseModule ): Unit = { import BindingDirection.{Input, Internal, Output} // Using extensively so import these - val left = reify(_left) - val right = reify(_right) + val left = _left + val right = _right // 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: BaseModule = left.topBinding.location.getOrElse(context_mod) @@ -451,7 +412,7 @@ private[chisel3] object BiConnect { } // This function checks if analog element-level attaching is allowed, then marks the Analog as connected - def markAnalogConnected(implicit sourceInfo: SourceInfo, analog: Analog, contextModule: RawModule): Unit = { + def markAnalogConnected(implicit sourceInfo: SourceInfo, analog: Analog, contextModule: BaseModule): Unit = { analog.biConnectLocs.get(contextModule) match { case Some(sl) => throw AttachAlreadyBulkConnectedException(sl) case None => // Do nothing diff --git a/core/src/main/scala/chisel3/internal/Binding.scala b/core/src/main/scala/chisel3/internal/Binding.scala index bab79bc1..63936212 100644 --- a/core/src/main/scala/chisel3/internal/Binding.scala +++ b/core/src/main/scala/chisel3/internal/Binding.scala @@ -82,15 +82,7 @@ sealed trait UnconstrainedBinding extends TopBinding { // Location will track where this Module is, and the bound object can be referenced in FIRRTL sealed trait ConstrainedBinding extends TopBinding { def enclosure: BaseModule - def location: Option[BaseModule] = { - // If an aspect is present, return the aspect module. Otherwise, return the enclosure module - // This allows aspect modules to pretend to be enclosed modules for connectivity checking, - // inside vs outside instance checking, etc. - Builder.aspectModule(enclosure) match { - case None => Some(enclosure) - case Some(aspect) => Some(aspect) - } - } + def location: Option[BaseModule] = Some(enclosure) } // A binding representing a data that cannot be (re)assigned to. diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala index ab1435c5..57f878aa 100644 --- a/core/src/main/scala/chisel3/internal/Builder.scala +++ b/core/src/main/scala/chisel3/internal/Builder.scala @@ -6,13 +6,11 @@ import scala.util.DynamicVariable import scala.collection.mutable.ArrayBuffer import chisel3._ import chisel3.experimental._ -import chisel3.experimental.hierarchy.{Clone, ImportDefinitionAnnotation, Instance} import chisel3.internal.firrtl._ import chisel3.internal.naming._ import _root_.firrtl.annotations.{CircuitName, ComponentName, IsMember, ModuleName, Named, ReferenceTarget} import _root_.firrtl.annotations.AnnotationUtils.validComponentName import _root_.firrtl.{AnnotationSeq, RenameMap} -import chisel3.experimental.dataview.{reify, reifySingleData} import chisel3.internal.Builder.Prefix import logger.LazyLogging @@ -316,7 +314,6 @@ private[chisel3] trait HasId extends InstanceId { } val parentGuess: String = _parent match { - case Some(ViewParent) => s", in module '${reifyParent.pathName}'" case Some(p) => s", in module '${p.pathName}'" case None => "" } @@ -324,18 +321,8 @@ private[chisel3] trait HasId extends InstanceId { nameGuess + parentGuess } - // Helper for reifying views if they map to a single Target - private[chisel3] def reifyTarget: Option[Data] = this match { - case d: Data => reifySingleData(d) // Only Data can be views - case bad => throwException(s"This shouldn't be possible - got $bad with ${_parent}") - } - - // Helper for reifying the parent of a view if the view maps to a single Target - private[chisel3] def reifyParent: BaseModule = reifyTarget.flatMap(_._parent).getOrElse(ViewParent) - // Implementation of public methods. def instanceName: String = _parent match { - case Some(ViewParent) => reifyTarget.map(_.instanceName).getOrElse(this.refName(ViewParent.fakeComponent)) case Some(p) => (p._component, this) match { case (Some(c), _) => refName(c) @@ -348,16 +335,13 @@ private[chisel3] trait HasId extends InstanceId { } def pathName: String = _parent match { case None => instanceName - case Some(ViewParent) => s"${reifyParent.pathName}.$instanceName" case Some(p) => s"${p.pathName}.$instanceName" } def parentPathName: String = _parent match { - case Some(ViewParent) => reifyParent.pathName case Some(p) => p.pathName case None => throwException(s"$instanceName doesn't have a parent") } def parentModName: String = _parent match { - case Some(ViewParent) => reifyParent.name case Some(p) => p.name case None => throwException(s"$instanceName doesn't have a parent") } @@ -368,7 +352,6 @@ private[chisel3] trait HasId extends InstanceId { case None => instanceName case Some(o) => o.circuitName } - case Some(ViewParent) => reifyParent.circuitName case Some(p) => p.circuitName } @@ -413,7 +396,6 @@ private[chisel3] trait NamedComponent extends HasId { if (!validComponentName(name)) throwException(s"Illegal component name: $name (note: literals are illegal)") import _root_.firrtl.annotations.{Target, TargetToken} val root = _parent.map { - case ViewParent => reifyParent case other => other }.get.getTarget // All NamedComponents will have a parent, only the top module can have None here Target.toTargetTokens(name).toList match { @@ -427,7 +409,6 @@ private[chisel3] trait NamedComponent extends HasId { val localTarget = toTarget def makeTarget(p: BaseModule) = p.toAbsoluteTarget.ref(localTarget.ref).copy(component = localTarget.component) _parent match { - case Some(ViewParent) => makeTarget(reifyParent) case Some(parent) => makeTarget(parent) case None => localTarget } @@ -455,11 +436,6 @@ private[chisel3] class ChiselContext() { // Records the different prefixes which have been scoped at this point in time var prefixStack: Prefix = Nil - - // Views belong to a separate namespace (for renaming) - // The namespace outside of Builder context is useless, but it ensures that views can still be created - // and the resulting .toTarget is very clearly useless (_$$View$$_...) - val viewNamespace = Namespace.empty } private[chisel3] class DynamicContext( @@ -467,43 +443,9 @@ private[chisel3] class DynamicContext( val throwOnFirstError: Boolean, val warnReflectiveNaming: Boolean, val warningsAsErrors: Boolean) { - val importDefinitionAnnos = annotationSeq.collect { case a: ImportDefinitionAnnotation[_] => a } - - // Map holding the actual names of extModules - // Pick the definition name by default in case not passed through annotation. - val importDefinitionMap = importDefinitionAnnos - .map(a => a.definition.proto.name -> a.overrideDefName.getOrElse(a.definition.proto.name)) - .toMap - - // Helper function which does 2 things - // 1. Ensure there are no repeated names for imported Definitions - both Proto Names as well as ExtMod Names - // 2. Return the distinct definition / extMod names - private def checkAndGeDistinctProtoExtModNames() = { - val importAllDefinitionProtoNames = importDefinitionAnnos.map { a => a.definition.proto.name } - val importDistinctDefinitionProtoNames = importDefinitionMap.keys.toSeq - val importAllDefinitionExtModNames = importDefinitionMap.toSeq.map(_._2) - val importDistinctDefinitionExtModNames = importAllDefinitionExtModNames.distinct - - if (importDistinctDefinitionProtoNames.length < importAllDefinitionProtoNames.length) { - val duplicates = importAllDefinitionProtoNames.diff(importDistinctDefinitionProtoNames).mkString(", ") - throwException(s"Expected distinct imported Definition names but found duplicates for: $duplicates") - } - if (importDistinctDefinitionExtModNames.length < importAllDefinitionExtModNames.length) { - val duplicates = importAllDefinitionExtModNames.diff(importDistinctDefinitionExtModNames).mkString(", ") - throwException(s"Expected distinct overrideDef names but found duplicates for: $duplicates") - } - (importAllDefinitionProtoNames ++ importAllDefinitionExtModNames).distinct - } val globalNamespace = Namespace.empty - // Ensure imported Definitions emit as ExtModules with the correct name so - // that instantiations will also use the correct name and prevent any name - // conflicts with Modules/Definitions in this elaboration - checkAndGeDistinctProtoExtModNames().foreach { - globalNamespace.name(_) - } - val components = ArrayBuffer[Component]() val annotations = ArrayBuffer[ChiselAnnotation]() val newAnnotations = ArrayBuffer[ChiselMultiAnnotation]() @@ -518,9 +460,6 @@ private[chisel3] class DynamicContext( */ val aspectModule: mutable.HashMap[BaseModule, BaseModule] = mutable.HashMap.empty[BaseModule, BaseModule] - // Views that do not correspond to a single ReferenceTarget and thus require renaming - val unnamedViews: ArrayBuffer[Data] = ArrayBuffer.empty - // 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 @@ -529,9 +468,6 @@ private[chisel3] class DynamicContext( var currentReset: Option[Reset] = None val errors = new ErrorLog(warningsAsErrors) val namingStack = new NamingStack - - // Used to indicate if this is the top-level module of full elaboration, or from a Definition - var inDefinition: Boolean = false } private[chisel3] object Builder extends LazyLogging { @@ -588,10 +524,6 @@ private[chisel3] object Builder extends LazyLogging { def annotationSeq: AnnotationSeq = dynamicContext.annotationSeq def namingStack: NamingStack = dynamicContext.namingStack - def importDefinitionMap: Map[String, String] = dynamicContext.importDefinitionMap - - def unnamedViews: ArrayBuffer[Data] = dynamicContext.unnamedViews - def viewNamespace: Namespace = chiselContext.get.viewNamespace // Puts a prefix string onto the prefix stack def pushPrefix(d: String): Unit = { @@ -612,7 +544,6 @@ private[chisel3] object Builder extends LazyLogging { case Index(_, ILit(n)) => Some(n.toString) // Vec static indexing case Index(_, ULit(n, _)) => Some(n.toString) // Vec lit indexing case Index(_, _: Node) => None // Vec dynamic indexing - case ModuleIO(_, n) => Some(n) // BlackBox port } def map2[A, B](a: Option[A], b: Option[A])(f: (A, A) => B): Option[B] = a.flatMap(ax => b.map(f(ax, _))) @@ -628,7 +559,6 @@ private[chisel3] object Builder extends LazyLogging { case PortBinding(mod) if Builder.currentModule.contains(mod) => data.seedOpt case PortBinding(mod) => map2(mod.seedOpt, data.seedOpt)(_ + "_" + _) case (_: LitBinding | _: DontCareBinding) => None - case _ => Some("view_") // TODO implement } id match { case d: Data => recData(d) @@ -672,10 +602,7 @@ private[chisel3] object Builder extends LazyLogging { def currentModule_=(target: Option[BaseModule]): Unit = { dynamicContext.currentModule = target } - def aspectModule(module: BaseModule): Option[BaseModule] = dynamicContextVar.value match { - case Some(dynamicContext) => dynamicContext.aspectModule.get(module) - case _ => None - } + /** Retrieves the parent of a module based on the elaboration context * @@ -683,25 +610,8 @@ private[chisel3] object Builder extends LazyLogging { * @param context the context the parent should be evaluated in * @return the parent of the module provided */ - def retrieveParent(module: BaseModule, context: BaseModule): Option[BaseModule] = { - module._parent match { - case Some(parentModule) => { //if a parent exists investigate, otherwise return None - context match { - case aspect: ModuleAspect => { //if aspect context, do the translation - Builder.aspectModule(parentModule) match { - case Some(parentAspect) => Some(parentAspect) //we've found a translation - case _ => Some(parentModule) //no translation found - } - } //otherwise just return our parent - case _ => Some(parentModule) - } - } - case _ => None - } - } - def addAspect(module: BaseModule, aspect: BaseModule): Unit = { - dynamicContext.aspectModule += ((module, aspect)) - } + def retrieveParent(module: BaseModule, context: BaseModule): Option[BaseModule] = module._parent + def forcedModule: BaseModule = currentModule match { case Some(module) => module case None => @@ -710,20 +620,7 @@ private[chisel3] object Builder extends LazyLogging { // A bare api call is, e.g. calling Wire() from the scala console). ) } - def referenceUserModule: RawModule = { - currentModule match { - case Some(module: RawModule) => - aspectModule(module) match { - case Some(aspect: RawModule) => aspect - case other => module - } - case _ => - throwException( - "Error: Not in a RawModule. Likely cause: Missed Module() wrap, bare chisel API call, or attempting to construct hardware inside a BlackBox." - // A bare api call is, e.g. calling Wire() from the scala console). - ) - } - } + def forcedUserModule: RawModule = currentModule match { case Some(module: RawModule) => module case _ => @@ -768,12 +665,6 @@ private[chisel3] object Builder extends LazyLogging { dynamicContext.currentReset = newReset } - def inDefinition: Boolean = { - dynamicContextVar.value - .map(_.inDefinition) - .getOrElse(false) - } - def forcedClock: Clock = currentClock.getOrElse( throwException("Error: No implicit clock.") ) @@ -801,11 +692,6 @@ private[chisel3] object Builder extends LazyLogging { * (Note: Map is Iterable[Tuple2[_,_]] and thus excluded) */ def nameRecursively(prefix: String, nameMe: Any, namer: (HasId, String) => Unit): Unit = nameMe match { - case (id: Instance[_]) => - id.underlying match { - case Clone(m: internal.BaseModule.ModuleClone[_]) => namer(m.getPorts, prefix) - case _ => - } case (id: HasId) => namer(id, prefix) case Some(elt) => nameRecursively(prefix, elt, namer) case (iter: Iterable[_]) if iter.hasDefiniteSize => @@ -853,31 +739,12 @@ private[chisel3] object Builder extends LazyLogging { } } - // Builds a RenameMap for all Views that do not correspond to a single Data - // These Data give a fake ReferenceTarget for .toTarget and .toReferenceTarget that the returned - // RenameMap can split into the constituent parts - private[chisel3] def makeViewRenameMap: RenameMap = { - val renames = RenameMap() - for (view <- unnamedViews) { - val localTarget = view.toTarget - val absTarget = view.toAbsoluteTarget - val elts = getRecursiveFields.lazily(view, "").collect { case (elt: Element, _) => elt } - for (elt <- elts) { - val targetOfView = reify(elt) - renames.record(localTarget, targetOfView.toTarget) - renames.record(absTarget, targetOfView.toAbsoluteTarget) - } - } - renames - } - private[chisel3] def build[T <: BaseModule]( f: => T, dynamicContext: DynamicContext, forceModName: Boolean = true ): (Circuit, T) = { dynamicContextVar.withValue(Some(dynamicContext)) { - ViewParent // Must initialize the singleton in a Builder context or weird things can happen // in tiny designs/testcases that never access anything in chisel3.internal checkScalaVersion() logger.info("Elaborating design...") @@ -888,7 +755,7 @@ private[chisel3] object Builder extends LazyLogging { errors.checkpoint(logger) logger.info("Done elaborating.") - (Circuit(components.last.name, components.toSeq, annotations.toSeq, makeViewRenameMap, newAnnotations.toSeq), mod) + (Circuit(components.last.name, components.toSeq, annotations.toSeq, null, newAnnotations.toSeq), mod) } } initializeSingletons() diff --git a/core/src/main/scala/chisel3/internal/MonoConnect.scala b/core/src/main/scala/chisel3/internal/MonoConnect.scala index a0cca4a6..257c543f 100644 --- a/core/src/main/scala/chisel3/internal/MonoConnect.scala +++ b/core/src/main/scala/chisel3/internal/MonoConnect.scala @@ -3,10 +3,9 @@ package chisel3.internal import chisel3._ -import chisel3.experimental.{Analog, BaseModule, FixedPoint, Interval, UnsafeEnum} +import chisel3.experimental.{Analog, BaseModule, UnsafeEnum} import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl.{Connect, Converter, DefInvalid} -import chisel3.experimental.dataview.{isView, reify, reifyToAggregate} import scala.language.experimental.macros import chisel3.internal.sourceinfo.SourceInfo @@ -96,7 +95,7 @@ private[chisel3] object MonoConnect { connectCompileOptions: CompileOptions, sink: Data, source: Data, - context_mod: RawModule + context_mod: BaseModule ): Unit = (sink, source) match { @@ -109,10 +108,6 @@ private[chisel3] object MonoConnect { elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) case (sink_e: SInt, source_e: SInt) => elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) - case (sink_e: FixedPoint, source_e: FixedPoint) => - elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) - case (sink_e: Interval, source_e: Interval) => - elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) case (sink_e: Clock, source_e: Clock) => elemConnect(sourceInfo, connectCompileOptions, sink_e, source_e, context_mod) case (sink_e: AsyncReset, source_e: AsyncReset) => @@ -131,28 +126,12 @@ private[chisel3] object MonoConnect { // Handle Vec case case (sink_v: Vec[Data @unchecked], source_v: Vec[Data @unchecked]) => if (sink_v.length != source_v.length) { throw MismatchedVecException } - - val sinkReified: Option[Aggregate] = if (isView(sink_v)) reifyToAggregate(sink_v) else Some(sink_v) - val sourceReified: Option[Aggregate] = if (isView(source_v)) reifyToAggregate(source_v) else Some(source_v) - - if ( - sinkReified.nonEmpty && sourceReified.nonEmpty && canBulkConnectAggregates( - sinkReified.get, - sourceReified.get, - sourceInfo, - connectCompileOptions, - context_mod - ) - ) { - pushCommand(Connect(sourceInfo, sinkReified.get.lref, sourceReified.get.ref)) - } else { - for (idx <- 0 until sink_v.length) { - try { - implicit val compileOptions = connectCompileOptions - connect(sourceInfo, connectCompileOptions, sink_v(idx), source_v(idx), context_mod) - } catch { - case MonoConnectException(message) => throw MonoConnectException(s"($idx)$message") - } + for (idx <- 0 until sink_v.length) { + try { + implicit val compileOptions = connectCompileOptions + connect(sourceInfo, connectCompileOptions, sink_v(idx), source_v(idx), context_mod) + } catch { + case MonoConnectException(message) => throw MonoConnectException(s"($idx)$message") } } // Handle Vec connected to DontCare. Apply the DontCare to individual elements. @@ -168,34 +147,19 @@ private[chisel3] object MonoConnect { // Handle Record case case (sink_r: Record, source_r: Record) => - val sinkReified: Option[Aggregate] = if (isView(sink_r)) reifyToAggregate(sink_r) else Some(sink_r) - val sourceReified: Option[Aggregate] = if (isView(source_r)) reifyToAggregate(source_r) else Some(source_r) - - if ( - sinkReified.nonEmpty && sourceReified.nonEmpty && canBulkConnectAggregates( - sinkReified.get, - sourceReified.get, - sourceInfo, - connectCompileOptions, - context_mod - ) - ) { - pushCommand(Connect(sourceInfo, sinkReified.get.lref, sourceReified.get.ref)) - } else { - // For each field, descend with right - for ((field, sink_sub) <- sink_r.elements) { - try { - source_r.elements.get(field) match { - case Some(source_sub) => connect(sourceInfo, connectCompileOptions, sink_sub, source_sub, context_mod) - case None => { - if (connectCompileOptions.connectFieldsMustMatch) { - throw MissingFieldException(field) - } + // For each field, descend with right + for ((field, sink_sub) <- sink_r.elements) { + try { + source_r.elements.get(field) match { + case Some(source_sub) => connect(sourceInfo, connectCompileOptions, sink_sub, source_sub, context_mod) + case None => { + if (connectCompileOptions.connectFieldsMustMatch) { + throw MissingFieldException(field) } } - } catch { - case MonoConnectException(message) => throw MonoConnectException(s".$field$message") } + } catch { + case MonoConnectException(message) => throw MonoConnectException(s".$field$message") } } // Handle Record connected to DontCare. Apply the DontCare to individual elements. @@ -210,8 +174,7 @@ private[chisel3] object MonoConnect { } // Source is DontCare - it may be connected to anything. It generates a defInvalid for the sink. - case (_sink: Element, DontCare) => - val sink = reify(_sink) // Handle views + case (sink: Element, DontCare) => pushCommand(DefInvalid(sourceInfo, sink.lref)) // DontCare as a sink is illegal. case (DontCare, _) => throw DontCareCantBeSink @@ -235,7 +198,7 @@ private[chisel3] object MonoConnect { connectCompileOptions: CompileOptions, sink: Aggregate, source: Aggregate, - context_mod: RawModule + context_mod: BaseModule ): Boolean = { import ActualDirection.{Bidirectional, Input, Output} // If source has no location, assume in context module @@ -334,7 +297,7 @@ private[chisel3] object MonoConnect { wantToBeSink: Boolean, currentlyFlipped: Boolean, data: Data, - context_mod: RawModule + context_mod: BaseModule ): Boolean = { val sdir = data.specifiedDirection val coercedFlip = sdir == SpecifiedDirection.Input @@ -349,8 +312,8 @@ private[chisel3] object MonoConnect { case _ => true } } - def canBeSink(data: Data, context_mod: RawModule): Boolean = traceFlow(true, false, data, context_mod) - def canBeSource(data: Data, context_mod: RawModule): Boolean = traceFlow(false, false, data, context_mod) + def canBeSink(data: Data, context_mod: BaseModule): Boolean = traceFlow(true, false, data, context_mod) + def canBeSource(data: Data, context_mod: BaseModule): Boolean = traceFlow(false, false, data, context_mod) /** Check whether two aggregates can be bulk connected (<=) in FIRRTL. (MonoConnect case) * @@ -363,7 +326,7 @@ private[chisel3] object MonoConnect { source: Aggregate, sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, - context_mod: RawModule + context_mod: BaseModule ): Boolean = { // Assuming we're using a <>, check if a bulk connect is valid in that case def biConnectCheck = @@ -391,13 +354,11 @@ private[chisel3] object MonoConnect { def elemConnect( implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions, - _sink: Element, - _source: Element, - context_mod: RawModule + sink: Element, + source: Element, + context_mod: BaseModule ): Unit = { import BindingDirection.{Input, Internal, Output} // Using extensively so import these - val sink = reify(_sink) - val source = reify(_source) // If source has no location, assume in context module // This can occur if is a literal, unbound will error previously val sink_mod: BaseModule = sink.topBinding.location.getOrElse(throw UnwritableSinkException(sink, source)) diff --git a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala index ca39608f..c9719498 100644 --- a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala +++ b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala @@ -90,16 +90,6 @@ private[chisel3] object Converter { val uint = convert(ULit(unsigned, slit.width), ctx, info) fir.DoPrim(firrtl.PrimOps.AsSInt, Seq(uint), Seq.empty, fir.UnknownType) // TODO Simplify - case fplit @ FPLit(n, w, bp) => - val unsigned = if (n < 0) (BigInt(1) << fplit.width.get) + n else n - val uint = convert(ULit(unsigned, fplit.width), ctx, info) - val lit = bp.asInstanceOf[KnownBinaryPoint].value - fir.DoPrim(firrtl.PrimOps.AsFixedPoint, Seq(uint), Seq(lit), fir.UnknownType) - case intervalLit @ IntervalLit(n, w, bp) => - val unsigned = if (n < 0) (BigInt(1) << intervalLit.width.get) + n else n - val uint = convert(ULit(unsigned, intervalLit.width), ctx, info) - val lit = bp.asInstanceOf[KnownBinaryPoint].value - fir.DoPrim(firrtl.PrimOps.AsInterval, Seq(uint), Seq(n, n, lit), fir.UnknownType) case lit: ILit => throwException(s"Internal Error! Unexpected ILit: $lit") } @@ -319,8 +309,6 @@ private[chisel3] object Converter { case d: EnumType => fir.UIntType(convert(d.width)) case d: UInt => fir.UIntType(convert(d.width)) case d: SInt => fir.SIntType(convert(d.width)) - case d: FixedPoint => fir.FixedType(convert(d.width), convert(d.binaryPoint)) - case d: Interval => fir.IntervalType(d.range.lowerBound, d.range.upperBound, d.range.firrtlBinaryPoint) case d: Analog => fir.AnalogType(convert(d.width)) case d: Vec[_] => val childClearDir = clearDir || @@ -343,13 +331,6 @@ private[chisel3] object Converter { } } - def convert(name: String, param: Param): fir.Param = param match { - case IntParam(value) => fir.IntParam(name, value) - case DoubleParam(value) => fir.DoubleParam(name, value) - case StringParam(value) => fir.StringParam(name, fir.StringLit(value)) - case RawParam(value) => fir.RawStringParam(name, value) - } - def convert(port: Port, topDir: SpecifiedDirection = SpecifiedDirection.Unspecified): fir.Port = { val resolvedDir = SpecifiedDirection.fromParent(topDir, port.dir) val dir = resolvedDir match { @@ -368,14 +349,6 @@ private[chisel3] object Converter { def convert(component: Component): fir.DefModule = component match { case ctx @ DefModule(_, name, ports, cmds) => fir.Module(fir.NoInfo, name, ports.map(p => convert(p)), convert(cmds, ctx)) - case ctx @ DefBlackBox(id, name, ports, topDir, params) => - fir.ExtModule( - fir.NoInfo, - name, - ports.map(p => convert(p, topDir)), - id.desiredName, - params.map { case (name, p) => convert(name, p) }.toSeq - ) } def convert(circuit: Circuit): fir.Circuit = diff --git a/core/src/main/scala/chisel3/internal/firrtl/IR.scala b/core/src/main/scala/chisel3/internal/firrtl/IR.scala index ddad6b10..8ed5ed07 100644 --- a/core/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/core/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -53,7 +53,6 @@ object PrimOp { val AsUIntOp = PrimOp("asUInt") val AsSIntOp = PrimOp("asSInt") val AsFixedPointOp = PrimOp("asFixedPoint") - val AsIntervalOp = PrimOp("asInterval") val WrapOp = PrimOp("wrap") val SqueezeOp = PrimOp("squz") val ClipOp = PrimOp("clip") @@ -168,25 +167,6 @@ case class FPLit(n: BigInt, w: Width, binaryPoint: BinaryPoint) extends LitArg(n } } -case class IntervalLit(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"asInterval(${ULit(unsigned, width).name}, ${n}, ${n}, ${binaryPoint.asInstanceOf[KnownBinaryPoint].value})" - } - val range: IntervalRange = { - new IntervalRange( - IntervalRange.getBound(isClosed = true, BigDecimal(n)), - IntervalRange.getBound(isClosed = true, BigDecimal(n)), - IntervalRange.getRangeWidth(binaryPoint) - ) - } - def minWidth: Int = 1 + n.bitLength - - def cloneWithWidth(newWidth: Width): this.type = { - IntervalLit(n, newWidth, binaryPoint).asInstanceOf[this.type] - } -} - case class Ref(name: String) extends Arg /** Arg for ports of Modules @@ -314,483 +294,6 @@ object MemPortDirection { object INFER extends MemPortDirection("infer") } -sealed trait RangeType { - def getWidth: Width - - def *(that: IntervalRange): IntervalRange - def +&(that: IntervalRange): IntervalRange - def -&(that: IntervalRange): IntervalRange - def <<(that: Int): IntervalRange - def >>(that: Int): IntervalRange - def <<(that: KnownWidth): IntervalRange - def >>(that: KnownWidth): IntervalRange - def merge(that: IntervalRange): IntervalRange -} - -object IntervalRange { - - /** Creates an IntervalRange, this is used primarily by the range interpolator macro - * @param lower lower bound - * @param upper upper bound - * @param firrtlBinaryPoint binary point firrtl style - * @return - */ - def apply(lower: firrtlir.Bound, upper: firrtlir.Bound, firrtlBinaryPoint: firrtlir.Width): IntervalRange = { - new IntervalRange(lower, upper, firrtlBinaryPoint) - } - - def apply(lower: firrtlir.Bound, upper: firrtlir.Bound, binaryPoint: BinaryPoint): IntervalRange = { - new IntervalRange(lower, upper, IntervalRange.getBinaryPoint(binaryPoint)) - } - - def apply(lower: firrtlir.Bound, upper: firrtlir.Bound, binaryPoint: Int): IntervalRange = { - IntervalRange(lower, upper, BinaryPoint(binaryPoint)) - } - - /** Returns an IntervalRange appropriate for a signed value of the given width - * @param binaryPoint number of bits of mantissa - * @return - */ - def apply(binaryPoint: BinaryPoint): IntervalRange = { - IntervalRange(firrtlir.UnknownBound, firrtlir.UnknownBound, binaryPoint) - } - - /** Returns an IntervalRange appropriate for a signed value of the given width - * @param width number of bits to have in the interval - * @param binaryPoint number of bits of mantissa - * @return - */ - def apply(width: Width, binaryPoint: BinaryPoint = 0.BP): IntervalRange = { - val range = width match { - case KnownWidth(w) => - val nearestPowerOf2 = BigInt("1" + ("0" * (w - 1)), 2) - IntervalRange( - firrtlir.Closed(BigDecimal(-nearestPowerOf2)), - firrtlir.Closed(BigDecimal(nearestPowerOf2 - 1)), - binaryPoint - ) - case _ => - IntervalRange(firrtlir.UnknownBound, firrtlir.UnknownBound, binaryPoint) - } - range - } - - def unapply(arg: IntervalRange): Option[(firrtlir.Bound, firrtlir.Bound, BinaryPoint)] = { - return Some((arg.lower, arg.upper, arg.binaryPoint)) - } - - def getBound(isClosed: Boolean, value: String): firrtlir.Bound = { - if (value == "?") { - firrtlir.UnknownBound - } else if (isClosed) { - firrtlir.Closed(BigDecimal(value)) - } else { - firrtlir.Open(BigDecimal(value)) - } - } - - def getBound(isClosed: Boolean, value: BigDecimal): firrtlir.Bound = { - if (isClosed) { - firrtlir.Closed(value) - } else { - firrtlir.Open(value) - } - } - - def getBound(isClosed: Boolean, value: Int): firrtlir.Bound = { - getBound(isClosed, (BigDecimal(value))) - } - - def getBinaryPoint(s: String): firrtlir.Width = { - firrtlir.UnknownWidth - } - - def getBinaryPoint(n: Int): firrtlir.Width = { - if (n < 0) { - firrtlir.UnknownWidth - } else { - firrtlir.IntWidth(n) - } - } - def getBinaryPoint(n: BinaryPoint): firrtlir.Width = { - n match { - case UnknownBinaryPoint => firrtlir.UnknownWidth - case KnownBinaryPoint(w) => firrtlir.IntWidth(w) - } - } - - def getRangeWidth(w: Width): firrtlir.Width = { - if (w.known) { - firrtlir.IntWidth(w.get) - } else { - firrtlir.UnknownWidth - } - } - def getRangeWidth(binaryPoint: BinaryPoint): firrtlir.Width = { - if (binaryPoint.known) { - firrtlir.IntWidth(binaryPoint.get) - } else { - firrtlir.UnknownWidth - } - } - - def Unknown: IntervalRange = range"[?,?].?" -} - -sealed class IntervalRange( - val lowerBound: firrtlir.Bound, - val upperBound: firrtlir.Bound, - private[chisel3] val firrtlBinaryPoint: firrtlir.Width) - extends firrtlir.IntervalType(lowerBound, upperBound, firrtlBinaryPoint) - with RangeType { - - (lowerBound, upperBound) match { - case (firrtlir.Open(begin), firrtlir.Open(end)) => - if (begin >= end) throw new ChiselException(s"Invalid range with ${serialize}") - binaryPoint match { - case KnownBinaryPoint(bp) => - if (begin >= end - (BigDecimal(1) / BigDecimal(BigInt(1) << bp))) { - throw new ChiselException(s"Invalid range with ${serialize}") - } - case _ => - } - case (firrtlir.Open(begin), firrtlir.Closed(end)) => - if (begin >= end) throw new ChiselException(s"Invalid range with ${serialize}") - case (firrtlir.Closed(begin), firrtlir.Open(end)) => - if (begin >= end) throw new ChiselException(s"Invalid range with ${serialize}") - case (firrtlir.Closed(begin), firrtlir.Closed(end)) => - if (begin > end) throw new ChiselException(s"Invalid range with ${serialize}") - case _ => - } - - override def toString: String = { - val binaryPoint = firrtlBinaryPoint match { - case firrtlir.IntWidth(n) => s"$n" - case _ => "?" - } - val lowerBoundString = lowerBound match { - case firrtlir.Closed(l) => s"[$l" - case firrtlir.Open(l) => s"($l" - case firrtlir.UnknownBound => s"[?" - } - val upperBoundString = upperBound match { - case firrtlir.Closed(l) => s"$l]" - case firrtlir.Open(l) => s"$l)" - case firrtlir.UnknownBound => s"?]" - } - s"""range"$lowerBoundString,$upperBoundString.$binaryPoint"""" - } - - val increment: Option[BigDecimal] = firrtlBinaryPoint match { - case firrtlir.IntWidth(bp) => - Some(BigDecimal(math.pow(2, -bp.doubleValue))) - case _ => None - } - - /** If possible returns the lowest possible value for this Interval - * @return - */ - val getLowestPossibleValue: Option[BigDecimal] = { - increment match { - case Some(inc) => - lower match { - case firrtlir.Closed(n) => Some(n) - case firrtlir.Open(n) => Some(n + inc) - case _ => None - } - case _ => - None - } - } - - /** If possible returns the highest possible value for this Interval - * @return - */ - val getHighestPossibleValue: Option[BigDecimal] = { - increment match { - case Some(inc) => - upper match { - case firrtlir.Closed(n) => Some(n) - case firrtlir.Open(n) => Some(n - inc) - case _ => None - } - case _ => - None - } - } - - /** Return a Seq of the possible values for this range - * Mostly to be used for testing - * @return - */ - def getPossibleValues: NumericRange[BigDecimal] = { - (getLowestPossibleValue, getHighestPossibleValue, increment) match { - case (Some(low), Some(high), Some(inc)) => (low to high by inc) - case (_, _, None) => - throw new ChiselException(s"BinaryPoint unknown. Cannot get possible values from IntervalRange $toString") - case _ => - throw new ChiselException(s"Unknown Bound. Cannot get possible values from IntervalRange $toString") - - } - } - - override def getWidth: Width = { - width match { - case firrtlir.IntWidth(n) => KnownWidth(n.toInt) - case firrtlir.UnknownWidth => UnknownWidth() - } - } - - private def doFirrtlOp(op: firrtlir.PrimOp, that: IntervalRange): IntervalRange = { - PrimOps - .set_primop_type( - firrtlir - .DoPrim(op, Seq(firrtlir.Reference("a", this), firrtlir.Reference("b", that)), Nil, firrtlir.UnknownType) - ) - .tpe match { - case i: firrtlir.IntervalType => IntervalRange(i.lower, i.upper, i.point) - case other => sys.error("BAD!") - } - } - - private def doFirrtlDynamicShift(that: UInt, isLeft: Boolean): IntervalRange = { - val uinttpe = that.widthOption match { - case None => firrtlir.UIntType(firrtlir.UnknownWidth) - case Some(w) => firrtlir.UIntType(firrtlir.IntWidth(w)) - } - val op = if (isLeft) PrimOps.Dshl else PrimOps.Dshr - PrimOps - .set_primop_type( - firrtlir - .DoPrim(op, Seq(firrtlir.Reference("a", this), firrtlir.Reference("b", uinttpe)), Nil, firrtlir.UnknownType) - ) - .tpe match { - case i: firrtlir.IntervalType => IntervalRange(i.lower, i.upper, i.point) - case other => sys.error("BAD!") - } - } - - private def doFirrtlOp(op: firrtlir.PrimOp, that: Int): IntervalRange = { - PrimOps - .set_primop_type( - firrtlir.DoPrim(op, Seq(firrtlir.Reference("a", this)), Seq(BigInt(that)), firrtlir.UnknownType) - ) - .tpe match { - case i: firrtlir.IntervalType => IntervalRange(i.lower, i.upper, i.point) - case other => sys.error("BAD!") - } - } - - /** Multiply this by that, here we return a fully unknown range, - * firrtl's range inference can figure this out - * @param that - * @return - */ - override def *(that: IntervalRange): IntervalRange = { - doFirrtlOp(PrimOps.Mul, that) - } - - /** Add that to this, here we return a fully unknown range, - * firrtl's range inference can figure this out - * @param that - * @return - */ - override def +&(that: IntervalRange): IntervalRange = { - doFirrtlOp(PrimOps.Add, that) - } - - /** Subtract that from this, here we return a fully unknown range, - * firrtl's range inference can figure this out - * @param that - * @return - */ - override def -&(that: IntervalRange): IntervalRange = { - doFirrtlOp(PrimOps.Sub, that) - } - - private def adjustBoundValue(value: BigDecimal, binaryPointValue: Int): BigDecimal = { - if (binaryPointValue >= 0) { - val maskFactor = BigDecimal(1 << binaryPointValue) - val a = (value * maskFactor) - val b = a.setScale(0, RoundingMode.DOWN) - val c = b / maskFactor - c - } else { - value - } - } - - private def adjustBound(bound: firrtlir.Bound, binaryPoint: BinaryPoint): firrtlir.Bound = { - binaryPoint match { - case KnownBinaryPoint(binaryPointValue) => - bound match { - case firrtlir.Open(value) => firrtlir.Open(adjustBoundValue(value, binaryPointValue)) - case firrtlir.Closed(value) => firrtlir.Closed(adjustBoundValue(value, binaryPointValue)) - case _ => bound - } - case _ => firrtlir.UnknownBound - } - } - - /** Creates a new range with the increased precision - * - * @param newBinaryPoint - * @return - */ - def incPrecision(newBinaryPoint: BinaryPoint): IntervalRange = { - newBinaryPoint match { - case KnownBinaryPoint(that) => - doFirrtlOp(PrimOps.IncP, that) - case _ => - throwException(s"$this.incPrecision(newBinaryPoint = $newBinaryPoint) error, newBinaryPoint must be know") - } - } - - /** Creates a new range with the decreased precision - * - * @param newBinaryPoint - * @return - */ - def decPrecision(newBinaryPoint: BinaryPoint): IntervalRange = { - newBinaryPoint match { - case KnownBinaryPoint(that) => - doFirrtlOp(PrimOps.DecP, that) - case _ => - throwException(s"$this.decPrecision(newBinaryPoint = $newBinaryPoint) error, newBinaryPoint must be know") - } - } - - /** Creates a new range with the given binary point, adjusting precision - * on bounds as necessary - * - * @param newBinaryPoint - * @return - */ - def setPrecision(newBinaryPoint: BinaryPoint): IntervalRange = { - newBinaryPoint match { - case KnownBinaryPoint(that) => - doFirrtlOp(PrimOps.SetP, that) - case _ => - throwException(s"$this.setPrecision(newBinaryPoint = $newBinaryPoint) error, newBinaryPoint must be know") - } - } - - /** Shift this range left, i.e. shifts the min and max by the specified amount - * @param that - * @return - */ - override def <<(that: Int): IntervalRange = { - doFirrtlOp(PrimOps.Shl, that) - } - - /** Shift this range left, i.e. shifts the min and max by the known width - * @param that - * @return - */ - override def <<(that: KnownWidth): IntervalRange = { - <<(that.value) - } - - /** Shift this range left, i.e. shifts the min and max by value - * @param that - * @return - */ - def <<(that: UInt): IntervalRange = { - doFirrtlDynamicShift(that, isLeft = true) - } - - /** Shift this range right, i.e. shifts the min and max by the specified amount - * @param that - * @return - */ - override def >>(that: Int): IntervalRange = { - doFirrtlOp(PrimOps.Shr, that) - } - - /** Shift this range right, i.e. shifts the min and max by the known width - * @param that - * @return - */ - override def >>(that: KnownWidth): IntervalRange = { - >>(that.value) - } - - /** Shift this range right, i.e. shifts the min and max by value - * @param that - * @return - */ - def >>(that: UInt): IntervalRange = { - doFirrtlDynamicShift(that, isLeft = false) - } - - /** - * Squeeze returns the intersection of the ranges this interval and that Interval - * @param that - * @return - */ - def squeeze(that: IntervalRange): IntervalRange = { - doFirrtlOp(PrimOps.Squeeze, that) - } - - /** - * Wrap the value of this [[Interval]] into the range of a different Interval with a presumably smaller range. - * @param that - * @return - */ - def wrap(that: IntervalRange): IntervalRange = { - doFirrtlOp(PrimOps.Wrap, that) - } - - /** - * Clip the value of this [[Interval]] into the range of a different Interval with a presumably smaller range. - * @param that - * @return - */ - def clip(that: IntervalRange): IntervalRange = { - doFirrtlOp(PrimOps.Clip, that) - } - - /** merges the ranges of this and that, basically takes lowest low, highest high and biggest bp - * set unknown if any of this or that's value of above is unknown - * Like an union but will slurp up points in between the two ranges that were part of neither - * @param that - * @return - */ - override def merge(that: IntervalRange): IntervalRange = { - val lowest = (this.getLowestPossibleValue, that.getLowestPossibleValue) match { - case (Some(l1), Some(l2)) => - if (l1 < l2) { this.lower } - else { that.lower } - case _ => - firrtlir.UnknownBound - } - val highest = (this.getHighestPossibleValue, that.getHighestPossibleValue) match { - case (Some(l1), Some(l2)) => - if (l1 >= l2) { this.lower } - else { that.lower } - case _ => - firrtlir.UnknownBound - } - val newBinaryPoint = (this.firrtlBinaryPoint, that.firrtlBinaryPoint) match { - case (firrtlir.IntWidth(b1), firrtlir.IntWidth(b2)) => - if (b1 > b2) { firrtlir.IntWidth(b1) } - else { firrtlir.IntWidth(b2) } - case _ => - firrtlir.UnknownWidth - } - IntervalRange(lowest, highest, newBinaryPoint) - } - - def binaryPoint: BinaryPoint = { - firrtlBinaryPoint match { - case firrtlir.IntWidth(n) => - assert(n < Int.MaxValue, s"binary point value $n is out of range") - KnownBinaryPoint(n.toInt) - case _ => UnknownBinaryPoint - } - } -} - abstract class Command { def sourceInfo: SourceInfo } @@ -858,14 +361,6 @@ abstract class Component extends Arg { } @nowarn("msg=class Port") // delete when Port becomes private case class DefModule(id: RawModule, name: String, ports: Seq[Port], commands: Seq[Command]) extends Component -@nowarn("msg=class Port") // delete when Port becomes private -case class DefBlackBox( - id: BaseBlackBox, - name: String, - ports: Seq[Port], - topDir: SpecifiedDirection, - params: Map[String, Param]) - extends Component case class Circuit( name: String, |
