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
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
    • STA Foundations
      • Where RTL Meets STA
      • Canonical STA Flow
      • Corners
      • SDC Starter Set
      • Why RTL Architecture Dominates
    • Setup, Hold and Slack
    • Skew and Variation
    • Timing Exceptions
    • Clock Gating
    • RTL for Timing
    • Clock Architecture
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹STA Foundations
  1. Topics
  2. RTL Design
  3. Timing & Clocking
  4. STA Foundations
  5. Why RTL Architecture Dominates

Part 5 · Timing & Clocking · Intermediate

Why RTL Architecture Dominates

Two 32-bit adders show why restructuring beats extra tool effort.

On this page

    Why this matters

    Synthesis resizes gates and buffers nets, but it rarely changes the algorithm behind your RTL. In a generic mapping a Kogge-Stone prefix adder had about 40 % fewer levels than the plain adder, at about 46 % more gates.

    After this lesson you can: compare a plain adder with a prefix adder by depth and gate count, trace one carry through the prefix network, and list the levers that shorten a slow path.

    Depth, not effort

    A path's delay is set mostly by how many logic levels the RTL puts between two registers. Synthesis resizes gates, buffers nets and re-maps logic, but it rarely changes the algorithm behind the RTL. So when a datapath misses timing, change its structure, not the tool effort.

    Two forms of 32-bit addition show it. One uses the plain a + b operator; the other is a 5-level Kogge-Stone prefix adder. Both have registered inputs and outputs and are mapped with the same generic flow.

    Version (registered output)

    Longest path (levels)

    Gates (AND/OR/XOR, excluding the 97 flops)

    a + b

    63

    167

    Kogge-Stone prefix adder

    38

    243

    The prefix adder has about 40 % fewer levels and about 46 % more gates. It buys depth with area: that is the usual trade.

    Plain + specifies the sum, not a ripple architecture. Synthesis can infer and restructure carry logic. An explicit prefix network expresses a candidate structure, but mapping can rewrite that too; compare both under the same target before replacing portable arithmetic.

    Levers that shorten a path

    Several levers shorten slow paths. The table lists each with its effect.

    Lever

    Effect

    Pipeline the operation

    Cuts the path; costs latency and registers. A 16-bit carry split is one candidate: delay upper operands, low sum and valid alongside the carry so both halves belong to the same transaction. Re-measure stage depth.

    Balance pipeline stages

    A historical generic-flow multiply-add example reported 33 levels before a split and 31 after splitting at the multiplier output. That suggests the multiplier dominated; evaluate a split inside it if necessary. Those counts lack versioned reproduction evidence here.

    Parallelise (tree instead of chain)

    Summing 8 values as a balanced tree has 3 adders in series instead of 7. Synthesis often balances plain sums of equal-width operands by itself. Write the tree explicitly when the tool cannot see it (different operand widths, enables, or operations in between).

    Restructure the operator

    Replace a long chain with a shallower network, as the prefix adder above does.

    Precompute or register early

    Move work off the critical path.

    Reduce fanout

    Duplicate registers or decode earlier (see RTL for timing).

    Kogge-Stone in five minutes

    For one bit, g = a & b, p = a ^ b, and carry_out = g | (p & carry_in). For a high group H above a low group L, substitute the low carry equation into the high one: G = G_H | (P_H & G_L) and P = P_H & P_L. Group order matters: carry flows from low to high.

    A prefix adder applies that combine step to all bits at once, doubling the reach each stage: distance 1, then 2, then 4. Trace a=0111 and b=0001 with carry-in 0. Each box holds the values after that stage. In the two distance rows, solid boxes are combine cells and dashed grey boxes just pass a value down.

    Kogge-Stone trace for a=0111, b=0001, carry-in 0: g and p, two combine stages (distance 1, then 2), the carries c1=c2=c3=1 and c4=0, and the sum 1000. The highlighted path is bit 0 reaching c4.

    Read the figure top to bottom: each row combines a column with the column one or two places to its right.

    • Distance 1 combines neighbours: G[2:1]=0, P[2:1]=1 and G[1:0]=1.

    • Distance 2 reuses those results: G[2:0]=G[2:1]|(P[2:1]&G[0])=0|(1&1)=1.

    • Bit 0 reaches every carry through at most two combine cells, so the path to c4 is two cells deep, not three ripple stages.

    • The sum row is p XOR the carry from the column to the right: 0110 XOR 1110 = 1000.

    For 32 bits, distances 1,2,4,8,16 cover all lower bits: five stages instead of a 31-stage ripple.

    Five prefix stages are not five mapped gate levels: each stage contains generate/propagate Boolean logic, followed by sum logic and mapping choices. The 38-level result counts the mapped graph, not abstract prefix stages. A timing-driven library flow may favor either implementation once routing and fanout are included.

    Common mistakes

    Common pitfall

    Don't assume that a split pipeline helps. The historical 33-to-31-level multiply-add example suggests a stage with the multiplier remained almost the whole path. Measure every stage before and after in the actual target flow; preserve operand, result and valid alignment when adding latency.

    Warning

    Limits. The level and gate counts come from the measure_plain and measure_prefix tops below and the preceding lesson's commands (synth -flatten -noabc; abc -g AND,OR,XOR,MUX; stat; ltp -noff). Another mapper or library can give different counts, and generic gate count is not mapped area. The testbench checks agreement on 20,000 sampled/directed vectors, including long carry chains; this is not exhaustive or formal equivalence proof.

    Interview

    Whenever setup fails on a datapath, the strong answer starts from the path: how many logic levels, which operator dominates, and which of {pipeline, restructure, precompute, reduce fanout} fits.

    Check yourself In the recorded generic mapping, the prefix adder has about 40 % fewer levels and about 46 % more gates. What evidence would justify selecting it?

    Compare both on the same target library, constraints and physical flow. Select the prefix candidate if its implemented timing benefit is needed and its area, power and routing costs fit the budget. Generic depth alone cannot establish that benefit; retain readable + when it already meets the actual requirements.

    Testbench

    The two adders, matching measurement tops, and a sampled functional checker. For the depth experiment, save only the design modules before tb_ks as design.sv; keep the testbench in a separate simulation source. Only the selected measurement top is synthesized. Simulation requires SystemVerilog with 1 ns / 1 ps timing.

    add32_ripple.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    `timescale 1ns/1ps
    // The historical name is retained; '+' does not require ripple mapping.
    module add32_ripple (input logic [31:0] a, b, output logic [32:0] y);
      assign y = a + b;
    endmodule
    
    // Kogge-Stone parallel-prefix adder: log2(32) = 5 prefix levels
    module add32_ks (input logic [31:0] a, b, output logic [32:0] y);
      logic [31:0] g [6], p [6];
      assign g[0] = a & b;
      assign p[0] = a ^ b;
      for (genvar l = 0; l < 5; l++) begin : lvl
        localparam int D = 1 << l;
        for (genvar i = 0; i < 32; i++) begin : bit_i
          if (i >= D) begin : comb
            assign g[l+1][i] = g[l][i] | (p[l][i] & g[l][i-D]);
            assign p[l+1][i] = p[l][i] & p[l][i-D];
          end else begin : pass
            assign g[l+1][i] = g[l][i];
            assign p[l+1][i] = p[l][i];
          end
        end
      end
      logic [31:0] carry_in;
      assign carry_in = {g[5][30:0], 1'b0};            // carry into bit i = group generate of bits [i-1:0]
      assign y = {g[5][31], p[0] ^ carry_in};
    endmodule
    
    module reg32 (input logic clk, input logic [31:0] a, b, output logic [32:0] y);
      logic [32:0] r; logic [31:0] ra, rb;
      logic [32:0] s;
      add32_ks u (.a(ra), .b(rb), .y(s));
      always_ff @(posedge clk) begin ra <= a; rb <= b; r <= s; end
      assign y = r;
    endmodule
    
    module measure_plain (input logic clk, input logic [31:0] a, b, output logic [32:0] y);
      logic [31:0] ra, rb;
      logic [32:0] s;
      add32_ripple u (.a(ra), .b(rb), .y(s));
      always_ff @(posedge clk) begin ra <= a; rb <= b; y <= s; end
    endmodule
    
    module measure_prefix (input logic clk, input logic [31:0] a, b, output logic [32:0] y);
      reg32 u (.clk, .a, .b, .y);
    endmodule
    

    Remember

    • Plain + specifies the sum and not a ripple structure. Synthesis can restructure carry logic, and an explicit prefix network expresses one candidate.

    • Five prefix stages are not five gate levels, so the mapped depth is higher.

    • Compare candidates on the same library, constraints and physical flow before replacing portable arithmetic.

    Rule of thumb: start from the path: how many levels, which operator dominates, and which lever fits.

    How this was checked

    Counts from Yosys 0.69 (2026-10-16) with the measure_plain and measure_prefix tops and synth -flatten -noabc; abc -g AND,OR,XOR,MUX; stat; ltp -noff. Another tool version, mapper or library can give different counts, so this is one experiment and not a universal tool limit. Generic gate count is not mapped area.

    The testbench checks 20,000 sampled and directed vectors, including long carry chains, with Icarus Verilog 13.0 (2026-10-16): prints PASS. It is not exhaustive and not a formal equivalence proof.

    Keep going

    • Interview: run a mock interview on this topic

    Related topics

    • Setup and hold fundamentals

    • Pipelining

    Previous

    120 / 350

    Next: Setup, Hold and Slack

    Up next

    Up nextSetup, Hold and Slack

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Where RTL Meets STA
    • Canonical STA Flow
    • Corners