Xilinx clocking wizard - Requested frequency vs actual frequency - Page 1
Forum section: electronics / general

author: pigtwo
author_rank: Regular Contributor
timestamp: January 14, 2019, 02:17:04 pm
content: Hello all,I'm working on a simple project where I want to drive a DVI display with a Spartan 6 but I'm having a little trouble interpreting the clocking wizard output in ISE. I'm trying to generate two clocks. One for logic to generate the pixel data and another high speed clock for clocking out serial data. At the end of this will be a serializer. Since I'm serializing all this data, it seems to me that the parallel data clock and the serial clock need to be exact integer ratio multiples of each other or they would slowly drift out of sync.So I've generated a 270MHz serial clock from an external oscillator using a DCM. Then to make sure the parallel clock is an exact multiple of the serial clock I'm trying to generate a 108MHz clock from the 270MHz clock using a DCM. (I'm using 108MHz here which is 2/5 270MHz because I need to load the serializer twice due to it being DDR. Opposed to just 1/5 270MHz). But when I put 108MHz into the clocking wizard I get weird numbers on the final screen. See the attached picture.I inputted exactly 270MHz for the input frequency but on this screen it says 270.051MHz. And then the output is 108.021MHz when I put in 108MHz. I wouldn't really care about the slight changes to the frequencies but I need them to be a multiple of 2/5 so they don't go out of sync.Does anyone know why this happens? I don't see why it should assume the input frequency is different.Thank you!

author: Yansi
author_rank: Super Contributor
timestamp: January 14, 2019, 02:21:00 pm
content: I am no xilinx expert, but probably your requested frequency is not an integer multiple of something else, so the PLL can't do it exactly.What is the source of the 270MHz?

author: pigtwo
author_rank: Regular Contributor
timestamp: January 14, 2019, 04:51:50 pm
content: The source frequency for the 270MHz clock is a 50MHz clock. Which is a little bit of an weird multiple(27/5). But when I go to that same screen for the 270MHz generation it shows the output being 270.000MHz. Maybe there are some digits not shown there that aren't zeros.I don't know much about how the DCM actually works but once I have my 270MHz(ish) clock shouldn't it be able to apply the 2/5 ratio exactly? So if the 270MHz clock is really 270.015MHz shouldn't the output be 270.015MHz*(2/5) = 108.006MHz instead of what I'm seeing(108.021MHz)? Unless maybe the 2/5 ratio is wonky and can't be done exactly.It's possible I'm misinterpreting the actual frequency output listed. There's something I don't understand here because I still don't get why it says the input clock is 270.015MHz. The 270MHz value is a value I just put in the input clock dialog box so it doesn't seem like it should it should change. Unless this is the minium resolution of the DCM or something.

author: hamster_nz
author_rank: Super Contributor
timestamp: January 14, 2019, 06:05:53 pm
content: Looks to be a rounding error somewhere internal to the clocking wizard as it converts from frequency to period and then back to frequency.I suggest you read the FPGA user guide, especially the section on clocking - it will answer all your questions and more as it details the inner workings.https://www.xilinx.com/support/documentation/user_guides/ug382.pdfBut here is a quick summary for the PLL primative:The input clock is multiples by an integer between 1 and 64 to give an internal clock signal. This has to be in the range of 400MHz to 1080MHz (or 1000MHz, depending on speed grade of FPGA). See table 52 ofhttps://www.xilinx.com/support/documentation/data_sheets/ds162.pdf.All outputs are made by dividing this frequency by 1 through 128 to generate the outputs.The DCM performative works along the same lines, but can multiply by 2 to 32, then divide by 1 to 32.To go from 50MHz to 108MHz and 270MHz ideally you need a Vco frequency of 540MHz or 810MHz. You can't do that with a 50MHz clock, so maybe the Clocking wizard is using some other sets of numbers that gets it close, or you are chaining multiple PLLs/DCMs.How do do this stuff on paperYou could possibly get what you want by chaining two PLLs together - not the best, but can work. Here's how you do it:You are trying to go from 50MHz to 108 and 270 MHz. You need to work out the prime factors of these numbers.Expressed using prime factors, you want to go from the (5*5*2) MHz to (3*3*3*5) MHz and (3*3*3*2*5) MHz .The first PLL has to multiply by (3*3*2) = 18 (giving a 900MHz Vco, which is good) and divide by (2*5) = 10 to get a (2*3*3*5) = 90MHz signal.The second PLL multiplies that signal by (2*3) to get a (2*2*3*3*3*5)=540 MHz Vcco frequency, that then needs to be divided by 2 and 5 to give the desired 270MHz and 108MHz.You could bounce through 180MHz instead of 90MHz instead, if you wanted.

author: pigtwo
author_rank: Regular Contributor
timestamp: January 14, 2019, 11:04:51 pm
content: Thank you for pointing me to UG382. It was extremely helpful. After reading through it I believe I have it figured out.In case someone else finds it helpful I'll describe a little of my thought process.The first thing is I didn't know the clocking wizard chooses which primitive(PLL_Base, DCM_SP) to use based on your desired outputs. This would lead to a lot of confusion because it would seem like sometimes I would just lose precision on values that previously had better precision.Next, following what hamster_nz said I was noticing that the clocking wizard was able to generate frequencies that it shouldn't be able to. For example with a 50MHz source clock generating a 54MHz clock was fine. This shouldn't work because your M would be 27 which gives 27*50MHz = 1350MHz which should be outside of the VCO frequency range. But looking at the primitives created by the clocking wizard this was indeed what it was doing. The reason(I think) this is possible is because it is using a DCM(_SP). DCMs use a DLL which does not use a VCO. So when using the DCM primitive you are free to multiple and divide indiscriminately so long as you use allowed M and D values.Now my original problem isn't really solved by any of this because the input frequency should never change and I should have been able to generate the frequency I was trying to generate. So as hamster_nz said it appears to be a rounding error and not representative of the actual frequencies generated.https://forums.xilinx.com/t5/Welcome-Join/Clocking-wizard-3-2-clock-summary-differs-from-clock-output-page/td-p/425038Thanks for the help again!

author: hamster_nz
author_rank: Super Contributor
timestamp: January 14, 2019, 11:27:38 pm
content: Oh, the DCM most likely uses the CLKIN_DIVIDE_BY_2 attribute to make the input clock a 25MHz.... Forgot to mention that

author: pigtwo
author_rank: Regular Contributor
timestamp: January 15, 2019, 12:23:37 am
content: Generating 108MHz from 50MHz didn't use the CLKIN_DIVIDE_BY_2 attribute but using 270MHz as the source does. Which makes sense as you want lower frequencies so it gives you more head room on your multiplier.I forgot to post before, I created a handy little python script to test some of these. ISE/the clocking wizard take forever to start and hang frequently for me so it's nice to test things quickly.Code:sourceFreq = 50; #All frequencies in MHzdesiredFreq = 270;multMin = 2;multMax = 32;divMin = 1.0;divMax = 32;minIFFreq = 400;# Set very low for DCMmaxIFFreq = 1000; # Set very high for DCMmultFreq = [];mult = 0;div = 0;answer = 0;i = multMin;j = 1;while i <= multMax:if(sourceFreq*i >= minIFFreq and sourceFreq*i <= maxIFFreq):multFreq.append(sourceFreq*i)i = i + 1i = divMin;for j in multFreq:i = divMin;while(i <= 32):if(abs(j/i-desiredFreq) < abs(answer-desiredFreq)):answer = j/i;div = i;mult = j/sourceFreq;i = i + 1;print("Multiplier :", int(mult)); # If there are multiple solutions this will only output the final one.print("Divisor :", int(div));print("Actual Freq:", answer);As a side question, is there a good oscillator frequency for generating clocks for various DVI resolutions? I'm thinking of 54MHz but I chose it arbitrarily.

author: hamster_nz
author_rank: Super Contributor
timestamp: January 15, 2019, 12:55:27 am
content: Quote from: pigtwo on January 15, 2019, 12:23:37 amIf I was making a board just for for video work I would put a second 74.25 MHz clock on it for 720, 1080i or 1080p... but if you were making a board for video then that crystal would most likely end up being a reference clock for the high speed transceivers blocks, and you would have a 50MHz or 100MHz clock for the rest of the FPGA.

author: exmadscientist
author_rank: Frequent Contributor
timestamp: January 16, 2019, 05:01:37 am
content: The clocking wizard is stupid. It's usually a lot easier to just instantiate the clocking primitives yourself, once you've taken the time to read about them in the appropriate UG. They may look scary and imposing -- and theyarecomplicated -- but I'll take that any day over the... arbitrariness... of that dumb wizard. (Who thought it was a good idea for that thing to "automatically" choose PLL vs DCM, anyway?)Here's some old production-ish code of mine that instantiates a PLL to double an input clock for handling DDR data coming in from an ADC. The actual problem was handling some misrouting of clock signals (donotroute clocks into non-clock-capable input pads for no reason!) that was fixed on the next spin of this board, so the details are weird and not worth copying, but it shows that manual instantiation of the clocking primitives from VHDL isn't that painful. This particular example also includes manual instantiation of the PLL feedback and output buffers. I don't think that is usually needed, but cleaning up this particular routing mess was... not pleasant. This style also has the decided advantage of version controlling much better than anything the wizard ever does!Code:--Use a PLL to generate a DCO-derived doubled clock (for DDR sampling) and-- divided clock (for clock domain intermediate to fabric and for SERDES-- strobes)u_dco_pll : PLL_BASEgeneric map (BANDWIDTH => "OPTIMIZED",COMPENSATION => "SOURCE_SYNCHRONOUS",CLK_FEEDBACK => "CLKOUT0",DIVCLK_DIVIDE => 1,CLKFBOUT_MULT => 2,CLKOUT0_DIVIDE => 2,CLKOUT2_DIVIDE => 12,--VCO frequency: 576MHzCLKIN_PERIOD => 6.9444, --144MHzREF_JITTER => 0.1000 --pulled out of nowhere)port map (--input clocksclkin => clk_dco_in_buf,clkfbin => pll_feedback_return,--output clocksclkout0 => clk_dco_double, -- 288 MHz: DDR DCO clock--clkout1 => clk_dco_pll, -- 144 MHz: DCO clock cloneclkout2 => pll_48MHz, -- 48 MHz: double the fabric clock-- control & statusrst => pll_reset,locked => pll_is_locked);u_bufg_48mhz : BUFGport map (i => pll_48MHz,o => clk_intermediate);u_dco_pll_feedback : BUFIO2FBgeneric map (DIVIDE_BYPASS => TRUE)port map (i => clk_dcoddr_bank0,o => pll_feedback_return);bank0_dco_bufpll: BUFPLLgeneric map (DIVIDE => 6,ENABLE_SYNC => TRUE)port map (pllin => clk_dco_double,gclk => clk_intermediate,locked => pll_is_locked,ioclk => clk_dcoddr_bank0,serdesstrobe => clk_dcostrobe_bank0,lock => bufpll_bank0_is_locked);