Партнерка на США и Канаду по недвижимости, выплаты в крипто

  • 30% recurring commission
  • Выплаты в USDT
  • Вывод каждую неделю
  • Комиссия до 5 лет за каждого referral

Рис. 28. DSL-модель кольцевого регистра сдвига

При M=0 регистр переключается в режим циклического (кольцевого) сдвига. При этом бит, вытолкнутый из старшего разряда Q3, поступает в младший разряд Q0 (Y[0]=Y[3];). В схеме возникает тактируемая обратная связь.

Как следует из рис.28, в регистр выполнен на четырёх D-триггерах Y[3], Y[2], Y[1], Y[0], управляемых сигналом сдвига SHIFT. В режиме приёма числа (M=1) происходит сдвиг в сторону старших разрядов: Y[3]=Y[2]; Y[2]=Y[1]; Y[1]=Y[0];, а в освободившийся младший разряд заносятся данные с входа DL: Y[0]=DL. Затем состояние внутреннего регистра транслируется на внешние выходы: [Q3..Q0]=Y;.

Интуитивно кажется, что нарушать логическую последовательность записанных один за другим операторов присваивания никак нельзя. Надо постараться не испортить ещё не сдвинутые данные. Если работу выполнить в обратном порядке: Y[0] = DL; Y[1] = Y[0]; Y[2] = Y[1]; Y[3] = Y[2];, то возникают основания полагать, что они потеряются. Действительно, исполнив сначала оператор Y[0]=DL;, мы обновили содержимое младшего разряда, не успев передать его старое значение в следующий разряд.

Однако опасения напрасны. Во-первых, имена, стоящие в левой части операторов присваивания, это не выходы, а входы D-триггеров. Об этом уже упоминалось, когда шёл разговор о триггерах. У нас даже есть возможность описать их явным образом: Y[0].D = DL; Y[1].D = Y[0]; Y[2].D = Y[1]; Y[3].D = Y[2];. Теперь видно, что новая информация не «забивает» старые (текущие) данные.

НЕ нашли? Не то? Что вы ищете?

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

§  не надо ранжировать элементы схемы и расставлять их в порядке срабатывания;

§  не надо вводить промежуточные переменные и использовать их как «перевалочную базу», сохраняя в них старое состояние устройства.

Единственно чего следует избегать – это обратных связей в асинхронных схемах. В частности, не пытайтесь строить DSL-модели триггеров на вентильном уровне, – ничего не получится. Из-за отсутствия задержек на элементах попытки моделировать такие схемы приводят к фатальным ошибкам.

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

Его модель, правда, не претендует на роль образца: она довольно громоздка. Вот если использовать массивы и группы, то можно получить более компактный DSL-код:

IF /M THEN Y. D = [Y[2..0],DR];

ELSE Y. D = [Y[2..0],Y[3]];

END IF;

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

Приведём ещё один пример кольцевого регистра сдвига с перекрёстной обратной связью (рис. 29).

Исторически этот узел называется счётчиком Джонсона (реже счётчиком Мёбиуса) и служит причиной всякого рода недоразумений, потому что это вовсе и не счётчик, а регистр. Реализуем его на JK-триггерах.

Компилятор языка DSL «видит» схему так, как показано на рис.29, а. Прежде всего, отметим, что все встроенные в язык DSL триггеры имеют один выход. Триггер JK не является в этом смысле исключением. Чтобы имитировать инверсные выходы триггеров, приходится добавлять в схему инверторы INVR. Кроме того, имена внешних выходов регистра Q[3..0] не совпадают с выходами внутренних триггеров Y[3..0], да и не могут совпадать. Это означает, что между ними должны стоять буферные элементы BUF.

Рис. 29. DSL-модель кольцевого регистра сдвига с перекрёстной обратной связью

И, наконец, о входах триггеров. Их имена получаются добавлением к соответствующему выходу триггера суффиксов. J или. K. С учётом сказанного и в соответствии со структурной схемой регистра можно написать:

Y[3].J=Y[2]; Y[2].J=Y[1]; Y[1].J=Y[0];Y[0].J=/Y[3];

Y[3].K=/Y[2]; Y[2].K=/Y[1]; Y[1].K=/Y[0];Y[0].K=Y[3];

С помощью массивов и групп эту развернутую запись легко представить в более компактном виде, как показано на рис.29, б, или даже так:

Y. J=[Y[2..0],/Y[3]];

Y. K=[/Y[2..0],Y[3]];

Ну а вершиной (АКМЕ) нашего творчества, несомненно, является версия, приведённая на рис.30. Здесь вообще нет внутренних узлов, а внешние выходы объявлены как JK-триггеры, которыми непосредственно управляют сигналы сдвига С и сброса R. Не правда ли, получился весьма лаконичный DSL-код? В остальном модель не отличается от предыдущей.

Рис. 30. АКМЕ - модель кольцевого регистра сдвига с перекрёстной обратной связью,
в которой выходы Q[3..0] объявлены как JK-триггеры

В рассмотренных примерах для построения моделей использовалась информация о структурных данных исследуемых узлов. Нам даже пришлось привести логическую структуру счётчика Джонсона (рис.29, а). Правда, структурные свойства использовались лишь в той мере, насколько это было необходимо для решения поставленной задачи (по минимуму). Мы не детализировали объект до описания отдельных элементов и структурных связей, описывая их в явном виде. Такое «половинчатое» использование структурных данных порождает своеобразный вид моделей, называемых потоковыми. Об этом говорилось ранее.

Структурные модели требуют явного описания элементов объекта в виде процедур или функций и полного (хотя и не явного) описания структурных связей через списки фактических параметров процедур. На рис.31 показан пример структурной DSL-модели только что рассмотренного счётчика Джонсона, реализованной по его структурному описанию (рис.29, а). Правда, вместо абстрактных JKFFR-триггеров используется реальная ИМС K555TV6. DSL-модель этого триггера была построена ранее (рис.25, б) и помещена в библиотечный файл LIB_DSL_PROC. dsl. Поэтому на неё необходимо сделать ссылку.

Рис.31. Структурная модель кольцевого регистра сдвига с перекрёстной обратной связью

Так как JK-триггер K555TV6 имеет парафазный выход, то необходимость в инверторах INVR отпадает. Не нужны теперь и буферы BUF, которые разделяли внутренние переменные модели и внешние выходы. Фактически логическая структура упрощается до четырех JK-триггеров типа K555TV6 (DD1..DD4), а структурные связи неявно заданы через списки фактических параметров процедур. Например, инверсный выход NQ3 триггера DD4 соединён с входом J триггера DD1 (выделено цветом). Об этом говорит общее имя цепи NQ3.

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

Проектируя модель триггера K555TV6 (см. рис.25, б), мы сначала объявили входы в последовательности J, C, K, R, потом выходы Q, NQ. В таком же порядке они должны следовать и при вызове процедуры K555TV6.

Заканчивая разговор о регистрах, приведём пример практической реализации универсального сдвигового регистра K555IR11 (рис.32, а). Логическая таблица, описывающая работу данного узла, изображена на рис.32, б, а его DSL-модель – на рис.32, в. Придётся сделать некоторые пояснения, касающиеся направления сдвигов. На схемах регистры и счётчики рисуют так, чтобы младший разряд был ближе к входам. Поэтому он оказывается левее всех других триггеров. В позиционных кодах всё наоборот – младший разряд числа занимает правую крайнюю позицию.

Отсюда и возникают всякие недоразумения, когда говорят о сдвиге вправо (или влево), не уточняя при этом, где расположен младший разряд. Мы всегда будем иметь ввиду позиционный код, а не рисунок. Значит, сдвиг влево – это сдвиг в сторону старшего разряда (к MSB), а сдвиг вправо – в сторону младшего разряда (к LSB). Например, при сдвиге влево (см. табл. на рис.32, б) в триггер Q3 записывается содержимое Q2, а при сдвиге вправо – содержимое Q3, наоборот, передаётся в Q2.

Рис. 32. DSL-модель универсального регистра R555IR11

DSL-МОДЕЛИ СЧЁТЧИКОВ

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

Для начала напишем DSL-модель асинхронного двоичного счётчика (рис.33, а). Схема выполнена на D-триггерах, работающих в счётном режиме. Каждый следующий триггер кроме первого получает счётный импульс с инверсного выхода предыдущего триггера. Другими словами, у них нет единого тактирующего сигнала, и, следовательно, их нельзя описать массивом.

Так как у триггеров нет инверсных выходов, то их приходится объявлять локальными узлами: NODE NF3..NF0; (рис.33, б) и вычислять значения внутри модели: [NF0..NF3] = /[F0..F3];. Операция инверсии реализуется с помощью групп.

Наконец, каждый D-триггер надо поместить в счётный режим, замкнув его инверсный выход обратной связью с D-входом. Эта работа выполняется коллективно групповым оператором присваивания: [F0.D..F3.D] = [NF0..NF3];. В развёрнутом виде запись выглядит так: F0.D=NF0; F1.D=NF1; F2.D=NF2; F3.D=NF3;. Впрочем, в языке DSL имеется специальная опция DEFAULT_TO, позволяющая задать по умолчанию (то есть, не описывая явно) ту же самую информацию. На рис.33, в показано, как она используется.

Рис. 33. DSL-модель асинхронного двоичного счётчика на D-триггерах

В данном примере конструкция DEFAULT_TO указывает для каждого триггера, какие данные надо подавать на его D-вход по умолчанию. Так для триггера F0 на его вход F0.D необходимо подать значение, вычисляемое выражением /F0 (а это инверсия прямого выхода). Нам теперь вообще не нужны инверсные выходы триггеров NF3..NF0, они даже не декларируются в модели счётчика. Посмотрите, их нет и конструкции CLOCKED_BY.

При построении модели асинхронного счётчика на JK-триггерах (рис.34) тоже удобного использовать опцию DEFAULT_TO.

Рис. 34. DSL-модель асинхронного двоичного счётчика на JK-триггерах

Но у JK-триггера два тактируемых входа, и поэтому потребуется задавать не одно, а два значения (или выражения). Для того чтобы JK-триггер оказался в счётном режиме, на оба входа надо подать 1. Левая единица в опции DEFAULT_TO определяет состояние входа J, а правая – входа K. Обратите внимание, вся модель кроме оператора Q=[Y3..Y0];, реализована в разделе деклараций триггеров.

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

Попробуем убить сразу двух зайцев: построим модель двоично-десятичного реверсивного счётчика (рис.35), имеющего выходы переноса P1 и заёма P0. Направлением счёта управляет вход U_D (Up_Down - вверх_вниз). При U_D=1 счётчик работает на увеличение, при U_D=0 – на уменьшение.

Если при счёте вверх содержимое счётчика станет равным 9 (1001b), то сформируется выходной перенос P1=1 и следующим кодом будет 0. При счёте вниз заём P0=1 формируется на коде 0 (0000b), и следующий импульс установит код 9. Никаких новых инструментов кроме, пожалуй, вложенных операторов IF, в приведённой модели не используется.

Рис. 35. DSL-модель двоично-десятичного реверсивного счётчика
с цепями выходного переноса и заёма

Интересные решения получаются при построении моделей последовательностных схем с помощью оператора TRUTH_TABLE. Если у вас сложилось впечатление, что таблица истинности пригодна лишь для комбинационных схем, то вас ждёт приятное разочарование. Посмотрите, как просто и изящно реализуется модель только что рассмотренного счётчика с помощью табличного описания (рис.36).

Первые две строки таблицы описывают режим счёта на увеличение (U_D=1). Проверяется условие Y=9. Если оно не выполняется (первая строка), то есть содержимое счётчика не достигло предельного значенияY=9, то в счётчик добавляется 1, а выходного переноса нет P1=0. Если обнаружен максимальный код Y=9 (вторая строка), то сформируется перенос P1=1 и определится будущее состояние счётчика Y=0. Но в отличие от асинхронного сигнала P1, массив Y является тактируемым, то есть он примет новое значение не в текущий момент времени, а только в следующем цикле работы моделирующей программы, когда дождётся нового фронта на входе C.

Аналогичные процессы происходят в режиме счёта вниз (U_D=0).

Рис. 36. DSL-модель двоично-десятичного реверсивного счётчика,
построенная с помощью логической таблицы TRUTH_TABLE

Счётчики с произвольным порядком счёта проще всего реализовать с помощью таблицы истинности TRUTH_TABLE (рис.37, а).

Рис. 37. DSL-модель счётчика с произвольным порядком счёта

В данном примере порядок счёта указан в самом его названии: 0_1_3_5_7_6_4_2_0. Эту информацию и следует занести в таблицу истинности, причем в левом столбце указывается старое (текущее) состояние счётчика, а в правом – состояние, в которое он должен перейти.

Обратите внимание, нам не нужна информация о структурной схеме счётчика. Всё что требуется – это таблица переходов. Таким образом, речь идёт о чисто поведенческой (функциональной) модели счётчика.

На рис.37, б показан другой вариант реализации того же самого узла. Теперь уже используются структурные данные о счётчике. Они «спрятаны» в функциях возбуждения каждого триггера. Сама структура весьма громоздка и здесь не приводится. Мы видим только логические уравнения, которые её описывают. Чтобы получить DSL-модель, надо сначала синтезировать эти уравнения, то есть проделать предварительную и не очень простую работу. В варианте с таблицей TRUTH_TABLE ничего подобного делать не требуется. Мы уже знаем, что модели, построенные с использованием структурных данных, называются потоковыми.

Заметим, что две и более моделей могут находиться в одном DSL-файле. А для того, чтобы обратиться к одной из них, надо в атрибуте PLMODEL указать имя желаемой модели, например:

PLMODEL = COUNTER_0_1_3_5_7_6_4_2_0

или

PLMODEL = COUN_0_1_3_5_7_6_4_2_0_FORMULA

Такая возможность делает очень удобной отладку DSL-моделей в тех случаях, когда создаётся несколько рабочих версий.

Для счётчиков с произвольным модулем счёта остаётся справедливым всё сказанное выше. На рис.38 показаны три варианта DSL-модели счётчика по модулю M=6, начинающего счёт с кода 2 (010b).

Рис. 38. DSL-модель счётчика с произвольным модулем счёта (M=6)

Первая модель построена с использованием логической таблицы TRUTH_TABLE, вторая – с использованием булевых уравнений, описывающих функции возбуждения каждого триггера. Здесь мы наблюдаем те же самые решения, что и для предыдущей схемы (рис.37). Единственное отличие заключается в том, что исходное состояние, задаваемое сигналом R, равно не 0, а 2.

Эта деталь принципиальна в языке DSL. Дело в том, что при коллективном описании триггеров мы можем установить их все либо в 1 (PRESET_BY R), либо в 0 (RESET_BY R). А нам требуется задать им разные исходные состояния. Вот и приходится собирать триггеры в разные группы, те, что должны оказаться в 0 (Y2,Y0) и те, что должны установиться в 1(Y1). Переходы на отсутствующих наборах отдаём на откуп компилятору (ELSE :: .X.;).

Третий вариант модели (рис.38, в) использует операцию инкремента текущего состояния счётчика. Здесь, в отличие от двоично-десятичного счётчика (см. рис.35) необходимо контролировать не только верхнюю, но и нижнюю границы возможных состояний узла ( в примере - 7 и 1):

IF 1<[Y2..Y0] AND [Y2..Y0]<7 THEN

Тогда при сбое он сразу начнёт счёт с разрешённого состояния, восстановив работоспособность за один такт.

Структурная модель счётчика M6 (рис.39) строится с использованием DSL-моделей отдельных его элементов - триггеров K555TM2, логических элементов OR2_DSL, INVR_DSL и AND2_OR2_DSL. Модель AND2_OR2_DSL, выполняющая функцию 2И-2ИЛИ, построена специально для этого примера и включена в библиотеку DSL-моделей LIB_DSL_PROC. dsl.

Названные элементы объединяются в логическую структуру так, чтобы реализовать уравнения, которыми описывается работа данного узла (рис.38, б). Обратите внимание, как задаётся исходное состояние, отличное от 0. Для того, чтобы установить в 1 триггер DD2, сигнал NR подаётся не на вход сброса R, а на вход установки S.

Рис. 39. Структурная модель счётчика с произвольным модулем счёта (M=6)

Заканчивая разговор о счётчиках, приведём пример построения DSL-модели реальной микросхемы K555IE7 – двоичного реверсивного счётчика (рис.40).

Сразу скажу, что построение поведенческой модели (рис.41) – весьма трудоёмкое занятие. На её отладку у меня ушло почти полдня. Да и то один дефект в ней остался не устранённым.

Основная трудность заключается в том, что счётчик имеет как тактируемые, так и асинхронные режимы работы. Асинхронный сброс реализуется элементарно (опция RESET_BY), а вот с параллельной загрузкой возникают заморочки. В этом режиме счётчик ведёт себя подобно триггеру-защёлке (D_LATCH).

Рис. 40. Условное графическое обозначение и логическая таблица ИМС К555ИЕ7

При появлении сигнала L=0 счетчик открывается для приёма данных с входов D3..D0. Если информация на этих входах меняется, то все изменения транслируются на выходы счётчика. В момент переключения входа L с 0 на 1 все его триггеры «защелкиваются», фиксируя последнее состояние, в котором оказался счётчик непосредственно перед выключением режима параллельной загрузки.

Рис. 41. Поведенческая DSL-модель ИМС К555ИЕ7

Знакомясь с текстом DSL-модели счётчика K555IE7, вы обнаружите, что тактируемые и асинхронные режимы реализуются порознь. Для тактируемых режимов декларирован внутренний массив Y[3..0], для асинхронных режимов используются внешние выходы Q3..Q0.

Труднее всего, оказалось «склеить» оба режима, чтобы они работали согласованно. Например, после загрузки счёт должен начинаться не с нуля, а с того кода, который был только что загружен. Эта задача решается с помощью оператора IF R+/L THEN Y=[Q3..Q0];. Но Y – тактируемый массив, и в него будут переданы данные от Q3..Q0 только в том случае, когда управляющее выражение опции CLOCKED_BY CU*CD*L сформирует фронт.

Особенность работы ИМС К555ИЕ7 заключается в том, что пассивным (нерабочим) уровнем на счётных входах CU и CD является 1. Например, если счётчик считает вверх, то CD (Clock Down) должен равняться 1. И, наоборот, при счёте вниз на пассивном входе CU (Clock Up) необходимо установить высокий уровень.

Обратите внимание, в режиме параллельной загрузки L=0, значит выражение CU*CD*L тоже равно 0. Другими словами, загрузка блокирует счёт. В момент окончания режима загрузки сигнал L переключается на 1 и выражение CU*CD*L формирует фронт, по которому асинхронные данные Q3..Q0 передаются в тактируемый массив. В этот же момент условие R+/L перестаёт выполняться, и в режиме счёта обмен данными происходит в обратном направлении: [Q3..Q0]=Y;. По-другому не получается.

Гораздо проще построить модель того же счётчика на основании его структурных данных. Именно так и реализованы фирменные DSL-модели. Мы не станем приводить логическую структуру всего счётчика – она довольно громоздкая. Покажем только его младший разряд (рис.42) и проследим, как он представлен в фирменной DSL-модели счётчика (рис.43). Чтобы было удобнее работать, рядом со структурной схемой приведены описания и операторы, «обслуживающие» младший разряд счётчика. Вы без труда обнаружите, что приведённые логические уравнения неявно описывают структурную схему, то есть фирменная модель есть ни что иное, как потоковая модель.

Рис. 42. Логическая структура младшего разряда ИМС К555ИЕ7

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

Рис. 43. Фирменная DSL-модель реверсивного счётчика К555ИЕ7
(зарубежный аналог 74LS193)

ОПЕРАТОР STATE_MACHINE

В языке DSL есть ещё один замечательный оператор. Он называется STATE_MACHINE и предназначен для описания цифровых автоматов. Дословно STATE_MACHINE переводится как автомат состояний. С помощью этого оператора декларируются возможные состояния автомата и условия перехода из одного состояния в другое. Простейшим цифровым автоматом является двоичный счётчик. С него и начнём.

На рис.44, а показано графическое обозначение трёхразрядного счётчика, а рядом – его DSL-модель с оператором STATE_MACHINE. Возможные состояния счётчика описываются с помощью ключевого слова STATE (состояние). Вслед за ним идёт имя состояния. В нашем примере счётчик имеет всего восемь состояний, и они называются S0..S7. После разделительного символа «:» могут следовать операторы, которые должны быть выполнены в этом состоянии. В нашем примере выполняется единственный оператор безусловного перехода GOTO, который задаёт ссылку на следующее состояние: из состояния S0 автомат должен перейти в S1, из S1 – в S2 и т. д.

Рис. 44. DSL-модель 3-разрядного двоичного суммирующего счётчика,
построенного с использованием оператора STATE_MACINE

Вы, вероятно, недоумеваете, почему у нас получился именно счётчик, а не какой-либо другой автомат? А всё очень просто. Каждому состоянию компилятор автоматически назначает цифровой код, называемый STATE_BITS. Причём первому состоянию (в примере S0) будет задано значение 0, второму – 1, третьему – 2 и так далее. В опции STATE_BITS Q указано, какому массиву (или группе) будут передаваться эти биты состояния. В нашем примере – это шинный сигнал (массив) Q. Вот и получился двоичный суммирующий счётчик.

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

Посмотрите, как просто из суммирующего счётчика сделать вычитающий (рис.45, а) или счётчик с произвольным порядком счёта 0_1_3_5_7_6_4_2_0 (рис.45, б). Впрочем, также легко построить счётчик с произвольным модулем счёта (рис.46, а) или счётчик, работающий в коде Грея (рис.46, б).

Единственная деталь, которая требует пояснения, это стартовый код, отличный от 0. Счётчик, работающий по модулю M=6, должен начинать счёт с состояния 2. По умолчанию оператор STATE_MACHINE стартует со значения 0 (с первого декларированного состояния).

Чтобы всё работало как надо, следует задать первому состоянию (в примере S0) требуемый бит состояния ([010b]) и перенести опцию асинхронного сброса RESET_BY R в описание оператора STATE_MACHINE. И ещё надо помнить, что опция CLOCKED_BY в описании автомата должна совпадать с аналогичной опцией в декларации внутренних узлов или внешних выходов процедуры, где используется оператор STATE_MACHINE.

Рис. 45. DSL-модели вычитающего счётчика и счётчика с произвольным порядком счёта,
построенные с использованием оператора STATE_MACINE

Рис. 46. DSL-модели счётчика с произвольным модулем счёта (M=6)
и счётчика в коде Грея, построенные с использованием оператора STATE_MACINE

Оператор STATE_MACHINE поддерживает три способа автоматической генерации кодов бит-состояний. С одним из них мы уже познакомились. Он задаётся умолчанием, когда биты состояний явно не описаны, и соответствует работе обычного суммирующего счётчика, стартующего с 0.

Два других способа требуют явной декларации. Это делается с помощью опций: STATE_VALUES GRAY_CODE и STATE_VALUES ONE_HOT. В первом случае биты состояний изменяются в соответствии с кодом Грея (GRAY_CODE), во втором случае цифровые коды содержат только по одной единице, начиная с младшего разряда (ONE_HOT).

На рис.47, а показана модель счётчика, работающего в коде Грея и использующая опцию STATE_VALUES GRAY_CODE. В DSL-описании биты состояний не присутствуют в явном виде. Мы их привели только в качестве комментария. Однако на прогоне этой модели легко убедиться, что счёт идёт в коде Грея.

На рис.47, б представлена модель распределителя тактов (иначе счётчика в коде 1 из N). На выходе этой схемы генерируется двоичный код, содержащий 1 только в одном разряде. Первый импульс входного генератора C передаётся на первый выход счётчика (), второй импульс появляется на втором выходе () и т. д. Для реализации такого механизма генерации бит-состояний и используется опция STATE_VALUES ONE_HOT.

Рис. 47. DSL-модели счётчика, работающего в коде Грея,
и распределителя тактов, построенных с использованием опции STATE_VALUES

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

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

В подтверждение сказанному приведём диаграмму состояний синхронного автомата, реализующего двоичный счёт при M=0 или счёт в коде Грея, если M=1 (рис.48). Переходы 000 ® 001 и 110 ® 111 не зависят от режима работы. Рядом со стрелками, показывающими направления переходов, не стоит никаких условий (это безусловные переходы).

Переходы из остальных состояний зависят от условия M. Например, из состояния 001 схема перейдёт в состояние 010, если M=0 (/M=1) – режим двоичного счёта. В противном случае (M=1) автомат перейдёт в состояние 011, что соответствует счёту в коде Грея. Такие переходы на рис.48 изображены пунктирными линиями. На рис.49 приведена DSL-модель рассмотренного автомата.

Обратите внимание, из состояния S0 (по умолчанию компилятор присвоит ему код 000) автомат переходит в состояние S1 (компилятор определит ему код 001) без анализа каких-либо условий. Аналогично обстоят дела и на переходе S6 (110) ® S7 (111). Однако прежде чем произойдёт переход из состояния S1, автомат проверит условие M. Если оно выполняется, то последует переход в состояние S3 (счёт в коде Грея), иначе следующим будет состояние S2 (двоичный счёт).

Рис. 48. Диаграмма состояний цифрового автомата, работающего в режиме
двоичного счёта (M=0) и в режиме счёта в коде Грея (M=1)

Рис. 49. DSL-модель цифрового автомата, работающего в режиме двоичного счёта (M=0)

или в режиме счёта в коде Грея (M=1)

Заканчивая разговор об операторе STATE_MACHINE приведём ещё один пример (рис.50). Здесь цифровой автомат имитирует работу 3-разрядного регистра сдвига влево (в сторону старших разрядов). При сдвиге в младший разряд регистра Q0 заносятся данные с входа DL.

Рис. 50. Диаграмма состояний цифрового автомата, имитирующего работу
регистра сдвига влево (в сторону старшего разряда)

Рис. 51. DSL-модель цифрового автомата, имитирующего работу
регистра сдвига влево (в сторону старшего разряда)

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3