sonyps4.ru

Плис понимающая язык c. Делаем таймер или первый проект на плис

Недавно я все-таки сделал свой первый шаг к ПЛИС и призвал вас за собой . Мое фанатическое увлечение ПЛИС и идея о том, что ПЛИС является лучшей платформой для создания любых устройств приобрела религиозный характер. Моя секта ПЛИСоводов проповедует полный отказ от микроконтроллеров, а особо экстремистская ветвь проповедует отказ не только от софт процессоров , но и вообще от последовательных вычислений!

Как всегда, постижению истин помогло решение реальных задач. В сегодняшней проповеди я хотел бы рассказать об испытаниях, которые выпадают на долю молодого ПЛИСовода. Преодолевая испытания мы постигаем истину. Но остаются вопросы, на которые я не нашел ответов. Поэтому я бы очень хотел, чтобы братья-хабровчане - ПЛИСоводы с опытом, поучаствовали в обсуждении, протянули руку помощи своим младшим собратьям.

Эта статья для новичков. В ней я опишу типичные проблемы, вопросы, заблуждения, ошибки, которые могут появиться в самом начале обучения (потому что они появились у меня). Однако, контекст статьи ограничен тем, что разработка ведется на ПЛИС от Altera в среде Quartus на языке Verilog .

Трудно жить ничего не делая, но мы не боимся трудностей!

Одна из причин, по которой многие не начинают изучать Verilog вот прямо сейчас - это отсутствие реальной ПЛИС. Кто-то не может заказать, потому что дорого, а кто-то потому, что не знает, что именно взять (вопрос выбора рассмотрен в предыдущей статье). Кому-то ПЛИС пока еще едет по почте.

Но в своих разработках я пришел к тому, что наличие реальной ПЛИС мне требуется уже на финальном этапе разработки, когда нужно протестировать проект «в железе». Речь о том, что бóльшую часть времени я провожу в отладке своего кода с помощью симуляторов.

Поэтому мой совет: отсутствие ПЛИС - это не повод бездействовать. Пишите и отлаживайте модули для ПЛИС в симуляторах!

Симулятор для Verilog

Итак, чем же развлечь себя скучными длинными рабочими днями (если они таковыми являются)? Конечно же освоеним ПЛИС! Но как же затащить на работу целую среду разработки от Altera, если она весит 3 ежемесячных рабочих лимита интернета? Можно принести на флешке! Но если предметом изучения является Verilog, то можно ограничиться блокнотом, компилятором IcarusVerilog, а результат смотреть в GTK Wave.

Попробовать прямо сейчас

Для начала работы в среде Windows, достаточно скачать по ссылке http://bleyer.org/icarus/ файл установки iverilog-20130827_setup.exe (development snapshot)

Установка трудностей не вызывает. Теперь немного забежим вперед: создадим папку для проекта и в ней пару файлов с пока что не понятным содержимым:

Файл-модуль с кодом для тестирования модулей - bench.v

`timescale 1ns / 100 ps module testbench(); reg clk; initial begin $display("start"); $dumpfile("test.vcd"); $dumpvars(0,testbench); clk <= 0; repeat (100) begin #10; clk <= 1; #10; clk <= 0; end $display("finish"); end


В файле bench.v описан тестовый модуль testbench, в нем создан тестовый источник сигнала clk (меандр). Другие модули будут создаваться в отдельных файлах, либо логику можно протестировать сначала в этом модуле, а потом вынести в отдельный модуль. Потом в модуль testbench будут добавляться экземпляры этих модулей, где мы будем подавать на их входы тестовые сигналы и получать из них результаты. Из модулей мы можем строить иерархию, думаю это понятно всем.

BAT Файл, который скомпилирует и просимулирует главный модуль, добавив другие модули из текущей папки - makev.bat

iverilog -o test -I./ -y./ bench.v vvp test pause


После запуска этого файла мы увидим на экране текст, заданный в $display (это отладочный вывод), значение же сигналов и регистров схемы будут находиться в файле test.vcd. Кликаем по файлу и выбираем программу для просмотра - GTKWave (в моем случае D:\iverilog\gtkwave\bin\gtkwave.exe). Еще пару кликов и мы увидим наш clk.



Практически, каждый свой новый модуль я создаю в блокноте и отлаживаю IcarusVerilog. Следующим этапом после такой отладки идет проверка модулей в Quartus. Хотя в Quartus тоже есть свой симулятор, но я его использую реже. Причина в простоте обновления кода и просмотра результата в IcarusVerilog: сохранил изменения в файле, запустил BAT, нажал кнопку «обновить» в GTKWave - все! В ModelSim для этого требуется чуть больше движений, но он тоже не плох, особенно на данных сложных структур.

После симуляции наступает пора запуска Quartus. Но загружать прошивку в ПЛИС пока еще рано. Нужно убедиться, что божественная вычислительная машина правильно поняла, какую схему мы хотим получить, изложив свои мысли в виде Verilog"а.

Разница между симуляцией и работой в реальном железе

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

Пытливый котенок, начинает искать взаимосвязь между своими действиями и результатом («голубиное суеверием»).

Самая большая драма
Ниже будет список странностей, но сначала самая большая драма, с которой я столкнулся: не все конструкции Verilog могут быть синтезированы в железе . Это связано с тем, что на Verilog описывается не только аппаратная логика, которая объединяется в модули и работает в железе. На том же Verilog описываются тестовые модули, которые объединяют тестируемые модули, подают на их входы тестовые сигналы и в целом существуют только для проверки на компьютере. Изменение значений сигналов во времени задается конструкциями, содержащим знак "#" в тексте Verilog. Такой знак означает задержку во времени. В примере выше именно так генерируется сигнал CLK. И я грешным делом думал, что таким же образом внутри настоящей ПЛИС можно генерировать, к примеру, последовательность бит для отправки сообщения по RS232. Ведь на вход ПЛИС подан сигнал от генератора 50 МГц! Может быть она как-то на него ориентируется. Как оказалось, я не единственный, кто надеялся на чудо: , , , , . Реальность как всегда оказывается более суровой: ПЛИС это набор логики и временная задержка в ней может появиться при использовании счетчика, значение которого увеличивается тактами от генератора до заданной величины, либо как-то иначе (но всегда аппаратно).
Список найденных странностей
Удивительные вещи, однако, прочтение книг проливает свет на эту бесовщину. Более того, обретается благодать.
Если обозначить reg, то не факт, что он будет создан
Как я пришел к проблеме? Допустим есть один модуль, на вход которого я должен подавать значение (по типу параметра). В перспективе, этот параметр должен будет изменяться во времени в зависимости от каких-то внешних событий. Поэтому значение должно хранится в регистре (reg). Но реализация приема внешних событий пока не реализована, поэтому я регистр не меняю, а просто задаю ему изначальное значение, которое в дальнейшем не меняется.

//задаю 8 битный регистр reg val; //инициирую его значением initial val <= 8"d0240; //wire к которому подключим выход из модуля wire out_data; //неведомый модуль, называется bbox //экземпляр этого модуля называется bb_01 //будем считать, что в модуле есть входной порт in_data и выходной out_data //во входной порт подаем значение с регистра val, а выход подключаем к wire - out_data bbox bb_01(.in_data(val), .out_data(out_data));
Казалось бы в чем подвох? В императивных ЯП мы часто задаем переменные в качестве констант и потом ни разу их не меняем и все работает. Что же мы видим в железе?


Во-первых, мы не видим регистра. Во-вторых, на вход модуля подано 8"hFF вместо наших 8"d0240! И этого уже достаточно для того, чтобы схема заработала не так, как мы планировали. То, что регистра нет - это нормально. В Verilog можно описывать логику разными способами, в то же время, синтезатор всегда оптимизирует аппаратную реализацию. Даже если написать блок always и в нем работать с регистрами, но при этом выходное значение всегда будет определяться входными, то применение регистра тут окажется лишним и синтезатор его не поставит. И наоборот, если при каких то значениях входных данных выходное значение не меняется, то тут никак не обойтись без регистра-защелки и синтезатор его создаст. (Книга 1 стр. 88-89). Что из этого следует? Если мы начнем менять значение регистра, например, в зависимости от нажатии кнопок, то геристр уже будет создан и все будет работать так, как нужно. Если же окажется, что кнопки ничего не меняют, то синтезатор его опять же выкинет и опять все поломается. Что же делать с константой? Нужно подать ее напрямую на вход модуля:

Bbox bb_01(.in_data(8"d0240), .out_data(out_data));
Теперь на входе модуля мы имеем правильное значение:

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

Размерность wire лучше задавать самому.
При разработке в среде Quartus, допускается не задавать линии wire заранее. В этом случае они будут созданы автоматически, но об этом будет выдано предупреждение (warning). Проблема заключается в том, что разрядность wire будет 1-бит, а если порты будут иметь разрядность больше 1 бита, то значение не будет передано.

Bbox bb_01(.in_data(8"d0240), .out_data(int_data)); other_bbox bb_02(.in_data(int_data), .out_data(out_data));
Предупреждение
Warning (10236): Verilog HDL Implicit Net warning at test.v(15): created implicit net for "int_data"
Результат:

Как видим, один бит подключен, а остальные 7 бит получаются не подключены (NC). Чтобы такой проблемы не было - нужно создать wire самостоятельно. Не зря компилятор IcarusVerilog выдает не warning, а ошибку, если wire не задан заранее.

Wire int_data; bbox bb_01(.in_data(8"d0240), .out_data(int_data)); other_bbox bb_02(.in_data(int_data), .out_data(out_data));

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

Нельзя использовать выход логической функции, в качестве тактового сигнала
Иногда в проекте требуется снизить тактовую частоту, либо ввести временную задержку в N тактов. Новичёк может применить счетчик и дополнительную схему определения достижения счетчиком определенного значения (схема сравнения). Однако, если напрямую использовать выход со схемы сравнения в качестве тактового, то могут возникнуть проблемы. Это связано с тем, что логической схеме требуется некоторое время для установки стабильного значения на выходе. Эта задержка смещает фронт сигнала, проходящего через разные части логической схемы относительно тактового, в итоге получаются гонки, метастабильность, асинхронщина. Даже довелось однажды услышать реплику об этом в качестве критики ПЛИС: «с ПЛИС постоянные проблемы - гонки сигналов».

Если прочитать хотя бы парочку статей:
Метастабильность триггера и межтактовая синхронизация
Пару слов о конвейерах в FPGA

То становится ясно, каким образом разрабатываются устройства на ПЛИС: вся задача делится на аппаратные блоки, а данные между ними движутся по конвеерам, синхронно защелкиваясь в регистрах по тактовому сигналу. Таким образом, зная общую тактовую частоту, синтезатор рассчитывает максимальную частоту работы всех комбинаторных схем, определяет, укладывается ли их скорость к период такта и делает вывод - будет или не будет работать схема в ПЛИС. Все это происходит на этапе синтеза. Если схемы укладываются в параметры, то можно прошивать ПЛИС.

Таким образом, для разработчиков устройств на базе ПЛИС созданы все необходимые методологии, и если их придерживаться, то проблем не будет.

А что, если я хочу пойти против системы?
Порядок разработки и поведение синтезатора схем подводит нас к выводу о том, что же такое ПЛИС на аппаратном уровне. Это синхронные схемы. Поэтому, среди целей синтезатора - уложиться во временные интервалы. Для этого он, к примеру, упрощает логические выражения, выбрасывает из синтеза части схем, которые не используются другими схемами и не привязаны к физическим выводам ПЛИС. Асинхронные решения и аналоговые трюки не приветствуются, потому что их работа может быть непредсказуемой и зависеть от чего угодно (напряжение, температура, техпроцесс, партия, поколение ПЛИС), а поэтому не дает гарантированного, повторяемого, переносимого результата. А всем же нужен стабильный результат и общие подходы к проектированию!

Но что же делать, если вы не согласны с мнением синтезатора о том, что нужно выкидывать неизменяемые регистры, сокращать логические схемы? Как быть, если хотите делать схемы с асинхронной логикой? Нужна тонкая настройка? А может быть вы сами хотите собрать схему на низкоуровневых компонентах ПЛИС? Легко! Спасибо разработчикам Altera за такую возможность и подробную документацию!

Как это сделать? Можно попробовать графический редактор схем. Вы, возможно, слышали о том, что Quartus позволяет рисовать схемы? Можно самому выбрать стандартные блоки и соединить их. Но это не решение! Даже нарисованная схема будет оптимизирована синтезатором, если на это будет возможность.

В итоге мы приходим к старой истине: если ничего не помогает - прочитайте инструкцию . А именно «Altera Handbook» часть под названием «Quartus II Synthesis Options» .

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

//модуль синхронного RS триггера module rs(clk, r, s, q); input wire clk, r,s; output reg q; always @(posedge clk) begin if (r) begin q <= 0; end else if (s) begin q <= 1; end end endmodule
В этом случае получится синхронный триггер.

Если не брать во внимание тактовый сигнал и переключаться в зависимости от любых изменений r и s, то в результате получится элемент с асинхронной установной значений - защелка (latch).

//пример модуль асинхронного RS триггера module ModuleTester(clk, r, s, q); input wire clk, r,s; output reg q; always @(r or s) begin if (r) begin q <= 0; end else if (s) begin q <= 1; end end endmodule

Module ModuleTester(clk, r, s, q); input wire clk, r,s; output reg q; DLATCH lt(.q(q), .clrn(~r), .prn(~s)); endmodule

В итоге, весь «обвес» на входе защелки, который синтезатор посчитал нужным, исчезнет и мы получим именно то, что хотели:

Список существующих примитивов можно посмотреть на сайте Altera.

А теперь небольшой пример про асинхронность и сокращение. Задумал я, к примеру, сделать генератор по тому же принципу, как это было принято делать раньше, но только на ПЛИС:

Но для увеличения периода я возьму 4 элемента, но только один из них будет с инверсией:

Module ModuleTester(q); output wire q; wire a,b,c,d; assign a = b; assign b = c; assign c = d; assign d = ~a; assign q = a; endmodule

Но получается сокращение (1 элемент, вместо четырех). Что логично. Но мы то задумывали линию задержки.

Но если поставить синтезатору условие, что линии a,b,c,d не сокращать, то получится то, что мы задумали. Для подсказки синтезатору применяются директивы . Один из способов указания - это текст в комментарии:

Module ModuleTester(q); output wire q; wire a,b,c,d /* synthesis keep */; // ^^^--- это директива для синтезатора assign a = b; assign b = c; assign c = d; assign d = ~a; assign q = a; endmodule
А вот и результат - цепочка из четырех элементов:

И это далеко не все! Оставлю на радость самостоятельного изучения: работу с case и директиву для реализации его в качестве RAM/ROM или логической схемой; работу со встроенными блоками памяти (RAM/ROM); выбор реализации умножения - аппаратным умножителем или логической схемой.

Недавно я все-таки сделал свой первый шаг к ПЛИС и . Мое фанатическое увлечение ПЛИС и идея о том, что ПЛИС является лучшей платформой для создания любых устройств приобрела религиозный характер. Моя секта ПЛИСоводов проповедует полный отказ от микроконтроллеров, а особо экстремистская ветвь проповедует отказ не только от софт процессоров , но и вообще от последовательных вычислений!

Как всегда, постижению истин помогло решение реальных задач. В сегодняшней проповеди я хотел бы рассказать об испытаниях, которые выпадают на долю молодого ПЛИСовода. Преодолевая испытания мы постигаем истину. Но остаются вопросы, на которые я не нашел ответов. Поэтому я бы очень хотел, чтобы братья-хабровчане - ПЛИСоводы с опытом, поучаствовали в обсуждении, протянули руку помощи своим младшим собратьям.

Эта статья для новичков. В ней я опишу типичные проблемы, вопросы, заблуждения, ошибки, которые могут появиться в самом начале обучения (потому что они появились у меня). Однако, контекст статьи ограничен тем, что разработка ведется на ПЛИС от Altera в среде Quartus на языке Verilog .

Трудно жить ничего не делая, но мы не боимся трудностей!

Одна из причин, по которой многие не начинают изучать Verilog вот прямо сейчас - это отсутствие реальной ПЛИС. Кто-то не может заказать, потому что дорого, а кто-то потому, что не знает, что именно взять (вопрос выбора рассмотрен в ). Кому-то ПЛИС пока еще едет по почте.

Но в своих разработках я пришел к тому, что наличие реальной ПЛИС мне требуется уже на финальном этапе разработки, когда нужно протестировать проект «в железе». Речь о том, что бóльшую часть времени я провожу в отладке своего кода с помощью симуляторов.

Поэтому мой совет: отсутствие ПЛИС - это не повод бездействовать. Пишите и отлаживайте модули для ПЛИС в симуляторах!

Симулятор для Verilog

Итак, чем же развлечь себя скучными длинными рабочими днями (если они таковыми являются)? Конечно же освоеним ПЛИС! Но как же затащить на работу целую среду разработки от Altera, если она весит 3 ежемесячных рабочих лимита интернета? Можно принести на флешке! Но если предметом изучения является Verilog, то можно ограничиться блокнотом, компилятором IcarusVerilog, а результат смотреть в GTK Wave.

Попробовать прямо сейчас

Для начала работы в среде Windows, достаточно скачать по ссылке http://bleyer.org/icarus/ файл установки iverilog-20130827_setup.exe (development snapshot)

Установка трудностей не вызывает. Теперь немного забежим вперед: создадим папку для проекта и в ней пару файлов с пока что не понятным содержимым:

Файл-модуль с кодом для тестирования модулей - bench.v

`timescale 1ns / 100 ps module testbench(); reg clk; initial begin $display("start"); $dumpfile("test.vcd"); $dumpvars(0,testbench); clk <= 0; repeat (100) begin #10; clk <= 1; #10; clk <= 0; end $display("finish"); end


В файле bench.v описан тестовый модуль testbench, в нем создан тестовый источник сигнала clk (меандр). Другие модули будут создаваться в отдельных файлах, либо логику можно протестировать сначала в этом модуле, а потом вынести в отдельный модуль. Потом в модуль testbench будут добавляться экземпляры этих модулей, где мы будем подавать на их входы тестовые сигналы и получать из них результаты. Из модулей мы можем строить иерархию, думаю это понятно всем.

BAT Файл, который скомпилирует и просимулирует главный модуль, добавив другие модули из текущей папки - makev.bat

iverilog -o test -I./ -y./ bench.v vvp test pause


После запуска этого файла мы увидим на экране текст, заданный в $display (это отладочный вывод), значение же сигналов и регистров схемы будут находиться в файле test.vcd. Кликаем по файлу и выбираем программу для просмотра - GTKWave (в моем случае D:\iverilog\gtkwave\bin\gtkwave.exe). Еще пару кликов и мы увидим наш clk.



Практически, каждый свой новый модуль я создаю в блокноте и отлаживаю IcarusVerilog. Следующим этапом после такой отладки идет проверка модулей в Quartus. Хотя в Quartus тоже есть свой симулятор, но я его использую реже. Причина в простоте обновления кода и просмотра результата в IcarusVerilog: сохранил изменения в файле, запустил BAT, нажал кнопку «обновить» в GTKWave - все! В ModelSim для этого требуется чуть больше движений, но он тоже не плох, особенно на данных сложных структур.

После симуляции наступает пора запуска Quartus. Но загружать прошивку в ПЛИС пока еще рано. Нужно убедиться, что божественная вычислительная машина правильно поняла, какую схему мы хотим получить, изложив свои мысли в виде Verilog"а.

Разница между симуляцией и работой в реальном железе

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

Пытливый котенок, начинает искать взаимосвязь между своими действиями и результатом («голубиное суеверием»).

Самая большая драма
Ниже будет список странностей, но сначала самая большая драма, с которой я столкнулся: не все конструкции Verilog могут быть синтезированы в железе . Это связано с тем, что на Verilog описывается не только аппаратная логика, которая объединяется в модули и работает в железе. На том же Verilog описываются тестовые модули, которые объединяют тестируемые модули, подают на их входы тестовые сигналы и в целом существуют только для проверки на компьютере. Изменение значений сигналов во времени задается конструкциями, содержащим знак "#" в тексте Verilog. Такой знак означает задержку во времени. В примере выше именно так генерируется сигнал CLK. И я грешным делом думал, что таким же образом внутри настоящей ПЛИС можно генерировать, к примеру, последовательность бит для отправки сообщения по RS232. Ведь на вход ПЛИС подан сигнал от генератора 50 МГц! Может быть она как-то на него ориентируется. Как оказалось, я не единственный, кто надеялся на чудо: , , , , . Реальность как всегда оказывается более суровой: ПЛИС это набор логики и временная задержка в ней может появиться при использовании счетчика, значение которого увеличивается тактами от генератора до заданной величины, либо как-то иначе (но всегда аппаратно).
Список найденных странностей
Удивительные вещи, однако, прочтение книг проливает свет на эту бесовщину. Более того, обретается благодать.
Если обозначить reg, то не факт, что он будет создан
Как я пришел к проблеме? Допустим есть один модуль, на вход которого я должен подавать значение (по типу параметра). В перспективе, этот параметр должен будет изменяться во времени в зависимости от каких-то внешних событий. Поэтому значение должно хранится в регистре (reg). Но реализация приема внешних событий пока не реализована, поэтому я регистр не меняю, а просто задаю ему изначальное значение, которое в дальнейшем не меняется.

//задаю 8 битный регистр reg val; //инициирую его значением initial val <= 8"d0240; //wire к которому подключим выход из модуля wire out_data; //неведомый модуль, называется bbox //экземпляр этого модуля называется bb_01 //будем считать, что в модуле есть входной порт in_data и выходной out_data //во входной порт подаем значение с регистра val, а выход подключаем к wire - out_data bbox bb_01(.in_data(val), .out_data(out_data));
Казалось бы в чем подвох? В императивных ЯП мы часто задаем переменные в качестве констант и потом ни разу их не меняем и все работает. Что же мы видим в железе?


Во-первых, мы не видим регистра. Во-вторых, на вход модуля подано 8"hFF вместо наших 8"d0240! И этого уже достаточно для того, чтобы схема заработала не так, как мы планировали. То, что регистра нет - это нормально. В Verilog можно описывать логику разными способами, в то же время, синтезатор всегда оптимизирует аппаратную реализацию. Даже если написать блок always и в нем работать с регистрами, но при этом выходное значение всегда будет определяться входными, то применение регистра тут окажется лишним и синтезатор его не поставит. И наоборот, если при каких то значениях входных данных выходное значение не меняется, то тут никак не обойтись без регистра-защелки и синтезатор его создаст. (Книга 1 стр. 88-89). Что из этого следует? Если мы начнем менять значение регистра, например, в зависимости от нажатии кнопок, то геристр уже будет создан и все будет работать так, как нужно. Если же окажется, что кнопки ничего не меняют, то синтезатор его опять же выкинет и опять все поломается. Что же делать с константой? Нужно подать ее напрямую на вход модуля:

Bbox bb_01(.in_data(8"d0240), .out_data(out_data));
Теперь на входе модуля мы имеем правильное значение:

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

Размерность wire лучше задавать самому.
При разработке в среде Quartus, допускается не задавать линии wire заранее. В этом случае они будут созданы автоматически, но об этом будет выдано предупреждение (warning). Проблема заключается в том, что разрядность wire будет 1-бит, а если порты будут иметь разрядность больше 1 бита, то значение не будет передано.

Bbox bb_01(.in_data(8"d0240), .out_data(int_data)); other_bbox bb_02(.in_data(int_data), .out_data(out_data));
Предупреждение
Warning (10236): Verilog HDL Implicit Net warning at test.v(15): created implicit net for "int_data"
Результат:

Как видим, один бит подключен, а остальные 7 бит получаются не подключены (NC). Чтобы такой проблемы не было - нужно создать wire самостоятельно. Не зря компилятор IcarusVerilog выдает не warning, а ошибку, если wire не задан заранее.

Wire int_data; bbox bb_01(.in_data(8"d0240), .out_data(int_data)); other_bbox bb_02(.in_data(int_data), .out_data(out_data));

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

Нельзя использовать выход логической функции, в качестве тактового сигнала
Иногда в проекте требуется снизить тактовую частоту, либо ввести временную задержку в N тактов. Новичёк может применить счетчик и дополнительную схему определения достижения счетчиком определенного значения (схема сравнения). Однако, если напрямую использовать выход со схемы сравнения в качестве тактового, то могут возникнуть проблемы. Это связано с тем, что логической схеме требуется некоторое время для установки стабильного значения на выходе. Эта задержка смещает фронт сигнала, проходящего через разные части логической схемы относительно тактового, в итоге получаются гонки, метастабильность, асинхронщина. Даже довелось однажды услышать реплику об этом в качестве критики ПЛИС: «с ПЛИС постоянные проблемы - гонки сигналов».

То становится ясно, каким образом разрабатываются устройства на ПЛИС: вся задача делится на аппаратные блоки, а данные между ними движутся по конвеерам, синхронно защелкиваясь в регистрах по тактовому сигналу. Таким образом, зная общую тактовую частоту, синтезатор рассчитывает максимальную частоту работы всех комбинаторных схем, определяет, укладывается ли их скорость к период такта и делает вывод - будет или не будет работать схема в ПЛИС. Все это происходит на этапе синтеза. Если схемы укладываются в параметры, то можно прошивать ПЛИС.

Таким образом, для разработчиков устройств на базе ПЛИС созданы все необходимые методологии, и если их придерживаться, то проблем не будет.

А что, если я хочу пойти против системы?
Порядок разработки и поведение синтезатора схем подводит нас к выводу о том, что же такое ПЛИС на аппаратном уровне. Это синхронные схемы. Поэтому, среди целей синтезатора - уложиться во временные интервалы. Для этого он, к примеру, упрощает логические выражения, выбрасывает из синтеза части схем, которые не используются другими схемами и не привязаны к физическим выводам ПЛИС. Асинхронные решения и аналоговые трюки не приветствуются, потому что их работа может быть непредсказуемой и зависеть от чего угодно (напряжение, температура, техпроцесс, партия, поколение ПЛИС), а поэтому не дает гарантированного, повторяемого, переносимого результата. А всем же нужен стабильный результат и общие подходы к проектированию!

Но что же делать, если вы не согласны с мнением синтезатора о том, что нужно выкидывать неизменяемые регистры, сокращать логические схемы? Как быть, если хотите делать схемы с асинхронной логикой? Нужна тонкая настройка? А может быть вы сами хотите собрать схему на низкоуровневых компонентах ПЛИС? Легко! Спасибо разработчикам Altera за такую возможность и подробную документацию!

Как это сделать? Можно попробовать графический редактор схем. Вы, возможно, слышали о том, что Quartus позволяет рисовать схемы? Можно самому выбрать стандартные блоки и соединить их. Но это не решение! Даже нарисованная схема будет оптимизирована синтезатором, если на это будет возможность.

В итоге мы приходим к старой истине: если ничего не помогает - прочитайте инструкцию . А именно «Altera Handbook» часть под названием «Quartus II Synthesis Options» .

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

//модуль синхронного RS триггера module rs(clk, r, s, q); input wire clk, r,s; output reg q; always @(posedge clk) begin if (r) begin q <= 0; end else if (s) begin q <= 1; end end endmodule
В этом случае получится синхронный триггер.

Если не брать во внимание тактовый сигнал и переключаться в зависимости от любых изменений r и s, то в результате получится элемент с асинхронной установной значений - защелка (latch).

//пример модуль асинхронного RS триггера module ModuleTester(clk, r, s, q); input wire clk, r,s; output reg q; always @(r or s) begin if (r) begin q <= 0; end else if (s) begin q <= 1; end end endmodule

Module ModuleTester(clk, r, s, q); input wire clk, r,s; output reg q; DLATCH lt(.q(q), .clrn(~r), .prn(~s)); endmodule

В итоге, весь «обвес» на входе защелки, который синтезатор посчитал нужным, исчезнет и мы получим именно то, что хотели:

Список существующих примитивов можно посмотреть на сайте Altera.

А теперь небольшой пример про асинхронность и сокращение. Задумал я, к примеру, сделать генератор по тому же принципу, как это было принято делать раньше, но только на ПЛИС:

Но для увеличения периода я возьму 4 элемента, но только один из них будет с инверсией:

Module ModuleTester(q); output wire q; wire a,b,c,d; assign a = b; assign b = c; assign c = d; assign d = ~a; assign q = a; endmodule

Но получается сокращение (1 элемент, вместо четырех). Что логично. Но мы то задумывали линию задержки.

Но если поставить синтезатору условие, что линии a,b,c,d не сокращать, то получится то, что мы задумали. Для подсказки синтезатору применяются директивы . Один из способов указания - это текст в комментарии:

Module ModuleTester(q); output wire q; wire a,b,c,d /* synthesis keep */; // ^^^--- это директива для синтезатора assign a = b; assign b = c; assign c = d; assign d = ~a; assign q = a; endmodule
А вот и результат - цепочка из четырех элементов:

И это далеко не все! Оставлю на радость самостоятельного изучения: работу с case и директиву для реализации его в качестве RAM/ROM или логической схемой; работу со встроенными блоками памяти (RAM/ROM); выбор реализации умножения - аппаратным умножителем или логической схемой.

6. ПРОГРАММИРУЕМЫЕ ЛОГИЧЕСКИЕ ИНТЕГРАЛЬНЫЕ СХЕМЫ (ПЛИС)

Программируемая логическая интегральная схема (ПЛИС, Programmable Logic Device, PLD) - электронный компонент,

используемый для создания цифровых интегральных схем. В отличие от обычных цифровых микросхем, логика работы ПЛИС не определяется при изготовлении, а задаётся посредствомпрограммирования (проектирования).

История развития ПЛИС начинается с программируемых постоянных запоминающих устройств (PROM – Programmable Read Only Memory). Первое время PROM использовались исключительно для хранения данных, позже их стали применять для реализации логических функций. Для реализации систем булевых функций с большим числом переменных были разработаны программируемые логические массивы ПЛМ (PLA – Programmable Logic Array) – наиболее традиционный тип ПЛИС, имеющий программируемые матрицы «И» и «ИЛИ». Примерами таких ПЛИС могут служить отечественные схемы K556PT1, PT2, PT21.

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

Рис. 6.1. Схема построения PLA

Недостаток такой архитектуры - слабое использование ресурсов программируемой матрицы «ИЛИ», поэтому дальнейшее развитие получили микросхемы, построенные по архитектуре программируемой матричной логики (PAL - Programmable Array Logic) - это ПЛИС, имеющие программируемую матрицу «И» и фиксированную матрицу «ИЛИ» (рис. 6.2). К этому классу относятся большинство современных ПЛИС небольшой степени интеграции. В качестве примеров можно привести отечественные ИС КМ1556ХП4, ХП6, ХП8, ХЛ8, ранние разработки (середина-конец 1980-х годов) ПЛИС фирм INTEL, ALTERA, AMD, LATTICE и др.

Рис. 6.2. Схема построения PAL

Совершенствование ПЛИС привело к появлению программируемой макрологики. Они содержат единственную программируемую матрицу «И- НЕ» или «ИЛИ-НЕ», но за счёт многочисленных инверсных обратных связей способны формировать сложные логические функции. К этому классу относятся, например, ПЛИС PLHS501 и PLHS502 фирмы SIGNETICS, имеющие матрицу «И-НЕ», а также схема XL78C800 фирмы EXEL, основанная на матрице «ИЛИ-НЕ».

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

Дальнейшее усовершенствование технологии производства привело к возможности реализации на одном кристалле нескольких PAL, объединенных программируемыми соединениями. Подобные архитектуры получили название сложных (комплексных) программируемых логических

ПРОГРАММИРУЕМЫЕ ЛОГИЧЕСКИЕ

ИНТЕГРАЛЬНЫЕ CХЕМЫ

устройств (CPLD – Complex Programmable Logic Device) – это ПЛИС,

Рис. 6.3. Схема макроячейки CPLD

Микросхемы этого типа могут быть использованы для создания нестандартных АЛУ, дешифраторов, мультиплексоров и др., т.е. таких устройств, где требуется логические функции многих переменных и небольшое количество триггеров. ПЛИС типа CPLD, как правило, имеют высокую степень интеграции (до 10000 эквивалентных вентилей, до 256 макроячеек).

К этому классу относятся ПЛИС семейства MAX фирмы ALTERA, семейства XC9500 и CoolRunner фирмы XILINX, а также большое число микросхем других производителей (Atmel, Vantis, Lucent и др.).

Другой тип архитектуры ПЛИС – программируемые вентильные матрицы (FPGA – Field Programmable Gate Array Logic), состоящие из конфигурируемых логических блоков (КЛБ) и коммутирующих путей – программируемых матриц соединений (рис. 6.4). Конфигурируемые логические блоки таких ПЛИС состоят из одного или нескольких относительно простых логических элементов, в основе которых лежит таблица перекодировки (LUT – Look-up table), программируемые мультиплексоры, триггер, а также цепи управления. Характерными для FPGA-архитектур являются блоки ввода/вывода (IOB – input/output blocks),

позволяющие реализовать двунаправленный ввод/вывод, третье состояние и т. п.

Рис. 6.4. Структура FPGA

Таких простых элементов может быть достаточно много, например, у современных ПЛИС ёмкостью 1 млн. вентилей и более число логических элементов достигает нескольких десятков тысяч. За счёт такого большого числа логических элементов они содержат значительное число триггеров, а также некоторые семейства ПЛИС имеют встроенные реконфигурируемые модули памяти. Это делает ПЛИС данной архитектуры весьма удобным средством реализации алгоритмов цифровой обработки сигналов, основными операциями в которых являются перемножение, умножение на константу, суммирование и задержка сигнала.

К FPGA классу относятся ПЛИС семейства Spartan, Virtex фирмы

XILINX; Fusion, M1 и M7 Fusion и др. фирмы ACTEL, а также семейства Cyclone, Stratix фирмы ALTERA, ПЛИС фирм Atmel и Vantis.

6.1. Особенности программирования ПЛИС

Конфигурационные данные для CPLD хранятся в энергонезависимой памяти внутри ПЛИС, поэтому нет необходимости их

ЦИФРОВЫЕ УСТРОЙСТВА И МИКРОПРОЦЕССОРЫ. ЧАСТЬ 2

ПРОГРАММИРУЕМЫЕ ЛОГИЧЕСКИЕ

ИНТЕГРАЛЬНЫЕ CХЕМЫ

перепрограммировать при включении. Программа для конфигурации FPGA хранится в распределённой энергозависимой оперативной памяти микросхемы, которая при выключении питания стирается, поэтому файл конфигурации хранится во внешней памяти, и при включении питания файл конфигурации загружается в память ПЛИС. Для хранения файла конфигурации используются, как правило, перепрограммируемое ПЗУ

(EPRM, EEPROM или FLASH).

При работе в подобных системах конфигурация схемы, которая должна быть получена «внутри» ПЛИС или алгоритм ее работы задается либо на текстовом языке описаний: VDHL (V ery high speed integrated circuitsH ardwareD escriptionL anguage – язык описания аппаратуры высокоскоростных интегральных схем), Verilog, ADHL (A lteraH ardwareD escriptionL anguage), напоминающем язык программирования высокого уровня (например Си); либо в графическом редакторе (в виде электрической схемы); либо при помощи блок-схем алгоритмов или графа состояний. Далее, все этапы работы, включая программирование или загрузку ПЛИС, выполняет автоматизированная система проектирования. Такие системы выпускают как все ведущие производители ПЛИС

(www.actel.com) ACTEL, (www.altera.com) ALTERA, (www.xilinx.com) XILINX, так и другие компании.

7. ЦИФРО-АНАЛОГОВЫЕ И

7.1 Принципы построения цифро-аналоговых преобразователей

Цифро-аналоговый преобразователь (ЦАП) представляет собой устройство для преобразования числовых кодов в эквивалентные им значения напряжения или тока. Схемы ЦАП строятся с использованием как цифровых, так и аналоговых элементов (операционных усилителей, ключей, резистивных матриц и т.п.). Большинство ЦАП, выполненных в виде интегральных схем, представляют собой устройства параллельного типа. Их работа основана на суммировании токов, величины которых пропорциональны весовым коэффициентам разрядов входного кода.

Схема 4-разрядного ЦАП приведена на рис. 7.1.

Рис. 7.1. Принцип построения схемы ЦАП

Она включает в себя резистивную матрицу, источник опорного напряжения U R , операционный усилитель и переключателиS 0 − S 3 .

Сопротивления резисторов матрицы таковы, что протекающие через резисторы токи соответствуют весовым коэффициентам разрядов числа

D = d 3 d 2 d 1 d 0 . Положение контактов переключателей зависит от значенийd i . Еслиd i = 0 , то ток, протекающий через резистор матрицы под действием опорного напряженияU R , замыкается на общий провод.

При d i = 1 ток резистора черезS i . течет к схеме суммирования

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

ЦИФРОВЫЕ УСТРОЙСТВА И МИКРОПРОЦЕССОРЫ. ЧАСТЬ 2

ЦИФРО-АНАЛОГОВЫЕ И

АНАЛОГО-ЦИФРОВЫЕ ПРЕОБРАЗОВАТЕЛИ

потенциал относительно общего провода, поэтому выходное напряжение можно записать следующим образом:

U 0= − R R 0 U R (2 3 d 3+ 2 2 d 2+ 2 1 d 1+ 2 0 d 0) .

Для увеличения разрядности ЦАП необходимо добавить соответствующее количество резисторов и переключателей.

Изготовление высокоточных резисторов для матриц сопряжено с трудностями, особенно в случае многоразрядных ЦАП (значения сопротивлений резисторов находятся в широком диапазоне - от R до

R 2 n − 1 , но требования к абсолютной точности установления

сопротивлений одинаковы для всех резисторов). Поэтому часто используют матрицу сопротивлений типа R − 2R (рис. 7.2).

Рис. 7.2. ЦАП с матрицей типа R – 2R

Весовые коэффициенты ступеней задаются последовательным делением опорного напряжения. Коэффициент ослабления каждой ступени матрицы равен двум. Выходное напряжение ЦАП равно:

U 0=− 16 R 0 R U R (2 3 d 3+ 2 2 d 2+ 2 1 d 1+ 2 0 d 0) .

В качестве электронных переключателей в схемах ЦАП часто используют МОП-транзисторы (рис.7.3). Находят применение также токовые ключи на биполярных транзисторах.

Рис. 7.3. 4-разрядный ЦАП:

а – фрагмент схемы с МОП-ключами, б – УГО

Примеры ИС:

К572ПА1 - 10-разрядный ЦАП. ИС содержит прецизионную матрицу типаR − 2R , ключи на МОП-транзисторах, входные усилителиинверторы, а также резистор для цепи обратной связи операционного усилителя. Для преобразования суммарного тока в напряжение необходимо подключение операционного усилителя. Требуется также внешний источник опорного напряжения.

ЦИФРОВЫЕ УСТРОЙСТВА И МИКРОПРОЦЕССОРЫ. ЧАСТЬ 2

ЦИФРО-АНАЛОГОВЫЕ И

АНАЛОГО-ЦИФРОВЫЕ ПРЕОБРАЗОВАТЕЛИ

7.2. Принципы построения аналого-цифровых преобразователей

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

По способу преобразования можно разделить АЦП на параллельные

и последовательные.

В параллельных АЦП входное напряжение одновременно сравнивается со всеми пороговыми уровнями шкалы квантования (рис. В.1. ). В результате сравнения находится ближайший уровень квантования, номер которого с помощью шифратора выражается в двоичном коде. Схема, представляющая собой 3-разрядный параллельный АЦП, показана на рис. 7.4. Источник опорного напряжения и набор резисторов позволяют сформировать напряжения, равные пороговым уровням.

Опорное напряжение в (2n -1) = 7 раз превышает значение шага квантованияU S . Если, например, входное напряжение находится в

диапазон от (4+ 1 2 ) U S до,(5+ 1 2 ) U S оно должно быть представлено

уровнем квантования, равным 5U S , и, соответственно, двоичным кодом 101. Формирование выходного кода происходит следующим образом. При заданном значенииU I на выходах шести компараторов устанавливаются

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

примере это X 5 ).

Рис. 7.4. Параллельный АЦП: а – схема, б - УГО

Пример ИС :

К1107ПВ1 - 6-разрядный параллельный АЦП. ИС изготавливается по биполярной технологии. Максимальная частота дискретизации - 20 МГц.

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

ЦИФРОВЫЕ УСТРОЙСТВА И МИКРОПРОЦЕССОРЫ. ЧАСТЬ 2

ЦИФРО-АНАЛОГОВЫЕ И

АНАЛОГО-ЦИФРОВЫЕ ПРЕОБРАЗОВАТЕЛИ

последовательного счета. Его работа основана на подсчете числа суммирований шага квантования, необходимого для получения значения входного напряжения. Схема АЦП последовательного счета показана на рис. 7.5. Она состоит из n -разрядного реверсивного счетчика, компаратора иn -разрядного цифро-аналогового преобразователя, включенного в цепи обратной связи.

Рис. 7.5. АЦП последовательного счета

С помощью компаратора сравниваются входное напряжение U I и выходное напряжение ЦАПU O . ЕслиU I > U O , то на выходе компаратора единичный уровень и счетчик работает в режиме суммирования тактовых импульсовC . Благодаря этому напряжениеU O стремится кU I . Когда они сравниваются,n -разрядный выходной кодD будет представлять входное напряжение АЦП. ЕслиU I < U O то счетчик работает в вычитающем режиме. Таким образом, напряжениеU O , а следовательно, и выходной код, отслеживают выходное напряжениеU I Для того, чтобы

предотвратить колебания сигнала реверсирования U /D после завершения процесса отслеживания, можно дополнить схему АЦП устройством

блокировки счетчика при U I − U O < U S 2 .

Схема АЦП, показанного на рис. 7.5, очень проста. Но при скачках входного напряжения процесс отслеживания может занять до 2n тактов (периодов импульсовC ). Ускорение преобразования достигается в АЦП поразрядного взвешивания. Его схема похожа на схему рис. 7.5, только счетчик заменяется регистром с устройством управления. Работа АЦП поразрядного взвешивания происходит следующим образом. Сначала все разряды регистра устанавливаются в нулевое состояние. Затем в старший разряд регистра вводится 1. При этом на выходе ЦАП

устанавливается напряжение U O = 2n − 1 U S , равное половине всего2 n − 2) ,

то d n − 2 = 1

Если нет,

d n − 2 = 0 .

После n

этапов процесс уравновешивания заканчивается и на выходе регистра устанавливается кодовая комбинация, представляющая входное напряжение АЦП. Для того, чтобы во время преобразования напряжение

U I не изменялось, на входы компаратора ставится схема выборкихранения.

Известны и другие последовательные АЦП, например, АЦП, работающие по методу интегрирования.

Примеры ИС :

К572ПВ1 - 12-разрядный АЦП поразрядного взвешивания. ИС изготавливается по КМОП-технологии. Используется с внешним операционными усилителями и источником опорного напряжения. Типовое время преобразования - 110 мксек.

К1113ПВ1 - 10-разрядный АЦП поразрядного взвешивания. ИС изготавливается по биполярной технологии и содержит все функциональные узлы АЦП, включая источник опорного напряжения и генератор тактовых импульсов. Выходные каскады выполнены по схеме с тремя состояниями. Время преобразования - не более 30 мксек.

Сопоставляя параллельные и последовательные АЦП, можно отметить следующее. Параллельные АЦП являются схемами быстродействующими, но их реализация требует больших аппаратурных затрат (6-разрядный АЦП содержит 64 компаратора). АЦП последовательного счета имеют самую простую схему, но работают сравнительно с низкочастотными напряжениями. АЦП поразрядного взвешивания занимают по показателям сложности и быстродействию промежуточное положение. Сочетание схем параллельных и последовательных АЦП позволяет построить большое число вариантов преобразователей с различными параметрами и разнообразными функциональными возможностями.

ЦИФРОВЫЕ УСТРОЙСТВА И МИКРОПРОЦЕССОРЫ. ЧАСТЬ 2

ЛИТЕРАТУРА

ЛИТЕРАТУРА

1. Гласман К.Ф., Покопцева М.Н. Цифровые устройства и микропроцессоры. Учебное пособие для студентов специальности 210312 «Аудиовизуальная техника». Часть 1. – СПб.: СПбГУКиТ, 2008.

2. Новиков Ю.В. Основы цифровой схемотехники. Базовые элементы и схемы. Методы проектирования. – М.: Мир, 2001.

3. Новиков Ю., Скоробогатов П. Основы микропроцессорной техники: Курс лекций. – М.: ИНТУИТ.РУ, 2003.

4. Белов А. Самоучитель по микропроцессорной технике. – М.: Наука и техника, 2003.

5. Новожилов О.П. Основы цифровой техники: Учебное пособие. – М.: Радио Софт, 2004.

6. Угрюмов Е. Цифровая схемотехника от логического элемента до перспективных БИС/СБИС с программируемыми структурами. – СПб.: БХВ – Петербург, 2004.

7. Бойко В. Схемотехника электронных систем. Цифровые устройства.

– СПб.: БХВ – Петербург, 2004.

8. Бойко В. Схемотехника электронных систем. Микропроцессоры и микроконтроллеры. – БХВ – Петербург, 2004.

9. Нарышкин А.К. Цифровые устройства и микропроцессоры. – М.: Изд. центр «Академия», 2004.

10. Уилкинсон Б. Основы проектирования цифровых схем. – Киев.: Вильямс, 2004.

11. Фрике К. Вводный курс цифровой электроники. – М.: Техносфера, 2004.

12. Опадчий Ю.А. Аналоговая и цифровая электроника. Учебник для ВУЗов. – М.: Горячая линия – Телеком, 2005.

13. Точчи Р. Уидмер Н. Цифровые системы. Теория и практика. – Киев.: Вильямс, 2004.

14. Алексеева Л.А., Буль М.П., Гласман К.Ф., Покопцева М.Н.. Методические указания по выполнению лабораторных работ для студентов специальности 201400 «Аудиовизуальная техника» по курсу «Цифровые устройства и микропроцессоры». – СПб.: СПбГУКиТ, 2002.

Altera-Cyclone and Arduino

Суть вопроса. Разница между ПЛИС и микроконтроллером

Каждый начинающий микропрогер на определенном этапе своего развития задается вопросом в чем же разница между ПЛИС (фирм Altera или Xilinx) и микроконтроллером (микропроцессором)?

Читаешь форумы — знатоки дела пишут, что это совершенно разные вещи, которые нельзя сравнить, аргументируя это тем, что у них разная архитектура . Читаешь мануал по Verilog или C++ — и тот и другой используют похожие операторы со схожим функционалом, даже синтаксис похож, а почему разные? Заходишь на марсоход — там светодиодами (или даже просто лампочками) с помощью FPGA моргают, смотришь проекты на Arduino — там роботами управляют. СтОп!

А вот теперь остановимся и спросим себя: почему с ПЛИС — тупо лампочка, а Ардуино — умно робот? Ведь и первый и второй вроде как программируемое устройство, неужели у ПЛИС возможностей для робота не хватает?

В какой-то степени суть вопроса «В чем разница между ПЛИС и микроконтроллером ?» раскрывается именно на таком примере.

Отметим сразу. Функционал ПЛИС изначально не уступает микроконтроллеру (и микропроцессору, кстати, тоже), точнее — основные функции у одного и второго по сути идентичны — выдавать логические 0 или 1 при определенных условиях, а если говорить о быстродействии, количестве выводов(ножек) и возможностях конвейерной обработки, то микроконтроллеру до ПЛИС а вообще далеко. Но есть одно «но». Время на разработку одного и того же программного алгоритма на двух разных устройствах (ПЛИС и микроконтроллер ) различается в разы, а то и в десятки раз. Именно ПЛИС здесь в 99% случаев сильно уступает МК. И дело вовсе не в замороченности языков Verilog , VHDL или AHDL , а в устройстве самой ПЛИС .

О взаимодействии программного языка с архитектурой ПЛИС и микроконтроллера

FPGA : в ПЛИС и нет сложных автоматизированных цепочек(делающих часть работы за вас). Есть только железные проводные трассы и магистрали, входы, выходы, логические блоки и блоки памяти. Среди трасс есть особый класс — трасса для тактирования(привязанная к определенным ножкам, через которые рекомендуется проводить тактовую частоту).

Основной состав:

Трасса — металл, напаянный на слои микросхемы, является проводником электричества между блоками.

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

Ячейки — группы от нескольких единиц до нескольких десятков транзисторов.

Транзистор — основной элемент ТТЛ логики.

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

Тактовый генератор — внешняя микросхема, вырабатывающая тактовые импульсы, на которых основывается большая часть работы ПЛИС .

Архитектура ПЛИС. Взаимосвязь составляющих элементов

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

Архитектура ПЛИС (FPGA)

Архитектура Микроконтроллера

В этом элементе ТТЛ логики все операции по обработкам отдельных сигнальчиков проводятся независимо от вас. Вы лишь указываете что делать с тем или иным набором принятых сигналов и куда выдавать те сигналы, которые нужно передать. Архитектура микроконтроллера состоит совсем из других блоков, нежели ПЛИС . И связи между блоками осуществляются по постоянным магистралям(а не перепрошиваемым). Среди блоков МК можно выделить основные:

Постоянная память (ПЗУ) — память, в которой хранится ваша программа. В нее входят алгоритмы действий и константы. А так же библиотеки(наборы) команд и алгоритмов.

Оперативная память (ОЗУ) — память, используемая микроконтроллером для временного хранения данных(как триггеры в ПЛИС ). Например, при вычислении в несколько действий. Допустим, нужно умножить первое пришедшее число на второе(1-е действие), затем третье на четвертое(2 действие) и сложить результат(3 действие). В оперативную память при этом занесется результат 1 действия на время выполнения второго, затем внесется результат 2 действия. А затем оба этих результата пойдут из оперативной памяти на вычисление 3 действия.

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

Средства (порты) ввода-вывода и последовательные порты ввода-вывода — ножки микроконтроллера , предназначенные для взаимодействия с внешним миром.

Таймеры — блоки, предназначенные для подсчета количества циклов при выполнении алгоритмов.

Контроллер шины — блок, контролирующий обмен между всем блоками в микроконтроллере . Он обрабатывает запросы, посылает управляющие команды, организовывает и упорядочивает общение внутри кристалла.

Контроллер прерываний — блок, принимающий запросы на прерывание от внешних устройств. Запрос на прерывание — сигнал от внешнего устройства, информирующий о том, что ему необходимо совершить обмен какой-либо информацией с микроконтроллером .

Внутренние магистрали — трассы, проложенные внутри микроконтроллера для информационного обмена между блоками.

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

Взаимосвязь составляющих блоков микроконтроллера

В микроконтроллере , в отличии от ПЛИС , работа происходит между вышеперечисленными блоками, имеющими сложную архитектуру , облегчающую процесс разработки программ. При прошивке вы изменяете только постоянную память, на которую опирается вся работа МК.

Основное отличие ПЛИС и микроконтроллера

ПЛИС прошивается на уровне железа, практически по всей площади кристалла. Сигналы проходят через сложные цепочки транзисторов. Микропроцессор же прошивается на уровне программы для железа, сигналы проходят группами, от блока к блоку — от памяти к процессору, к оперативной памяти, от оперативной к процессору, от процессору к портам ввода-вывода, от портов ввода-вывода к оперативной памяти, от оперативной памяти… и так далее. Вывод: за счет архитектуры ПЛИС выигрывает в быстродействии и более широких возможностях конвеерной обработки, МК выигрывает в простоте написания алгоритмов. За счет более простого способа описания программ, фантазия разработчика Микроконтроллера менее скованна временем на отладку и разработку, и, таким образом, время на программирование того же робота на МК и ПЛИС будет отличаться во многие и многие разы. Однако робот, работающий на ПЛИС будет гораздо шустрее, точнее и проворнее.

Железо и программа.

В ПЛИС всю работу нужно делать самому, вручную: для того, чтобы реализовать какую-либо программу на ПЛИС , нужно отследить каждый сигнальчик по каждому проводку, приходящему в ПЛИС , расположить какие-то сигнальчики в ячейки памяти, позаботиться о том, чтобы в нужный момент именно к этим ячейкам памяти обратился другой сигнальчик, который вы так же отслеживаете или даже генерируете, и в итоге набор сигнальчиков, задержанный в памяти задействовал нужный вам сигнальчик, который, например, пойдет на определенную выходную ножку и включит светодиодик, который к ней подключен. Часть сигнальчиков идет не в память, а например на запуск определенной части алгоритма(программы). То есть, говоря языком микропрогера, эти ножки являются адресными. Например, имеем на нашей плате в нашей программе три адресные ножки для включения неких не связанных(или связанных) друг с другом алгоритмов, которые мы реализовали на языке Verilog в ПЛИС . Также в программе, кроме трех адресных ножек, у нас есть еще например 20 информационных ножек, по которым приходит набор входных сигнальчиков(например с разных датчиков) с какой-либо информацией (например температура воды в аквариуме с датчика температуры воды в аквариуме). 20 ножек = 20 бит. 3 ножки -3 бита. Когда приходит адресный сигнал 001(с трех ножек адреса) — запускаем первый алгоритм, который записывает 20 информационных сигнальчиков в 20 ячеек памяти(20 триггеров), затем следующие 20 сигнальчиков умножаем на полученные ранее 20, а результат умножения записываем в память, а потом отсылаем по другим ножкам например в терморегулятор воды в аквариуме. Но Отошлем мы этот результат только тогда, когда на наши адресные ножки придет код например 011 и запустит алгоритм считывания и передачи. Ну, естественно «отсылаем», «считываем» и еще что-то прописываем в ручную. Ведем каждый сигнальчик в каждый такт работы ПЛИС по определенному пути, не теряем. Обрабатываем или записываем. Складываем или умножаем. Не забываем записать. Не забываем принять следующий сигнал и записать в другие триггеры. Еще добавьте сюда работу, привязанную к тактовой частоте, синхронизацию (которая так же реализуется вручную), неизбежные ошибки на этапах разработки и отладки и кучу других проблем, которые в данной статье рассматривать просто бессмысленно. Трудно. Долго. Но зато на выходе работает супер оперативно, без глюков и тормозов. Железно!

Теперь микроконтроллер . 20 ножек на прием информации — для большинства микроконтроллеров физически невозможная задача. А вот 8 или 16 — да пожалуйста! 3 информационных — в легкую! Программа? По адресу 001 умножить первое пришедшее число на второе, по адресу 011 отсылай результат в терморегулятор. Все! Быстро. Легко. Не супер, но оперативно. Если очень грамотно написать программу- без глюков и тормозов. Программно!

Железо и Программа! Вот главное отличие между ПЛИС и Микроконтроллером .

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

Заключение

Современные разработчики процессоров и микропроцессоров изначально разрабатывают свои устройства на ПЛИС . Да-да, вы правильно догадываетесь: сначала они имитируют создаваемую архитектуру микроконтроллера с помощью разработки и прошивки программы на ПЛИС , а затем измеряют скорость выполнения алгоритмов при том или ином расположении имитируемых блоков МК и том или ином наборе функционала каждого блока отдельно.

По характеристикам выдаваемого сигнала, ПЛИС чаще всего рассчитана на 3,3В, 20мА, Микроконтроллер на 5В, 20мА.

Под микроконтроллер AVR, успешно внедренный в платформу Arduino, написано множество открытых программ, разработано великое множество примочек в виде датчиков, двигателей, мониторчиков, да всего, чего только душе угодно! Arduino в настоящее время больше похож на игровой конструктор для детей и взрослых. Однако не стоит забывать, что ядро этого конструктора управляет «умными домами», современной бытовой электроникой, техникой, автомобилями, самолетами, оружием и даже космическими аппаратами. Несомненно, такой конструктор будет являться одним из лучших подарков для любого представителя сильной половины человечества.

В принципе, все просто!

Остались вопросы? Напишите комментарий. Мы ответим и поможем разобраться =)


Поле, засеянное Массивами Программируемых Калиток

Начинаем курс лекций о том, что такое программируемая логика и как начать ее использовать на благо себя и ближнего своего…

ПЛИС - так ЭТО называется по-русски. П рограммируемая Л огическая И нтегральная С хема.
По-буржуйски это звучит несколько иначе - FPGA - F ield of P rogrammable G ate A rrays. Дословно это переводится как "Поле, засеянное массивами программируемых калиток."
Если быть чуть серьезнее, можно назвать это "Матрица программируемых вентилей"

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

Так вот, пусть для вас это будет откровением, но каждая микросхема состоит из вентилей. Правда, они не совсем похожи на то, что у вас и у меня в подвале. Но делают они то же самое - открываются и закрываются.

Вентиль - это элементарная составляющая любой цифровой микросхемы.

Даже самый навороченный супермегапроцессор состоит из вентилей. Их в нем много, очень много, просто целое море. Естественно, что в каждой микросхеме вентили соединены определенным образом. Собственно, от того, как они соединены, и зависит функциональность микросхемы.

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

Это в-общем.

На самом деле, все гораздо сложнее:) Смотрим на рисунок


Это есть одна макроячейка - Macrocell по-ихнему.
Каждая микросхема ПЛИС состоит из таких вот макроце… макроячеек. Как видно из схемы макроячейки, она состоит из блока Look-Up Table (LUT ) - "Просмотровой таблицы", а также, триггера с синхронными и асинхронными входами и некоторой логики по входам триггера. Программируется, собственно, только LUT. Как видите, у нее 4 входа и один выход. Этот выход может быть подан как непосредственно на выход макроячейки (Q0), так на синхронный вход данных триггера (D).

LUT - это ни что иное как ПЗУ на 16 1-битных ячеек. При подаче на входы LUT (D0…D3) некой комбинации цифровых сигналов, она воспринимает их как адрес и выдает на выход содержимое ячейки по этому адресу.

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

Таблица истинности описывает логический уровень выхода схемы (Q) для всех возможных комбинаций сигналов на входах (D0…D3). Точно так же в LUT каждой комбинации входных сигналов (читай - каждому адресу ПЗУ) сопоставлен свой выходной сигнал. То есть, в LUT прошивается таблица истинности той схемы, которую мы хотим видеть на его месте. Вот так все просто!

Если схема содержит более 4 входов или более 1 выхода - используются LUT нескольких макроячеек.

clear="all">

Но самое главное - это триггер. Ведь, как вы знаете (а может, еще не знаете), все регистры, счетчики и многие другие элементы цифровой техники состоят именно из триггеров. Так вот, количество макроячеек в микросхеме ПЛИС определяет количество триггеров. И наоборот:) Так что, выбирая микросхему для какого-либо проекта, надо предварительньно прикинуть, сколько триггеров будет в схеме, и брать с запасом…

На рисунке чуть ниже изображена структурная схема микросхем серии EPM7000 фирмы Altera Эта картинка дернута из даташита https://www.altera.com/literature/ds/m7000.pdf Она относится к микросхемам EPM7032, EPM7064, EPM7096. Дык вот, последние две цифры в названии обозначают именно количество макроячеек в микросхеме.


Как видно из схемы, макроячейки объединяются в "блоки логических массивов" (LAB - Logic Array Block).
Эти блоки соединяются между собой через "программируемый массив внутренних соединений" - programmable interconnect array (PIA).
Кроме того, LAB"ы подключаются к выводам микросхемы через блоки управления ввода/вывода (I/O Control Block).

При прошивке, в каждый из блоков "зашивается" своя информация:
- В Макроячейках программируются LUT"ы,
- в PIA зашивается информация о внутренних межблочных соединениях,
- в блоки управления ввода/вывода (I/O Control Block) зашивается информация о подключениях к ногам микросхемы.

По-серьезному, "прошивка" ПЛИС называется "загрузка конфигурации".

А как вы думаете, чем мы будем загружать конфигурацию???
Ну конечно же, старым добрым Байт Бластером! :) Байт бластер - это штука универсальная:) О том, как его сделать, подробнейшим образом я рассказывал вот



Загрузка...