Visualizing RISC-V Chipyard systems with Chipyard Viewer
Last autumn I took an SoC course as a grad class at my alma mater. In this course we started with a framework called Chipyard which comes out of UC Berkeley and their Architecture Research department.
Chipyard seems to make it easy to bootstrap custom SoCs, particularly RISC-V chips that have custom accelerators for application-specific logic.
In our course we covered how to set up Chipyard for ourselves, run through example projects, and eventually go on to prototype something for ourselves in small groups.
My team eventually did present something, though we were stymied at times by a few limitations we found in their go-to hardware description language Chisel. In particular, a lack of analog operations required some workarounds.
Now when you simulate an SoC with Chipyard, it generates a rather large
.out file that contains a number of CPU operations and register values.
An example of one such output file is shown above, truncated heavily to make it more reasonable for this blog post. Even for the simplest program, built from their examples repository, it’s over a hundred lines long.
For debugging, this is a lot of information. That’s useful, but too much information can be equally unhelpful. There’s so much happening you aren’t going to know entirely what’s important.
I built a web app where you are able to open and load one of these files and see it in a visual interface.
Operations are now shown visually on a timeline with accurate clock timing. Below the timeline is a rendering of the text file we saw above, but now with color-coded highlighting so that you can get a better sense of what parts of the text are visually similar and help you identify patterns much easier.
And as you can see it’s designed with a dark theme. There’s an optional light theme too. This is important, to be consistent with your tools.
Hovering over one of the blocks in the timeline provides this helpful card with more details at the given clock cycle. You can see the opcode and what the opcode stands for. You can see the program counter and the individual register operations. For specific RISC-V operations, we can go further and provide a more useful label and description for what this operation does.
Seeing the register reads and writes at each clock are fine, but what about the entire CPU state at each clock?
Integrating all of the register operations over time, you can open the Register Viewer tool. From there you can see the value of every register at any clock cycle you choose.
I wrote this web app using Angular and was very happy with how quick it was to iterate while taking advantage of TypeScript for type-safety and components to iterate on each section independently.
I shared this web app with others in the Chipyard community. They noted some areas of improvement, as I definitely made some assumptions about the file format based on the simple examples.
Although the class has ended, the code continues to be available on GitHub for anyone else to take a look. I hope it can be useful for you.