Electrical – Implementing a derived clock in a FPGA

clockclock-speedfpgahdl

Preparing a lab excercise, where we are tasked to generate a 1 Hz clock out of the 50 Mhz system clock of a FPGA. This should be achieved without using any libraries besides ieee.std_logic_1164 and ieee.numeric_std.

The obvious possibility would be, to run a counter. When it hits 25*10^6 ticks, a edge can be transmitted (alternating between rising and falling edged). Then reset the timer. This would require a 25 Bit timer and a 25 bit comparison. As our overall excercise is not that complex, we should not run into limitations of the FPGA ressources. However I wondered how this could be implemented more efficiently. E.g. one could compare only the first couple of bits thereby loosing accuracy of the clock frequency.

The excercise documentation notes, that such timers are usually only loocking at one bit within the counter. So one possibility would be to count faster, so that after half a second one specific bit would swap. This could be done by counting to 2^n and increasing the counter steps. However this would create an error due to the truncated remainder in the step size. E.g. counting to 2^30 with a step size of 43 would result in an error of 0.1% , whereas counting to 2^27 has an error of 6.9% with a step size of 5.

Are there more ressource efficient concepts to generate such a clock? Preferably using a counter and loocking at a single bit for clock generation.

Best Answer

You would not do something like this in a real design. See this for an example design rule you would be violating. Sometimes, you cannot avoid this, but you should only violate the design rule, if you know what you are doing. Instead, you should use an enable signal to enable the 1 Hz logic for 1 clock cycle every second. All the logic still runs at 50 MHz.

Now that's out of the way, there are many ways to implement what you have specified. You cannot avoid the comparator really, because even if you are counting down you still need to reset the counter. The comparator will not use much logic anyway. It is just a large AND gate.

You could have problems when using fast clocks, resulting in long counter chains. The way to avoid this is to use linear feedback shift registers (LFSRs). The way they work is like a shift registers, but with XOR gates inserted in between some DFFs. lfsr By choosing where to place the XOR gates you can control the number of cycles it takes for the LFSR to return to its original state. The LFSR is like a counter, but it counts in a random order. Since you do not care about the order, it will work in your application. The advantage of the LFSR is that the next state of a DFF depends only on the previous DFF. There is no carry to propagate.

The other advantage is that you are using the carry chain in an FPGA. carry_chain All LUTs have a fast connection to the next LUT called the carry chain. The LFSR uses the carry chain to connect to the next LUT instead of using the routing multiplexers. This is what your standard counter also uses, but the carry needs to propagate through the entire chain.

The problem with LFSRs is that you need to know where to place the XOR gates, i.e. which characteristic polynomial to use. This can be difficult to find. However, there are other things you can do. When you implement a counter in the naive way, \$ A = A + 1 \$, the synthesizer will implement it as a ripple adder. There are other adder topologies you can use. The Kogge-Stone adder for example becomes faster as the width becomes large. My own experiments on the Cyclone IV suggest that happens at around 16. However, you sacrifice area, because, unlike with LFSRs, you need more logic to implement it. It also does not use the carry chain, making it slower for low widths.

If you really need to gate a clock, see this as an example, or check your manufacturer's guidelines. Notice the presence of a falling edge DFF. This is to prevent glitches on the clock line from race conditions in the logic gate.