Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Диплом.Екимова_v3_2.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
4.48 Mб
Скачать
      1. Построение ячейки транзистора на языке skill.

Краткий маршрут написания кода на языке SKILL, для элементарных ячеек:

  1. Определение названия библиотеки, ячейки и ее представления.

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

  3. Перевод этих параметров в формат, с которым сможет работать компилятор.

  4. Анализ используемых слоев.

  5. Описание необходимых правил проектирования для этих слоев.

  6. Разработка алгоритма создания ячейки, используя операторы.

  7. Вычисление внутренних параметром, координат расположения фигур, следую выбранному алгоритму.

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

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

Для создания топологии ячеек используется функция pcDefinePCell(). Все тело кода заключено непосредственно в эту функцию. Компилятор заканчивает построение ячейки после того, как встретит скобку, завершающую функцию. Все, что написано за ее пределами будет выполнено как отдельные операции.

Далее представлен краткий отчет создания кода, соответствуя представленному маршруту.

pcDefinePCell()

Список, определяющий библиотеку, в которой будет создана ячейка (Lib2013), ее название (pmos), а также ее вид (layout):

list(ddGetObj("Lib2013") "pmos " "layout")

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

((w string "280n") - ширина транзистора

(l string "180n") - длина транзистора

(Nfing string "1") - количество пальцев

(x_coor string "0") - координаты местоположения ячейки по оси Х

(y_coor string "0") - координаты местоположения ячейки по оси Y

))

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

Let() - функция, в которой указываются внутренние параметры кода .

После завершения компиляции кода, значения параметров, которые были прописаны в данной функции, станут недоступны. Это очень полезно. Так как часто разработчик за день запускает не одну свою программу. И если в разных проектах окажутся одинаковые названия параметров, может произойти ошибка. Т.е. компилятор может в качестве значения параметра выполняемого кода взять значение такого же параметра из ранее выполненной программы. Но в этом есть и недостатки, так как нельзя будет проверить промежуточные значения параметров, что является важным на этапе отладки кода. Поэтому при разработке программы следует помнить об этих свойствах данной функции.

Все значения начальных параметров задаются как строки. Для того, чтобы ими можно было пользоваться при вычислении внутренних параметров, их необходимо перевести в числовой вид. Для этого применяется функция evalstring().Функция читает и вычисляет выражение, хранящееся в строке. С помощью этой функции мы переводим все необходимые начальные параметры в числовой вид:

width = evalstring( «280n» )*1e6 - результатом данного действия будет width = 0.28 мкм.

length = evalstring(«180n»)*1e6 - результатом данного действия будет length = 0.18 мкм.

Необходимо учесть, что все элементы должны попадать в сетку. Для нашей технологии стандартная сетка «lambda» = 0.02 мкм. Поэтому мы осуществляем перевод всех начальных параметров в микрометры, так как это стандартная размерность сетки.

Для построения ячеек необходимо знать, из каких слоев они будут состоять.

Список слоев, используемых для построения нашего p-канального транзистора, исходя из требований выбранной структуры, и их роль при проектировании топологии:

«poly» - слой поликремния, который является затвором транзистора;

«pplus» - слой кремния, сильно легированного носителями p-типа проводимости;

«pldd» - слой, обозначающий мелкие слабо легированные области p-типа;

«contact» - слой контакта;

«metal- слой металла;

«active» - слой, отвечающий за активную (рабочую) часть транзистора;

«nwell» - карман n-типа проводимости.

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

Список нескольких параметров, отвечающих за разного типа технологические нормы (типы были рассмотрены выше):

drmPolyExtActive = 0.20 ; определяет минимальное расстояние, на которое слой «Poly» должен выступать за слой «Active» (Правило 13-3).

drmMetal1MinWidth = 0.32 ; определяет минимально-допустимую ширину слоя «Metal1» (Правило 23-1).

drmPplusSpace = 0.48 ; определяет минимально-допустимое расстояние между одинаковыми слоями «Pplus» (Правило 17-2).

drmMetal1EncCont = 0.04 ; определяет минимальное расстояние, на которое слой «Metal1» должен перекрывать слой «Cont» (Правило23-3).

Для написания алгоритма создания транзистора проанализируем, от каких условий будет зависеть конфигурация топологии. Во-первых, от необходимости использования стока или истока (это условие затрагивает фиктивные транзисторы, в которых сток/исток могут быть не подключены); во-вторых, от того, какой из терминалов транзистора сток/исток будет идти первым. От этого будут зависеть размеры и координаты слоев, количество и начальные координаты стоковых и истоковых областей.

На рисунке 2.8 представлен алгоритм разрабатываемого нами транзистора.

Рис.2.8. Алгоритм создания транзистора.

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

Для этого мы пользуемся операторами if, when, for. Используем циклы и конструкции вида:

if ( [условие] then [действие]

else [действие]

)

for ( i 1 5

[действие, зависящее от значения переменной цикла ( i )]

)

when ( [условие]

[действие, которое производится, когда выполняется условие]

)

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

if( sd == "Source" then - условие: если первым идет исток

numbSources = floor(Nfing /2) + 1 - высчитываем количество истоков

numbDrains = ceiling(Nfing /2) - высчитываем количество истоков

originS_X = width - 2*drmMetal1Space - высчитываем координаты первого истока

originD_X = length - 2*drmMetal1EncCont - высчитываем координаты первого стока

)

Для построения фигур используются функции rodCreateRect() и rodCreatePath(). В качестве аргументов используются параметры и координаты, которые были высчитаны ранее.

figure = rodCreateRect(

?layer list("poly" "drawing") - описание слоя

?width Width - описание ширины

?length Length - описание длины

?origin ( x1 : y1 ) - описание координат расположения слоя

Описание электрических терминалов:

?termName "G" - определение названия терминала

?termIOType "inputOutput" - описание назначения

?pin t - подтверждение использования пина

?pinAccessDir list("top" "bottom" "left" "right") - расположение пина относительно центральной точки основного металла

)))

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

С помощью данной функции создаются терминалы транзистора: G (затвор), S (исток), D (сток), B (подложка).

Ниже приведены функции, которые были использованы в коде, и их назначение.

atof() – переводит строку в число с плавающей точкой.

evalstring() – читает и вычисляет выражение, хранящееся в строке.

floor() – возвращает наибольшее целое число, не больше, чем данное.

ceiling() – возвращает наименьшее целое число, не меньше, чем данное.

oddp() – проверяет является ли число нечетным. В результате выполнения данной функции, будет выведено либо nil (если число четное), либо t (если число нечетное).

evenp() – проверяет является ли число четным. В результате выполнения данной функции, будет выведено либо nil (если число нечетное), либо t (если число четное).

sprintf() – присваивает результат введенной строки переменной, которая задана в качестве первого аргумента.

round() – переводит число с плавающей точкой в ближайшее целое.

Прокомпилировав код, мы получили ячейку транзистора. Проверка правил проектирования (DRC-проверка), не выявила ошибок. Спроектированная нами топологическая конструкция полностью соответствует поставленной задаче (Рис.2.9).

Рисунок 2.9. Ячейка транзистора, написанная на языке SKILL.

Таким же способом были созданы n-канальный МОП транзистор, поликремневый конденсатор (Рис.2.10.) и несалицидированный n+ поликремневый резистор (Рис.2.11.). Для проектирования были выбраны данные ячейки как наиболее часто употребляемые.

В качестве изменяемых параметров для конденсатора были выбраны ширина и длина. Для построении использовались слои: polyfg, hvwell, poly, nplus, matrix, mcapa, metal1, contac.

Рисунок 2.10. Ячейка конденсатора, написанная на языке SKILL.

В качестве изменяемых параметров для резистора были выбраны ширина и длина. Для построении использовались слои: poly2, siprot, poly, nplus, metal1, contac.

Рисунок 2. 11. Ячейка резистора, написанная на языке SKILL.

Рекомендации для написания кода.

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

Для удобства редактирования кода рекомендуем вставлять комментарии к выполняемым действиям и задавать понятные, соответствующие назначению, параметры. Это поможет быстро вспомнить код, если потребуется к нему вернуться через какое-то время.

Чтобы не загромождать код, рекомендуем избегать большого количества внутренних параметров. Для этого необходимо определить основные величины, с помощью которых можно будет выразить все остальные. Это также позволит быстрее сориентироваться в коде и при необходимости его изменить.

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