Pull to refresh

Comments 25

У вас первый модуль должен не Delay называться, а Divider — это делитель тактовой частоты для получения сигнала с периодом 1 секунда.
Не добавите в статью результаты симуляции для вашего кода, желательно помодульно — состояние входов, выходов?


ПС так и хочется продемонстрировать, что такое сегодня возможно сделать вообще без знаний Verilog/VHDL с помощью Матлаба/Симулинка в полностью графическом виде, с полной симуляцией и скорей всего быстрее. Получится намного проще и наглядней. Интересно? Сесть за статью?

Согласен, divider подходит больше. Симуляцию для кода постараюсь добавить завтра, но это не точно, посмотрю как со временем завтра будет. А статью если напишите, я с удовольствием почитал бы :)
Можно и в Quartus в графическом виде. Логические компоненты, проводки… Но, скорее всего, вы имели в виду другое.
Добавил временную диаграмму в статью.
такое сегодня возможно сделать вообще без знаний Verilog/VHDL с помощью Матлаба/Симулинка в полностью графическом виде

А что с этим дальше делать? В железку можно залить результат?
Да. Simulink порождает исходный код.
Другое дело что в данном случае это будет операция на глазе через ж*.
Такой подход оправдан, когда Вы делаете на FPGA ЦОС — всякие фильтры и прочее такое.
Ну и глобально — владение такими средствами проектирования — это бонус, который не отменяет необходимости знания HDL языка.

Не согласен. Сегодня Simulink дает достаточно оптимальный код и с точки зрения быстродействия и с точки зрения ресурсов. Мало того, разработчик может легко сам поменять приоритеты при генерации кода, чтобы, например, сделать полностью параллельную схему, но занимающую большую площадь, или с мультиплексированием с разделением по времени.
Попробуйте сделать то же самое на Verilog/VHDL, если вдруг окажется, что проект не пролазит по размеру или частоте — пол кода придется переписать.


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

Попробуйте сделать то же самое на Verilog/VHDL, если вдруг окажется, что проект не пролазит по размеру или частоте — пол кода придется переписать.

Я делал это периодически с достаточно грузными IP-блоками. Причем в основном я занимался различного рода неблокирующими маршрутизаторами интерфейсов с 100% hardware offload. На такое применение данные пакеты ну совсем не кладутся.
К тому же я имел в виду кейс написания обсуждаемой прошивки.
Касательно «не проходят по частоте». По частое обычно не пролазят какие-то конкретные участки, где наворочено 100500 уровней логики и все это в том же такте заводится в какой-нить BRAM. Это все локализуемо и исправляемо. Вот прям глоабально все переписывать приходилось когда заказчик решал идеологию поменять, или добавить какую-то незначительную на его взгляд поправку в интерфейс.
Второй типовой случай не прохождения по частоте — это когда Вы сожрали все макроблоки, которые имеют фиксированные точки размещения — и синтезатор просто не может оптимально их разместить. Например съели всю память, а долбитесь в нее со всех концов ПЛИС, а она вся в 2х локациях собрана.
Нет — я не против Матлабов, Симлинков и IP-интеграторов. И даже почти не против HLS. Просто я эти вещи рассматриваю как дополнительные скиллы. Вот не владея ими можно писать что угодно. Хоть процессорные ядра. А не владея HDL (хотя бы одним) — писать что угодно — нельзя.
Я с темой оптимизации не сталкивался, но возник такой вопрос. На сколько я понял Quartus тоже умеет оптимизировать код (поправьте, если не прав), оптимизирует ли Simulink код для Altera лучше, чем Quartus?

Если использовать Simulink HDL Coder, то нет. Код будет кросс-платформенным и полностью написанным на стандартном VHDL или VERILOG. То есть его можно будет запихнуть и в altera и Xilinx и он везде скомпилируется, но при этом использование специальных фич на данном кристалле будет зависеть полностью от синтезатора — сможет ли он, например, распознать в исходном коде умножитель и запихнуть его в соответствующий Hardware блок или нет? Как правило простые вещи, как умножители, память, синтезаторы распознают неплохо и используют по мере возможности железные блоки. Но далеко не во всех случаях и проблема в том, что разработчик не всегда имеет возможность повлиять на решение синтезатора использовать логику или железный блок. Приходится придумывать уловки.


Если же использовать более специализированные тулбоксы для Simulinka (для Xilinx это System Generator, для Altera это DSP Builder), то там уже появляются оптимизированные блоки, которые хорошо ложатся на конкретную плисину и используют ресурсы, доступные только в данной модели. А в случае с умножителями или памятью дизайнеру даже предоставляется выбор из нескольких опций — использовать железный блок, логику, LUT и т.д. То есть здесь оптимизации более гибкие.

Интересно? Сесть за статью?

Конечно да. Садитесь)
Как там первая реализация называлась, 155ИД1?
К155ИД1, ИД3, ИД10 не семисегментные, а позиционные.

Я совсем дилетант в верилоге, и меня всегда интересовало слелдующее: насколько оптимально то, что генерируется по Verilog коду? Например, делитель — двоичный счетчик, последовательность триггеров. А код автора код практически как на обычных императивных языках. Что получится в итоге? Поэтому есть ряд вопросов:


  • Насколько правильно так вообще писать?
  • Какие есть правила написания эффективного verilog-кода?
Оптимальность результата зависит от того насколько правильно программист понимает что получится в результате синтеза его кода.
По делителю: вот эти строчки:
generic (delay_cnt: integer);
...
variable clk_cnt: integer range 0 to delay_cnt := 0;
...
        if(rising_edge(clk)) then
            clk_cnt := clk_cnt + 1;			

фактически и являются цепочкой последовательно соединенных триггеров в количестве integer (если не ошибаюсь, это 32), первый из которых «щелкает» по фронту clk :) Точнее, первые две строчки синтезируют цепочку триггеров, а две последние подключают к первому из этих триггеров сигнал клока. Синтезатору дано в коде прямое указание на это, никак иначе он трактовать и синтезировать не сможет.
Фактически, если понимаешь что делаешь, то VHDL, Verilog — это ассемблер для FPGA. У каждого кода будет вполне предсказуемый результат синтеза. Но если не очень понимаешь, то запросто пройдешься по массе способов отстрелить себе обе ноги :)
Что касается оптимальности по быстродействию и объему, то тут уже зависит не только от искусства программирования, но и от знания архитектуры конкретной FPGA, от умения правильно вручную расположить разные блоки на «карте» чипа, распределить клоки, задействовать аппаратные возможности и т.п.
Не соглашусь с Вашим описанием счётчика.
То, о чём Вы говорите (цепочка триггеров, на первый из которых подан тактовый сигнал) — это Асинхронный счётчик, или счётчик пульсаций, где каждый последующий бит тактируется предыдущим, и просто щёлкает в два раза реже. Его огромный недостаток — состоит в том, что биты на выходе встают в новое состояние последовательно, а не одновременно. Синтезировать такую конструкцию можно, видимо, только используя generate. А потом к ней ещё констрейны писАть, чтобы синтезатор знал, как тактировать триггеры…
У автора же описан обычный синхронный счётчик, т.е. все биты clk_cnt затактированы сигналом clk. А к выходу регистра подключена асинхронная логика, вычисляющая "+1", и подающая на его же вход. А дальше — цифровой компаратор. На мой взгляд, оптимальнее было бы поставить компаратор на строгое равенство: он проще, меньше и быстрее, а значения счётчик всё равно перебирает последовательно.
Да, Вы правы про триггеры, это я ступил :) Давно уже не занимался плисками…
Отимальнее, только собирать из макроблоков, но с таким кодом тяжело работать людям непосвященным. Я как-то таким образом написал автомат тренинга DDR (тюнинг элементов задержки на буферах) процентов на 70. Пришлось — так как иначе просто не растаскивалось по таймингам. Этот код люди даже открывать боятся, не то что править. Благо работает.
Еще оптимальность зависит от особенностей FPGA
Пример 1:
Есть такое понятие как Unique Controlling Set. Обычно это набор сигналов Set/Reset/Clock. Этот набор заходит в логический блок и все триггеры внутри него управляются этим уникальным набором и никаким другим. То есть логика @(posedge CLK) и логика @(posedge CKL or negedge nRST) обречены располагаться в разных блоках. Один несчастный регистр с уникальным набором сожрет целую ячейку со всем ее фаршем. Количество уникальных наборов прямо влияет на оптимальность размещения и утилизацию. На больших проектах оптимизация управляющих наборов дает весьма заметные результаты.
Пример 2.
ЛОгические генераторы в FPGA Xilinx имеют 6 входов. Соотвественно логика A = C1 | C2 & C3 & C4 | C5 & C6 — займет один логический генератор, а когда туда добавляется C7 — скорее всего три генератора и два уровня логики. А логика с двумя условиями будет иметь ту же утилизацию, что и с 6ю. Понимая это можно оптимизировать код. Например можно ориентироваться где выткать регистры. То есть если Вы ушли за пределы одного логического генератора и Вас не жмет latency — имеет смысл отбиться регистром. И наоборот — выткать регистры между кусками логики менее чем с 6ю условиями — бесполезное увеличение latency и поедание ресурсов.
Пример 3.
Блочная память. Количество элементов блочной памяти обычно ограничено как по количеству так и по расположению в ПЛИС. Если бездумно жрать её не обращая внимания на размерность блоков и их особенности — закончиться она очень быстро и размещаться будет очень не оптимально.
Пример 4
***
сотни их. Мораль в том что надо читать даташиты на ПЛИСы.
Еще кстати есть такой момент как энергоэффективность.
Чтобы ПЛИС поменьше жрала — нужно:
1. Все что имеет входы EN — держать под EN только когда надо.
2. Писать логику так, чтобы регистры не переключались просто так, то есть чтобы все имели какой-то «if». Так как потребление в основном обусловленно тем — каким током и как часто внутренние блочки заряжают друг другу входную емкость в момент смены своих состояний. Ну и от SLEW_RATE настроек выходных каскадов — смысл тот же, просто емкость снаружи по отношению к ПЛИС.

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


Например bcd_to_7seg синтезатор наверняка зафигачит, как look-up-table, которую вы можете получить и с помощью LUT и используя block ram. При этом в исходном коде я бы тоже написал тупо таблицу, а не AND/OR.

UFO just landed and posted this here
Мечтаю сделать полностью аппаратный PWM контроллер для кулера. На вход ему кол-во оборотов + последовательный вход с тахометра, на выходе — PWM на pin для мотора.
Это не полностью аппаратный, так как кто-то же должен количество оборотов задать.
Полностью аппаратный — это когда на вход температура и конфиг на бутстрапах или флэшке.
Готовый чип с таким функционалом называется Hardware Monitor, стоит 6 баксов и стоит в любой материнской плате. Они конечно все подруливаются программно, но многие имеют небольшую энергонезависимую память внутри (точнее некоторые регистры бывают non-volatile), либо как вариант имеют куски, запитанные от VBAT, и будучи один раз настроены могут в дальнейшем работать полностью автономно. Как правило имеют в ассортименте 2-3 стратегии управления фанами и настойку зонирования.
Остальное там пару лапок или i2c или UART для того что бы было что закинуть в управляющий регистр. Именно этот блок мне почему то не даёт покоя как это делается полупрограммно в stm32-M0, или не разобрался. Но даже если так — то всё равно интересно самому как реальная задача.
То что вы описали, иногда гуглю в надежде что, что-то появилось. Готового и адекватного по цене — не вижу пока, всё равно тот же stm32f030p4 (~$0.3 TSSOP-20)- на вскидку там если часть каналов управления программно делать, то 5-6 каналов таких получится. 1 ADC -> 1 PWM, +UART/i2c
ps был когда то трёхногий чип в то-92 с шим выходом и сам термометром на линейку фиксированных температур с шагом в 5С и с шириной _плавной_ регулировки (а не ON/OFF которых полно) в 5С, но я даже сейчас не могу его название найти, что это было
Интересно было бы сравнить с дешифратором на PROM, например на 155ре3. По сложности получившейся схемы и току потребления.
Sign up to leave a comment.

Articles