- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all.
I'm interfacing a CycloneIV-E to a AD9266 ADC and I'm struggling trying to close timings.
FPGA design has one 100MHz pll clock; the adc is clocked with a divide-by-two register (=50MHz); data from adc is 8bit wide, double data rate: it outputs even bits at one 100MHz clock cycle, and odd bits at the next 100MHz clock cycle.
This is the rtl view that generates the 50MHz clock (adc_clk) and latches the data (data[7:0]) to two registers with odd and even data. To avoid muxes (is this a wise choice?) the two latch registers are filled with odd and even bits at the odd and even positions and then or-ed together:
These are the .sdc constraints:
# Clock definition
create_generated_clock -name {ad9266_clk_reg} -source [get_pins {bk39_common_inst|pll_inst|altpll_component|auto_generated|pll1|clk[0]}] -divide_by 2 [get_registers {rf_in:rf_in_inst|ad9266:adc_inst|adc_clk_reg}]
create_generated_clock -name {ad9266_clk} -source [get_registers {rf_in:rf_in_inst|ad9266:adc_inst|adc_clk_reg}] [get_ports {rf_in_adc_clk}]
#delays (from datasheets and pcb design)
set ad9266_dco_tpd_rising_clk_max 4.04
set ad9266_dco_tpd_rising_clk_min 1.86
set ad9266_data_tpd_rising_clk_max 3.9
set ad9266_data_tpd_rising_clk_min 1.84
set ad9266_clk_tpd_delay_max 1.5
set ad9266_clk_tpd_delay_min 0.5
set ad9266_clk_trace_delay_max 0.15
set ad9266_clk_trace_delay_min 0.05
set ad9266_data_trace_delay_max 0.15
set ad9266_data_trace_delay_min 0.05
set ad9266_dco_delay_max [expr $ad9266_data_trace_delay_max + $ad9266_dco_tpd_rising_clk_max - $ad9266_clk_trace_delay_min - $ad9266_clk_tpd_delay_min]
set ad9266_dco_delay_min [expr $ad9266_data_trace_delay_min - $ad9266_dco_tpd_rising_clk_min - $ad9266_clk_trace_delay_max - $ad9266_clk_tpd_delay_max]
set ad9266_data_delay_max [expr $ad9266_data_trace_delay_max + $ad9266_data_tpd_rising_clk_max - $ad9266_clk_trace_delay_min - $ad9266_clk_tpd_delay_min]
set ad9266_data_delay_min [expr $ad9266_data_trace_delay_min - $ad9266_data_tpd_rising_clk_min - $ad9266_clk_trace_delay_max - $ad9266_clk_tpd_delay_max]
#input delay constraints (ddr)
set_input_delay -clock { ad9266_clk } -max $ad9266_dco_delay_max [get_ports {rf_in_adc_dco}]
set_input_delay -clock { ad9266_clk } -min $ad9266_dco_delay_min [get_ports {rf_in_adc_dco}]
set_input_delay -clock { ad9266_clk } -clock_fall -max $ad9266_dco_delay_max [get_ports {rf_in_adc_dco}] -add_delay
set_input_delay -clock { ad9266_clk } -clock_fall -min $ad9266_dco_delay_min [get_ports {rf_in_adc_dco}] -add_delay
set_input_delay -clock { ad9266_clk } -max $ad9266_data_delay_max [get_ports {rf_in_adc_data[*]}]
set_input_delay -clock { ad9266_clk } -min $ad9266_data_delay_min [get_ports {rf_in_adc_data[*]}]
set_input_delay -clock { ad9266_clk } -clock_fall -max $ad9266_data_delay_max [get_ports {rf_in_adc_data[*]}] -add_delay
set_input_delay -clock { ad9266_clk } -clock_fall -min $ad9266_data_delay_min [get_ports {rf_in_adc_data[*]}] -add_delay
Timequest reports all paths failing setup, with ~3.5ns of negative slack:
Tried "Fast input" and "Fast output" assignments:
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to "rf_in:rf_in_inst|ad9266:adc_inst|adc_clk_reg"
set_instance_assignment -name GLOBAL_SIGNAL GLOBAL_CLOCK -to "rf_in:rf_in_inst|ad9266:adc_inst|adc_clk_reg"
set_instance_assignment -name FAST_INPUT_REGISTER ON -to "rf_in:rf_in_inst|ad9266:adc_inst|dco_adc_data_odd"
set_instance_assignment -name FAST_INPUT_REGISTER ON -to "rf_in:rf_in_inst|ad9266:adc_inst|dco_adc_data_even"
But no big improvement:
I've tried to insert a pipeline for data(in) and clock(out):
Updated .sdc constraints:
create_generated_clock -name {ad9266_clk_reg} -source [get_pins {bk39_common_inst|pll_inst|altpll_component|auto_generated|pll1|clk[0]}] -divide_by 2 [get_registers {rf_in:rf_in_inst|ad9266:adc_inst|adc_clk_pipeline}]
create_generated_clock -name {ad9266_clk} -source [get_registers {rf_in:rf_in_inst|ad9266:adc_inst|adc_clk_pipeline}] [get_ports {rf_in_adc_clk}]
Updated fast i/o assignments:
set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to "rf_in:rf_in_inst|ad9266:adc_inst|adc_clk_pipeline"
set_instance_assignment -name FAST_INPUT_REGISTER ON -to "rf_in:rf_in_inst|ad9266:adc_inst|adc_pipeline"
Bit of improvement, but still not a game changer:
Timequest is measuring a beefy delay from I/O pin and the first register:
11.529 3.284 data path
8.245 0.000 FF IC 1 IOIBUF_X0_Y11_N8 rf_in_adc_dco~input|i
9.087 0.842 FF CELL 1 IOIBUF_X0_Y11_N8 rf_in_adc_dco~input|o
11.281 2.194 FF IC 1 FF_X0_Y11_N10 rf_in_inst|adc_inst|adc_pipeline[8]|d
11.529 0.248 FF CELL 1 FF_X0_Y11_N10 rf_in:rf_in_inst|ad9266:adc_inst|adc_pipeline[8]
The contribution of .sdc delay is 3.64ns, about a third of the net delay from IOIBUF_X0_Y11_N8 to FF_X0_Y11_N10.
pipeline register are placed close to I/O, so I quite don't get where this delay is coming from:
pipeline register is then routed to the actual data register, with a "long" path shown in chip planner:
Albeit long in chip planner, the delay is quite short:
report_path -from rf_in:rf_in_inst|ad9266:adc_inst|adc_pipeline[8] -npaths 100 -panel_name {Report Path} -multi_corner
Report Path: Found 16 paths. Longest delay is 2.956
I'm having really a bad times trying to make sense from this data.
Am I missing something? Hints for timings closure?
Thank you!!!
- Tags:
- Timings
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I noticed that the clock skew and data delay are quite large in the failing timing.
Also, why is most of the logic placed in the center in the Chip Planner? It seems congested.
Could there be a location assignment set that might cause this?
If so, try disabling it, as this might limit the fitter's capability to place and route the design in order to meet timing.
Regards,
Richard Tan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
All ports location are pcb driven, no chance to modify them.
Other than these, I didn't find other relevant assignments that could upset the fitter:
set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
set_global_assignment -name GENERATE_RBF_FILE ON
set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name SIMULATION_MODE FUNCTIONAL
set_global_assignment -name POWER_USE_TA_VALUE 50
set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC OFF
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED
set_global_assignment -name TIMING_ANALYZER_DO_REPORT_TIMING ON
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL OFF
set_global_assignment -name SYNCHRONIZER_IDENTIFICATION "FORCED IF ASYNCHRONOUS"
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON
set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON
set_global_assignment -name ROUTER_TIMING_OPTIMIZATION_LEVEL NORMAL
set_global_assignment -name QII_AUTO_PACKED_REGISTERS AUTO
set_global_assignment -name FITTER_EFFORT "AUTO FIT"
set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS OFF
set_global_assignment -name FLOW_ENABLE_RTL_VIEWER ON
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL
set_global_assignment -name TIMING_ANALYZER_REPORT_SCRIPT_INCLUDE_DEFAULT_ANALYSIS OFF
set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON
set_global_assignment -name POST_FLOW_SCRIPT_FILE "quartus_sh:post_build.tcl"
set_global_assignment -name OPTIMIZATION_MODE BALANCED
set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS"
set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON
set_global_assignment -name OPTIMIZE_POWER_DURING_SYNTHESIS "NORMAL COMPILATION"
set_global_assignment -name HDL_MESSAGE_LEVEL LEVEL3
set_global_assignment -name FITTER_AGGRESSIVE_ROUTABILITY_OPTIMIZATION AUTOMATICALLY
set_global_assignment -name AUTO_DELAY_CHAINS_FOR_HIGH_FANOUT_INPUT_PINS ON
set_global_assignment -name MUX_RESTRUCTURE OFF
set_global_assignment -name STATE_MACHINE_PROCESSING AUTO
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 1
set_global_assignment -name ENABLE_OCT_DONE OFF
set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "PASSIVE SERIAL"
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
set_global_assignment -name SAFE_STATE_MACHINE ON
set_global_assignment -name SYNTH_PROTECT_SDC_CONSTRAINT ON
set_global_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION OFF
set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON
set_global_assignment -name ALLOW_ANY_ROM_SIZE_FOR_RECOGNITION ON
set_global_assignment -name ALLOW_ANY_RAM_SIZE_FOR_RECOGNITION ON
set_global_assignment -name ALLOW_ANY_SHIFT_REGISTER_SIZE_FOR_RECOGNITION ON
set_global_assignment -name ALLOW_SHIFT_REGISTER_MERGING_ACROSS_HIERARCHIES ALWAYS
set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA OFF
set_global_assignment -name PHYSICAL_SYNTHESIS_MAP_LOGIC_TO_MEMORY_FOR_AREA ON
set_global_assignment -name AUTO_RAM_RECOGNITION OFF
set_global_assignment -name OPTIMIZE_TIMING "NORMAL COMPILATION"
set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION NEVER
I've relaxed the fitter effort and this result in ~100ps of slack improvement, not a big deal yet.
Chip planner still shows this scenario; the blocks in red contain the adc interface logic with failing paths:
The first of failing paths looks like this in technology map viewer:
Going down the rabbit hole in property editor I can see "Input pin to Input Register Delay" set to 5:
Does this ring a bell? The value is the same for all the failing paths, both for rising and falling clock edges (adc behaves like-ish a ddr device, odd bits can be lathed during rising edge of adc clk, even can be lathed during falling edge).
In assignment editor I specified that adc_clk should be a fast output register and adc_data a fast input register:
This result in actual DDIOOUTCELL usage for clock out, but a regular register for input:
No ignored assignment message in compilation report, but fitter decided not to accept the suggestion and use a regular register.
Could this be the issue?
This is how I (tried to) constrain the input timings, bearing the ddr-ish behavior:
#input delay constraints (ddr)
set_input_delay -clock { ad9266_clk } -max $ad9266_dco_delay_max [get_ports {rf_in_adc_dco}]
set_input_delay -clock { ad9266_clk } -min $ad9266_dco_delay_min [get_ports {rf_in_adc_dco}]
set_input_delay -clock { ad9266_clk } -clock_fall -max $ad9266_dco_delay_max [get_ports {rf_in_adc_dco}] -add_delay
set_input_delay -clock { ad9266_clk } -clock_fall -min $ad9266_dco_delay_min [get_ports {rf_in_adc_dco}] -add_delay
set_input_delay -clock { ad9266_clk } -max $ad9266_data_delay_max [get_ports {rf_in_adc_data[*]}]
set_input_delay -clock { ad9266_clk } -min $ad9266_data_delay_min [get_ports {rf_in_adc_data[*]}]
set_input_delay -clock { ad9266_clk } -clock_fall -max $ad9266_data_delay_max [get_ports {rf_in_adc_data[*]}] -add_delay
set_input_delay -clock { ad9266_clk } -clock_fall -min $ad9266_data_delay_min [get_ports {rf_in_adc_data[*]}] -add_delay
Is something wrong?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Let me know if there is any update from previous reply.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've responded with more details and with the results of the suggested modifications, asking for further suggestions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
From the timing report, seem this issue probably related to CDC. Have you tried to constraint the CDC between the 2 different clocks?
This might be the reason why you are having a large skew. Multicycle path or synchronizer is the way to handle this.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page