Skip to content
This repository has been archived by the owner on Aug 20, 2024. It is now read-only.

Remove useless extmodule port name checks #2438

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions src/main/scala/firrtl/passes/CheckHighForm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,34 +117,13 @@ trait CheckHighFormLike { this: Pass =>
case a: AggregateType => a.mapType(stripWidth)
}

val extmoduleCollidingPorts = c.modules.collect {
case a: ExtModule => a
}.groupBy(a => (a.defname, a.params.nonEmpty))
.map {
/* There are no parameters, so all ports must match exactly. */
case (k @ (_, false), a) =>
k -> a.map(_.copy(info = NoInfo)).map(_.ports.map(_.copy(info = NoInfo))).toSet
/* If there are parameters, then only port names must match because parameters could parameterize widths.
* This means that this check cannot produce false positives, but can have false negatives.
*/
case (k @ (_, true), a) =>
k -> a.map(_.copy(info = NoInfo)).map(_.ports.map(_.copy(info = NoInfo).mapType(stripWidth))).toSet
}
.filter(_._2.size > 1)

c.modules.collect {
case a: ExtModule =>
a match {
case ExtModule(info, name, _, defname, _) if (intModuleNames.contains(defname)) =>
errors.append(new DefnameConflictException(info, name, defname))
case _ =>
}
a match {
case ExtModule(info, name, _, defname, params)
if extmoduleCollidingPorts.contains((defname, params.nonEmpty)) =>
errors.append(new DefnameDifferentPortsException(info, name, defname))
case _ =>
}
}

def checkHighFormPrimop(info: Info, mname: String, e: DoPrim): Unit = {
Expand Down
138 changes: 1 addition & 137 deletions src/test/scala/firrtlTests/CheckSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -531,142 +531,7 @@ class CheckSpec extends AnyFlatSpec with Matchers {
}
}

behavior.of("CheckHighForm running on circuits containing ExtModules")

it should "throw an exception if parameterless ExtModules have the same ports, but different widths" in {
val input =
s"""|circuit Foo:
| extmodule Bar:
| input a: UInt<1>
| defname = bar
| extmodule Baz:
| input a: UInt<2>
| defname = bar
| module Foo:
| skip
|""".stripMargin
assertThrows[CheckHighForm.DefnameDifferentPortsException] {
try {
checkHighInput(input)
} catch {
case e: firrtl.passes.PassExceptions => throw e.exceptions.head
}
}
}

it should "throw an exception if ExtModules have different port names, but identical widths" in {
val input =
s"""|circuit Foo:
| extmodule Bar:
| input a: UInt<1>
| defname = bar
| extmodule Baz:
| input b: UInt<1>
| defname = bar
| module Foo:
| skip
|""".stripMargin
assertThrows[CheckHighForm.DefnameDifferentPortsException] {
try {
checkHighInput(input)
} catch {
case e: firrtl.passes.PassExceptions => throw e.exceptions.head
}
}
}

it should "NOT throw an exception if ExtModules have parameters, matching port names, but different widths" in {
val input =
s"""|circuit Foo:
| extmodule Bar:
| input a: UInt<1>
| defname = bar
| parameter width = 1
| extmodule Baz:
| input a: UInt<2>
| defname = bar
| parameter width = 2
| module Foo:
| skip
|""".stripMargin
checkHighInput(input)
}

it should "throw an exception if ExtModules have matching port names and widths, but a different order" in {
val input =
s"""|circuit Foo:
| extmodule Bar:
| input a: UInt<1>
| input b: UInt<1>
| defname = bar
| extmodule Baz:
| input b: UInt<1>
| input a: UInt<1>
| defname = bar
| module Foo:
| skip
|""".stripMargin
assertThrows[CheckHighForm.DefnameDifferentPortsException] {
try {
checkHighInput(input)
} catch {
case e: firrtl.passes.PassExceptions => throw e.exceptions.head
}
}
}

it should "throw an exception if ExtModules have matching port names, but one is a Clock and one is a UInt<1>" in {
val input =
s"""|circuit Foo:
| extmodule Bar:
| input a: UInt<1>
| defname = bar
| extmodule Baz:
| input a: Clock
| defname = bar
| module Foo:
| skip
|""".stripMargin
assertThrows[CheckHighForm.DefnameDifferentPortsException] {
try {
checkHighInput(input)
} catch {
case e: firrtl.passes.PassExceptions => throw e.exceptions.head
}
}
}

it should "throw an exception if ExtModules have differing concrete reset types" in {
def input(rst1: String, rst2: String) =
s"""|circuit Foo:
| extmodule Bar:
| input rst: $rst1
| defname = bar
| extmodule Baz:
| input rst: $rst2
| defname = bar
| module Foo:
| skip
|""".stripMargin
info("exception thrown for 'UInt<1>' compared to 'AsyncReset'")
assertThrows[CheckHighForm.DefnameDifferentPortsException] {
try {
checkHighInput(input("UInt<1>", "AsyncReset"))
} catch {
case e: firrtl.passes.PassExceptions => throw e.exceptions.head
}
}
info("exception thrown for 'UInt<1>' compared to 'Reset'")
assertThrows[CheckHighForm.DefnameDifferentPortsException] {
try {
checkHighInput(input("UInt<1>", "Reset"))
} catch {
case e: firrtl.passes.PassExceptions => throw e.exceptions.head
}
}
}

it should "throw an exception if a statement name is used as a reference" in {
"Statement name used as a reference" should "throw an exception" in {
val src = """
|circuit test:
| module test:
Expand All @@ -679,7 +544,6 @@ class CheckSpec extends AnyFlatSpec with Matchers {
checkHighInput(src)
}
}

}

object CheckSpec {
Expand Down