Well, finals week month is over, and at least one holiday has come & gone, which means I’ve gotten a chance to finish up the projects pages and a few other things on my to-do list. That being said, I think it’s about time I start actually posting here.
Today’s topic is on compiling designs in Quartus II (12.1), or rather, reducing the compilation time. Since I’ve started working with FPGAs & Quartus three years ago, there’s one thing that always bugged me. Coming from a programming background, where even a few thousand lines of code, some moderately sized libraries, etc. may take only a few seconds to compile, I was constantly frustrated by the apparent lack of debugging tools in hardware, and stemming from that, the time it took to recompile the design after even a small change.
I’ve learned a lot since then about the simulation & debugging tools, so it’s not a huge deal anymore. However, the compilation time is still somewhat frustrating, especially when I’m working with interfacing some other devices on the FPGA board and it’s easier to just test.
I know the compiler has a lot of work to do, even compared with say, GCC. Analysis may be relatively fast, but synthesis? Partition merge? Generating a netlist? Place & Route? There’s a lot of programmable interconnects available, and the problem is NP-complete.
Still, there are a few things you can do to save time, especially if you’re willing to make the sacrifices on (area/delay) optimization early on. All of these hints and more can be found in the Advisors menu (Tools > Advisors), but I’m going to highlight two important ones:
Design Partitioning & Incremental Compilation
Partitioning your design is in general a good practice, especially if you’re working on a team. Incremental compilation can make use of this by preserving post-synthesis or post-fit netlists if the internal logic has not changed. In other words, if the source file hasn’t changed, there’s no need to re-synthesize or re-map that module. Of course, you run the risk of having less-than-optimal timing characteristics since you can’t optimize the “flat” design. However this can be a small price to pay if you’re only changing the logic in one module, and twenty other modules are unchanged. Goes back to that design mantra – first make it work, then make it work faster/better. Feel free to turn on physical synthesis & optimization for fmax or resource utilization later; but for now, we’re prototyping!
You can select individual modules for different netlist types from the Design Partition menu (right click an entity in the Hierarchy tab of the Project Navigator window, Design Partitions). As an example, even a small VGA controller on my machine took 42 seconds for a fresh compile; without design partitioning changing one parameter took nearly as long, but after partitioning, changing that parameter dropped the compilation time to 24 seconds.
Alternatively, if you don’t want to mess with designating design partitions and post-synthesis/post-fit, etc., you can simply enable “Smart Compilation” from the Assignments > Settings > Compilation Process Settings. It will do something very similar, but automatically. The same settings (besides manually designating design partitions) and the same changes only took “Smart Compilation” an extra second, which for all intensive purposes is the same time.
Fitter Effort
As mentioned above, the place & route (done by the Quartus II (PowerFit) Fitter) gives some non-optimal (but close?) solution to the NP-complete problem of place & route. To help move things along at the early stages of development, you can adjust the “fitter effort” to reduce compilation time.
The options here are Auto Fit, Standard Fit, and Fast Fit. Auto Fit is the default – it will work hard to meet timing requirements, then breeze through the rest of the operations (sounds like a case of senioritis to me…). Alternatively, you can go with Fast Fit, which will (as the name implies) quickly pass the place & route stage, but not necessarily meet timing requirements at n MHz – you may have to reduce fMax for the design to work. Finally the Standard Fit option meets timing and does not give up, and as a result you may face unnecessary delays in the early prototyping stage.
One thing I cannot stress enough is know what a setting does before trying it. Setting to Fast Fit on a whim and later wondering why the design doesn’t run at 50MHz is a big waste of time. Read the literature – the Quartus II knowledge base has a wealth of information on every setting to help make a hardware engineer’s life a little bit easier.