0
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ How about a cascaded counter? Like 50 Mhz --> 25 Mhz ------> 1Hz \$\endgroup\$ – ammar.cma Nov 17 '16 at 10:29
  • 1
    \$\begingroup\$ I guess you are using VHDL or Verilog to program the function of the FPGA. You don't have to worry about optimizing this counter, nowadays synthesis tools are intelligent and know how to optimize a given function in a way the FPGA's hardware is used most efficiently. Aside of that it is not possible to realize a counter that "looks" only at 1 bit for numbers that are not a power of two, as far as I know. \$\endgroup\$ – Longbow_iic Nov 17 '16 at 13:16
  • \$\begingroup\$ @Longbow_iic: We work with VHDL. I was aware that the tools can and do optimize a lot. However unlike writing compiler optimization friendly C++ or similar, I lack in experience writing optimization friendly VHDL. \$\endgroup\$ – Grebu Nov 18 '16 at 19:26
  • \$\begingroup\$ @ammar.cma: I think a cascaded counter would make the single counter smaller and maybe improve place and route, while enabling code sharing. However we went for the ressource hungry solution as we had not much time. \$\endgroup\$ – Grebu Nov 18 '16 at 19:48
1
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ I learned a lot from your answer. During the lab the result actually was an enable signal as described in your first paragraph. The counter used two 26 bit std_logic_vectors to count to 50*10^6. \$\endgroup\$ – Grebu Nov 18 '16 at 19:18
3
\$\begingroup\$

If your counters have a load function, load the counter to (full scale - desired period - 1) and use the ripple carry to perform a load. This has the advantage that there is no extra timing penalty for a comparator.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.