MyHDL synthesis: from browser to FPGA in five seconds
When it comes to feeding (mostly proprietary) synthesis tools, the most widely supported HDL (hardware design language) is probably plain Verilog, then comes VHDL. The reasons for that are simply based on popularity or the fact that VHDL is a little more complex to parse.
So, all super-HDLs (like Chisel, SpinalHDL, etc.) transfer to one of these V* HDLs in one way or another, then synthesis/mapping/place'n'route turns it into a wiring map for the silicon. Same went for MyHDL or its also popular competitor, (n)migen.
Now the rising stars in the OpenSource synthesis world, mainly yosys at the front, have changed the game so far, that it became rather easy to generate synthesizeable elements the way you want them to be, and turn them into a firmware file without having to go through lengthy and sometimes problematic conversion procedures.
Yosys -- by default -- takes Verilog and there is quite a bit of effort put into VHDL support through the ghdl-yosys-plugin. On top of that, there is a Python API, allowing to create design elements on the fly. It's like:
- Creating a gate or primitive (like an XOR element from a 74xx chip, remember them?)
- Wiring them up
- Enclosing logic in a user-defined cell, like, packing all these elements into a virtual 74xx with well defined input/output pins
There's more that yosys can do:
- Displaying a schematic of the design (or elements of it)
- Writing out Verilog of a synthesized, mapped, or otherwise optimized design
Let's recall the work flow: You design using a description language (actually, a programming language abused for HDL), then elements are created and wired up. The language describes, how things would functionally work, but the generated elements might work a bit differently. To ensure, they're doing the same thing, you'll need to co-verify them against each other (by Co-Simulation). MyHDL has these mechanisms built-in and can interact with yosys and auxiliary external simulators nicely by running the synthesized design in parallel to the original description.
Some might be thinking: Oh no, not again, yet another (incomplete/clumsy/whatever) HDL methodology.
Well, there's comfort: MyHDL has been used in various big projects for years using Verilog as transfer, paying off big time with respect to maintenance and testing. So there's always something to fall back to: development in MyHDL has been rather conservative in order to not break their user's large projects. In fact, tool migrations on the VHDL side had caused way more pain then migrating the entire design to MyHDL. But back to the focus.
13 reasons why...
Ok, so why the hassle of creating a new transfer method to the so called RTL (register transfer language)?
Actually, the complexity of some designs, in particular DSP elements turned out to be handled and tested optimally through Python, due to the large toolbox of existing modules for unit testing and interfacing to the real world.
For example, the challenge of modelling/developing certain DSP applications, starting from a functional prototype (a.k.a. Matlab script) towards a design tested under many many scenarios and corner cases turned out to be most reusable and best-performing under CI aspects (continuous integration) using the Jupyter notebook environment (which some might call an engineer's true wet dream).
Once you have a designed a well functioning/well tested element, you might want to stick it into a library and never touch it again. It's like a Black box then. Maintaining these black boxes and composing them in classic HDL into complex pipelines has been so painful in the past, that a large number of different HLS concepts were developed in various languages (from C, C++ to Python or other class concepts).
In other words, you might want to write something like this:
@hls(style_sheet) def dsp_elem(res, a, b): q = a * b result = q >> 1 res.out = resultand see your verified black boxes instanciated, so you can be sure your formula is calculating right, with exact the same numerical errors as you've modelled it in the first place.
This also, due to its 'hidden inference', allows you to reuse the above abstract formula with other data types or generate code for a Digital Signal Processor, by using a different `style_sheet`.
Yosys allows you to:
- explicitely infer a created blackbox element through the Python API
- Wrap an existing Verilog blackbox model through any HDL
So you can skip the complicated process of modelling versus emulating at a higher level, once you've ensured correct behaviour of your core data type that is using the verified black boxes.
- You can create your own high level synthesis constructs without inventing a new language and by using existing, well proven Python mechanisms.
- You can separate the explicit description (defining how hardware elements should be inferred) nicely from your actual model (that might be rather procedural or software-oriented)
- You don't have to go through iteration procedures by trying to turn abstract formulas into an explicit representation until that one specific synthesis tool happens to infer right (and on top, iterations of the same for further portability). You yourself define the inference rules by building your library.
- You always have the fallback scenario by using a classic HDL for transfer or for creating explicit design elements/simulation constructs
I want to play
So what about the snazzy headline?
Yes, there's a playground, called jupyosys for now, which demonstrates some of the above. If you have an ECP5 Versa Board or similar, you can get a 'blinky' spin in short time without having to install a lot of software, thanks to the Docker featured technologies. If you have no hardware, you can still modify Python code and see what yosys creates out of it. But keep in mind it's all still in an experimental early stage and you might not like what you see. Feedback, error reports and more examples are welcome.
You'll find all the code and the entry point here:
Clicking on the binder logo will fire up the virtual machine in the browser (be patient).
And have fun!
To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.
Please login (on the right) if you already have an account on this platform.
Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: