nMigen is a pretty fledgling project so there aren't a ton of big projects in it yet, but for example Luna[0] (from the makers of the HackRF) implements a full USB stack including USB3 support, with enough abstraction that you can create a USB-serial converter inside your FPGA using two I/Os for full-speed USB and wire it into the rest of your project in about ten lines of Python[1].
[0]: https://github.com/greatscottgadgets/luna [1]: https://github.com/greatscottgadgets/luna/blob/master/exampl...
Migen, the Python-based project nMigen is based off, has been around for longer and has some large projects, such as LiteX[2] which uses Migen to glue together entire SoCs, including peripheral cores such as GigE, DDR3/4, SATA, PCIe, etc, all written in Migen, and is pretty widely used. It also pulls in Verilog/VHDL designs (such as many of its CPU core choices) since it's easy to pull in those from the Python side.
For example, both:
x = Signal(4, true)
y = signed(4)
will create a 4 bit signed number. Use `false` or `unsigned` for a signed. Setting either x or y to a Python integer will handle the sign extension behind the scenes.I will agree with you on the syntax, however. It’s caused by the fact that you’re not synthesizing your program, but writing code that generates code.
nmigen is a library, not a language. So it has to use what’s available to it. The upside is you don’t have to write tokenizers, parsers, etc, but the downside is it looks “hackish”.
For example:
m.d.comb += x.eq(y + 1)
...means: in the combinatorial domain (clockless) of the m `Module`, set x equal to y+1. If you come from a VHDL/Verilog background, nmigen’s “syntax” is pretty off putting, but if you come from a programming background (like me), the Python syntax is easier to grok IMO.Robert Baruch has a nice tutorial on nmigen: https://github.com/RobertBaruch/nmigen-tutorial