aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Koenig2017-02-14 13:22:26 -0800
committerGitHub2017-02-14 13:22:26 -0800
commit088b72a2d5c2c467ac6851339d0a3263e6c06bed (patch)
tree3a742e83c650d9d8e47f92cae678cd605f30b2c6
parent208176767a8b93172e02b55fe5e5cc19891e5921 (diff)
Add support for Analog types in partial connect (#435)
Also add support for width inference
-rw-r--r--src/main/scala/firrtl/Utils.scala1
-rw-r--r--src/main/scala/firrtl/passes/Checks.scala2
-rw-r--r--src/main/scala/firrtl/passes/InferWidths.scala1
-rw-r--r--src/main/scala/firrtl/passes/Passes.scala15
-rw-r--r--src/test/scala/firrtlTests/AttachSpec.scala48
5 files changed, 61 insertions, 6 deletions
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala
index bce8e1be..fe6472a8 100644
--- a/src/main/scala/firrtl/Utils.scala
+++ b/src/main/scala/firrtl/Utils.scala
@@ -269,6 +269,7 @@ object Utils extends LazyLogging {
case (_: UIntType, _: UIntType) => if (flip1 == flip2) Seq((0, 0)) else Nil
case (_: SIntType, _: SIntType) => if (flip1 == flip2) Seq((0, 0)) else Nil
case (_: FixedType, _: FixedType) => if (flip1 == flip2) Seq((0, 0)) else Nil
+ case (_: AnalogType, _: AnalogType) => if (flip1 == flip2) Seq((0, 0)) else Nil
case (t1x: BundleType, t2x: BundleType) =>
def emptyMap = Map[String, (Type, Orientation, Int)]()
val t1_fields = t1x.fields.foldLeft(emptyMap, 0) { case ((map, ilen), f1) =>
diff --git a/src/main/scala/firrtl/passes/Checks.scala b/src/main/scala/firrtl/passes/Checks.scala
index 03d6a98c..bd4c7f63 100644
--- a/src/main/scala/firrtl/passes/Checks.scala
+++ b/src/main/scala/firrtl/passes/Checks.scala
@@ -392,7 +392,7 @@ object CheckTypes extends Pass {
case (_: UIntType, _: UIntType) => flip1 == flip2
case (_: SIntType, _: SIntType) => flip1 == flip2
case (_: FixedType, _: FixedType) => flip1 == flip2
- case (_: AnalogType, _: AnalogType) => false
+ case (_: AnalogType, _: AnalogType) => true
case (t1: BundleType, t2: BundleType) =>
val t1_fields = (t1.fields foldLeft Map[String, (Type, Orientation)]())(
(map, f1) => map + (f1.name -> (f1.tpe, f1.flip)))
diff --git a/src/main/scala/firrtl/passes/InferWidths.scala b/src/main/scala/firrtl/passes/InferWidths.scala
index f3f1e945..f3b77ec5 100644
--- a/src/main/scala/firrtl/passes/InferWidths.scala
+++ b/src/main/scala/firrtl/passes/InferWidths.scala
@@ -229,6 +229,7 @@ object InferWidths extends Pass {
case (t1: SIntType, t2: SIntType) => Seq(WGeq(t1.width, t2.width))
case (ClockType, ClockType) => Nil
case (FixedType(w1, p1), FixedType(w2, p2)) => Seq(WGeq(w1,w2), WGeq(p1,p2))
+ case (AnalogType(w1), AnalogType(w2)) => Seq(WGeq(w1,w2), WGeq(w2,w1))
case (t1: BundleType, t2: BundleType) =>
(t1.fields zip t2.fields foldLeft Seq[WGeq]()){case (res, (f1, f2)) =>
res ++ (f1.flip match {
diff --git a/src/main/scala/firrtl/passes/Passes.scala b/src/main/scala/firrtl/passes/Passes.scala
index 2dc71364..c595727e 100644
--- a/src/main/scala/firrtl/passes/Passes.scala
+++ b/src/main/scala/firrtl/passes/Passes.scala
@@ -140,12 +140,17 @@ object ExpandConnects extends Pass {
val ls = get_valid_points(sx.loc.tpe, sx.expr.tpe, Default, Default)
val locs = create_exps(sx.loc)
val exps = create_exps(sx.expr)
- Block(ls map {case (x, y) =>
- get_flip(sx.loc.tpe, x, Default) match {
- case Default => Connect(sx.info, locs(x), exps(y))
- case Flip => Connect(sx.info, exps(y), locs(x))
+ val stmts = ls map { case (x, y) =>
+ locs(x).tpe match {
+ case AnalogType(_) => Attach(sx.info, Seq(locs(x), exps(y)))
+ case _ =>
+ get_flip(sx.loc.tpe, x, Default) match {
+ case Default => Connect(sx.info, locs(x), exps(y))
+ case Flip => Connect(sx.info, exps(y), locs(x))
+ }
}
- })
+ }
+ Block(stmts)
case sx => sx map expand_s
}
}
diff --git a/src/test/scala/firrtlTests/AttachSpec.scala b/src/test/scala/firrtlTests/AttachSpec.scala
index 32dc00a0..5eed33bd 100644
--- a/src/test/scala/firrtlTests/AttachSpec.scala
+++ b/src/test/scala/firrtlTests/AttachSpec.scala
@@ -144,6 +144,29 @@ class InoutVerilogSpec extends FirrtlFlatSpec {
executeTest(input, check, compiler)
}
+ it should "work in partial connect" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Attaching :
+ | module Attaching :
+ | input foo : { b : UInt<3>, a : Analog<3> }
+ | output bar : { b : UInt<3>, a : Analog<3> }
+ | bar <- foo""".stripMargin
+ // Omitting `ifdef SYNTHESIS and `elseif verilator since it's tested above
+ val check =
+ """module Attaching(
+ | input [2:0] foo_b,
+ | inout [2:0] foo_a,
+ | output [2:0] bar_b,
+ | inout [2:0] bar_a
+ |);
+ | assign bar_b = foo_b;
+ | alias bar_a = foo_a;
+ |endmodule
+ |""".stripMargin.split("\n") map normalized
+ executeTest(input, check, compiler)
+ }
+
it should "preserve attach order" in {
val compiler = new VerilogCompiler
val input =
@@ -190,6 +213,31 @@ class InoutVerilogSpec extends FirrtlFlatSpec {
|""".stripMargin.split("\n") map normalized
executeTest(input2, check2, compiler)
}
+
+ it should "infer widths" in {
+ val compiler = new VerilogCompiler
+ val input =
+ """circuit Attaching :
+ | module Attaching :
+ | input an: Analog
+ | inst a of A
+ | attach (an, a.an1)
+ | module A:
+ | input an1: Analog<3>""".stripMargin
+ val check =
+ """module Attaching(
+ | inout [2:0] an
+ |);
+ | A a (
+ | .an1(an)
+ | );
+ |endmodule
+ |module A(
+ | inout [2:0] an1
+ |);
+ |endmodule""".stripMargin.split("\n") map normalized
+ executeTest(input, check, compiler)
+ }
}
class AttachAnalogSpec extends FirrtlFlatSpec {