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
  • Logic Optimisation and Mapping20
    • Boolean Optimisation
    • Technology Mapping
    • Cell Libraries and Liberty
      • What a Library Contains
      • Reading the Teaching Library
      • Delay Tables and Interpolation
      • Flops, Power, and Variants
      • Mapping Against the Library
    • Structuring and Buffering
  • 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

←Cell Libraries and Liberty
  1. Topics
  2. Logic Synthesis
  3. Logic Optimisation and Mapping
  4. Cell Libraries and Liberty
  5. Reading the Teaching Library
On this page

    Part 2 of 9, lesson 12 of 20Part 2 of 9/Logic Optimisation and Mapping/Lesson 12 of 20Intermediate

    Reading the Teaching Library

    The course teaching library cell by cell, with an abridged Liberty excerpt.

    Every delay lookup in this course indexes these tables slew-first. One swapped axis corrupts all of them at once, and nothing flags the error except the file itself.

    After this lesson you can: list all fifteen teaching-library cells with areas, and read the real INV and NAND2 tables slew-first.

    The question

    A library the mapper cannot read might as well not exist. This lesson reads course.lib end to end: the script instantiates all fifteen cells once, and the stat report below is the recorded listing, one row per cell with areas straight from the report. Two tables are copied exactly from the file along the way, the INV and NAND2 rise tables, so every later lookup has a ground truth to point at.

    The course library is a small fictional library called course, kept in course.lib. A second library, nand_only.lib, holds only INV, BUF, and NAND2 at the same areas, and the mapping lesson prices the difference.

    Every cell, recorded

    The script reads course.lib so its fifteen cells become known modules, instantiates each once, and asks stat -liberty for the histogram. Each select line pins one count: one row per cell, areas straight from the recorded report.

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    read_liberty -lib course.lib
    read_verilog <<EOV
    module top(input a, b, c, s, d, clk, rn, output [14:0] y);
    INV g0(.A(a), .Y(y[0]));
    BUF g1(.A(a), .Y(y[1]));
    NAND2 g2(.A(a), .B(b), .Y(y[2]));
    NOR2 g3(.A(a), .B(b), .Y(y[3]));
    AND2 g4(.A(a), .B(b), .Y(y[4]));
    OR2 g5(.A(a), .B(b), .Y(y[5]));
    NAND3 g6(.A(a), .B(b), .C(c), .Y(y[6]));
    NOR3 g7(.A(a), .B(b), .C(c), .Y(y[7]));
    XOR2 g8(.A(a), .B(b), .Y(y[8]));
    XNOR2 g9(.A(a), .B(b), .Y(y[9]));
    AOI21 g10(.A(a), .B(b), .C(c), .Y(y[10]));
    OAI21 g11(.A(a), .B(b), .C(c), .Y(y[11]));
    MUX2 g12(.A(a), .B(b), .S(s), .Y(y[12]));
    DFF g13(.D(d), .CLK(clk), .Q(y[13]));
    DFFR g14(.D(d), .CLK(clk), .RN(rn), .Q(y[14]));
    endmodule
    EOV
    hierarchy -check -top top
    tee -o stat_all.txt stat -liberty course.lib
    select -assert-count 1 t:INV
    select -assert-count 1 t:BUF
    select -assert-count 1 t:NAND2
    select -assert-count 1 t:NOR2
    select -assert-count 1 t:AND2
    select -assert-count 1 t:OR2
    select -assert-count 1 t:NAND3
    select -assert-count 1 t:NOR3
    select -assert-count 1 t:XOR2
    select -assert-count 1 t:XNOR2
    select -assert-count 1 t:AOI21
    select -assert-count 1 t:OAI21
    select -assert-count 1 t:MUX2
    select -assert-count 1 t:DFF
    select -assert-count 1 t:DFFR
    check
    log PASS: all fifteen teaching-library cells instantiate with listed areas
    Predict first The script instantiates fifteen cells, one of each kind. How many rows will the stat histogram hold, and which cell costs the most?

    Fifteen rows, one per cell kind, each with count 1. The two flop cells cost the most: DFF at 8 units and DFFR at 10, against 1 to 5 for every combinational cell. The recorded table shows it.

    Cell

    Function (exact from course.lib)

    Count (recorded)

    Area (recorded)

    AND2

    A*B

    1

    3

    AOI21

    !((A*B)+C)

    1

    3

    BUF

    A

    1

    2

    DFF

    IQ

    1

    8

    DFFR

    IQ

    1

    10

    INV

    !A

    1

    1

    MUX2

    (S*B)+(!S*A)

    1

    5

    NAND2

    !(A*B)

    1

    2

    NAND3

    !(A*B*C)

    1

    3

    NOR2

    !(A+B)

    1

    2

    NOR3

    !(A+B+C)

    1

    3

    OAI21

    !((A+B)*C)

    1

    3

    OR2

    A+B

    1

    3

    XNOR2

    !(A^B)

    1

    5

    XOR2

    A^B

    1

    5

    Read the shape of the menu: INV 1, BUF 2, NAND2 and NOR2 at 2, AND2 and wider gates at 3, XOR and mux structures 5, flops 8 and 10. This price list is why XOR-heavy logic costs more against the three-cell library: the recorded 4-bit adder in mapping-in-yosys comes out at about 1.12x, area 66 against 59, because sums that take one 5-unit XOR2 each are rebuilt from several 2-unit NAND2 cells.

    Recorded stat areas for the fifteen teaching-library cells, one of each instantiated: INV 1, BUF 2, NAND2 and NOR2 2, AND2 and OR2 3, three-input and compound gates 3, XOR2, XNOR2 and MUX2 5, DFF 8, DFFR 10.

    The real INV table

    Each delay table repeats the template axes: index_1 is input_net_transition, the rows, and index_2 is total_output_net_capacitance, the columns. Both axes of the teaching library read 0.01, 0.1. The INV rise table below is copied exactly from course.lib, where it stands as values("0.05,0.07","0.08,0.11"): first string, first row; values across a string run across the loads.

    Input slew (rows) / output load (cols)

    0.01

    0.1

    0.01

    0.05

    0.07

    0.1

    0.08

    0.11

    Read the second row as carefully as the first: the slow-slew row reads 0.08 and 0.11 ns. One digit moves every lookup touching that corner, so check each values string entry by entry before interpolating.

    The real NAND2 table

    The NAND2 rise table stands in course.lib as values("0.08,0.1","0.11,0.14") on both the A and B arcs, read row by row: slew 0.1 with load 0.01 is 0.11, and slew 0.01 with load 0.1 is 0.10.

    Input slew (rows) / output load (cols)

    0.01

    0.1

    0.01

    0.08

    0.10

    0.1

    0.11

    0.14

    Both tables are nanoseconds by the file header, so 0.11 is 110 ps. Fall tables match rise on every arc here, and all output-slew tables read values("0.02,0.04","0.04,0.08"). Real libraries vary per arc and direction; this one stays symmetric so the lessons can concentrate on the lookup.

    Reading one cell, top to bottom

    Read a cell the way the mapper does: area for the price, pin functions and capacitances for compute and load, one timing group per arc for speed. NAND2 has one group per input pin; DFF replaces output arcs with constraint groups on D against CLK plus clock-to-output, printed in full in the flops lesson.

    Timing sense tells the tool which input direction matters, arc by arc as course.lib lists it: negative_unate on both NAND2 arcs, positive_unate on both AND2 arcs, non_unate on both XOR2 arcs (A and B) and on all three MUX2 arcs (data A, data B, and select S). The mapper uses it to propagate the right slew through each stage.

    Break it: drop the library from the report

    The second script instantiates one NAND2 and runs stat without -liberty. Counts survive, because the design still holds the cell. Areas vanish, because no library prices them: structure comes from the RTL, cost from the library.

    yosys
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    read_liberty -lib course.lib
    read_verilog <<EOV
    module top(input a, b, output y);
    NAND2 g1(.A(a), .B(b), .Y(y));
    endmodule
    EOV
    hierarchy -check -top top
    tee -o stat_nolib.txt stat
    select -assert-count 1 t:NAND2
    check
    log PASS: stat without a library counts the cell but reports no area

    The recorded plain report, shown below, counts one NAND2 and prints no area line at all: no zero, no total. The recorded library report above prices the same cell at 2 units. When a stat report shows counts but no area line, check whether -liberty named the right file before doubting the netlist.

    Diagram
    4. Printing statistics.
    
    === top ===
    
            +----------Local Count, excluding submodules.
            | 
            3 wires
            3 wire bits
            3 public wires
            3 public wire bits
            3 ports
            3 port bits
            1 cells
            1   NAND2

    Common mistakes

    Reading rows as loads. Index_1 is input slew and prints first in every values string pair, starting with the fast-slew row at slew 0.01. Swapping the axes transposes the table, mirroring 0.10 and 0.11 across every lookup built on it.

    Quoting the shortened excerpt for a lookup. Any table with ellipses in it is a sketch. Only the full two-by-two values above, copied from the file, give exact entries.

    A colleague hands you a NAND2 table copied into slides. How do you check it before interpolating?

    Weak answer: I trust the copy I was given and interpolate from it. Small table errors average out.

    Strong answer: the file wins, always. I reread values("0.08,0.1","0.11,0.14") row by row against index_1 for slew and index_2 for load, so slew 0.1 with load 0.01 is 0.11, and I check the INV second row starts at 0.08. Then I rerun any lookup that consumed the copied values.

    Follow-up: a colleague's script parsed rows as loads for a year. What breaks first, and how would you notice?

    Check yourself At slew 0.1 and load 0.01, what is the NAND2 rise delay, and which values string holds it?

    0.11 ns from the second string of values("0.08,0.1","0.11,0.14"). The first string is the fast-slew row at 0.01, so the second string is slew 0.1, and its first entry is load 0.01.

    Check yourself The plain stat report counts the NAND2 but prices nothing. Which half of the lesson does that prove?

    That structure comes from the RTL and cost comes from the library. The count survives without -liberty; the area needs the file.

    • index_1 is input slew (rows); index_2 is output load (columns).

    • NAND2 rise is values("0.08,0.1","0.11,0.14"): slew 0.1 with load 0.01 is 0.11.

    • Structure comes from the RTL; cost comes from the library, so stat without -liberty prices nothing.

    Rule of thumb: the file wins over any excerpt: reread the values strings row by row.

    How this was checked

    Every number and picture on this page comes from Yosys 0.69 runs of the two scripts shown, recorded by the course checker (scripts/tools/run-rtl-testbenches.mjs with COURSE=synth): all fifteen cells instantiated once with a stat -liberty histogram, plus one NAND2 with a plain stat report. Tables and functions are copied exactly from scripts/tools/synth-libs/course.lib.

    • Interview: run a mock interview on this topic

    Related topics

    • Delay tables and interpolation

    • Technology Mapping

    Previous

    28 / 139

    Next: Delay Tables and Interpolation

    Up next

    Up nextDelay Tables and Interpolation

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Flops, Power, and Variants
    • Mapping Against the Library