Skip to content

Commit e710e61

Browse files
committed
Add drawbacks
1 parent 449bfb6 commit e710e61

File tree

2 files changed

+89
-43
lines changed

2 files changed

+89
-43
lines changed

README.md

Lines changed: 77 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,26 @@
22

33
Demo backend of the Tywaves project: a type based waveform viewer for Chisel
44
and [Tydi-Chisel](https://github.com/abs-tudelft/Tydi-Chisel) circuits.
5+
56
This repo contains functions that parse the information of a Chisel circuit and the debug info emitted by the firtool
6-
compiler, simulate a circuit using ChiselSim and combine all the information to the
7-
[surfer-tywaves-demo](https://gitlab.com/rameloni/surfer-tywaves-demo) frontend (an extension of the Surfer waveform
8-
viewer written in Rust to support Chisel constructs).
7+
compiler, simulate a circuit using ChiselSim and combine all the information and pass them to the
8+
[surfer-tywaves-demo](https://gitlab.com/rameloni/surfer-tywaves-demo) frontend for visualization (an extension of the
9+
Surfer waveform viewer written in Rust to support Chisel constructs).
910

1011
Since it is a demo project, it has been tested and developed for a restricted set of examples (it may not work with
1112
all circuits). In the [features](#features) section, you can find the already supported features.
13+
This demo served only as an example to show how the waveform viewer can potentially look like and **for initial feedback
14+
and suggestions from the community**.
15+
16+
> If you are interested in using the tool and have any feedback on its implementation, please open an issue or contact
17+
> me.
1218
1319
Starting from this demo project, a better implementation and integration in the Chisel/Firrtl infrastructure will be
14-
developed that aims to address the issues
15-
discovered [here](https://github.com/rameloni/Tydi-Chisel-testing-frameworks-analysis).
20+
developed with the aim of solving the issues
21+
addressed [here](https://github.com/rameloni/Tydi-Chisel-testing-frameworks-analysis).
1622

17-
> Do not use Verilog / System Verilog reserved keywords in Chisel circuit (i.e. `wire`, `reg`).
23+
24+
> Do not use Verilog / System Verilog reserved keywords in your Chisel circuit (i.e. `wire`, `reg`).
1825
> In that case, `firtool` will change the `var_name` (which should be `wire`) field of the emitted HGLDD to get a legal
1926
> name as explained in the comments
2027
> [here](https://github.com/llvm/circt/blob/37fbe5e5f5c7a07064d02cea8bf4e8454178fc0e/lib/Target/DebugInfo/EmitHGLDD.cpp#L163C1-L175C2).
@@ -67,7 +74,7 @@ libraryDependencies += "com.github.rameloni" %% "tywaves-demo-backend" % "0.1.0-
6774

6875
The `TywavesBackend` provides 2 simulators with functionalities to simulate a circuit
6976
through [svsim](https://github.com/chipsalliance/chisel/tree/main/svsim), emit VCD
70-
traces and of course generate the symbol table for the waveform viewer itself automatically:
77+
traces and generate the symbol table for the surfer-tywaves waveform viewer itself automatically:
7178

7279
- [ParametricSimulator](./src/main/scala/tywaves/simulator/ParametricSimulator.scala): provides some generic features
7380
such as VCD trace emission, name the trace file, pass additional arguments to firtool before simulation, save the
@@ -76,10 +83,10 @@ traces and of course generate the symbol table for the waveform viewer itself au
7683
order to generate the symbol table for Tywaves waveform viewer and provides an option to launch the waveform viewer
7784
after the simulation
7885

79-
> While `TywavesSimulator` is central part of the Tywaves project and its functionalities are not fully supported
80-
> yet, `ParametricSimulator` is
81-
> should be able to simulate any Chisel circuit. In case you need to simulate a circuit that is not supported
82-
> by `TywavesSimulator`, you can use `ParametricSimulator`.
86+
> While `TywavesSimulator` is a central part of the Tywaves project and its functionalities are not fully supported
87+
> yet, the `ParametricSimulator` is able to simulate any Chisel circuit. In case you need to simulate a circuit that is
88+
> not supported by `TywavesSimulator`, you can use `ParametricSimulator` to emit a VCD trace (however, you will not have
89+
> a "chisel" representation of the signals in the waveform viewer).
8390
>
8491
> If you want to try the functionalities of `Tywaves` then `TywavesSimulator` is the right choice.
8592
> But, if you want to visualize waveforms of any chisel circuit without issues related to features not supported yet,
@@ -92,6 +99,7 @@ The following example shows how it is possible also to:
9299
workspace of svsim)
93100
- Launch the waveform viewer after the simulation
94101
- Use tywaves and expect API to test the circuit
102+
95103
### Use TywavesSimulator
96104

97105
```scala
@@ -119,6 +127,7 @@ class GCDTest extends AnyFunSpec with Matchers {
119127
```
120128

121129
### Use ParametricSimulator
130+
122131
```scala
123132
import tywaves.simulator.ParametricSimulator._
124133
import tywaves.simulator.simulatorSettings._
@@ -145,7 +154,8 @@ class GCDTest extends AnyFunSpec with Matchers {
145154

146155
# Example output
147156

148-
The following images show the classic and tywaves waveform visualization of the [GCD](./src/test/scala/gcd/GCD.scala) module.
157+
The following images show the classic and tywaves waveform visualization of the [GCD](./src/test/scala/gcd/GCD.scala)
158+
module.
149159
It is possible to see that the left picture does not provide any information about Chisel level types and hierarchy.
150160

151161
```scala
@@ -185,6 +195,9 @@ class GCD extends Module {
185195
- [ ] Represent vectors
186196
- [ ] Represent enums
187197
- [ ] Represent hierarchical modules
198+
- [x] Generic submodules (all different types of modules)
199+
- [x] Variants of the same module (i.e. parametric module)
200+
- [ ] Instances of the same module
188201
- [ ] For loops code generation
189202
- [ ] Reg with init
190203

@@ -193,14 +206,26 @@ class GCD extends Module {
193206
The following diagram shows the main components of the demo project and how they interact with each other.
194207
![Tywaves backend diagram](./images/tywaves-backend-diagram.png)
195208

196-
It retrieves, parses and finally maps together the Intermediate Representation (IR) of the Chisel, Firrtl and debug info
197-
emitted by the firtool (HGLDD) to output a symbol table that can be used by the frontend to display the waveform.
198-
It aims to map each high level signal (Chisel) to the low level signal (System Verilog) and vice versa. Usually, HGLDD
199-
would be enough, but it does provide only information about FIRRTL-to-SystemVerilog mapping, so it does not contain user
200-
types information.
209+
This backend retrieves, parses and finally maps together the Intermediate Representations (IR) of the Chisel, Firrtl and
210+
debug info emitted by the firtool (HGLDD) to output a symbol table that can be used by the frontend to display the
211+
waveform.
212+
It aims to map each high level signal (Chisel) to the low level signal (in System Verilog and in the VCD/FST trace) and
213+
vice versa. In this way it would be possible to access a variable/signal value from any waveform viewer able to support
214+
a **multi-level typed** view. For this demo I managed to do so by:
215+
216+
- parsing Chisel IR, Firrtl IR, and the HGLDD (debug info emitted by firtool to link verilog and firrtl)
217+
- retrieving and joining signals together by identifying IDs (shared between IRs) based on signal names and source
218+
locators
219+
- emitting the symbol table suited for the waveform viewer
220+
221+
However, this approach has some issues associated with the IRs parsing and mapping. The [drawbacks](#drawbacks) section
222+
explains them and suggests a solution to them that I will implement.
223+
224+
Considering only Firrtl, using the HGLDD file would be enough, but it does provide only information about
225+
FIRRTL-to-SystemVerilog mapping, so it does not contain user types information.
201226

202227
In this small example if I use only HGLDD I would be able to see that they are both bundles, but it is not possible to
203-
see that they are actually `MyFloat` and `IntCoordination` respectively. Also `Bool`, `UInt`, `SInt` would not be
228+
see that they are actually `MyFloat` and `IntCoordinates` respectively. Also `Bool`, `UInt`, `SInt` would not be
204229
retrieved from HGLDD/FIRRTL only. From here the reason to use Chisel IR to get the user types information.
205230

206231
```scala
@@ -210,18 +235,48 @@ class MyFloat extends Bundle {
210235
val significand = UInt(23.W)
211236
}
212237

213-
class IntCoordination extends Bundle {
238+
class IntCoordinates extends Bundle {
214239
val x = SInt(32.W)
215240
val y = SInt(32.W)
216241
}
217242
```
218243

219244
## Drawbacks
220245

221-
Chisel IR is an **internal** IR, and it is not meant to be used by external tools. It is not stable, and it can change
222-
basing on additional future features. It will be really hard to maintain this project for future Chisel versions.
246+
The current approach accesses and uses the Chisel IR which is private to the package `chisel3` since it is part of the
247+
chisel **internals,** and it is not meant to be used by external tools. It is not stable, it may change and this may
248+
compromise compatibility with future chisel versions. Using Chisel IR in this way will make relatively hard to maintain
249+
this project for future Chisel versions.
250+
251+
Mapping different IRs together requires to find common characteristics between them. Different IRs have different
252+
information, reserved keywords and syntax. This can lead to different ways to represent variables and changes to their
253+
names. For example, a variable `x` child of a bundle `b` may be represented with `b_x` in Verilog, but it is not
254+
guaranteed when there are some conflicting variables.
255+
Therefore, this methodology requires to find an ID for each signal which is unique within the same IR, but it
256+
is shared between IRs. Finding an ID with these characteristics is not trivial at all since it really depends on the
257+
characteristics emitted during the different elaboration/compilation phases. These information, even if available,
258+
should remain consistent between different versions of the tools but this may not be guaranteed.
259+
Currently, the IDs (`ElId`) used by the tool to join the different IRs are based on source locators (where a variable is
260+
declared in a **source** module, not instance) contained in the IRs and names of the variables. However, this may cause
261+
issues when signals and modules are generated using for loops. This explains why multiple instances of the same module
262+
are not supported yet (the source locators of internal signals of multiple instances of the same module are the same).
263+
Furthermore, finding the original chisel name from HGLDD requires manipulation based on the transform function used.
264+
265+
```scala
266+
case class ElId(source: String, row: Int, col: Int, name: String)
267+
```
268+
269+
Finally, this tool relies on HGLDD which is a file realized for Synopsys tools and its format is not stable since it
270+
mainly depends on what Synopsys will need in the future.
271+
272+
These issues reveal the need for a more stable and consistent way to map different IRs together. Parsing the IRs
273+
externally and joining them basing on a "guessed and unstable" ID is not an optimal solution (guessed and unstable since
274+
it depends on internal characteristics of compilers).
223275
Therefore, I planned to "integrate" a functionality to directly transfer Chisel information to FIRRTL. In this way,
224276
the `firtool` would be able to access all the needed information for `surfer-tywaves-demo` to render the signals.
225277
This would also allow to simplify the process that `tywaves-demo-backend` currently does to generate the symbol table,
226278
improving performances. And it may extend the support to other languages/dialects in
227-
the [CIRCT](https://circt.llvm.org/) ecosystem.
279+
the [CIRCT](https://circt.llvm.org/) ecosystem.
280+
281+
Despite the drawbacks, this demo successfully shows the potential of the Tywaves project and the feasibility of a Typed
282+
Waveform Viewer for Chisel circuits.

src/test/scala/hierarchicalmodules/MultiBlink.scala

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ package hierarchicalmodules
33
import chisel3._
44

55
class SubBlink(n: Int) extends Module {
6-
val iox = IO(new Bundle {
7-
val enablex = Input(Bool())
8-
val ledx = Output(Bool())
6+
val io = IO(new Bundle {
7+
val enable = Input(Bool())
8+
val led = Output(Bool())
99
})
1010
val blinkerx = Module(new Blink(n))
1111

12-
blinkerx.io.enable := iox.enablex
13-
iox.ledx := blinkerx.io.led
12+
blinkerx.io.enable := io.enable
13+
io.led := blinkerx.io.led
1414
}
1515

1616
class AnotherModule extends Module {
@@ -30,28 +30,19 @@ class AMultiBlink extends Module {
3030

3131
val blinker: SubBlink = Module(new SubBlink(5))
3232
val blinker2: Blink = Module(new Blink(3))
33+
val blinker3: Blink = Module(new Blink(2))
3334

34-
blinker.iox.enablex := io.enable
35-
blinker2.io.enable := io.enable
35+
blinker.io.enable := io.enable
36+
blinker2.io.enable := io.enable
37+
blinker3.io.enable := io.enable
3638

3739
when(anotherModule.out === 1.U) {
38-
blinker.iox.enablex := false.B
39-
blinker2.io.enable := false.B
40+
blinker.io.enable := false.B
41+
blinker2.io.enable := false.B
4042
}
4143
io.leds :=
42-
(blinker.iox.ledx << 3).asUInt + (blinker.iox.ledx << 2).asUInt + (blinker.iox.ledx << 1).asUInt + (blinker.iox.ledx << 0).asUInt
43-
// val blinks = Seq.fill(4)(Module(new Blink(5)))
44-
45-
// for (i <- 1 until 5) {
46-
// val b = Module(new Blink(i))
47-
// b.io.enable := io.enable
48-
// io.leds(i - 1) := b.io.led
49-
// }
44+
(blinker.io.led << 3).asUInt + (blinker.io.led << 2).asUInt + (blinker.io.led << 1).asUInt + (blinker.io.led << 0).asUInt
5045

51-
// blinks.zip(io.leds).foreach { case (b, l) =>
52-
// b.io.enable := io.enable
53-
// l := b.io.led
54-
// }
5546
}
5647

5748
object MainMultiBlink extends App {

0 commit comments

Comments
 (0)