Знакомство с пакетом DesignLab 8 (PSpice). Урок 6. Как проектировать иерархические схемы

Знакомство

с пакетом DesignLаb 8

Урок 6. Как проектировать иерархические схемы Материальный мир склонен к иерархии. Это значит, что любой объект можно представить как совокупность взаимодействующих частей, которые, в свою очередь, состоят из более мелких деталей. Например, сложные объекты вычислительной техники состоят из устройств, те — из узлов, узлы — из элементов, элементы — из компонентов (радиодеталей). В связи с усложнением создаваемых объектов иерархическое проектирование становится самым мощным и, вероятно, единственным методологическим инструментом процесса проектирования.

Александр Шалагинов, к. т. н.

shalag@vt.cs.nstu.ru

Человек не в состоянии воспринимать слишком большой объем данных. Если деталей очень много, он может легко «утонуть» в них, и успешное завершение проекта станет проблематичным. При иерархическом проектировании в поле зрения необходимо держать лишь один фрагмент объекта. Остальные фрагменты представлены в виде «черных ящиков» и присутствуют в проекте только для того, чтобы имитировать «окружение», то есть взаимодействие проектируемого фрагмента с другими частями объекта. Благодаря иерархическому проектированию удается ограничить текущую сложность проекта на приемлемом уровне.

Процесс иерархического проектирования может развиваться в двух противоположных направлениях — «сверхувниз» (нисходящее проектирование) и «снизувверх» (восходящее проектирование).

САПР DesignLab 8 поддерживает обе стратегии иерархического проектирования, предоставляя в распоряжение пользователя такие инструменты, как блоки, иерархические символы и макромодели.

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

Блоки

Для функционального описания объекта в пакете DesignLab 8 рекомендуется использовать так называемые DSL-блоки (от англ. Design Synthesis Language — язык синтеза проекта).

Предположим, целью нашего проекта является разработка мультиплексора на два входа. Информация с одного из них D0 или D1 передается на выход Q в зависимости от состояния селекторного входа A. Работа устройства может быть описана функцией:

Q=(not A)xD0+Ax*D1.

Построим DSL-блок, реализующий данную функцию. С этой целью запустим графический редактор Schematics и активизируем команду Block в меню Draw (в дальнейшем Draw > Block). На экране появится прямоугольный контур будущего блока, который можно поместить в любое место чертежа. Нажав левую кнопку мыши, мы зафиксируем его положение на схеме. По умолчанию блок получит имя HB1. Можно продолжить ввод блоков, но нам достаточно одного. Поэтому нажмем клавишу Esc или правую кнопку мыши. В углах блока появятся небольшие квадратики — узелки, которые можно буксировать мышью, изменяя первоначальные размеры блока.

Установим желаемые размеры и активизируем команду Draw > Wire — рисовать проводники. Подведем к левой стороне блока три входных проводника D0, D1 и A, а к правой — один выходной проводник Q. В точках, где проводники соприкасаются с блоком, редактор создаст интерфейсные контакты и присвоит им имена по шаблону P1.. .P4. Двойным щелчком на имени контакта вызовем диалоговую панель Change Pin и переименуем их в D0, D1, A и Q (рис. 6.1).

Мы создали внешнее описание блока и теперь запрограммируем его функцию. Выделим блок и активизируем команду Navigate > Push, чтобы понизить иерархию проекта на один уровень. Редактору придется закрыть текущий уровень иерархии, по-

этому он запросит имя файла, в котором надо сохранить проектируемую схему мультиплексора.

Введем имя test1_mux2, к которому редактор добавит расширение SCH. После этого откроется диалоговая панель Set Up Block, где необходимо указать имя будущего DSL-блока, например HB1_mux2, а в поле Type заменить значение Schematic на DSL (рис. 6.2). Дело в том, что мы собираемся создавать не схему замещения блока, а его функциональное DSL-описание.

Нажав кнопку OK, мы увидим окно текстового редактора Text Editor, встроенного в пакет DesignLab 8. В нем будет размещен автоматически созданный шаблон будущего DSL-описания.

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

Q =/AxD0+AxD1.

В языке DSL логическая операция инверсии кодируется знаком «/».

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

Итак, функциональное описание мультиплексора готово. Теперь в соответствии со стратегией нисходящего проектирования нам предстоит детализировать проект, заменив функциональное описание структурным (схемой замещения блока).

Создадим только что описанным способом новый блок в нашей схеме. Активизируем команду Draw > Block и разместим рядом с уже существующим блоком HB1 еще один. Редактор автоматически присвоит ему имя HB2. Начинкой этого блока должно быть структурное описание мультиплексора. Мы реализуем его в виде функциональной схемы на элементах серии 74AC.

Зададим блоку HB2 такие же размеры, как у первого, и подведем к нему те же входные сигналы от генераторов стимулов DSTM1...DSTM3. Мы уже знаем, что если проводник подведен к левой стороне блока, создаются входные порты, а если к правой — выходные. Заданные умолчанием имена контактов P1...P4 заменим на DO, D1, A и Q. Выходную цепь назовем Q_SCH1 и подключим к ней маркер (рис. 6.4).

Сохраним созданную схему замещения блока HB2 (файл HB2_1_mux2.sch) и вернемся на верхний уровень иерархии (клавиша F3 или команда Navigate > Pop). Чтобы убедиться, что в проделанной работе нет ошибок, выполним контрольное моделирование (рис. 6.6). Сравнивая временные диаграммы выходных сигналов Q_DSL и Q_SCH1, легко заметить, что в отличие от первого блока, второй блок моделирует не только функцию, но и временные задержки компонента.

Мы сделали для блока HB2 одну схему замещения. Однако пакет DesignLab позволяет любому блоку назначить несколько различных схем замещения и выполнять моделирование в поисках наилучшего варианта. Можно даже ассоциировать с одним блоком описания разных видов — функциональное (DSL-описание) и структурное (схему замещения).

Закончив программирование блока, сохраним полученный файл НВ1_тих2^1 и закроем окно текстового редактора. Произойдет возврат на верхний уровень иерархии. Нам осталось верифицировать свой проект. С этой целью подключим к построенному блоку генераторы входных воздействий Б8ТМ1...08ТМ3, присвоим проводникам имена (Б0, Б1, А, Q_DSL) и установим на них маркеры.

Не забудьте подключить к проекту файл внешних воздействий 1е8И_тих2.8ІІ. Кроме того, при тестировании к внешнему выходу блока надо подсоединить какой-нибудь элемент, например инвертор 7-^04, иначе пла-

Рис. 6.4. В схему добавлен блок HB2, для которого будет создана схема замещения

Создадим схему замещения блока HB2. Для этого следует понизить уровень его иерархии (команда Navigate > Push), присвоить имя будущей подсхеме, например HB2_1_mux2, и после того как редактор выполнит эту команду, показав входные и выходные порты, приступить к построению его схемы замещения.

Конечно, если вы выполнили урок 1, то в файле mux2.sch уже есть готовая схема мультиплексора и ее можно просто скопировать. Однако дополнительная тренировка не повредит, и вы можете заодно проверить степень усвоения первого урока — если схема будет готова через З минут, значит, все в порядке.

Разместив элементы 74AC04 (НЕ), 74AC08 (2И) и 74AC32 (2ИЛИ) и соединив их проводниками, следует подключить к внешним входным и выходным цепям соответствующие порты. Для этого требуется выделить подключаемый порт и отбуксировать его к нужному проводнику, контролируя образование электрического соединения (в точке подключения появляется крестик и рядом с ним предупреждающий восклицательный знак). Главное — не перепутать порты местами (рис. 6.З).

Подсоединение к блоку конкретной схемы замещения выполняется командой Edit > Views... Активизировав ее, если был выделен блок HB2, мы увидим диалоговую панель Block HB2 (рис. 6.7).

Рис. 6.7. Подсоединение к блоку HB2 конкретной схемы замещения

Так как с блоком HB2 связана только одна подсхема, то в левом поле View Name мы увидим слово DEFAULT, а в правом — имя файла с расширением SCH, в котором хранится схема замещения этого блока (в примере — это файл HB2_1_mux2.sch). Она подключена к данному блоку по умолчанию.

Мы хотим создать для этого же блока еще одну схему замещения. С этой целью в поле View Name дадим ей имя schema_2, а в поле

Schematic or DSL File Name укажем имя файла, например, HB2_2_mux2.sch, где она будет храниться. Нажмем кнопку Save View, закроем диалоговую панель Block HB2 и дважды щелкнем на блоке HB2. На экране монитора появится новая диалоговая панель Select View со списком подключенных к данному блоку подсхем. Выделим строку schema_2=HB2_2_mux2.sch и нажмем OK. Редактор понизит уровень иерархии и загрузит файл HB2_2_mux2.sch, в котором нам предстоит создать второй вариант реализации мультиплексора. Нарисуем его функциональную схему на элементах 2И-НЕ типа 74AC00 и подключим расположенные здесь же порты. Чтобы отличить созданную схему от предыдущей, цепь на выходе элемента U1 назовем not_A и подключим к ней маркер (впрочем, они отличаются и величинами задержек). Сохраним новую схему замещения (рис. 6.В) и вернемся на верхний уровень иерархии.

Запустим редактор Schematics и скопируем (загрузим) любимую, хотя и изрядно надоевшую нам схему мультиплексора из файла mux2.sch. Сохраним ее в файле test2_mux2.sch.

А теперь попробуем «спрятать» схему мультиплексора (без внешних генераторов DSTM1...DSTM3) в черный ящик (блок). В местах, где контуры будущего блока должны пересекать проводники, поставим маркеры и выполним команду Draw > Block. Первоначальные размеры блока никак не соответствуют «вырезаемой» подсхеме, поэтому для начала захватим блоком только верхний левый маркер (или несколько соседних с ним). Щелкнем левой кнопкой мыши, чтобы зафиксировать блок на схеме, и нажмем клавишу Esc. Зацепим мышью за правый нижний узелок и отбуксируем его так, чтобы внутри блока оказалась вся подсхема. В точках расположения маркеров (там, где проводники входят в блок или выходят из него) редактор автоматически поставит контакты (рис. 6.9). Заданные по умолчанию имена P1...P4 лучше сразу изменить, назвав их именами соответствующих цепей DO, D1, A и Q.

Если теперь дважды щелкнуть на блоке HB2, то откроется панель Select View и для редактирования на выбор будет предложено два варианта реализации мультиплексора.

Чтобы указать, какую из двух схем следует использовать в текущем сеансе моделирования, необходимо выполнить команду Edit > Views..., выбрать строку с нужной схемой и задать ей атрибут DEFAULT. Понятно, что ключевое слово DEFAULT может встречаться только в одной строке списка схем замещения данного блока.

При проектировании «снизувверх» сначала создаются принципиальные схемы отдельных элементов или узлов, которые на более высоком уровне иерархии объединяются в устройства. По мере проработки проекта принципиальная схема разрастается и может достичь невероятных размеров. Возникает уже известная нам проблема чрезмерной сложности. Ее можно избежать с помощью тех же блоков. Для этого нужно выделить в проектируемой схеме некоторую ее часть (подсхему) и «спрятать» в черный ящик, который в пакете DesignLab В называется блоком. В блок рекомендуется упаковывать регулярные, часто повторяющиеся, функционально законченные фрагменты схемы.

Блок сохраняет все внешние связи с остальной схемой и при моделировании «незаметно» для пользователя раскрывается до нижнего уровня иерархии. Однако для проектировщика укрупнение схемы облегчает ее восприятие и снимает психологический фактор сложности. С точки зрения нагрузки на ЭВМ такой прием никаких преимуществ не дает.

Рис. 6.9. Выделенная схема должна быть «спрятана» в блок HB1

Развернем, используя горячие клавиши Ctrl+R, маркеры таким образом, чтобы они находились за пределами блока, и выделим курсором мыши «вырезаемую» подсхему, не выходя за габариты блока. Командой Edit > Cut удалим ее из блока. Размеры пустого блока излишне велики, их следует уменьшить до желаемой величины. Закончив с внешним представлением блока (рис. 6.10), позаботимся о его «начинке».

Рис.6.10. Схема мультиплексора «спрятана» в блок HB1

Выделим блок и активизируем команду Navigate > Push. Появится диалоговая панель Set Up Block. В поле Filename, расположенном на этой панели, введем имя подсхемы, например HB1_mux2, и нажмем OK. Редактор по-

низит уровень иерархии, превратив блок в подсхему. Впрочем, подсхемы еще нет — на экране видны лишь интерфейсные контакты (порты) D0, D1, A и Q. Понизить иерархию можно и другими приемами, например, дважды щелкнув на нужном блоке или нажав клавишу F2 (клавиша F3 или команда Navigate > Pop выполняет обратную операцию — повышает иерархию на один уровень).

Командой Edit > Paste вставим ранее вырезанную подсхему и подключим к ее входам и выходу соответствующие порты. Для этого требуется выделить подключаемый порт и отбуксировать его к нужному проводнику.

Сохраним созданную подсхему (файл HB1_mux2.sch) и вернемся на верхний уровень иерархии. Выполним контрольное моделирование, чтобы убедиться, что в проделанной работе нет ошибок.

Моделирование схем на низком уровне (в наших примерах — на вентильном) требует больших затрат времени и ресурсов ЭВМ, а для сложных проектов становится вообще невозможным. Выручает высокоуровневое моделирование, при котором уже разработанная принципиальная схема какого-либо фрагмента (структурная модель) заменяется черным ящиком, имеющим функциональное описание (поведенческая модель). Таким образом, выполняется переход на одну ступеньку вверх по иерархии проекта (восходящее проектирование). Однако, в отличие от проектирования «свер-хувниз», когда о разрабатываемом объекте (или его фрагменте) мы ничего не знали, кроме выполняемой функции, теперь, при наличии его принципиальной схемы, мы знаем, по крайней мере, его временные параметры. Поэтому высокоуровневое моделирование желательно выполнять с учетом временных задержек и контролем других временных соотношений в схеме (времена предустановки и удержания, минимальные длительности сигналов, соблюдение правил синхронизации и т. п.). Язык описания DSL, используемый в ходе нисходящего проектирования, таких возможностей не обеспечивал. Однако в пакете DesignLab 8 для этих целей существуют другие инструментальные средства. Они используются при построении поведенческих макромоделей сложных цифровых компонентов и будут рассмотрены позднее. Укажем лишь, что первое из них — LOGICEXP — применяется для описания функции объекта, второе — PINDLY — для задания задержек распространения сигналов, а третье — CONSTRAINT — контролирует временные соотношения в схеме.

Иерархические символы

Рассмотренные блоки имеют один весьма серьезный недостаток — их графическое изображение неудобно редактировать. Конечно, можно изменить размеры и число контактов блока, но на этом наши возможности заканчиваются. Вы можете нанести на блок дополнительные графические примитивы и текст, однако полученный рисунок не будет восприниматься как единое целое. Кроме того, блок нельзя поместить в библиотеку и в дальнейшем использовать его как готовый объект.

Чтобы такая возможность появилась, необходимо преобразовать блок в иерархический символ. Это делается с помощью команды Edit > Convert Block.

Загрузим в графический редактор файл test1_mux2.sch и сохраним его под именем test3_mux2.sch. Выделим конвертируемый блок (например, HB1) и активизируем названную команду. Мы увидим диалоговую панель, которая запрашивает имя будущего символа. Введем его название, например HS1_mux2, и нажмем кнопку OK. Последует запрос, в какую библиотеку поместить новый символ. Можно выбрать уже существующую библиотеку, например my_lib.slb, или назвать новую.

Теперь полученный иерархический символ можно редактировать, как и любые другие простые символы. Выделим созданный символ и переведем редактор в режим Symbol Editor (команда Edit > Symbol). Пронумеруем подряд его контакты и дополним графику так, чтобы она удовлетворяла требованиям ГОСТ.

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

Создавая иерархический символ мультиплексора, мы действовали в следующей последовательности: блок-схема замещения-иерархический символ, то есть по принципу «сверхувниз». Классический способ построения иерархических символов начинается «снизу» — с его схемы замещения. Это самостоятельная процедура, и мы познакомимся с нею на другом примере.

Предположим, требуется создать иерархический символ демультиплексора на два входа. Откроем новый файл и разместим в окне редактора требуемые компоненты: 7408 (2И) и 74LS04 (НЕ). Соединим их проводниками в соответствии со структурой демультиплексора и подведем к внешним входным и выходным цепям интерфейсные порты IF________IN и

IF_OUT, которые находятся в библиотеке port.slb. Входным портам присвоим имена D и A, а выходным — Q0 и Q1. Полученную схему замещения (рис. 6.11) сохраним в файле dmux2.sch.

фическое изображение. При этом предварительно запрашивается имя символа (назовем его HS_dmux2) и библиотека, где будет храниться его внешнее описание.

Изображение иерархического символа заносится в названную библиотеку (например, в личную библиотеку ту_ііЬ.8ІЬ), а схема замещения символа оказывается в файле с расширением SCH. В нашем примере — это файл dmux2.sch.

Автоматически созданное изображение символа, как правило, требует коррекции. Вы легко убедитесь в этом, если загрузите его в графический редактор (рис. 6.12, справа). Но в DesignLab она выполняется так же просто, как и для обычного символа (рис. 6.12, слева).

Рис. 6.12. Автоматически созданное изображение символа DMUX2

Рис. 6.11. Схема замещения демультиплексора DMUX2

После этого по команде File > Symbolize автоматически создается внешнее описание иерархического символа — его условное гра-

готовая схема замещения этого компонента, и выполним команду Tools > Create Subcircuit.

В статусной строке редактор сообщит, что он создал список цепей макромодели (Netlist complete) и поместил его в файл dmux2.sub. Найдем этот файл и посмотрим его содержимое (рис. 6.13).

Рис. 6.13. Макромодель демультиплексора DMUX2, представленная списком элементов

Макромодели

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

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

Рассмотрим первый способ построения макромоделей. Схема замещения компонента создается точно так же, как и для иерархического символа (рис. 6.11). Затем выполняется команда Tools > Create Subcircuit, по которой осуществляется преобразование графического описания подсхемы в текстовое. Оно заносится в файл с расширением SUB и впоследствии может быть скопировано в любую библиотеку макромоделей (в файлы с расширением LIB).

Если отсутствует графическое изображение компонента, для которого строится макромодель, то его надо создать обычным образом (урок 5). Затем с помощью атрибута MODEL из созданного символа следует сделать ссылку на соответствующую макромодель.

Построим первым способом макромодель демультиплексора dmux2. Откроем файл dmux2.sch (рис. 6.11), в котором хранится уже

По умолчанию файл должен оказаться в папке Projects. Обратите внимание на структуру макромодели. Она начинается с директивы .SUBCKT и заканчивается директивой .ENDS. Между этими директивами помещен список соединений демультиплексора. Вы без труда найдете элементы, на которых он построен (74LS04 и 74AC08), а также связи между ними.

Итак, внутреннее описание компонента (в виде макромодели) готово. Теперь предстоит нарисовать его внешнее описание — графическое изображение. В принципе оно уже есть, и его можно позаимствовать от иерархического символа HS_dmux2, который находится в библиотеке my_lib.slb. Однако это не совсем простая работа, и мы отложим ее на некоторое время.

Кроме того, дополнительная тренировка никогда не повредит, а заодно вы можете проверить степень усвоения урока З. Считайте, что вы освоили технологию проектирования символов, если на работу у вас уйдет не более 10 минут. Не забудьте, определяя атрибуты, сделать ссылку на ранее созданную макромодель:

MODEL=dmux2

Сохраните нарисованный символ под именем macro_dmux2 в библиотеке my_lib.slb.

Спроектированную макромодель и символ необходимо протестировать. С этой целью создадим новый файл test2_dmux2.sch. Найдем в библиотеке my_lib.slb только что созданный символ macro_dmux2 и подведем к нему сигналы D и A от внешних генераторов стимулов (рис. 6.14).

Рис. 6.14. Тестирование макромодели демультиплексора и проверка правильности созданного символа mаcro_dmux2

Сформируем для них временные диаграммы и сохраним в файле test2_dmux2.stl. Командой Analysis > Library and Include Files...

подключим его к исследуемой схеме и то же самое сделаем с файлом dmux2.sub. Теперь схему можно промоделировать, чтобы убедиться, что мы не наделали ошибок. Если все правильно (рис. 6.1З), то построенную макромодель демультиплексора из файла dmux2.sub следует перенести в библиотеку макромоделей my_lib.lib и отключить ненужный больше файл dmux2.sub.

Если вы все же решили не рисовать новый символ, а скопировать его графическое изображение с уже готового иерархического символа, то возникнет небольшая проблема. Дело в том, что с иерархическим символом ассоциирована одна или несколько схем замещения, которые за ненадобностью нужно отключить. Эта работа выполняется в режиме Symbol Editor командой Edit > Set Schematic... Когда появится диалоговая панель с тем же названием, из нижнего окна удаляют все подключенные к символу схемы замещения. Кроме того, необходимо заменить шаблон атрибута REFDES с HS (для иерархических символов) на DD (для цифровых компонентов).

Высокоуровневое моделирование

Все рассмотренные ранее приемы иерархического проектирования, кроме, пожалуй, DSL-блоков, преследовали одну главную цель — контролировать сложность проекта на приемлемом для человека уровне. Однако и для ЭВМ когда-то наступает предел дозволенной сложности. Ее весьма внушительные ресурсы рано или поздно могут быть исчерпаны. Именно эти причины не позволяют реализовать сверхбольшие проекты. Поэтому в современных САПР должны быть инструменты, позволяющие расширять возможности не только человека, но и ЭВМ.

Одним из таких инструментов является высокоуровневое моделирование, а точнее высокоуровневое логико-временное моделирование. В этих словах заложена основная его идея: не раскрывая структуру объекта, смоделировать его работу, по возможности так же точно, как если бы он моделировался на низком уровне (например, на уровне вентилей или даже компонентов).

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

возможностями. Познакомимся с ними на примере мультиплексора на два входа.

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

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

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

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

Логико-временная модель не имеет списка соединений, а содержит два (LOGICEXP и PINDLY) или даже три (LOGICEXP, PINDLY и CONSTRAINT) примитива. Можно ограничиться и одним примитивом LOGICEXP, но тогда вы не сможете имитировать и проверять временные соотношения.

Примитив LOGICEXP (от слов Logic Expression) описывает логику работы компонента. Он имеет следующий формат:

Uxxx LOGICEXP (<число входов>, <число

выходов>)

+ <питание> <земля>

+ <вхо дной_узел_ 1 >... <вхо дной_узел_m> + <выходной_узел_1>...<выходной_узел_п> + <имя_модели_динамики> < имя_моде-ли_вход/выход>

+ [IO_LEVEL=<уровень_модели_интерфей-са>]

+ [MNTYMXDLY=<выбор_значения_задерж-ки>]

+ LOGIC:

+ <логическое_назначение>

Логическое назначение может включать логические выражения для выходных узлов и промежуточных переменных в следующей форме:

<имя_выходного_узла> = {<логическое выражение^

<промежуточная_переменная> = ^логическое выражение>!

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

Посмотрим, как выглядит этот примитив для мультиплексора MUX2 (рис. 6.17).

Здесь показана наиболее простая макромодель, которая имитирует только функцию мультиплексора:

Q = {~A&D0 I A&D1}.

Отметим, что в описании присутствует динамическая модель D_MUX2, а это означает, что есть принципиальная возможность моделировать задержки распространения сигналов в компоненте. Правда, возможности здесь невелики и ограничены уровнем простых логических элементов (встроенная модель задержки UGATE). Пустые круглые скобки модели UGATE означают нулевые задержки.

Создадим компонент MUX2, поддерживаемый макромоделью, показанной на рис. 6.17. Сначала откроем текстовый редактор, загрузим в него библиотечный файл my_lib.lib и допишем туда текст макромодели mux2_log, приведенный на рис. 6.17.

Затем нарисуем графическое изображение мультиплексора, из него сделаем ссылку на

логического блока разрешения них узлов

Рис. 6.16. Структура функционального описания цифровых устройств на примере мультиплексора на два входа mux2_log

* Функциональная модель мультиплексора MUX2 с пулевыми задержками

.SUBCKT mux2_log DO Dl A Q ; директива начала макромодели

U_MUX2_LOG LOGICEXP (3, l) ; имя примитива должно начинаться с буквы «И»

+ DPWR DGND ; контакты питания и земли

+ DO Dl A ; входы в логический блок ЮвІСЕХР

+ Q ; выход из логического блока ЮвІСЕХР

+ D_MUX2 ; ссылка на модель динамики

+ IO_STD ; ссылка на стандартную модель вход/выход

+ LOGIC: ; логическая секция

+ Q = {~A&D0 I A&Dl} ; логическое выражение для выходного узла Q

.ENDS mux2_log ; директива конца макромодели

*S* ; строка комментария начинается с символа «*»

.MODEL D_MUX2 UGATE () ; модель динамики логического примитива

Рис. 6.17. Функциональная модель мультиплексора без учета задержек

поведенческую модель ших2_^ и сохраним его образ в библиотеке шу_11Ь.81Ь. Протестируем полученную макромодель, чтобы убедиться, что она правильно выполняет свою функцию и имеет нулевые задержки. С этой целью создадим файл 1е81_ших2_^.8сЬ и проведем требуемые модельные эксперименты.

Вновь вернемся к макромодели ших2_^, скопируем ее содержимое и изменим имя на тих2_1о§_Шу. Мы собираемся отразить в названии тот факт, что теперь модель должна имитировать задержки. Добавим в нее примитив РВДОЬУ, который воспроизводит эти задержки (рис. 6.18).

Как видно из рис. 6.18, с добавлением нового примитива пришлось внести изменения и в ранее созданный логический блок LOGIC-EXP. Теперь он имеет не один, а целых четыре выхода. Они используются в качестве входов в блок задержки (рис. 6.16). На выходы D0_INT, D1_INT и A_INT (INT от слова internal — внутренний) осуществляется прямая трансляция входных сигналов D0, D1 и A. Они не претерпевают никаких логических преобразований (Buffering) и будут использованы в блоке задержки PINDLY в качестве внутренних (дополнительных) узлов.

Сигнал Q_INT является выходом из LOGIC-EXP и входом в PINDLY. Для таких сигналов в

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

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

Запаздывание выходного сигнала Q зависит от того, с какого входа поступает конкретное событие (переключение). Путь от входов D0 и D1 включает два вентиля, а от входа A — три, следовательно, от него задержка должна быть больше.

Изменения состояний на входах контролируется функциями:

CHANGED (<узел>, <интервал_времени>) CHANGED_LH (<узел>, <интервал_времени>) CHANGED_HL (<узел>, <интервал_времени>).

Функция CHANGED принимает истинное значение TRUE, если указанный в спецификации узел изменял свое состояние на указанном интервале времени. Функция CHANGED_LH контролирует фронт, а функция CHANGED_HL — спад сигнала в соответствующем узле. Если параметр <интервал времени> задать равным нулю, то будут выявляться переключения в текущий момент модельного времени.

Функции TRN_LH и TRN_HL следят за изменением выходных узлов, для которых вычисляются задержки. Вместо уровней L (низкий уровень) и H (высокий уровень) можно использовать также Z (высокоомный выход) и $ (любой уровень). Эти функции не имеют аргументов и просто фиксируют изменения состояний выходных узлов в текущий момент времени.

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

Оператор DELAY (<min>, <typ>, <max>) определяет соответственно минимальную, типичную (задается по умолчанию) и максимальную задержки. Для спецификации неизвестной величины используется значение «-1».

В нашем примере типичная задержка, связанная с переключением любого из входов D0 или D1, равна 25 нс, а при изменении входа A — 50 нс. Минимальные задержки не специфицированы. Если ни одно условие не будет истинным, то выполняется последний оператор DELAY, не имеющий вообще никакого условия.

Чтобы увидеть воочию потрясающие результаты работы примитива PINDLY, загрузим в редактор Schematics файл test_mux2_log.sch и выделим компонент mux2_log. Переведем редактор в режим редактирования символов и командой Part > Copy... скопируем символ mux2_log, сменив его имя на mux2_log_dly. Активизируем команду Part > Attributes... и изменим значе-

* Функциональная макромодель мультиплексора MUX2 с учетом задержек

.SUBCKT mux2_log_dly DO Dl A Q U_MUX2_LOG_DLY LOGICEXP (3, 4) + DPWRDGND + DO Dl A

+ D0_INT Dl_INT A_INT Q_INT + D_MUX2 IO_STD + LOGIC:

+ D0_INT = {DO}

+ Dl_INT = {Dl}

+ A_INT = {A}

+ Q_INT={~A&D0 I A&Dl}

U_MUX2_DLY PINDLY (l, 0, 3) + DPWR DGND + Q_INT

+

+ D0_INT, Dl_INT, A_INT

+

+ Q +

+ IO_STD + BOOLEAN:

+

; новое имя макромодели мультиплексора ; теперь логический блок имеет четыре выхода

; имена выходных узлов логического блока ; они являются внутренними сигналами модели

; прямая трансляция входных данных ; на выход блока

; определение выходного сигнала без учета задержки начало примитива РШБЬУ

примитив имеет один путь (вход), для которого вычисляется задержка ; примитив имеет три внутренних узла, от которых ; зависит эта задержка ; имя выходного узла примитива PINDLY,

; для которого вычисляется задержка ; стандартная модель вход/выход ; секция определяет промежуточные переменные,

; которые используются для вычисления задержек + ANY_CH_D={CHANGED (D0_INT, 0) I CHANGED (D1_INT, 0)}

+ PINDLY: ;

+ Q = {

+ CASE ; оператор вычисляет конкретную задержку

+ ( ANY_CH_D & (TRN_LH I TRN_HL, DELAY (-1, 25ns, 25ns),

+ CHANGED (A_INT, 0) & (TRN_HL I TRN_LH), DELAY (-1, 50ns, 50ns),

+ DELAY

+ )

+ }

.ENDS mux2_log_dly Рис. 6.18. Поведенческая модель мультиплексора с учетом задержки

ния двух атрибутов: PART = mux2_log_dly и MODEL = mux2_log_dly.

В результате проделанной работы в библиотеке my_lib.slb появится еще один символ мультиплексора, который поддерживается макромоделью mux2_log_dly, учитывающей временные задержки. Разместим его рядом с уже существующим символом mux2_log и подадим на него те же самые сигналы (рис. 6.19).

Промоделировав оба варианта, следует измерить все задержки и убедиться, что они соответствуют заданным в примитиве PINDLY (рис. 20).

Примитив CONSTRAINT проверяет соблюдение временных параметров в моделируемой схеме.

На рис. 6.2l показано, каким образом он контролирует максимальную частоту пере-

Рис. 6.20. Результаты тестирования поведенческих моделей мультиплексора MUX2

ключения сигнала на входе D0 и минимальную длительность импульсов на входе D1.

Добавим текст примитива CONSTRAINT, приведенный на рис. 6.2l, в макромодель mux2_log_dly (она находится в библиотеке my_lib.lib) и повторим только что проведенные эксперименты. Варьируя частоту сигна-

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

Кроме рассмотренных параметров, данный примитив позволяет также контролировать время установки SETUPTIME, время удержания HOLDTIME и время восстановления RELEASETIME.

Более подробно о функциональном описании цифровых устройств с помощью рассмотренных примитивов можно прочитать в [1].

Литература

1. Разевиг В. Д. Система схемотехнического моделирования и проектирования печатных плат Design Center (PSpice). — М.: СК Пресс, 1996. — С. 272.

Рис. 6.19. Схема для тестирования макромоделей мультиплексора MUX2

U_MUX2_CON CONSTRAINT (2) ; примитив контролирует два входа

+ DPWRDGND

+ DO Dl ; имена контролируемых входов Б0 и Б1

+ IO_STD ; стандартная модель вход/выход

+ FREQ:

+ NODE = DO

+ MAXFREQ = 10MEG ; максимальная частота равна 10 мегагерц

+ WIDTH:

+ NODE = Dl

+ MIN_LO = 50NS ; минимальная пауза между импульсами равна 50нс

+ MIN_HI = 100NS ; минимальная длительность импульсов равна 100нс

Рис. 6.21. Содержимое примитива CONSTRAINT для мультиплексора MUX2