Skip to content

Commit

Permalink
Merge pull request chipsalliance#3436 from chipsalliance/tuple-naming
Browse files Browse the repository at this point in the history
update ChiselPlugin to name tuples
  • Loading branch information
albertchen-sifive authored Aug 9, 2023
2 parents b2b7e1a + c7ea51e commit df60677
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
6 changes: 6 additions & 0 deletions core/src/main/scala/chisel3/internal/Builder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,12 @@ private[chisel3] object Builder extends LazyLogging {
for ((elt, i) <- iter.zipWithIndex) {
nameRecursively(s"${prefix}_${i}", elt, namer)
}
case product: Product =>
product.productIterator.zip(product.productElementNames).foreach {
case (elt, fullName) =>
val name = fullName.stripPrefix("_")
nameRecursively(s"${prefix}_${name}", elt, namer)
}
case _ => // Do nothing
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments)
} else if (outerMatches(s)) {
// These are type parameters, loops *are* possible here
recShouldMatch(s.typeArgs.head, seen + s)
} else if (definitions.isTupleType(s)) {
s.typeArgs.exists(t => recShouldMatch(t, seen + s))
} else {
// This is the standard inheritance hierarchy, Scalac catches loops here
s.parents.exists(p => recShouldMatch(p, seen))
Expand All @@ -59,7 +61,8 @@ class ChiselComponent(val global: Global, arguments: ChiselPluginArguments)

// If doesn't match container pattern, exit early
def earlyExit(t: Type): Boolean = {
!(t.matchesPattern(inferType(tq"Iterable[_]")) || t.matchesPattern(inferType(tq"Option[_]")))
!(t.matchesPattern(inferType(tq"Iterable[_]")) || t.matchesPattern(inferType(tq"Option[_]")) || definitions
.isTupleType(t))
}

// Return function so that it captures the cache
Expand Down
62 changes: 62 additions & 0 deletions src/test/scala/chiselTests/naming/NamePluginSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -375,4 +375,66 @@ class NamePluginSpec extends ChiselFlatSpec with Utils {
Select.wires(top).map(_.instanceName) should be(List("_a_b_c"))
}
}

"tuples" should "be named" in {
class Test extends Module {
val x = (Wire(UInt(3.W)), Wire(UInt(3.W)))
}

aspectTest(() => new Test) { top: Test =>
Select.wires(top).map(_.instanceName) should be(List("x_1", "x_2"))
}
}

"nested tuples" should "be named" in {
class Test extends Module {
val x = (
(Wire(UInt(3.W)), Wire(UInt(3.W))),
(Wire(UInt(3.W)), Wire(UInt(3.W)))
)
}

aspectTest(() => new Test) { top: Test =>
Select.wires(top).map(_.instanceName) should be(List("x_1_1", "x_1_2", "x_2_1", "x_2_2"))
}
}

"tuples containing non-Data" should "be named" in {
class Test extends Module {
val x = (Wire(UInt(3.W)), "foobar", Wire(UInt(3.W)))
}

aspectTest(() => new Test) { top: Test =>
Select.wires(top).map(_.instanceName) should be(List("x_1", "x_3"))
}
}

"tuples nested in options" should "be named" in {
class Test extends Module {
val x = Option((Wire(UInt(3.W)), Wire(UInt(3.W))))
}

aspectTest(() => new Test) { top: Test =>
Select.wires(top).map(_.instanceName) should be(List("x_1", "x_2"))
}
}

"tuple assignment" should "name IOs and registers" in {
class Test extends Module {
def myFunc(): (UInt, String) = {
val out = IO(Output(UInt(3.W)))
val in = IO(Input(UInt(3.W)))
out := Mux(in(0), RegNext(in + 2.U), in << 3)
(out, "Hi!")
}

val foo = myFunc()
}

aspectTest(() => new Test) { top: Test =>
Select.ios(top).map(_.instanceName) should be(List("clock", "reset", "foo_1", "foo_in"))
Select.registers(top).map(_.instanceName) should be(List("foo_out_REG"))
Select.wires(top).map(_.instanceName) should be(List())
}
}
}

0 comments on commit df60677

Please sign in to comment.