From abb8b4c90e7218129783372235619be00a215d66 Mon Sep 17 00:00:00 2001 From: Kevin Laeufer Date: Thu, 20 May 2021 19:17:31 -0700 Subject: WiringTransform: cannot run after RemoveWires (#2240) --- src/main/scala/firrtl/passes/wiring/WiringTransform.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/scala/firrtl/passes/wiring/WiringTransform.scala b/src/main/scala/firrtl/passes/wiring/WiringTransform.scala index 86afe520..d8b8eed9 100644 --- a/src/main/scala/firrtl/passes/wiring/WiringTransform.scala +++ b/src/main/scala/firrtl/passes/wiring/WiringTransform.scala @@ -40,7 +40,9 @@ class WiringTransform extends Transform with DependencyAPIMigration { override def prerequisites = Forms.MidForm override def optionalPrerequisites = Seq.empty - override def optionalPrerequisiteOf = Forms.MidEmitters + override def optionalPrerequisiteOf = Forms.MidEmitters ++ + // once wire targets are turned into nodes, our logic to wire them up no longer works + Seq(Dependency[firrtl.transforms.RemoveWires]) private val invalidates = Forms.VerilogOptimized.toSet -- Forms.MinimalHighForm override def invalidates(a: Transform): Boolean = invalidates(Dependency.fromTransform(a)) -- cgit v1.2.3 From d35248c8efc8c7afb1b99ddea631be5e6537d46d Mon Sep 17 00:00:00 2001 From: Kevin Laeufer Date: Fri, 21 May 2021 12:58:02 -0700 Subject: Annotation: override getTargets for SingleTargetAnnotation (#2241) --- src/main/scala/firrtl/annotations/Annotation.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/scala/firrtl/annotations/Annotation.scala b/src/main/scala/firrtl/annotations/Annotation.scala index b5c9c7e0..8722c4fa 100644 --- a/src/main/scala/firrtl/annotations/Annotation.scala +++ b/src/main/scala/firrtl/annotations/Annotation.scala @@ -48,6 +48,9 @@ trait NoTargetAnnotation extends Annotation { trait SingleTargetAnnotation[T <: Named] extends Annotation { val target: T + // we can implement getTargets more efficiently since we know that we have exactly one target + override def getTargets: Seq[Target] = Seq(target) + /** Create another instance of this Annotation */ def duplicate(n: T): Annotation -- cgit v1.2.3 From 15309c972cd9bc2d95437af9aef9875aa169b37e Mon Sep 17 00:00:00 2001 From: Albert Chen Date: Fri, 21 May 2021 15:27:17 -0700 Subject: Fix renaming of local targets in InlineInstances (#2238) * add more inline renaming test cases * InlineInstances: fix renaming for local targets * run scalafmt Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>--- src/main/scala/firrtl/passes/Inline.scala | 8 ++++++-- .../scala/firrtlTests/InlineInstancesTests.scala | 21 +++++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/scala/firrtl/passes/Inline.scala b/src/main/scala/firrtl/passes/Inline.scala index 912acf8e..78b3ce36 100644 --- a/src/main/scala/firrtl/passes/Inline.scala +++ b/src/main/scala/firrtl/passes/Inline.scala @@ -179,7 +179,7 @@ class InlineInstances extends Transform with DependencyAPIMigration with Registe /** Add a prefix to all declarations updating a [[Namespace]] and appending to a [[RenameMap]] */ def appendNamePrefix( - currentModule: IsModule, + currentModule: InstanceTarget, nextModule: IsModule, prefix: String, ns: Namespace, @@ -197,8 +197,13 @@ class InlineInstances extends Transform with DependencyAPIMigration with Registe } ofModuleOpt match { case None => + renameMap.record(currentModule.ofModuleTarget.ref(name), nextModule.ref(prefix + name)) renameMap.record(currentModule.ref(name), nextModule.ref(prefix + name)) case Some(ofModule) => + renameMap.record( + currentModule.ofModuleTarget.instOf(name, ofModule), + nextModule.instOf(prefix + name, ofModule) + ) renameMap.record(currentModule.instOf(name, ofModule), nextModule.instOf(prefix + name, ofModule)) } renames(name) = prefix + name @@ -348,7 +353,6 @@ class InlineInstances extends Transform with DependencyAPIMigration with Registe .map(appendRefPrefix(inlineTarget, prefixMap)) renames.record(inlineTarget, currentModule) - renamedBody case sx => sx diff --git a/src/test/scala/firrtlTests/InlineInstancesTests.scala b/src/test/scala/firrtlTests/InlineInstancesTests.scala index cc7257d2..b54db7cc 100644 --- a/src/test/scala/firrtlTests/InlineInstancesTests.scala +++ b/src/test/scala/firrtlTests/InlineInstancesTests.scala @@ -380,8 +380,12 @@ class InlineInstancesTests extends LowTransformSpec { execute(input, check, Seq(inline("Inline"))) } - case class DummyAnno(target: ReferenceTarget) extends SingleTargetAnnotation[ReferenceTarget] { - override def duplicate(n: ReferenceTarget): Annotation = DummyAnno(n) + case class DummyAnno(targets: CompleteTarget*) extends Annotation { + override def update(renames: RenameMap): Seq[Annotation] = { + Seq(DummyAnno(targets.flatMap { t => + renames.get(t).getOrElse(Seq(t)) + }: _*)) + } } "annotations" should "be renamed" in { val input = @@ -573,6 +577,9 @@ class InlineInstancesTests extends LowTransformSpec { val nestedNotInlined = inlined.instOf("bar", "NestedNoInline") val innerNestedInlined = nestedNotInlined.instOf("foo", "NestedInline") + val inlineModuleTarget = top.copy(module = "Inline") + val nestedInlineModuleTarget = top.copy(module = "NestedInline") + executeWithAnnos( input, check, @@ -586,7 +593,10 @@ class InlineInstancesTests extends LowTransformSpec { DummyAnno(nestedNotInlined.ref("a")), DummyAnno(nestedNotInlined.ref("b")), DummyAnno(innerNestedInlined.ref("a")), - DummyAnno(innerNestedInlined.ref("b")) + DummyAnno(innerNestedInlined.ref("b")), + DummyAnno(inlineModuleTarget.instOf("bar", "NestedNoInline")), + DummyAnno(inlineModuleTarget.ref("a"), inlineModuleTarget.ref("b")), + DummyAnno(nestedInlineModuleTarget.ref("a")) ), Seq( DummyAnno(top.ref("i_a")), @@ -596,7 +606,10 @@ class InlineInstancesTests extends LowTransformSpec { DummyAnno(top.instOf("i_bar", "NestedNoInline").ref("a")), DummyAnno(top.instOf("i_bar", "NestedNoInline").ref("b")), DummyAnno(top.instOf("i_bar", "NestedNoInline").ref("foo_a")), - DummyAnno(top.instOf("i_bar", "NestedNoInline").ref("foo_b")) + DummyAnno(top.instOf("i_bar", "NestedNoInline").ref("foo_b")), + DummyAnno(top.instOf("i_bar", "NestedNoInline")), + DummyAnno(top.ref("i_a"), top.ref("i_b")), + DummyAnno(top.ref("i_foo_a"), top.copy(module = "NestedNoInline").ref("foo_a")) ) ) } -- cgit v1.2.3 From 117b84a15a352451c1217155f96b09d098681baf Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Fri, 21 May 2021 15:42:53 -0700 Subject: Optimize Annotation.getTargets (#2244) --- src/main/scala/firrtl/annotations/Annotation.scala | 17 +++++++---- .../annotationTests/AnnotationSpec.scala | 35 ++++++++++++++++++++++ 2 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 src/test/scala/firrtlTests/annotationTests/AnnotationSpec.scala diff --git a/src/main/scala/firrtl/annotations/Annotation.scala b/src/main/scala/firrtl/annotations/Annotation.scala index 8722c4fa..08555a84 100644 --- a/src/main/scala/firrtl/annotations/Annotation.scala +++ b/src/main/scala/firrtl/annotations/Annotation.scala @@ -5,6 +5,8 @@ package annotations import firrtl.options.StageUtils +import scala.collection.Traversable + case class AnnotationException(message: String) extends Exception(message) /** Base type of auxiliary information */ @@ -23,18 +25,19 @@ trait Annotation extends Product { * @param ls * @return */ - private def extractComponents(ls: scala.collection.Traversable[_]): Seq[Target] = { - ls.collect { + private def extractComponents(ls: Traversable[_]): Traversable[Target] = { + ls.flatMap { case c: Target => Seq(c) - case o: Product => extractComponents(o.productIterator.toIterable) case x: scala.collection.Traversable[_] => extractComponents(x) - }.foldRight(Seq.empty[Target])((seq, c) => c ++ seq) + case o: Product => extractComponents(o.productIterator.toIterable) + case _ => Seq() + } } /** Returns all [[firrtl.annotations.Target Target]] members in this annotation * @return */ - def getTargets: Seq[Target] = extractComponents(productIterator.toSeq) + def getTargets: Seq[Target] = extractComponents(productIterator.toIterable).toSeq } /** If an Annotation does not target any [[Named]] thing in the circuit, then all updates just @@ -42,6 +45,8 @@ trait Annotation extends Product { */ trait NoTargetAnnotation extends Annotation { def update(renames: RenameMap): Seq[NoTargetAnnotation] = Seq(this) + + override def getTargets: Seq[Target] = Seq.empty } /** An Annotation that targets a single [[Named]] thing */ @@ -103,6 +108,8 @@ trait MultiTargetAnnotation extends Annotation { */ def targets: Seq[Seq[Target]] + override def getTargets: Seq[Target] = targets.flatten + /** Create another instance of this Annotation * * The inner Seqs correspond to the renames of the inner Seqs of targets diff --git a/src/test/scala/firrtlTests/annotationTests/AnnotationSpec.scala b/src/test/scala/firrtlTests/annotationTests/AnnotationSpec.scala new file mode 100644 index 00000000..2729b4dc --- /dev/null +++ b/src/test/scala/firrtlTests/annotationTests/AnnotationSpec.scala @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 + +package firrtlTests.annotationTests + +import firrtl.RenameMap +import firrtl.annotations._ +import firrtl.testutils.FirrtlFlatSpec + +object AnnotationSpec { + case class TestAnno(pairs: List[(String, ReferenceTarget)]) extends Annotation { + def update(renames: RenameMap): Seq[Annotation] = { + val pairsx = pairs.flatMap { + case (n, t) => + val ts = renames + .get(t) + .map(_.map(_.asInstanceOf[ReferenceTarget])) + .getOrElse(Seq(t)) + ts.map(n -> _) + } + Seq(TestAnno(pairsx)) + } + } +} + +class AnnotationSpec extends FirrtlFlatSpec { + import AnnotationSpec._ + + behavior.of("Annotation.getTargets") + + it should "not stack overflow" in { + val ref = CircuitTarget("Top").module("Foo").ref("vec") + val anno = TestAnno((0 until 10000).map(i => (i.toString, ref.index(i))).toList) + anno.getTargets should be(anno.pairs.map(_._2)) + } +} -- cgit v1.2.3 From 8bca41522cdc4b8ff69734cd159ce29f984d3290 Mon Sep 17 00:00:00 2001 From: sinofp Date: Sat, 22 May 2021 15:16:32 +0800 Subject: Rewrite vlsi_mem_gen into a Firrtl Transform (#2202) * Add GenVerilogMemBehaviorModelAnno & vlsiMemGen * Add CLI support for GenVerilogMemBehaviorModelAnno * Add simple test for GenVerilogMemBehaviorModelAnno * Fix for review 1. rename case class Port(prefix, `type`) to Port(prefix, portType) 2. fix AnnotatedMemoriesAnnotation collect function. 3. fix bug that ModuleName is not correct. * Format DumpMemoryAnnotations & ReplSeqMemTests * Fix for review 1. Inline genDecl, genPortSpec, genSequential, genCombinational 2. Add DefAnnotatedMemory informations in header 3. Change helpText 4. Check output Verilog by Verilator, the code is from FirrtlRunners#lintVerilog * Fix ReadWritePort mask name Co-authored-by: Jiuyang Liu Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>--- .../passes/memlib/DumpMemoryAnnotations.scala | 138 ++++++++++++++++++++- .../firrtl/passes/memlib/ReplaceMemTransform.scala | 22 +++- src/test/scala/firrtlTests/ReplSeqMemTests.scala | 61 ++++++++- 3 files changed, 213 insertions(+), 8 deletions(-) diff --git a/src/main/scala/firrtl/passes/memlib/DumpMemoryAnnotations.scala b/src/main/scala/firrtl/passes/memlib/DumpMemoryAnnotations.scala index 5cc1e0bf..f88e7e39 100644 --- a/src/main/scala/firrtl/passes/memlib/DumpMemoryAnnotations.scala +++ b/src/main/scala/firrtl/passes/memlib/DumpMemoryAnnotations.scala @@ -4,7 +4,9 @@ package firrtl package passes package memlib +import firrtl.annotations.{CircuitName, ModuleName} import firrtl.stage.Forms +import firrtl.transforms.BlackBoxInlineAnno class DumpMemoryAnnotations extends Transform with DependencyAPIMigration { @@ -13,16 +15,146 @@ class DumpMemoryAnnotations extends Transform with DependencyAPIMigration { override def optionalPrerequisiteOf = Forms.MidEmitters override def invalidates(a: Transform) = false + private def vlsiMemGen(annotatedMemory: DefAnnotatedMemory, genBlackBox: Boolean): (String, String) = { + // MaskedWritePort => WritePort with masked = true + case class Port(prefix: String, portType: MemPort) + + val masked = annotatedMemory.maskGran.isDefined + + val name = annotatedMemory.name + val width = { + val width = bitWidth(annotatedMemory.dataType) + require(width <= Int.MaxValue) + width.toInt + } + val depth = annotatedMemory.depth.toInt + val maskGran = if (masked) { + val maskGran = annotatedMemory.maskGran.get + require(maskGran <= Int.MaxValue) + maskGran.toInt + } else width + val maskSeg = width / maskGran + val ports = annotatedMemory.readers.indices.map(number => Port(s"R${number}_", ReadPort)) ++ + annotatedMemory.writers.indices.map(number => Port(s"W${number}_", WritePort)) ++ + annotatedMemory.readwriters.indices.map(number => Port(s"RW${number}_", ReadWritePort)) + + val addrWidth = math.max(math.ceil(math.log(depth) / math.log(2)).toInt, 1) + val readPorts = ports.filter(port => port.portType == ReadPort || port.portType == ReadWritePort) + + val portSpec = ports.flatMap(port => + Seq(s"input ${port.prefix}clk", s"input [${addrWidth - 1}:0] ${port.prefix}addr", s"input ${port.prefix}en") ++ + ((port, masked) match { + case (Port(prefix, ReadPort), _) => Seq(s"output [${width - 1}:0] ${prefix}data") + case (Port(prefix, WritePort), false) => Seq(s"input [${width - 1}:0] ${prefix}data") + case (Port(prefix, WritePort), true) => + Seq(s"input [${width - 1}:0] ${prefix}data", s"input [${maskSeg - 1}:0] ${prefix}mask") + case (Port(prefix, ReadWritePort), false) => + Seq( + s"input ${prefix}wmode", + s"input [${width - 1}:0] ${prefix}wdata", + s"output [${width - 1}:0] ${prefix}rdata" + ) + case (Port(prefix, ReadWritePort), true) => + Seq( + s"input ${prefix}wmode", + s"input [${maskSeg - 1}:0] ${prefix}wmask", + s"input [${width - 1}:0] ${prefix}wdata", + s"output [${width - 1}:0] ${prefix}rdata" + ) + }) + ) + + val decl = readPorts.flatMap(port => + Seq(s"reg reg_${port.prefix}ren;", s"reg [${addrWidth - 1}:0] reg_${port.prefix}addr;") + ) ++ Seq( + s"reg [${width - 1}:0] ram [${depth - 1}:0];", + "`ifdef RANDOMIZE_MEM_INIT", + " integer initvar;", + " initial begin", + " #`RANDOMIZE_DELAY begin end", + s" for (initvar = 0; initvar < $depth; initvar = initvar+1)", + s" ram[initvar] = {${(width - 1) / 32 + 1} {$$random}};" + ) ++ readPorts.map(port => s" reg_${port.prefix}addr = {${(addrWidth - 1) / 32 + 1} {$$random}};") ++ Seq( + " end", + "`endif" + ) + + val sequential = { + def genReadSequential(en: String, prefix: String): Seq[String] = Seq( + s"always @(posedge ${prefix}clk)", + s" reg_${prefix}ren <= $en;", + s"always @(posedge ${prefix}clk)", + s" if ($en) reg_${prefix}addr <= ${prefix}addr;" + ) + def genWriteSequential(en: String, prefix: String, inputData: String, maskName: String): Seq[String] = Seq( + s"always @(posedge ${prefix}clk)", + s" if ($en) begin" + ) ++ (0 until maskSeg).map { i => + val ifMask = if (masked) s"if (${prefix}${maskName}[$i]) " else "" + val ram_range = s"${(i + 1) * maskGran - 1}:${i * maskGran}" + s" ${ifMask}ram[${prefix}addr][$ram_range] <= ${prefix}$inputData[$ram_range];" + } ++ Seq(" end") + ports.flatMap(port => + port.portType match { + case ReadPort => genReadSequential(port.prefix + "en", port.prefix) + case WritePort => genWriteSequential(port.prefix + "en", port.prefix, "data", "mask") + case ReadWritePort => + genReadSequential(s"${port.prefix}en && !${port.prefix}wmode", port.prefix) ++ + genWriteSequential(s"${port.prefix}en && ${port.prefix}wmode", port.prefix, "wdata", "wmask") + } + ) + } + + val combinational = readPorts.flatMap { port => + val data = port.prefix + (if (port.portType == ReadWritePort) "rdata" else "data") + Seq( + "`ifdef RANDOMIZE_GARBAGE_ASSIGN", + s"reg [${((width - 1) / 32 + 1) * 32 - 1}:0] ${port.prefix}random;", + "`ifdef RANDOMIZE_MEM_INIT", + " initial begin", + " #`RANDOMIZE_DELAY begin end", + s" ${port.prefix}random = {${Seq.fill((width - 1) / 32 + 1)("$random").mkString(", ")}};", + s" reg_${port.prefix}ren = ${port.prefix}random[0];", + " end", + "`endif", + s"always @(posedge ${port.prefix}clk) ${port.prefix}random <= {${Seq.fill((width - 1) / 32 + 1)("$random").mkString(", ")}};", + s"assign $data = reg_${port.prefix}ren ? ram[reg_${port.prefix}addr] : ${port.prefix}random[${width - 1}:0];", + "`else", + s"assign $data = ram[reg_${port.prefix}addr];", + "`endif" + ) + } + + val body = if (genBlackBox) "" else s""" + | ${decl.mkString("\n ")} + | ${sequential.mkString("\n ")} + | ${combinational.mkString("\n ")}""".stripMargin + + (name, s"""// name:$name depth:$depth width:$width masked:$masked maskGran:$maskGran maskSeg:$maskSeg + |module $name( + | ${portSpec.mkString(",\n ")} + |); + | + |$body + | + |endmodule""".stripMargin) + } + def execute(state: CircuitState): CircuitState = { state.copy(annotations = state.annotations.flatMap { // convert and remove AnnotatedMemoriesAnnotation to CustomFileEmission case AnnotatedMemoriesAnnotation(annotatedMemories) => state.annotations.collect { case a: MemLibOutConfigFileAnnotation => - a.copy(annotatedMemories = annotatedMemories) - // todo convert xxx to verilogs here. - } + Seq(a.copy(annotatedMemories = annotatedMemories)) + case GenVerilogMemBehaviorModelAnno(genBlackBox) => + annotatedMemories.map(vlsiMemGen(_, genBlackBox)).map { + case (name, content) => + BlackBoxInlineAnno(ModuleName(name, CircuitName(state.circuit.main)), name + ".v", content) + } + }.flatten case MemLibOutConfigFileAnnotation(_, Nil) => Nil + case GenVerilogMemBehaviorModelAnno(_) => Nil case a => Seq(a) }) } diff --git a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala index f9df27a7..c7b0fbcd 100644 --- a/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala +++ b/src/main/scala/firrtl/passes/memlib/ReplaceMemTransform.scala @@ -6,9 +6,10 @@ package memlib import firrtl.Utils.error import firrtl._ import firrtl.annotations._ -import firrtl.options.{CustomFileEmission, HasShellOptions, ShellOption} +import firrtl.options.{CustomFileEmission, Dependency, HasShellOptions, ShellOption} import firrtl.passes.wiring._ import firrtl.stage.{Forms, RunFirrtlTransformAnnotation} +import firrtl.transforms.BlackBoxSourceHelper import java.io.{CharArrayWriter, PrintWriter} @@ -46,6 +47,8 @@ object PassConfigUtil { case class ReplSeqMemAnnotation(inputFileName: String, outputConfig: String) extends NoTargetAnnotation +case class GenVerilogMemBehaviorModelAnno(genBlackBox: Boolean) extends NoTargetAnnotation + /** Generate conf file for a sequence of [[DefAnnotatedMemory]] * @note file already has its suffix adding by `--replSeqMem` */ @@ -131,6 +134,20 @@ class ReplSeqMem extends SeqTransform with HasShellOptions with DependencyAPIMig helpText = "Blackbox and emit a configuration file for each sequential memory", shortOption = Some("frsq"), helpValueName = Some("-c::-i::-o:") + ), + new ShellOption[String]( + longOption = "gen-mem-verilog", + toAnnotationSeq = (a: String) => + Seq( + a match { + case "blackbox" => GenVerilogMemBehaviorModelAnno(genBlackBox = true) + case _ => GenVerilogMemBehaviorModelAnno(genBlackBox = false) + }, + RunFirrtlTransformAnnotation(new ReplSeqMem) + ), + helpText = "Blackbox and emit a Verilog behavior model for each sequential memory", + shortOption = Some("gmv"), + helpValueName = Some("") ) ) @@ -144,6 +161,7 @@ class ReplSeqMem extends SeqTransform with HasShellOptions with DependencyAPIMig new ResolveMemoryReference, new ReplaceMemMacros, new WiringTransform, - new DumpMemoryAnnotations + new DumpMemoryAnnotations, + new BlackBoxSourceHelper ) } diff --git a/src/test/scala/firrtlTests/ReplSeqMemTests.scala b/src/test/scala/firrtlTests/ReplSeqMemTests.scala index 4e00cb3a..cb6dd7a6 100644 --- a/src/test/scala/firrtlTests/ReplSeqMemTests.scala +++ b/src/test/scala/firrtlTests/ReplSeqMemTests.scala @@ -10,6 +10,8 @@ import firrtl.passes.memlib._ import firrtl.testutils.FirrtlCheckers._ import firrtl.testutils._ import firrtl.transforms._ +import firrtl.util.BackendCompilationUtilities.loggingProcessLogger +import scala.sys.process._ class ReplSeqMemSpec extends SimpleTransformSpec { def emitter = new LowFirrtlEmitter @@ -45,6 +47,23 @@ class ReplSeqMemSpec extends SimpleTransformSpec { ) } + def checkGenMemVerilog(input: String, mems: Set[MemConf], additionalAnnos: Annotation*): Unit = { + Seq(true, false).foreach { genBlackBox => + val annos = Seq(GenVerilogMemBehaviorModelAnno(genBlackBox = genBlackBox)) ++ additionalAnnos + val res = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annos)) + // Check correctness of firrtl + parse(res.getEmittedCircuit.value) + // Check the emitted Verilog + mems.foreach { mem => + val file = new java.io.File(mem.name + ".v") + require(file.exists(), s"${file.getName} should be emitted!") + val cmd = Seq("verilator", "--lint-only", file.getAbsolutePath) + assert(cmd.!(loggingProcessLogger) == 0, "Generated Verilog is not valid.") + file.delete() + } + } + } + "ReplSeqMem" should "generate blackbox wrappers for mems of bundle type" in { val input = """ circuit Top : @@ -77,6 +96,8 @@ circuit Top : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems) } "ReplSeqMem" should "not infinite loop if control signals are derived from registered versions of themselves" in { @@ -102,6 +123,8 @@ circuit Top : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems) } "ReplSeqMem" should "not fail with FixedPoint types " in { @@ -130,6 +153,8 @@ circuit CustomMemory : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems) } "ReplSeqMem" should "not fail with Signed types " in { @@ -158,6 +183,8 @@ circuit CustomMemory : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems) } "ReplSeqMem Utility -- getConnectOrigin" should @@ -232,9 +259,11 @@ circuit CustomMemory : MemConf("mem_1_ext", 7, 16, Map(WritePort -> 1, ReadPort -> 1), None) ) val confLoc = "ReplSeqMemTests.confTEMP" + val noDedupMemAnnotation = + NoDedupMemAnnotation(ComponentName("mem_0", ModuleName("CustomMemory", CircuitName("CustomMemory")))) val annos = Seq( ReplSeqMemAnnotation.parse("-c:CustomMemory:-o:" + confLoc), - NoDedupMemAnnotation(ComponentName("mem_0", ModuleName("CustomMemory", CircuitName("CustomMemory")))) + noDedupMemAnnotation ) val res = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annos)) // Check correctness of firrtl @@ -247,6 +276,8 @@ circuit CustomMemory : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems, noDedupMemAnnotation) } "ReplSeqMem" should "only not de-duplicate memories with the nodedupe annotation " in { @@ -279,9 +310,11 @@ circuit CustomMemory : MemConf("mem_1_ext", 7, 16, Map(WritePort -> 1, ReadPort -> 1), None) ) val confLoc = "ReplSeqMemTests.confTEMP" + val noDedupMemAnnotation = + NoDedupMemAnnotation(ComponentName("mem_1", ModuleName("CustomMemory", CircuitName("CustomMemory")))) val annos = Seq( ReplSeqMemAnnotation.parse("-c:CustomMemory:-o:" + confLoc), - NoDedupMemAnnotation(ComponentName("mem_1", ModuleName("CustomMemory", CircuitName("CustomMemory")))) + noDedupMemAnnotation ) val res = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annos)) // Check correctness of firrtl @@ -294,6 +327,8 @@ circuit CustomMemory : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems, noDedupMemAnnotation) } "ReplSeqMem" should "dedup mems with the same instance name as other mems (in other modules) marked NoDedup" in { @@ -337,9 +372,11 @@ circuit CustomMemory : MemConf("mem_0_0_ext", 7, 16, Map(WritePort -> 1, ReadPort -> 1), None) ) val confLoc = "ReplSeqMemTests.confTEMP" + val noDedupMemAnnotation = + NoDedupMemAnnotation(ComponentName("mem_0", ModuleName("ChildMemory", CircuitName("CustomMemory")))) val annos = Seq( ReplSeqMemAnnotation.parse("-c:CustomMemory:-o:" + confLoc), - NoDedupMemAnnotation(ComponentName("mem_0", ModuleName("ChildMemory", CircuitName("CustomMemory")))) + noDedupMemAnnotation ) val res = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annos)) // Check correctness of firrtl @@ -356,6 +393,8 @@ circuit CustomMemory : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems, noDedupMemAnnotation) } "ReplSeqMem" should "de-duplicate memories without an annotation " in { @@ -391,6 +430,8 @@ circuit CustomMemory : } require(numExtMods == 1) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems) } "ReplSeqMem" should "not have a mask if there is none" in { @@ -416,6 +457,8 @@ circuit CustomMemory : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems) } "ReplSeqMem" should "not conjoin enable signal with mask condition" in { @@ -446,6 +489,8 @@ circuit CustomMemory : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems) } "ReplSeqMem" should "not conjoin enable signal with wmask condition (RW Port)" in { @@ -480,6 +525,8 @@ circuit CustomMemory : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems) } "ReplSeqMem" should "produce an empty conf file with no SeqMems" in { @@ -501,6 +548,8 @@ circuit NoMemsHere : // Check the emitted conf checkMemConf(res, mems) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, mems) } "ReplSeqMem" should "throw an exception when encountering masks with variable granularity" in { @@ -529,6 +578,10 @@ circuit Top : val annos = Seq(ReplSeqMemAnnotation.parse("-c:Top:-o:" + confLoc)) val res = compileAndEmit(CircuitState(parse(input), ChirrtlForm, annos)) } + + intercept[ReplaceMemMacros.UnsupportedBlackboxMemoryException] { + checkGenMemVerilog(input, Set.empty) + } } "ReplSeqMem" should "not run a buggy Uniquify" in { @@ -551,6 +604,8 @@ circuit Top : // Just check that it doesn't crash compileAndEmit(CircuitState(parse(input), ChirrtlForm, annos)) (new java.io.File(confLoc)).delete() + + checkGenMemVerilog(input, Set.empty) } } -- cgit v1.2.3 From dc98264565c8b78b75cd82bcf92df22ac43b41b5 Mon Sep 17 00:00:00 2001 From: Scala Steward Date: Wed, 26 May 2021 12:36:58 +0200 Subject: Update sbt-mima-plugin to 0.9.2 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index b7b3a220..b934fd06 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -24,7 +24,7 @@ addSbtPlugin("com.thoughtworks.sbt-api-mappings" % "sbt-api-mappings" % "3.0.0") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.9.1") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.9.2") addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.7") -- cgit v1.2.3