У меня есть элемент IO с отображением в памяти в моей FPGA (точнее, элемент AXI GPIO, который в основном отображает интерфейс AXI Memory-Mapped на набор контактов), который подключен и сопоставлен с адресным пространством процессора ARM посредством Мастер порт GP0. И FPGA, и процессор ARM являются частью устройства семейства ZYNQ7000. Когда я пишу по адресу элемента, где я должен искать документацию или каков общий механизм, чтобы гарантировать, что схема «видит» эту запись? Давайте предположим, что у меня есть эта последовательность записей в volatile
отображаемая в память переменная port
port = 0;
port = 1;
Тогда как я могу гарантировать, что для одного цикла 10 нс синхронизированный процесс (VHDL, если это имеет какое-либо значение) видит 0
и для более позднего цикла синхронизированный процесс видит 1
? В идеале это было бы для следующий цикл, если это возможно. Для первого подхода я бы просто подождал достаточно длительных циклов ЦП (используя счетчик циклов). Но это выглядит довольно «жестоким» способом ведения дел.
Для MMIO в целом: нет «как долго» для записи, которая будет видна. Если вы сделаете запись, она отправится в автобус. Если вы сделаете еще одну запись, она отправится в автобус позже. (Предполагая отображение без кэширования, без объединения записей для диапазона MMIO). Если устройству на другом конце шины требуется некоторое время для обработки записи, то это обычно решается опросом устройства.
Я не совсем понимаю ваш конкретный случай, но, поскольку вы говорите, что он действует как периферийное устройство GPIO, я предполагаю, что это очень просто и что сторона FPGA не видит записи как события на шине, она просто видит «Линии GPIO» меняют состояние. Учитывая это, у вас есть несколько вариантов:
Ничего не делать. Две записи должны поразить периферийное устройство GPIO, разделенное по крайней мере одним циклом шины, и если это достаточно хорошо (то есть GPIO не требует никакого времени удержания, а один цикл шины достаточно длинный), то это достаточно хорошо.
Вставьте чтение порта между двумя записями. Это должно добавить дополнительный поворот автобуса.
Просто подождите, как вы предложили в своем вопросе. Это совершенно нормально, когда дело доходит до аппаратного обеспечения, и 10 нс не так уж долго.
Есть еще одна проблема, не упомянутая в предыдущем ответе. Вставки чтения перед записью недостаточно, особенно если местоположение затенено. В этом случае возможно, что две последовательные записи могут достичь пункта назначения не в порядке. Вот почему ядра ARM имеют специальные инструкции по защите.
В идеале это было бы для следующего цикла
Вы не можете делать такие предположения. Вам нужно проанализировать конкретный случай и выбрать подходящий метод
Почти на любом микроконтроллере, имеющем периферийное устройство «внешняя шина памяти», это периферийное устройство будет автоматически блокировать любые запросы чтения ЦП до тех пор, пока данные не станут доступными, либо будет блокировать любые запросы записи ЦП до их завершения, либо остановит любую операцию, следующую за записью. запрос, пока этот запрос не будет завершен. Обратите внимание, что операции на внешней шине могут быть упорядочены только относительно друг друга, а не относительно другой памяти или устройств в микроконтроллере. Например, если есть сопоставленное с памятью периферийное устройство по адресу 0xABCD1234, и код записывает вывод 1 в GPIO A0, затем записывает данные на это периферийное устройство, а затем записывает вывод A1 в GPIO A1, эффекты периферийной записи могут произойти до того, как запись в A0, или после записи в A1, или между двумя операциями на портах ввода / вывода. Использование инструкций по защите памяти может помочь обеспечить последовательность, но на самом деле ничто не заменит чтение таблиц данных. Барьер памяти в ARM может гарантировать, что запись на внешнюю шину завершится до выполнения инструкции, которая устанавливает порт ввода-вывода, но если внешнему оборудованию требуется два цикла для выполнения действия в ответ на запись на шину (что весьма необычно), Операция на порте ввода / вывода может все еще произойти сначала.