aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/firrtlTests/InlineInstancesTests.scala21
-rw-r--r--src/test/scala/firrtlTests/ReplSeqMemTests.scala61
-rw-r--r--src/test/scala/firrtlTests/annotationTests/AnnotationSpec.scala35
3 files changed, 110 insertions, 7 deletions
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"))
)
)
}
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)
}
}
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))
+ }
+}