К сожалению, сильно больше, чем показано в видео, рассуждать не могу. Я всегда опытным путём под конкретный случай пытаюсь подогнать, так что теоретизировать об общих вещах, без предварительных изучений конкретного случая — сложно.
Как показано в видео — точно работает. Там есть, как войти в настройку поведения этих ножек, на что переключить, кратко видно, какие ещё варианты имеются в списках. В тексте это сложно разъяснить, именно поэтому я считаю, что первично всё-таки видео (но без текста нельзя делать публикации, поэтому он тоже нужен). Возможно, из того, что там ещё попало в кадр, можно какие-то идеи вывести под те чипы, что у Вас (для четвёртого Циклона — просто следовать этой инструкции).
А дальше — если не получается какая-то конкретика, то нужно уже под конкретный случай занудно документацию смотреть, «что там можно, что нельзя».
Посмотрел статистику продаж их и средств разработки на них и на Altera/Xilinx на Ali Express. Посмотрел предложения в отечественных конторах. Давайте сойдёмся на том, что они ещё не настолько популярны, как их загружаемые конкуренты. А статья — вообще про Альтеру. Которая на сегодняшний день в паре с Xilinx пока, вроде, популярней остальных. Усложнять фразу в основном тексте в сегодняшних реалиях — не вижу смысла. Особенно если учитывать, что дальше — даже Xilinx не рассматривается.
Ой знаком. Наши Заказчики с целью защиты от клонирования в своей плате такую использовали однажды… Вернее, они использовали с однократкой без возможности перешивки. Воспоминания — только самые ужасные.
Так или иначе, спасибо за замечание, добавил одно слово в текст. Теперь там говорится про описания на популярные FPGA.
Кстати, на самом деле, они все совместимы на чтение. Задали адрес, дальше — нам идут данные, а адрес — автоинкрементируется. А вот на запись — у них действительно могут быть всякие несовместимости по размеру страницы и прочему. Не даром же приходится заполнять конфигурационный файл. Почему нельзя его заполнять для штатного GUI-программатора — вопрос открытый.
Тоже вариант. Но, в целом, как видим, можно воспользоваться и фирменными Альтеровскими вещами, которые всё равно установились, просто их надо несколько извратно вызывать.
Но на самом деле, готовим прошивальщик — один раз на жизнь схемы и ей подобных схем.
Готовим файл под прошивку — единожды на версию, так как всё равно при отладке он льётся прямо в ПЛИС, на то она и отладка. Причём готовить — что этим способом, что мышкой давить — и там и тут надо кучку действий выполнить.
Ну, и дальше — только кто платы прошивает, должен будет ввести заклинание один раз за смену против трёх движений мышкой. Потом — просто «Вверх, Enter» нажимать.
Скорее всего, не проверяет, что логично, ведь в целом — нет жёсткого требования, какой ёмкости конфигуратор использовать для конкретного кристалла. Главное — чтобы этой ёмкости хватило. По крайней мере, всё работает именно с 32-й флэшкой, а EPCS — бывает 16, бывает 64 и далее — уже вверх. А 32 — не бывает. И всё работает. Проверено.
За комментарий по подключаемым файлам — спасибо. Век живи — век учись. Буду пробовать.
Беру свои слова обратно. Не отмоделируется… Чтобы отмоделировалось (я играл с последним примером) надо добавить начальную инициализацию переменной iter. В ПЛИС же она чему-то, да равна, а длина перебора — 4 такта. В модели же к неизвестно чему прибавляем единицу — будет опять неизвестно что. Так что
Ну, а там видно, что изменение состояния кнопки (я выделил их жёлтым) даст «разбегающееся» изменение состояния ножек. С какой ножки начнётся разбег — зависит от того, в какой момент кнопку нажали (на то он и Round Robin)
Кажется, я понял, где мы друг друга не понимаем. Давным-давно я прослушал курсы по программированию ПЛИС на VHDL, где нас как раз на ActiveHDL обучали. Изучили мы язык, набрались опыта, наделали лабораторных работ… И вот добыл я свою первую ПЛИС (тогда их было добыть достаточно сложно, из Швеции привёз), начинаю делать под неё первую прошивку… И на меня сыплется гора ошибок. Гружу в систему моделирования — всё прекрасно работает.
Оказалось, что нас забыли предупредить, что есть язык, а есть — его синтезируемое подмножество. И только жалкая часть языковых конструкций будет синтезирована. Да и там — тоже свои заморочки (например, управлять сигналом можно только из одного процесса). Пришлось потратить месяц, чтобы изменить стиль разработки.
Большинство обзорных статей про SystemVerilog едины по стилю. Сначала идёт рассказ о новых вещах, как они прекрасны. Затем — комментарий: «А это вообще синтезируемо?». И дальше — обычно разговор сходит на общие темы. Вот я и решил выбрать красивых вещей и проверить:
1) Насколько они синтезируемы
2) Насколько оптимален результат синтеза конкретно массивов с индексацией «на лету»
Результаты — в статье. И именно поэтому моделирование самого языка для данной статьи бесполезно. Оно сработает, куда ж оно денется? Моделировать пришлось бы на уровне вентилей после упаковки в ПЛИС. Осциллограмма — это практически то же самое. Но глядя на результаты моделирования, скептики у нас сказали бы, что этому верить можно, но с натягом, а вот то, что видно на осциллографе — оно видно на осциллографе. Это уже физическая вещь.
Посему в данной конкретной статье осциллограммы — более приемлемы.
Я моделирую в ModelSim Altera, так как она совершенно бесплатная. Ну, или в ISIM, если работа идёт с Xilinx (хоть они и не рассматривались в данной статье). ActiveHDL — на заре тысячелетия изучал, но «париться» с ломанными версиями при наличии совершенно бесплатных и встроенных в систему разработки — а смысл?
Но в рамках рассмотренной проблематики — проверять надо, как оно синтезируется, а Gate Level моделирование — замутное. Проще было осциллографом убедиться. Тем более, что хотелось именно реальные результаты увидеть.
Ну, если чисто формально, то какие именно — подписано под рисунком. Слово «Задача» там есть. А мельчить на самом рисунке — есть ли смысл? Или наоборот, загромождать всё, отбирая место у стрелок.
Поправка: Перечитал. Автор говорит, как делит частоту. Но зато ещё он говорит, что осциллограф работает почти на пределе частотного диапазона. А я после этой ночи чего-то перестал доверять показаниям китайских осциллографов на высоких пределах. Я вёл проверку сразу двумя. У обоих полоса 250 МГц, дискретизация — у одного 1ГГц, у второго — целых 2 ГГц (разумеется, прямая, а не стробоскоп). Но похоже, там АЦП в таком режиме работает, что лучше конкретные импульсы было не измерять…
В общем, на уменьшенных частотах всё у меня сошлось (8 тактов с NOP, 6 тактов без NOP дают 21 и 28 МГц соответственно), а у автора по ссылке всё может оказаться не строго 84 МГц, так как RIGOL — тоже китайская марка. И он работает без курсоров, на предельных частотах этого осциллографа… Но чем больше записей в порты на итерацию, тем ближе будет частота именно к 84 МГц. Однако, к обсуждаемому тексту, это уже не имеет никакого отношения.
Не вижу никаких противоречий. Он писал много раз на итерацию, как и я в ночном эксперименте. В основном же примере, я пишу 1 раз на итерацию, и 4 такта каждый раз тратится на переход. Ну, потому что у меня немного другая задача, мне надо показать, как работает ОС, а не как добиться максимальной частоты. Хотя, факты катастрофической просадки «ниоткуда» я и отмечаю.
Чтобы закрыть тему окончательно и бесповоротно (судя по оценкам, она нравится не всем), я сделал следующее: Как и ночью, увеличил делитель частоты на 16, чтобы попасть в область точных измерений моего осциллографа. Убедился, что тратится 8 тактов на итерацию.
Получил следующую осциллограмму в чёткой области работы осциллографа:
Напомню, 1 такт равен примерно 95.2 нс. Здесь чётко видно, что сначала имеем взлёт на 1 такт (запись единицы), затем — падение на 1 такт (запись нуля). Затем — взлёт на 3 такта (запись единицы + NOP), затем — падение на 5 тактов (запись нуля + ветвление).
Итого, в примере из моего основного текста имеем взлёт (1) NOP (ничего не знаю, чётко видно, что 2), падение (1), ветвление (4). 1 + 2 + 1 + 4 = 8. 168/8 = 21. Всё сходится.
Если писать много раз за итерацию — да, будет почти 84. До первого ветвления, которое у автора по ссылке не попало на экран (тем более, что он пишет, что осциллограф ловит сигнал, уже поделённый в ПЛИС, как именно он там делится — не говорит).
Нет, не могу уснуть. Провел ещё одно исследование, которое несколько подмывает официальные документы, но зато никак не противоречит моему основному трактату. Итак. Чтобы сделать красивые фронты на моём осциллографе, делим частоту на 16. 168000000/16=10500000, один такт примерно 95.2 нс.
Один, один, один такт на состояние! Чушь какая-то!
Тем не менее, видны вот такие чёткие пачки
у которых провал равен пяти тактам. Один такт на состояние и четыре — на ветвление. В целом, не противоречит документу, где сказано 1+P, P зависит от Pipeline, и может быть до трёх. То есть, 1+3 = 4. Оставляем один переброс на итерацию, провал как был, так и есть пять тактов
Получаем одно подтверждение (ветвление 4 такта) и одно противоречие (GPIO работает за один такт). Возвращаем частоту на 168 МГц
1 такт равен 5.95 нс. У нас явно два такта! Два, два, два! А поменяна только частота. Вернее, делитель частоты. И ничего больше. В нуле находится 5 тактов. Я измерял на более крутом стационарном осциллографе.
Получается, что запись идёт 2 такта, но если буфер занят (две записи подряд) — ждём, если свободен (после записи идёт ветвление) — продолжаем работать. Но всё это — только на предельной частоте.
В общем, спишем это всё на то, что система как-то определяет, что работает на высокой частоте и добавляет лишний такт при записи в порт. Иного объяснения я не вижу. Возможно, это касается только отдельных чипов, так как я уже ловил несоответствие моего F429 более новым. Там DWT по умолчанию по-разному настроен, знаменитая ошибка с приёмом младшего бита в SPI по-разному проявляется/не проявляется. Может и тут что-то такое.
Но как видим, это — практическое поведение чипа, а не грубый ляп в моём повествовании. Надеюсь.
Вообще, эти ARMы всех запутать хотят. Перечитал процитированное ранее. Не очень убедительно. Но ниже они пишут
•Other instructions cannot be pipelined after STR with register offset. STR can only be pipelined when it follows an LDR, but nothing can be pipelined after the store. Even a stalled STR normally only takes two cycles, because of the write buffer.
И в другой таблице — чётко пишут, что 2 цикла и всё тут.
Все описания касаются именно Cortex M4. То есть, обсуждаемой архитектуры.
8.2 GPIO main features
…
• Fast toggle capable of changing every two clock cycles
Запись в GPIO у STM32F4 требует двух тактов. Тогда понятно, что в описании команды STR срабатывает оговорка:
STR Rx,[Ry,#imm] is always one cycle. This is because the address generation is performed in the initial cycle, and the data store is performed at the same time as the next instruction is executing. If the store is to the write buffer, and the write buffer is full or not enabled, the next instruction is delayed until the store can complete. If the store is not to the write buffer, for example to the Code segment, and that transaction stalls, the impact on timing is only felt if another load or store operation is executed before completion.
Почему «почти просто » — команда NOP не должна исполняться два такта. Но спишем это на какие-то особенности, вытекающие из выше сказанного, с учётом гарвардской архитектуры. Тем более, что реально скважность не строго 50%, как выяснилось при снижении частоты шины (я много экспериментировал сейчас). Тем не менее — кажущиеся глобальные странности разрешены. И они не относятся ни к проблемам ОС, ни к проблемам повествования. Просто я нашёл ссылки на официальные документы, говорящие, что это — совершенно нормальное поведение программы. Теперь можно спать спокойно.
Согласно описанию STM32F4, если делитель APB не равен одному, то частота на таймеры удваивается. Получем (168/4)*2 = 84. Дальше делитель таймера 1000, итого 84 КГц. Тут всё верно.
Так что проблема работы с GPIO не в настройке PLL. Где-то ещё возникает деление на два. Потому что 21*4 = 28 * 3 = 84. Всё работает на 84 МГц. Можно было бы сказать, что перед нами такт на выборку и такт на запись, но все книжки говорят про Гарвардскую архитектуру…
В общем, в тексте моего руководства, вроде, особых ляпов больше нет, я там убрал неверное утверждение. Но задачку Вы задали интересную. Если разберусь, то напишу.
Как показано в видео — точно работает. Там есть, как войти в настройку поведения этих ножек, на что переключить, кратко видно, какие ещё варианты имеются в списках. В тексте это сложно разъяснить, именно поэтому я считаю, что первично всё-таки видео (но без текста нельзя делать публикации, поэтому он тоже нужен). Возможно, из того, что там ещё попало в кадр, можно какие-то идеи вывести под те чипы, что у Вас (для четвёртого Циклона — просто следовать этой инструкции).
А дальше — если не получается какая-то конкретика, то нужно уже под конкретный случай занудно документацию смотреть, «что там можно, что нельзя».
Так или иначе, спасибо за замечание, добавил одно слово в текст. Теперь там говорится про описания на популярные FPGA.
Но на самом деле, готовим прошивальщик — один раз на жизнь схемы и ей подобных схем.
Готовим файл под прошивку — единожды на версию, так как всё равно при отладке он льётся прямо в ПЛИС, на то она и отладка. Причём готовить — что этим способом, что мышкой давить — и там и тут надо кучку действий выполнить.
Ну, и дальше — только кто платы прошивает, должен будет ввести заклинание один раз за смену против трёх движений мышкой. Потом — просто «Вверх, Enter» нажимать.
Не так и сложно, как оказалось.
За комментарий по подключаемым файлам — спасибо. Век живи — век учись. Буду пробовать.
На что мне было сказано:
Вывод: Чекает! Ну, и второй вывод — не зря я всё-таки вёл осмотр возможностей на самой свежей версии.
Тогда вот такая моделька
даст такую картинку
Ну, а там видно, что изменение состояния кнопки (я выделил их жёлтым) даст «разбегающееся» изменение состояния ножек. С какой ножки начнётся разбег — зависит от того, в какой момент кнопку нажали (на то он и Round Robin)
Оказалось, что нас забыли предупредить, что есть язык, а есть — его синтезируемое подмножество. И только жалкая часть языковых конструкций будет синтезирована. Да и там — тоже свои заморочки (например, управлять сигналом можно только из одного процесса). Пришлось потратить месяц, чтобы изменить стиль разработки.
Большинство обзорных статей про SystemVerilog едины по стилю. Сначала идёт рассказ о новых вещах, как они прекрасны. Затем — комментарий: «А это вообще синтезируемо?». И дальше — обычно разговор сходит на общие темы. Вот я и решил выбрать красивых вещей и проверить:
1) Насколько они синтезируемы
2) Насколько оптимален результат синтеза конкретно массивов с индексацией «на лету»
Результаты — в статье. И именно поэтому моделирование самого языка для данной статьи бесполезно. Оно сработает, куда ж оно денется? Моделировать пришлось бы на уровне вентилей после упаковки в ПЛИС. Осциллограмма — это практически то же самое. Но глядя на результаты моделирования, скептики у нас сказали бы, что этому верить можно, но с натягом, а вот то, что видно на осциллографе — оно видно на осциллографе. Это уже физическая вещь.
Посему в данной конкретной статье осциллограммы — более приемлемы.
Но в рамках рассмотренной проблематики — проверять надо, как оно синтезируется, а Gate Level моделирование — замутное. Проще было осциллографом убедиться. Тем более, что хотелось именно реальные результаты увидеть.
В общем, на уменьшенных частотах всё у меня сошлось (8 тактов с NOP, 6 тактов без NOP дают 21 и 28 МГц соответственно), а у автора по ссылке всё может оказаться не строго 84 МГц, так как RIGOL — тоже китайская марка. И он работает без курсоров, на предельных частотах этого осциллографа… Но чем больше записей в порты на итерацию, тем ближе будет частота именно к 84 МГц. Однако, к обсуждаемому тексту, это уже не имеет никакого отношения.
Чтобы закрыть тему окончательно и бесповоротно (судя по оценкам, она нравится не всем), я сделал следующее: Как и ночью, увеличил делитель частоты на 16, чтобы попасть в область точных измерений моего осциллографа. Убедился, что тратится 8 тактов на итерацию.
Дальше, модифицировал код следующим образом:
Получил следующую осциллограмму в чёткой области работы осциллографа:
Напомню, 1 такт равен примерно 95.2 нс. Здесь чётко видно, что сначала имеем взлёт на 1 такт (запись единицы), затем — падение на 1 такт (запись нуля). Затем — взлёт на 3 такта (запись единицы + NOP), затем — падение на 5 тактов (запись нуля + ветвление).
Итого, в примере из моего основного текста имеем взлёт (1) NOP (ничего не знаю, чётко видно, что 2), падение (1), ветвление (4). 1 + 2 + 1 + 4 = 8. 168/8 = 21. Всё сходится.
Если писать много раз за итерацию — да, будет почти 84. До первого ветвления, которое у автора по ссылке не попало на экран (тем более, что он пишет, что осциллограф ловит сигнал, уже поделённый в ПЛИС, как именно он там делится — не говорит).
Переписываем программу вот так
Получаем вот такие импульсы
Один, один, один такт на состояние! Чушь какая-то!
Тем не менее, видны вот такие чёткие пачки
у которых провал равен пяти тактам. Один такт на состояние и четыре — на ветвление. В целом, не противоречит документу, где сказано 1+P, P зависит от Pipeline, и может быть до трёх. То есть, 1+3 = 4. Оставляем один переброс на итерацию, провал как был, так и есть пять тактов
Получаем одно подтверждение (ветвление 4 такта) и одно противоречие (GPIO работает за один такт). Возвращаем частоту на 168 МГц
1 такт равен 5.95 нс. У нас явно два такта! Два, два, два! А поменяна только частота. Вернее, делитель частоты. И ничего больше. В нуле находится 5 тактов. Я измерял на более крутом стационарном осциллографе.
Получается, что запись идёт 2 такта, но если буфер занят (две записи подряд) — ждём, если свободен (после записи идёт ветвление) — продолжаем работать. Но всё это — только на предельной частоте.
В общем, спишем это всё на то, что система как-то определяет, что работает на высокой частоте и добавляет лишний такт при записи в порт. Иного объяснения я не вижу. Возможно, это касается только отдельных чипов, так как я уже ловил несоответствие моего F429 более новым. Там DWT по умолчанию по-разному настроен, знаменитая ошибка с приёмом младшего бита в SPI по-разному проявляется/не проявляется. Может и тут что-то такое.
Но как видим, это — практическое поведение чипа, а не грубый ляп в моём повествовании. Надеюсь.
И в другой таблице — чётко пишут, что 2 цикла и всё тут.
Все описания касаются именно Cortex M4. То есть, обсуждаемой архитектуры.
Запись в GPIO у STM32F4 требует двух тактов. Тогда понятно, что в описании команды STR срабатывает оговорка:
Почему «почти просто » — команда NOP не должна исполняться два такта. Но спишем это на какие-то особенности, вытекающие из выше сказанного, с учётом гарвардской архитектуры. Тем более, что реально скважность не строго 50%, как выяснилось при снижении частоты шины (я много экспериментировал сейчас). Тем не менее — кажущиеся глобальные странности разрешены. И они не относятся ни к проблемам ОС, ни к проблемам повествования. Просто я нашёл ссылки на официальные документы, говорящие, что это — совершенно нормальное поведение программы. Теперь можно спать спокойно.
Получаем 84 КГц
При том, что
Согласно описанию STM32F4, если делитель APB не равен одному, то частота на таймеры удваивается. Получем (168/4)*2 = 84. Дальше делитель таймера 1000, итого 84 КГц. Тут всё верно.
Так что проблема работы с GPIO не в настройке PLL. Где-то ещё возникает деление на два. Потому что 21*4 = 28 * 3 = 84. Всё работает на 84 МГц. Можно было бы сказать, что перед нами такт на выборку и такт на запись, но все книжки говорят про Гарвардскую архитектуру…
В общем, в тексте моего руководства, вроде, особых ляпов больше нет, я там убрал неверное утверждение. Но задачку Вы задали интересную. Если разберусь, то напишу.