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

dividing system clock frequency

Jump to solution

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 

0 Kudos
1 Solution

Accepted Solutions
gszakacs
Instructor
Instructor
27,597 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

View solution in original post

10 Replies
yashp
Moderator
Moderator
17,496 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)
0 Kudos
gszakacs
Instructor
Instructor
17,488 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
0 Kudos
studentofdsi
Observer
Observer
17,471 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 ??

0 Kudos
kkn
Moderator
Moderator
17,463 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

0 Kudos
gszakacs
Instructor
Instructor
27,598 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

View solution in original post

studentofdsi
Observer
Observer
17,452 Views
Registered: ‎03-27-2014

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

0 Kudos
gszakacs
Instructor
Instructor
17,441 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
0 Kudos
studentofdsi
Observer
Observer
17,439 Views
Registered: ‎03-27-2014
ok got it..
0 Kudos
gszakacs
Instructor
Instructor
17,436 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
studentofdsi
Observer
Observer
9,721 Views
Registered: ‎03-27-2014

k done..

 

0 Kudos