Hi everyone, I'm currently using a vitex-II pro FPGA, I've implemented an NCO frequency generator, which is supplied with a 64bit init & delta phase value. I'm currently using a local oscillator to clock the NCO ( must use specific local oscillator) but this does contain a margin of offset and drift thus influencing output frequency of NCO. A compensation circuit which includes another stable clock is used to correct the drift and offset by using a frequency counter on both clocks then calculating appropriate delta phase to compensate. My problem is that my equation to calculate adjusted delta which requires a 64 bit division
Delta2 = (count2/count1) * delta1
Delta2 = new delta phase with correction Count2 = frequency counter for Local Oscillator Count1 = frequency counter for external Oscillator Delta1 = Original calculated delta phase to product output frequency
What would be the most appropriate way of doing this calculation, especially with the division? also time constraints, everyone 1.6ms roughly this will occur. Maybe this could be done differently? Ideas I've been thinking about are on the lines of, Maybe reduces the counting resolution ? use internal PPC (CPU)
Why not design your circuit such that count1 is always a power of two? I might not have understood your requirements correctly, and I'm not sure exactly what frequencies you're dealing with... but if you can just "choose" a convenient 2^N value for count1 to count up to, then calculating the ratio of count2/count1 just means dropping N LSbits of the value measured for count2.
Of course, if the external oscillator frequency is allowed to vary significantly, then in this case the delta update period would vary at the same rate.
This answer sounds way too simple, so I bet I've misunderstood what you're trying to do... if so, sorry to waste your time! :)
Division is the brute force way of addressing that, but is not really a good approach in most cases. When dealing with two counts like that, you can count the number of clocks of the numerator clock per cycle (or multiple cycles) of the denominator clock to determine the ratio without performing an explicit division. In fact, you don't even need a frequency counter, as that is what you are constructing here anyway. The more cycles of clk1 you accumulate clk2 over, the greater the precision of your result. Basically you have a counter that counts up with each cycle of clk2 that is read and reset every N cycles of clk1. Multiply that by your delta constant to get the adjustment.
There are some more advanced tricks to determine fractional clocks in order to reduce the accumulation time, but that is beyond the scope of a usenet post I think.
For this type of application, it is more common to use a feedback loop and a measured parameter such as residual frequency after the mixer to nudge the DDS increment up or down. Look at phase lock loops for this.
perhaps you can elaborate a bit more on what it is all good for? I am asking this because the parts that you are playing with seem not to fit each other very well: Using a 64 bit NCO seems to indicate an EXTREME need for precision while the idea to simply divide the counter results in order to get a new delta phase value for the NCO sounds more like a LOW fidelity frequency locked loop.
Nevertheless, the most basic question that you should care about is the resolution of the counters. This being so because the resolution of the counters limits the precision with that you may know the input values of your control loop.
Let us first consider the case that Count1 and Count2 are integer values (i.e. they are really simply the counted values for a given timebase). In this case the typical +/-1 digit error of a measurement like that is the limiting factor in resolution. Under the very optimistic assumption that your clocks are in the range of 1 GHz (and that your fpga can handle clocks like that) then at a timebase of 1.6 ms you end up with count rates in the order of 1.6E6. At count rates like that the +/- 1 digit error produces an
6.25E-7 relative statistic error. This relative error will increase with decreasing clock frequencies.
With the 64 bit NCO the resolution of the lest significant bit is in the order of 5.4E-20 !!!!! Clearly you will not be able to compute a result with that precision with input values having a relative error of 6.25E-7 or even more. In this case you are well served with a 32 bit division which will provide more than enough bits. If you want to stay with the 64 bit NCO then you change only the upper 32 bit and let the rest stay at zero.
Things may look a bit different if your counters are not simply "counters" but sophisticated frequency measurement devices. With sub clock interpolation schemes you may get down to a relative error of 2E-11. Where this number comes from is a bit OT. The dynamic range that is necessary to handle this is more than is available with 32 bits and you would indeed need a >32 bit computation.
In general, a good control loop will need some more computations than simply the frequency ratio, for example integrations and low pass filtering. Stuff that is not so easily done in VHDL etc. So, the question whether you should try the "all hardware" approach or make use of an fpga embedded processor depends a bit on what development environment you have available. There are systems out that may translate complete DSP based models into VHDL for you that you put into the fpga. A system like that will address all VHDL generation problems on its own and take a lot of complexity out of your project. If you have no such system at hand the embedded processor variant may be the more easy one. Most of the modern compilers for 32 bit embedded processors handle 64 bit integers as well as 64 bit floating points with ease. The fact that the fpga emdedded processor may take use of fpga hardware multipliers makes floating point operations a matter of microseconds and not of milliseconds even without a dedicated floating point unit. So speed should not be a problem.
In any case you should search for a technical solution that enables you to measure the frequency error with more resolution&precision than you have now. A DIRECT phase comparison between the two oscillators and so a PLL may be more appropiate to the problem.
Best regards Ulrich Bangert
schrieb im Newsbeitrag news: email@example.com...
Really appreciate everyone's input , the specifies are a little different to my first understand of the problem but never the less useful information ( I'm just an undergrad , still learning the ropes) . Ben with your response , I'm unable to make count1 2^N because its actually the measured result that will vary depending on the drift of the oscillator, if the formula was the other way around it would make the problem much easier , using your solution. Peter , I can't use the external clock reference because the nco utilizes a rocketio mgt component and the specifics require the local
125MHz clock to drive it ,, only with hardware changes can I change this " and for the time been isn't really the most viable option , hence implementing compensator circuit. Ray , similar to Bens answer , the problem is , the denominator is measured , thus varying
So delta2 = (nominal/ measured) * delta1
One solution is to do a lookup table and also utilize linear interpolation between points. Count of NCO (which is measured count of local oscillator) corresponds to a particular delta correction phase.
Please feel free to ask more question if anything is un clear.. Also you future references are there custom cores available for divisions?
Since you are in a V2Pro, you have multipliers galore, and can build adders. For a 64-bit quotient in good time you might try Newton-Raphson approximation. See e.g.:
for a start (the simplest early google hit for Newton-Raphson division). If you have 1.6ms, that's an incredibly long time, and a long divider would work easily if you are strapped for multipliers or fabric.
The circuitry goes together easily, if you're a student, the exercise will do you good!
Perhaps I am missing a few things here. You have both clocks, no? If you do, you don't need the frequency measurement from somewhere else, you use the clocks themselves and the counter arrangement I described.
A more conventional approach would be to not worry about the specific delta, but instead nudge it up or down with feedback derived from the frequency or phase error at the NCO output (mix the NCO with the signal and determine the phase/frequency offset from the resulting beat). Properly done, it will self adjust without ever having to compute the delta value.
The sample rate through your NCO is fixed by the clock (I think you said it is a 125 MHz clock). The signal's center frequency is determined by the transmitter, but you don't have access to exact transmitter frequency (besides, it will drift). As a result, you need to vary the phase increment for the NCO in order to match the transmitter's carrier.
Sorry Ray , I now understand what you meant at the beginning, its my fault I've got mixed up with my notation ( and was looking at a different aspect) . The counter relationship is between the nco_nominal count (theoretical) calculated from the delta phase and the measured count (using the external stable reference 10^-15 precision and counting rising edges on 125MHz reference clock for nco). The external clock uses 10MHz and I've purposely change its timebase to 1.6ms. My intention is to get the ratio between nominal/measured and adjust the delta phase accordantly. Now as Ulrich mentioned I I'm using integer counters and I'll need to continue evaluating the resolutions ( I will post back with results )
I did further research , this is what I've came up with ( with help from my senior engineer)
The following looks too simple to be true. However, it uses constant division whereas we need variable division.
Who said arithmetic was difficut in an FPGA ;-)
It's just an example. It can be further optimized. It's a parallel full speed solution...
-- Divide a 24 bits unsigned by 1.122
-- Author : Bert Cuzeau
-- not overly optimized (yet under 150 LCs of plain logic)
LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL;
-- --------------------------------------- Entity DIVBYR is -- Divide a 24 bits by 1.122
-- --------------------------------------- Port ( Clk : In std_logic; -- Main System Clock Rst : In std_logic; -- Asynchronous reset, active high D : in unsigned (23 downto 0); -- use std_logic_vector ! Q : out unsigned (23 downto 0) -- use std_logic_vector ! ); -- end;
-- --------------------------------------- Architecture RTL of DIVBYR is
I think I must still be misunderstanding something fundamental. Let me see if I've got this straight.
You have two clocks but you don't know their exact frequencies. You have the ability to count rising edges of these clocks, presumably by sampling them using a third, higher-speed clock and detecting 0-1 transitions. Every time you see a transition on clock A, you increment counter A. Every time you see a transition on clock B, you increment counter B. The ratio A/B is the number you're looking for.
So, at some point in time you have to start your counters at 0, right? And at some later point in time you have to stop both the counters and calculate the ratio, right?
So, why not monitor counter B and when it reaches some predetermined convenient value, e.g. 65536, stop counting and call that your sample period?
I don't see how it matters which clock is supposed to be the "nominal" and which is the "measured" clock, if you're really measuring both of them. That is, instead of asking the question "how many rising edges of clock B do I see in this fixed time period", you should ask "how long does it take for me to see 65536 rising edges of clock B"?