Skip to content

Commit 8726ef4

Browse files
Re-do fmc timing constraints (#403)
new answers here :)
1 parent 2cab975 commit 8726ef4

File tree

1 file changed

+119
-50
lines changed

1 file changed

+119
-50
lines changed

hdl/projects/cosmo_seq/cosmo_timing.xdc

Lines changed: 119 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,62 +13,131 @@ set_clock_groups -asynchronous -group {fmc_clk_pin fmc_virt_clk} -group {clk_125
1313
# FMC Interface
1414
# #######################
1515

16+
# SP output a continuous clock here.
17+
# The FMC interface is clocked at 66.67MHz, which is a 15ns period.
1618
# FPGA's input delays have to be low enough that they don't run into the uncertainty region due to any possible skew.
17-
# skew_bre is the shortests trace delay vs the clock, and skew_are is the longest trace delay vs the clock.
18-
# On grapefruit, clock trace is 61.195mm. shortest trace is FMC_SP_TO_FPGA_BL1_L at 60.504mm, longest is FMC_SP_TO_FPGA_BL0_L at 65.116mm
19-
# 6.8ns per m so 61.195-60.504 = 0.691mm * 6.8ns/m = 0.0047ns skew_bre
20-
# 65.116-61.195 = 3.921mm * 6.8ns/m = 0.0266ns skew_are
21-
22-
# Also note that the SP changes outputs only on the *falling* edge of the fmc clock, which means there's a phase-shift
23-
24-
# in delay max = tco_ext to max delay ext to fpga
25-
# in delay min = minTco_ext to min delay ext to fpga
26-
# chipsel example:
27-
# Since data comes out on the falling edge, but we didn't shift the clock,
28-
# we need to add an additional 1/2 period to the TCO_exts so
29-
# max= 7.5ns (1/2 period) + 1ns (maxreal tco) + 0.0266ns max skew
30-
# min= 7.5ns (1/2 period) + 0ns (min real tco) + 0.0047 min skew
31-
set_input_delay -clock fmc_virt_clk -max 8.527 [get_ports fmc_sp_to_fpga1_cs_l]
32-
set_input_delay -clock fmc_virt_clk -min 7.505 [get_ports fmc_sp_to_fpga1_cs_l]
33-
set_input_delay -clock fmc_virt_clk -max 8.527 [get_ports fmc_sp_to_fpga1_we_l]
34-
set_input_delay -clock fmc_virt_clk -min 7.505 [get_ports fmc_sp_to_fpga1_we_l]
35-
set_input_delay -clock fmc_virt_clk -max 8.527 [get_ports fmc_sp_to_fpga1_oe_l]
36-
set_input_delay -clock fmc_virt_clk -min 7.505 [get_ports fmc_sp_to_fpga1_oe_l]
37-
set_input_delay -clock fmc_virt_clk -max 8.527 [get_ports fmc_sp_to_fpga1_adv_l]
38-
set_input_delay -clock fmc_virt_clk -min 7.505 [get_ports fmc_sp_to_fpga1_adv_l]
39-
set_input_delay -clock fmc_virt_clk -max 8.527 [get_ports fmc_sp_to_fpga1_bl_l]
40-
set_input_delay -clock fmc_virt_clk -min 7.005 [get_ports fmc_sp_to_fpga1_bl_l]
41-
# Address has diff relationship
42-
# max= 7.5ns (1/2 period) + 2.5ns (maxreal tco) + 0.0266ns max skew
43-
# min= 7.5ns (1/2 period) + 0ns (min real tco) + 0.0047ns max skew
44-
set_input_delay -clock fmc_virt_clk -max 10.027 [get_ports fmc_sp_to_fpga1_a[*]]
45-
set_input_delay -clock fmc_virt_clk -min 7.505 [get_ports fmc_sp_to_fpga1_a[*]]
46-
# Data in has diff relationship
47-
# max= 7.5ns (1/2 period) + 3ns (maxreal tco) + 0.0266ns max skew
48-
# min= 7.5ns (1/2 period) + 0ns (min real tco) + 0.0047ns max skew
49-
set_input_delay -clock fmc_virt_clk -max 10.527 [get_ports fmc_sp_to_fpga1_da[*]]
50-
set_input_delay -clock fmc_virt_clk -min 7.505 [get_ports fmc_sp_to_fpga1_da[*]]
51-
52-
# out delay max = ext setup + max delay fpga to external
53-
# out delay min = ext hold + min delay fpga to external
54-
55-
# max = 3ns (SP's needed setup time) + return delay (60.797mm)
56-
# max = 3ns (SP's needed setup time) + 0.414 ns
57-
# min = 1 ns (SP's needed hold time) + 0.414 ns
58-
set_output_delay -clock fmc_virt_clk -max 3.414 [get_ports fmc_sp_to_fpga1_wait_l]
59-
set_output_delay -clock fmc_virt_clk -min 1.414 [get_ports fmc_sp_to_fpga1_wait_l]
60-
61-
# max = 3ns (SP's needed setup time) + clock delay to FPGA (61.195mm) + return delay (63.985mm)
62-
# max = 3ns (SP's needed setup time) + 0.851 ns
63-
# min = 0 ns (SP's needed hold time) + 0.851 ns
64-
set_output_delay -clock fmc_virt_clk -max 3.851 [get_ports fmc_sp_to_fpga1_da[*]]
65-
set_output_delay -clock fmc_virt_clk -min 0.830 [get_ports fmc_sp_to_fpga1_da[*]]
66-
19+
# skew_bre is the shortest trace delay vs the clock, and skew_are is the longest trace delay vs the clock.
20+
# On cosmo, clock trace is 60.787 rev1, 53.026mm rev2 .
21+
# shortest trace rev1 is FMC_SP_TO_FPGA1_A22 at 58.956, rev2 is FMC_SP_TO_FPGA1_DA14 at 52.54
22+
# longest trace rev1 (ignoring BL) is FMC_SP_TO_FPGA1_DA5 at 61.565, rev2 is FMC_SP_TO_FPGA1_A20 at 54.473
23+
24+
# Max clock delay to FPGA: 60.787mm * 6.8ns/m = 0.4134 ns (rev1 longest)
25+
set max_clock_delay 0.4134
26+
# Min clock delay to FPGA: 53.026mm * 6.8ns/m = 0.3602 ns (rev2 shortest)
27+
set min_clock_delay 0.3602
28+
# Max data delay between SP and FPGA: 61.565mm * 6.8ns/m = 0.4186 ns (rev1 longest)
29+
set max_data_delay 0.4186
30+
# Min data delay between SP and FPGA: 52.54mm * 6.8ns/m = 0.3573 ns (rev2 shortest)
31+
set min_data_delay 0.3573
32+
# Max wait delay between SP and FPGA: 60.787*6.8ns/m = 0.4134 ns (rev1 longest)
33+
set max_wait_delay 0.4134
34+
# Min wait delay between SP and FPGA: 53.467*6.8ns/m = 0.3635 ns (rev1 longest)
35+
set min_wait_delay 0.3635
36+
37+
# #################
38+
# Input constraints.
39+
# Effectively longest data delay, fastest clock arrival at FPGA.
40+
# input_max = clk_ext_delay_max + extTco_max + board_delay_max - fpga_clk_delay_min
41+
# Effectively shortest data delay, slowest clock arrival at FPGA.
42+
# input_min = clk_ext_delay_min + extTco_min + board_delay_min - fpga_clk_delay_max
43+
44+
# For the inputs data valid before rising edge can be calculated based on the SP's datasheet timings and trace delays.
45+
# td(CLKL-NExL) clock to out is max 1ns
46+
# td(CLKH_NExH) is min
47+
# td(CLKL-AV) 2.5ns
48+
# td(CLKH-AIV) 8ns?
49+
# td(CLKL-NOEL) 1.5ns
50+
# td(CLKH-NOEH) 7.5ns
51+
# td(CLKL-ADV) 3 ns
52+
# td(CLKL-ADIV) 0 ns
53+
# tsu(ADV-CLKH) 3 ns
54+
# th(CLKH-ADV) 0
55+
# tsu(NWAIT-CLKH) 3 ns (worst read timing)
56+
# th(CLKH-NWAIT) 2 ns (worst write timing)
57+
58+
# Source sync so external_clk_delay is 0.
59+
# Setup time is 1ns, and we include the 1/2 period due to SP shifting the data out on the falling edge.
60+
set sp_output_half_period 7.5
61+
set sp_0_hold 0
62+
set sp_clk_delay 0
63+
64+
# We have our 1/2 period of 7.5 ns due to SP outputting on falling edges, plus the td in the datasheet
65+
set td_clkl_nehl 1
66+
set nl_output_delay [expr {sp_output_half_period + td_clkl_nehl}]
67+
set max_nl expr [expr {$sp_clk_delay + $nl_output_delay + $max_data_delay - $min_clock_delay}]
68+
# latest clock, earliest data. We assume a hold time of 0 for the SP.
69+
# min external: fastest data, slowest clock
70+
set min_nl expr [expr {$sp_clk_delay + $sp_0_hold + $min_data_delay - $max_clock_delay}]\
71+
72+
# Apply to all of these pins with similar or better timing relationships.
73+
set_input_delay -clock fmc_virt_clk -max $max_nl [get_ports fmc_sp_to_fpga1_cs_l]
74+
set_input_delay -clock fmc_virt_clk -min $min_nl [get_ports fmc_sp_to_fpga1_cs_l]
75+
set_input_delay -clock fmc_virt_clk -max $max_nl [get_ports fmc_sp_to_fpga1_we_l]
76+
set_input_delay -clock fmc_virt_clk -min $min_nl [get_ports fmc_sp_to_fpga1_we_l]
77+
set_input_delay -clock fmc_virt_clk -max $max_nl [get_ports fmc_sp_to_fpga1_oe_l]
78+
set_input_delay -clock fmc_virt_clk -min $min_nl [get_ports fmc_sp_to_fpga1_oe_l]
79+
set_input_delay -clock fmc_virt_clk -max $max_nl [get_ports fmc_sp_to_fpga1_adv_l]
80+
set_input_delay -clock fmc_virt_clk -min $min_nl [get_ports fmc_sp_to_fpga1_adv_l]
81+
set_input_delay -clock fmc_virt_clk -max $max_nl [get_ports fmc_sp_to_fpga1_bl_l]
82+
set_input_delay -clock fmc_virt_clk -min $min_nl [get_ports fmc_sp_to_fpga1_bl_l]
83+
84+
# Address has diff relationship 2.5ns (max tco)
85+
set td_clkl_av 2.5
86+
set a_output_delay [expr {sp_output_half_period + td_clkl_av}]
87+
set max_a expr [expr {$sp_clk_delay + $a_output_delay + $max_data_delay - $min_clock_delay}]
88+
# Still 0 hold on these pins.
89+
set min_a expr [expr {$sp_clk_delay + $sp_0_hold + $min_data_delay - $max_clock_delay}]
90+
set_input_delay -clock fmc_virt_clk -max $max_a [get_ports fmc_sp_to_fpga1_a[*]]
91+
set_input_delay -clock fmc_virt_clk -min $min_a [get_ports fmc_sp_to_fpga1_a[*]]
92+
93+
# Data in has diff relationship 3ns (max tco)
94+
set td_clkl_adv 3
95+
set ad_output_delay [expr {sp_output_half_period + td_clkl_adv}]
96+
set max_ad expr [expr {$sp_clk_delay + $ad_output_delay + $max_data_delay - $min_clock_delay}]
97+
# Still 0 hold on these pins.
98+
set min_ad expr [expr {$sp_clk_delay + $sp_0_hold + $min_data_delay - $max_clock_delay}]
99+
set_input_delay -clock fmc_virt_clk -max $max_ad [get_ports fmc_sp_to_fpga1_da[*]]
100+
set_input_delay -clock fmc_virt_clk -min $min_ad [get_ports fmc_sp_to_fpga1_da[*]]
101+
102+
#### END Of inputs
103+
104+
# #################
105+
# Output constraints.
106+
# Effectively need to meet setup time with longest FPGA data delay and fastest clock arrival at other device.
107+
# output_max = fpga_clk_delay_max + board_delay_max + extTsu - ext_clk_delay_min
108+
# Effectively need to meet hold time with shortest FPGA data delay and slowest clock arrival at other device.
109+
# input_min = fpga_clk_delay_min + board_delay_min - extTh - ext_clk_delay_max
110+
111+
# Ext setup time is 3ns
112+
set tsu_nwait_clkh 3
113+
# SP rising edge samples so 0 clock delay at external device.
114+
set max_wait expr [expr {$tsu_nwait_clkh + $max_wait_delay + $max_clock_delay - $sp_clk_delay}]
115+
# Ext hold time is 2ns, still 0 clock delay at external device.
116+
set th_clkh_nwait 2
117+
set min_wait expr [expr {$min_clock_delay + $min_wait_delay - $th_clkh_nwait - $sp_clk_delay}]
118+
set_output_delay -clock fmc_virt_clk -max max_wait [get_ports fmc_sp_to_fpga1_wait_l]
119+
set_output_delay -clock fmc_virt_clk -min min_wait [get_ports fmc_sp_to_fpga1_wait_l]
120+
121+
# Ext setup time is 3ns
122+
set tsu_adv_clkh 3
123+
# Ext hold time is 0ns
124+
set th_clkh_adv 0
125+
# Still 0 clk delay at external device
126+
set max_da expr [expr {$tsu_adv_clkh + $max_data_delay + $max_clock_delay - $sp_clk_delay}]
127+
set min_da expr [expr {$min_data_delay - $th_clkh_adv + $min_clock_delay - $sp_clk_delay}]
128+
set_output_delay -clock fmc_virt_clk -max $max_da [get_ports fmc_sp_to_fpga1_da[*]]
129+
set_output_delay -clock fmc_virt_clk -min $min_da[get_ports fmc_sp_to_fpga1_da[*]]
130+
131+
132+
# assuming wait_l works, we have multiple cycles to get the data out. This is likely needed due to the tri-state stuff here
133+
# and it has trouble meeting timing without the additional cycles. The fpga design compensates for this with wait_l.
67134
set_multicycle_path -from [get_pins {stm32h7_fmc_target_inst/data_out*/C}] -to [get_ports {fmc_sp_to_fpga1_da[*]}] -setup 2
68135
set_multicycle_path -from [get_pins {stm32h7_fmc_target_inst/data_out*/C}] -to [get_ports {fmc_sp_to_fpga1_da[*]}] -hold 1
69136
set_multicycle_path -from [get_pins {stm32h7_fmc_target_inst/data_out_en_reg*/C}] -to [get_ports {fmc_sp_to_fpga1_da[*]}] -setup 2
70137
set_multicycle_path -from [get_pins {stm32h7_fmc_target_inst/data_out_en_reg*/C}] -to [get_ports {fmc_sp_to_fpga1_da[*]}] -hold 1
71138

139+
# End FMC
140+
72141
set_false_path -from [get_nets *] -to [get_ports {fpga1_spare_v3p3*}]
73142
set_false_path -from [get_nets *] -to [get_ports {fpga1_spare_v1p8[*]}]
74143

0 commit comments

Comments
 (0)