In my project of a modern replica of a retro computer “Agat-7” I needed to generate several different clocks. Some of them can be produced by the PLL built in FPGA, others are a simple division of the main clock. But there is another group of clock signals that are not as simple to get. I use a 50MHz oscillator with FPGA and produce the main system clock of 32.5MHz by PLL. It is perfect for a VGA output in 1024×768 mode and for the CPU clock (32.5 / 32 = 1.016MHz), but it is not good for the TV output which requires 10.5MHz for pixel clock and 17.734475MHz for colour encoding subcarrier. Instead of using additional oscillators, user svofski from zx.pk.ru forum suggested me to use phase accumulator to generate such frequencies in FPGA. It is a quite simple but efficient method that can be also used for generating different waveforms apart of a simple clock signal. You can have more information about it in Wikipedia.
I’ve created a simple calculator to determine constants and accuracy of the generator:
Here is an example of a VHDL code. It generates 17.5MHz output clock from 250MHz clock using a 32-bit accumulator register:
1 2 3 4 5 6 7 8 9 10 11 12
signal acc: std_logic_vector (31 downto 0); -- It is 32-bit phase accumulator. Change if different signal clk_main: std_logic; -- 250MHz main clock source signal clk_gen: std_logic; -- 17.5MHz generated clock signal process(clk_main) -- phase accumulator clock generator (adder) begin if (clk_main'event and clk_main = '1') then acc <= acc + 981707; -- use the calculated number to add it at each step end if; end process; clk_gen <= acc(31); -- use the highest bit of the accumulator for output clock (31 for 32-bit acc.)
The idea of this method is to have an accumulator register (usually at least 32-bit) to which a certain constant is added at each step of the main clock. It causes overflow after certain periods and the remainder goes to the next cycle causing another overflow after some cycles. The generated clock is the highest bit of the accumulator. On a certain step it will take one step less to overflow the accumulator, so the output clock time will be less on this step. The proportion between “long” and “short” timings determines the average output frequency. Higher input frequency will make the difference between “long” and “short” steps less, so the output signal becomes more accurate.Therefore, the disadvantage of this method is unstable duty cycle, especially when the main and the generated frequencies are too close. Here is an example of generating 15MHz clock with a 50MHz main clock:
As you can see, despite of an accurate average frequency of the clock, individual periods are different. If we use a 250MHz main clock the picture becomes much better:
There are still some irregularities in the duty cycle, but they are good enough for most purposes. At least in my project abovementioned TV signals are generated from a 275MHz clock (produced by a PLL multiplication) with this method and the output is quite impressive.
To use the calculator, you need to enter the main clock and the desired clock frequencies as well as the intended length of the accumulator register. The best achievable frequency and its variance against the goal is calculated. If the result is not good enough, try to increase accumulator length.
Also, the calculator shows how the duty cycle fluctuates from period to period compare to the ideal 50% duty cycle. To improve this parameters the initial clock frequency needs to be increased.
The last calculated parameter is the decimal number that needs to be added to the accumulator register at each step of the main clock. This number is used directly in VHDL code.
Of course that method is not universal but can serve as a great tool in many cases, reducing elements in a project or allowing to use cheaper FPGA with less PLLs on board. The calculator helps to assess the drawbacks of the method in each particular situation and make a decision of which method of clock generation to use.
Hope this post will help in you in your projects. See ya!