Quote from: simmconn on Today at 06:10:49 AMIn general, I agree. But like Bassman59 suggested, there are always cases that you have to use logic to divide the clock and then feed to the global clock tree. For instance, I once have a clock divider whose output clock phase needs to quickly align with a one-shot input trigger signal edge. The number of possible phases are more than the simultaneously available DCM/PLL outputs, and the 'time to lock' needed is shorter than it takes to reconfigure the DCM/PLL through its serial interface.
IMO if the FPGA vendor provided a function (or routing possibility), they have envisioned its use. It is up to the designer to use it wisely.
Some comments on the use of the clock enable as a mechanism for dividing clocks.
One, it is always instructive to see what a synthesizer does with your code. For example, Xilinx flops have a D and a CE input, and you might think that if your code was something like:
UseCE : process (clk) is
begin
if rising_edge(clk) then
if (ce == ‘1’) then
q <= d;
end if;
end if;
end process UseCE;
it will synthesize to what you expect: the ce signal driving the CE input on the flop. But in more complex situations, I’ve seen the synthesizer build interesting logic in front of the CE input as well as the D, because ultimately the goal of the synthesizer is logic minimization, and in those cases the synth thought splitting the logic between the D and CE inputs was more efficient.
Two, the clock enable signal can have a high fan-out, which makes it a candidate for a low-skew global net, but in newer architectures those global nets are for clocks only, and you can’t route from a clock net to a logic net. So even if you’ve worked out the timing constraints for the multi-cycle paths, you still have to ensure that the clock enable signal itself meets timing.
I think we all agree that the “Best” thing to do is to use a DLL or PLL or other clock-conditioning block to generate a lower-frequency clock which is guaranteed to be synchronous with the generating clock. Crossing the clock domains in this case is straightforward. Xilinx pushes you to do this, what with the generous number of DLLs and global clock nets available in their parts, combined with the inability to route a CE on a global net.
But it’s the case where you don’t have or can’t use a DLL/PLL and you also have a lot of logic that doesn’t meet timing at some high clock frequency, and the clock enable is loaded down such that it won’t work either, that you have to resort to dividing the clock with flops and then putting that output on a global net. And like I said before, once you do that, you have to consider the two clock domains to be totally asynchronous and manage the crossing very carefully. And yeah, you’ll feel dirty doing it.
If you’re worked with Microsemi ProASIC-3 parts this all might seem familiar.