Nmigen PLL ICE40HX8K/HX1K

I’ve been playing with a couple of ICE40 boards. These are some quick notes on using the PLL with the HX8K and HX1K. There’s nothing particularly innovative here, but I wanted to get some notes down.

I used pll.py from this repository: https://github.com/kbob/nmigen-examples/tree/master/nmigen_lib

The examples in this repository are for the ICEBreaker platform, which uses ICE40UP5K. The code doesn’t work with the HX1K and HX8K as laid out on the ICEStick and ICE40HX8KBEVN (these are the boards supplied by Lattice).

In particular pll.py is hardcoded to use B_PLL40_PAD. It appears that the oscillator on the above platforms can not be connected to this type of PLL. As such, if you try and use pll.py unmodified with these platforms you’ll get the following error (as I understand it from nextpnr):

ERROR: PLL ‘U$$0.U$$0’ PACKAGEPIN SB_IO ‘clk12_0__io$sb_io’ is not connected to any PLL BEL

Instead I use SB_PLL40_CORE. This also means you need to use i_REFERENCECLK instead of i_PACKAGEPIN. So the following changes are required:

pll = Instance(“SB_PLL40_CORE”, becomes pll = Instance(“SB_PLL40_PAD”,

and

i_PACKAGEPIN=self.clk_pin, becomes i_REFERENCECLK=self.clk_pin,

In pll.py. A tarball containing a working example for the Icestick is below (if you want to use the HX8K, just change the platform).

Aside from the PLL stuff, I had an issue programming the ICE40HX8KBEVN. As I understand it “platform.build(Top(), do_program=True)” should program this board. iceprog gets called, and appears to succeed but the ICE40 doesn’t seem to get programmed correctly (possibly it needs to be erased first?). I need to run iceprog manually. Programming the Icestick doesn’t have this issue.

Tarball: here