Problems with PLL

I am new to the ICE40, but I have worked with Spartan3 before. I am trying some of the old projects on my ICEBreaker, in particular a digital pattern generator. This design has a slow part that can run with 12 MHz and a fast part where I try to go as fast as possible (100MHz). The slow part handles the uart communication and the fast part spits out the digital pattern. I managed to run the fast code alone but when I add the slow uart part, I get an error

    nextpnr-ice40 -q --freq 12 --up5k --package sg48 --pcf icebreaker.pcf --json patterngen4.json --asc patterngen4.asc
ERROR: PLL 'pll_inst' clock input 'CLK$SB_IO_IN' can only drive PLL
ERROR: Packing design failed.
0 warnings, 2 error

Does that mean I can run on the ICE40 only with one clock frequency?

Hi @Qubit,

Welcome to the iCEBreaker community. :slight_smile:

You will need to use the SB_PLL40_PAD because the pin where the clock is connected is “special” :slight_smile:

You can use a secondary output from the PLL to drive a 1/2 or 1/4 speed clock. And then maybe even divide it down further. I don’t think you can use the PLL clock input to drive anything else but the PLL itself.

I hope you get your project to work. Just keep in mind that 100MHz is a best and ideal condition spec of the ICE40UP5k a much more realistic max speed is more in the 60MHz range. But it does not hurt to try. The main limiting factor is the routing speed so if you pin the blocks of the fast part right and do it right you might be able to push it.

As an additional resource you might also want to join our Discord chat. We have some very knowledgeable people in the icebreaker channel: https://1bitsquared.com/pages/chat

Cheers,
Piotr

You can’t feed the clock net to both the PLL and to internal logic. That’s just not something supported by the iCE40. (Basically the input buffer of pin 36 of the FPGA can either be connected to a global clock network to drive logic, or to the PLL but not both at the same time).

To overcome that, what you can do is use the special primitive SB_PLL40_2_PAD . This will have two outputs PLLOUTGLOBALA and PLLOUTGLOBALB. The first one is your synthesized clock (which would be 100 MHz in your case) and the second output is going to be a buffered version of the input clock through the PLL block ( so 12 MHz ).

Also note that nextpnr does NOT apply clock constraints on generated clocks, so you will need to manually specify the frequency of your generated clocks either in the .pcf or using the python API.

Something like :

ctx.addClock("clk_out_a", 100)
ctx.addClock("clk_out_b", 12)

in a clocks.py file that you give to nextpnr-ice40 --pre-pack clocks.py

1 Like

It worked!

Info: Max frequency for clock 'clk_100mhz': 123.61 MHz (PASS at 100.00 MHz)
Info: Max frequency for clock  'clk_12mhz': 56.03 MHz (PASS at 12.00 MHz)

Thanks to tnt for the great help!