Some paths are designed to take more than one clock cycle: the data is held stable and captured only every N cycles. Telling STA lets it check against the real capture edge instead of a one-cycle requirement that the design deliberately does not meet. The command has a well-known trap: setting only the setup multiplier moves the hold check too.
# not-run: SDC is not executable here
set_multicycle_path 3 -setup -from [get_pins cfg_reg*/CK] -to [get_pins eng_reg*/D]
set_multicycle_path 2 -hold -from [get_pins cfg_reg*/CK] -to [get_pins eng_reg*/D]# Same clock, period T. Edges counted in cycles after the launch edge (launch = 0).
def edges(setup_n, hold_n=0):
setup_capture = setup_n # data may take up to setup_n cycles
hold_capture = (setup_n - 1) - hold_n # default hold check is one cycle before the setup capture edge
return setup_capture, hold_capture
# default path
assert edges(1) == (1, 0)
# 3-cycle path with only the setup multiplier: hold is checked 2 cycles after launch (too late; wrong)
assert edges(3) == (3, 2)
# with the hold multiplier 2: hold is back at the launch edge
assert edges(3, hold_n=2) == (3, 0)
print("PASS: setup 3 + hold 2 gives capture edge 3, hold edge 0")A default path has its setup capture at one cycle and hold check at the launch edge (0). Setting -setup 3 alone moves the setup capture to 3 and drags the hold check to edge 2. That means new data must not arrive before about 2T after launch, which is usually false: the hold check becomes far too pessimistic and forces large delay padding. The fix is -hold 2, which pulls the hold check back to edge 0. The rule of thumb is hold multiplier = setup multiplier - 1.
The multipliers count cycles of a reference clock. With the same clock on both ends it does not matter. When launch and capture clocks differ, the option that selects the reference, -start (launch clock reference) or -end (capture clock reference), changes the result, so write it explicitly and check the report's launch and capture times.
Every multicycle path has a matching hold exception, and the report's capture and hold edges match the intended ones.
The design really holds the data stable for N cycles (an enable or a handshake), and an assertion or protocol check exists.
Multicycle paths are listed with their N and their evidence, and not extended "to make it pass".
-setup 4 and -hold 3; the setup capture is at edge 4 and the hold check returns to edge 0 (the launch edge), matching a normal hold requirement.