rgeries

Driving multiple DCMs

Recommended Posts

Hello,

I recently ran into a problem driving multiple DCM's from a single external clock source. Ive looked around for solutions and become familiar with Xilinx's documentation for the Spartan's DCM layout. The problem is that you cannot drive more than one DCM from the same external signal because when mapping it will try to duplicate the input clock buffer [1]. The solution is that you must buffer the external signal using IBUF and specifiy the DCMs to be driven by this internal signal. I've implemented a buffer to do this [2] and drive each DCM with this buffered signal. However, I still run into mapping errors when compiling the project. I am not on a computer with my source code or mapping errors at the moment, however I wanted to see if anyone had any insight about this.

References:

[1] http://forums.xilinx.com/t5/Spartan-Family-FPGAs/Two-parallel-DCMs-on-Spartan3e/td-p/182856

[2] http://www.cs.indiana.edu/hmg/le/project-home/xilinx/ise_8.1/doc/usenglish/de/libs/lib/ibuf4816.pdf

Share this post


Link to post
Share on other sites

So what works for me, and it can be frustrating to get it just right, is the following:

 

I put an IBUFG on the input clock signal from the oscillator, I feed this into one of the DCM's and then I feed the output from the IBUFG to the input of that DCM but also back out of the DCM's module. Like this:

(Please note, this is a simplified version of what I actually use. I didn't test this code, I just post it to illustrate what works for me.)

The key here is that I'm feeding clkin into a IBUFG and sending it back out of the module as clk_osc_32Mhz.

library IEEE;use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; use ieee.numeric_std.all;library UNISIM;use UNISIM.VCOMPONENTS.all;entity clkgen is  port (         clkin:  in std_logic;	 clk_1Mhz_out: out std_logic;	 clk_osc_32Mhz: out std_logic  );end entity clkgen;architecture behave of clkgen issignal clkin_i_1mhz: std_logic;signal clkfb_1mhz: std_logic;signal clk0_1mhz: std_logic;begin  clk_osc_32Mhz <= clkin_i;  -- Clock buffers     clkin_inst: IBUFG    port map (      I =>  clkin,      O =>  clkin_i    );   DCM_inst_1mhz : DCM  generic map (    CLKDV_DIVIDE => 16.0, -- Divide by: 1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,5.5,6.0,6.5,7.0,7.5,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0 or 16.0    CLKFX_DIVIDE => 1,--8, -- Can be any integer from 1 to 32    CLKFX_MULTIPLY => 3,--23, -- Can be any integer from 1 to 32    CLKIN_DIVIDE_BY_2 => TRUE, -- TRUE/FALSE to enable CLKIN divide by two feature    CLKIN_PERIOD => 31.25, -- Specify period of input clock    CLKOUT_PHASE_SHIFT => "NONE", -- Specify phase shift of NONE, FIXED or VARIABLE    CLK_FEEDBACK => "NONE", -- Specify clock feedback of NONE, 1X or 2X    DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or an integer from 0 to 15    DFS_FREQUENCY_MODE => "LOW", -- HIGH or LOW frequency mode for frequency synthesis    DLL_FREQUENCY_MODE => "LOW", -- HIGH or LOW frequency mode for DLL    DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE    FACTORY_JF => X"C080", -- FACTORY JF Values    PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255 to 255    STARTUP_WAIT => FALSE -- Delay configuration DONE until DCM LOCK, TRUE/FALSE    )  port map (    CLK0 => clk0_1mhz, -- 0 degree DCM CLK ouptput    CLKIN => clkin_i, -- Clock input (from IBUFG, BUFG or DCM)  );  clkfx_inst_1mhz: BUFG    port map (      I => dcmclock_1mhz,      O => clk_1Mhz_out    );   end behave;

When I want to implement another DCM in its own module I feed the clk_osc_32Mhz signal as the 2nd DCM's input clock. You then have to put it through a BUFG like so:

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;use ieee.numeric_std.all;library unisim;use unisim.vcomponents.all;entity clk_32to25_dcm isport (-- Clock in ports  CLK_IN1           : in     std_logic;  -- Clock out ports  CLK_OUT1          : out    std_logic );end clk_32to25_dcm;architecture xilinx of clk_32to25_dcm is  attribute CORE_GENERATION_INFO : string;  attribute CORE_GENERATION_INFO of xilinx : architecture is "clk_32to25_dcm,clk_wiz_v3_6,{component_name=clk_32to25_dcm,use_phase_alignment=false,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,feedback_source=FDBK_AUTO,primtype_sel=DCM_SP,num_out_clk=1,clkin1_period=31.25,clkin2_period=31.25,use_power_down=false,use_reset=false,use_locked=false,use_inclk_stopped=false,use_status=false,use_freeze=false,use_clk_valid=false,feedback_type=SINGLE,clock_mgr_type=AUTO,manual_override=false}";	  -- Input clock buffering / unused connectors  signal clkin1            : std_logic;  -- Output clock buffering  signal clkfb             : std_logic;  signal clk0              : std_logic;  signal clkfx             : std_logic;  signal clkfbout          : std_logic;  signal locked_internal   : std_logic;  signal status_internal   : std_logic_vector(7 downto 0);begin  -- Input buffering  --------------------------------------  --clkin1 <= CLK_IN1;  clkin2_inst: BUFG    port map (      I =>  CLK_IN1,      O =>  clkin1    );  -- Clocking primitive  --------------------------------------    -- Instantiation of the DCM primitive  --    * Unused inputs are tied off  --    * Unused outputs are labeled unused  dcm_sp_inst: DCM_SP  generic map   (CLKDV_DIVIDE          => 2.000,    CLKFX_DIVIDE          => 32,    CLKFX_MULTIPLY        => 25,    CLKIN_DIVIDE_BY_2     => FALSE,    CLKIN_PERIOD          => 31.25,    CLKOUT_PHASE_SHIFT    => "NONE",    CLK_FEEDBACK          => "NONE",    DESKEW_ADJUST         => "SYSTEM_SYNCHRONOUS",    PHASE_SHIFT           => 0,    STARTUP_WAIT          => FALSE)  port map   -- Input clock   (CLKIN                 => clkin1,    CLKFB                 => clkfb,    -- Output clocks    CLK0                  => clk0,    CLK90                 => open,    CLK180                => open,    CLK270                => open,    CLK2X                 => open,    CLK2X180              => open,    CLKFX                 => clkfx,    CLKFX180              => open,    CLKDV                 => open,   -- Ports for dynamic phase shift    PSCLK                 => '0',    PSEN                  => '0',    PSINCDEC              => '0',    PSDONE                => open,   -- Other control and status signals    LOCKED                => locked_internal,    STATUS                => status_internal,    RST                   => '0',   -- Unused pin, tie low    DSSEN                 => '0');  -- Output buffering  -------------------------------------  -- no phase alignment active, connect to ground  clkfb <= '0';--  clkout1_buf : BUFG--  port map--   (O   => CLK_OUT1,--    I   => clkfx);CLK_OUT1 <= clkfx;end xilinx;

Hope this helps.

 

Jack.

Share this post


Link to post
Share on other sites

Ah ok. I didn't try a second internal clock buffer. I will try this out as soon as I get a chance. Thank you for your help.

 

Just out of curiousity, do you know if the IBUFG just can't drive multiple DCMs? And if so would it also help to buffer this signal (clkin1) to all of the DCMs and not exclude the first DCM?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now