aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorAdam Izraelevitz2016-09-25 20:35:09 -0700
committerGitHub2016-09-25 20:35:09 -0700
commite54fb610c6bf0a7fe5c9c0f0e0b3acbb3728cfd0 (patch)
tree7c186c96c782f488a9ceea21abb3f60594bf98c7 /src/test
parent7c4fa71a062f0c18a3af13c9e8853fdec2818da9 (diff)
Spec features added: AnalogType and Attach (#295)
* Spec features added: AnalogType and Attach AnalogType(width: Width): - Concrete syntax: wire x: AnalogType<10> - New groundtype, very restricted in use cases. - Can only declare ports and wires with Analog type - Analog types are never equivalent, thus if x and y have Analog types: x <= y is never legal. Attach(info: Info, source: Expression, exprs: Seq[Expression]): - Concrete syntax: attach x to (y, z) - New statement - Source can be any groundtyped expression (UInt, SInt, Analog, Clock) - Exprs must have an Analog type reference an instance port - Source and exprs must have identical widths Included WDefInstanceConnector to enable emission of Verilog inout Should be mostly feature complete. Need to update spec if PR gets accepted. * Fixed bug where invalidated ports aren't handled * Bugfix for VerilogPrep Intermediate wires for invalidated instance ports were not invalidated * Bugfix: calling create_exp with name/tpe Returns unknown gender, which was passing through Caused temporary wire to not be declared Because Verilog is dumb, undeclared wires are assumed to be 1bit signals * Addressed donggyukim's style comments * Reworked pass to only allow analog types in attach Restrict source to be only wire or port kind Much simpler implementation, almost identical functionality Clearer semantics (i think?) * Fixup bugs from pulling in new changes from master * comments for type eqs and small style fixes
Diffstat (limited to 'src/test')
-rw-r--r--src/test/scala/firrtlTests/AttachSpec.scala413
1 files changed, 413 insertions, 0 deletions
diff --git a/src/test/scala/firrtlTests/AttachSpec.scala b/src/test/scala/firrtlTests/AttachSpec.scala
new file mode 100644
index 00000000..d1e07eae
--- /dev/null
+++ b/src/test/scala/firrtlTests/AttachSpec.scala
@@ -0,0 +1,413 @@
+/*
+Copyright (c) 2014 - 2016 The Regents of the University of
+California (Regents). All Rights Reserved. Redistribution and use in
+source and binary forms, with or without modification, are permitted
+provided that the following conditions are met:
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ two paragraphs of disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ two paragraphs of disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of the Regents nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
+ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION
+TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+*/
+
+package firrtlTests
+
+import java.io._
+import org.scalatest._
+import org.scalatest.prop._
+import firrtl._
+import firrtl.Annotations._
+import firrtl.ir.Circuit
+import firrtl.passes._
+import firrtl.Parser.IgnoreInfo
+
+class InoutVerilog extends FirrtlFlatSpec {
+ def parse (input:String) = Parser.parse(input.split("\n").toIterator, IgnoreInfo)
+ private def executeTest(input: String, expected: Seq[String], compiler: Compiler) = {
+ val writer = new StringWriter()
+ compiler.compile(parse(input), new AnnotationMap(Seq.empty), writer)
+ val lines = writer.toString().split("\n") map normalized
+ expected foreach { e =>
+ lines should contain(e)
+ }
+ }
+ "Circuit" should "attach a module input source" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Attaching :
+ | module Attaching :
+ | input an: Analog<3>
+ | inst a of A
+ | inst b of B
+ | attach an to (a.an, b.an)
+ | module A:
+ | input an: Analog<3>
+ | module B:
+ | input an: Analog<3> """.stripMargin
+ val check =
+ """module Attaching(
+ | inout [2:0] an
+ |);
+ | A a (
+ | .an(an)
+ | );
+ | B b (
+ | .an(an)
+ | );
+ |endmodule
+ |module A(
+ | inout [2:0] an
+ |);
+ |endmodule
+ |module B(
+ | inout [2:0] an
+ |);
+ |endmodule
+ |""".stripMargin.split("\n") map normalized
+ executeTest(input, check, compiler)
+ }
+
+ "Circuit" should "attach a module output source" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Attaching :
+ | module Attaching :
+ | output an: Analog<3>
+ | inst a of A
+ | inst b of B
+ | attach an to (a.an, b.an)
+ | module A:
+ | input an: Analog<3>
+ | module B:
+ | input an: Analog<3> """.stripMargin
+ val check =
+ """module Attaching(
+ | inout [2:0] an
+ |);
+ | A a (
+ | .an(an)
+ | );
+ | B b (
+ | .an(an)
+ | );
+ |endmodule
+ |module A(
+ | inout [2:0] an
+ |);
+ |endmodule
+ |module B(
+ | inout [2:0] an
+ |);
+ |endmodule
+ |""".stripMargin.split("\n") map normalized
+ executeTest(input, check, compiler)
+ }
+
+ "Circuit" should "not attach an instance input source" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Attaching :
+ | module Attaching :
+ | inst a of A
+ | inst b of B
+ | attach a.an to (b.an)
+ | module A:
+ | input an: Analog<3>
+ | module B:
+ | input an: Analog<3> """.stripMargin
+ intercept[CheckTypes.IllegalAttachSource] {
+ executeTest(input, Seq.empty, compiler)
+ }
+ }
+
+ "Circuit" should "attach an instance output source" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Attaching :
+ | module Attaching :
+ | inst a of A
+ | inst b of B
+ | attach b.an to (a.an)
+ | module A:
+ | input an: Analog<3>
+ | module B:
+ | input an: Analog<3> """.stripMargin
+ intercept[CheckTypes.IllegalAttachSource] {
+ executeTest(input, Seq.empty, compiler)
+ }
+ }
+
+ "Circuit" should "attach a wire source" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Attaching :
+ | module Attaching :
+ | wire x: Analog
+ | inst a of A
+ | attach x to (a.an)
+ | module A:
+ | input an: Analog<3> """.stripMargin
+ val check =
+ """module Attaching(
+ |);
+ | wire [2:0] x;
+ | A a (
+ | .an(x)
+ | );
+ |endmodule
+ |""".stripMargin.split("\n") map normalized
+ executeTest(input, check, compiler)
+ }
+}
+
+class AttachAnalogSpec extends FirrtlFlatSpec {
+ def parse (input:String) = Parser.parse(input.split("\n").toIterator, IgnoreInfo)
+ private def executeTest(input: String, expected: Seq[String], passes: Seq[Pass]) = {
+ val c = passes.foldLeft(Parser.parse(input.split("\n").toIterator)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ val lines = c.serialize.split("\n") map normalized
+
+ expected foreach { e =>
+ lines should contain(e)
+ }
+ }
+
+ "Connecting analog types" should "throw an exception" in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | input y: Analog<1>
+ | output x: Analog<1>
+ | x <= y""".stripMargin
+ intercept[CheckTypes.InvalidConnect] {
+ passes.foldLeft(parse(input)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
+ "Declaring register with analog types" should "throw an exception" in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | input clk: Clock
+ | reg r: Analog<2>, clk""".stripMargin
+ intercept[CheckTypes.IllegalAnalogDeclaration] {
+ passes.foldLeft(parse(input)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
+ "Declaring memory with analog types" should "throw an exception" in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | input clk: Clock
+ | mem m:
+ | data-type => Analog<2>
+ | depth => 4
+ | read-latency => 0
+ | write-latency => 1
+ | read-under-write => undefined""".stripMargin
+ intercept[CheckTypes.IllegalAnalogDeclaration] {
+ passes.foldLeft(parse(input)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
+ "Declaring node with analog types" should "throw an exception" in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | input in: Analog<2>
+ | node n = in """.stripMargin
+ intercept[CheckTypes.IllegalAnalogDeclaration] {
+ passes.foldLeft(parse(input)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
+ "Attaching a non-analog source" should "not be ok" in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | input source: UInt<2>
+ | inst a of A
+ | inst b of B
+ | attach source to (a.o, b.o)
+ | extmodule A :
+ | output o: Analog<2>
+ | extmodule B:
+ | input o: Analog<2>""".stripMargin
+ intercept[CheckTypes.IllegalAttachSource] {
+ passes.foldLeft(parse(input)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
+ "Attach instance analog male source" should "not be ok." in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | inst a of A
+ | inst b of B
+ | attach a.o to (b.o)
+ | extmodule A :
+ | output o: Analog<2>
+ | extmodule B:
+ | input o: Analog<2>""".stripMargin
+ intercept[CheckTypes.IllegalAttachSource] {
+ passes.foldLeft(parse(input)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
+ "Attach instance analog female source" should "not be ok." in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | inst a of A
+ | inst b of B
+ | attach b.o to (a.o)
+ | extmodule A :
+ | output o: Analog<2>
+ | extmodule B:
+ | input o: Analog<2>""".stripMargin
+ intercept[CheckTypes.IllegalAttachSource] {
+ passes.foldLeft(parse(input)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
+ "Attach port analog expr" should "throw an exception" in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | input i: Analog<2>
+ | input j: Analog<2>
+ | attach j to (i) """.stripMargin
+ intercept[CheckTypes.IllegalAttachExp] {
+ passes.foldLeft(parse(input)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
+ "Inequal attach widths" should "throw an exception" in {
+ val passes = Seq(
+ ToWorkingIR,
+ CheckHighForm,
+ ResolveKinds,
+ InferTypes,
+ CheckTypes,
+ InferWidths,
+ CheckWidths)
+ val input =
+ """circuit Unit :
+ | module Unit :
+ | input i: Analog<3>
+ | inst a of A
+ | attach i to (a.o)
+ | extmodule A :
+ | output o: Analog<2> """.stripMargin
+ intercept[CheckWidths.AttachWidthsNotEqual] {
+ passes.foldLeft(parse(input)) {
+ (c: Circuit, p: Pass) => p.run(c)
+ }
+ }
+ }
+
+ //"Simple compound expressions" should "be split" in {
+ // val passes = Seq(
+ // ToWorkingIR,
+ // ResolveKinds,
+ // InferTypes,
+ // ResolveGenders,
+ // InferWidths,
+ // SplitExpressions
+ // )
+ // val input =
+ // """circuit Top :
+ // | module Top :
+ // | input a : UInt<32>
+ // | input b : UInt<32>
+ // | input d : UInt<32>
+ // | output c : UInt<1>
+ // | c <= geq(add(a, b),d)""".stripMargin
+ // val check = Seq(
+ // "node GEN_0 = add(a, b)",
+ // "c <= geq(GEN_0, d)"
+ // )
+ // executeTest(input, check, passes)
+ //}
+}