В этой части мы:
- Будем рисовать схему, используя XSCHEM
- Произведём симуляцию нашей схемы, используя NGSPICE
- Поймём цикл производства микросхемы
- Нарисуем 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, либо у вас не установлен 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
:Затем я создал
IOPIN
с названиями VPWR
, VGND
, иIPIN
с названием A
и B
. Эти типы используются, чтобы сказать XSCHEM, чтобы он создал пины для этой схемы с соответствующим типом и названием.Также я поменял параметр W nfet транзисторов на 0.65мкм. А W транзисторов PFET я поменял на 1:
Затем я использовал Shift + W и W, чтобы подключить транзисторы. Чтобы выбрать объекты зажмите левый клик и выберите регион внутри, которого будут выбраны все объекты.
Используйте M, чтобы двигать выбранные объекты. Нажмите U для отмены последнего действия:
Давайте поймём, как выглядит 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
анализа инвертора.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 нашего проекта.И 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 лет.
После симуляции в терминале должна быть следующая консоль։
И следующее окно:
Really cool!
Сделаем plot по отдельности. Введите в консоль NGSPICE:
plot v(output_net)
plot v(input0_net)
plot v(input1_net)
Должно получиться так:
Чтобы выйти из 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:
В левой панели нужно найти ячейку
sky130_fd_sc_hd_inv_1
. Затем нажать правую кнопку мыши и выбрать Save Selected Cells As
, и сохранить его, как my_nand.gds
в папке gds нашего проекта. И в открывшемся окне нажмите ОК.Затем откроем этот файл. Выйдите из 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
Должно открыться следующее окно.
Причина, почему мы копируем существующий элемент в том, что нам нужен слой OUTLINE, а точнее её высота. Без неё наша ячейка не поместится внутри линий питания библиотеки sky130_fd_sc_hd, ибо инструмент Place and route не будет знать, как именно поставить эту ячейку относительно линий питания (Power Rails).
Ещё стоит сказать, про то, что эта библиотека использует транзисторы с повышенным уровнем Vth для уменьшения энергопотребления. Для этого над всеми PFET транзисторами проведён слой hvtp. Мы удалим его, ибо наша схема построена на обычных транзисторах.
Для этого выберем этот слой, кликнув несколько раз, пока надпись внизу не укажет полигон, который находится на слое HVTP. Затем нажмите Delete:
В правой верхней панели HVTP должно стать серым. Это означает, что данный слой не содержит полигонов.
Скроем слои, которые не содержат полигонов. Нажмите правой кнопкой на любой слой и выберете Hide Empty Layers.
Должно получиться вот так:
Красота! А теперь поменяем стиль отрисовки некоторых слоёв. Для этого поставим галочки в панели Layer Toolbox.
Для этого в верхней панели выбираем слой, а в нижней можем менять цвет и паттерн конкретного слоя.
- Poly -> Первый паттерн
- Licon1 -> Purple, 4ая линия, 3ий паттерн
- Diff -> Orange, whole pattern (первый)
- Li1 -> Orange, netted pattern (последний)
Должно выйти вот так:
Чтобы спрятать слой, выберете слой и нажмите на него левой кнопкой мыши, должно открыться следующее подменю. В нём вы можете либо спрятать один слой, показать слой, либо спрятать и показать все слои.
Теперь наконец-то, поменяем эту схему на схему NAND. Скроем слои, которые мы не будем пока менять. Оставим только poly, licon и diff. Нажимаем на любой слой и «Hide all». Затем нажимаем на poly, diff, licon и нажимаем на Show. Должно быть так:
Настроим рулетку. Откройте меню
Edit
и нажмите Ruler And Annotation Setup
.Поменяйте рулетку в ортогональный режим и включите
Snap To Grid
.Закройте это окно и нажмите F3. И поменяйте шаг на 0.01.
Теперь продлим diff. Двойной клик по diff откроет меню редактирования полигона. Поменяйте Upper right X: 0.34 + 1.09.
Откуда взялся 1.09? Я добавил длину каждого элемента. Прочитаем правила DRC для нашей технологи вот тут. Нас интересуют следующие правила.
Расстояние licon от поликремния должно быть более чем 0.05мкм:
Расстояние между двумя полигонами должно быть ровно 150нм:
Licon должен быть окружён диффузией минимум на 40нм:
Licon позволяют подключать металлический слой li1 к поликремнию, либо к диффузии. Вот слои в разрезе:
Из документации мы узнаём, что расстояние между licon должно быть 170нм, а сами licon должны быть размером 0.17мкм на 0.17мкм:
Итоговая структура. Видим все наши правила в деле:
Чувствуйте обман? Вроде технология называется 130нм, а поликремний 150нм? Всё просто 130нм можно применять только в специальных компонентах SRAM ячеек.
Теперь нарисуем второй поликремний, который в скором времени станет gate-ом для двух транзисторов. Для этого я создал Box из поликремния и установил координаты. Чтобы понять какие координаты поставить, я просто взял координаты первого поликремния и добавил к ним 0.05мкм + 0.17мкм + 0.05мкм + 0.150мкм = 0.27 + 0.15 мкм по горизонтали.
Затем повторил те же действия для нижней диффузии. Теперь сделаем контакты (licon).
Скопировал три верхние и два нижние licon и переместил их центр так, чтобы между ними было расстояние 0.25мкм от второго licon. 0.25 мкм взято не из воздуха. Поликремний должен быть от левого licon на 50нм правее. Затем, сам поликремний имеет длину 0.150мкм, и в конце концов 50нм от поликремния находится сам licon. В итоге должно быть вот так:
Добавим второе соединение к поликремнию. Из документации мы узнаем, что поликремний должен окружать licon с двух сторон по 80нм, а по всем остальным сторонам хотя бы 50нм.
Для этого создадим Box 0.34мкм на 0.34мкм. Минимум нужен 0.33 на 0.33. Затем скопируем licon1 и поместим его посередине поликремния. Получится как-то так:
Удалим средние нижние два контакта ибо мы не хотим подключать ничего извне к drain левого NMOS транзистора, который по совместительству является source-ом правого NMOS.
Сделаем металлический слой li1. Включаем отображение li1. Заглянем в документацию и поймём, каким размером должен быть li1 по правилам DRC.
Здесь мы найдём правила касательно минимального li1 от li1 расстояния, и минимальной ширины LI1.
Я удалил весь LI1, кроме верхнего и нижнего Box-а, которые я удлинил так, чтобы он выступал из диффузии на 0.34. Затем я заново нарисовал остальные LI1:
Затем я удлинил OUTLINE на 0.05 + 0.34 так, чтобы он включал нарисованный LI1.
Повторим те же действия для слоёв nwell.drawing, psdm.drawin, nsdm.drawing, areaid.standardc. А ещё я поменял слой text.drawing, поменяв text слева снизу из inv_1 в my_nand:
Затем я включил отображение NPC.drawing и поменял паттерн на что-то видное. И пошёл читать, что это такое. В документации видим:
Так что удлиняем его на 0.34+0.05. Затем я взял Ruler и измерил насколько licon1 окружён npc. Упс 0.08мкм:
Давайте это исправим. Я переместил горку правого поликремния на 0.02мкм вниз. Затем я скопировал правый вертикальный Box поликремния и переместил его, используя Move на 0.42 влево. Потом я удалил старый полигон поликремния.
После чего я скопировал горку правого поликремния и поместил его под licon-ом левого поликремния. Затем я удалил старый полигон.
Теперь к слою металла. Включаем отображение met1.drawing, met1.label, met1.pin и также удлиняем металл VPWR/VGND power rail. Для этого двойным нажатием по met1 открываем меню редактирования Path и удлиняем его на 0.05+0.34мкм. Меняем значение 1.38 на 1.77. Должно получиться вот так.
Это нужно, чтобы когда инструмент Place and route поместит ячейки рядом с друг другом, эти ячейки автоматическим образом поместились на уже нарисованные power rail-и.
Логичный вопрос: почему бы не использовать LI1 для линий питания?
Ответ прост: LI1 тонкий слой металла. На короткие расстояния, сопротивление LI1 можно игнорировать. Для бОльших расстояний LI1 не годится для подачи питания ибо имеет значительное сопротивление.
Решение: Используйте met1 для подачи питания, поскольку met1 имеет в 4 раза меньше сопротивления чем li1.
Теперь повторяем это же действие для VPWR.
▍met1.pin/met1.label и другие .pin/.label
Теперь остановимся и поймём, что такое met1.pin и met1.label. Слои .pin показывают, где находится точка соединения, а .label содержит текст с именем этого .pin-а. Давайте скроем все наши слои и взглянем на met1.pin и met1.label. Если мы не поставим текст с названием пина в слое .label, то инструменты place and route не будут знать, какие пины данного компонента соответствуют одноимённым названиям пинов в SPICE netlist.
На данной картинке плохо видно, но в слое met1.label содержится элемент text с текстом VGND и VPWR. Вот они вблизи.
Если пины не будут соответствовать названиям пинов в нашей схеме, то во время 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 слои. Вот посмотрите!
Теперь разберёмся с mcon. Этот слой используется для подключения металлического слоя met1 и слоя li1. Включим отображение этого слоя:
Как видим, MCON используется для подачи VPWR/VGND в слой LI1. MCON должен находиться от другого MCON на 0.19мкм, а сам MCON должен иметь размер 0.17 на 0.17мкм. Я не стал добавлять больше MCON.
Включаем LI1.pin:
Сначала поменяем цвет на лаймовый, затем переместим li1.pin, туда где будут подключаться наши входы и выходы.
Теперь сделаем li1.label. Смотрим на схему и видим, что в схеме к VGND подключён NFET с гейтом, который подключён к входу A. Почему это важно? Если мы подключим вход B к гейту этой NFET, то LVS пожалуется на то, что схема не соответствует нашей layout:
Включаем слой li1.label. И перемещаем текст Y на почти центр li1, который проходит посередине. Перемещаем A на левый li1.
Затем переименовываем оставшийся текст Y в B и перемещаем на правый LI1. Для этого двойным нажатием открываем меню редактирования текста.
Сохраняем файл через File -> Save all и НЕ закрываем Klayout. Он нам понадобится в следующей части.
Об автореМеня зовут Арман и я окончил институт Synopsys по профилю VLSI разработки микросхем. В основном я занимаюсь разработкой цифровых компонентов для микросхем и IP для ПЛИС. В прошлом я был программистом, писал бэкенд на Node.js и разрабатывал под микроконтроллеры, но решил пересесть на что-то сложнее, попробовать себя, так сказать.
Я открыт к найму, поэтому, если вас интересует найм разработчика цифровых микросхем с тремя годами опыта и очень интересными проектами (Радиомодемы, преобразователи интерфейсов, процессоры и очень многое), напишите мне в личку.
Комментарии (17)
Delsian
09.12.2021 13:01+8"вводятся ионные импланты Арсения"
Арсений сегодня взял отгул, вводите Геннадия!
Может, все-таки мышьяк по-русски?DmitryVS
09.12.2021 21:28+3А ионные импланты типа Вас не смущают? Это ж всё-таки не про лечение зубов статья. "Производится легирование областей n-карманов мышьяком методом ионной имплантации".
Про технологию в целом написано чудовищным языком. К сожалению, это просто надо переписывать.
amartology
10.12.2021 12:28+1Про технологию в целом написано чудовищным языком
Про технологию написано английским языком и дословно переведено на русский без знания профильных терминов. Ставлю на то, что дело в англоязычном образовании автора статьи, я такой русский технический язык неоднократно видел у эмигрантов.DmitryVS
10.12.2021 14:53Казалось бы да, но нет. То, что написано в части "разбираемся в слоях" имеет мало общего с релевантной английской терминологией. Как минимум, я не вижу адекватной кальки для "покрыть N полупроводником", "вставляем диффузии типа P и типа N", "где диффузия (diff) соприкасается с PSDM", "вставляется слой поликремния", "поликремний испаряется", "микрочастицы (Что это вообще? Так тип дефектов называют обычно.) вставляются в области". Так можно написать только, если не знать и русскую, и английскую терминологию одновременно. Ну или иметь только практику "рисования", где логично "покрывать", "вставлять" и "соприкасать" полигоны, но никак не понимать сути происходящего с пластиной, и что из себя представляют физические слои представленные слоями дизайна, т.к. каша в маршруте начинается практически с самой первой литографии.
Тут, конечно, есть и вина skywater, т.к. могли бы маршрут свой описать хотя бы схематично. Я уже не говорю о явной провокации с иллюстрацией "Process Stack Diagram", т.к. это ничего общего с STI не имеет, более того, там результат принципиально другого маршрута FEOL изображён, и эта структура ну никак не может образоваться при использовании STI (см. различие по высоте затворного поликремния и на FOX).
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 можно прилететь на дополнительные фотошаблоны и маски, хотя программы физической верификации скорее всего это поймают.
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 он всё-таки не указан, а на структуре приборов есть :/ Что-то ребята темнят.
VertiBird
09.12.2021 14:50+1Отличная статья! Какая же чудовищная пропасть между коммерческими и открытыми САПР, наверное так же выглядело проектирование микросхем в 90-х на каком-нибудь NeXTcube.
Armleo Автор
09.12.2021 15:17"Какая же чудовищная пропасть между коммерческими и открытыми САПР"
Ну незнаю, не такая и далёкая. Да есть фичи, который отсутвуют, но без них можно жить. А если очень надо, то допилить всегда достаточно легко.
amartology
09.12.2021 15:23В девяностых уже был нормальный cadence virtuoso на сановских воркстейшенах.
mikki33_2000
09.12.2021 18:01В девяностых уже был нормальный cadence virtuoso
Только с 95-го. А до этого нетлист писали руками, а лейаут рисовали в Edge/
justPersonage
09.12.2021 14:53+3В прошлом я был программистом, писал бэкенд на Node.js и разрабатывал под микроконтроллеры, но решил пересесть на что-то сложнее, попробовать себя, так сказать.
Сколько по времени это у вас заняло? Переход Node.js -> Разработчик ПЛИС
А какие языки программирования(помимо другого софта) вы используете (иногда я видел в вакансиях Python). Ну и еще вопрос, иногда требуется владение математическим аппаратом — Что под этим подразумевается(то что математика это понятно)))) Спасибо.Armleo Автор
09.12.2021 15:22+2Node.js -> Разработчик ПЛИС занял несколько недель. Единственное, что мне было сложно это понять, что в Flip Flop-ах записанные данные появляются только в следующем такте. Остальное было просто и приятно. Особенно в этом помогли книги и статьи по тематике.
А какие языки программирования(помимо другого софта) вы используете (иногда я видел в вакансиях Python).
В основном Tcl/Tk, изредка Python. В ПЛИС и мире разработки микросхем всё в основном на SystemVerilog/Verilog.
Ну и еще вопрос, иногда требуется владение математическим аппаратом — Что под этим подразумевается
Ну булева логика. Плюс понимание многих принципов очень помогает понять, что происходит под капотом. Например считать расстояние от точки до точки, полигоны, их совмещение и так далее. В основном очень нужно знание микроэлектроники: транзисторов резисторов кондесаторов и тд и тп.
amartology
Называть топологию topology — это типичная ошибка пишущих по-английски русскоязычных людей.
Armleo Автор
Учту на будущее. Сейчас менять будет слишком муторно