When two blocks exchange data every cycle, their combined delay must fit in one period. If each assumes the other is fast, the total can exceed the period. Budgeting assigns each side a share before implementation, and the boundary delays are then derived from the shares.
Component | Delay (ns, illustrative) | Owner |
|---|---|---|
Block A clock-to-Q | 0.45 | Block A |
Block A output logic | 1.20 | Block A |
Top-level routing | 1.40 | Top |
Block B input logic | 1.60 | Block B |
Block B setup | 0.15 | Block B |
T = 5.0
parts = {"A cq": 0.45, "A logic": 1.20, "route": 1.40, "B logic": 1.60, "B setup": 0.15}
total = sum(parts.values())
slack = T - total
assert abs(total - 4.80) < 1e-9 and abs(slack - 0.20) < 1e-9
# Derived constraints: A's output delay (everything after A's logic) and B's input delay (everything before B's logic)
a_output_delay = parts["route"] + parts["B logic"] + parts["B setup"] # 3.15
b_input_delay = parts["A cq"] + parts["A logic"] + parts["route"] # 3.05
assert abs(a_output_delay - 3.15) < 1e-9 and abs(b_input_delay - 3.05) < 1e-9
print("PASS: total", round(total, 2), "slack", round(slack, 2), "A output delay", a_output_delay, "B input delay", b_input_delay)The sum is 4.80 ns against a 5.0 ns period: 0.20 ns of margin. From the table, block A is told its output delay is 3.15 ns (the rest of the path after A's logic) and block B its input delay is 3.05 ns (everything before B's logic). The two constraints are not the same number because they exclude each side's own logic. Budgets that skip this and give each side the full period guarantee a failure at integration.
Both ends of every top-level interface carry matching budgets that sum to less than the period with explicit margin.
Budgets are revised when implementation reveals a cost that differs from the assumption, and both sides are updated together.
The budget table is a signoff artifact, versioned with the constraints.
Each excludes its own logic: A's output delay covers everything after A's logic (route, B logic, B setup) and B's input delay covers everything before B's logic (A's clock-to-Q, A logic, route). They share the route but each leaves out its own side.