08-06-2013 07:56 AM
Hello Xilinx,
(using a Spartan 3A 400A)
I just want to clarify the Dcm Lock status output. If using any signals output from the DCM the user should check at all times to see the lock is high before assigning the outputting clocks?
For example,
I have a DCM :
DCM_SP_inst : DCM_SP
generic map (
CLKDV_DIVIDE => 15.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, -- Can be any interger from 1 to 32
CLKFX_MULTIPLY => 5, -- Can be any integer from 1 to 32
CLKIN_DIVIDE_BY_2 => FALSE, -- TRUE/FALSE to enable CLKIN divide by two feature
CLKIN_PERIOD => 40.0, -- Specify period of input clock
CLKOUT_PHASE_SHIFT => "NONE", -- Specify phase shift of "NONE", "FIXED" or "VARIABLE"
CLK_FEEDBACK => "1X", -- Specify clock feedback of "NONE", "1X" or "2X"
DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", -- "SOURCE_SYNCHRONOUS", "SYSTEM_SYNCHRONOUS" or
-- an integer from 0 to 15
DLL_FREQUENCY_MODE => "LOW", -- "HIGH" or "LOW" frequency mode for DLL
DUTY_CYCLE_CORRECTION => TRUE, -- Duty cycle correction, TRUE or FALSE
PHASE_SHIFT => 0, -- Amount of fixed phase shift from -255 to 255
STARTUP_WAIT => FALSE) -- Delay configuration DONE until DCM_SP LOCK, TRUE/FALSE
port map (
CLK0 => clk_fb, -- 0 degree DCM CLK ouptput
CLK180 => open, -- 180 degree DCM CLK output
CLK270 => open, -- 270 degree DCM CLK output
CLK2X => clk50, -- 2X DCM CLK output
CLK2X180 => open, -- 2X, 180 degree DCM CLK out
CLK90 => open, -- 90 degree DCM CLK output
CLKDV => clkdiv15, -- Divided DCM CLK out (CLKDV_DIVIDE)
CLKFX => clk125, -- DCM CLK synthesis out (M/D)
CLKFX180 => open, -- 180 degree CLK synthesis out
LOCKED => clk_lock, -- DCM LOCK status output
PSDONE => open, -- Dynamic phase adjust done output
STATUS => open, -- 8-bit DCM status bits output
CLKFB => clk_fb, -- DCM clock feedback
CLKIN => clk_25Mhz, -- Clock input (from IBUFG, BUFG or DCM)
PSCLK => open, -- Dynamic phase adjust clock input
PSEN => open, -- Dynamic phase adjust enable input
PSINCDEC => open, -- Dynamic phase adjust increment/decrement
RST => '0' -- DCM asynchronous reset input
);
and I have these statements:
clk50MHz <= clk50 when clk_lock = '1' else '0';
clk125MHz <= clk125 when clk_lock = '1' else '0';
clkdiv_15 <= clkdiv15 when clk_lock = '1' else '0';
Is this a reasonable thing to do? What is the normal practice with the DCM lock? I am just trying to fully understand the DCM. Does my dcm instantiation look correct?
Thanks
For the help
08-06-2013 08:09 AM
c,
Your last three statements are not required, and will probably cause all sorts of problems.
LOCKED means the clocks are valid. If you are not locked, there is nothing that can be said about the outputs (they may, or may not be toggling, and the frequencies and duty cycles are nothing useful, or even predictable).
If you wish to switch clocks, you should use the BUFGMUX (look it up). Generally speaking, this is not needed -- nothing "bad" happens if a clock is indeterminate to the logic or flip flops -- it just doesn't do what you want it to.
So one ould follow each output with a BUFGMUX, and switch to a valid clock, based on the status. Or one can use a BUFGCE, and turn off, and on, global clocks, based on the status (but again, it is most often not required to do this).
Also, LOCKED is only valid, if the DCM has an input clock (it is synchronous). So the other very useful status bit is CLOCK_LOST which asserts if there is no clock (and none of the other status bits are valid if the clock is lost, so ALWAYS check this first!).
08-06-2013 08:09 AM
c,
Your last three statements are not required, and will probably cause all sorts of problems.
LOCKED means the clocks are valid. If you are not locked, there is nothing that can be said about the outputs (they may, or may not be toggling, and the frequencies and duty cycles are nothing useful, or even predictable).
If you wish to switch clocks, you should use the BUFGMUX (look it up). Generally speaking, this is not needed -- nothing "bad" happens if a clock is indeterminate to the logic or flip flops -- it just doesn't do what you want it to.
So one ould follow each output with a BUFGMUX, and switch to a valid clock, based on the status. Or one can use a BUFGCE, and turn off, and on, global clocks, based on the status (but again, it is most often not required to do this).
Also, LOCKED is only valid, if the DCM has an input clock (it is synchronous). So the other very useful status bit is CLOCK_LOST which asserts if there is no clock (and none of the other status bits are valid if the clock is lost, so ALWAYS check this first!).
08-06-2013 09:29 AM - edited 08-06-2013 09:33 AM
Austin is correct about gating the clock outputs with the DCM locked signal. It's bad.
Here's what I do. I use the DCM locked as the async reset of a small shift register. The various DCM clock outputs each clock such a shift register. The shift registers create a synchronous reset in each of the clock domains. Something like this:
signal iReset50_sr : std_logic_vector(3 downto 0);
alias sReset50 : std_logic is iReset50_sr(iReset50_sr'left);
-- an async reset is needed here because the clock won't be
-- running when the DCM isn't locked.
Reset50MHz : process (clk50, dcmLocked) is
begin
if dcmLocked = '0' then
iReset50_sr <= (others => '1'); -- assume active-high reset downstream
elsif rising_edge(clk50) then
iReset50_sr <= iReset50_sr(iReset50_sr'left - 1 downto 0) & '0';
end if;
end process Reset50MHz;
-- some process which runs on the 50 MHz clock and needs a reset.
-- Note reset is synchronous.
MyLogic : process(clk50) is
begin
if rising_edge(clk50) then
if sReset50 = '1' then
myFlopFoo <= '0';
myVectorBar <= (others => '0');
else
if bletch = '1' then
myFlopFoo <= bazinga;
myVectorBar <= bogus;
end if;
end if;
end process MyLogic;
So you do one of those little shift registers for each clock domain. The length of the shift register is somewhat arbitrary; if it's 16 or less it'll fit into an SRL16 and use only one LUT.
The point of all of this is that the stuff clocked by the DCM outputs gets reset properly once the clocks start running, since the reset is held asserted for a few clocks.
if you really need to ensure that downstream stuff goes to a known benign state when the clocks are not running, you can use the shift register's output as an async reset.
08-06-2013 10:10 AM
Thanks for the explanation A and B.
I like the way you are doing the synchronous reset based on dcm_locked.
I knew what I suggested was wrong but it seemed the easiest way to ask the question :).
In my particular application I do not want to reset based on a DCM losing lock. I would however like to Log a fault, so instead of using it to gate my clock, I will just store the lock in a register and write it to my flash to log the status of dcm lock. I already have other mechanisms in my system that will trigger other faults if the clock's start working unproperly.
10-31-2013 07:53 PM
Austin, you said:
"Also, LOCKED is only valid, if the DCM has an input clock (it is synchronous). So the other very useful status bit is CLOCK_LOST which asserts if there is no clock (and none of the other status bits are valid if the clock is lost, so ALWAYS check this first!)."
Where is the CLOCK_LOST status?
I'm using a Virtex-5, not a spartan, but I don't see any such status output on the DCM.
It'd be useful to have, since right now I'm trying to figure out why the DCM's LOCKED output doesn't go to 0 when I force the input clk to a steady 0 in simulation. (not sure yet if it works any better in real hardware)
I'm trying to provide some decent clock status and if there is a CLOCK_LOST somewhere, I'd sure love to know where/how.
thanks
jeff
11-04-2013 10:40 PM
Hello Jeff,
In fact, de DCM LOCKED does not go low when the input clock stopped. The locked signal keeps his logic '1' vaue.
The CLKIN stopped status is indicated by the DO(1) bit. See UG190 page 56.
Good luck,
Jasper