cancel
Showing results for
Show  only  | Search instead for
Did you mean:
Observer
17,445 Views
Registered: ‎03-27-2014

## dividing system clock frequency

hi i am using virtex 4 ml403 eval board. the system clock frequency is 100MHZ and i am interfacing an ADC to this fpga board. the Clock requirement of ADC is 500khz and i need to divide the system clock of fpga to 500khz so i can use it as input clock to ADC..can anyone suggest how to implement this and how to write the vhdl code for this..any example code..

thanks

1 Solution

Accepted Solutions
Professor
27,537 Views
Registered: ‎08-14-2007

Your code divides the clock by 2^7 or 256.  That gives 390.625 KHz.  My suggestion to place the clock output in an IOB flip-flop would be easier if you make it registered like:

process(clk)      -- system clock

if rising_edge(clk) then

div <= div +1;

clkdiv <= div(7); -- This adds a register that can easily be pushed in to the IOB (no feedback)

end if;

end process;

If you want to divide by something other than a power of two, then you need to add more logic to restrict the count.  This is one way to divide by 200 with 50% duty cycle:

signal div :natural range is 0 to 199;

signal clkdiv : std_logic;

process(clk)      -- system clock

if rising_edge(clk) then

if div = 99 then

clkdiv <= '1';

elsif div = 199 then

clkdiv <= '0';

div <= 0;

else

div <= div +1;

endif

end if;

end process;

-- Gabor
10 Replies
Moderator
17,436 Views
Registered: ‎01-16-2013

Hello,

To divide frequency in Virtex 4 you can use DCM.

To know more about DCM refer this link: http://www.xilinx.com/support/documentation/user_guides/ug070.pdf {Page # 55}

Thanks,

Yash

Tags (1)
Professor
17,428 Views
Registered: ‎08-14-2007

You can't get such a low frequency from a DCM.  However it's not that hard to generate this frequency using counters.  To get a clean signal at the ADC, I'd recommend using an IOB flip-flop for the output.

100 MHz divided by 500 KHz is 200.

So effectively you want to divide by 200.  If you need a square wave, then the obvious way is to divide the 100 MHz by 100 to get 1 MHz, and then divide that by 2 to get a 50% duty cycle waveform at 500 KHz.

There should be plenty of counter examples in the language templates.

-- Gabor
Observer
17,411 Views
Registered: ‎03-27-2014

could you just put it here ..how to divide using counters..vhdl code of it.. is it something like this..

signal div :std_logic_vector (7 downto 0 );

signal clkdiv;

process(clk)      -- system clock

if rising_edge(clk) then

div <= div +1;

end if;

end process;

clkdiv <= div(7)

will this give me close to 400khz ??

Moderator
17,403 Views
Registered: ‎01-15-2008

Yes, your counter signal clkdiv will be able to drive approx 400 Khz clock when the input clk is 100 Mhz.

--Krishna

Professor
27,538 Views
Registered: ‎08-14-2007

Your code divides the clock by 2^7 or 256.  That gives 390.625 KHz.  My suggestion to place the clock output in an IOB flip-flop would be easier if you make it registered like:

process(clk)      -- system clock

if rising_edge(clk) then

div <= div +1;

clkdiv <= div(7); -- This adds a register that can easily be pushed in to the IOB (no feedback)

end if;

end process;

If you want to divide by something other than a power of two, then you need to add more logic to restrict the count.  This is one way to divide by 200 with 50% duty cycle:

signal div :natural range is 0 to 199;

signal clkdiv : std_logic;

process(clk)      -- system clock

if rising_edge(clk) then

if div = 99 then

clkdiv <= '1';

elsif div = 199 then

clkdiv <= '0';

div <= 0;

else

div <= div +1;

endif

end if;

end process;

-- Gabor
Observer
17,392 Views
Registered: ‎03-27-2014

ok thanks i will try it out.. but i didnt get thst IOB .. what is that ??

Professor
17,381 Views
Registered: ‎08-14-2007

IOB (I think this originally stood for Input/Ouput Block) refers to the logic block associated with each I/O pin.  The flip-flops in these blocks have very consistent timing from clock to output pin, and setup to clock.  It generally makes your board-level design simpler when you use registers in the IOB, especially when you are concerned with the relative timing between output pins (source synchronous design).

-- Gabor
Observer
17,379 Views
Registered: ‎03-27-2014
ok got it..
Professor
17,376 Views
Registered: ‎08-14-2007

I just wanted to clean up some issues with the code I posted earlier.  That code had some syntax errors (sorry VHDL is not my native language).  It also would have gotten stuck with div at 99.  To help in simulation I also added a reset.  Here's the update:

signal clk : STD_LOGIC;
signal rst : STD_LOGIC;
signal clkdiv : STD_LOGIC;

signal div :  natural range 0 to 199;

process (clk)  -- system clock
begin
if rising_edge(clk) then
if (rst = '1') then
div <= 0;
clkdiv <= '0';
elsif div = 99 then
clkdiv <= '1';
div <= div +1;  -- must increment or it gets stuck at 99!
elsif div = 199 then
clkdiv <= '0';
div <= 0;
else
div <= div +1;
end if;
end if;

-- Gabor
Observer
9,661 Views
Registered: ‎03-27-2014

k done..