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

  • Logic Synthesis Glossary
  • Logic Synthesis Cheatsheet
  • Synthesis Foundations14
    • Synthesis Flow Overview
    • Synthesizable RTL and Inference
      • Combinational Blocks Infer Logic
      • Priority Chains versus Parallel Selects
      • Latch Inference from Incomplete Assignment
      • Flops, Tri-States and Unrolled Loops
      • What Is Not Synthesizable
    • Reading Netlists and Reports
  • Logic Optimisation and Mapping20
  • Constraints and Timing15
  • Sequential, FSM and Memory19
  • Datapath Synthesis14
  • Area, Power and Test14
  • Verification, ECO and Handoff15
  • Flows and Debugging15
  • Interview and Judgment11
Loading lesson

‹Synthesizable RTL and Inference
  1. Topics
  2. Logic Synthesis
  3. Synthesis Foundations
  4. Synthesizable RTL and Inference
  5. Flops, Tri-States and Unrolled Loops

Part 1 · Synthesis Foundations · Intermediate

Flops, Tri-States and Unrolled Loops

Clocked blocks infer flops, tri-states belong at pins, and loops unroll.

On this page

    Clocked blocks infer flops

    An always block triggered on a clock edge infers one flip-flop per bit. Branches inside it become enable or data muxes, never latches.

    The script below reads one flop and pins exactly one $dff with no $dlatch. Areas below are teaching-library units, with DFF at 8 and DFFR at 10.

    yosys
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    read_verilog <<EOV
    module dff_top (
      input wire clk,
      input wire d,
      output reg q
    );
      always @(posedge clk) begin
        q <= d;
      end
    endmodule
    EOV
    hierarchy -check -top dff_top
    proc
    select -assert-count 1 t:$dff
    select -assert-none t:$dlatch
    log PASS: clocked block infers one flop with no latch
    Diagram
    8-bit register from the teaching library
    DFF area is 8 units, DFFR area is 10 units
    no reset: 8 x 8 = 64 units
    with reset: 8 x 10 = 80 units
    reset cost = 80 - 64 = 16 units

    Tri-states live at the boundary

    An output driven to high impedance infers a tri-state driver. Such drivers map cleanly to chip pins and shared buses.

    Inside the core most flows convert them to multiplexers instead. The exact handling varies between tools, so keep tri-states at the boundary.

    Loops unroll

    A for loop with bounds fixed at elaboration unrolls into repeated hardware. Eight iterations build eight copies, not one reused unit.

    The program below replays the worked arithmetic of this topic. Its six self-checks repeat the hand totals for select depth and register area.

    example.py
    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
    import sys
    
    MUX2_AREA = 5
    DFF_AREA = 8
    DFFR_AREA = 10
    
    def tree_cells(n):
        return n - 1
    
    def tree_depth(n):
        d = 0
        p = 1
        while p < n:
            p = p * 2
            d = d + 1
        return d
    
    def chain_depth(n):
        return n - 1
    
    def mux_area(n):
        return tree_cells(n) * MUX2_AREA
    
    def reg_area(bits, with_reset):
        cell = DFFR_AREA if with_reset else DFF_AREA
        return bits * cell
    
    checks = [
        (tree_cells(8), 7),
        (tree_depth(8), 3),
        (chain_depth(8), 7),
        (mux_area(8), 35),
        (reg_area(8, False), 64),
        (reg_area(8, True), 80),
    ]
    
    for i in range(len(checks)):
        got, want = checks[i]
        if got != want:
            print("FAIL: check " + str(i + 1) + " got " + str(got) + " want " + str(want))
            sys.exit(1)
    
    print("PASS: depth and area arithmetic agrees on 6 checks")

    Common mistakes

    Common pitfall

    A clocked branch with no else does not infer a latch. It infers a flop with an enable path, which simulates the same but reports differently in the netlist.

    Interview

    Likely probes: flops against latches, tri-state placement, and loop bounds.

    • Clocked blocks give one $dff per bit, and the script proves it with no $dlatch.

    • Tri-states belong at pins and buses, since core logic usually becomes muxes.

    • Only loops with elaboration-fixed bounds unroll into repeated hardware.

    Check yourself A clocked if without an else skips the register update on one branch. Latch or flop?

    Flop with an enable path. Clocked blocks infer storage with enables, never latches.

    Check yourself An 8-bit register with reset costs how many teaching-library units, and what does the reset add?

    80 units. The reset term costs 16 units over the 64 of the plain register.

    Related topics

    • What Is Not Synthesizable

    • Flops Resets and Enables

    • Flip-Flops and Registers

    Previous

    11 / 139

    Next: What Is Not Synthesizable

    Up next

    Up nextWhat Is Not Synthesizable

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Combinational Blocks Infer Logic
    • Priority Chains versus Parallel Selects