mirror of https://github.com/llvm/circt.git
942 lines
27 KiB
Plaintext
942 lines
27 KiB
Plaintext
; RUN: firtool -split-input-file -ir-fir --preserve-aggregate=all -disable-opt %s | FileCheck %s
|
|
; Tests extracted from:
|
|
; - test/scala/firrtlTests/transforms/DedupTests.scala
|
|
; The following tests are not included:
|
|
; - "The module A and A_ should be deduped with the same annotation targets
|
|
; when there are a lot" because this is checking an internal bug in SFC.
|
|
; - "The module A and A_ should be dedup with same annotations with same
|
|
; multi-targets" because multi-target annotations are not used in CIRCT.
|
|
; Instead multiple annotations are scattered into the circuit. An
|
|
; approximation of multi-target annotations (which uses multiple annotations
|
|
; with the same payload) is tested in a later test.
|
|
; - "The module A and A_ should be deduped with same annotations with same
|
|
; multi-targets, that share roots" for the same reason as above.
|
|
|
|
; "The module A should be deduped"
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top0"
|
|
FIRRTL version 4.0.0
|
|
circuit Top0 :
|
|
; CHECK: firrtl.module @Top0
|
|
public module Top0 :
|
|
; CHECK-COUNT-2: firrtl.instance {{a(1|2)}} @A(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
module A :
|
|
output x: UInt<1>
|
|
connect x, UInt(1)
|
|
module A_ :
|
|
output x: UInt<1>
|
|
connect x, UInt(1)
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
|
|
; // -----
|
|
; "The module A and B should be deduped"
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top1"
|
|
FIRRTL version 4.0.0
|
|
circuit Top1 :
|
|
; CHECK: firrtl.module @Top1
|
|
public module Top1 :
|
|
; CHECK-COUNT-2: firrtl.instance {{a(1|2)}} @A(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
; CHECK: firrtl.module private @A
|
|
module A :
|
|
output x: UInt<1>
|
|
; CHECK: firrtl.instance b @B(
|
|
inst b of B
|
|
connect x, b.x
|
|
module A_ :
|
|
output x: UInt<1>
|
|
inst b of B_
|
|
connect x, b.x
|
|
module B :
|
|
output x: UInt<1>
|
|
connect x, UInt(1)
|
|
module B_ :
|
|
output x: UInt<1>
|
|
connect x, UInt(1)
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
; CHECK-NOT: firrtl.module private @B_
|
|
|
|
; // -----
|
|
; "The module A and B with comments should be deduped"
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top2"
|
|
FIRRTL version 4.0.0
|
|
circuit Top2 :
|
|
; CHECK: firrtl.module @Top2
|
|
public module Top2 :
|
|
; CHECK: firrtl.instance a1 @A(
|
|
; CHECK: firrtl.instance a2 @A(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
module A : @[yy 2:2]
|
|
output x: UInt<1> @[yy 2:2]
|
|
inst b of B @[yy 2:2]
|
|
connect x, b.x @[yy 2:2]
|
|
module A_ : @[xx 1:1]
|
|
output x: UInt<1> @[xx 1:1]
|
|
inst b of B_ @[xx 1:1]
|
|
connect x, b.x @[xx 1:1]
|
|
module B :
|
|
output x: UInt<1>
|
|
connect x, UInt(1)
|
|
module B_ :
|
|
output x: UInt<1>
|
|
connect x, UInt(1)
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
; CHECK-NOT: firrtl.module private @B_
|
|
|
|
; // -----
|
|
; "A_ but not A should be deduped if not annotated"
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top3"
|
|
FIRRTL version 4.0.0
|
|
circuit Top3 :
|
|
; CHECK: firrtl.module @Top3
|
|
public module Top3 :
|
|
; CHECK-COUNT-2: firrtl.instance {{a(1|2)}} @A(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
module A : @[yy 2:2]
|
|
output x: UInt<1> @[yy 2:2]
|
|
connect x, UInt(1)
|
|
module A_ : @[xx 1:1]
|
|
output x: UInt<1> @[xx 1:1]
|
|
connect x, UInt(1)
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
|
|
; // -----
|
|
; "Extmodules with the same defname and parameters should dedup"
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top4"
|
|
FIRRTL version 4.0.0
|
|
circuit Top4 :
|
|
; CHECK: firrtl.module @Top4
|
|
public module Top4 :
|
|
output out: UInt<1>
|
|
; CHECK-COUNT-2: firrtl.instance {{a(1|2)}} @A(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
connect out, and(a1.x, a2.y)
|
|
; CHECK: firrtl.module private @A
|
|
module A : @[yy 2:2]
|
|
output x: UInt<1> @[yy 2:2]
|
|
; CHECK-NEXT: firrtl.instance b @B(
|
|
inst b of B
|
|
connect x, b.u
|
|
module A_ : @[xx 1:1]
|
|
output y: UInt<1> @[xx 1:1]
|
|
inst c of C
|
|
connect y, c.u
|
|
extmodule B : @[aa 3:3]
|
|
output u : UInt<1> @[aa 4:4]
|
|
defname = BB
|
|
parameter N = 0
|
|
extmodule C : @[bb 5:5]
|
|
output u : UInt<1> @[bb 6:6]
|
|
defname = BB
|
|
parameter N = 0
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
; CHECK-NOT: firrtl.extmodule private @C
|
|
|
|
; // -----
|
|
; "Extmodules with different defname should NOT dedup"
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top5"
|
|
FIRRTL version 4.0.0
|
|
circuit Top5 :
|
|
; CHECK: firrtl.module @Top5
|
|
public module Top5 :
|
|
output out: UInt<1>
|
|
; CHECK-NEXT: firrtl.instance a1 @A(
|
|
; CHECK-NEXT: firrtl.instance a2 @A_(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
connect out, and(a1.x, a2.y)
|
|
module A : @[yy 2:2]
|
|
output x: UInt<1> @[yy 2:2]
|
|
inst b of B
|
|
connect x, b.u
|
|
; CHECK: firrtl.module private @A_
|
|
module A_ : @[xx 1:1]
|
|
output y: UInt<1> @[xx 1:1]
|
|
inst c of C
|
|
connect y, c.u
|
|
; CHECK: firrtl.extmodule private @B
|
|
extmodule B : @[aa 3:3]
|
|
output u : UInt<1> @[aa 4:4]
|
|
defname = BB
|
|
parameter N = 0
|
|
; CHECK: firrtl.extmodule private @C
|
|
extmodule C : @[bb 5:5]
|
|
output u : UInt<1> @[bb 6:6]
|
|
defname = CD
|
|
parameter N = 0
|
|
|
|
; // -----
|
|
; "Extmodules with different parameters should NOT dedup"
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top6"
|
|
FIRRTL version 4.0.0
|
|
circuit Top6 :
|
|
; CHECK: firrtl.module @Top6
|
|
public module Top6 :
|
|
output out: UInt<1>
|
|
; CHECK-NEXT: firrtl.instance a1 @A(
|
|
; CHECK-NEXT: firrtl.instance a2 @A_(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
connect out, and(a1.x, a2.y)
|
|
module A : @[yy 2:2]
|
|
output x: UInt<1> @[yy 2:2]
|
|
inst b of B
|
|
connect x, b.u
|
|
; CHECK: firrtl.module private @A_
|
|
module A_ : @[xx 1:1]
|
|
output y: UInt<1> @[xx 1:1]
|
|
inst c of C
|
|
connect y, c.u
|
|
; CHECK: firrtl.extmodule private @B
|
|
extmodule B : @[aa 3:3]
|
|
output u : UInt<1> @[aa 4:4]
|
|
defname = BB
|
|
parameter N = 0
|
|
; CHECK: firrtl.extmodule private @C
|
|
extmodule C : @[bb 5:5]
|
|
output u : UInt<1> @[bb 6:6]
|
|
defname = BB
|
|
parameter N = 1
|
|
|
|
; // -----
|
|
; "Modules with aggregate ports that are connected should NOT dedup if their
|
|
; port names differ".
|
|
;
|
|
; Since the MFC support expanding connects and partial connects when the port
|
|
; names differ, this now testing that the modules succesfully dedup.
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "FooAndBarModule0"
|
|
FIRRTL version 4.0.0
|
|
circuit FooAndBarModule0 :
|
|
; CHECK: firrtl.module private @FooModule
|
|
module FooModule :
|
|
output io : {flip foo : UInt<1>, fuzz : UInt<1>}
|
|
connect io.fuzz, io.foo
|
|
; CHECK-NOT: firrtl.module private @BarModule
|
|
module BarModule :
|
|
output io : {flip bar : UInt<1>, buzz : UInt<1>}
|
|
connect io.buzz, io.bar
|
|
; CHECK: firrtl.module @FooAndBarModule0
|
|
public module FooAndBarModule0 :
|
|
output io : {foo : {flip foo : UInt<1>, fuzz : UInt<1>}, bar : {flip bar : UInt<1>, buzz : UInt<1>}}
|
|
; CHECK: firrtl.instance foo @FooModule
|
|
; CHECK: firrtl.instance bar @FooModule
|
|
inst foo of FooModule
|
|
inst bar of BarModule
|
|
connect io.foo, foo.io
|
|
connect io.bar, bar.io
|
|
|
|
; // -----
|
|
; "Modules with aggregate ports that are connected should dedup if their port
|
|
; names are the same".
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "FooAndBarModule1"
|
|
FIRRTL version 4.0.0
|
|
circuit FooAndBarModule1 :
|
|
; CHECK: firrtl.module private @FooModule
|
|
module FooModule :
|
|
output io : {flip foo : UInt<1>, fuzz : UInt<1>}
|
|
connect io.fuzz, io.foo
|
|
; CHECK-NOT: firrtl.module private @BarModule
|
|
module BarModule :
|
|
output io : {flip foo : UInt<1>, fuzz : UInt<1>}
|
|
connect io.fuzz, io.foo
|
|
; CHECK: firrtl.module @FooAndBarModule1
|
|
public module FooAndBarModule1 :
|
|
output io : {foo : {flip foo : UInt<1>, fuzz : UInt<1>}, bar : {flip foo : UInt<1>, fuzz : UInt<1>}}
|
|
; CHECK-COUNT-2: firrtl.instance {{(foo|bar)}} @FooModule
|
|
inst foo of FooModule
|
|
inst bar of BarModule
|
|
connect io.foo, foo.io
|
|
connect io.bar, bar.io
|
|
|
|
; // -----
|
|
; "The module A and B should be deduped with the first module in order".
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top7"
|
|
FIRRTL version 4.0.0
|
|
circuit Top7 :
|
|
; CHECK: firrtl.module @Top7
|
|
public module Top7 :
|
|
; CHECK-COUNT-2: firrtl.instance {{a(1|2)}} @A(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
module A :
|
|
output x: UInt<1>
|
|
inst b of B
|
|
connect x, b.x
|
|
module A_ :
|
|
output x: UInt<1>
|
|
inst b of B_
|
|
connect x, b.x
|
|
module B :
|
|
output x: UInt<1>
|
|
connect x, UInt(1)
|
|
module B_ :
|
|
output x: UInt<1>
|
|
connect x, UInt(1)
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
; CHECK-NOT: firrtl.module private @B_
|
|
|
|
; // -----
|
|
; "The module A and A_ should be deduped with fields that sort of match".
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top8"
|
|
FIRRTL version 4.0.0
|
|
circuit Top8 :
|
|
; CHECK: firrtl.module @Top8
|
|
public module Top8 :
|
|
; CHECK-COUNT-2: firrtl.instance {{a(1|2)}} @A(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
module A :
|
|
output x: UInt<1>
|
|
wire b: {c: UInt<1>}
|
|
invalidate b
|
|
connect x, b.c
|
|
module A_ :
|
|
output x: UInt<1>
|
|
wire b: {b: UInt<1>}
|
|
invalidate b
|
|
connect x, b.b
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
|
|
; // -----
|
|
; "The module A and A_ should dedup with different annotation targets".
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top9"
|
|
FIRRTL version 4.0.0
|
|
circuit Top9 : %[[
|
|
{
|
|
"class":"circt.test",
|
|
"target":"Top9.A.b"
|
|
}
|
|
]]
|
|
; CHECK: hw.hierpath private @[[nlaSym:[_a-zA-Z0-9]+]] [@Top9::@[[a1Sym:[_a-zA-Z0-9]+]], @A]
|
|
; CHECK: firrtl.module @Top9
|
|
; CHECK-NEXT: firrtl.instance a1 sym @[[a1Sym]] @A(
|
|
; CHECK-NEXT: firrtl.instance a2 @A(
|
|
public module Top9 :
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
; CHECK: module private @A(
|
|
module A :
|
|
output x: UInt<1>
|
|
; CHECK-NEXT: firrtl.wire {annotations = [{circt.nonlocal = @[[nlaSym]], class = "circt.test"}]}
|
|
wire b: UInt<1>
|
|
invalidate b
|
|
connect x, b
|
|
module A_ :
|
|
output x: UInt<1>
|
|
wire b: UInt<1>
|
|
invalidate b
|
|
connect x, b
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
|
|
; // -----
|
|
; "The module A and A_ should dedup with the same annotation targets".
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top10"
|
|
FIRRTL version 4.0.0
|
|
circuit Top10 : %[[
|
|
{
|
|
"class":"circt.test",
|
|
"data":"hello",
|
|
"target":"Top10.A.b"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"world",
|
|
"target":"~Top10|A_>b"
|
|
}
|
|
]]
|
|
; CHECK: hw.hierpath private @[[nlaSym2:[_a-zA-Z0-9]+]] [@Top10::@[[a2Sym:[_a-zA-Z0-9]+]], @A]
|
|
; CHECK: hw.hierpath private @[[nlaSym1:[_a-zA-Z0-9]+]] [@Top10::@[[a1Sym:[_a-zA-Z0-9]+]], @A]
|
|
; CHECK: firrtl.module @Top10
|
|
; CHECK-NEXT: firrtl.instance a1 sym @[[a1Sym]] @A(
|
|
; CHECK-NEXT: firrtl.instance a2 sym @[[a2Sym]] @A(
|
|
public module Top10 :
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
; CHECK: module private @A(
|
|
module A :
|
|
output x: UInt<1>
|
|
; CHECK-NEXT: firrtl.wire {annotations = [{circt.nonlocal = @[[nlaSym1]], class = "circt.test", data = "hello"}, {circt.nonlocal = @[[nlaSym2]], class = "circt.test", data = "world"}]}
|
|
wire b: UInt<1>
|
|
invalidate b
|
|
connect x, b
|
|
module A_ :
|
|
output x: UInt<1>
|
|
wire b: UInt<1>
|
|
invalidate b
|
|
connect x, b
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
|
|
; // -----
|
|
; "The deduping module A and A_ should rename internal signals that have
|
|
; different names".
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top11"
|
|
FIRRTL version 4.0.0
|
|
circuit Top11 : %[[
|
|
{
|
|
"class":"circt.test",
|
|
"data":"hello",
|
|
"target":"~Top11|A>a"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"hello",
|
|
"target":"~Top11|A_>b"
|
|
}
|
|
]]
|
|
; CHECK-NOT: hw.hierpath
|
|
; CHECK: hw.hierpath private @[[nlaSym2:[_a-zA-Z0-9]+]] [@Top11::@[[a1sym:[_a-zA-Z0-9]+]], @A]
|
|
; CHECK: hw.hierpath private @[[nlaSym1:[_a-zA-Z0-9]+]] [@Top11::@[[a1Sym]], @A]
|
|
public module Top11 :
|
|
inst a1 of A
|
|
invalidate a1.x
|
|
inst a2 of A_
|
|
invalidate a2.x
|
|
; CHECK: firrtl.module private @A(
|
|
module A :
|
|
input x: UInt<1>
|
|
output y: UInt<1>
|
|
; CHECK: firrtl.node {{.+}} {annotations = [{circt.nonlocal = @[[nlaSym1]], class = "circt.test", data = "hello"}, {circt.nonlocal = @[[nlaSym2]], class = "circt.test", data = "hello"}]}
|
|
node a = add(x, UInt(1))
|
|
connect y, add(a, a)
|
|
module A_ :
|
|
input x: UInt<1>
|
|
output y: UInt<1>
|
|
node b = add(x, UInt(1))
|
|
connect y, add(b, b)
|
|
|
|
; CHECK-NOT: firrtl.module private @A_(
|
|
|
|
; // -----
|
|
; "main should not be deduped even if it's the last module"
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "main"
|
|
FIRRTL version 4.0.0
|
|
circuit main:
|
|
module dupe:
|
|
input in: UInt<8>
|
|
output out: UInt<8>
|
|
connect out, in
|
|
; CHECK: firrtl.module @main
|
|
public module main:
|
|
input in: UInt<8>
|
|
output out: UInt<8>
|
|
connect out, in
|
|
|
|
; // -----
|
|
; "The deduping module A and A_ should rename instances and signals that have different names"
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top12"
|
|
FIRRTL version 4.0.0
|
|
circuit Top12 : %[[
|
|
{
|
|
"class":"circt.test",
|
|
"data":"B",
|
|
"target":"~Top12|Top12/a:A/b:B"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"B.foo",
|
|
"target":"~Top12|Top12/a:A/b:B>foo"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"B_",
|
|
"target":"~Top12|Top12/a_:A_/b_:B_"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"B_.bar",
|
|
"target":"~Top12|Top12/a_:A_/b_:B_>bar"
|
|
}
|
|
]]
|
|
; CHECK: hw.hierpath private @[[nla_a:[_a-zA-Z0-9]+]] [@Top12::@[[aSym:[_a-zA-Z0-9]+]], @A::@[[bSym:[_a-zA-Z0-9]+]], @B]
|
|
; CHECK: hw.hierpath private @[[nla_a_:[_a-zA-Z0-9]+]] [@Top12::@[[a_Sym:[_a-zA-Z0-9]+]], @A::@[[bSym]], @B]
|
|
; CHECK: firrtl.module @Top12
|
|
public module Top12 :
|
|
; CHECK-NEXT: firrtl.instance a sym @[[aSym]] @A()
|
|
inst a of A
|
|
; CHECK-NEXT: firrtl.instance a_ sym @[[a_Sym]] @A()
|
|
inst a_ of A_
|
|
; CHECK: firrtl.module private @A
|
|
module A :
|
|
; CHECK-NEXT: firrtl.instance b sym @[[bSym]]
|
|
; CHECK-SAME: B()
|
|
inst b of B
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
module A_ :
|
|
inst b_ of B_
|
|
; CHECK: firrtl.module private @B
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_a]], class = "circt.test", data = "B"}
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_a_]], class = "circt.test", data = "B_"}
|
|
module B :
|
|
; CHECK: firrtl.node
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_a]], class = "circt.test", data = "B.foo"}
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_a_]], class = "circt.test", data = "B_.bar"}
|
|
node foo = UInt<1>(0)
|
|
; CHECK-NOT: firrtl.module private @B_
|
|
module B_ :
|
|
node bar = UInt<1>(0)
|
|
|
|
; // -----
|
|
;
|
|
; "The deduping module A and A_ should rename nested instances that have
|
|
; different names". The original test used two multi-target annotations where
|
|
; each annotation targets both a module and a reference in the module. This
|
|
; tests approximates this with two annotations with the same class that mimics
|
|
; how a multi-target annotation would be scattered.
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top13"
|
|
FIRRTL version 4.0.0
|
|
circuit Top13 : %[[
|
|
{
|
|
"class":"circt.test",
|
|
"data":"one",
|
|
"target":"~Top13|Top13/a:A/b:B/c:C/d:D"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"one",
|
|
"target":"~Top13|Top13/a:A/b:B/c:C/d:D>foo"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"two",
|
|
"target":"~Top13|Top13/a_:A_/b_:B_/c_:C_/d_:D_"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"two",
|
|
"target":"~Top13|Top13/a_:A_/b_:B_/c_:C_/d_:D_>bar"
|
|
}
|
|
]]
|
|
; CHECK: hw.hierpath private @[[nla_a:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top13::@[[aSym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @A::@[[bSym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @B::@[[cSym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @C::@[[dSym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @D]
|
|
; CHECK-NEXT: hw.hierpath private @[[nla_a_:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top13::@[[a_Sym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @A::@[[bSym]],
|
|
; CHECK-SAME: @B::@[[cSym]],
|
|
; CHECK-SAME: @C::@[[dSym]],
|
|
; CHECK-SAME: @D]
|
|
; CHECK-NEXT: firrtl.module @Top13
|
|
public module Top13 :
|
|
; CHECK-NEXT: firrtl.instance a sym @[[aSym]]
|
|
; CHECK-SAME: @A()
|
|
inst a of A
|
|
; CHECK-NEXT: firrtl.instance a_ sym @[[a_Sym]]
|
|
; CHECK-SAME: @A()
|
|
inst a_ of A_
|
|
|
|
; CHECK: firrtl.module private @A
|
|
module A :
|
|
; CHECK-NEXT: firrtl.instance b sym @[[bSym]]
|
|
; CHECK-SAME: @B()
|
|
inst b of B
|
|
|
|
; CHECK: firrtl.module private @B
|
|
module B :
|
|
; CHECK-NEXT: firrtl.instance c sym @[[cSym]]
|
|
; CHECK-SAME: @C()
|
|
inst c of C
|
|
|
|
; CHECK: firrtl.module private @C
|
|
module C :
|
|
; CHECK-NEXT: firrtl.instance d sym @[[dSym]]
|
|
; CHECK-SAME: @D()
|
|
inst d of D
|
|
|
|
; CHECK: firrtl.module private @D
|
|
module D :
|
|
; CHECK: firrtl.node
|
|
node foo = UInt<1>(0)
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
; CHECK-NOT: firrtl.module private @B_
|
|
; CHECK-NOT: firrtl.module private @C_
|
|
; CHECK-NOT: firrtl.module private @D_
|
|
module A_ :
|
|
inst b_ of B_
|
|
module B_ :
|
|
inst c_ of C_
|
|
module C_ :
|
|
inst d_ of D_
|
|
module D_ :
|
|
node bar = UInt<1>(0)
|
|
|
|
; // -----
|
|
;
|
|
; "Deduping modules with multiple instances should correctly rename
|
|
; instances".
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top14"
|
|
FIRRTL version 4.0.0
|
|
circuit Top14 : %[[
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla1",
|
|
"target":"~Top14|Top14/b:B"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla2",
|
|
"target":"~Top14|Top14/b_:B_"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla3",
|
|
"target":"~Top14|Top14/a1:A/b_:B_"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla4",
|
|
"target":"~Top14|Top14/a2:A/b_:B_"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla5",
|
|
"target":"~Top14|Top14/a1:A/b:B"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla6",
|
|
"target":"~Top14|Top14/a2:A/b:B"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla7",
|
|
"target":"~Top14|Top14/b:B/c:C"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla8",
|
|
"target":"~Top14|Top14/b_:B_/c:C"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla9",
|
|
"target":"~Top14|Top14/a1:A/b_:B_/c:C"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla10",
|
|
"target":"~Top14|Top14/a2:A/b_:B_/c:C"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla11",
|
|
"target":"~Top14|Top14/a1:A/b:B/c:C"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla12",
|
|
"target":"~Top14|Top14/a2:A/b:B/c:C"
|
|
}
|
|
]]
|
|
; CHECK: hw.hierpath private @[[nla_1:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[TopbSym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @B]
|
|
; CHECK: hw.hierpath private @[[nla_2:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topb_Sym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @B]
|
|
; CHECK: hw.hierpath private @[[nla_3:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topa1Sym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @A::@[[Ab_Sym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @B]
|
|
; CHECK: hw.hierpath private @[[nla_4:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topa2Sym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @A::@[[Ab_Sym]],
|
|
; CHECK-SAME: @B]
|
|
; CHECK: hw.hierpath private @[[nla_5:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topa1Sym]],
|
|
; CHECK-SAME: @A::@[[AbSym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @B]
|
|
; CHECK: hw.hierpath private @[[nla_6:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topa2Sym]],
|
|
; CHECK-SAME: @A::@[[AbSym]],
|
|
; CHECK-SAME: @B]
|
|
; CHECK: hw.hierpath private @[[nla_7:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[TopbSym]],
|
|
; CHECK-SAME: @B::@[[BcSym:[_a-zA-Z0-9]+]],
|
|
; CHECK-SAME: @C]
|
|
; CHECK: hw.hierpath private @[[nla_8:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topb_Sym]],
|
|
; CHECK-SAME: @B::@[[BcSym]],
|
|
; CHECK-SAME: @C]
|
|
; CHECK: hw.hierpath private @[[nla_9:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topa1Sym]],
|
|
; CHECK-SAME: @A::@[[Ab_Sym]],
|
|
; CHECK-SAME: @B::@[[BcSym]],
|
|
; CHECK-SAME: @C]
|
|
; CHECK: hw.hierpath private @[[nla_10:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topa2Sym]],
|
|
; CHECK-SAME: @A::@[[Ab_Sym]],
|
|
; CHECK-SAME: @B::@[[BcSym]],
|
|
; CHECK-SAME: @C]
|
|
; CHECK: hw.hierpath private @[[nla_11:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topa1Sym]],
|
|
; CHECK-SAME: @A::@[[AbSym]],
|
|
; CHECK-SAME: @B::@[[BcSym]],
|
|
; CHECK-SAME: @C]
|
|
; CHECK: hw.hierpath private @[[nla_12:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top14::@[[Topa2Sym]],
|
|
; CHECK-SAME: @A::@[[AbSym]],
|
|
; CHECK-SAME: @B::@[[BcSym]],
|
|
; CHECK-SAME: @C]
|
|
; CHECK-NEXT: firrtl.module @Top14
|
|
public module Top14 :
|
|
; CHECK-NEXT: firrtl.instance b sym @[[TopbSym]]
|
|
; CHECK-SAME: @B()
|
|
inst b of B
|
|
; CHECK-NEXT: firrtl.instance b_ sym @[[TopbSym]]
|
|
; CHECK-SAME: @B()
|
|
inst b_ of B_
|
|
; CHECK-NEXT: firrtl.instance a1 sym @[[Topa1Sym]]
|
|
; CHECK-SAME: @A()
|
|
inst a1 of A
|
|
; CHECK-NEXT: firrtl.instance a2 sym @[[Topa2Sym]]
|
|
; CHECK-SAME: @A()
|
|
inst a2 of A
|
|
|
|
; CHECK: firrtl.module private @A()
|
|
module A :
|
|
; CHECK-NEXT: firrtl.instance b sym @[[AbSym]]
|
|
; CHECK-SAME: @B()
|
|
inst b of B
|
|
; CHECK-NEXT: firrtl.instance b_ sym @[[Ab_Sym]]
|
|
; CHECK-SAME: @B()
|
|
inst b_ of B_
|
|
|
|
; CHECK: firrtl.module private @B()
|
|
; CHECK-SAME: [{circt.nonlocal = @[[nla_1]], class = "circt.test", data = "nla1"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_5]], class = "circt.test", data = "nla5"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_6]], class = "circt.test", data = "nla6"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_2]], class = "circt.test", data = "nla2"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_3]], class = "circt.test", data = "nla3"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_4]], class = "circt.test", data = "nla4"}]
|
|
module B :
|
|
; CHECK-NEXT: firrtl.instance c sym @[[BcSym]]
|
|
; CHECK-SAME: @C()
|
|
inst c of C
|
|
|
|
; CHECK: firrtl.module private @C()
|
|
; CHECK-SAME: [{circt.nonlocal = @[[nla_7]], class = "circt.test", data = "nla7"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_8]], class = "circt.test", data = "nla8"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_9]], class = "circt.test", data = "nla9"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_10]], class = "circt.test", data = "nla10"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_11]], class = "circt.test", data = "nla11"},
|
|
; CHECK-SAME: {circt.nonlocal = @[[nla_12]], class = "circt.test", data = "nla12"}]
|
|
module C :
|
|
skip
|
|
|
|
; CHECK-NOT: firrtl.module private @B_()
|
|
module B_ :
|
|
inst c of C
|
|
|
|
; // -----
|
|
;
|
|
; "dedup should properly rename target components after retyping". This test is
|
|
; checking for a possible deduplication bug where there is a string name
|
|
; collision of the field of a merged aggregate. This test is very specific to
|
|
; the implementation of the Scala FIRRTL Compiler's rename map (which relies on
|
|
; strings) and is unlikely to occur in CIRCT due to the use of field IDs.
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top15"
|
|
FIRRTL version 4.0.0
|
|
circuit Top15 : %[[
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla1",
|
|
"target":"~Top15|a>i.a"
|
|
},
|
|
{
|
|
"class":"circt.test",
|
|
"data":"nla2",
|
|
"target":"~Top15|b>q.a"
|
|
}
|
|
]]
|
|
; CHECK: hw.hierpath private @[[nla_2:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top15::@[[topbSym:[_a-zA-Z0-9]+]], @a]
|
|
; CHECK: hw.hierpath private @[[nla_1:[_a-zA-Z0-9]+]]
|
|
; CHECK-SAME: [@Top15::@[[topaSym:[_a-zA-Z0-9]+]], @a]
|
|
; CHECK: firrtl.module @Top15
|
|
public module Top15:
|
|
input ia: {z: {y: {x: UInt<1>}}, a: UInt<1>, un: UInt<2>}
|
|
input ib: {a: {b: {c: UInt<1>}}, z: UInt<1>, un: UInt<2>}
|
|
output oa: {z: {y: {x: UInt<1>}}, a: UInt<1>, un: UInt<2>}
|
|
output ob: {a: {b: {c: UInt<1>}}, z: UInt<1>, un: UInt<2>}
|
|
; CHECK: firrtl.instance a sym @[[topaSym]]
|
|
inst a of a
|
|
connect a.i.z.y.x, ia.z.y.x
|
|
connect a.i.a, ia.a
|
|
connect a.i.un, ia.un
|
|
connect oa.z.y.x, a.o.z.y.x
|
|
connect oa.a, a.o.a
|
|
connect oa.un, a.o.un
|
|
|
|
; CHECK: firrtl.instance b sym @[[topbSym]]
|
|
inst b of b
|
|
connect b.q.un.b.c, ib.a.b.c
|
|
connect b.q.z, ib.z
|
|
connect b.q.a, ib.un
|
|
connect ob.a.b.c, b.r.un.b.c
|
|
connect ob.z, b.r.z
|
|
connect ob.un, b.r.a
|
|
|
|
; CHECK: firrtl.module private @a(
|
|
; CHECK-SAME: in %i:
|
|
; CHECK-NOT: out
|
|
; CHECK-SAME: [{circt.fieldID = 4 : i32, circt.nonlocal = @[[nla_1]], class = "circt.test", data = "nla1"},
|
|
; CHECK-SAME: {circt.fieldID = 5 : i32, circt.nonlocal = @[[nla_2]], class = "circt.test", data = "nla2"}]
|
|
module a:
|
|
input i: {z: {y: {x: UInt<1>}}, a: UInt<1>, un: UInt<2>}
|
|
output o: {z: {y: {x: UInt<1>}}, a: UInt<1>, un: UInt<2>}
|
|
connect o, i
|
|
|
|
; CHECK-NOT: firrtl.module private @b(
|
|
module b:
|
|
input q: {un: {b: {c: UInt<1>}}, z: UInt<1>, a: UInt<2>}
|
|
output r: {un: {b: {c: UInt<1>}}, z: UInt<1>, a: UInt<2>}
|
|
connect r, q
|
|
|
|
; // -----
|
|
; "The module A and A_ should be deduped even with different port names and info,
|
|
; and annotations should be remapped".
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top16"
|
|
FIRRTL version 4.0.0
|
|
circuit Top16 : %[[
|
|
{
|
|
"class": "circt.test",
|
|
"target": "Top16.Top16.a2.y",
|
|
"pin": "pin"
|
|
}
|
|
]]
|
|
; CHECK: firrtl.module @Top16
|
|
public module Top16 :
|
|
output out: UInt<1>
|
|
; CHECK: instance a1 @A(
|
|
; CHECK-NOT: SourceAnnotation
|
|
; CHECK: instance a2 {{.+}} @A(
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
connect out, and(a1.x, a2.y)
|
|
; CHECK: module private @A
|
|
; CHECK-SAME: [{circt.nonlocal = {{[^,]+}}, class = "circt.test", pin = "pin"}]
|
|
module A : @[yy 2:2]
|
|
output x: UInt<1> @[yy 2:2]
|
|
connect x, UInt(1)
|
|
module A_ : @[xx 1:1]
|
|
output y: UInt<1> @[xx 1:1]
|
|
connect y, UInt(1)
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
|
|
|
|
; // -----
|
|
; "The module A and A_ should dedup with different annotation targets."
|
|
;
|
|
; This test is checking that a "DontTouchAnnotation" has the same behavior as
|
|
; any other annotation due to deduplication.
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top17"
|
|
FIRRTL version 4.0.0
|
|
circuit Top17 : %[[
|
|
{
|
|
"class":"firrtl.transforms.DontTouchAnnotation",
|
|
"target":"~Top17|Top17/a1:A>b"
|
|
}
|
|
]]
|
|
; CHECK: firrtl.module @Top17
|
|
; CHECK-NEXT: firrtl.instance a1 @A(
|
|
; CHECK-NEXT: firrtl.instance a2 @A(
|
|
public module Top17 :
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
; CHECK: module private @A(
|
|
module A :
|
|
output x: UInt<1>
|
|
; CHECK-NEXT: firrtl.wire {annotations = [{class = "firrtl.transforms.DontTouchAnnotation"}]}
|
|
wire b: UInt<1>
|
|
invalidate b
|
|
connect x, b
|
|
module A_ :
|
|
output x: UInt<1>
|
|
wire b: UInt<1>
|
|
invalidate b
|
|
connect x, b
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|
|
|
|
; // -----
|
|
; "The module A and A_ should dedup with the same annotation targets."
|
|
;
|
|
; This is the same situation as the previous test, except that two
|
|
; "DontTouchAnnotation"s apply to the same deduplicated wire. It is arguable
|
|
; that generating a symbol here is fine. However, this is different from the
|
|
; Scala FIRRTL Compiler and we should make a decision on what to do with this.
|
|
;
|
|
; CHECK-LABEL: firrtl.circuit "Top18"
|
|
FIRRTL version 4.0.0
|
|
circuit Top18 : %[[
|
|
{
|
|
"class":"firrtl.transforms.DontTouchAnnotation",
|
|
"target":"Top18.A.b"
|
|
},
|
|
{
|
|
"class":"firrtl.transforms.DontTouchAnnotation",
|
|
"target":"~Top18|A_>b"
|
|
}
|
|
]]
|
|
; CHECK: firrtl.module @Top18
|
|
; CHECK-NEXT: firrtl.instance a1 @A(
|
|
; CHECK-NEXT: firrtl.instance a2 @A(
|
|
public module Top18 :
|
|
inst a1 of A
|
|
inst a2 of A_
|
|
; CHECK: module private @A(
|
|
module A :
|
|
output x: UInt<1>
|
|
; CHECK: firrtl.wire
|
|
; CHECK-SAME: [{class = "firrtl.transforms.DontTouchAnnotation"}]
|
|
wire b: UInt<1>
|
|
invalidate b
|
|
connect x, b
|
|
module A_ :
|
|
output x: UInt<1>
|
|
wire b: UInt<1>
|
|
invalidate b
|
|
connect x, b
|
|
|
|
; CHECK-NOT: firrtl.module private @A_
|