Невозможно получить доступ к Znyq AXI BRAM из Linux

В моем проекте данные записываются в BRAM (сгенерированный с помощью IP-генератора Block Ram) с пользовательского IP-адреса. Затем я использую контроллер AXI BRAM, чтобы связать память с шиной AXI и сделать ее доступной для Linux, работающего на ARM.

Базовый адрес для контроллера - 0x4200_0000 с диапазоном 8K (до 0x4200_1FFF). Память также имеет 8K позиций, каждая шириной 32 бита.

Чтобы убедиться, что проблема доступа не связана с данными, сгенерированными в моем настраиваемом IP-адресе, я инициализирую память, просто нумеруя каждый из 8К-адресов (таким образом, адрес 1 содержит 0x01 и т. Д. До 0x1fff).

Проблема возникает при попытке прочитать эти значения из Linux. С помощью devmem 0x42000001 в командной строке возвращает 0x04000000 и следующее:

Alignment trap: devmem (1257) PC=0x0001ca94 Instr=0xe7902005 Address=0xb6f9d2fd FSR 0x011

Похоже, что Linux ожидает, что каждое значение адреса будет отображаться в байте, а не в 32-битном слове. Выравнивание ловушек происходит до devmem 0x42000004, который возвращает 0x00000004, правильное значение для четвертого направления, но значения в адресах, не кратных 4, не могут быть доступны. devmem 0x42000002 возвращает 0x00040000 (обратите внимание на смещение 0x04), а также ловушку выравнивания. Я обнаружил проблему с моим оригинальным скриптом Python, который использует mmap для отображения /dev/mem: мне нужно прочитать каждые 4 значения адреса, так как каждый отдельный адрес отображается в байт, но это означает, что я получаю только одно из каждых четырех значений.

Любые идеи о том, как правильно взаимодействовать с контроллером AXI и памятью за ним?

******* Редактировать, чтобы уточнить проблему, которая у меня есть. Если сомневаетесь, добавьте картинку:

Рисунок вопроса

1 ответ

Похоже, что Linux ожидает, что каждое значение адреса будет сопоставлено с байтом

Это стандартное отображение во всех современных процессорах. Когда вы используете AXI с шиной данных шире, чем на 8 бит, нижние биты адреса выбирают байт из шины данных AXI. Перейдите на веб-сайт ARM и загрузите спецификацию AXI.

Базовый адрес для контроллера - 0x4200_0000 с диапазоном 8K (до 0x4200_1FFF). Память также имеет 8K позиций, каждая шириной 32 бита.

Это неправильно, 8K из 32 битов имеют диапазон адресов 8K*4 = 0x0000 .. 0x7FFF.

Я предлагаю вам пересобрать BRAM, но использовать другие параметры для генератора Block Ram IP.


Я изменил RAM так, чтобы порт, выставленный контроллеру AXI, работал с 8 битами......

Ваша шина Zynq AXI, вероятно, имеет ширину 32 бита. Таким образом, стандартная подключенная память должна иметь ширину 32 бита, где вы должны иметь возможность побайтовой записи.
Если вы подключите 8-битную память к 32-битной шине и не измените адрес или неправильно адаптируете его, вы можете потерять 3 из 4 байтов.

Что мне не понятно, так это поведение, которое вы точно хотите.

  1. Стандартная 8Kx32 битная память с байтовым доступом
    или же
  2. 8kx8 битная память, где у вас есть байт 0x0, 0x4, 0x8 и т. Д.

В случае 2 вы должны использовать адрес AXI по-другому: вы должны сдвинуть биты адреса вверх на две позиции, чтобы каждый байт занимал 4 адреса. Вы также должны решить, где разместить байт:

  • Только позиция LS: привязать 24 бита MS к нулю

  • Только положение MS: привязать биты LS 24 к нулю

  • Повторяется во всех 4 местах: повторить байт четыре раза по 32 битам.

  • Что бы ты ни думал. (Это ваше оборудование, вы можете делать то, что вы хотите.)

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

Другие вопросы по тегам