UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Explorer
Explorer
4,129 Views
Registered: ‎04-16-2009

Cascading DCMs with 2x

Jump to solution

I use cascading like here. The first DCM produces frequency while second splits it into multiple phases.

 

The source is 100 MHz. Dividing seems ok. But, as soon as I use the first DCM for 2x or Fx with a factor larger than 1, the following DCM locks but runs unstably and even slower than 1x. Yet, the timing analisys tools calculate like period is shortened 2x. The cascaded DCM may not even start after power reset.

 

 

 

 

 

 

 

0 Kudos
1 Solution

Accepted Solutions
Xilinx Employee
Xilinx Employee
5,233 Views
Registered: ‎01-03-2008

Re: Cascading DCMs with 2x

Jump to solution

You should be using

 

  IF rising_edge(clock) THEN


instead of

 

 WAIT UNTIL clock = '1';

 

The first will generate an edge sensitive d flip/flop register, the second will generate a latch and latches are bad.

 

The "reset_dcm1" process doesn't actually do anything as far as I can tell.

 

 

------Have you tried typing your question into Google? If not you should before posting.
Too many results? Try adding site:www.xilinx.com
4 Replies
Explorer
Explorer
4,110 Views
Registered: ‎04-16-2009

Re: Cascading DCMs with 2x

Jump to solution

The situation is not improving. Let me give the minimal example

 

 

-- DCMs work unreliably. FX (x2/2) may not run. Both FX timers may run at twice lower speed.
	 
library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
entity CLKEN_DIVIDER is 
port (
	CLK: std_logic;
	OUTPUT: inout std_logic := '0'
);
end CLKEN_DIVIDER;	  	 

architecture RTL of CLKEN_DIVIDER is
begin 
	process variable delay, delay_reg: integer range 0 to 100000011 := 0; 
		variable overrun: boolean := false;	  
		
	begin 
		wait until CLK = '1';
			
		overrun := delay_reg = 100000000;
		-- synthesis translate_off
		overrun := delay_reg = 100;
		-- synthesis translate_on
		
		delay_reg := delay;
		delay := delay + 1;
		if overrun then 
			OUTPUT <= not OUTPUT;
			delay := 0;
		end if;
	end process;

end architecture;

library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.Vcomponents.ALL;

entity DCM_BLOCK is
   port ( 
          CLKIN        : in    std_logic; 
		  LEDS: inout unsigned(3 downto 0) := "0000"
          );
end DCM_BLOCK;		

architecture BEHAVIORAL of DCM_BLOCK is
   signal CLKIN_IBUFG     : std_logic;
   signal GND_BIT         : std_logic;
   signal VCC_BIT         : std_logic;	
		  signal  CLK2x_BUFG, speedFB, SpeedFB_BUFG: std_logic;	 
		  
		signal CLK2x: std_logic;  
		signal DCM1_RESET, DCM2_RESET: std_logic := '1';
	  signal CLK0_unbuffered: std_logic; -- do we need buffering it?
	  signal CLK0, DCM1_LOCKED, DCM2_LOCKED: std_logic; -- do we need buffering it?

begin
   GND_BIT <= '0';
   VCC_BIT <= '1';
   CLKIN_IBUFG_INST : IBUFG
      port map (I=>CLKIN,
                O=>CLKIN_IBUFG);
				
   DCM1 : DCM
   generic map( CLK_FEEDBACK => "1X",
            CLKDV_DIVIDE => 2.0, 
            CLKFX_DIVIDE => 1,
            CLKFX_MULTIPLY => 2,
            CLKIN_DIVIDE_BY_2 => FALSE,
            CLKIN_PERIOD => 10.000,
            CLKOUT_PHASE_SHIFT => "NONE",
            DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
            DFS_FREQUENCY_MODE => "LOW",
            DLL_FREQUENCY_MODE => "LOW",
            DUTY_CYCLE_CORRECTION => TRUE,
            FACTORY_JF => x"C080",
            PHASE_SHIFT => 0,
            STARTUP_WAIT => FALSE)
      port map (CLKFB=>SpeedFB_BUFG,
                CLKIN=>CLKIN_IBUFG,
                DSSEN=>'0',
                PSCLK=>'0',
                PSEN=>'0',
                PSINCDEC=>'0',
                RST=>'0',
                CLK0=>speedFB,
                CLK2X=>CLK2x,
                LOCKED=>DCM1_LOCKED);	 
					  
    SpeedFB_BUFG_INST : BUFG port map (I=>SpeedFB, O=>SpeedFB_BUFG); -- do we need the buffers?
	BUFG_INST : BUFG port map (I=>CLK2x, O=>CLK2x_BUFG);
					
	-- as proposed in http://joule.bu.edu/~hazen/mulan/WFD_docs/dcmreset.pdf
	RESET_DCM1: process 
		variable cnt: integer range 15 downto 0 := 15;
	begin
		wait until CLKIN_IBUFG = '1';
		if CNT = 0 then 
			DCM1_RESET <= '0';
		else 
			CNT := CNT - 1;
		end if;
	end process;
		
	-- Virtex-II Pro User Guide: Use the LOCKED output from DCM1 to create a Reset for DCM2. The recommended
	--length of a Reset pulse is three CLKIN cycles. The LOCKED signal from DCM1 could
	--be inverted to LOCKED and used as the input to an SRL16							
	RESET_DCM2 : SRL16
   port map (Q => DCM2_RESET,
             A0 => '1',	-- If A3, A2, A1, and A0 are all zeros (0000), the shift register is one bit long. 
             A1 => '1', -- If they are all ones (1111), it is 16 bits long. 
             A2 => '1',
             A3 => '1',
             CLK => SpeedFB_BUFG,
			 	--SPEED_BUFG, -- not stable
             D => "not"(DCM1_LOCKED)); 
			 
   DCM2 : DCM
   generic map( CLK_FEEDBACK => "1X",
            CLKDV_DIVIDE => 2.0,
            CLKFX_DIVIDE => 1,
            CLKFX_MULTIPLY => 4,
            CLKIN_DIVIDE_BY_2 => FALSE,
            CLKIN_PERIOD => 5.000, -- this seems affecting nothing
            CLKOUT_PHASE_SHIFT => "NONE",
            DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
            DFS_FREQUENCY_MODE => "LOW",
            DLL_FREQUENCY_MODE => "LOW",
            DUTY_CYCLE_CORRECTION => TRUE,
            FACTORY_JF => x"C080",
            PHASE_SHIFT => 0,
            STARTUP_WAIT => FALSE)
      port map (
			  	CLKFB=> CLK0,  
                CLKIN=>	CLK2x,
                DSSEN=>'0',
                PSCLK=>'0',
                PSEN=>'0',
                PSINCDEC=>'0',
                RST=> DCM2_RESET,
                CLK0=>CLK0_unbuffered,
                LOCKED=>DCM2_LOCKED
		);
    BUFG0_INST : BUFG  port map (I=>CLK0_unbuffered, O=>CLK0);
 
	-- LED 0 and 1 are in-phase. 
-- LED 2 is unstable rather than a copy of LED1
CLKEN_DIVIDER1: entity CLKEN_DIVIDER port map (CLK => CLKIN_IBUFG, OUTPUT=> LEDS(0)); CLKEN_DIVIDER2: entity CLKEN_DIVIDER port map (CLK => CLK2x_BUFG, OUTPUT=> LEDS(1)); CLKEN_DIVIDER3: entity CLKEN_DIVIDER port map (CLK => CLK0, OUTPUT=> LEDS(2)); LEDS(3) <= not DCM2_LOCKED; end BEHAVIORAL;

 

Just clock input and four leds to reproduce in v2p.

 

0 Kudos
Xilinx Employee
Xilinx Employee
5,234 Views
Registered: ‎01-03-2008

Re: Cascading DCMs with 2x

Jump to solution

You should be using

 

  IF rising_edge(clock) THEN


instead of

 

 WAIT UNTIL clock = '1';

 

The first will generate an edge sensitive d flip/flop register, the second will generate a latch and latches are bad.

 

The "reset_dcm1" process doesn't actually do anything as far as I can tell.

 

 

------Have you tried typing your question into Google? If not you should before posting.
Too many results? Try adding site:www.xilinx.com
Explorer
Explorer
4,097 Views
Registered: ‎04-16-2009

Re: Cascading DCMs with 2x

Jump to solution

You rock!

 

Resetting the first DCM stabilizes the second.

 

But, you are wrong regarding the wait until = '1'. According to definition, it triggers when there is event and new value is '1'. The event means FF. The article says that we should avoid latches if possible and recommends wait-until for synthesis. And, I know that Xilinx does support wait-until synthesis properly (not that good as Quartus, of course, but in simple situations it accepts the construction and produces what is needed - FFs). 

0 Kudos
Xilinx Employee
Xilinx Employee
4,094 Views
Registered: ‎01-03-2008

Re: Cascading DCMs with 2x

Jump to solution

I use Verilog far more than I use VHDL and my expectations do not appear to match what the synthesizer produced for the wait statement.

 

I would strongly encourage you to adopt the rising_edge style for defining your registers as this is the defacto standard.

------Have you tried typing your question into Google? If not you should before posting.
Too many results? Try adding site:www.xilinx.com
0 Kudos