Use a phase accumulator approach rather than a divider. That way, you can
set the exact frequency. It will introduce some jitter with a peak
deviation of 1/2 your master clock period. The phase accumulator
(sometimes described as a direct digital synthesizer) is simply a
registered adder with one input coming from its output and the other set
to a constant increment value. The adder output represents a fraction of
a cycle of your desired oscillator. For a square wave output, you use
just the MSB of the output as your clock or as a clock enable. The width
of the adder determines the frequency resolution. The output frequency is
Fo= Fc * N/ (2^bits)
In the case of generating a 115.2Khz clock from a 50 MHz master:
Lets assume you want 0.1% accuracy, which is to say 115.2KHz +/- 115 Hz.
You need enough bits to have at least 230Hz resolution, so
230 = 50,000,000 * 1/(2^bits) tells us we need 18 bits in the
accumulator. 18 bits gives us a frequency resolution of 191 Hz.
Now, find the constant N that provides the 115.2KHz
115200 = 50M * N/2^18 ===> N=604.
plugging that back in you get an output frequency of 115203.9Hz. If you
needed more accuracy, you could increase the width of the accumulator.
signal accum:unsigned(17 downto 0);
begin
process(clk,reset)
if reset='1' then
accum<=(others=>'0');
elsif rising_edge(clk) then
accum<= accum+to_unsigned(604,18);
end if;
end process;
baud_clk<= accum(accum'left);
Now if you want to change the baud rate, all you need to do is change the
constant. The baud_clock is proportional to the constant. The output
taken from the msb of the accumulator is a square wave with approximately
50% duty cycle (there is a little bit of jitter +/- a half master clock
cycle) if the constant results in a non-integer division of the master
clock. That little bit of jitter is quite acceptable for serial comms.
I am trying to write a clock divider that will be used for input from
a serial port that is outputting data at 115200 baud. This means I
would need a clk that runs at 115.2 kHz. My on board clk is currently
running at 50 MHz (oscillator). One option is to add another clk to
my design using a second oscillator but I would prefer to find another
option since this will drive up costs. Is there an easy way to divide
50 MHz downto 115.2 kHz using VHDL?
--
--Ray Andraka, P.E.
President, the Andraka Consulting Group, Inc.
401/884-7930 Fax 401/884-7950
email (e-mail address removed)
http://www.andraka.com
"They that give up essential liberty to obtain a little
temporary safety deserve neither liberty nor safety."
-Benjamin Franklin, 1759