Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
  • Combinational Design25
    • Combinational Timing Overview
      • Propagation Delay and Levels of Logic
      • Zero-Delay Simulation vs Inertial Delay
      • Critical-Path Mindset in RTL
    • Muxes, Decoders and Encoders
    • Arithmetic Blocks
    • Comparators and Shifters
    • Tri-State and Shared Buses
    • Latch Inference
    • Arithmetic Datapaths
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹Combinational Timing Overview
  1. Topics
  2. RTL Design
  3. Combinational Design
  4. Combinational Timing Overview
  5. Critical-Path Mindset in RTL

Part 2 · Combinational · Intermediate

Critical-Path Mindset in RTL

Only the slowest path sets the clock: reshape chains, late signals, and precompute.

On this page

    Why this matters

    Speeding up a path that is not critical costs area and gains nothing. The skill is to find the worst path in the timing report, trace it to the RTL behind it, and change the structure there.

    After this lesson you can: list the four ways to shorten a path (parallel select, late signal last, precompute, pipeline) and say when each is safe.

    The critical path

    The critical path is the slowest register-to-register route in the design. Only changes on that path improve the clock rate, and only up to the next-worst path. Fix every path with negative slack, worst first, and expect the critical path to move after each fix.

    Speeding up anything else costs area for no gain. The workflow is always the same: read the timing report, find the worst path, see which RTL it came from, and change the structure.

    Iteration loop from timing report to restructure and back.
    A tight loop: measure, change structure, measure again.

    Shorten the path

    Parallel select instead of a serial chain

    An if / else if chain means priority. Each condition waits for all earlier ones to fail.

    Built literally, it is as deep as the chain is long. If the conditions can never overlap, use a parallel AND-OR select instead.

    A one-hot request is one example. The parallel form has shallow depth. It uses one AND stage plus one wide OR.

    Built from bounded-fan-in gates, that OR is a tree, so the select costs roughly 1 + ceil(log_f N) levels for fan-in f in that idealized topology, plus routing and load. That still grows far more slowly than a chain N deep. It gives the same answer when the one-hot invariant holds.

    The same four-request select built two ways. Top: the if/else-if chain, where d3 passes through four muxes. Bottom: the one-hot AND-OR, where every input passes one AND and two 2-input OR levels.

    Read each panel from the data inputs to y and count the gates on the highlighted path from d3.

    • Chain: d3 is the last choice, so it crosses all four muxes. Adding a fifth request adds a fifth level.

    • AND-OR: every input crosses one AND and two OR levels: 1 + ceil(log2 4) = 3 for 2-input gates.

    • Growth: doubling to 8 requests makes the chain 8 deep but the AND-OR tree only 4.

    $onehot0(req) is true when zero or one bits of req are set. Every AND-OR select in this section needs that invariant.

    Warning

    The two forms are not equivalent when more than one request is active. The chain picks the lowest index; the AND-OR ORs the data together. Use the parallel form only when the one-hot property is guaranteed (and checked with an assertion).

    Late-arriving signals close to the output

    If one input arrives much later than the rest, structure the logic so that signal passes through as few gates as possible. Compute both outcomes from the early inputs, then use the late signal as the final mux select.

    Precompute and share

    • Compute conditions in the previous cycle and register them, so the current cycle only consumes a flop output.

    • Share a sub-expression only if the shared node does not become the fan-out bottleneck.

    • Replace a wide comparison (a == b on 64 bits) with a registered partial result when the inputs are available earlier.

    Pipeline

    When no restructuring is enough, cut the path with a register. This trades latency (one more cycle) for clock rate, and is the topic of the pipelining section in the sequential chapter.

    Symptom in the timing report

    First thing to try

    Long chain of if/else if

    Parallel select or unique case if inputs are exclusive

    Deep adder or comparator

    Let the tool build a fast adder; check you did not write a bit-serial loop

    One very late input

    Make it the last mux select

    High fan-out net

    Duplicate or buffer the driver; register it

    Everything is slightly too slow

    Pipeline

    Interview check

    Interview

    Likely question: “Your design misses timing. What do you change first?”

    • Find the critical path and count its logic levels.

    • Restructure the RTL behind it: parallel select, late signal last, precompute, or pipeline.

    • Re-synthesize and read the report again. Only the worst path moves the clock, and only up to the next-worst path, so expect a new critical path after each fix.

    Check yourself Your critical path is an 8-way if / else if chain that selects a data bus. The requests are one-hot by protocol. What do you change, and what do you add for safety?

    Replace the chain with a parallel AND-OR (or unique case) select. Add an assertion that $onehot0(req) always holds, because the faster structure is only correct under that assumption.

    Check yourself One path has 30 levels and misses timing; a nearby path has 5. Which do you fix?

    The 30-level path first. It is the critical one, and shortening the 5-level path does not raise the clock rate. Fixing the 30-level path helps only until the next-worst path becomes critical, so keep going until no path has negative slack.

    Check yourself Two requests overlap in an AND-OR select. What comes out, and how does the chain differ?

    The AND-OR ORs both data words together, a defined but wrong value. The chain would have picked the lowest index instead. That is why the one-hot invariant needs an assertion.

    Testbench

    This testbench proves the chain and the parallel select agree whenever requests never overlap.

    prio_chain.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    module prio_chain (
      input  logic [3:0] req,
      input  logic [7:0] d0, d1, d2, d3,
      output logic [7:0] y
    );
      always_comb begin
        if      (req[0]) y = d0;       // serial priority: req[3] waits for req[0..2]
        else if (req[1]) y = d1;
        else if (req[2]) y = d2;
        else if (req[3]) y = d3;
        else             y = '0;
      end
    endmodule
    
    module onehot_select (
      input  logic [3:0] req,        // assumed one-hot or zero
      input  logic [7:0] d0, d1, d2, d3,
      output logic [7:0] y
    );
      // parallel AND-OR: shallow depth. One AND stage plus a bounded-fan-in OR tree, about 1 + ceil(log_f N) levels.
      assign y = ({8{req[0]}} & d0) | ({8{req[1]}} & d1)
               | ({8{req[2]}} & d2) | ({8{req[3]}} & d3);
    endmodule
    

    Remember

    • Fix the worst negative-slack path first. The critical path moves after each fix.

    • A priority chain can become a parallel AND-OR select only if the requests are one-hot, so assert $onehot0.

    • Pipelining trades one cycle of latency for clock rate.

    Rule of thumb: read the report first, then change the structure behind the worst path.

    Keep going

    • Interview: run a mock interview on this topic

    Related topics

    • Muxes, decoders and encoders

    • Pipelining

    Previous

    39 / 350

    Next: Muxes, Decoders and Encoders

    Up next

    Up nextMuxes, Decoders and Encoders

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Propagation Delay and Levels of Logic