FreqSwitch

From Hamsterworks Wiki!

Jump to: navigation, search

This FPGA Project was completed in an hour in November 2012.

It is possible to reprogram the multiply and divide values for a DCM_CLKGEN on the fly. Here is a little test program I made. It switches the incoming 32MHz signal to 25MHz, 40Mhz, 64MHz or 74MHz for use in a VGA controller.

See the Spartan 6 Clocking Resources User Guide for for more info.

Source file

----------------------------------------------------------------------------------
-- Engineer: Michael Field <hamster@snap.net.nz>
-- 
-- Description: Make four different clock speeds
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

library UNISIM;
use UNISIM.VComponents.all;

entity dcm_clockgen_test is
    Port ( clk_in  : in  STD_LOGIC;
           clk_out : out STD_LOGIC;
           sw      : in  STD_LOGIC_VECTOR (3 downto 0));
end dcm_clockgen_test;

architecture Behavioral of dcm_clockgen_test is
   signal prog_data_sr : std_logic_vector(27 downto 0) := (others => '0');
   signal prog_en_sr   : std_logic_vector(27 downto 0) := (others => '0');
   
   signal prog_data    : std_logic;
   signal prog_en      : std_logic;
   
   signal desired_mode: std_logic_vector(3 downto 0)   := "0001";
   signal current_mode: std_logic_vector(3 downto 0)   := "0000";
begin
   prog_data <= prog_data_sr(0);
   prog_en   <= prog_en_sr(0);
   
process(clk_in)
   begin
      if rising_edge(clk_in) then
         -- Update the clock reprogramming signals
         prog_en_sr   <= '0' & prog_en_sr((prog_en_sr'length)-1 downto 1);
         prog_data_sr <= '0' & prog_data_sr((prog_data_sr'length)-1 downto 1);
         
         -- Do we need to switch modes? 
         if desired_mode /= current_mode and unsigned(prog_en_sr) = 0 then
            case desired_mode is 
            when "0001"  =>
               -- switch to 25MHz
               prog_en_sr   <= "1000" & "11111111" & "11" & "0000" & "11111111" & "11"; -- Two 10-bit xfers + 1-bit 'go'
               prog_data_sr <= "0000" & "00001010" & "11" & "0000" & "00001101" & "01"; -- Code for D 14 M 11
               current_mode <= desired_mode;

            when "0010"  =>
               -- switch to 40MHz
               prog_en_sr   <= "1000" & "11111111" & "11" & "0000" & "11111111" & "11"; -- Two x 10-bit xfers + 1-bit 'go'
               prog_data_sr <= "0000" & "00000100" & "11" & "0000" & "00000011" & "01"; -- Code for D 5 M 4
               current_mode <= desired_mode;

            when "0100"  =>
               -- switch to 64.0MHz 
               prog_en_sr   <= "1000" & "11111111" & "11" & "0000" & "11111111" & "11"; -- Two x 10-bit xfers + 1-bit 'go'
               prog_data_sr <= "0000" & "00000001" & "11" & "0000" & "00000000" & "01" ; -- Code for D 1 M 2
               current_mode <= desired_mode;

            when "1000"  =>
               -- switch to 74.6MHz
               prog_en_sr   <= "1000" & "11111111" & "11" & "0000" & "11111111" & "11"; -- Two x 10-bit xfers + 1-bit 'go'
               prog_data_sr <= "0000" & "00000110" & "11" & "0000" & "00000010" & "01" ; -- Code for D 3 M 7
               current_mode <= desired_mode;

            when others =>
            
            end case;
         end if;
         if sw /= "0000" then
            desired_mode <= sw;
         end if;
      end if;
   end process;

DCM_CLKGEN_inst : DCM_CLKGEN
   generic map (
      CLKFXDV_DIVIDE => 2,    
      CLKFX_DIVIDE   => 14,   
      CLKFX_MD_MAX   => 2.0,  
      CLKFX_MULTIPLY => 11,   
      CLKIN_PERIOD   => 31.25, 
      SPREAD_SPECTRUM => "NONE", 
      STARTUP_WAIT => FALSE
   )
   
   port map (
      CLKIN     => clk_in,   
      CLKFX     => clk_out,  
      CLKFX180  => open,     
      CLKFXDV   => open,     
      LOCKED    => open,     
      PROGDONE  => open,     
      STATUS    => open,     
      FREEZEDCM => '0',      
      PROGCLK   => clk_in,   
      PROGDATA  => PROG_DATA,
      PROGEN    => PROG_EN,  
      RST       => '0'       
   );

end Behavioral;

Personal tools