Конечно, вы не программируете ПМЛ так, а используете вместо этого прямую загрузку универсального JEDEC программирующего формата. В этом примере язык CUPL, очевидно, делает трудную задачу простой.
Как пример, давайте спроектируем регистровую ПМЛ для диаграммы состояний на рис. 8.80.
Рис. 8.80.
Это — торговый автомат, предназначенный для выдачи бутылки сладкой шипучей жидкости, когда опущено 25 цент или более. Существует некоторый вид монетного интерфейса, который «заглатывает», распознает монету и посылает на наш ПМЛ 2-битовый входной сигнал (С1, С0), действительный для одного такта, показывающего монету, которую опустили (01-5 цент, 10–10 — цент монета, 11–25 — цент монета, 00 — нет монеты). Задача машины состояний добавлять к общему вкладу и формировать выход, называемый «бутылка», когда опущено достаточно монет. Рис. 8.81 показывает спецификацию, выполненную в синтаксисе машины состояний языка CUPL.
/** Inputs **/
Pin = elk; /* clock — positive edge */
Pin = c0; /* coin type — low bit */
Pin = c1; /* coin type — high bit */
Pin = reset; /* reset input */
/** Outputs **/
Pin 18 = !Q0; /* bit 0 of state variable */
Pin 17 = !Q1; /* bit 1 */
Pin 16 = !Q2; /* bit 2 */
Pin 15 = !bottle; /* bottle disgorge command */
/* Define machine states with symbolic names;
"enough" = 25 cents or more */
$define S0 'b'000
$define S5 'b'001
$define S10 'b'010
$define S15 'b'011
$define S20 'b'100
$define ENOUGH 'b'101
/* define intermediate variables */
nocoin = !c0 & !c1 & !reset;
nicke1 = c0 & !c1 & !reset;
dime = !c0 & c1 & !reset;
quarter = c0 & c1 & !reset;
/* Define state bit variable field */
field statebit = [Q2..0];
/* Transition rules for vending machine */
sequence statebit {
present S0 if nocoin next S0;
if nicke1 next S5;
if dime next S10;
if quarter next ENOUGH out bottle;
present S5 if nocoin next S5
if nicke1 next S10;
if dime next S15;
if quarter next ENOUGH out bottle;
present S10 if nocoin next S10
if nicke1 next S15;
if dime next S20;
if quarter next ENOUGH out bottle;
present S15 if nocoin next S15
if nicke1 next S20;
if dime next ENOUGH out bottle;
if quarter next ENOUGH out bottle;
present S20 if nocoin next S20
if nicke1 next ENOUGH out bottle;
if dime next ENOUGH out bottle;
if quarter next ENOUGH out bottle;
present ENOUGH next S0; }
Рис. 8.81
.Как и прежде, мы начнем с определения входных-выходных контактов. Заметим, что мы добавили вход
Заметим, что вы должны определить точно переход из некоторого состояния в себя, также, как мы делали для входа «нет монеты». Неопределенное условие безусловно сбрасывает состояние во все нули. Это происходит потому, что эти условия собираются в комбинационную логику для выставления на D-входы регистров и, таким образом, если условие не удовлетворяется, то соответствующий D-вход не подтверждается. Рис. 8.82 показывает вывод из языка CUPL.
** Expanded Product Terms **
Q0.d =>
!Q0 & !Q1 & cQ & !reset
# !Q0 & !Q2 & cO & !reset
# Q0 & !Q2 & !c0 & !reset
# Q0 & !Q2 & c1 & !reset
# !Q0 & !Q1 & Q2 & c1 & !reset
Q1.d =>
!Q1 & !Q2 & !c0 & c1 & !reset
# !Q0 & Q1 & !Q2 & !c1 & !reset
# Q1 & !Q2 & !c0 & !c1 & !reset
# Q0 & !Q1 & !Q2 & cO & !c1 & !reset
Q2.d =>
!Q0 & !Q1 & Q2 & !reset
# Q1 & !Q2 & c1 & !reset
# !Q2 & c0 & c1 & !reset
# Q0 & Q1 & !Q2 & c0 & !reset
bottle.d =>
!Q2 & c0 & c1 & !reset
# !Q0 & !Q1 & Q2 & c0 & !reset