internal clock divider in FPGA - Page 1
Forum section: electronics / general

author: Dmeads
author_rank: Regular Contributor
timestamp: August 31, 2019, 04:29:54 am
content: Hi all!I would like a different clock frequency for my verilog module, therefore the clock division must happen internally.I read that I need to avoid using flip-flops in the clock divider code, and you should only use those when generating an external clock.Is there a way to do internal clock division without the use of a PLL? Like just with HDL*?*it needs to be synthesizable.Thanks!

author: Daixiwen
author_rank: Frequent Contributor
timestamp: September 02, 2019, 07:28:29 am
content: It is not recommended because any glitch on the generated clock signals can generate additional clock cycles, possibly not respecting the design's setup and hold requirements and can generate all sorts of problems. You can reduce the risk by resynchronizing the generated clock signal with the original clock, using one or several d flip flops in series.Check also if your FPGA allows this. I remember at least in the Altera Cyclone 3 a signal generated in the logic couldn't be connected to the clock network. Only the PLL outputs and the dedicated clock input pins could be used as clocks for the logic.

author: NorthGuy
author_rank: Super Contributor
timestamp: September 02, 2019, 04:20:30 pm
content: Combinatory logic has rather unpredictable delays, so it is not good for clock generation as you'll get jitter. If your design is slow, it might be Ok.It may be possible to remove some of the clock edges by dynamically enabling/disabling a clock buffer, but it will not work with very fast clocks neither, and the clock you get will have a weird duty cycle. Similarly, you can use CE in your target areas.The best way is to use the elements specifically designed to work with clocks, such as PLL. Xilinx has dedicated clock dividers - BUFR, which will work very well too.

author: aandrew
author_rank: Frequent Contributor
timestamp: September 02, 2019, 04:50:06 pm
content: You're exactly right; don't divide down a clock and use that slow clock output as the input for other logic.Instead, use clock enables, I know you asked for Verilog, but VHDL is my jam. It should be simple enough to adapt though:Code:signal slow_ce: std_logic;-- generate a clock enable that drives logic at 1/1000th the main clock frequencygen_slow_ce: process(clk, rst)variable counter: integer range 0 to 999;beginif rst = '1' thenslow_ce <= '0';counter := counter'high;else if rising_edge(clk) thenif counter = 0 thenslow_ce <= '1';counter := counter'highelseslow_ce <= '0';counter := counter - 1;end if;end if;end process;use_slow_ce: process(clk)beginif rising_edge(clk) thenif slow_ce = '1' then-- ...end if;end if;end process;(stolen from my e.se answer on the same subject:https://electronics.stackexchange.com/a/34540/17429Basically now your logic is still running at your main clock freq (say 100MHz) but you're driving the clock enable signal of whatever logic block you want to run slower so it only sees every 'n'th tick of the fast clock.

author: Bassman59
author_rank: Super Contributor
timestamp: September 03, 2019, 06:59:26 pm
content: Quote from: aandrew on September 02, 2019, 04:50:06 pmAnd remember to put the proper constraint on those enabled paths, otherwise the static timing analyzer will still want it all to meet the clock period constraint and not the divided period.

author: asmi
author_rank: Super Contributor
timestamp: September 03, 2019, 09:01:33 pm
content: Quote from: Bassman59 on September 03, 2019, 06:59:26 pmAnd after you put down all those set_multicycle_path, you'd better be ABSOLUTELY sure that faster clock will NEVER ever appear on these inputsWhy not do it properly and use PLL/DCMM? That's exactly what they are for after all...

author: davep238
author_rank: Contributor
timestamp: September 04, 2019, 02:37:22 pm
content: QuoteI'm not the OP, but I am a bit fuzzy on constraints. What would that look like?

author: SiliconWizard
author_rank: Super Contributor
timestamp: September 04, 2019, 02:51:57 pm
content: Quote from: asmi on September 03, 2019, 09:01:33 pmSure... and this is the safest way of doing this. Two drawbacks though:- it's non-portable;- it may not be configurable on the fly (which can be required in a given design). Some FPGA allow this, others do not...

author: asmi
author_rank: Super Contributor
timestamp: September 04, 2019, 03:03:41 pm
content: Quote from: SiliconWizard on September 04, 2019, 02:51:57 pmIt's very easy to isolate HW-specific parts into wrappers, so porting is limited to modifying these modules. That is, if one cares about this at all, which isn't very common in HW world as there are often other, much more pressing reasons to use HW-specific modules. For example, I'd love to see HW-neutral MGT module, or DSP block, or SERDES, heck, even DDR cells usually have to be explicitly instantiated (even thou it is technically possible to describe them in pure HDL)...Quote from: SiliconWizard on September 04, 2019, 02:51:57 pmAllgoodFPGAs allow this

author: SiliconWizard
author_rank: Super Contributor
timestamp: September 04, 2019, 03:46:10 pm
content: Quote from: asmi on September 04, 2019, 03:03:41 pmSure.Note that still, unless you're targetting high clock freq stuff, in many cases you can still generate a clock divider in pure HDL on FPGAs with success. The tools will route the output through a clock distribution tree (if there is any available). One thing that will still be a potential problem with this is: you can't assume the generated clock is synchronized to the input clock, so you'll basically have to treat them as clocks in different clock domains. Also, the output may not be routed to a clock tree for various reasons you have little control over... but in that case, you should get some timing violations.Admittedly this is not a clean approach, as there are unknowns you'd have to check after each implementation run...Quote from: asmi on September 04, 2019, 03:03:41 pmDefine "good".

author: asmi
author_rank: Super Contributor
timestamp: September 04, 2019, 03:58:36 pm
content: Quote from: SiliconWizard on September 04, 2019, 03:46:10 pmIn Vivado you can force FF out into BUFG et al (infact this can be used to close timing for some super-high-fanout signal if you have a clock line to spare), but like you said it is essentially an asynchronous clock with unknown phase relationship to original clock. Another issue is duty cycle is only accurate up to a original clock period, but this is not a problem if division factor is high enough, and you don't care about jitter too much. If you need to divide by 8 or less, in 7 series you can use BUFR as it's got builtin clock division.Quote from: SiliconWizard on September 04, 2019, 03:46:10 pmI thought that was obvious - "don't have DRP == not good"

author: Bassman59
author_rank: Super Contributor
timestamp: September 04, 2019, 06:10:33 pm
content: Quote from: davep238 on September 04, 2019, 02:37:22 pmI hate to ask, but what FPGA family?In some cases, when you instantiate a clock divider or PLL block, the multi-cycle constraint is automatically created for you.

author: asmi
author_rank: Super Contributor
timestamp: September 04, 2019, 06:22:19 pm
content: Quote from: Bassman59 on September 04, 2019, 06:10:33 pmI think you confused multicycle constraints with generated (or derived) clocks. Multicycle constraints are not used for clocks generated by PLL because static analysis can derive them automatically from input clock and PLL/MCMM settings. MCCs are used for entirely different purposes - like allowing longer combinatorial chains which you can't split into pipeline for some reason, or dealing with very long physical routes inside actual FPGA (for example they are used in Xilinx's DDR3 controller).

author: Bassman59
author_rank: Super Contributor
timestamp: September 04, 2019, 06:43:09 pm
content: Quote from: asmi on September 04, 2019, 06:22:19 pmApologies, you are correct. For the PLL dividers, the tools will write a period constraint that uses the input clock period times the divide ratio.For clock enables it's a multi-cycle path constraint, and you have to set the multi-clock period yourself.In SDC format the latter might be like:set_multicycle_path 4 -to [get_cells { NETS } ]

author: NorthGuy
author_rank: Super Contributor
timestamp: September 04, 2019, 07:52:32 pm
content: Quote from: Bassman59 on September 04, 2019, 06:43:09 pmYou can use "create_generated_clock" to, sort of, declare the clock you have created. For example you have BUFG which you enable and disable it in a pattern, then you do "create_generated_clock" on the output pin of BUFG to tell the tools the characteristics of the clock you have just created.You can do the same no matter how you have generated your clock, even if you did it with flip-flops.See:https://www.xilinx.com/support/answers/62488.html

author: Daixiwen
author_rank: Frequent Contributor
timestamp: September 05, 2019, 06:31:12 am
content: Quote from: davep238 on September 04, 2019, 02:37:22 pmTo all those who need an introduction on timing constraints in FPGA designs, this webinar next week could be interesting:https://www.doulos.com/content/events/TimingConstraintsUsingSDC.php