Перейти к содержанию
    

Как сделать параллельную шину в NIOS?

Нужно из NIOS читать писать обычное статическое ОЗУ, по параллельной шине. Т.е. нужно в ниосе шина адреса, шина данных и управление - rd, wr и cs. Как собрать такой контроллер параллельной шины в Qsys? В SOPC-Builder собрал через Avalon Memory Mapped Tristate Slave и Avalon Tristate Bridge. Пытаюсь также в Qsys сделать - не получается. Почему-то в итоге сигнал wr из процессора выходит как inout, т.е. двунаправленный.

 

2 juvf

не пробовали AVALON компонент использовать вместо мостов?

В приложении моё чЮдо, использую правда в SOPC, но проблем не было :laughing:

sram_top.7z

Это я вообще не понял, что к чему.

 

Как сделать простую, обычную, параллельную шину в NIOS с помощью Qsys?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В Qsys'е тристейт делается по-другому.

Посмотрите Avalon Tri-State Conduit Components User Guide

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

..Это я вообще не понял, что к чему..

Так а собсно что не ясно? Можно через Avalon Memory Mapped Tristate Slave+Avalon Tristate Bridge а можно через свой Avalon Memory Mapped компонент. Я вам выложил 2й вариант (на мой взгляд гораздо проще будет+ всё своё, а не индусское).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В Qsys'е тристейт делается по-другому.

Посмотрите Avalon Tri-State Conduit Components User Guide

спасибо, кое что прояснилось в теории. Но теоретически лошадь, а практически упала.

 

Так а собсно что не ясно?
Как сделать параллельную шину. Как это делается практически? Открыл я твой компонент в Qsys. Что за сигналы lb и ub? Как изменить разрядность шины адреса? Как удалить не нужные сигналы? Так то у меня на этой шине ожидается 5..7 устройств. Я раньше брал и на старших адресах ставил дешифратор, на выходе которого получал чипселекты. Судя по альтеровской доке Avalon Tri-State Conduit Components User Guide можно сделать для каждого устройства свой тристэйт контроллер и через Tristate Conduit Pin Sharer посадить их все на одну шину с несколькими чипселектами. Такой вариант мне больше нравится. Но не получается.

 

Как я делаю по "индусски":

Требуется получить параллельную шину адресс, данные, и положительные сигналы чтения и записи.

Добавил Generic Tristate Controller + Tristate Conduit Pin Sharer + Tristate Conduit Bridge. см рис. Скомпелял. Теперь пишу прогу. Как достучаться до памяти? пишу

 

IOWR_16DIRECT(DAC1_BASE, 0, 0x100); - выполняю эту строчку и смотрю в сигналтабе сигналы своей параллельной шины. Сигналы не меняются. А на строке

alt_u16 = IORD_16DIRECT(DAC1_BASE, 0); вообще прога виснет. Заходит в эту функцию и не выходит. Пробовал так

alt_u16 = *(alt_u16*)(IORD_16DIRECT); Тоже на этом месте виснет. Как читать/писать в/из с параллельной шиной?

 

 

Что я делаю не так?

post-49045-1315389260_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нашел в чем была проблема. вроде шина заработала. но осталась одна проблема. сделал свой модуль, с которым ниос общается через параллельную шину.

команда IOWR_16DIRECT(0x10013202, 0, 0x4); работает нормально. в нужное место прописывается 4. пробую так *((alt_u16*)0x10013202) = 4; - не работает. шагаю в дебаге по сишным строчкам... прохожу строчку *((alt_u16*)0x10013202) = 4;, все работает. снимаю точки останова запускаю программу - обращение через указатель не работает. посмотрел дизассемблер нашел разницу

 

вот как компилятор скомпилировал код IOWR_16DIRECT(0x10013202, 0, 0x4);

//IOWR_16DIRECT(0x10013202, 0, 0x4);
800bb70:    00c40074     movhi    r3,4097
800bb74:    18cc8084     addi    r3,r3,12802
800bb78:    00800104     movi    r2,4
800bb7c:    1880002d     sthio    r2,0(r3)

 

а вот как скомпилировал *((alt_u16*)0x10013202) = 4;

//*((alt_u16*)0x10013202) = 4;
800b634:    00c40074     movhi    r3,4097
800b638:    18cc8084     addi    r3,r3,12802
800b63c:    00800104     movi    r2,4
800b640:    1880000d     sth    r2,0(r3)

 

разница в последней команде. с sthio - работает, а с sth. посмотрел в чем разница этих команд:

sthio These operations load/store byte and half-word data from/to peripherals without caching or buffering.

 

как сделать чтоб обращение через указатель к нужным областям памяти не кешировались и не буферезировались, т.е. чтоб компилятор при обращении через указатель использовал команду sthio?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как сделать чтоб обращение через указатель к нужным областям памяти не кешировались и не буферезировались, т.е. чтоб компилятор при обращении через указатель использовал команду sthio?

Например вот так

*((alt_u16*)0x10013202|0x80000000) = 4;

Установка старшего бита адреса в 1 указывает, что данную операцию необходимо осуществлять в обход кэш памяти.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Например вот так
*((alt_u16*)0x10013202|0x80000000) = 4;

Установка старшего бита адреса в 1 указывает, что данную операцию необходимо осуществлять в обход кэш памяти.

Спасибо тебе добрый человек!!! Заработало!

 

ps надо битик выставить на GPIO. пишу на си так

 

alt_u32 portB = IORD_ALTERA_AVALON_PIO_DATA(PORTB_BASE);

portB |= 1 << MODBUS_1;

IOWR_ALTERA_AVALON_PIO_DATA(PORTB_BASE, portB);

 

но идее можно обойти кеш и без альтеровских функций. если записать так:

 

*((alt_u32*)(PORTB_BASE|0x80000000)) |= 1 << MODBUS_1; - это таже песня. по идее сначала в обход кеш значения прочитаются, потом выставиться в 1 бит MODBUS_1, и полученный результат запишится в порт?

Изменено пользователем juvf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Конечно, только не во всех версиях ядра Ниос этот старший бит работает.

Мы обычно с IOWR/IORD не заморачиваемся, отключая кэш данных в SOPCB -- тогда и sth хорошо работает напрямую, и чтение.

Ну, пару дней попрыгаем после создания очередного проекта, почему это записи на шину не попадают из проца, затем кэш нафиг -- и прога не замутняется больше лабудой всякой ! ;)

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

А как криво выглядят фразы в мануале "After reset, the contents of the instruction cache and data cache are unknown. They must be initialized at the start of the software reset handler for correct operation." ! Неужто резет на эти блочки трудно им было завести ? Зато спецкоманды ассемблерные устроили и обрабатывают в ядре ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Неужто резет на эти блочки трудно им было завести ?

просвятите как можно сбросить память на плис, за один такт. будет интересно %)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мы обычно с IOWR/IORD не заморачиваемся, отключая кэш данных в SOPCB -- тогда и sth хорошо работает напрямую, и чтение.

а как вы делаете? понятно что вы кеш отключаете. а что дальше? как изменить 1 бит в GPIO без макрасов IOWR/IORD?

 

*((alt_u32*)(PORTB_BASE)) |= (1 << MODBUS_1);

 

такой код выставит битик с номером MODBUS_1 на GPIO по адресу PORTB_BASE, не затрагивая другие?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, запись по какому-то адресу -- она и в Африке запись, dest у себя определяет, что ему с этими данными делать, глотать или битики сбрасывать, а обе инструкции вроде ж только отношением к кэшу отличаются ?

Конечно, если вдруг на практике не сможет эту операцию простая запись, пусть это будет IOWR в виде исключения, главное, чтобы остальной код был понятный. Мне лично эти IOWR с циферками не импонируют, надо указатель/переменная и имя поля, ну и справа переменная/константа присваивается нужная. Пока проблем не было.

 

Про сброс памяти за такт -- необязательно всё занулять, у линейки кэша есть тэги всякие, определяющие её состояние, вот их на регистрах вполне можно установить в пустое состояние мгновенно по резету, последующие обращения в кэш выявят его пустым. Сами инструкции очистительные, скорей всего, выкинуть нельзя, т.к. могут понадобиться в самомодифицирующемся коде, при получении данных снаружи в кэшируемые области, хотя это тяжкое занятие -- вылечить все глюки в такой системе ;)

 

Вообще, в SOPCB напротив каждого региона можно галочку ставить, кэшируемый это регион или нет, проц на этапе компиляции может табличку сварганить... Или хотя бы предоставлять такую возможность для простых систем ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...