From 58b212878bcef1ec52acb413128ba6901eee5f92 Mon Sep 17 00:00:00 2001 From: Deborah Soung Date: Tue, 8 Feb 2022 15:18:01 -0800 Subject: [PATCH 1/7] initial attempt at d/i mems --- core/src/main/scala/chisel3/Mem.scala | 6 ++- core/src/main/scala/chisel3/Module.scala | 4 +- .../experimental/hierarchy/Lookupable.scala | 40 ++++++++++++++++++- .../main/scala/chisel3/internal/Builder.scala | 1 + .../experimental/hierarchy/Annotations.scala | 9 ++++- .../hierarchy/DefinitionSpec.scala | 21 ++++++++++ .../experimental/hierarchy/Examples.scala | 6 +++ .../experimental/hierarchy/InstanceSpec.scala | 11 +++++ 8 files changed, 92 insertions(+), 6 deletions(-) diff --git a/core/src/main/scala/chisel3/Mem.scala b/core/src/main/scala/chisel3/Mem.scala index 3f37308cbf1..716ff1412a1 100644 --- a/core/src/main/scala/chisel3/Mem.scala +++ b/core/src/main/scala/chisel3/Mem.scala @@ -246,6 +246,8 @@ sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt) )( implicit compileOptions: CompileOptions ): T = { + require(Builder.currentModule == _parent, + s"cannot create a memory port in a different module (${Builder.currentModule.get.name}) than where the memory is (${_parent.get.name}).") requireIsHardware(idx, "memory port index") val i = Vec.truncateIndex(idx, length)(sourceInfo, compileOptions) @@ -267,7 +269,7 @@ sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt) * @note when multiple conflicting writes are performed on a Mem element, the * result is undefined (unlike Vec, where the last assignment wins) */ -sealed class Mem[T <: Data] private (t: T, length: BigInt) extends MemBase(t, length) +sealed class Mem[T <: Data] private[chisel3] (t: T, length: BigInt) extends MemBase(t, length) object SyncReadMem { @@ -345,7 +347,7 @@ object SyncReadMem { * @note when multiple conflicting writes are performed on a Mem element, the * result is undefined (unlike Vec, where the last assignment wins) */ -sealed class SyncReadMem[T <: Data] private (t: T, n: BigInt, val readUnderWrite: SyncReadMem.ReadUnderWrite) +sealed class SyncReadMem[T <: Data] private[chisel3] (t: T, n: BigInt, val readUnderWrite: SyncReadMem.ReadUnderWrite) extends MemBase[T](t, n) { override def read(x: UInt): T = macro SourceInfoTransform.xArg diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala index 3611f5dd521..29729dc5ff3 100644 --- a/core/src/main/scala/chisel3/Module.scala +++ b/core/src/main/scala/chisel3/Module.scala @@ -101,8 +101,8 @@ object Module extends SourceInfoDoc { compileOptions: CompileOptions ): T = { val parent = Builder.currentModule - val module: T = bc // bc is actually evaluated here + Builder.currentModule = parent module } @@ -229,6 +229,7 @@ package internal { // Private internal class to serve as a _parent for Data in cloned ports private[chisel3] class ModuleClone[T <: BaseModule](val getProto: T) extends PseudoModule with IsClone[T] { override def toString = s"ModuleClone(${getProto})" + override def addId(d: HasId): Unit = () def getPorts = _portsRecord // ClonePorts that hold the bound ports for this module // Used for setting the refs of both this module and the Record @@ -307,6 +308,7 @@ package internal { override def toString = s"DefinitionClone(${getProto})" // No addition components are generated private[chisel3] def generateComponent(): Option[Component] = None + override def addId(d: HasId): Unit = () // Necessary for toTarget to work private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = () // Module name is the same as proto's module name diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala index 8552267a36b..ec6f4ed7703 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala @@ -19,7 +19,7 @@ import chisel3.internal.{throwException, AggregateViewBinding, Builder, ChildBin */ @implicitNotFound( "@public is only legal within a class or trait marked @instantiable, and only on vals of type" + - " Data, BaseModule, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable, Option, or Either" + " Data, BaseModule, Mem, IsInstantiable, IsLookupable, or Instance[_], or in an Iterable, Option, or Either" ) trait Lookupable[-B] { type C // Return type of the lookup @@ -348,6 +348,44 @@ object Lookupable { } } + private[chisel3] def cloneMemToContext[T <: MemBase[_]]( + mem: T, + context: BaseModule + )( + implicit sourceInfo: SourceInfo, + compileOptions: CompileOptions + ): T = { + mem._parent match { + case None => mem + case Some(parent) => + val newParent = cloneModuleToContext(Proto(parent), context) + newParent match { + case Proto(p) if p == parent => mem + case Clone(mod: BaseModule) => + val existingMod = Builder.currentModule + Builder.currentModule = Some(mod) + val newChild: T = mem match { + case m: Mem[_] => new Mem(m.t.asInstanceOf[Data].cloneTypeFull, m.length).asInstanceOf[T] + case m: SyncReadMem[_] => new SyncReadMem(m.t.asInstanceOf[Data].cloneTypeFull, m.length, m.readUnderWrite).asInstanceOf[T] + } + Builder.currentModule = existingMod + newChild.setRef(mem.getRef, true) + newChild + } + } + } + + implicit def lookupMem[B <: MemBase[_]](implicit sourceInfo: SourceInfo, compileOptions: CompileOptions) = + new Lookupable[B] { + type C = B + def definitionLookup[A](that: A => B, definition: Definition[A]): C = { + cloneMemToContext(that(definition.proto), definition.getInnerDataContext.get) + } + def instanceLookup[A](that: A => B, instance: Instance[A]): C = { + cloneMemToContext(that(instance.proto), instance.getInnerDataContext.get) + } + } + import scala.language.higherKinds // Required to avoid warning for lookupIterable type parameter implicit def lookupIterable[B, F[_] <: Iterable[_]]( implicit sourceInfo: SourceInfo, diff --git a/core/src/main/scala/chisel3/internal/Builder.scala b/core/src/main/scala/chisel3/internal/Builder.scala index 247be57a422..1ffe54ab2c6 100644 --- a/core/src/main/scala/chisel3/internal/Builder.scala +++ b/core/src/main/scala/chisel3/internal/Builder.scala @@ -258,6 +258,7 @@ private[chisel3] trait HasId extends InstanceId { (p._component, this) match { case (Some(c), _) => refName(c) case (None, d: Data) if d.topBindingOpt == Some(CrossModuleBinding) => _ref.get.localName + case (None, _: MemBase[Data]) => _ref.get.localName case (None, _) => throwException(s"signalName/pathName should be called after circuit elaboration: $this, ${_parent}") } diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala index 2c1d2e9e1e3..68a00a15ed9 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala @@ -3,8 +3,8 @@ package chiselTests.experimental.hierarchy import _root_.firrtl.annotations._ -import chisel3.experimental.{annotate, BaseModule} -import chisel3.Data +import chisel3.experimental.{BaseModule, annotate} +import chisel3.{Data, MemBase} import chisel3.experimental.hierarchy.{Definition, Hierarchy, Instance} object Annotations { @@ -19,7 +19,12 @@ object Annotations { extends chisel3.experimental.ChiselAnnotation { def toFirrtl = if (isAbsolute) MarkAnnotation(d.toAbsoluteTarget, tag) else MarkAnnotation(d.toTarget, tag) } + case class MarkChiselMemAnnotation[T <: Data](m: MemBase[T], tag: String, isAbsolute: Boolean) + extends chisel3.experimental.ChiselAnnotation { + def toFirrtl = if (isAbsolute) MarkAnnotation(m.toAbsoluteTarget, tag) else MarkAnnotation(m.toTarget, tag) + } def mark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, false)) + def mark[T <: Data](d: MemBase[T], tag: String): Unit = annotate(MarkChiselMemAnnotation(d, tag, false)) def mark[B <: BaseModule](d: Hierarchy[B], tag: String): Unit = annotate(MarkChiselHierarchyAnnotation(d, tag, true)) def amark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, true)) def amark[B <: BaseModule](d: Hierarchy[B], tag: String): Unit = annotate(MarkChiselHierarchyAnnotation(d, tag, true)) diff --git a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala index 63beb394094..997812a2180 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala @@ -329,6 +329,27 @@ class DefinitionSpec extends ChiselFunSpec with Utils { annos should contain(MarkAnnotation("~Top|HasEither>x".rt, "xright")) annos should contain(MarkAnnotation("~Top|HasEither>y".rt, "yleft")) } + it("3.12: should work on Mems/SyncReadMems") { + class Top() extends Module { + val i = Definition(new HasMems()) + mark(i.mem, "Mem") + mark(i.syncReadMem, "SyncReadMem") + } + val (_, annos) = getFirrtlAndAnnos(new Top) + annos should contain(MarkAnnotation("~Top|HasMems>mem".rt, "Mem")) + annos should contain(MarkAnnotation("~Top|HasMems>syncReadMem".rt, "SyncReadMem")) + } + it ("3.13: should not create memory ports") { + class Top() extends Module { + val i = Definition(new HasMems()) + i.mem(0) := 100.U // should be illegal! + } + val failure = intercept[IllegalArgumentException] { + getFirrtlAndAnnos(new Top) + } + assert(failure.getMessage == + "requirement failed: cannot create a memory port in a different module (Top) than where the memory is (HasMems).") + } } describe("4: toDefinition") { it("4.0: should work on modules") { diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala index 5b78b7ccce3..9e7a846dbde 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/Examples.scala @@ -252,4 +252,10 @@ object Examples { val i10 = Instance(tpDef1) val i11 = Instance(tpDef1) } + + @instantiable + class HasMems() extends Module { + @public val mem = Mem(8, UInt(32.W)) + @public val syncReadMem = SyncReadMem(8, UInt(32.W)) + } } diff --git a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala index 45d1f85f668..9b17d57373b 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala @@ -320,6 +320,17 @@ class InstanceSpec extends ChiselFunSpec with Utils { @public override final lazy val y: Int = 4 } } + it("3.13: should work with Mems/SyncReadMems") { + class Top() extends Module { + val i = Instance(Definition(new HasMems())) + mark(i.mem, "Mem") + mark(i.syncReadMem, "SyncReadMem") + } + val (_, annos) = getFirrtlAndAnnos(new Top) + annos.foreach{x => println(x.serialize)} + annos should contain(MarkAnnotation("~Top|Top/i:HasMems>mem".rt, "Mem")) + annos should contain(MarkAnnotation("~Top|Top/i:HasMems>syncReadMem".rt, "SyncReadMem")) + } } describe("4: toInstance") { it("4.0: should work on modules") { From 9d6a386547c1280963c309cba5481680e689e8fe Mon Sep 17 00:00:00 2001 From: Deborah Soung Date: Tue, 8 Feb 2022 15:59:18 -0800 Subject: [PATCH 2/7] scalafmt --- core/src/main/scala/chisel3/Mem.scala | 6 ++++-- .../scala/chisel3/experimental/hierarchy/Lookupable.scala | 5 +++-- .../chiselTests/experimental/hierarchy/Annotations.scala | 4 ++-- .../experimental/hierarchy/DefinitionSpec.scala | 8 +++++--- .../chiselTests/experimental/hierarchy/InstanceSpec.scala | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/src/main/scala/chisel3/Mem.scala b/core/src/main/scala/chisel3/Mem.scala index 716ff1412a1..572b8ba0639 100644 --- a/core/src/main/scala/chisel3/Mem.scala +++ b/core/src/main/scala/chisel3/Mem.scala @@ -246,8 +246,10 @@ sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt) )( implicit compileOptions: CompileOptions ): T = { - require(Builder.currentModule == _parent, - s"cannot create a memory port in a different module (${Builder.currentModule.get.name}) than where the memory is (${_parent.get.name}).") + require( + Builder.currentModule == _parent, + s"cannot create a memory port in a different module (${Builder.currentModule.get.name}) than where the memory is (${_parent.get.name})." + ) requireIsHardware(idx, "memory port index") val i = Vec.truncateIndex(idx, length)(sourceInfo, compileOptions) diff --git a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala index ec6f4ed7703..de5d892bbda 100644 --- a/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala +++ b/core/src/main/scala/chisel3/experimental/hierarchy/Lookupable.scala @@ -349,7 +349,7 @@ object Lookupable { } private[chisel3] def cloneMemToContext[T <: MemBase[_]]( - mem: T, + mem: T, context: BaseModule )( implicit sourceInfo: SourceInfo, @@ -366,7 +366,8 @@ object Lookupable { Builder.currentModule = Some(mod) val newChild: T = mem match { case m: Mem[_] => new Mem(m.t.asInstanceOf[Data].cloneTypeFull, m.length).asInstanceOf[T] - case m: SyncReadMem[_] => new SyncReadMem(m.t.asInstanceOf[Data].cloneTypeFull, m.length, m.readUnderWrite).asInstanceOf[T] + case m: SyncReadMem[_] => + new SyncReadMem(m.t.asInstanceOf[Data].cloneTypeFull, m.length, m.readUnderWrite).asInstanceOf[T] } Builder.currentModule = existingMod newChild.setRef(mem.getRef, true) diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala index 68a00a15ed9..d8dfaa022d5 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala @@ -3,7 +3,7 @@ package chiselTests.experimental.hierarchy import _root_.firrtl.annotations._ -import chisel3.experimental.{BaseModule, annotate} +import chisel3.experimental.{annotate, BaseModule} import chisel3.{Data, MemBase} import chisel3.experimental.hierarchy.{Definition, Hierarchy, Instance} @@ -20,7 +20,7 @@ object Annotations { def toFirrtl = if (isAbsolute) MarkAnnotation(d.toAbsoluteTarget, tag) else MarkAnnotation(d.toTarget, tag) } case class MarkChiselMemAnnotation[T <: Data](m: MemBase[T], tag: String, isAbsolute: Boolean) - extends chisel3.experimental.ChiselAnnotation { + extends chisel3.experimental.ChiselAnnotation { def toFirrtl = if (isAbsolute) MarkAnnotation(m.toAbsoluteTarget, tag) else MarkAnnotation(m.toTarget, tag) } def mark(d: Data, tag: String): Unit = annotate(MarkChiselAnnotation(d, tag, false)) diff --git a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala index 997812a2180..129baf0f6b5 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala @@ -339,7 +339,7 @@ class DefinitionSpec extends ChiselFunSpec with Utils { annos should contain(MarkAnnotation("~Top|HasMems>mem".rt, "Mem")) annos should contain(MarkAnnotation("~Top|HasMems>syncReadMem".rt, "SyncReadMem")) } - it ("3.13: should not create memory ports") { + it("3.13: should not create memory ports") { class Top() extends Module { val i = Definition(new HasMems()) i.mem(0) := 100.U // should be illegal! @@ -347,8 +347,10 @@ class DefinitionSpec extends ChiselFunSpec with Utils { val failure = intercept[IllegalArgumentException] { getFirrtlAndAnnos(new Top) } - assert(failure.getMessage == - "requirement failed: cannot create a memory port in a different module (Top) than where the memory is (HasMems).") + assert( + failure.getMessage == + "requirement failed: cannot create a memory port in a different module (Top) than where the memory is (HasMems)." + ) } } describe("4: toDefinition") { diff --git a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala index 9b17d57373b..9b9cd35fa3d 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/InstanceSpec.scala @@ -327,7 +327,7 @@ class InstanceSpec extends ChiselFunSpec with Utils { mark(i.syncReadMem, "SyncReadMem") } val (_, annos) = getFirrtlAndAnnos(new Top) - annos.foreach{x => println(x.serialize)} + annos.foreach { x => println(x.serialize) } annos should contain(MarkAnnotation("~Top|Top/i:HasMems>mem".rt, "Mem")) annos should contain(MarkAnnotation("~Top|Top/i:HasMems>syncReadMem".rt, "SyncReadMem")) } From 54d5c257b190a0125540174748ad4d495adc75ec Mon Sep 17 00:00:00 2001 From: Deborah Soung Date: Thu, 10 Feb 2022 11:45:19 -0800 Subject: [PATCH 3/7] fixing missing dynamic context issue --- core/src/main/scala/chisel3/Module.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala index 29729dc5ff3..8e35e29981f 100644 --- a/core/src/main/scala/chisel3/Module.scala +++ b/core/src/main/scala/chisel3/Module.scala @@ -102,7 +102,9 @@ object Module extends SourceInfoDoc { ): T = { val parent = Builder.currentModule val module: T = bc // bc is actually evaluated here - Builder.currentModule = parent + if (Builder.currentModule != parent) { + Builder.currentModule = parent + } module } From 4de6faa8170ef6a8088f218805671bf9e6daeb38 Mon Sep 17 00:00:00 2001 From: Deborah Soung Date: Thu, 10 Feb 2022 14:51:42 -0800 Subject: [PATCH 4/7] actual fix for builder error --- core/src/main/scala/chisel3/Module.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala index 8e35e29981f..de718317291 100644 --- a/core/src/main/scala/chisel3/Module.scala +++ b/core/src/main/scala/chisel3/Module.scala @@ -102,9 +102,7 @@ object Module extends SourceInfoDoc { ): T = { val parent = Builder.currentModule val module: T = bc // bc is actually evaluated here - if (Builder.currentModule != parent) { - Builder.currentModule = parent - } + if (!parent.isEmpty) { Builder.currentModule = parent } module } From f57ba73d64a218df8148aa39e279b8b9fb52b5fc Mon Sep 17 00:00:00 2001 From: Deborah Soung Date: Thu, 10 Feb 2022 16:22:06 -0800 Subject: [PATCH 5/7] addId override explanation comments --- core/src/main/scala/chisel3/Module.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/scala/chisel3/Module.scala b/core/src/main/scala/chisel3/Module.scala index de718317291..ed3235046bc 100644 --- a/core/src/main/scala/chisel3/Module.scala +++ b/core/src/main/scala/chisel3/Module.scala @@ -229,6 +229,7 @@ package internal { // Private internal class to serve as a _parent for Data in cloned ports private[chisel3] class ModuleClone[T <: BaseModule](val getProto: T) extends PseudoModule with IsClone[T] { override def toString = s"ModuleClone(${getProto})" + // Do not call default addId function, which may modify a module that is already "closed" override def addId(d: HasId): Unit = () def getPorts = _portsRecord // ClonePorts that hold the bound ports for this module @@ -308,6 +309,7 @@ package internal { override def toString = s"DefinitionClone(${getProto})" // No addition components are generated private[chisel3] def generateComponent(): Option[Component] = None + // Do not call default addId function, which may modify a module that is already "closed" override def addId(d: HasId): Unit = () // Necessary for toTarget to work private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = () From 837dbfbd0e180ff1b0e8fb73d90c0ab3d25c0864 Mon Sep 17 00:00:00 2001 From: Deborah Soung Date: Thu, 10 Feb 2022 16:31:34 -0800 Subject: [PATCH 6/7] use throwException instead of require --- core/src/main/scala/chisel3/Mem.scala | 9 +++++---- .../experimental/hierarchy/DefinitionSpec.scala | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/core/src/main/scala/chisel3/Mem.scala b/core/src/main/scala/chisel3/Mem.scala index 572b8ba0639..36984a3a592 100644 --- a/core/src/main/scala/chisel3/Mem.scala +++ b/core/src/main/scala/chisel3/Mem.scala @@ -246,10 +246,11 @@ sealed abstract class MemBase[T <: Data](val t: T, val length: BigInt) )( implicit compileOptions: CompileOptions ): T = { - require( - Builder.currentModule == _parent, - s"cannot create a memory port in a different module (${Builder.currentModule.get.name}) than where the memory is (${_parent.get.name})." - ) + if (Builder.currentModule != _parent) { + throwException( + s"Cannot create a memory port in a different module (${Builder.currentModule.get.name}) than where the memory is (${_parent.get.name})." + ) + } requireIsHardware(idx, "memory port index") val i = Vec.truncateIndex(idx, length)(sourceInfo, compileOptions) diff --git a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala index 11ed3e183ef..6ff4a3eb2ad 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/DefinitionSpec.scala @@ -354,12 +354,12 @@ class DefinitionSpec extends ChiselFunSpec with Utils { val i = Definition(new HasMems()) i.mem(0) := 100.U // should be illegal! } - val failure = intercept[IllegalArgumentException] { + val failure = intercept[ChiselException] { getFirrtlAndAnnos(new Top) } assert( failure.getMessage == - "requirement failed: cannot create a memory port in a different module (Top) than where the memory is (HasMems)." + "Cannot create a memory port in a different module (Top) than where the memory is (HasMems)." ) } } From 221bc5bf70d28e1f4a44c55947ce8d3d6de16b9c Mon Sep 17 00:00:00 2001 From: Deborah Soung Date: Fri, 11 Feb 2022 10:54:15 -0800 Subject: [PATCH 7/7] make test annotations package private --- .../scala/chiselTests/experimental/hierarchy/Annotations.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala index d8dfaa022d5..ec71fe094b7 100644 --- a/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala +++ b/src/test/scala/chiselTests/experimental/hierarchy/Annotations.scala @@ -7,7 +7,8 @@ import chisel3.experimental.{annotate, BaseModule} import chisel3.{Data, MemBase} import chisel3.experimental.hierarchy.{Definition, Hierarchy, Instance} -object Annotations { +// These annotations exist purely for testing purposes +private[hierarchy] object Annotations { case class MarkAnnotation(target: IsMember, tag: String) extends SingleTargetAnnotation[IsMember] { def duplicate(n: IsMember): Annotation = this.copy(target = n) }