Результаты работы логических функций, входные или конечные данные нужно где-то хранить — в общем нужны регистры.
Если провести аналогию работы нашего чипа с кухней, то, например, чистка картошки, наливание в кастрюлю воды и т.д. - логические функции. А кастрюля, тарелки, ложки и т.д - средства хранения промежуточных или конечных результатов работы этих функций.
Как уже было сказано в предыдущей статье, для реализации регистровой логики в каждом "LE" (логическом элементе) есть D-триггер. Он имеет один выход и три входа - вход данных (data), клок (clk) и разрешение записи (enable).
Работает он следующим образом. Если присутствует сигнал разрешения записи, то по фронту клока, входные данные появляются на выходе и далее будут оставаться неизменными до следующего фронта клока (т.е. храниться).
При отсутствии разрешения записи данные на выходе меняться не будут. Это, собственно , и есть регистр на 1 бит.
Для реализации в схемотехническом дизайне в среде Altera Quartus II можно использовать примитив "DFFE", или его частный случай (когда запись разрешена всегда) "DFF":
Так же, как и во всех предыдущих случаях, чтобы не заниматься вырисовыванием каждого триггера в отдельности, можно использовать мегафункции.
Мегафункция LPM_DFF - параллельный регистр:
Здесь "data[]" - входы всех триггеров, "q[]" их выходы, а сигналы клока и разрешения записи для всех триггеров общие.
Мегафункция LPM_SHIFTREG - сдвиговый (последовательный) регистр:
В отличие от параллельного регистра , здесь "shiftin" является входом для самого младшего триггера, а выход этого триггера является входом для следующего и т.д. Сигналы клока и разрешения записи, так-же как и в параллельном регистре, для всех триггеров общие.
Ну и далее , некоторые рекомендации (на этот раз - настоятельные):
- Не используйте в качестве клока выход комбинаторной логики. Какой-бы простой не была функция, реализуемая этой логикой, на ее выполнение необходимо какое-то время, в течении которого на выходе будет неопределенное состояние и может произойти ложное срабатывание триггера. Клок можно взять с входного пина (если к нему с наружи подключен тактовый генератор), с внутреннего тактового генератора или с выхода какого-то другого триггера.
- Не используйте в проектах асинхронные сигналы (на примитивах это входы с кружочками сверху и с низу, а на мегафункциях сигналы "aclr" и "aset"), за одним исключением, на котором я хочу остановиться подробнее.
Наш чип ( да, наверное, и все другие ПЛИС ), кроме самой программируемой логики, содержат в себе еще ряд служебных функций. Одна из них "Power-On Reset". Подробно обо всем этом написано в документации, а здесь хочу отметить, что одно из действий, которые эта функция выполняет - установка всех триггеров программируемой логики в одно начальное состояние(в "0"). Поэтому, хочу особо отметить, что стартовать ваш проект, после включения питания, всегда будет с "нулевым" начальным состоянием всех регистров. Для корректного старта вашего проекта это нужно обязательно учитывать. Бывают случаи, когда проект ( или какой-то его фрагмент ) разрабатывается для дальнейшего использования, например , в ASIC или вообще не известно где, а ПЛИС используется только для его отладки. В этом случае, позаботится о начальном состоянии регистров нужно в самом проекте. Обычно это реализуется объединением асинхронных сбросов всех тригеров проекта в один общий сигнал, какой-нибудь "GLOBAL_RESET".
В следующей статье - Часть4. Элементы комбинированной логики. Счетчик.
Подробнее...