Sorting out 'Unbuffered IO' warnings for Lattice ICE40 Ultralite devices - Page 1
Forum section: electronics / general

author: ConKbot
author_rank: Super Contributor
timestamp: April 22, 2023, 09:47:41 pm
content: I'm a total beginner at writing for FPGAs, but Ive been trying to learn as of late. Ive been wanting to start with ICE40 devices because they look small and simple and cheap enough to be useful without being overwhelming or adding on a lot of requirements. In addition to learning verilog, Ive been wanting to make sure the workflow is functioning from synthesis, to test bench and figured starting simple would be a good way to go.With IceCube2 installed, I run though their quick start demo targeting an ice40 HX1K in VQ100, everything good, no errors and no warnings that appear out of place.I plug in a lattice demo project (i.e. UG75, ICE40 Ultra RGB LED Controller) targeting an ice5LP4k, and it synthesizes, places, routes everything is good, with no errors and no warnings that appear out of place.I do a project of my own, targeting an ice40UL1k and I cant stop getting "FX689 Unbuffered I/O <name> which could cause problems in P&R "Ive tried searching online, and the synthesizer specific thing with the error code yields 1 unhelpful result, and my generic searching yields C/C+ related stuff (buffered transactions) or more FPGA specific things are generic articles about the BUF NOT BUFIF and NOTIF primitivesIve tried transplanting Lattice demo code into my project, it still gives the error, so I dont think its specific to what I'm doing, but a setup of the project issue, but there is hardly any options I see up front? The Lattice UG75 project doesn't have any constraints file, and any directives aimed at the synthesizer, dont at first glance appear to be related to the error. The quick start demo had a constraints file defining clocks, and that was it.Ive been beating on it for a bit, code and errors and screenshots from the synthesizer as follows:Starting with simple combinational logicCode:module top(inA, inB, inC, outY);inputinA;inputinB;inputinC;output wire outY;wire mid1;assign mid1 = inA & inB;assign outY = mid1 ^ inC;endmoduleIt spits out "@W: FX689 :"h:\laticecube2\proj\test1\test1\blinktop.v":23:15:23:25|Unbuffered I/O outY which could cause problems in P&R"I check out what it synthesized, and everything makes sense ( RTL 1.png and tech 1.png for the generic logic gates and actual FPGA primitives it used )Ok, well I mean yeah its not buffered, so lets throw an actual buffer at it.Code:module top(inA, inB, inC, outY);inputinA;inputinB;inputinC;output wire outY;wire mid1;wire mid2;assign mid1 = inA & inB;assign mid2 = mid1 ^ inC;buf(outY, mid2);endmoduleNow it is upset about mid2 " @W: FX689 :"h:\laticecube2\proj\test1\test1\blinktop.v":24:15:24:25|Unbuffered I/O mid2 which could cause problems in P&R " RTL 2.png is sure enough the same thing as RTL1, but with a buffer added out. But the actual implementation ( tech 2.png ) is the exact same. Plus its not like mid2 is an output that can run off elsewhere to be used in something else, its local to this module.Ok if its not looking for an actual buffer, let try sequential logicCode:module top(inA,inB,inC,clkA,outY);inputinA;inputinB;inputinC;inputclkA;output reg outY;always @ (posedge clkA) beginoutY = (inA & inB) ^ inC;endendmoduleOutY swapped from a wire to a reg as needed, and the two lines combined, yielding RTL 3.png and tech 3.png. But doubling down on the errors this time.FX689 :"h:\laticecube2\proj\test1\test1\blinktop.v":24:10:24:26|Unbuffered I/O outY_2 which could cause problems in P&RFX689 :"h:\laticecube2\proj\test1\test1\blinktop.v":23:1:23:6|Unbuffered I/O outY which could cause problems in P&RRTL3 is exactly what I expect, as is the implementation in tech3. "outY_2" is the net from the LUT to the flip-flop, and "outY" is the output of the flip-flop. Which is where I knew something was being weird, as the logic cell of the lattice is a carry/LUT/DFF, so this entire thing would be in one logic cell, so outY_2 causing problems in P&R seems pretty nonsensical to me.I plugged all of my code examples above into the quickstart project targeting the ice40HX instead of the ice40UL, and everything was fine.Is the Synplify Pro setup from Lattice for the ice40UL's just broken? All of the design files/reference designs on their website are for the ice40 ultra, not the ultralite, so I cant compare and contrast with someone else's code. Just a warning I'll have to ignore enmasse if I design something with the ultralite? Because it looks like it throws it for every net that isnt removed by baking it down into a LUT. Some architectural thing I'm missing about the ice40UL and need to change something about how I code for them? Am I missing something laughably basic?Thanks for any insight anyone has.

author: langwadt
author_rank: Super Contributor
timestamp: April 22, 2023, 10:06:53 pm
content: is there an option somewhere in the tools like "insert I/O buffers" ?

author: ConKbot
author_rank: Super Contributor
timestamp: April 23, 2023, 01:48:03 am
content: Less than a dozen options on a new project, and I managed to get one very wrong.Checking "IP Generation" when I shouldnt have is the culprit here. I was thinking it would run setup tools for the hard IP on the chips (like the onboard oscs, the hardware I2C etc). No, its for black-boxing your own IP to the implementation stage so every time you use that module, it gets placed and routed the same way.So 1) as a user, RTFM. 2) Would some hover-over tooltips have killed anyone?