Строительным материалом (кирпичиком) в ПЛИС является логическая макроячейка ("LE"). Их количество является основным ресурсом, когда решается вопрос выбора чипа для реализации заданного проекта.
В чипе платы Марсоход их 240.
В "Resource Property Editor" среды Quartus II макроячейка выглядит так:
Макроячейка, в свою очередь, состоит из двух частей. Одна из них - это элемент регистровой логики (справа). Это один D-триггер, имеющий вход разрешения записи ("enable" ). Вторая часть - это универсальный четырехвходовый логический элемент("LUT"), который может быть запрограммирован на реализацию любой четырехвходовой логической функции (на картинке слева). Именно на этих элементах реализуется вся комбинаторная логика проекта в ПЛИС.
Если нужна функция больше 4х входов, то будет использоваться два таких элемента, больше 7 входов - три ячейки и т.д.
Для описания логических функций в проекте можно использовать базовые примитивы "AND", "OR", "XOR" и "NOT":
Я думаю, подавляющему большинству наших читателей, эти элементы и функции, которые они реализуют, хорошо знакомы. Примитивы "AND" и "OR" могут быть на 2,3,4,6 и 8 входов. Этих базовых примитивов достаточно, чтобы реализовать
нужную нам логическую функцию любой сложности.
Для начала, не очень сложная функция:
Это пример реализации часто используемой логической конструкции - мультиплексора, в нашем случае очень простого - 2х1.
В зависимости от состояния адресного входа key[0], на выходе будет или сигнал key[1], или key[2].
Если добавить входной пин с именем key[2..0], выходной led[0] и назначить им соответствующие ножки, то этот проект можно будет откомпилировать, зашить в платку и посмотреть "в живую" на его работу (не забудьте проверить назначение номенов пинов чипа сигналам проекта).
Кроме того, из любопытства, можно посмотреть его реализацию в "Resource Property Editor":
Какие-то достаточно сложные конструкции не очень удобно набирать из примитивов, и, так-же как и в случае с константами, можно использовать мегафункции. Для нашего случая нужна мегафункция LPM_MUX:
В отличии от использования LPM_CONSTANT , в меню "Properties", нужно не только задать параметры (в данном случае LPM_WIDTH и LPM_SIZE), но и отключить входы регистровой логики (aclr,clken и clock). Это нужно для того, чтобы компонент содержал только комбинаторную логику:
После компиляции этого компонента, мы получим точно такой-же результат, как и в предыдущем случае.
Приведу еще несколько примеров наиболее часто используемых логических конструкций: LPM_COMPARE - компаратор:
Выдает результат сравнения двух переменных. В данном случае на led[0] будет "1", если
состояния сигналов key[1..0] и key[3..2] будут равны.
LPM_DECODE - дешифратор:
Преобразует бинарный код в позиционный.
В данном примере "1" будет на том выходе, номер которого набран на key[2..0].
LPM_ADD_SUB - сумматор ( или вычитатель ):
На led[1..0] будет арифметическая сумма сигналов key[1..0] и key[3..2].
Напоследок некоторые рекомендации.
На принципиальных схемах для обозначения инверсии на выходах или входах каких-нибудь компонентов используют маленькие кружочки. Не используйте примитивы с кружочками и не ставьте их в мегафункциях.
Инвертор - такой-же важный логический элемент как и все остальные, и его отсутствие в нужном месте (или наличие
в ненужном) приводит к полной неработоспособности проекта. Ставьте инверторы в "явном виде". Это значительно облегчит понимание работы схемы и поиск ошибок. Из тех же соображений (облегчения визуального восприятия ) старайтесь создавать мегафункции, содержащие только один тип логики - или только комбинаторную логику, или только регистры.
В следующей статье - Часть3. Регистровая логика.
Подробнее...