[ad_1]
Hello all.
I am interfacing a CycloneIV-E to a AD9266 ADC and I am struggling making an attempt to shut timings.
FPGA design has one 100MHz pll clock; the adc is clocked with a divide-by-two register (=50MHz); knowledge from adc is 8bit vast, double knowledge price: it outputs even bits at one 100MHz clock cycle, and odd bits on the subsequent 100MHz clock cycle.
That is the rtl view that generates the 50MHz clock (adc_clk) and latches the info (knowledge[7:0]) to 2 registers with odd and even knowledge. To keep away from muxes (is that this a smart alternative?) the 2 latch registers are stuffed with odd and even bits on the odd and even positions after which or-ed collectively:
These are the .sdc constraints:
# Clock definition
create_generated_clock -name {ad9266_clk_reg} -source [get_pins pll1] -divide_by 2 [get_registers adc_clk_reg]
create_generated_clock -name {ad9266_clk} -source [get_registers 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]
#enter 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 experiences all paths failing setup, with ~3.5ns of destructive slack:
Tried “Quick enter” and “Quick 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”
However no massive enchancment:
I’ve tried to insert a pipeline for knowledge(in) and clock(out):
Up to date .sdc constraints:
create_generated_clock -name {ad9266_clk_reg} -source [get_pins pll1] -divide_by 2 [get_registers ad9266:adc_inst]
create_generated_clock -name {ad9266_clk} -source [get_registers ad9266:adc_inst] [get_ports {rf_in_adc_clk}]
Up to date quick 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”
Little bit of enchancment, however nonetheless not a sport changer:
Timequest is measuring a beefy delay from I/O pin and the primary register:
11.529 3.284 knowledge path
8.245 0.000 FF IC 1 IOIBUF_X0_Y11_N8 rf_in_adc_dco~enter|i
9.087 0.842 FF CELL 1 IOIBUF_X0_Y11_N8 rf_in_adc_dco~enter|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, a few third of the online delay from IOIBUF_X0_Y11_N8 to FF_X0_Y11_N10.
pipeline register are positioned near I/O, so I fairly do not get the place this delay is coming from:
pipeline register is then routed to the precise knowledge register, with a “lengthy” path proven in chip planner:
Albeit lengthy in chip planner, the delay is kind of quick:
report_path -from rf_in:rf_in_inst|ad9266:adc_inst|adc_pipeline[8] -npaths 100 -panel_name {Report Path} -multi_corner
Report Path: Discovered 16 paths. Longest delay is 2.956
I am having actually a foul occasions making an attempt to make sense from this knowledge.
Am I lacking one thing? Hints for timings closure?
Thanks!!!
[ad_2]