Lattice iCE40 Ultra internal oscillator - Page 1
Forum section: electronics / general

author: davorin
author_rank: Unknown
timestamp: April 02, 2018, 01:47:02 pm
content: Recently acquired the iCE40Ultra breakout board to test some FPGA designs as the iCE40 Ultra devices come in smaller packages...The iCEcube2 software lists no options to include the two built-in oscillators HFOSC and LFOSC...there is a document "iCE40 Oscillator Usage Guide" describing how to instantiate but this doesn't work at all....Code:SB_HFOSC OSCInst0 (.CLKHF_EN(ENCLKHF),.CLKHF_PU(CLKHF_POWERUP),.CLKHF(CLKHF));Anyone used the internal oscillators? Preferably with Verilog?Well the iCEcube2 software has some other bugs as it suddenly assigns an output as register driven by a logical "1" and clocked by internal oscillator..thanks in advancedavorin

author: daveshah
author_rank: Unknown
timestamp: April 02, 2018, 01:52:29 pm
content: I've not only used them, but reverse engineered and documented the oscillators in the iCE40 UltraPlus forProject IceStormand I understand they are the same on the iCE40 Ultra.Can you post the whole of the design file? I've never seen any problems in iCEcube2. In particular, could you post the definitions of ENCLKHF, CLKHF_POWERUP and CLKHF, and the assignments to ENCLKHF and CLKHF_POWERUP?A minimal template for the SB_HFOSC is athttps://github.com/cliffordwolf/icestorm/blob/master/icefuzz/tests/intosc.v.A larger design using one is herehttps://github.com/cliffordwolf/icestorm/blob/master/examples/up5k_rgb/rgb.v.

author: davorin
author_rank: Unknown
timestamp: April 02, 2018, 01:59:25 pm
content: Actually the error message is clear about it:Code:@E: CS168 :"/home2/Develop/fpga/icecube/quad/quad.v":85:10:85:10|Port CLKHF_EN does not existBut CLKHF_EN is mentioned in one of their hundreds docs about iCE (o;Here is the whole design (where rgb out is stuck at 1 driven by internal oscillator):The same design runs perfect on a MAX1000.Code:module quad(quadA,quadB,rgb,push);inputquadA, quadB, push;outputrgb;reg [2:0] quadA_delayed, quadB_delayed;reg [2:0] pushA_delayed, pushB_delayed;always @(posedge hfclk)if(push)quadA_delayed <= {quadA_delayed[1:0], quadA};elsepushA_delayed <= {pushA_delayed[1:0], quadA};always @(posedge hfclk)if(push)quadB_delayed <= {quadB_delayed[1:0], quadB};elsepushB_delayed <= {pushB_delayed[1:0], quadB};wire count_enable = quadA_delayed ^ quadA_delayed ^ quadB_delayed ^ quadB_delayed;wire count_direction = quadA_delayed ^ quadB_delayed;wire volume_enable = pushA_delayed ^ pushA_delayed ^ pushB_delayed ^ pushB_delayed;wire volume_direction = pushA_delayed ^ pushB_delayed;reg [7:0] count;reg [7:0] volume;wire rgb;always @(posedge hfclk)beginif(count_enable)beginif(count_direction)beginif (count < 165)count<=count+1;endelsebeginif (count > 0)count<=count-1;endendendalways @(posedge hfclk)beginif(volume_enable)beginif(volume_direction)beginif (volume < 191)volume<=volume+1;endelsebeginif (volume > 0)volume<=volume-1;endendendws2811 rgb_ring (.wsclk(hfclk),.reset(1'b0),.DO(rgb),.red_in(count),.green_in(count),.blue_in(count),.volume(volume));SB_HFOSC OSCInst0 (.CLKHF_EN(1'b1),.CLKHF_PU(1'b1),.CLKHF(hfclk));endmodule

author: daveshah
author_rank: Unknown
timestamp: April 02, 2018, 02:33:17 pm
content: You shouldn't have an underscore in CLKHF_EN or CLKHF_PU - it should just be CLKHFEN and CLKHFPU.FYI, the official reference for these things is the Technology Library document -http://www.latticesemi.com/view_document?document_id=52206.

author: davorin
author_rank: Unknown
timestamp: April 03, 2018, 10:26:30 am
content: Thanks for the pointer (o;Though getting now with P&R:Code:I2100: Reading design library: //VMWARE-host/Shared Folders/Downloads/icecube/quad/quad/quad_Implmnt\sbt\netlist\oadb-quad/BFPGA_DESIGN_epThe master file does not existoaInterface::OpenLib_Design OpenDesign failed //VMWARE-host/Shared Folders/Downloads/icecube/quad/quad/quad_Implmnt\sbt\netlist\oadb-quad BFPGA_DESIGN_ep quad INTERFACEThis stupid icecube2 software is killing me, sad this device isn't supported in ice storm yet...Correction: Seems iCEcube doesn't like VMWare shares (o;

author: daveshah
author_rank: Unknown
timestamp: April 03, 2018, 10:45:45 am
content: Mapping it as a network drive will probably solve that problem, it should then just appear as a normal drive with a letter. Icecube is certainly not the first program I've seen with UNC path issues.

author: davorin
author_rank: Unknown
timestamp: April 03, 2018, 11:07:07 am
content: Is there a difference in Verflog language interpretation between Quarts and iCEcube besides iCEcube is using Synplify?For example this designhttps://github.com/dhrosa/ws2812-verilog/blob/master/ws2811.vworks fine in Quarts...but does nothing in iCEcube besides using up space (o;

author: daveshah
author_rank: Unknown
timestamp: April 03, 2018, 12:18:56 pm
content: I don't think there is any difference that would be significant enough to stop that design from working. It's more likely another issue. Is that design passing timing on the iCE40?

author: davorin
author_rank: Unknown
timestamp: April 03, 2018, 07:06:54 pm
content: Stupid question...but does iCEcube2 really support several verilog files?Have now both HF and LF clock running, and feeding them for example to a 10-bit counter and route the MSB to a pin, I can see the clock...but seems everything clocking a submodule in a separate file doesn't gets feeded by the clock...From regular FPGA software there is always an option to set the top design entry...which is missing here...What does actually this mean during synthesis?Code:@W: MT420 |Found inferred clock quad|clk_inferred_clock with period 83.32ns. Please declare a user-defined clock on object "n:clk"

author: davorin
author_rank: Unknown
timestamp: April 03, 2018, 08:30:31 pm
content: I never liked Synplify in the past ;-)Seems others like Quartus and Lattice Diamond are initializing a state machine by default, whereas Synplify just leaves it...so the ws2812 state machine stays always in an undefined state...Is there some internal /reset signal that can be used on the ICE40 devices?

author: NorthGuy
author_rank: Super Contributor
timestamp: April 04, 2018, 12:42:45 am
content: Quote from: davorin on April 03, 2018, 08:30:31 pmI don't know if this is of any interest to you, but PIC16 can drive WS8212 using just 2 logic cells:http://ww1.microchip.com/downloads/en/AppNotes/00001606A.pdf

author: daveshah
author_rank: Unknown
timestamp: April 04, 2018, 06:35:23 pm
content: Quote from: davorin on April 03, 2018, 08:30:31 pmAll flip-flops in the iCE40 initialise to zero when the FPGA is configured. If you need a flip-flop to be initialised to 1, an inverter must be inserted before and after this (AIUI both Synplify and LSE will do this for you if you specify an initial value of 1). There is no internal global reset signal, the only way to force a reset of the chip is to reconfigure it using the external CRESET signal, or the internal WARMBOOT primitive - the latter will only work when configuring from SPI flash, the former will work for both SPI flash and NVCM. Normally if you need a global reset you would connect a reset signal to all flip-flops, and this would use one of the 8 general global routing nets (shared with clocks, clock enables and other high-fanout signals).

author: davorin
author_rank: Unknown
timestamp: April 04, 2018, 08:21:27 pm
content: Well seems you have a deep knowledge about iCE40 devices. Just got my company to order another iCE40 eval board as I very like the small form factor and features you never find in CPLDs.Now I have to figure out why the RAM initialisation with a custom RGB color map doesn't work as it does with Altera. I will say Intel FPGA when there will be an FPGA with Intel 4-core inside ;-)

author: daveshah
author_rank: Unknown
timestamp: April 04, 2018, 09:18:03 pm
content: The iCE40 devices really are great for a lot of applications - CPLD simplicity and pricing, but large enough to contain a RISC-V processor with custom logic. This works even better with the extra 128kB SPRAM in the UltraPlus.In terms of the BRAM there are two issues to be aware of. Firstly there is a small delay (a couple of us IIRC) between configuration finishing and the block RAM actually being initialised - if you need initialised block RAM it is best to keep you logic in reset, and keep RCLKE and WCLKE deasserted for a few us after startup.Secondly, and more likely the problem you are facing, the Lattice tools are a bit fussy about initialisation of BRAMs in initial blocks. Using an "initial $readmemh" initialisation should work though.

author: davorin
author_rank: Unknown
timestamp: April 04, 2018, 10:07:42 pm
content: Ah good to know...Is there a good chance the other ICE40 devices will soon be supported in icestorm like the ICE5LP devices?Sad all ICE40 eval boards from Lattice are expensive compared to the used chip costs...time to fire up kicad and do something similar like those nice and small MAX1000/CYC1000 boards from Trenz Electronics Germany ;-)

author: daveshah
author_rank: Unknown
timestamp: April 05, 2018, 08:11:46 am
content: I don't know if I will have time to work on adding more devices in the short term, although I know someone who might take this on. A lot of the UltraPlus work could be reused for the Ultra and UltraLite.

author: iMo
author_rank: Super Contributor
timestamp: April 06, 2018, 09:47:09 pm
content: Quote from: daveshah on April 04, 2018, 09:18:03 pmYou cannot initialize the 128kB of SPRAM off the bitstream, however..

author: daveshah
author_rank: Unknown
timestamp: April 07, 2018, 06:28:23 am
content: No, but most applications with it will have an external SPI flash - these days a QSPI flash is sufficiently cheap that you can use it both for bitstream storage and code (most code can run directly off the flash, performance-critical code can be copied to RAM by software). Clifford has a QSPI memory mapped controller (supporting regular SPI and dual SPI too) as part ofpicosoc

author: davorin
author_rank: Unknown
timestamp: April 07, 2018, 12:41:37 pm
content: [quoteYou cannot initialize the 128kB of SPRAM off the bitstream, however..Ehm....you cannot initialise sysMEM contents?Well..didn't work for me so far...but TN1250 states:Code:sysMEM memories can be initialized as needed. The initialization can be achieved through HDL (Verilog or VHDL) by specifying the initial values or through an initialization file (.mem file).

author: daveshah
author_rank: Unknown
timestamp: April 07, 2018, 01:07:28 pm
content: imo was referring to initialising the extra 128kB of SPRAM in the iCE40 UltraPlus. It is definitely possible to initialise the normal block RAM from HDL. Can you post an example of the HDL file giving you trouble?

author: davorin
author_rank: Unknown
timestamp: April 07, 2018, 02:05:56 pm
content: The RAM initialization looks like this for a rgb led colormap:Code:SB_RAM256x16 rg_ram (.RDATA(rgbdata[23:8]),.RADDR(counter),.RCLK(clk),.RCLKE(1'b1),.RE(1'b1));defparam rg_ram.INIT_0 = 256'h00000004001000150019001d0026002a002e0033003f0043004800540059005d;defparam rg_ram.INIT_1 = 256'h0061006a006e00720077007f0087008c0098009d00a100a500ae00b200b600bb;defparam rg_ram.INIT_2 = 256'h00c300c700d800dc00e100e500e900f200f600fa00ff00ff00ff00ff00ff00ff;defparam rg_ram.INIT_3 = 256'h00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff;defparam rg_ram.INIT_4 = 256'h00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff;defparam rg_ram.INIT_5 = 256'h00ff00ff00ff00ff08ff0cff15ff19ff1dff2aff2eff33ff37ff3fff43ff48ff;defparam rg_ram.INIT_6 = 256'h4cff59ff5dff61ff6eff72ff77ff7bff83ff87ff8cff90ff99ffa1ffa5ffb2ff;defparam rg_ram.INIT_7 = 256'hb6ffbbffbfffc7ffcbffd0ffd4ffddffe1fff2fff6fffafffffffffafff2ffee;defparam rg_ram.INIT_8 = 256'hffe9ffe5ffddffd8ffd4ffc7ffbfffbbffb2ffaeffaaffa5ffa1ff99ff94ff90;

author: davorin
author_rank: Unknown
timestamp: April 07, 2018, 04:17:52 pm
content: Ah this diamond standalone programmer is just a pita...maybe one out of 4 attempts work...Would the "iceprog" tool also work for other Lattice ice40 (non-supported icestorm devices) breakout boards for programming the spi flash or are then any incompatibilities with the binary file?At least reading out the ID seems to work nicely...Code:me@debian:~$ iceprog -d i:0x0403:0x6010 -v -tinit..cdone: highreset..cdone: lowflash ID: 0x20 0xBA 0x16 0x10 0x00 0x00 0x23 0x54 0x93 0x93 0x13 0x00 0x16 0x00 0x35 0x19 0x01 0x16 0x7C 0x7Bcdone: highBye.

author: davorin
author_rank: Unknown
timestamp: April 07, 2018, 04:38:30 pm
content: Yepp..iceprog nicely programs the spi flash form the ICE5LP breakout board ;-)Code:me@debian:/home2/Develop/fpga/icecube/quad/quad/quad_Implmnt/sbt/outputs$ iceprog -d i:0x0403:0x6010 bitmap/quad_bitmap.bininit..cdone: highreset..cdone: lowflash ID: 0x20 0xBA 0x16 0x10 0x00 0x00 0x23 0x54 0x93 0x93 0x13 0x00 0x16 0x00 0x35 0x19 0x01 0x16 0x7C 0x7Bfile size: 71338erase 64kB sector at 0x000000..erase 64kB sector at 0x010000..programming..reading..VERIFY OKcdone: highBye.

author: daveshah
author_rank: Unknown
timestamp: April 07, 2018, 05:53:11 pm
content: Thanks for testing iceprog! Good to see that it works. I can't see anything obviously wrong with your HDL.Do you have the latest (git) version of icestorm installed? If so, you should be able to unpack the bitstream to a text format using iceunpack (it supports bitstream unpack/pack for iCE40 Ultra, but nothing more) and see if the RAM initialisation data is present or not in the output. Otherwise you can send the bitstream to me and I'll take a look.

author: davorin
author_rank: Unknown
timestamp: April 08, 2018, 10:19:36 am
content: The sysMEM initialisation works now....had a typo (o;Now the colormap looks different on the WS2812 LEDs compared to the MAX10 design...In the initialization statements in Verilog, how are the hex bytes mapped?Code:defparam rg_ram.INIT_0 = 256'h00000004001000150019001d0026002a002e0033003f0043004800540059005d;Is the first hex byte 15:8 and the second one 7:0?

author: davorin
author_rank: Unknown
timestamp: April 08, 2018, 02:00:11 pm
content: Stupid me...it doesn't start with the first byte or word, but with the last one in a row....The order of the hex bytes have to be swapped ;-)So:Code:defparam rg_ram.INIT_0 = 256'h00000004001000150019001d0026002a002e0033003f0043004800540059005d;becomes:Code:defparam rg_ram.INIT_0 = 256'h005d0059005400480043003f0033002e002a0026001d00190015001000040000;

author: jonnyb
author_rank: Newbie
timestamp: April 08, 2018, 10:09:30 pm
content: The INIT_* is a bit weird...and undocumented. See Clifford's reply herehttps://stackoverflow.com/questions/41499494/how-can-i-use-ice40-4k-block-ram-in-512x8-read-mode-with-icestorm

author: davorin
author_rank: Unknown
timestamp: April 09, 2018, 12:00:36 pm
content: Also works now on a iCE40UL-1K board with plenty of space left...well...UART RX/TX is missingAnd best of all...can also use iceprog wo program the onboard SPI flash (o;Here a short clip what it is actually doing, a rotary encoder with pushbutton controlling a WS2812 RGB led ring:BTW: Is there a standalone SPI flash programmer which works with "iceprog" ?

author: iMo
author_rank: Super Contributor
timestamp: April 11, 2018, 06:02:24 pm
content: QuoteAny cheapo FT232H board works

author: daveshah
author_rank: Unknown
timestamp: May 07, 2018, 10:09:16 am
content: This is interesting, and relates to how the internal oscillators work.If you look into the detail, the internal oscillators are actually trimable and on the FPGA I tested go from about 30MHz to 75MHz. Normally, the trim is loaded from OTP at power up, but if you tell iCECUBE that Vpp2V5 is connected to 1.8V (so the OTP is not available), it will connect the oscillator trim to the fabric and hard code it to a middling value instead. If you know what you're doing, you can also manually trim the oscillators (in Radiant or icestorm, but not iCEcube2).Thus I suspect what is happening is the OTP is either corrupted or not being read correctly (could be QA failure, due to overheating from the rework, Vpp2V5 not being connected, or bad power-up cycles), so the trim values are stuck at all 1s so the oscillator is rammed to its maximum possible frequency, which is about 75MHz for the HFOSC (I haven't analysed the LFOSC in detail, but 16.49kHz sounds like a plausible maximum too).If you're using iCEcube2, try setting the VPP_2V5_TO_1P8V attribute on the top level module as described on page 170 of the iCEcube2 user guide. This will hardcode the trim values to the midpoint, instead of trying to read them from OTP, and should get the oscillators within 10% at least.The oscillators are officially specified to be within +/- 5%. Because of the trimming, at room temperature they should actually be considerably better than this, within 1% or so.

author: iMo
author_rank: Super Contributor
timestamp: May 07, 2018, 11:27:08 am
content: I did a measurement on the ice40UP5k with its internal 48MHz oscillator.UPduino board v2.The frequency (48MHz/2) was 23.960MHz +/-30kHz jitter (25degC, 3.3V/1.2V).No trimming.Running 115k2 uart based on that (forth cpu), no issues seen..Could it be you've done your measurement on a different pin? Double check your wiring and verilog.

author: SiliconWizard
author_rank: Super Contributor
timestamp: May 07, 2018, 01:16:24 pm
content: Haven't thoroughly read all answers, so maybe it has been mentioned, but just in case: a lot of primitives have different names with Radiant compared to icecube. So for those using Radiant:For instance, the primitive for the low freq osc is now: LSOSC.You can find that in the online docs for Radiant in "Alphanumeric Primitives List" category.

author: iMo
author_rank: Super Contributor
timestamp: May 07, 2018, 05:19:08 pm
content: This should work with Radiant (here is UP5k, it may work with your chip as well provided it is an UP3k or UP5k):Code:module top(output wire CLK24,output wire NCLK24);wire clk;HSOSC #( .CLKHF_DIV ("0b01") ) // 48MHz DIVIDED by 2myOSC(.CLKHFEN(1'b1),.CLKHFPU(1'b1),.CLKHF(clk));assign CLK24 = clk;assign NCLK24 = !clk;endmoduleQuoteYou can route those signals out of the chip, via a standard pin. You have to see a nice square wave.BTW, Radiant supports UP3/5K chips only, afaik. What chip do you use?PS: it may happen Radiant places the outputs at different pins when running PAR. You must have the .pdc file (post synthesis constraint file with pin assignments) created and placed properly (.pdc visible in bold in "Post Synthesis Constraint Files" folder in your project manager view; .pdc has to be created in DCE).Also open the DCE (Device Constraint Editor) in Radiant, go to View menu and then check "Display IO Placement".Otherwise you will see empty fields with no pin assignments after a regular build (when no .pdc file available).L. tech support says it is not a bug but a feature, they will enable it by default in the next release..

author: daveshah
author_rank: Unknown
timestamp: May 07, 2018, 06:49:11 pm
content: To try hardcoded rather than OTP trim in Radiant, just change HSOSC to HSOSC_1P8V in the code.

author: iMo
author_rank: Super Contributor
timestamp: May 08, 2018, 09:40:23 am
content: Hopefully Lattice comes with UP32k soon