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

AboutRoadmapCareersInternshipsFAQContactPrivacyTerms
Skip to lesson

Course contents

  • Logic Synthesis Glossary
  • Logic Synthesis Cheatsheet
  • Synthesis Foundations14
    • Synthesis Flow Overview
      • What Synthesis Does
      • The Five Flow Stages
      • Why Constraints Change the Netlist
      • A Small Design Through Yosys
      • Concepts, Not Commands
    • Synthesizable RTL and Inference
    • 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

←Synthesis Flow Overview
  1. Topics
  2. Logic Synthesis
  3. Synthesis Foundations
  4. Synthesis Flow Overview
  5. A Small Design Through Yosys
On this page

    Part 1 of 9, lesson 4 of 14Part 1 of 9/Synthesis Foundations/Lesson 4 of 14Intermediate

    A Small Design Through Yosys

    A real Yosys flow on a small design, asserting only robust mapped facts.

    A flow you have never watched end to end is a flow you cannot debug. This is the smallest design that exercises every stage boundary with assertions that survive rebuilds.

    After this lesson you can: run the AND-OR cone from RTL to mapped netlist, assert exact generic counts with zero generic gates, assert library-only cells after mapping without pinning the covering, and show how one operator changes both netlists.

    The example design

    The design computes y from (a and b) or (c and d): an AND-OR cone over four inputs and one output. It is the smallest design that still exercises every stage boundary: coarse gates after elaboration, bit-level gates after lowering, and a handful of library cells after mapping. The full Verilog sits inside the runnable block below, one module only, finishing in a fraction of a second.

    Two deliberate choices keep the assertions honest. First, the script pins exact counts only before mapping, where elaboration is deterministic: two $and cells and one $or cell. Second, after mapping it pins only absences plus a lower bound: no coarse cells, no generic gates, and at least one library cell without naming which family the mapper chose. Pin shape, not exact library cells: a minimum on one family such as NAND2 names a covering choice the mapper is free to change between builds, so that detail stays in the recording and out of the assertions.

    Stage by stage

    Command

    Stage

    What it does here

    read_verilog

    1. Read

    Loads the inline design through a here-document.

    hierarchy

    2. Elaborate

    Checks the design and sets the top module.

    proc

    2. Elaborate

    Resolves processes; a no-op on this purely continuous design.

    opt

    3. Optimise

    Cleans up the generic graph; nothing to fold here.

    techmap

    3. Optimise

    Lowers the coarse cells toward mappable bit-level gates.

    abc -liberty

    4. Map

    Maps the logic to cells of course.lib.

    stat -liberty

    5. Report

    Prints counts and area in library units.

    The runnable flow

    The script below records the generic netlist, freezes it, maps it, freezes the result, then reloads each frozen stage for assertions. A wrong claim fails the run instead of printing PASS, so every number quoted after this block was checked by the tool, not by the author.

    yosys
    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
    read_verilog <<EOV
    module and_or(input a, b, c, d, output y);
    assign y = (a & b) | (c & d);
    endmodule
    EOV
    hierarchy -check -top and_or
    proc
    opt
    tee -o stat_generic.txt stat
    write_json net_generic.json
    design -save generic
    techmap
    tee -o abc_mapped.txt abc -liberty course.lib -constr typical.constr -D 1000
    tee -o stat_mapped.txt stat -liberty course.lib
    write_json net_mapped.json
    design -save mapped
    design -load generic
    select -assert-count 2 t:$and
    select -assert-count 1 t:$or
    select -assert-none t:$_AND_ t:$_OR_ t:$_NOT_ t:$_MUX_ t:$_XOR_ t:$fa %u
    design -load mapped
    select -assert-none t:$and t:$or t:$xor t:$mux t:$not t:$add t:$sub %u
    select -assert-none t:$_AND_ t:$_OR_ t:$_NOT_ t:$_MUX_ t:$_XOR_ t:$_NAND_ t:$_NOR_ %u
    select -assert-min 1 t:INV t:BUF t:NAND2 t:NOR2 t:AND2 t:OR2 t:NAND3 t:NOR3 t:XOR2 t:XNOR2 t:AOI21 t:OAI21 t:MUX2 %u
    check
    log PASS: and_or keeps two ands and one or until mapping, then uses library cells only
    Predict first After mapping, will any $and or $_AND_ cell remain, and will the mapped netlist use NAND2 cells?

    No coarse or generic cell remains: the script asserts the absence of both families, and the recording honours it. NAND2 is likely but deliberately unasserted, because the exact covering is the mapper's choice and varies between builds. The mapped netlist holds 3 library cells at area 6 library units; which families those are is read from the recording below, never pinned in the script.

    What the recording says

    The generic census is exactly what the RTL wrote: two $and cells feeding one $or cell, three cells total, zero generic gates. Elaboration preserves structure here the way it preserved the adder's word cells in the flow-stages lesson; only the cell family differs.

    Generic cell type

    Cells

    $and

    2

    $or

    1

    Mapping covers those three coarse cells with the library cells the stat report totals below, reaching 178 ps against the loose 1000 ps target. The per-family split is read from that same report, and the union assertion guarantees at least one of these families is present without saying which one the mapper must pick.

    Library cell

    Cells

    NAND2

    3

    Generic netlist: 3 coarse cells, two ANDs feeding one OR.
    The same cone mapped to course.lib: 3 cells, area 6 library units.

    Compare: xor instead of and-or

    This comparison swaps the design rather than breaking the flow. Replace the cone with a single exclusive-or, y = a ^ b, and rerun the identical flow. The generic stage must change shape: one $xor cell instead of two $and cells plus one $or. The mapped stage must change with it, because different logic offers different coverings. The second script pins the new generic count and the same library-only shape after mapping.

    yosys
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    read_verilog <<EOV
    module xor_ab(input a, b, output y);
    assign y = a ^ b;
    endmodule
    EOV
    hierarchy -check -top xor_ab
    proc
    opt
    tee -o stat_generic_xor.txt stat
    write_json net_generic_xor.json
    design -save generic_xor
    techmap
    tee -o abc_xor.txt abc -liberty course.lib -constr typical.constr -D 1000
    tee -o stat_xor.txt stat -liberty course.lib
    write_json net_xor.json
    design -save mapped_xor
    design -load generic_xor
    select -assert-count 1 t:$xor
    design -load mapped_xor
    select -assert-none t:$and t:$or t:$xor t:$mux t:$not t:$add t:$sub %u
    select -assert-none t:$_AND_ t:$_OR_ t:$_NOT_ t:$_MUX_ t:$_XOR_ t:$_NAND_ t:$_NOR_ %u
    select -assert-min 1 t:INV t:BUF t:NAND2 t:NOR2 t:AND2 t:OR2 t:NAND3 t:NOR3 t:XOR2 t:XNOR2 t:AOI21 t:OAI21 t:MUX2 %u
    check
    log PASS: xor variant maps to library cells with a different mix and area

    The xor variant elaborates to a single generic cell and maps to the library cells the comparison table totals below, at the area it totals there. Fewer inputs and a different operator, with the single output unchanged: every one of those changes is visible in the two recordings side by side.

    Build

    Generic cells

    Mapped cells

    Area (library units)

    AND-OR cone

    3

    3

    6

    XOR (`a ^ b`)

    1

    1

    5

    Common mistakes

    Pinning an exact mapped cell, such as asserting a NAND2 minimum, makes the proof brittle across tool builds. Pin generic counts, absence of generics after mapping, and a library-cell lower bound; read the exact mix from the recording.

    What does this flow assert about the mapped design, and what does it deliberately leave unasserted?

    Weak answer: the mapped design uses NAND2 cells, which proves mapping worked.

    Strong answer: the script proves mapping completed without naming the covering. It asserts two $and plus one $or before mapping with zero generic gates, then zero coarse and zero generic cells after mapping with at least one library cell. The recording reads 3 cells at area 6 library units. Which families appear is the mapper's choice, so the script never pins it.

    Follow-up: a rebuild maps to a different mix with the same area. Is the proof broken? No: the assertions pin shape, not covering, so they still pass. Only a test that named the old mix would break, which is exactly why this page does not.

    Check yourself What does the script assert about the generic netlist, and why are exact counts safe there but not after mapping?

    Two $and cells, one $or cell, and zero generic gates. Elaboration is deterministic from the RTL, so exact counts are stable; the mapped covering varies between builds, so only absences and a lower bound are pinned there.

    Check yourself The mapped netlist holds 3 cells. Which assertion guarantees the mapping completed, and what does it not say?

    The union assertion requiring at least one library cell, together with the absence of every coarse and generic family. It guarantees library-only cells without saying which families the mapper chose.

    • Pin exact counts only where elaboration is deterministic.

    • After mapping, pin absences plus a library-cell lower bound, never the mix.

    • Read the exact covering from the recording, not from the assertions.

    Rule of thumb: assert shape in the script and read the mix from the report.

    How this was checked

    Every number and picture on this page comes from two Yosys 0.69 runs of the shown scripts, recorded by the course checker (scripts/tools/run-rtl-testbenches.mjs with COURSE=synth): an AND-OR cone elaborated, lowered, and mapped against course.lib with a loose 1000 ps target, plus an xor variant through the identical flow. The library is fictional, so absolute areas are teaching units.

    • Interview: run a mock interview on this topic

    Related topics

    • Concepts, not commands

    • Equivalence Checking

    • Scripted Flows and Regression

    Previous

    6 / 139

    Next: Concepts, Not Commands

    Up next

    Up nextConcepts, Not Commands

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • What Synthesis Does
    • The Five Flow Stages