Как разработать микросхему, от идеи до результата. Часть 3. Схемотехническое представление и Layout

В прошлой статье мы установили все программы, а в этой части, мы наконец приступим к практической части. Готовьтесь, эта часть будет очень большой. Для тех кто пропустил прошлые части — ссылки ниже.

image-loader.svg
Как разработать микросхему, от идеи до результата. Ссылки на все статьи։


В этой части мы:

  1. Будем рисовать схему, используя XSCHEM
  2. Произведём симуляцию нашей схемы, используя NGSPICE
  3. Поймём цикл производства микросхемы
  4. Нарисуем Layout, используя KLayout


Предполагается, что вы уже прочитали предыдущие материалы. Если мне удалось вас заинтересовать, прошу под кат!

Откроем xschem:

cd xschem
xschem


Типичная ошибка, если вы не выполнили source sourceme.sh։

Tcl_AppInit() error: can not execute /home/armleo/Desktop/habr_nand_sky130/xschem/xschemrc, please fix:

can't read "env(PDK_ROOT)": no such variable


Если вы сделали всё правильно, откроется следующее окно XSCHEM:

xschem_opened.png


Если вам открылось что-то иное, то скорее всего — вы не в папке xschem, либо у вас не установлен PDK, либо вы НЕ клонировали мой репозиторий, который содержит Caravel и изменённый файл xschemrc. Вам не нужно менять этот файл, если вы используете проект из моего репозитория. Мой файл xschemrc можно найти тут.

Затем я собрал схему простого NAND.

File -> New Schematic:

image-loader.svg


Затем нажал на Insert и создал 4 транзистора:

image-loader.svg


В окне я выбрал компонент, который мне нужен. Для этого в списке я выбрал sky130A/libs.tech из левого списка (отмечено красным).

Затем из списка, я открыл папкуsky130_fd_pr, отмечено черным:

image-loader.svg


Затем я добавил nfet_01v8 из списка sky130_fd_pr, затем я скопировал этот транзистор:

image-loader.svg


Повторяем те же действия для pfet_01v8из sky130_fd_pr.

Затем я добавил OPIN из devices. Для этого я нажал Insert и выбрал из списка стандартной библиотеки (красная) папку devices (синий цвет):

image-loader.svg


Затем я выбрал OPIN:

image-loader.svg


Левый клик для того, чтобы открыть меню параметров. Чтобы назвать его, поменяйте параметр lab на Y:

laby.png


Затем я создал IOPIN с названиями VPWR, VGND, иIPIN с названием A и B. Эти типы используются, чтобы сказать XSCHEM, чтобы он создал пины для этой схемы с соответствующим типом и названием.

Также я поменял параметр W nfet транзисторов на 0.65 мкм. А W транзисторов PFET я поменял на 1:

image-loader.svg


Затем я использовал Shift + W и W, чтобы подключить транзисторы. Чтобы выбрать объекты зажмите левый клик и выберите регион внутри, которого будут выбраны все объекты.

Используйте M, чтобы двигать выбранные объекты. Нажмите U для отмены последнего действия:

nand_xschem.png


Давайте поймём, как выглядит SPICE netlist. Документацию можно взять из NGSPICE manual.

Первая строка всегда комментарий. Будьте осторожны.
* это комментарий

* .lib, чтобы включить библиотеку.
* После пути к библиотеке должен стоять corner case (tt/ss/ff)
* .lib не может содержать enviornment variables,
* так что нам нужно использовать абсолютный путь
.lib "/home/armleo/Desktop/pdk_root/sky130A/libs.tech/ngspice/sky130.lib.spice" tt

* Включить файлы с объявлениями разных компонентов
.include "/home/armleo/Desktop/pdk_root/sky130A/libs.ref/sky130_fd_io/spice/sky130_fd_io.spice"
.include "/home/armleo/Desktop/pdk_root/sky130A/libs.ref/sky130_fd_sc_hvl/spice/sky130_fd_sc_hvl.spice"
.include "/home/armleo/Desktop/pdk_root/sky130A/libs.ref/sky130_fd_sc_hd/spice/sky130_fd_sc_hd.spice"


* Создать компонент типа subckt с именем X123
* Первая буква означает։
* R - Resistor
* C - Capacitors
* X - subckt
* sky130 объявляет транзисторы в виде subckt
* Подключить a, b, c, vdd, vss линии к пинам subckt
* последний идентификатор показывает тип subckt: subckt_example

X123 a b c vdd vss subckt_example

* Декларация самой subckt example
.subckt subckt_example pin_a pin_b pin_c vdd vss

* Объявить резистор R1
* Между a и b
* И имеющая 1k (тысяча) сопротивления
R1 a b 1k

* Декларация конденсатора C1
* между b и vss
* И имеющая 10 pico Farad
C1 b vss 10p

* конец subckt
.ends

* Провести анализ transient
* 1ns шаг, 10ns до конца
.tran 1ns 10ns

* Конец декларации SPICE
.end


SPICE netlist это список соединения компонентов (nets), декларация компонентов (subckt, resistor, capacitor, etc) и их определений (.subckt/.ends).

Симуляторы SPICE поддерживают 3 (основных) режима работы. .TRAN анализ, используется для того, чтобы составить графики время-значения напряжения, либо время-значение тока. Вот результат .TRAN анализа инвертора.

inverter_waveform.png

AC симуляция позволяет построить график зависимости напряжения, усиления и тока от частоты источника. DC позволяет построить график зависимости напряжения и тока от напряжения и тока. Во всех режимах поддерживаются скрипты измерения значений (.meas). Про анализы написано много статей, стоит обратиться именно к ним. В этой статье мы не будем рассматривать ничего кроме .TRAN.

Для генерации SPICE netlist нажмём на кнопку netlist.

image-loader.svg

SPICE netlist имеет следующий вид:

**.subckt my_nand Y A VPWR B VGND VPB VNB
*.opin Y
*.ipin A
*.iopin VPWR
*.ipin B
*.iopin VGND
*.iopin VPB
*.iopin VNB
XM1 Y B net1 VNB sky130_fd_pr__nfet_01v8 L=0.15 W=0.65 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1 
XM2 net1 A VGND VNB sky130_fd_pr__nfet_01v8 L=0.15 W=0.65 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1 
XM3 Y A VPWR VPB sky130_fd_pr__pfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1 
XM4 Y B VPWR VPB sky130_fd_pr__pfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1 
**.ends
** flattened .save nodes
.end


Но этот netlist не содержит источников напряжения либо тока. Поэтому, если вы попробуете просимулировать эту схему, у вас будет ошибка о том, что схему нельзя просимулировать. Также netlist компонента не содержит ․lib/.include которые подскажут симулятору, где искать объявленные модели транзисторов и других компонентов PDK.

Теперь сгенерируем symbol: Symbol -> Make symbol from schematic.

Затем создадим новую схему. Для этого нажмём на File -> New Schematic и назовём её my_nand_tb.sch. Файл следует сохранить в той же папке, где и другие ․sch в папке xschem нашего проекта.

nand_tb.PNG


И code для code S1 и S2. Первый кусок кода подключает необходимые библиотеки. Второй кусок кода говорит симулятору NGSPICE просимулировать по 0.1ns до достижения 30ns. Конкретно блок ․control работает только в NGSPICE, в других симуляторах нужно поменять под конкретный симулятор.

vsource для источников напряжения. И этот же компонент в режиме пульса для входов. Для этого я прочитал в мануале NGSPICE, как создать пульс. Все напряжения я взял 1.65 вольт.

Параметр mc_mm_switch поставлен в значение 0, поскольку в древних версиях был баг, из-за чего этот параметр нужно было определять вручную.

Схему можно найти в файле my_nand_tb.sch, в моём репозитории.

Затем я нажал на кнопку «netlist», для того чтобы сгенерировать my_nand_tb.spice, который содержит источники напряжения, а значит, если вы всё сделали правильно, симуляция должна пройти удачно.

После этого сгенерируется файл netlist: my_nand_tb.spice. Вот его содержимое:

**.subckt my_nand_tb input0_net vdd1v8 output_net input1_net
*.opin input0_net
*.opin vdd1v8
*.opin output_net
*.opin input1_net
V2 input0_net GND PULSE(0 1.65 5ns 1ns 1ns 4ns 10ns)
V3 vdd1v8 GND 1.65
V4 input1_net GND PULSE(0 1.65 15ns 1ns 1ns 9ns 20ns)
C1 output_net GND 20ff m=1
x1 vdd1v8 vdd1v8 input0_net output_net input1_net GND GND my_nand
**** begin user architecture code

.param mc_mm_switch=0
.lib /opt/pdk_root/sky130A/libs.tech/ngspice/sky130.lib.spice ss
.temp 125


.control
tran 0.1n 30n
plot V(input0_net) V(input1_net) V(output_net)
write
.endc

**** end user architecture code
**.ends

* expanding   symbol:  my_nand.sym # of pins=7
* sym_path: /home/armleo/Desktop/habr_nand_sky130/xschem/my_nand.sym
* sch_path: /home/armleo/Desktop/habr_nand_sky130/xschem/my_nand.sch
.subckt my_nand  VPWR VPB A Y B VNB VGND
*.opin Y
*.ipin A
*.iopin VPWR
*.ipin B
*.iopin VGND
*.iopin VPB
*.iopin VNB
XM1 Y B net1 VNB sky130_fd_pr__nfet_01v8 L=0.15 W=0.65 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1 
XM2 net1 A VGND VNB sky130_fd_pr__nfet_01v8 L=0.15 W=0.65 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1 
XM3 Y A VPWR VPB sky130_fd_pr__pfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1 
XM4 Y B VPWR VPB sky130_fd_pr__pfet_01v8 L=0.15 W=1 nf=1 ad='int((nf+1)/2) * W/nf * 0.29' as='int((nf+2)/2) * W/nf * 0.29'
+ pd='2*int((nf+1)/2) * (W/nf + 0.29)' ps='2*int((nf+2)/2) * (W/nf + 0.29)' nrd='0.29 / W' nrs='0.29 / W'
+ sa=0 sb=0 sd=0 mult=1 m=1 
.ends

.GLOBAL GND
** flattened .save nodes
.end

Симуляция testbench


Чтобы произвести симуляцию выполним эту команду:

ngspice -r "my_nand_tb.raw" "my_nand_tb.spice"


Хотя ․spiceinit содержит настройки, которые ускорят запуск симуляции в несколько раз, тем не менее симуляция занимает очень длительное время. Все библиотеки и симуляторы, которые я использовал, производили симуляцию за пару секунд. Тим Митро утверждает, что причина в том, что мы загружаем все три corner case и абсолютно все определения, для всех компонентов, вне зависимости от того, какие варианты нам нужны.

Если у вас git status показывает, что ․spiceinit изменился, значит вы случайно запустили симуляцию пятой командой из списка конфигурации XSCHEM. Верните его в исходное положение. Либо страдайте симуляциями по 10 лет.

После симуляции в терминале должна быть следующая консоль։

ngspice console.png


И следующее окно:

image-loader.svg


Really cool!

Сделаем plot по отдельности. Введите в консоль NGSPICE:

plot v(output_net)
plot v(input0_net)
plot v(input1_net)


Должно получиться так:

nand_tb.raw.plotted.png


Чтобы выйти из NGSPICE введите:

exit

Разработка Layout


Мы научились делать схему и получать из неё SPICE netlist. Иногда выгодно писать SPICE netlist самому, но я не буду вас мучать симуляциями и SPICE netlist-ами ։D. Приступим, наконец, к так называемому layout.

Для рисования layout будем использовать Klayout, но для DRC и LVS будем использовать Magic VLSI.
PS: Я решил не переводить layout ибо не нашёл хорошего слова.

▍Разбираемся в слоях


Очевидно, что для того, чтобы сделать Layout, нам нужно понять значение каждого слоя в нашей layout, которую мы должны нарисовать. Рассмотрим процесс производства микросхемы.

Для начала делают подложку из силикона.

image-loader.svg


Затем вся пластина покрывается в фоторезист.

image-loader.svg


После чего, светом фоторезист убирается.

image-loader.svg


Во все места микросхемы, которые нужно покрыть N полупроводником (слой NWELL нашей микросхемы) вводятся ионные импланты Арсения.

image-loader.svg


После чего фоторезист убирается. Затем эти шаги повторяются, для создания PWELL, но вместо Арсения используется Бор.

Мы получили наш NWELL/PWELL, теперь мы вставляем диффузии типа P и типа N. Там, где диффузия (diff) соприкасается с PSDM вставляется P полупроводник. Там, где диффузия (diff) соприкасается с NSDM вставляется N полупроводник:

image-loader.svg


Используя термическую обработку, образуется диэлектрик из оксида силикона SiO2. Чтобы изготовить эту маску, берётся слой, в котором полисиликон находится над диффузией (слой poly).

image-loader.svg

После чего вставляется слой полисиликона. Для этого полисиликон испаряется, и микрочастицы вставляются в области, где фоторезист отсутствует:

image-loader.svg


Затем, аналогичным образом, вставляется контакт (licon1) и первый слой тонкого металла li1.

image-loader.svg


Эти два шага повторяются для каждого слоя via и Mx.

image-loader.svg

▍Разработка Layout (практическая часть)


Откроем уже существующую ячейку и скопируем из неё все необходимую базу: содержимое слоёв, стиль и т.д. и т.п.


 LD_LIBRARY_PATH=/opt/klayout-v0.27.4/bin-release /opt/klayout-v0.27.4/bin-release/klayout -e -nn $PDK_ROOT/sky130A/libs.tech/klayout/sky130A.lyt \
 -l $PDK_ROOT/sky130A/libs.tech/klayout/sky130A.lyp \
 $PDK_ROOT/sky130A/libs.ref/sky130_fd_sc_hd/gds/sky130_fd_sc_hd.gds


Это запустит Klayout с файлом технологии (lyt), настройками для конкретной технологии (lyp), в режиме редактирования (-e) и откроет файл sky130_fd_sc_hd.gds. Документацию можно найти вот тут.

Если у вас segfault, значит вы случайно запустили Klayout из репозитория Убунту. Если сверху у вас не видно большой T и надписи sky130A, значит у вас не установлен PDK, либо вы не сделали source sourcme.sh до того как запустить Klayout. Я на этом уже сто раз попадался.

Если вы всё сделали правильно, откроется окно Klayout:

klayout_opened.png


В левой панели нужно найти ячейку sky130_fd_sc_hd_inv_1. Затем нажать правую кнопку мыши и выбрать Save Selected Cells As, и сохранить его, как my_nand.gds в папке gds нашего проекта. И в открывшемся окне нажмите ОК.

SaveLayoutOptions.png


Затем откроем этот файл. Выйдите из Klayout и введите след. команду։

 LD_LIBRARY_PATH=/opt/klayout-v0.27.4/bin-release /opt/klayout-v0.27.4/bin-release/klayout -e -nn $PDK_ROOT/sky130A/libs.tech/klayout/sky130A.lyt -l $PDK_ROOT/sky130A/libs.tech/klayout/sky130A.lyp gds/my_nand.GDS


Должно открыться следующее окно.

klayout_my_nand_start.png


Причина, почему мы копируем существующий элемент в том, что нам нужен слой OUTLINE, а точнее её высота. Без неё наша ячейка не поместится внутри линий питания библиотеки sky130_fd_sc_hd, ибо инструмент Place and route не будет знать, как именно поставить эту ячейку относительно линий питания (Power Rails).

Ещё стоит сказать, про то, что эта библиотека использует транзисторы с повышенным уровнем Vth для уменьшения энергопотребления. Для этого над всеми PFET транзисторами проведён слой hvtp. Мы удалим его, ибо наша схема построена на обычных транзисторах.

Для этого выберем этот слой, кликнув несколько раз, пока надпись внизу не укажет полигон, который находится на слое HVTP. Затем нажмите Delete:

delete_hvtp.png


В правой верхней панели HVTP должно стать серым. Это означает, что данный слой не содержит полигонов.

hvtp_gray.png

Скроем слои, которые не содержат полигонов. Нажмите правой кнопкой на любой слой и выберете Hide Empty Layers.

hide_empty_layers.png

Должно получиться вот так:

after_hidden_layers.png

Красота! А теперь поменяем стиль отрисовки некоторых слоёв. Для этого поставим галочки в панели Layer Toolbox.

layer_toolbox.png

Для этого в верхней панели выбираем слой, а в нижней можем менять цвет и паттерн конкретного слоя.

  • Poly → Первый паттерн
  • Licon1 → Purple, 4ая линия, 3ий паттерн
  • Diff → Orange, whole pattern (первый)
  • Li1 → Orange, netted pattern (последний)


Должно выйти вот так:

inverter_layers_colored.png

Чтобы спрятать слой, выберете слой и нажмите на него левой кнопкой мыши, должно открыться следующее подменю. В нём вы можете либо спрятать один слой, показать слой, либо спрятать и показать все слои.

image-loader.svg


Теперь наконец-то, поменяем эту схему на схему NAND. Скроем слои, которые мы не будем пока менять. Оставим только poly, licon и diff. Нажимаем на любой слой и «Hide all». Затем нажимаем на poly, diff, licon и нажимаем на Show. Должно быть так:

inverter_after_hidden_layers.png

Настроим рулетку. Откройте меню Edit и нажмите Ruler And Annotation Setup.

Ruler menu.png

Поменяйте рулетку в ортогональный режим и включите Snap To Grid.

Rules and annotation.png

Закройте это окно и нажмите F3. И поменяйте шаг на 0.01.

grid step.png

Теперь продлим diff. Двойной клик по diff откроет меню редактирования полигона. Поменяйте Upper right X: 0.34 + 1.09.

diff upper right x.png

Откуда взялся 1.09? Я добавил длину каждого элемента. Прочитаем правила DRC для нашей технологи вот тут. Нас интересуют следующие правила.

Расстояние licon от полисиликона должно быть более чем 0.05 мкм:

licon.11a.PNG


Расстояние между двумя полигонами должно быть ровно 150нм:

poly.1a.png


Licon должен быть окружён диффузией минимум на 40нм:

licon.5a.png


Licon позволяют подключать металлический слой li1 к полисиликону, либо к диффузии. Вот слои в разрезе:

layers.png


Из документации мы узнаём, что расстояние между licon должно быть 170нм, а сами licon должны быть размером 0.17 мкм на 0.17 мкм:

licon2.png


licon1.png


Итоговая структура. Видим все наши правила в деле:

diff_len.png


Чувствуйте обман? Вроде технология называется 130нм, а полисиликон 150нм? Всё просто 130нм можно применять только в специальных компонентах SRAM ячеек.

Теперь нарисуем второй полисиликон, который в скором времени станет gate-ом для двух транзисторов. Для этого я создал Box из полисликона и установил координаты. Чтобы понять какие координаты поставить, я просто взял координаты первого полисиликона и добавил к ним 0.05 мкм + 0.17 мкм + 0.05 мкм + 0.150 мкм = 0.27 + 0.15 мкм по горизонтали.

second_poly.png


Затем повторил те же действия для нижней диффузии. Теперь сделаем контакты (licon).

Скопировал три верхние и два нижние licon и переместил их центр так, чтобы между ними было расстояние 0.25 мкм от второго licon. 0.25 мкм взято не из воздуха. Полисликон должен быть от левого licon на 50нм правее. Затем, сам полисиликон имеет длину 0.150 мкм, и в конце концов 50нм от полисиликона находится сам licon. В итоге должно быть вот так:

0.25 licon

Добавим второе соединение к полисилкону. Из документации мы узнаем, что полисилкон должен окружать licon с двух сторон по 80нм, а по всем остальным сторонам хотя бы 50нм.

licon8.png


Для этого создадим Box 0.34 мкм на 0.34 мкм. Минимум нужен 0.33 на 0.33. Затем скопируем licon1 и поместим его посередине полисилона. Получится как-то так:

second_licon1.PNG

Удалим средние нижние два контакта ибо мы не хотим подключать ничего извне к drain левого NMOS транзистора, который по совместительству является source-ом правого NMOS.

licon_done.png

Сделаем металлический слой li1. Включаем отображение li1. Заглянем в документацию и поймём, каким размером должен быть li1 по правилам DRC.

li.5.png


Здесь мы найдём правила касательно минимального li1 от li1 расстояния, и минимальной ширины LI1.

li.1.png


li.3.png


Я удалил весь LI1, кроме верхнего и нижнего Box-а, которые я удлинил так, чтобы он выступал из диффузии на 0.34. Затем я заново нарисовал остальные LI1:

li1_done.png
Затем я удлинил OUTLINE на 0.05 + 0.34 так, чтобы он включал нарисованный LI1.

outline1.png

Повторим те же действия для слоёв nwell.drawing, psdm.drawin, nsdm.drawing, areaid.standardc. А ещё я поменял слой text.drawing, поменяв text слева снизу из inv_1 в my_nand:

before_npc_met_li1_label_changes.PNG

Затем я включил отображение NPC.drawing и поменял паттерн на что-то видное. И пошёл читать, что это такое. В документации видим:

licon15.png


Так что удлиняем его на 0.34+0.05. Затем я взял Ruler и измерил насколько licon1 окружён npc. Упс 0.08 мкм:

npc_1.png

Давайте это исправим. Я переместил горку правого полисликона на 0.02 мкм вниз. Затем я скопировал правый вертикальный Box полисиликона и переместил его, используя Move на 0.42 влево. Потом я удалил старый полигон полисиликона.

npc_2.PNG

После чего я скопировал горку правого полисиликона и поместил его под licon-ом левого полисиликона. Затем я удалил старый полигон.

npc_3.PNG

Теперь к слою металла. Включаем отображение met1.drawing, met1.label, met1.pin и также удлиняем металл VPWR/VGND power rail. Для этого двойным нажатием по met1 открываем меню редактирования Path и удлиняем его на 0.05+0.34 мкм. Меняем значение 1.38 на 1.77. Должно получиться вот так.

met1_vgnd.png


Это нужно, чтобы когда инструмент Place and route поместит ячейки рядом с друг другом, эти ячейки автоматическим образом поместились на уже нарисованные power rail-и.

Логичный вопрос: почему бы не использовать LI1 для линий питания?
Ответ прост: LI1 тонкий слой металла. На короткие расстояния, сопротивление LI1 можно игнорировать. Для бОльших расстояний LI1 не годится для подачи питания ибо имеет значительное сопротивление.
Решение: Используйте met1 для подачи питания, поскольку met1 имеет в 4 раза меньше сопротивления чем li1.

Теперь повторяем это же действие для VPWR.

met1_vpwr.png

▍met1.pin/met1.label и другие .pin/.label


Теперь остановимся и поймём, что такое met1.pin и met1.label. Слои .pin показывают, где находится точка соединения, а .label содержит текст с именем этого .pin-а. Давайте скроем все наши слои и взглянем на met1.pin и met1.label. Если мы не поставим текст с названием пина в слое .label, то инструменты place and route не будут знать, какие пины данного компонента соответствуют одноимённым названиям пинов в SPICE netlist.

pin_label_1.png


На данной картинке плохо видно, но в слое met1.label содержится элемент text с текстом VGND и VPWR. Вот они вблизи.

pin_label_2.png


Если пины не будут соответствовать названиям пинов в нашей схеме, то во время LVS netgen пожалуется нам, что имена наших пинов схемы не соответствуют именам в layout.

Также стоит рассмотреть NWELL.pin, NWELL.label, PWELL.label. PWELL как мы уже рассмотрели, это по сути вся микросхема. Части PWELL можно изолировать, а поскольку он является полупроводником и является Bulk-ом транзистора, он должен быть подключен к источнику напряжения. Чтобы Place and route знал куда подключать VPWR/VGND, чтобы подать напряжение на Bulk, нам нужно поставить text в слое PWELL.label и Box в слое PWELL.pin. По аналогии, это нужно проделать и с NWELL.label и NWELL.pin, но в отличие от PWELL — NWELL нужно явно указать, нарисовав Box в NWELL.drawing.

Иногда разработчики Standard Cell Library требуют подать напряжение к Bulk, чтобы уменьшить Vth, подняв производительность, либо повышают Vth, чтобы уменьшить энергопотребление см. Body effect. Поскольку мы скопировали слои из inv_1 ячейки, то у нас уже есть нарисованные NWELL, PWELL слои. Вот посмотрите!

pwell_nwell.PNG


Теперь разберёмся с mcon. Этот слой используется для подключения металлического слоя met1 и слоя li1. Включим отображение этого слоя:

mcon_stage.png


Как видим, MCON используется для подачи VPWR/VGND в слой LI1. MCON должен находиться от другого MCON на 0.19 мкм, а сам MCON должен иметь размер 0.17 на 0.17 мкм. Я не стал добавлять больше MCON.

Включаем LI1.pin:

li1_pin.png


Сначала поменяем цвет на лаймовый, затем переместим li1.pin, туда где будут подключаться наши входы и выходы.

li1_pin_lime.png


Теперь сделаем li1.label. Смотрим на схему и видим, что в схеме к VGND подключён NFET с гейтом, который подключён к входу A. Почему это важно? Если мы подключим вход B к гейту этой NFET, то LVS пожалуется на то, что схема не соответствует нашей layout:

nand_xschem.png


Включаем слой li1.label. И перемещаем текст Y на почти центр li1, который проходит посередине. Перемещаем A на левый li1.

Затем переименовываем оставшийся текст Y в B и перемещаем на правый LI1. Для этого двойным нажатием открываем меню редактирования текста.

Text_edit.png


Сохраняем файл через File → Save all и НЕ закрываем Klayout. Он нам понадобится в следующей части.

Об авторе
Меня зовут Арман и я окончил институт Synopsys по профилю VLSI разработки микросхем. В основном я занимаюсь разработкой цифровых компонентов для микросхем и IP для ПЛИС. В прошлом я был программистом, писал бэкенд на Node.js и разрабатывал под микроконтроллеры, но решил пересесть на что-то сложнее, попробовать себя, так сказать.

Я открыт к найму, поэтому, если вас интересует найм разработчика цифровых микросхем с тремя годами опыта и очень интересными проектами (Радиомодемы, преобразователи интерфейсов, процессоры и очень многое), напишите мне в личку.

Как разработать микросхему, от идеи до результата. Ссылки на все статьи։


kghq9za934md5ceo14bxovinlgy.jpeg

© Habrahabr.ru