diff options
Diffstat (limited to 'core/src/main/scala/chisel3/experimental')
| -rw-r--r-- | core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala | 7 | ||||
| -rw-r--r-- | core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala | 29 |
2 files changed, 34 insertions, 2 deletions
diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala index 59b4c692..a8cfac2f 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Definition.scala @@ -11,6 +11,7 @@ import chisel3.internal.sourceinfo.{DefinitionTransform, DefinitionWrapTransform import chisel3.experimental.BaseModule import chisel3.internal.BaseModule.IsClone import firrtl.annotations.{IsModule, ModuleTarget} +import firrtl.annotations.{IsModule, ModuleTarget, NoTargetAnnotation} /** User-facing Definition type. * Represents a definition of an object of type [[A]] which are marked as @instantiable @@ -112,3 +113,9 @@ object Definition extends SourceInfoDoc { } } + +/** Stores a [[Definition]] that is imported so that its Instances can be + * compiled separately. + */ +case class ImportDefinitionAnnotation[T <: BaseModule with IsInstantiable](definition: Definition[T]) + extends NoTargetAnnotation diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala index cc926771..9f96dff1 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Instance.scala @@ -2,12 +2,13 @@ package chisel3.experimental.hierarchy -import scala.collection.mutable.{ArrayBuffer, HashMap} import scala.language.experimental.macros import chisel3._ import chisel3.internal.BaseModule.{InstantiableClone, IsClone, ModuleClone} +import chisel3.internal.Builder import chisel3.internal.sourceinfo.{InstanceTransform, SourceInfo} -import chisel3.experimental.BaseModule +import chisel3.experimental.{BaseModule, ExtModule} +import chisel3.internal.firrtl.{Component, DefBlackBox, DefModule, Port} import firrtl.annotations.IsModule /** User-facing Instance type. @@ -107,9 +108,33 @@ object Instance extends SourceInfoDoc { implicit sourceInfo: SourceInfo, compileOptions: CompileOptions ): Instance[T] = { + // Check to see if the module is already defined internally or externally + val existingMod = Builder.components.map { + case c: DefModule if c.id == definition.proto => Some(c) + case c: DefBlackBox if c.name == definition.proto.name => Some(c) + case _ => None + }.flatten + + if (existingMod.isEmpty) { + // Add a Definition that will get emitted as an ExtModule so that FIRRTL + // does not complain about a missing element + class EmptyExtModule extends ExtModule { + override def desiredName: String = definition.proto.name + override def generateComponent(): Option[Component] = { + require(!_closed, s"Can't generate $desiredName module more than once") + _closed = true + val firrtlPorts = definition.proto.getModulePorts.map { port => Port(port, port.specifiedDirection) } + val component = DefBlackBox(this, definition.proto.name, firrtlPorts, SpecifiedDirection.Unspecified, params) + Some(component) + } + } + Definition(new EmptyExtModule() {}) + } + val ports = experimental.CloneModuleAsRecord(definition.proto) val clone = ports._parent.get.asInstanceOf[ModuleClone[T]] clone._madeFromDefinition = true + new Instance(Clone(clone)) } |
