Skip to content

Commit 3462701

Browse files
authored
Merge pull request #2 from rameloni/tywaves-code-cleanup
Tywaves code cleanup and simplify some functions
2 parents cd76154 + 0685784 commit 3462701

File tree

16 files changed

+830
-167
lines changed

16 files changed

+830
-167
lines changed

build.sbt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ lazy val root = (project in file("."))
1818
addCompilerPlugin(
1919
"org.chipsalliance" % "chisel-plugin" % chiselVersion cross CrossVersion.full
2020
),
21-
libraryDependencies += "org.chipsalliance" %% "chisel" % chiselVersion,
22-
libraryDependencies += "org.scalatest" %% "scalatest" % scalatestVersion % "test",
23-
libraryDependencies += "io.circe" %% "circe-core" % circeVersion,
24-
libraryDependencies += "io.circe" %% "circe-generic" % circeVersion,
25-
libraryDependencies += "io.circe" %% "circe-parser" % circeVersion,
21+
libraryDependencies += "org.chipsalliance" %% "chisel" % chiselVersion,
22+
libraryDependencies += "org.scalatest" %% "scalatest" % scalatestVersion % "test",
23+
libraryDependencies += "io.circe" %% "circe-core" % circeVersion,
24+
libraryDependencies += "io.circe" %% "circe-generic" % circeVersion,
25+
libraryDependencies += "io.circe" %% "circe-generic-extras" % "0.14.3",
26+
libraryDependencies += "io.circe" %% "circe-parser" % circeVersion,
2627

2728
// libraryDependencies += "nl.tudelft" %% "root" % "0.1.0",
2829
libraryDependencies += "edu.berkeley.cs" %% "chiseltest" % "6.0.0",

src/main/chisel3/tywaves/circuitparser/ChiselIRParser.scala

Lines changed: 79 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import chisel3.experimental.{NoSourceInfo, SourceInfo, SourceLine}
44
import chisel3.internal.firrtl.{ir => chiselIR}
55
import chisel3.{Aggregate, Bundle, Data, Vec}
66
import tywaves.utils.UniqueHashMap
7-
import tywaves.circuitmapper.{ElId, Name, Direction, Type, HardwareType}
7+
import tywaves.circuitmapper.{Direction, ElId, HardwareType, Name, Type, tywaves_symbol_table}
88

99
class ChiselIRParser
1010
extends CircuitParser[chiselIR.Circuit, chiselIR.Component, chiselIR.Port, Aggregate, Data, chiselIR.Command] {
@@ -14,6 +14,9 @@ class ChiselIRParser
1414
override lazy val flattenedPorts = new UniqueHashMap[ElId, (Name, Direction, HardwareType, Type)]()
1515
override lazy val allElements = new UniqueHashMap[ElId, (Name, Direction, Type)]()
1616

17+
private var _tywavesState = tywaves_symbol_table.TywaveState(Seq.empty)
18+
def tywaveState: tywaves_symbol_table.TywaveState = _tywavesState
19+
1720
/** Parse a whole [[chiselIR.Circuit]] */
1821
override def parseCircuit(circuitChiselIR: chiselIR.Circuit): Unit =
1922
circuitChiselIR.components.foreach(parseModule) // each component is a module
@@ -24,14 +27,16 @@ class ChiselIRParser
2427
val name = chiselComponent.name
2528
val elId = this.createId(SourceLine(name, 0, 0), Some(name))
2629

27-
modules.put(elId, (Name(name, "root"), chiselComponent)) // Add the module and its name
30+
modules.put(elId, (Name(name, "root", "root"), chiselComponent)) // Add the module and its name
31+
_tywavesState.scopes = _tywavesState.scopes :+
32+
tywaves_symbol_table.Scope(name, Seq.empty, Seq.empty)
2833

2934
// Parse the internals of the module
3035
chiselComponent match {
31-
case chiselIR.DefModule(_, _, ports, body) =>
32-
ports.foreach(parsePort(name, _))
36+
case chiselIR.DefModule(_, moduleName, ports, body) =>
37+
ports.foreach(parsePort(name, _, moduleName))
3338
// TODO: Parse the body:
34-
body.foreach(parseBodyStatement(name, _))
39+
body.foreach(parseBodyStatement(name, _, moduleName))
3540
case chiselIR.DefBlackBox(_, name, ports, topDir, params) =>
3641
println(s"DefBlackBox: name: $name, ports: $ports, topDir: $topDir, params: $params")
3742

@@ -51,7 +56,7 @@ class ChiselIRParser
5156
* })
5257
* }}}
5358
*/
54-
override def parsePort(scope: String, port: chiselIR.Port): Unit = {
59+
override def parsePort(scope: String, port: chiselIR.Port, parentModule: String): Unit = {
5560
val portData: Data = port.id
5661

5762
// Parse generic info and create an ID for the port
@@ -60,16 +65,34 @@ class ChiselIRParser
6065

6166
ports.put(
6267
elId,
63-
(Name(name, scope), Direction(dir.toString), Type(portData.typeName) /*, port*/ ),// Fixme: type name
64-
) // Add the port and its name
68+
(
69+
Name(name, scope, parentModule),
70+
Direction(dir.toString),
71+
Type(portData.typeName), /*, port*/
72+
), // Fixme: type name
73+
) // Add the port and its name
6574

6675
// Types from here: https://github.com/chipsalliance/chisel?tab=readme-ov-file#data-types-overview
6776
portData match {
6877
case agg: Aggregate =>
6978
// TODO: check this
7079
println(s"AggregateType: $agg")
71-
parseAggregate(elId, Name(name, scope), Direction(dir.toString), HardwareType("Port"), agg)
72-
case _ => parseElement(elId, Name(name, scope), Direction(dir.toString), HardwareType("Port"), portData)
80+
parseAggregate(
81+
elId,
82+
Name(name, scope, parentModule),
83+
Direction(dir.toString),
84+
HardwareType("Port", None),
85+
agg,
86+
parentModule,
87+
)
88+
case _ => parseElement(
89+
elId,
90+
Name(name, scope, parentModule),
91+
Direction(dir.toString),
92+
HardwareType("Port", None),
93+
portData,
94+
parentModule,
95+
)
7396
}
7497
}
7598

@@ -83,24 +106,34 @@ class ChiselIRParser
83106
* types.
84107
*/
85108
override def parseAggregate(
86-
elId: ElId,
87-
name: Name,
88-
dir: Direction,
89-
hwType: HardwareType,
90-
aggrType: Aggregate,
109+
elId: ElId,
110+
name: Name,
111+
dir: Direction,
112+
hwType: HardwareType,
113+
aggrType: Aggregate,
114+
parentModule: String,
91115
): Unit = {
92116

93-
super.parseAggregate(elId, name, dir, hwType, aggrType)
117+
super.parseAggregate(elId, name, dir, hwType, aggrType, parentModule)
94118

95119
aggrType match {
96120
case b: Bundle =>
97121
b.elements.foreach { case (fieldName, dataType) =>
98-
parseElement(elId, Name(fieldName, name.name), dir, hwType, dataType)
122+
parseElement(elId, Name(fieldName, name.name, parentModule), dir, hwType, dataType, parentModule)
99123
println(s"AggregateType: $aggrType, dir: $dir, hwType: $hwType, name: $name")
124+
125+
val variable = tywaves_symbol_table.Variable(
126+
name.name,
127+
dataType.typeName,
128+
tywaves_symbol_table.hwtype.from_string(hwType.name, Some(dir.name)),
129+
tywaves_symbol_table.realtype.Bundle(Seq.empty, None),
130+
)
131+
_tywavesState.scopes = _tywavesState.scopes :+
132+
tywaves_symbol_table.Scope(fieldName, Seq.empty, Seq.empty)
100133
}
101134
case v: Vec[Data] =>
102135
for (i <- 0 until v.length) {
103-
parseElement(elId, Name(name.name + "[" + i + "]", name.scope), dir, hwType, v(i))
136+
parseElement(elId, Name(name.name + "[" + i + "]", name.scope, parentModule), dir, hwType, v(i), parentModule)
104137
}
105138

106139
}
@@ -112,31 +145,43 @@ class ChiselIRParser
112145
*
113146
* This function handles special cases of aggregate types.
114147
*/
115-
def parseElement(elId: ElId, name: Name, dir: Direction, hwType: HardwareType, dataType: Data): Unit =
148+
def parseElement(
149+
elId: ElId,
150+
name: Name,
151+
dir: Direction,
152+
hwType: HardwareType,
153+
dataType: Data,
154+
parentModule: String,
155+
): Unit =
116156
dataType match {
117-
case aggr: Bundle => parseAggregate(elId, name, dir, hwType, aggr)
118-
case aggr: Vec[Data] => parseAggregate(elId, name, dir, hwType, aggr) // TODO: Implement
157+
case aggr: Bundle => parseAggregate(elId, name, dir, hwType, aggr, parentModule)
158+
case aggr: Vec[Data] => parseAggregate(elId, name, dir, hwType, aggr, parentModule) // TODO: Implement
119159
case _ =>
120160
// TODO: other cases need to be implemented. For now, simply add the element to the map
121-
if (hwType == HardwareType("Port"))
161+
if (hwType == HardwareType("Port", Some(dataType.getWidth)))
122162
flattenedPorts.put(elId.addName(name.name), (name, dir, hwType, Type(dataType.typeName)))
123163
allElements.put(elId.addName(name.name), (name, dir, Type(dataType.typeName)))
124164
case _ => throw new Exception(s"Failed to parse type $dataType. Unknown type.")
125165
}
126166
// ??? // TODO: Implement for Data types
127167

128168
/** Parse a [[chiselIR.Command]]. In FIRRTL, commands are Statements */
129-
override def parseBodyStatement(scope: String, body: chiselIR.Command): Unit = {
169+
override def parseBodyStatement(scope: String, body: chiselIR.Command, parentModule: String): Unit = {
130170
val parseRes = body match {
131-
case chiselIR.DefWire(sourceInfo, dataType) => Some((sourceInfo, dataType, HardwareType("Wire")))
132-
case chiselIR.DefReg(sourceInfo, dataType, _) => Some((sourceInfo, dataType, HardwareType("Register")))
133-
case chiselIR.DefRegInit(sourceInfo, dataType, _, _, _) => Some((sourceInfo, dataType, HardwareType("Register")))
134-
135-
case _: chiselIR.Connect => Console.err.println("ChiselIRParser: Parsing Connect. Skip."); None
136-
case _: chiselIR.DefPrim[?] => Console.err.println("ChiselIRParser: Parsing DefPrim. Skip."); None
137-
case _: chiselIR.WhenBegin => Console.err.println("ChiselIRParser: Parsing WhenBegin. Skip."); None
138-
case _: chiselIR.WhenEnd => Console.err.println("ChiselIRParser: Parsing WhenEnd. Skip."); None
139-
case _: chiselIR.Printf => Console.err.println("ChiselIRParser: Parsing Printf. Skip."); None
171+
case chiselIR.DefWire(sourceInfo, dataType) =>
172+
Some((sourceInfo, dataType, HardwareType("Wire", Some(dataType.getWidth))))
173+
case chiselIR.DefReg(sourceInfo, dataType, _) =>
174+
Some((sourceInfo, dataType, HardwareType("Register", Some(dataType.getWidth))))
175+
case chiselIR.DefRegInit(sourceInfo, dataType, _, _, _) =>
176+
Some((sourceInfo, dataType, HardwareType("Register", Some(dataType.getWidth))))
177+
178+
case _: chiselIR.Connect => Console.err.println("ChiselIRParser: Parsing Connect. Skip."); None
179+
case _: chiselIR.DefPrim[?] => Console.err.println("ChiselIRParser: Parsing DefPrim. Skip."); None
180+
case _: chiselIR.WhenBegin => Console.err.println("ChiselIRParser: Parsing WhenBegin. Skip."); None
181+
case _: chiselIR.WhenEnd => Console.err.println("ChiselIRParser: Parsing WhenEnd. Skip."); None
182+
case _: chiselIR.Printf => Console.err.println("ChiselIRParser: Parsing Printf. Skip."); None
183+
case _: chiselIR.AltBegin => Console.err.println("ChiselIRParser: Parsing AltBegin. Skip."); None
184+
case _: chiselIR.OtherwiseEnd => Console.err.println("ChiselIRParser: Parsing OtherwiseEnd. Skip."); None
140185
case a =>
141186
println(s"a a a: $a")
142187
None
@@ -146,10 +191,11 @@ class ChiselIRParser
146191
case Some((sourceInfo, dataType, hwType)) =>
147192
parseElement(
148193
createId(sourceInfo),
149-
Name(dataType.toNamed.name, scope),
194+
Name(dataType.toNamed.name, scope, parentModule),
150195
Direction(dataType.direction.toString),
151196
hwType,
152197
dataType,
198+
parentModule,
153199
)
154200
case None => // Skip
155201
}

src/main/chisel3/tywaves/circuitparser/CircuitParser.scala

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,60 @@ trait CircuitParser[T, ModuleT, PortT, AggregateT, ElementT, BodyStatementT] {
1212

1313
def parseCircuit(circuit: T): Unit
1414
def parseModule(module: ModuleT): Unit
15-
def parsePort(scope: String, port: PortT): Unit
16-
def parseAggregate(elId: ElId, name: Name, dir: Direction, hwType: HardwareType, agg: AggregateT): Unit = {
17-
if (hwType == HardwareType("Port"))
18-
flattenedPorts.put(elId.addName(name.name), (name, dir, hwType, Type(agg.getClass.getName)))
19-
allElements.put(elId.addName(name.name), (name, dir, Type(agg.getClass.getName)))
15+
def parsePort(scope: String, port: PortT, parentModule: String): Unit
16+
17+
def getWidth(agg: AggregateT): Int = {
18+
val widthPattern = "<(\\d+)>".r
19+
agg match {
20+
case fir: firrtl.ir.AggregateType =>
21+
fir match {
22+
case firrtl.ir.BundleType(fields) => fields.map(f =>
23+
f.tpe match {
24+
case firrtl.ir.GroundType(width) => width.serialize match {
25+
case widthPattern(width) => width.toInt
26+
}
27+
case _: firrtl.ir.AggregateType => this.getWidth(f.tpe.asInstanceOf[AggregateT])
28+
}
29+
// extract the number <width> from the GroundType
30+
).sum
31+
}
32+
33+
case chisel: chisel3.Record => chisel.getWidth
34+
case aggr: chisel3.Aggregate => aggr.getWidth
35+
}
36+
}
37+
38+
def parseAggregate(
39+
elId: ElId,
40+
name: Name,
41+
dir: Direction,
42+
hwType: HardwareType,
43+
agg: AggregateT,
44+
parentModule: String,
45+
): Unit = {
46+
val aggString = agg match {
47+
case fir: firrtl.ir.AggregateType => fir.getClass.getName
48+
case chisel: chisel3.Record => chisel.className
49+
case aggr: chisel3.Aggregate => aggr.typeName
50+
}
51+
if (hwType == HardwareType("Port", Some(this.getWidth(agg))))
52+
flattenedPorts.put(
53+
elId.addName(name.name),
54+
(name.addTywaveScope(parentModule), dir, hwType, Type(aggString)),
55+
)
56+
57+
allElements.put(elId.addName(name.name), (name.addTywaveScope(parentModule), dir, Type(aggString)))
2058
}
2159

22-
def parseElement(elId: ElId, name: Name, dir: Direction, hwType: HardwareType, element: ElementT): Unit
23-
def parseBodyStatement(scope: String, body: BodyStatementT): Unit
60+
def parseElement(
61+
elId: ElId,
62+
name: Name,
63+
dir: Direction,
64+
hwType: HardwareType,
65+
element: ElementT,
66+
parentModule: String,
67+
): Unit
68+
def parseBodyStatement(scope: String, body: BodyStatementT, parentModule: String): Unit
2469

2570
def dumpMaps(fileDump: String): Unit = {
2671
modules.dumpFile(fileDump, "Modules:", append = false)

0 commit comments

Comments
 (0)