External logic is launched or captured by some clock that is not a pin of the design: a board clock or a clock on another chip. A virtual clock models it: it gives the external launcher its own period, waveform and latency, and keeps I/O delays independent of the internal clock's waveform, gating and tree.
# not-run: SDC is not executable here
create_clock -name vclk -period 10 ;# no source object: a virtual clock
set_clock_latency 0.8 [get_clocks vclk] ;# models the external clock's own latency
set_input_delay -clock vclk -max 4.0 [get_ports din]
set_output_delay -clock vclk -max 3.0 [get_ports dout]Real clock as reference | Virtual clock as reference | |
|---|---|---|
Latency of the reference | The clock edge at the definition point plus the clock's source latency (network latency only if the clock is ideal and set_clock_latency is given); the internal tree latency appears only on the capturing flop's side | Set explicitly to what the external clock really has |
Use | Interface clock is the same net as the internal clock | Interface clock is external, or you want to control its period, waveform and latency independently |
Risk | Port timing follows the internal clock's waveform, gating and tree | Wrong latency value gives wrong port timing |
# Setup on an input: arrival = reference source latency + input delay + internal path; required = T + capture latency - setup
T, setup = 10.0, 0.1
def slack(ref_latency, capture_latency, input_delay, path):
arrival = ref_latency + input_delay + path
required = T + capture_latency - setup
return required - arrival
# capture flop clock latency 1.2 ns; required = 10 + 1.2 - 0.1 = 11.1
s_virtual = slack(0.8, 1.2, 4.0, 3.5) # virtual clock carrying the external clock's own latency 0.8
s_real_ref = slack(0.0, 1.2, 4.0, 3.5) # real clock as reference with zero source latency: launch at the definition-point edge
assert abs(s_virtual - 2.8) < 1e-9 and abs(s_real_ref - 3.6) < 1e-9
print("PASS: virtual reference slack", round(s_virtual, 2), "vs real reference", round(s_real_ref, 2))The external clock's real latency is 0.8 ns. Using the internal clock as the reference with no source latency assumes the outside launches at the definition-point edge, 0.8 ns earlier than it really does, giving 3.6 ns of slack instead of 2.8 ns: optimistic on setup (and wrong in the other direction on hold). A virtual clock lets you put the real latency, period and waveform in, independent of the internal tree.
A virtual clock exists for each external clock that is not a pin of the design, with a stated period and latency.
Input and output delays reference the right clock; no port is tied to an internal clock by accident.
Virtual clock latency values come from the board or system plan.
When the external logic is launched from the same clock source, so the same period and waveform apply; set the clock's source latency to model the external path. The reference is still the edge at the clock's definition point, not the internal tree.