Spartan-6 DCM_CLKGEN -- unexpected derived timing constraints - Page 1
Forum section: electronics / general

author: ebastler
author_rank: Super Contributor
timestamp: June 15, 2020, 06:42:53 am
content: As discussed in another thread here, I have been spending too much time staring at Xilinx timing reports lately... (https://www.eevblog.com/forum/fpga/xilinx-ise-how-to-improve-erratic-timing-optimization/-- many thanks again for all your helpful comments there!) During that effort, I noticed an unexpected constraint which the timing analysis derives.I am using a DCM_CLKGEN primitive to generate my 100 MHz main clock from the 25 MHz external clock input. (I chose DCM_CLKGEN for its low power consumption compared to a PLL, and lower output jitter compared to DCM_SP.)Code:dcm_clkgen_inst: DCM_CLKGENgeneric map(CLKFXDV_DIVIDE => 2,CLKFX_DIVIDE => 1,CLKFX_MULTIPLY => 4,SPREAD_SPECTRUM => "NONE",STARTUP_WAIT => FALSE,CLKIN_PERIOD => 40.0,CLKFX_MD_MAX => 0.000)port map-- Input clock(CLKIN => clkin1,-- Output clocksCLKFX => clkfx,CLKFX180 => clkfx180_unused,CLKFXDV => clkfxdv_unused,-- Ports for dynamic phase shiftPROGCLK => '0',PROGEN => '0',PROGDATA => '0',PROGDONE => progdone_unused,-- Other control and status signalsFREEZEDCM => '0',LOCKED => locked_internal,STATUS => status_internal,RST => '0');The output frequency on CLKFX is the input frequency multiplied by 4, plain and simple. But the timing analysis thinks it needs to deal with a frequency multipled by 16, thesquareof the actual multiplier:Code:Timing constraint: PERIOD analysis for net "clock_main_inst/clkfx" derived fromNET "clk_i_IBUF" PERIOD = 40 ns HIGH 50%; divided by 16.00 to 2.500 nS andduty cycle corrected to HIGH 1.250 nSLikewise, I generate an 48 MHz USB clock by another DCM_CLKGEN. The real multiplier is 48/25 = 1.92, but the timing analysis looks at a period divided by 1.922= 3.69:Code:Timing constraint: PERIOD analysis for net "clock_usb_inst/clkfx" derived fromNET "clk_i_IBUF" PERIOD = 40 ns HIGH 50%; divided by 3.69 to 10.851 nS andduty cycle corrected to HIGH 5.425 nSUnless I "overrule" these derived constraints by manually setting period constraints for the 100 MHz and 48 MHz clocks, they are carried forward through the full timing analysis of the design. Setting the manual constraints is easy, of course, but I would like to understand what's going on here...So what gives?! Is this a plain old bug, or is something really happening at that fast rate? (Maybe some feedback mechanism -- although the DCM_CLKGEN mode does not really support that?) Or am I doing something wrong? (The most likely cause...) Thanks for your insights!

author: dnotq
author_rank: Contributor
timestamp: July 01, 2020, 10:08:32 am
content: I too have spent too many hours lately fussing with Xilinx DCM / PLL clocking. I always use the Core Generator to get the HDL file created quickly, then modify it if necessary. What I notice about the code you have below is, you don't have any of the "attributes" that the Core Generator produces.I believe those attributes auto-generate the constraints, and if you don't have the attributes, you need to add the constraints manually. I don't think the tools look at that actual inputs to the primitive to determine the timing constraints for the design.I have not tested this, however I was in a situation the other night where ISE was blowing an error that my clock period of 24.444ns did not meet the actual period of 24.4444444ns. It was very frustrating. The 24.444 was the "CLKIN_PERIOD" of the primitive (and put there by the Core Generator), but the 24.4444444 was a *calculated* value that was part of timing constraints that were auto-generated during synthesis and used in the mapping or place-and-route.Even if I changed the 24.444 to 24.4444444 in the primitive, it still bitched about a mis-match (the calculated value being compared is certainly held internally in a float or double, and the text converted to a value would never match exactly). I even tried manually adding the correct period as a timing constraints in my UCF file, but ISE then warned me that my manual constraints were being ignored due to the auto-generated constraints that were defined during synthesis.The only thing I could come up with was that those "attributes" were the cause of the auto-constraints, but I did not bother to test that. I commented out the "CLKIN_PERIOD" parameter, the warning went away, and the timing analysis had the correct values. I think you need to add the attributes.Here is the section of my PLL primitive I was fighting with. Note, I broke the attributes line for posting in the forum. In the HDL file, it is one long line.Code:architecture xilinx of clk_21m48 isattribute CORE_GENERATION_INFO : string;attribute CORE_GENERATION_INFO of xilinx : architecture is "clk_21m48,clk_wiz_v3_6,{component_name=clk_21m48,use_phase_alignment=true,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=24.444,clkin2_period=24.444,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 connectorssignal clkin1 : std_logic;-- Output clock bufferingsignal 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_40m909_i;-- Clocking primitive---------------------------------------- Instantiation of the DCM primitive-- * Unused inputs are tied off-- * Unused outputs are labeled unuseddcm_sp_inst: DCM_SPgeneric map(CLKDV_DIVIDE => 2.000,CLKFX_DIVIDE => 20,CLKFX_MULTIPLY => 21,CLKIN_DIVIDE_BY_2 => TRUE,-- Having this defined causes a warning due to a synthesizer rounding error-- since it *calculates* the period and generates constraints that cannot be-- overridden by a user constraint in the UCF file. Stupid.--CLKIN_PERIOD => 24.444,CLKOUT_PHASE_SHIFT => "NONE",CLK_FEEDBACK => "1X",DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",PHASE_SHIFT => 0,STARTUP_WAIT => FALSE)port map-- Input clock