Module 8: RTL Coding for Quality & Synthesis ยท 8.3 Timing Constraints & STA Basics

Reading a Timing Report

The last three articles covered what STA checks, how to constrain it, and what the tool does under pressure. This one is about reading what comes back.

A timing report can be intimidating the first time: hundreds or thousands of lines, cryptic gate names, delays in picoseconds. The good news is that you almost never read the whole thing. You read one number first, and it tells you where to look next.

Step 1: find the worst negative slack

Every STA tool reports slack for every path, the difference between how much time the path was allowed (from the clock period) and how much it used. Positive slack means the path finished with time to spare; negative slack is a violation.

$$\text{Slack} = \text{Required Time} - \text{Actual Arrival Time}$$

Worst negative slack (WNS) is the most negative slack anywhere in the design, the single worst violation if any exist. It is the first number to check after a synthesis or place-and-route run, because it answers the question that matters most: does this design meet timing, and if not, by how much?

Timing Report Summary:
  Worst Negative Slack (WNS):  -0.42 ns
  Total Negative Slack (TNS):  -1.85 ns
  Number of violating paths:    4

A WNS of -0.42 ns means that somewhere a path arrived 0.42 ns later than the period allowed: a real setup violation, so the design cannot reliably run at the constrained frequency as it stands. Total negative slack (TNS), the sum over every failing path, tells you whether this is one isolated problem (TNS close to WNS, essentially one bad path) or a systemic one (TNS much larger than WNS, many paths in trouble, often pointing at an over-aggressive constraint rather than one RTL bottleneck).

Step 2: trace the critical path

Once you know there is a problem, the path detail tells you where:

Startpoint: reg_a_reg (rising edge-triggered flip-flop)
Endpoint:   reg_b_reg (rising edge-triggered flip-flop)
Path Group: clk

  Point                          Incr      Path
  ------------------------------------------------
  reg_a_reg/CLK (rise edge)      0.00      0.00
  reg_a_reg/Q (clk-to-Q delay)   0.28      0.28
  U142/Y (AND2, fanout=3)        0.09      0.37
  U156/Y (MUX2, fanout=2)        0.15      0.52
  U178/Y (ADD_STAGE, fanout=1)   1.85      2.37
  U201/Y (MUX2, fanout=4)        0.18      2.55
  reg_b_reg/D                    0.00      2.55
  ------------------------------------------------
  data arrival time:                       2.55
  data required time:                      2.13
  ------------------------------------------------
  slack (VIOLATED):                       -0.42

Read it the way you would trace a schematic: an instance-by-instance list of every gate the signal passes through from reg_a_reg’s output to reg_b_reg’s input, with each gate’s delay and a running total. The largest single jump, here U178 (a synthesized adder stage) contributing 1.85 ns of the path’s 2.55 ns, is almost always where the bottleneck is. The other cells on this path contribute modest, unremarkable delays; U178 does nearly all the damage.

The critical path as a chain of cells with one dominant contributor
Figure 1: The reported path, with the adder stage dominating

Step 3: trace the bottleneck back to RTL

Synthesis tools annotate instances with the RTL source line, or at least the module hierarchy, that produced them. U178’s name or an accompanying cross-reference points at a specific + in a specific always block or assign. This is where Modules 7 and 8 converge into a decision:

  • If U178 is a wide, unpipelined adder or multiplier, this is the case Sections 7.2 and 7.3 addressed. The fix is architectural: add a pipeline stage to split the operation across a clock boundary.
  • If U178 is a resource-shared operation on this critical path, this is Section 8.2’s second article: consider suppressing sharing on this instance and accept the area cost.
  • If the whole path is simply deeper than it needs to be, several small operations chained in series, the restructuring from the previous article may apply, and it is worth confirming the constraints are driving the tool’s priorities correctly (Section 8.2’s closing article).
  • If no synthesis or pipelining fix is available and the violation is small, sometimes the honest answer is that the clock target needs revisiting. Not every timing miss is a design flaw; some are evidence the target was set before the logic depth was known.

Reports for a large chip span tens of thousands of paths, which is why WNS and TNS exist as summaries. The usual workflow: check WNS and TNS, pull up the worst path’s detail, find the dominant contributor, trace it to RTL, fix, re-run, and iterate on the new worst path, since fixing today’s worst violation often reveals the next one underneath. This iteration is called timing closure and can take several rounds even for a moderately sized design.

Practice Exercise

One report shows WNS = -0.05 ns and TNS = -0.05 ns (one violating path, barely failing). Another, on a different design, shows WNS = -0.08 ns but TNS = -14.3 ns across 60 paths. Explain what each suggests about root cause and fix.

Solution

The first, a small WNS with TNS equal to it, is one isolated, nearly passing path: most likely a single bottleneck (an unpipelined operation, or a shared resource on the wrong path) that a targeted local fix would resolve on its own, given how close it is to passing.

The second, a similarly small WNS but a much larger TNS spread across 60 paths, is systemic. Many paths are all slightly too slow, which more often points to the clock constraint being too aggressive for what the architecture can support, or a widespread RTL pattern (an unpipelined datapath reused in many places) repeated across the design. The fix is broader: reconsider the target, or apply pipelining consistently across the repeated pattern, rather than a single change to one instance.

WNS is the first and often only number you need to know whether a design meets timing; TNS alongside it tells you whether the problem is isolated or systemic. The path detail is a gate-by-gate account of where every nanosecond went, and the largest contributor is where the fix belongs, which once traced to RTL resolves into the toolkit from Sections 7.2, 7.3 and 8.2: pipeline it, stop sharing it, restructure it, or revisit the target. That closes Section 8.3. In the next article, Section 8.4 turns to a systematic method for debugging the RTL bugs that survive everything covered so far.

โ† How Synthesis Optimizes for Timing X-Propagation in Practice โ†’