Вот бывает так, что проект работает, вроде бы все нормально, но проходит время, возвращаешься к нему и находишь досадные ошибки. Сейчас речь пойдет о проекте ранее опубликованном на нашем сайте – это процессор reduced AVR.
В принципе, проблема в том проекте с самого начала была известна, и более того, на нее указывал мне лично наш читатель. В этом проекте Quartus II выдавал сообщение, что на сигнале тактовой частоты в проекте есть гейт (gate) и это якобы не хорошо:
Warning: Found 2 node(s) in clock paths which may be acting as ripple and/or gated clocks -- node(s) analyzed as buffer(s) resulting in clock skew
Info: Detected ripple clock "altufm_none0:inst13|altufm_none0_altufm_none_ghp: altufm_none0_altufm_none_ghp_component|arclkena_reg" as buffer
Info: Detected gated clock "altufm_none0:inst13|altufm_none0_altufm_none_ghp: altufm_none0_altufm_none_ghp_component|ufm_arclk" as buffer
Сказать по правде, в тот момент я не придал большого внимания этому предупреждению: работает проект да и ладно. Тем более, что исправить проблему не очень просто (позже объясню почему).
Совсем недавно другой наш читатель пожаловался, что у него не работает этот проект reduced AVR. Вы можете почитать его комментарии к статье о проекте.
Тогда уже я стал разбираться, и теперь появилось время рассказать подробнее о проблеме и ее решении.
Потом открываю этот же проект средой Altera Quartus II v11.0. Компилирую, зашиваю в плату – не работает. Как может быть, что работоспособность одного и того же проекта зависит от версии среды?
Захожу в свойства проекта и устанавливаю ему Seed=2 вместо Seed=1 для Fitter.
Свойство Seed позволяет изменить физическое расположение элементов в микросхеме. Мы не знаем точно, как элементы будут расположены в микросхеме после компиляции, но мы знаем, что при разных Seed расположение будет разным. Так вот после изменения Seed проект откомпилированный Quartus II v11.0 заработал.
Видно, что есть проблема и серьезная. Проект не стабилен и его работоспособность зависит от того, как он размещен по логическим элементам ПЛИС. Это, конечно, не хорошо.
Итак, вернемся к самому началу – предупреждению компилятора о гейте на клоке. Gate на сигнале тактовой частоты – это действительно не хорошо и может стать серьезной проблемой. На входы тактовой частоты триггеров можно / нужно подавать только сигнал с выходов других триггеров и никогда нельзя с выхода логической функции. На выходе логической функции в момент изменения ее входных сигналов, приходящих не одновременно, могут образовываться короткие пики. Если такой сигнал использовать, например, как тактовую частоту для счетчика, то каждый из пиков будет увеличивать значение счетчика.
Откуда же взялся этот странный gate в проекте? Я вроде бы нигде таких глупостей стараюсь не делать. В том проекте есть только мой модуль rAVR, написанный на Verilog и модуль ALTUFM, созданный с помощью Altera Quartus II Wizard.
Модуль rAVR – это собственно процессор, а модуль ALTUFM представляет внутреннюю флеш память ПЛИС MAX II с последовательным доступом. При этом предупреждение (Warning) квартус выдает на сигнал arclkena, который генерирует мой процессор.
Самый простой способ понять, что произошло – это откомпилировать проект и посмотреть, что получилось в RTL Viewer (Меню Tools \ Netlist Viewers \ RTL Viewer).
Вот как выглядит модуль верхнего уровня в RTL Viewer:
Давайте посмотрим, как уствоен altufm_none:
Хм... Еще один уровень.. Смотрим как устроен altufm_none0_altufm_none_ghp:
Ух ты! Что это еще такое: мы видим логическую функцию AND на входе тактовой частоты модуля UFM! Altera Quartus Wizard создал такой модуль, в котором используется AND на тактовой частоте, а потом сам же Quartus II и выдает на это безобразие предупреждение.
Моя версия такая: Altera допустила ошибку в микросхеме, забыла сделать в чипе родной сигнал arclkena для arclk. Чтобы выйти из положения они сделали обертку для ALTUFM и поставили там gate AND. Ну и действительно, что им еще оставалось делать?
Можно ли проблему решить как-то иначе и не использовать такой AND? Я боюсь, что скорее нет, чем да. По крайней мере тот оригинальный проект в общем не починить, так как там использовалась внутренняя тактовая частота из того же ALTUFM (примерно 5Мгц) и никакой другой более высокой частоты там нет.
Однако есть и хорошая новось. Сейчас на плате Марсоход есть кварцевый генератор 100Мгц, которого не было в те времена, когда я делал тот проект. Мы можем использовать внешнюю частоту, поделить ее на 10 и использовать уже 10Мгц для всего проекта. А входную частоту 100Мгц использовать для синтеза ARCLK.
Главное правило – выдать ARCLK для ALTUFM с выхода триггера.
Сейчас я сделал вот такую схему (можно кликнуть на ней, что бы увеличить):
Сам ALTUFM больше не использует вход ARCLKENA, ведь мы знаем, что он не может его правильно использовать. Поэтому его ARCLKENA теперь подключен к логической единице. Вместо этого я теперь сам синтезирую ARCLK из двух частот clock100Mhz и clk10Mhz и сигнала arclkena от модуля rAVR.
Временные диаграммы сигналов будут выглядеть примерно вот так:
Обратите внимание, что теперь активные фронты ARCLK передвинулись вперед по времени на время (t2-t1). Однако это оказалось не страшно. Сигналы передачи адреса для чтения из флеш памяти arshift и ardin успевают формироваться за время t1.
Вот теперь проект работает стабильно. Вы можете его компилировать и Quartus II v10 и Quartus II v11. Можете ставить разные Seed для различного размещения логики в микросхеме – все равно работает.
Взять новый проект можно здесь:
ЗЫ: кстати теперь процессор работает примерно в 2 раза быстрее, так как его тактовая теперь 10Мгц, а не 5Мгц.
Подробнее...