1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
// SPDX-License-Identifier: Apache-2.0
package firrtlTests
import java.io._
import firrtl._
import firrtl.ir.Circuit
import firrtl.passes._
import firrtl.testutils._
import clocklist._
class ClockListTests extends FirrtlFlatSpec {
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)
}
}
def passes = Seq(
ToWorkingIR,
ResolveKinds,
InferTypes,
ResolveFlows,
new InferWidths
)
"Getting clock list" should "work" in {
val input =
"""circuit Top :
| module Top :
| input clock: Clock
| inst ht of HTop
| ht.clock <= clock
| module HTop :
| input clock: Clock
| inst h of Hurricane
| h.clkTop <= clock
| h.clock <= h.clk1
| module Hurricane :
| input clock: Clock
| input clkTop: Clock
| output clk1: Clock
| inst b of B
| inst c of C
| inst clkGen of ClockGen
| clkGen.clkTop <= clkTop
| clk1 <= clkGen.clk1
| b.clock <= clkGen.clk2
| c.clock <= clkGen.clk3
| module B :
| input clock: Clock
| reg r: UInt<5>, clock
| inst d of D
| d.clock <= clock
| module C :
| input clock: Clock
| reg r: UInt<5>, clock
| module D :
| input clock: Clock
| reg r: UInt<5>, clock
| extmodule ClockGen :
| input clkTop: Clock
| output clk1: Clock
| output clk2: Clock
| output clk3: Clock
|""".stripMargin
val check =
"""Sourcelist: List(h$clkGen$clk1, h$clkGen$clk2, h$clkGen$clk3, clock)
|Good Origin of clock is clock
|Good Origin of h.clock is h$clkGen.clk1
|Good Origin of h$b.clock is h$clkGen.clk2
|Good Origin of h$c.clock is h$clkGen.clk3
|""".stripMargin
val c = passes
.foldLeft(CircuitState(parse(input), UnknownForm)) { (c: CircuitState, p: Transform) =>
p.runTransform(c)
}
.circuit
val writer = new StringWriter()
val retC = new ClockList("HTop", writer).run(c)
(writer.toString) should be(check)
}
"A->B->C, and A.clock == C.clock" should "still emit C.clock origin" in {
val input =
"""circuit A :
| module A :
| input clock: Clock
| input clkB: Clock
| inst b of B
| b.clock <= clkB
| b.clkC <= clock
| module B :
| input clock: Clock
| input clkC: Clock
| inst c of C
| c.clock <= clkC
| module C :
| input clock: Clock
| reg r: UInt<5>, clock
|""".stripMargin
val check =
"""Sourcelist: List(clock, clkB)
|Good Origin of clock is clock
|Good Origin of b.clock is clkB
|Good Origin of b$c.clock is clock
|""".stripMargin
val c = passes
.foldLeft(CircuitState(parse(input), UnknownForm)) { (c: CircuitState, p: Transform) =>
p.runTransform(c)
}
.circuit
val writer = new StringWriter()
val retC = new ClockList("A", writer).run(c)
(writer.toString) should be(check)
}
"Have not circuit main be top of clocklist pass" should "still work" in {
val input =
"""circuit A :
| module A :
| input clock: Clock
| input clkB: Clock
| inst b of B
| inst d of D
| b.clock <= clkB
| b.clkC <= clock
| module B :
| input clock: Clock
| input clkC: Clock
| inst c of C
| c.clock <= clkC
| module C :
| input clock: Clock
| reg r: UInt<5>, clock
| extmodule D :
| input clock: Clock
|""".stripMargin
val check =
"""Sourcelist: List(clock, clkC)
|Good Origin of clock is clock
|Good Origin of c.clock is clkC
|""".stripMargin
val c = passes
.foldLeft(CircuitState(parse(input), UnknownForm)) { (c: CircuitState, p: Transform) =>
p.runTransform(c)
}
.circuit
val writer = new StringWriter()
val retC = new ClockList("B", writer).run(c)
(writer.toString) should be(check)
}
}
|