Useful Skew
Everything from Section 5.1 onwards has framed skew as something to minimise. That is correct for the general case, but it hides an exception that clever CTS engineering exploits directly. If skew’s sign, not just its magnitude, decides whether it helps or hurts a path, as Section 5.1’s last article showed, then skew is not only something to fight. On a specific, identified path it is something you can deliberately spend.
The idea, precisely
Recall the setup slack equation:
$$\text{Slack} = T_{clk} - (t_{comb} + t_{setup} + \text{skew})$$
That assumed skew works against you, with the capturing register’s clock arriving earlier than the launching register’s and shrinking the window. Nothing in the physics forces that direction. If you arrange for the capturing register’s edge to arrive later than the launching register’s, the sign flips and skew starts adding to the window:
$$\text{Slack}{\text{useful skew}} = T{clk} - t_{comb} - t_{setup} + |\text{skew}|$$
This is useful skew. Instead of treating every register uniformly and driving latency differences to zero everywhere, you deliberately arrange, through buffer sizing and tree structure within one branch, for the capturing register on one marginal path to get its edge slightly later than the launching register, buying that path real setup margin it would not otherwise have.
Why this is not being sloppy
The crucial word is deliberate. Useful skew is applied to one identified path, usually the worst offender in a timing report, not scattered across the design. An engineer sees a marginal or failing setup path, traces it to its launching and capturing flops, and asks TritonCTS, through targeted constraints on that subtree rather than the design-wide CTS_TARGET_SKEW, to bias latency in the direction that helps precisely that path. Every other path is left alone under the ordinary minimise-skew objective.
It is a real, named technique in commercial flows on hard, high-frequency designs where every picosecond counts, not a course simplification. It is also inherently surgical. Trying to apply it everywhere at once means constantly fighting yourself, because making one path’s capturing edge later necessarily makes some other path, wherever that same flop is a launching register, earlier relative to its own downstream path.
The catch: hold does not forget
Here is the honest cost, and it is the bridge into Section 5.4. Useful skew helps setup by making the capturing edge arrive later. Hold checks the same-edge relationship between launch and capture, and a later capturing edge is exactly the direction that makes hold harder. Deliberately skewing a path to rescue setup can create, or worsen, a hold violation on that same pair of registers. That is never a reason to avoid the technique. It is a reason to always re-check hold on any path you have deliberately skewed, every time.
Practice Exercise
A setup path from u_tx/state_reg to u_tx/shift_reg fails by 15 ps. An engineer proposes 20 ps of useful skew on this path, making shift_reg’s clock arrive 20 ps later than state_reg’s. What must be checked immediately afterwards, and why?
Solution
Hold on that exact path, u_tx/state_reg to u_tx/shift_reg. Making the capturing register receive its edge 20 ps later is the same-sign change that helps setup and directly erodes hold margin on that pair. If the path’s hold margin was already tight, this fix could turn a passing hold check into a new violation, trading one problem for another.
You now have both the mechanics, TritonCTS’s clustering and buffering, and the strategic tool, useful skew. The last article in this section stops discussing and starts running: run_cts on the placed UART, and a real CTS summary report.