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
      • Covering a Network with Cells
      • Cuts and Matching
      • Area Against Delay
      • Inverters and Banned Cells
      • Mapping in Yosys
    • Cell Libraries and Liberty
    • 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

←Technology Mapping
  1. Topics
  2. Logic Synthesis
  3. Logic Optimisation and Mapping
  4. Technology Mapping
  5. Inverters and Banned Cells
On this page

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

    Inverters and Banned Cells

    Bubble pushing, polarity choice, and why some cells are banned.

    Inverters look like wiring until the cover has to place every one of them, and a ban list looks harmless until the fallback cover lands. Both move area without touching the logic.

    After this lesson you can: push bubbles with De Morgan, price polarity both ways, and measure what each stacked ban costs on a recorded run.

    Bubbles move

    An inverter at a gate input is a bubble: a small circle marking a complemented input. De Morgan's laws push bubbles through gates — NOT (a AND b) is (NOT a) OR (NOT b), and the dual for OR — so a bubble slides between a gate's output and its inputs while the function stays the same. The mapper slides bubbles until they merge: an inverter over an AND becomes a NAND2, a leftover pair folds into an AOI or OAI cell, and whatever cannot merge stays as a discrete inverter the cover must place.

    Take y = NOT ((NOT a) AND (NOT b)): two inverters feeding a NAND2. Push both bubbles through and the function is a plain OR of a and b. The calc block prices that move from library data (INV 1, NAND2 2, OR2 3): 4 before against 3 after. The saving of 1 unit is not the point; the mechanism is: bubbles travel until they find the cheapest gate to live in.

    Diagram
    y = NOT ((NOT a) AND (NOT b)); areas in teaching-library area units
    before: INV (1) + INV (1) + NAND2 (2) = 4
    De Morgan: y = a OR b
    after: OR2 (3) = 3
    saving = 4 - 3 = 1 area unit

    Polarity is a choice

    For each output the mapper can build the function as written or its complement plus an inverter, keeping whichever is cheaper — arithmetic, not style. The table shows both directions on XOR (XOR2 and XNOR2 at 5 units each, inverter at 1).

    Function

    Direct

    Complement plus inverter

    Cheaper

    a XOR b

    XOR2 (5)

    XNOR2 (5) + INV (1) = 6

    XOR2

    NOT (a XOR b)

    XNOR2 (5)

    XOR2 (5) + INV (1) = 6

    XNOR2

    Both rows resolve the same way: the direct cell wins by exactly the inverter it avoids — until a ban removes the direct cell, and the complement route becomes the only cover. The recorded covers below follow the same arithmetic on f: the free run absorbs the output inversion inside its single AOI21, while the double-banned run complements input c with a discrete INV feeding the AND2 beside the NAND2.

    Banning cells, recorded

    Libraries mark some cells dont_use, and the mapper must skip them even when they match: uncharacterised at this corner, kept only for legacy netlists, or unroutable in this block. Every ban shrinks the choice set, so re-read area and delay after each change.

    Cause

    Effect on the cover

    Cell not characterised for this corner

    Mapper covers that logic without it.

    Cell kept only for legacy netlists

    New logic never uses it.

    Footprint the block cannot route

    Local covers grow larger.

    The script maps f = NOT ((a AND b) OR c) three times against course.lib: free, then AOI21 and OAI21 banned, then NOR2 banned on top. All three runs use typical.constr with a very loose 100000 ps target, so every ABC report carries its Gates, Area, and Delay line. The assertions prove no generic gate survives any run and no banned cell survives its ban (1 AOI21 cell free; 0 AOI21 or OAI21 cells and 0 banned-kind cells after the bans).

    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
    read_verilog <<EOV
    module cover(input a, b, c, output y);
    assign y = ~((a & b) | c);
    endmodule
    EOV
    synth -top cover
    design -save generic
    tee -o abc_base.txt abc -liberty course.lib -constr typical.constr -D 100000
    tee -o stat_base.txt stat -liberty course.lib
    write_json net_base.json
    select -assert-none t:$and t:$or t:$xor t:$xnor t:$mux t:$not
    select -assert-none t:$_AND_ t:$_OR_ t:$_XOR_ t:$_XNOR_ t:$_MUX_ t:$_NOT_ t:$_NAND_ t:$_NOR_
    check
    design -load generic
    tee -o abc_ban1.txt abc -liberty course.lib -dont_use AOI21 -dont_use OAI21 -constr typical.constr -D 100000
    tee -o stat_ban1.txt stat -liberty course.lib
    write_json net_ban1.json
    select -assert-none t:$and t:$or t:$xor t:$xnor t:$mux t:$not
    select -assert-none t:$_AND_ t:$_OR_ t:$_XOR_ t:$_XNOR_ t:$_MUX_ t:$_NOT_ t:$_NAND_ t:$_NOR_
    select -assert-none t:AOI21 t:OAI21
    check
    design -load generic
    tee -o abc_ban2.txt abc -liberty course.lib -dont_use AOI21 -dont_use OAI21 -dont_use NOR2 -constr typical.constr -D 100000
    tee -o stat_ban2.txt stat -liberty course.lib
    write_json net_ban2.json
    select -assert-none t:$and t:$or t:$xor t:$xnor t:$mux t:$not
    select -assert-none t:$_AND_ t:$_OR_ t:$_XOR_ t:$_XNOR_ t:$_MUX_ t:$_NOT_ t:$_NAND_ t:$_NOR_
    select -assert-none t:AOI21 t:OAI21 t:NOR2
    check
    log PASS: one function maps cleanly with two stacked bans
    Predict first The free run should reach for the AOI21. What do the two banned runs cost?

    The free cover should be the single AOI21. Each ban then removes a cover the mapper could have wanted; the run table below shows what each removal actually cost in area and arrival.

    Mapping

    Cells

    Area (library units)

    Delay (ps, ABC report)

    AOI21/OAI21/NOR2 cells

    Free

    1

    3

    114

    1

    AOI21, OAI21 banned

    2

    5

    228

    0

    Plus NOR2 banned

    3

    6

    218

    0

    Read the table as a staircase built by subtraction. The free run holds 1 cell at area 3. The first ban forces it off the complex cells onto AND2 x1, NOR2 x1 at area 5, and the second ban takes the NOR2 fallback away as well for AND2 x1, INV x1, NAND2 x1 at area 6. The whole staircase is the price of the ban list.

    Recorded free netlist: 1 cell, area 3.
    Recorded netlist with AOI21 and OAI21 banned: 2 cells, area 5.

    Break it: ban the direct XOR cell

    The polarity table says the complement route wins when the direct cell is banned. This break-it records exactly that on a one-gate function, y = a XOR b, mapped twice against course.lib: free, then with XOR2 banned. Both runs use typical.constr with the same very loose 100000 ps target. The assertions prove no generic gate survives either run, the free run really uses an XOR2, and none survives the ban.

    yosys
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    read_verilog <<EOV
    module xorf(input a, b, output y);
    assign y = a ^ b;
    endmodule
    EOV
    synth -top xorf
    design -save generic
    tee -o abc_xfree.txt abc -liberty course.lib -constr typical.constr -D 100000
    tee -o stat_xfree.txt stat -liberty course.lib
    write_json net_xfree.json
    select -assert-none t:$and t:$or t:$xor t:$xnor t:$mux t:$not
    select -assert-none t:$_AND_ t:$_OR_ t:$_XOR_ t:$_XNOR_ t:$_MUX_ t:$_NOT_ t:$_NAND_ t:$_NOR_
    select -assert-min 1 t:XOR2
    check
    design -load generic
    tee -o abc_xxor.txt abc -liberty course.lib -dont_use XOR2 -constr typical.constr -D 100000
    tee -o stat_xxor.txt stat -liberty course.lib
    write_json net_xxor.json
    select -assert-none t:$and t:$or t:$xor t:$xnor t:$mux t:$not
    select -assert-none t:$_AND_ t:$_OR_ t:$_XOR_ t:$_XNOR_ t:$_MUX_ t:$_NOT_ t:$_NAND_ t:$_NOR_
    select -assert-none t:XOR2
    check
    log PASS: xor maps free and without its direct cell
    Predict first Banning XOR2 removes the direct cover. Will ABC fail, or take the complement route?

    The complement route, recorded: the banned run should read XNOR2 plus INV at 6 area units against 5 free, proving the polarity table with a run instead of arithmetic.

    Mapping

    Cells

    Area (library units)

    Delay (ps, ABC report)

    XOR2 cells

    Free

    1

    5

    194

    1

    XOR2 banned

    2

    6

    248

    0

    The free run holds XOR2 x1 at area 5: the direct cell, exactly as the table prices it. The banned run holds INV x1, XNOR2 x1 at area 6, with 0 XOR2 cells left — the complement route at the priced 6. The ban never strands the cone: XNOR2 plus INV build any XOR, so a complete library always leaves a cover and only the price moves. Arrival slips from 194 ps to 248 ps on two gates of logic, so recheck delay after every ban-list edit, not just area.

    Recorded netlist with XOR2 banned: 2 cells, area 6.

    Common mistakes

    Banning cells and walking away: each dont_use entry removes options the mapper may need. Recheck area and delay after every change to the ban list, and never assume the fallback cover is close to the original: here two bans move the area from 3 to 6 on three gates of logic.

    An inverter sits between two gates. What does the mapper do with it, and what if its favourite cell is banned?

    • Weak answer: inverters are free wiring, so the mapper ignores them; bans just pick the next cell in the list.

    • Strong answer: bubbles push to the cheapest merge — a bubble over an AND becomes a NAND2, leftover pairs fold into AOI or OAI cells. Here the free run is 1 AOI21 cell; each ban step raises the area the run table shows, and every step is proven by a select assertion reading 0 banned cells.

    • Follow-up: the banned cell was the only match for a cone. What now? Nothing breaks: INV plus NAND2 build any function, so a complete library always leaves a valid cover, just a larger one. Mapping fails only when the library itself cannot build every function — then fix the library setup, not the rule.

    Check yourself Rewrite y = NOT ((NOT a) AND (NOT b)) without inverters and state the saving.

    Push both bubbles through the gate: y = a OR b, one OR2 at 3 units against 4 before, saving 1 area unit. The inversions moved into the OR instead of being deleted.

    Check yourself Stacking the NOR2 ban raises the area yet the recorded arrival falls. Which cell drives the output in each cover?

    With one ban the output driver is the NOR2 of the AND2-plus-NOR2 cover; with two bans the AND2 over an inverter and a NAND2. In this ABC script the AND2 serving the 50 fF load reports the shorter arrival — 218 ps against 228 ps in the Delay column — so a bigger cover can be faster when the ban swaps the output stage.

    • Bubbles travel until they merge: over an AND into NAND2, leftover pairs into AOI or OAI.

    • Polarity is priced both ways; the complement route wins when the direct cell is banned.

    • Each dont_use entry removes options: recheck area and delay after every edit.

    Rule of thumb: after every ban-list edit, remap and re-read area and delay before signing anything off.

    How this was checked

    Every number and picture on this page comes from Yosys 0.69 runs of the scripts shown, recorded by the course checker (scripts/tools/run-rtl-testbenches.mjs with COURSE=synth): ABC maps f = ~((a & b) | c) against course.lib free, with AOI21 and OAI21 banned, and with NOR2 banned on top; a second script maps y = a XOR b free and with XOR2 banned. The library is fictional, so absolute areas are teaching units. The De Morgan and polarity arithmetic uses library cell areas as labelled teaching units, not run output.

    • Interview: run a mock interview on this topic

    Related topics

    • Area Against Delay

    • Mapping in Yosys

    • See also: Structuring and Buffering

    Previous

    25 / 139

    Next: Mapping in Yosys

    Up next

    Up nextMapping in Yosys

    Sign in to save progress

    Practice this lessonPrevious lessonReport an error

    See also

    • Covering a Network with Cells
    • Cuts and Matching