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



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

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

  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:


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


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

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


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


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

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


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


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

laby.png

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

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


Затем я использовал 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.



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

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


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, которую мы должны нарисовать. Рассмотрим процесс производства микросхемы.

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


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


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


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


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

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


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



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


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


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



▍Разработка 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

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


Теперь наконец-то, поменяем эту схему на схему 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 и разрабатывал под микроконтроллеры, но решил пересесть на что-то сложнее, попробовать себя, так сказать.

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

Комментарии (17)


  1. amartology
    09.12.2021 12:32
    +4

    PS: Я решил не переводить layout ибо не нашёл хорошего слова.
    По-русски layout называется «топология». Топология по-английски не называется «topology», а то, что по-английски называется topology, по-русски — «блок-схема» или " принципиальная схема".
    Называть топологию topology — это типичная ошибка пишущих по-английски русскоязычных людей.


    1. Armleo Автор
      09.12.2021 13:27
      +1

      Учту на будущее. Сейчас менять будет слишком муторно


  1. Delsian
    09.12.2021 13:01
    +8

    "вводятся ионные импланты Арсения"
    Арсений сегодня взял отгул, вводите Геннадия!


    Может, все-таки мышьяк по-русски?


    1. Armleo Автор
      09.12.2021 13:16

      Исправил


    1. DmitryVS
      09.12.2021 21:28
      +3

      А ионные импланты типа Вас не смущают? Это ж всё-таки не про лечение зубов статья. "Производится легирование областей n-карманов мышьяком методом ионной имплантации".

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


      1. amartology
        10.12.2021 12:28
        +1

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


        1. DmitryVS
          10.12.2021 14:53

          Казалось бы да, но нет. То, что написано в части "разбираемся в слоях" имеет мало общего с релевантной английской терминологией. Как минимум, я не вижу адекватной кальки для "покрыть N полупроводником", "вставляем диффузии типа P и типа N", "где диффузия (diff) соприкасается с PSDM", "вставляется слой поликремния", "поликремний испаряется", "микрочастицы (Что это вообще? Так тип дефектов называют обычно.) вставляются в области". Так можно написать только, если не знать и русскую, и английскую терминологию одновременно. Ну или иметь только практику "рисования", где логично "покрывать", "вставлять" и "соприкасать" полигоны, но никак не понимать сути происходящего с пластиной, и что из себя представляют физические слои представленные слоями дизайна, т.к. каша в маршруте начинается практически с самой первой литографии.

          Тут, конечно, есть и вина skywater, т.к. могли бы маршрут свой описать хотя бы схематично. Я уже не говорю о явной провокации с иллюстрацией "Process Stack Diagram", т.к. это ничего общего с STI не имеет, более того, там результат принципиально другого маршрута FEOL изображён, и эта структура ну никак не может образоваться при использовании STI (см. различие по высоте затворного поликремния и на FOX).


  1. VertiBird
    09.12.2021 13:43
    +3

    Кремниевая подложка изначально легирована до p-типа, в ней уже создается n-карман. Сначала на пластину кладется поликремниевый затвор, потом имплантируются области p+ и n+, называется "техпроцесс с самосовмещением".

    Не знаю как в этой технологии, но бывают отдельные сущности p-карман (p-well) и p-подложка (p-substrate). p-подложка - "пустое" пространство на пластине, где будут формироваться карманы. p-well - часто является опцией, в подложке формируется n-карман, в нем формируется p-карман, такой себе КНИ в объеме. Если перепутать p-well и p-sub можно прилететь на дополнительные фотошаблоны и маски, хотя программы физической верификации скорее всего это поймают.


    1. DmitryVS
      09.12.2021 21:58
      +1

      Я тут до конца не понял, что они делают на самом деле. По картинке "Process Stack Diagram" имеются только n-well и p-sub. Никаких p-карманов нет. Да на ней даже STI нет. Но открываем описание приборов и видим совсем другое дело. Всё как у людей.

      Раз 1.8V PMOS FET:

      Два 1.8V NMOS FET:

      Тот "Process Stack Diagram" скорее всего не полный в транзисторной части. Причём слоя p-well может и не быть в дизайне, а карман всё равно сделают :) На этапе преобразования дизайна в масочные слои автоматически его сгенерируют и ФШ закажут. С другой стороны, в перечне масок SKY130 он всё-таки не указан, а на структуре приборов есть :/ Что-то ребята темнят.


  1. VertiBird
    09.12.2021 14:50
    +1

    Отличная статья! Какая же чудовищная пропасть между коммерческими и открытыми САПР, наверное так же выглядело проектирование микросхем в 90-х на каком-нибудь NeXTcube.


    1. Armleo Автор
      09.12.2021 15:17

      "Какая же чудовищная пропасть между коммерческими и открытыми САПР"

      Ну незнаю, не такая и далёкая. Да есть фичи, который отсутвуют, но без них можно жить. А если очень надо, то допилить всегда достаточно легко.


    1. amartology
      09.12.2021 15:23

      В девяностых уже был нормальный cadence virtuoso на сановских воркстейшенах.


      1. mikki33_2000
        09.12.2021 18:01

        В девяностых уже был нормальный cadence virtuoso

        Только с 95-го. А до этого нетлист писали руками, а лейаут рисовали в Edge/


    1. VT100
      09.12.2021 21:22
      +2

      "Рубилитчицы" Intel, 1970.
      image


  1. justPersonage
    09.12.2021 14:53
    +3

    В прошлом я был программистом, писал бэкенд на Node.js и разрабатывал под микроконтроллеры, но решил пересесть на что-то сложнее, попробовать себя, так сказать.

    Сколько по времени это у вас заняло? Переход Node.js -> Разработчик ПЛИС
    А какие языки программирования(помимо другого софта) вы используете (иногда я видел в вакансиях Python). Ну и еще вопрос, иногда требуется владение математическим аппаратом — Что под этим подразумевается(то что математика это понятно)))) Спасибо.


    1. Armleo Автор
      09.12.2021 15:22
      +2

      Node.js ->  Разработчик ПЛИС занял несколько недель. Единственное, что мне было сложно это понять, что в Flip Flop-ах записанные данные появляются только в следующем такте. Остальное было просто и приятно. Особенно в этом помогли книги и статьи по тематике.

      А какие языки программирования(помимо другого софта) вы используете (иногда я видел в вакансиях Python).

      В основном Tcl/Tk, изредка Python. В ПЛИС и мире разработки микросхем всё в основном на SystemVerilog/Verilog.

      Ну и еще вопрос, иногда требуется владение математическим аппаратом — Что под этим подразумевается

      Ну булева логика. Плюс понимание многих принципов очень помогает понять, что происходит под капотом. Например считать расстояние от точки до точки, полигоны, их совмещение и так далее. В основном очень нужно знание микроэлектроники: транзисторов резисторов кондесаторов и тд и тп.


      1. justPersonage
        09.12.2021 15:46

        Очень интересно)) Спасибо.