jotego wrote:The design is made using a counter on a main 54MHz clock. With that counter there are other signals generated that are sometimes used as clocks directly (which is not a recommended practice) or have a clock enable signal (which is not great either). Again, the two approaches work well with small designs in comparison with the FPGA size.
Using a clock enable is actually the recommended way
to do it. Mixing clocks and clock enable is not a good idea.
The problem with clock enable is that it consumes more resources, but not nearly as much as when used on ASIC designs. Contrary to ASICs, the FPGA registers have dedicated clock enable logic built in. This doesn't mean that use them is completely free. On this Cyclone family there are two clock enable signals per LAB, you can't have a different clock enable for each register in a LAB. Also you might be already using them as part of a conditional updating of the registers. In such cases Quartus will make some further combinatorial logic to implement the desired behaviour. Say, the physical clock enable would become the AND of your logical clock enable and the conditional value. In some cases this might mean an additional LE (logic element) has to be used. But because FPGA implements combinatorial logic using 3 or 4 way LUTs, in many cases no extra LE is needed.
There is an additional problem when replacing a clock with a clock enable. The phasing changes. From the point of view of the master clock, a signal used directly as a clock updates the target register in THIS
cycle. A clock enable would do it on the NEXT
cycle. This must be considered.
The FPGA has signal routing and clock routing.... There seems to be an exception: there is support for reset signals so they go to many more cells. But I do not know how is reset routing done: is it only one? is it many? ... When clocks are generated without FPGA clock pins or FPGA PLL outputs, the global clock tree is not used but the regular signal routing.
The clock network can be used for any signal, clock, async reset or whatever. They are normally dedicated for low skew and high fanout signals. And it is not true that it is not used for internally generated clocks. What is happening here, I guess, is that Quartus is trying to help you.
The clock network is slower than the regular interconnect. It is designed for low skew, not for speed. If you have a derived clock, you already are having clock skew issues just as direct consequence of producing the derived clock. Taking the signal up to the clock network, plus the relative slow speed of it, would make the skew even worse.
Probably there is some clever instantiation of cells that can be done to force a global clock tree to be used. But we have not figured that out yet. So we have regular routing for clocks.
There are multiple ways to do that and it depends on the exact Quartus version. But check the "global_signal" option setting.
And when regular routing gets full because of true signals then the whole thing starts to break apart.
Are you sure that is the problem? Modern FPGAs normally have lots of interconnect resources. Normally you run out of logic elements way before you run out of routing resources. Can you post a compilation report, may be the summary at least?
Back again to the clock skew issues. The most important here seems to be to check Quartus TimeQuest reports. Depending on this you might try to fix the problem with different strategies.