Transitioning from Migen to nMigen

Migen is a Python library designed for building FPGA and ASIC applications that has seen what feels like exponentially increasing usage via word-of-mouth over the past 7 years. With many examples of Migen being used in production, the main architects over at M-labs have noticed a number of flaws with the language that have constituted a moderate reboot of the library called nMigen.1

While Migen (oMigen) continues to get updates for new targets and bug fixes, the future direction of work on Migen from M-labs will be focused on nMigen. A compatibility layer is provided so that designs not using nMigen's build modules can be ported seamlessly to nMigen with as little as a single import change from from migen import * to from nmigen.compat import *.2

This post is meant to serve as an primer to quickly get started in nMigen for someone familiar with oMigen. The target audience comfortable with using a large majority of oMigen features, although they need not know every single parameter by memory of some of the more complicated oMigen constructs like memories.

High Level Overview of Differences

Without delving into syntax, and as someone still more familiar with writing oMigen compared to nMigen, these are the major differences/similarities I personally noted when writing nMigen code and synthesizing code to FPGAs:

Writing nMigen Code By Comparison With oMigen

Now that I have summarized a high-level overview of nMigen and oMigen differences, I will now demonstrate how to write nMigen code by comparing and contrasting (effectively) functionally identical code snippets written in both languages. The previous section will serve as a guide.

Creating Modules

If/Else/Elif

Switch/Case

FSMs

Tristates

Other (I/O) Primitives

DDR I/O, etc. Good lead-in from Tristates

Building A Design

RTLIL/Verilog Generation

Building using a Platform

Next Steps

This post was ultimately meant to serve as a lead-in to porting your own FPGA development board to nMigen. In my analogous post for oMigen, I assumed a user had no prior Migen experience. Thus I gave a quick primer on Migen before describing how to port a board. This matched my original experiences with oMigen in April 2015, where I in fact successfully ported a board before I could ever test it at the bench.

For the analogous nMigen post, my intent was to inline this entire post into the porting a new board post, while also giving a quick primer for those wh have never seen oMigen or nMigen. This way, I felt I was accommodating multiple skill levels. However, I soon figured out there's enough information about oMigen and nMigen differences that it was best to create this post as a prerequisite for previous oMigen users.

That said, I hope this post is useful in and of itself for those familiar with oMigen and LiteX for getting started with the future direction of Migen development. As someone fairly satisfied5 with nMigen's design decisions, I look forward to what new designs people have to offer in nMigen.

Acknowledgements

I would like to thank whitequark and S├ębastien Bourdeauducq, both of M-labs, for looking over drafts of this post and offerring valuable overall feedback and catching typos.

Footnotes

1 While I am involved with submitting new features to nMigen not in (o)Migen, I was/am not personally involved design decisions of nMigen core. I defer a blog post or discussion of nMigen design decisions to someone at M-labs.

2 Miscompilation of code using the nMigen compatibility layer that previously worked in oMigen is considered a good bug report :).

3 This should be read as "I am not currently qualified to discuss the differences, and while I think they're important, I am deferring discussion to an update to this post" :).

4 There are a number of FOSS PNR tools in various states of development, but the primary two currently used by projects are nextpnr and arachne-pnr. Nextpnr is preferred for all new projects because it is FPGA-family agnostic and just about superior to arachne-pnr in features (multiple clock constraints, timing-driven placement) and resultant bitstream quality in every way.

5 Ask me personally if you're interested in my critiques :).