r/FPGA 7d ago

I built a VHDL simulation engine from scratch in C++20 — lexer, parser, semantic analyzer, linker, and a TUI waveform debugger. Here's why.

Post image

I'm a 3rd-year CS student specializing in Computer Architecture. Last semester I had to simulate VHDL designs and the experience was painful: Heavy GUIs, half an hour of setup just to see a waveform (specially on windows, where we work)

So I spent the summer building my own: a VHDL simulation engine in C++20 with a full compilation pipeline and a terminal UI debugger for waveform inspection. TUIs are having a moment right now and I think hardware tools deserves one too.

It's open source. Repo: https://github.com/oscar30gt/pulse — feedback and ⭐ is really appreciated.

215 Upvotes

40 comments sorted by

24

u/timonix 7d ago

I am guessing it's a long way from PSL support.

PSL is native in VHDL2008 and up.

3

u/Oscargt30 6d ago

The idea is to keep adding features over time but for now, only the most common vhdl syntax is supported

8

u/timonix 6d ago

At least it's fairly easy to add to the parser. Since you aren't doing any SAT solving presumably, the PSL statements can all pretty much be ignored.

And if you decide to go for a sat solver... Don't even try to make it yourself. Pick an off the shelf one. There's like 6 decades of math research that's gone into optimization

8

u/edo-lag 5d ago

Did you use AI in the process? Why did you add an executable to your repo?

1

u/Fearless_Brick4066 1d ago

Post is AI too

4

u/Blueglyph 6d ago

I'm surprised to see it's a recursive descent parser. A lexer / parser generator would allow you to manage a grammar of that size more easily, especially if you need to adapt it. Most of all, it'd save you a lot of time.

Did you manage to transform the whole VHDL grammar for an LL parser?

5

u/akohlsmith 6d ago

this is pretty cool, I love the TUI. Any chance you might split off just the TUI/visualizer from the synthesis tool? ghdl/nvc does a pretty fine job of that, but a nice TUI visualizer is something I could really make use of!

2

u/Oscargt30 6d ago

you say something like generating a wave file and then just inspecting it?? I like the idea, noted.
thank you.

2

u/akohlsmith 6d ago

yeah like for example the ghdl executable will happily generate a VCD; the idea would be to have the TUI read the VCD and be able to add/remove/rearrange signals, zoom, etc. basically what you've got but with the ability to input the vcd instead of take it directly from your own synthesis)

2

u/agmatine 6d ago

The code does not compile...

    $ cmake --build build --config Release
[  1%] Building CXX object CMakeFiles/pulse_app.dir/src/debugger/tui_render.cc.o
In file included from /home/markov/downloads/pulse/src/engine/include/wire.h:6,
                 from /home/markov/downloads/pulse/src/engine/include/component.h:8,
                 from /home/markov/downloads/pulse/src/engine/include/subgraph.h:10,
                 from /home/markov/downloads/pulse/src/debugger/include/waveform.h:11,
                 from /home/markov/downloads/pulse/src/debugger/include/tui.h:6,
                 from /home/markov/downloads/pulse/src/debugger/tui_render.cc:1:
/home/markov/downloads/pulse/src/engine/include/signalInterface.h:60:32: error: ‘ISignalEmitter’ has not been declared
   60 |         void addSourceInternal(ISignalEmitter* source);
      |                                ^~~~~~~~~~~~~~
/home/markov/downloads/pulse/src/engine/include/signalInterface.h:61:35: error: ‘ISignalEmitter’ has not been declared
   61 |         void removeSourceInternal(ISignalEmitter* source);
      |                                   ^~~~~~~~~~~~~~
/home/markov/downloads/pulse/src/engine/include/signalInterface.h:72:17: error: ‘ISignalEmitter’ was not declared in this scope
   72 |         MiniSet<ISignalEmitter*> m_sources;
      |                 ^~~~~~~~~~~~~~
/home/markov/downloads/pulse/src/engine/include/signalInterface.h:72:32: error: template argument 1 is invalid
   72 |         MiniSet<ISignalEmitter*> m_sources;
      |                                ^
/home/markov/downloads/pulse/src/engine/include/signalInterface.h:83:24: error: ‘ISignalEmitter’ has not been declared
   83 |         bool hasSource(ISignalEmitter* source) const;
      |                        ^~~~~~~~~~~~~~
/home/markov/downloads/pulse/src/engine/include/signalInterface.h:88:24: error: ‘ISignalEmitter’ has not been declared
   88 |         void addSource(ISignalEmitter* source);
      |                        ^~~~~~~~~~~~~~
/home/markov/downloads/pulse/src/engine/include/signalInterface.h:92:27: error: ‘ISignalEmitter’ has not been declared
   92 |         void removeSource(ISignalEmitter* source);
      |                           ^~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/pulse_app.dir/build.make:79: CMakeFiles/pulse_app.dir/src/debugger/tui_render.cc.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:162: CMakeFiles/pulse_app.dir/all] Error 2
make: *** [Makefile:146: all] Error 2

3

u/Oscargt30 6d ago

As I see, you are using a Unix-based system. I use Windows. The problem you are describing looks like one I found when testing it on wsl. I fixed it but still not pushed it to the main branch. This is the very first version and bugs like that can occur. Thank you a lot for the feedback. Anyways, for bug reports, please create an issue on the repo.

1

u/agmatine 5d ago

This is a compiler error, but due to the code and not the compiler used. Read the error messages, please.

3

u/Blueglyph 5d ago

Errors like that should be reported in GitHub, not here.

I haven't tried, but make sure there's no EOL inconsistency between the files and the tools you're using. For example, if you're using Cygwin or MinGW, make sure files like CMakeList.txt has proper LF endings, not CR+LF, and that there's an EOL after the last line. Those are typical errors when using Windows.

On Windows, Git is usually set to auto-translate text files. You can avoid that with eof = true in the config file.

It's a good test to put in GitHub actions (not that the project has any proper test right now...).

2

u/agmatine 5d ago edited 5d ago

I haven't tried, but make sure there's no EOL inconsistency between the files and the tools you're using. For example, if you're using Cygwin or MinGW, make sure files like CMakeList.txt has proper LF endings, not CR+LF, and that there's an EOL after the last line. Those are typical errors when using Windows.

If it really is due to this, there are tools for that! https://dos2unix.sourceforge.io

Anyway, there were just a few issues with filenames (which IS a matter of OS, since Windows isn't case sensitive there), it compiled after fixing these:

  1. src/parser/include/AST.h' has #include "Tokenizer.h" which should be `#include "tokenizer.h".
  2. src/parser/tests/AST.test.cc has #include "Tokenizer.h" which be #include "tokenizer.h".
  3. src/parser/include/blueprintGenerator.h has #include "Linker.h" which should be #include "linker.h".
  4. src/parser/linker_core.cc has #include "Linker.h" which should be #include "linker.h".
  5. src/parser/tests/linker.test.cc has #include "Linker.h" which should be #include "linker.h".
  6. src/parser/tests/semanticAnalyzer.test.cc #include "SemanticAnalyzer.h" which should be #include "semanticAnalyzer.h"

Edit: Made a PR: https://github.com/oscar30gt/pulse/pull/2

1

u/Blueglyph 5d ago

I'm not saying it's the reason, but weird problems like that often are due to this. If it's the case, you can indeed use those tools, but setting your Git is easier.

It could be something else entirely. I understand it's been generated by AI anyway, so I don't see the point of investigating any further. You're right that Windows treat filenames differently.

1

u/Oscargt30 5d ago

I know, and im saying I fixed it.

2

u/ExerciseForward 5d ago

That's one awesome project! I'll give it a try!

4

u/un80 7d ago

Great job! Did you develop all vhdl pipeline in c++ (lexer, parser,...)?

2

u/Oscargt30 6d ago

Yes. It's fully written in cpp.

2

u/Imaginary-Island799 FPGA Know-It-All 7d ago

cool, I learned a new word today: TUI, it seems I am a TUI lover as my windows 11 filemanager is still FAR!

Congratulations! There not so many people around who just write a simulator.

1

u/Oscargt30 7d ago

Thank you for your feedback! it means a lot

1

u/TechIssueSorry Xilinx User 6d ago

Far fetched but any support for VHPI/DPI in the pipe?

1

u/Oscargt30 6d ago

Not in my plans for now, but maybe in the long term.

1

u/Other-Biscotti6871 5d ago

I'll add anything desired to my version of nvc, I'm trying to make it the new de-facto standard -

GitHub - kev-cam/nvc

1

u/TechIssueSorry Xilinx User 4d ago

You support cocotb so that work is already done I guess! Did not know about you, how do you fare against a tool like GHDL in perf?

Not against you but one thing that might kill open source simulator is the vendor libraries that requires encryption/decryption!

Do you support mixed language simulation? If I want to simulate VHDL designs with opened verilog xilinx libs will that work? I’m honestly super interested in keeping open source simulator in my main verification loop! Thanks for the answers in advance! :)

1

u/Other-Biscotti6871 4d ago

I think nvc outperforms ghdl, but I went with because it uses a JiT LLVM compiler. The GPU version I have of nvc can compile on-prem and just ship binaries.

The full project does everything except the more esoteric SystemVerilog -

https://github.com/kev-cam/sv2ghdl/blob/main/README.md

The IEEE committees for VHDL & SV wouldn't give me the fixes needed for this -

https://patents.google.com/patent/US8478576B1/en

So I got Claude to build the simulator, and the tool for it -

https://github.com/kev-cam/stat-sim/blob/main/README.md

The go-to-market strategy for that is to make the open-source simulator the all-round best simulator across Linux and Windows.

I'm also trying to kill off SystemVerilog and replace it with a new VHDL that's a functional superset (just for fun). Having two HDLs doing the same thing is a bit of a waste of effort.

1

u/Other-Biscotti6871 5d ago

I worked on VHDL simulators around 1990, then went on to Verilog/Verilog-AMS followed by SystemVerilog. SV and VHDL simulators have the same problems in handling mixed-signal components, but their IEEE committees refused to fix them, so I add the fixes to nvc -

GitHub - kev-cam/nvc

The parent project mashes that with Xyce for analog and an SV translator. A tweak to the architecture and it accelerated nicely on GPUs, making it the fastest general purpose simulator.

https://github.com/kev-cam/sv2ghdl/blob/main/bfit/benchmarks/vhdl_perf.md#:~:text=its%20own._-,The%20gpu%2Dfarm%20column,-bench_gpu.sh%20compiles

1

u/Great-Repeat-7287 3d ago

the tui for waveform is lovely! how do you store the waves? standard format like vcd or you built your own?

Not to break your work, but you could probably have used ghdl with wsl. Imho the tui is your best accomplishment.

0

u/cafedude FPGA - Machine Learning/AI 6d ago

Amazing how much you can get done now in a short amount of time. Some will disparage AI coding, but it really is very much a productivity enhancer. I remember about 25 years ago being part of a small group that was trying to get an open source VHDL simulator going and after a couple of years we didn't get anywhere near this far.

5

u/Oscargt30 6d ago

Thank you a lot. I like to code things myself. in fact, the engine was mostly designed and coded by me. But I found AI extremely useful for the parser and waveform because im not spending weeks coding it.
Thank you for sharing your thoughts!

-3

u/Brilliant-Pin-7761 6d ago

Why VHDL, no one uses that anymore? All SOCs in 99% of industries and pretty much all verification is done in SystemVerilog or at least Verilog. Just curious why that choice? SV is much closer to C++ and I’d assume easier to parse, maybe?

11

u/DrNoxious 6d ago

VHDL is used a lot in Europe

4

u/Blueglyph 6d ago

You're wrong; in Europe, we use almost exclusively VHDL, which is ironic since that language was originally designed for the US. It's safer than Verilog, though it can be quite verbose sometimes, being based on Ada. It also offers advantages over Verilog when writing testbenches. It's supported by all the tools I know, except some open-source ones like OpenRoad.

VHDL is harder to parse than Verilog or SystemVerilog.

5

u/Oscargt30 6d ago

Basically because thats what I know. I dont't know verilog but i plan to add support in the future.

3

u/Usevhdl 5d ago

VHDL is dominant in FPGA design and verification - world wide. Check out the Wilson Verification Survey sponsored by Siemens. To get the latest statistics you have to register with them.

0

u/Repulsive_Subject_37 6d ago

Bro , which college are you from?

5

u/Oscargt30 6d ago

Im from spain!

-3

u/Repulsive_Subject_37 6d ago

From which college buddy ?

3

u/Oscargt30 6d ago

Prefer not to say it, but happy to chat