Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: MicroBlaze + DDR3 + my_IP на AXI
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Страницы: 1, 2
zuuuuk
Добрый день.
У меня система на SPARTAN6 Mbz + MCB_DDR3 на шине AXI.
Я хочу подключить свой IP блок ко второму порту MCB и получить доступ к DDR3.
т.е. мой IP блок должен быть мастером. Для чтения данных из DDR3.

Подскажите,пожалуйста, какой-нибудь пример подключения своего IP к шине AXI.
akorud
Цитата(zuuuuk @ May 5 2013, 17:44) *
Добрый день.
У меня система на SPARTAN6 Mbz + MCB_DDR3 на шине AXI.
Я хочу подключить свой IP блок ко второму порту MCB и получить доступ к DDR3.
т.е. мой IP блок должен быть мастером. Для чтения данных из DDR3.

Подскажите,пожалуйста, какой-нибудь пример подключения своего IP к шине AXI.

Лучше делать через "переходник" от Xilinx - http://www.xilinx.com/support/documentatio...aster_burst.pdf т.к. AXI достаточно сложная шина. Не скажу, что IP простой и очевидный - но все таки удалось его понять и все работает как часы.
Да, в Platform Studio меню Hardware->Create or import periferal - там вам визард сгенерирует работающий пример. У нас в проекте до сих пор фрагменты кода из того примера встречаются sm.gif.
serg_k1
Цитата(akorud @ May 5 2013, 22:47) *
Лучше делать через "переходник" от Xilinx - http://www.xilinx.com/support/documentatio...aster_burst.pdf т.к. AXI достаточно сложная шина. Не скажу, что IP простой и очевидный - но все таки удалось его понять и все работает как часы.
Да, в Platform Studio меню Hardware->Create or import periferal - там вам визард сгенерирует работающий пример. У нас в проекте до сих пор фрагменты кода из того примера встречаются sm.gif.

как тут действовать?
собрал схему на стр. 14 указанного pdf с синтезированным ip. но как добраться до входов ( Bus2IP_***)? Я так понимаю , что на них нужно подавать сигналы от внешнего устройства?
если же идти от обратного - т.е. взять проект синтезированного примера и туда добавить microblaze , то тоже непонятно как их состыковать?
может кто подскажет путь?
aabmail
Цитата(serg_k1 @ Jun 7 2013, 14:11) *
если же идти от обратного - т.е. взять проект синтезированного примера и туда добавить microblaze , то тоже непонятно как их состыковать?
может кто подскажет путь?


Я бы не советовал так делать.

Рекомендую вот такой путь (EDK 14.2).
Create or import peripheral -> выбрать To an XPS Projects -> core name -> AXI4 Burst-> галки User Logic Master, User logic SW registers -> число регистров побольше, например 32 -> ... -> галки generate ISE and XST, generate driver -> finish

Затем заходите в папку pcores/core name/devl/projnav/
открываете ISE, в нем открываете файл core name.xise
Там будет уже 2 готовых VHD-файла.
core name.vhd - это и есть "адаптер"
в user_logic вписывайте свой код.

Могу расписать более подробно.
serg_k1
Цитата(aabmail @ Jun 7 2013, 16:19) *
Могу расписать более подробно.

было бы очень полезно.
но это то и есть второй путь. вернее его первая часть. а вот дольше как действовать? нужно ведь добавить microblaze. и что в нем должно быть. ведь нужно собрать цепочку до DDR3 и при этом оставить существующую связь к DDR3. я ее собирал . но на axi external Master Connector(в Isim не заработало). а как здесь?
Golikov A.
А что если так.

Делаете микроблайз
в нем включаете контроллер ДДР (кто-то его должен так или иначе рефрешить), контроллер делаете вешаете на шину АКСИ
добавляете в микроблайз АКСИ конектор, соединяете микроблайз и ДДР

Дальше через крейт-импорт хардваре делаете модуль с интерфейсом акси, указываете что перефирия мастер.
И ее вешаете на тот же АКСИ конектор.

Я правда не знаю если делать 2 портовый контроллер ДДР, как это выглядит. У него появляется 2 подключения на акси или что? Но с 1 портовым у меня сейчас к нему подключен ДМА и Микроблайз, оба мастера, так что дружатся как то...


serg_k1
Цитата(Golikov A. @ Jun 10 2013, 14:44) *
А что если так.

Делаете микроблайз
в нем включаете контроллер ДДР (кто-то его должен так или иначе рефрешить), контроллер делаете вешаете на шину АКСИ
добавляете в микроблайз АКСИ конектор, соединяете микроблайз и ДДР

Дальше через крейт-импорт хардваре делаете модуль с интерфейсом акси, указываете что перефирия мастер.
И ее вешаете на тот же АКСИ конектор.

Я правда не знаю если делать 2 портовый контроллер ДДР, как это выглядит. У него появляется 2 подключения на акси или что? Но с 1 портовым у меня сейчас к нему подключен ДМА и Микроблайз, оба мастера, так что дружатся как то...

такой путь уже был другая тема. там уперся в то, что нет разрешения на обмен. даже после reset из переходит z-> 0, а разрешение -1.правда я ничего в тестбенче кроме частоты, reset и управления на запись на microblaze не подавал. но по reset должно появиться разрешение.
Golikov A.
так вы что хотите написать свой акси конектор что ли? Мне кажется это потенциальный источник ошибок в будущем. Лучше к своему модулю приделать интерфейс ДМА.

чего в память то писать-читать надо?
serg_k1
Цитата(Golikov A. @ Jun 10 2013, 18:07) *
так вы что хотите написать свой акси конектор что ли? Мне кажется это потенциальный источник ошибок в будущем. Лучше к своему модулю приделать интерфейс ДМА.

чего в память то писать-читать надо?

получается что да. известные - перечень сигналов(12вх+4вых), временная. ip в микроблайзе - ext_master_conn, который и выводит эти сигналы наружу.
хотелось через burst. но очень много вопросов. я начинающий.
ну вот собрал я в XPS microblaze систему с burst через крейт-импорт хардвар модуль с интерфейсом акси. и добавил его в мб. теперь нужно в модуле user logic(из pcore) добавить свою систему, которая принимает инф. извне и формирует запись. вот как конкретно это сделать? выйти из xps?.но в ise есть только микроблайз .
а так нужно принять данные видео преобразованные и передать их через интернет 1Gb. данные аппаратно в память, чтобы не загружать программу. а далее программно.
aabmail
Цитата(serg_k1 @ Jun 10 2013, 10:33) *
было бы очень полезно.
но это то и есть второй путь. вернее его первая часть. а вот дольше как действовать? нужно ведь добавить microblaze. и что в нем должно быть. ведь нужно собрать цепочку до DDR3 и при этом оставить существующую связь к DDR3. я ее собирал . но на axi external Master Connector(в Isim не заработало). а как здесь?


Открываете EDK.
Create a new project using Base system builder
Выбрать Axi system. Выбрать директорию для проекта. Название лучше оставить "system"
Далее укажите тип своей борды, а если у вас custom-плата, то указываете тип кристалла и частоту задающего генератора. Остальное по умочланию.
В следующем диалоге добавляете периферию, в т.ч. DDR3 SDRAM, Soft TEMAC Ethernet, UART16550 и др.
Finish.

Т.о. будет создан проект EDK, в котором будет уже готовый набор стандартных ядер. Вам теперь нужно создать свою user-ядро. Для этого:

Create or import peripheral -> выбрать To an XPS Projects -> core name -> AXI4 Burst-> галки User Logic Master, User logic SW registers -> число регистров побольше, например 32 -> ... -> галки generate ISE and XST, generate driver -> finish

Затем заходите в папку pcores/core name/devl/projnav/
открываете ISE, в нем открываете файл core name.xise
Там будет уже 2 готовых VHD-файла.
core name.vhd - это и есть "адаптер"
в user_logic вписывайте свой код.
serg_k1
Цитата(aabmail @ Jun 11 2013, 12:01) *
Открываете EDK.
Create a new project using Base system builder
Выбрать Axi system. Выбрать директорию для проекта. Название лучше оставить "system"
Далее укажите тип своей борды, а если у вас custom-плата, то указываете тип кристалла и частоту задающего генератора. Остальное по умочланию.
В следующем диалоге добавляете периферию, в т.ч. DDR3 SDRAM, Soft TEMAC Ethernet, UART16550 и др.
Finish.

Т.о. будет создан проект EDK, в котором будет уже готовый набор стандартных ядер. Вам теперь нужно создать свою user-ядро. Для этого:

Create or import peripheral -> выбрать To an XPS Projects -> core name -> AXI4 Burst-> галки User Logic Master, User logic SW registers -> число регистров побольше, например 32 -> ... -> галки generate ISE and XST, generate driver -> finish

Затем заходите в папку pcores/core name/devl/projnav/
открываете ISE, в нем открываете файл core name.xise
Там будет уже 2 готовых VHD-файла.
core name.vhd - это и есть "адаптер"
в user_logic вписывайте свой код.

все это я и раньше проделал.
1. теперь мой проект core name.xise. но там же нет микроблайза. нужно его добавить?
я добавил. делаю его головным.а при подключении "адаптера" в подчиненном выдает ошибку , что неизвестный "адаптер". если наоборот "адаптер" головной микроблайз подчиненный все проходит. но там слишком со многими сигналами микроблайза нужно разбираться.
и еще . к чему подключается "адаптер" в микроблайзе.
2.или проект остается в XPS. а ISE только для написания кода в адаптере? но тогда как мне сделать свой вход в "адаптере" от внешнего пина. в адаптере я так понял есть 4 модуля. 1-user , 2-axi_master_burst,3-axi_lite_ipif,4-головной(пусть mmm). и только ммм связан с микоблайзом. input my_clk мой входной сигнал. я его добавил в user , а дальше должен провести через эти модули в микроблайз. ведь в этом случае есть только он и через него нужно вводить сигналы от внешнего устройства?.
aabmail
Цитата(serg_k1 @ Jun 11 2013, 13:35) *
все это я и раньше проделал.
1. теперь мой проект core name.xise. но там же нет микроблайза. нужно его добавить?
я добавил. делаю его головным.а при подключении "адаптера" в подчиненном выдает ошибку , что неизвестный "адаптер". если наоборот "адаптер" головной микроблайз подчиненный все проходит. но там слишком со многими сигналами микроблайза нужно разбираться.
и еще . к чему подключается "адаптер" в микроблайзе.
2.или проект остается в XPS. а ISE только для написания кода в адаптере? но тогда как мне сделать свой вход в "адаптере" от внешнего пина. в адаптере я так понял есть 4 модуля. 1-user , 2-axi_master_burst,3-axi_lite_ipif,4-головной(пусть mmm). и только ммм связан с микоблайзом. input my_clk мой входной сигнал. я его добавил в user , а дальше должен провести через эти модули в микроблайз. ведь в этом случае есть только он и через него нужно вводить сигналы от внешнего устройства?.


Ваш второй вариант ближе к мной предложенному пути.
ISE фактически служит для написания кода (Кстати, что вы понимаете под словом "Адаптер"?). Еще через ISE удобно вызывать симуляцию.
В user-core есть не 4, а 2 модуля - по порядку: головной, типа axi_mmm_core.vhd и user_logic.vhd. Все остальное - это инклюды.

Вы хотите ввести извне сигнал my_clk? Это случайно не system_clock для всего проекта?
Если это "обычный просто сигнал", то его нужно прописать в следующие файлы: system.ucf, system.mhs, axi_mmm_core.mpd, axi_mmm_core.vhd, user_logic.vhd.
Таким образом вы вводите сигнал в свой user_core.
Подключить его напрямую к блэйзу нельзя. Это можно сделать только через AXI. Если вы это делаете впервые, попробуйте его для начала присоединить к сигналу USER_LOGIC/SLV_REG0(0).

Для проверки правильности написания имеет смысл делать синтез в ISE, и потом смотреть лог, исправлять ошибки.
Потом нажимаете Generate bitstream в EDK.
akorud
Цитата(aabmail @ Jun 11 2013, 11:54) *
Ваш второй вариант ближе к мной предложенному пути.

Поддерживаю. Мне такой вариант показался самым удобным, только код я писал в sublime text. ISE так ни разу и не запустил.
serg_k1
Цитата(aabmail @ Jun 11 2013, 13:54) *
Ваш второй вариант ближе к мной предложенному пути.

спасибо , сейчас как-то мне попонятнее.
я просто не понял какой путь предложен. теперь понял -второй.
Цитата
Вы хотите ввести извне сигнал my_clk? Это случайно не system_clock для всего проекта?

это просто для примера. нужно данные байт и строб.
Цитата
Если это "обычный просто сигнал", то его нужно прописать в следующие файлы: system.ucf, system.mhs, axi_mmm_core.mpd, axi_mmm_core.vhd, user_logic.vhd.
Таким образом вы вводите сигнал в свой user_core.

в головном m.vhd
port (my_clk :in std_logic;)

component user_logic
port
(my_clk_user : in std_logic;)
port map
( my_clk_user => my_clk,)

в user logic(он в verilog)
module user_logic
( my_clk_user, )
input my_clk_user;

что здесь?
m.mpd
PORT my_clk = ???, DIR = I, BUS = ???

system.ucf

PORT my_clk = my_clk, DIR = I
и нужно ли здесь
BEGIN m
PARAMETER INSTANCE = m_0
PARAMETER HW_VER = 1.00.a
PARAMETER C_BASEADDR = 0xa0000000
PARAMETER C_HIGHADDR = 0xa000ffff
BUS_INTERFACE M_AXI = axi4_0
BUS_INTERFACE S_AXI = axi4lite_0
PORT S_AXI_ACLK = clk_50_0000MHzPLL0
PORT m_axi_aclk = clk_100_0000MHzPLL0
END

system.ucf
NET my_clk LOC = "N19" | IOSTANDARD = "LVCMOS25"; N19 заменю на нужный контакт


если можно, то еще может подскажете как быстро подключиться в user_logic. нужна запись 32р слов, количество ~ 500.
aabmail
Цитата(akorud @ Jun 11 2013, 14:52) *
Поддерживаю. Мне такой вариант показался самым удобным, только код я писал в sublime text. ISE так ни разу и не запустил.



ISE все-таки удобно тем, что там можно генерить test_bench для ModelSim. А редактор в ISE конечно плохой, и даже иногда виснет на пустом месте.


Цитата
component user_logic
port
(my_clk_user : in std_logic;)
port map
( my_clk_user => my_clk,)


честно говоря мне до сих пор непонятно, когда следует применять ключевое слово component. Делаю обычно так:
LABEL: entity work.user_logic
port map
(
Bus2IP_Clk => clk,
...
);

Цитата
что здесь?
m.mpd
PORT my_clk = ???, DIR = I, BUS = ???


PORT my_clk = "", DIR = I

MHS лучше поначалу руками не править. Пользуйтесь графической средой.
Когда заполните MPD, перезагрузите EDK.
Найдите в EDK окно System Assembly View и в нем вкладку Ports. Найдите там свое ядро, свой сигнал и выберите Make external. Посмотрите, как изменится MHS.

Цитата
system.ucf
NET my_clk LOC = "N19" | IOSTANDARD = "LVCMOS25"; N19 заменю на нужный контакт

Как то так.

Цитата
если можно, то еще может подскажете как быстро подключиться в user_logic. нужна запись 32р слов, количество ~ 500.

500 слов раз в секунду или чаще?
Golikov A.
я делаю визардом из XPS компонент, обычно с верилоговским юзер файлом и с проектом ISE. Потом в ISE открываю проект, правлю файлы, добавляю сигналы в верхний модуль обертку, и провожу их в свой юзер. UCF и MHS не правлю, потом делаю имплемент том подуль, посел чего появляется xps проект, который импортится в платформ студию и уже имеет все нужные сигналы.

Только надо следить чтобы сигналы прерывания и клока спец словами снабжать в верхнем модуле, а то они таковыми не станут.

ISE виснет если переключится на русский язык после запуска любой процедуры ISE. То есть если только запустил ISE можно писать по русски, как только нажали чек синтез, симуляцию, или еще что-то, все... Любое переключение раскладки - висяк! Бесит, меня по контракту было раньше все комменты на русском, теперь привык, а ISE такую подлянку делает....

В ISE тоже можно делать компоненты хардварные, можно сделать память РАМ и ФИФО, оба эти компонента позволят быстро сохранить 500 слов...
serg_k1
Цитата
500 слов раз в секунду или чаще?

32р 400 слов ~16MГц , это как бы строка. затем новый адрес и повтор
aabmail
Цитата(serg_k1 @ Jun 13 2013, 09:36) *
32р 400 слов ~16MГц , это как бы строка. затем новый адрес и повтор


Разъясните, что означает ~16MГц?

Вы хотите передавать 16 000 000 раз в секунду 400 32-разрядных слов?
или 16 000 000 одно 32 разрядного слова,
или 16 мегабайт в сек
или 16 мегабит/сек?
serg_k1
Цитата(aabmail @ Jun 13 2013, 13:56) *
Разъясните, что означает ~16MГц?

Вы хотите передавать 16 000 000 раз в секунду 400 32-разрядных слов?
или 16 000 000 одно 32 разрядного слова,
или 16 мегабайт в сек
или 16 мегабит/сек?

32р слово записывается с частотой 16МГц. таких слов 400. это записывается по одному начальному адресу. 9 разрядов. пусть с адреса 8000_0000 по 8000_01FF(если 512) . потом наращивается адрес для следующей строки еще 10разрядов с 10 по 19,. всего 19разрядов. это вся информация. может быть еще один или два разряда, чтобы следующую писать в другую область памяти. всего от 19 до 22разрядов адреса.
aabmail
Цитата(serg_k1 @ Jun 13 2013, 15:52) *
32р слово записывается с частотой 16МГц. таких слов 400. это записывается по одному начальному адресу. 9 разрядов. пусть с адреса 8000_0000 по 8000_01FF(если 512) . потом наращивается адрес для следующей строки еще 10разрядов с 10 по 19,. всего 19разрядов. это вся информация. может быть еще один или два разряда, чтобы следующую писать в другую область памяти. всего от 19 до 22разрядов адреса.


Вы хотите сказать, что данные в Вашу плату вводятся по последовательному интерфейсу на частоте 16 МГц пакетами по 400 32битных слов? Если так, и если исходить из того, что пакеты поступают друг за другом встык, то поток данных получается 2 Мбайта в сек. Для нашего верианта построения проекта это максимально возможный поток. Мы недавно купили плату отладки AVNET, скачали с их сайта готовый проект, включающий тест пропускной способности. Там примерно так и получалось (несмотря на то, что там гигабитный Ethernet) . Это к тому, что возможно, система не будет успевать переработать ваши данные, и часть будет пропадать.

Чтобы переправить данные в DDR, записывать их в FIFO.

1. нужно найти в user_logic.vhd DATA_CAPTURE_FIFO_I. Там в качестве примера уже инстанциирован FIFO. Идея примера в том, что блэйз кладет данные в fifo и сам же их оттуда считывает. Нужно адаптировать пример под себя.

в DATA_CAPTURE_FIFO_I:

2. C_DEPTH заменяете на 400
3. к порту Data_In вместо того, что там написано, подключаете свои данные (32 bit)
4. управляете записью сигналом FIFO_Write.
5. Проверяйте состояние fifo сигналами FIFO_empty, FIFO_full и addr. Не допускайте переполнения.

В программе MicroBlaze:

6. Когда вы создавали ядро через визард, у вас в проекте должна была появиться папка drivers, в которой должны лежать примеры считывания из ядра. Должно быть что-то вроде AXI_mmm_core_MasterSendBytes (в зависимости от того, как вы назвали свое ядро).

Как-то так.
Golikov A.
на гигабитном езернете, в крайне не оптимальном режиме имею 29 Мегабит запись
и около 20 чтение. Это когда каждый пакет блокируется, то есть пока не обработается прошлый новый не лезет, и это на ЛвИП стеке. так что 2 мегобайта в секунду не предел, вроде как....

также у меня модуль фифо, который выдает по алгоритму данные, у меня поулчилось 7 тактов на запись в него 1 слова через акси-лите, и около 8 на выдачу, на самом деле из-за алгоритма, в целом около 2 тактов надо на чтение из фифо. При 100 МГц проце тоже весьма солидный поток.

Построить автомат который будет 400 входных слов собирать и перепихивать в фифо тоже вроде как не проблема для 16 МГц, правда если это не 16 мегаслов, а 16 мегабитsm.gif... если же это мегослов 16 штук, то тогда ой...
serg_k1
Цитата(aabmail @ Jun 13 2013, 19:34) *
3. к порту Data_In вместо того, что там написано, подключаете свои данные (32 bit)
4. управляете записью сигналом FIFO_Write.

т.е. к FIFO_Write тоже подключить свой сигнал?
и еще есть много вопросов по подключению.
Ведь для записи нужно задать адрес, количество записей и др. все это в mst_reg, а туда они из Bus2IP_Data. и как сюда попасть.
Golikov A.
такс...
ФИФО

это компонент с входом и выходом параллельная шина. и 2 строба запись чтение
и несколько сигналов.
клок
фифо полно
фифо почти полно
фифо пустое
в фифо лежит столько то строк.

Когда на входе строба записи появляется единица, с каждым положительным фронтом данные со входа попадают в фифо.
Аналогично с появление единицы на стробе чтения, с каждым фронтом клока на выходе появляются очередные данные.
количество данных в фифо также отмечается с каждым клоком.

это готовое ИП корка, которая добавляется через хардваре визард в исе или платформ студии...

я себе такое сделал, и в юзер_логик файле компонента его заюзал.

ФИФО не РАМ оно не адресуется, сначала все пихаете, а потом все забираете, это буфер.

В плис также можно сделать РАМ, если хотите адресовать, я не делал, мне не надо было, но в инете стандартный пример как раз делают таблицу РАМ.


Дальше если вы делаете из платформ студии через визард свой компонент. То там можно выбрать чтобы он имел регистры от 1 до 32 штук. И сразу создастся компонент с оберткой и всем необходимым для доступа. А в юзер логик будет уже написана часть отвечающая за чтение и запись регистров. Компонент уже сделан для подключения к акси шине. Все регистры что внутри компонента адресуются из вне, там в коментах написано как к ним достучаться.


serg_k1
Цитата(Golikov A. @ Jun 14 2013, 11:00) *
Дальше если вы делаете из платформ студии через визард свой компонент. То там можно выбрать чтобы он имел регистры от 1 до 32 штук. И сразу создастся компонент с оберткой и всем необходимым для доступа. А в юзер логик будет уже написана часть отвечающая за чтение и запись регистров. Компонент уже сделан для подключения к акси шине. Все регистры что внутри компонента адресуются из вне, там в коментах написано как к ним достучаться.

создал в XPS компонент. выбрал чтобы он имел регистры от 1 до 32. и не нахожу ничего кроме
Код
-- control register (byte 0)
        if ( mst_byte_we(0) = '1' ) then
          mst_reg(0) <= Bus2IP_Data(7 downto 0);
        end if;
        -- status register (byte 1)
        mst_reg(1)(1) <= mst_cmd_sm_busy;
        if ( mst_byte_we(1) = '1' ) then
          -- allows a clear of the 'Done'/'error'/'timeout'
          mst_reg(1)(0) <= Bus2IP_Data((1-(1/BE_WIDTH)*BE_WIDTH)*8);
          mst_reg(1)(2) <= Bus2IP_Data((1-(1/BE_WIDTH)*BE_WIDTH)*8+2);
          mst_reg(1)(3) <= Bus2IP_Data((1-(1/BE_WIDTH)*BE_WIDTH)*8+3);
        else
          -- 'Done'/'error'/'timeout' from master control state machine
          mst_reg(1)(0)  <= mst_cmd_sm_set_done or mst_reg(1)(0);
          mst_reg(1)(2)  <= mst_cmd_sm_set_error or mst_reg(1)(2);
          mst_reg(1)(3)  <= mst_cmd_sm_set_timeout or mst_reg(1)(3);
        end if;
        -- byte 2 and 3 are reserved
        -- address register (byte 4 to 7)
        -- be register (byte 8 to 9)
        -- length register (byte 12 to 13)
        -- byte 10, 11 and 14 are reserved
        for byte_index in 4 to 14 loop
          if ( mst_byte_we(byte_index) = '1' ) then
            mst_reg(byte_index) <= Bus2IP_Data(
                                     (byte_index-(byte_index/BE_WIDTH)*BE_WIDTH)*8+7 downto
                                     (byte_index-(byte_index/BE_WIDTH)*BE_WIDTH)*8);
          end if;
        end loop;
      end if;

я не вижу где здесь регистры?
или не там ищу, или еще чего-то не понимаю. этот компонент позволяет сделать (при написании дополнений в User_logic) задать нач.адрес записи,длину, принять данные и осуществлять запись в память?
aabmail
Цитата
Когда на входе строба записи появляется единица, с каждым положительным фронтом данные со входа попадают в фифо.
Аналогично с появление единицы на стробе чтения, с каждым фронтом клока на выходе появляются очередные данные.
количество данных в фифо также отмечается с каждым клоком.


Разве это FIFO работает по фронту? По-моему по уровню. Т.е. если fifo_write = '1', то данные из data_in на этом же цикле записываются в fifo.

Цитата
на гигабитном езернете, в крайне не оптимальном режиме имею 29 Мегабит запись
и около 20 чтение. Это когда каждый пакет блокируется, то есть пока не обработается прошлый новый не лезет, и это на ЛвИП стеке. так что 2 мегобайта в секунду не предел, вроде как....

Вот что-то такое и было на тестовом проекте. В принципе если использовать драйвер Ethernet напрямую (на MAC-уровне), то по крайней мере в spartan3 удавалось разогнать скорость до 6-7 мегабайт в сек. Но тогда получается громоздкий софтовый проект, приходится самому делать ARP, ICMP и т.д.

Цитата
Дальше если вы делаете из платформ студии через визард свой компонент. То там можно выбрать чтобы он имел регистры от 1 до 32 штук. И сразу создастся компонент с оберткой и всем необходимым для доступа. А в юзер логик будет уже написана часть отвечающая за чтение и запись регистров. Компонент уже сделан для подключения к акси шине. Все регистры что внутри компонента адресуются из вне, там в коментах написано как к ним достучаться.

Зачем нужны регистры, если речь идет о прокачке 2 MB/sec ? Если только для передачи медленных данных.
Golikov A.
то данные из data_in на этом же цикле записываются в fifo.
цикле чего?sm.gif когда на врайте 1, то каждый такт клока данные записываются, и произойдет это по переднему фронту.

Вот что-то такое и было на тестовом проекте.
да я тоже планирую подразогнать, но сильно усугубляет ЛвИП, все же он много чего еще делает кроме передачи данных...

Зачем нужны регистры, если речь идет о прокачке 2 MB/sec ?
для удобства пользования.

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


мне когда я генерю такую штуку получаю такой файл, это уже помененный мной,
по умолчанию он регистрам дает имена reg_0 reg_1 ....
и адреса
00001
00010
00100
....

Код
// ------------------------------------------------------
  // Example code to read/write user logic slave model s/w accessible registers
  //
  // Note:
  // The example code presented here is to show you one way of reading/writing
  // software accessible registers implemented in the user logic slave model.
  // Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond
  // to one software accessible register by the top level template. For example,
  // if you have four 32 bit software accessible registers in the user logic,
  // you are basically operating on the following memory mapped registers:
  //
  //    Bus2IP_WrCE/Bus2IP_RdCE   Memory Mapped Register
  //                     "1000"   C_BASEADDR + 0x0
  //                     "0100"   C_BASEADDR + 0x4
  //                     "0010"   C_BASEADDR + 0x8
  //                     "0001"   C_BASEADDR + 0xC
  //
  // ------------------------------------------------------

  assign
    slv_reg_write_sel = Bus2IP_WrCE[10:0],
    slv_reg_read_sel  = Bus2IP_RdCE[10:0],
    slv_write_ack     = Bus2IP_WrCE[0] || Bus2IP_WrCE[1] || Bus2IP_WrCE[2] || Bus2IP_WrCE[3] || Bus2IP_WrCE[4] || Bus2IP_WrCE[5] || Bus2IP_WrCE[6] || Bus2IP_WrCE[7] || Bus2IP_WrCE[8] || Bus2IP_WrCE[9]  || Bus2IP_WrCE[10],
    slv_read_ack      = Bus2IP_RdCE[0] || Bus2IP_RdCE[1] || Bus2IP_RdCE[2] || Bus2IP_RdCE[3] || Bus2IP_RdCE[4] || Bus2IP_RdCE[5] || Bus2IP_RdCE[6] || Bus2IP_RdCE[7] || Bus2IP_RdCE[8] || Bus2IP_RdCE[9]  || Bus2IP_RdCE[10];

  // implement slave model register(s)
  always @( posedge Bus2IP_Clk )
    begin

      if ( Bus2IP_Resetn == 1'b0 )
        begin
                    fifo_write_signal <= 0;
          command_reg <= 0;
          path_data_reg <= 0;
          start_step_time_reg <= 0;
          max_step_time_reg <= 0;
          min_step_time_reg <= 0;
          step_time_plus_reg <= 0;
          step_time_minus_reg <= 0;
          stop_path_length <= 0;
          step_len <= 0;
                    dir_len <= 0;
                    STATUS_ADDR <= MAIN_STATUS;
        end
      else
                begin
                    //сбрасываем флаг если нет сигнала записи в данные пути
                    if(slv_reg_write_sel !=  11'b0000000010)
                        fifo_write_signal <= 2'b00;    

                    case ( slv_reg_write_sel )
                        STATUS_REG_CE : //запись в регистр статуса - выбор регистра
                            begin
                                if ( Bus2IP_BE[0] == 1 ) //только младший байт
                                    STATUS_ADDR <=  Bus2IP_Data[STATUS_ADR_SIZE - 1 : 0];
                            end
                        COMMAND_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    command_reg[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                        PATH_DATA_REG_CE :
                            begin
                                for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                    if ( Bus2IP_BE[byte_index] == 1 )
                                        path_data_reg[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                                
                                //по клоку надо выдать строб на запись в фифо
                                if(fifo_write_signal == 0)
                                    fifo_write_signal <= 2'b01;
                                //по следующему клоку надо снять строб, но не поставить заново если будет еще клок
                                else if (fifo_write_signal == 2'b01)
                                    fifo_write_signal <= 2'b10;
                                //когда убиреться разрешение на запись, флаг сброситься в 0    
                            end            
                        START_STEP_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    start_step_time_reg[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                        MAX_STEP_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    max_step_time_reg[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                        MIN_STEP_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    min_step_time_reg[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                        PLUS_STEP_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    step_time_plus_reg[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                        MINUS_STEP_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    step_time_minus_reg[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                        STOP_PATH_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    stop_path_length[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                        STEP_LEN_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    step_len[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                        STEP_DIR_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    dir_len[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];
                        default :
                            begin
                            end
                    endcase
                end    
    end // SLAVE_REG_WRITE_PROC

  // implement slave model register read mux
  always @( slv_reg_read_sel or status_reg or command_reg or path_data_reg or start_step_time_reg or max_step_time_reg or min_step_time_reg or step_time_plus_reg or step_time_minus_reg or stop_path_length or step_len or dir_len)
    begin
      case ( slv_reg_read_sel )
        STATUS_REG_CE : slv_ip2bus_data <= status_reg;
        COMMAND_REG_CE : slv_ip2bus_data <= command_reg;
        PATH_DATA_REG_CE : slv_ip2bus_data <= path_data_reg;
        START_STEP_REG_CE : slv_ip2bus_data <= start_step_time_reg;
        MAX_STEP_REG_CE : slv_ip2bus_data <= max_step_time_reg;
        MIN_STEP_REG_CE : slv_ip2bus_data <= min_step_time_reg;
        PLUS_STEP_REG_CE : slv_ip2bus_data <= step_time_plus_reg;
        MINUS_STEP_REG_CE : slv_ip2bus_data <= step_time_minus_reg;
        STOP_PATH_REG_CE : slv_ip2bus_data <= stop_path_length;
        STEP_LEN_REG_CE : slv_ip2bus_data <= step_len;
                STEP_DIR_REG_CE : slv_ip2bus_data <= dir_len;
        default : slv_ip2bus_data <= 0;
      endcase

    end // SLAVE_REG_READ_PROC
serg_k1
Цитата(Golikov A. @ Jun 14 2013, 14:36) *
я сделал модуль у которого с одной стороны доступ через акси, через регистры, пишеш в регистр, данные в фифо проваливаются, с другой стороны уже контакты к исполняемым устройствам и автомат управления.


мне когда я генерю такую штуку получаю такой файл, это уже помененный мной,
по умолчанию он регистрам дает имена reg_0 reg_1 ....
и адреса
00001
00010
00100
....

да такой код есть . буду разбираться. я так понимаю , что он для записи и чтения ФИФО. а вот после него идет другая часть. для инициализации и запуска одиночной записи. я то думал , что нужно ей пользоваться для реализации алгоритма записи с помощью этого компонента. только не одиночной как в примере ,а Burst Write Transaction . как Figure 10: Example Burst Write Transaction Timing DS844.
Код
//  ------------------------------------------
// Example code to demonstrate user logic master model functionality
//
// Note:
// The example code presented here is to show you one way of instatiating
// the AXI4 (Burst) master interface under user control. It is provided for
// demonstration purposes only and allows the user to exercise the AXI4 (Burst)
// master interface during test and evaluation of the template.
// This user logic master model contains a 16-byte flattened register and
// the user is required to initialize the value to desire and then write to
// the model's 'Go' port to initiate the user logic master operation.
//
//    Control Register     (C_BASEADDR + OFFSET + 0x0):
//       bit 0    - Rd     (Read Request Control)
//       bit 1    - Wr     (Write Request Control)
//       bit 2    - BL     (Bus Lock Control)
//       bit 3    - Brst   (Burst Assertion Control)
//       bit 4-7  - Spare  (Spare Control Bits)
//    Status Register      (C_BASEADDR + OFFSET + 0x1):
//       bit 0    - Done   (Transfer Done Status)
//       bit 1    - Busy   (User Logic Master is Busy)
//       bit 2    - Error  (User Logic Master request got error response)
//       bit 3    - Tmout  (User Logic Master request is timeout)
//       bit 2-7  - Spare  (Spare Status Bits)
//    Addrress Register    (C_BASEADDR + OFFSET + 0x4):
//       bit 0-31 - Target Address (This 32-bit value is used to populate the
//                  ip2bus_Mst_Addr(0:31) address bus during a Read or Write
//                  user logic master operation)
//    Byte Enable Register (C_BASEADDR + OFFSET + 0x8):
//       bit 0-15 - Master BE (This 16-bit value is used to populate the
//                  ip2bus_Mst_BE byte enable bus during a Read or Write user
//                  logic master operation for single data beat transfer)
//    Length Register      (C_BASEADDR + OFFSET + 0xC):
//       bit 0-3  - Reserved
//       bit 4-15 - Transfer Length (This 12-bit value is used to populate the
//                  ip2bus_Mst_Length(0:11) transfer length bus which specifies
//                  the number of bytes (1 to 4095) to transfer during user logic
//                  master Read or Write fixed length burst operations)
//    Go Register          (C_BASEADDR + OFFSET + 0xF):
//       bit 0-7  - Go Port (Write to this byte address initiates the user
//                  logic master transfer, data key value of 0x0A must be used)
//
//    Note: OFFSET may be different depending on your address space configuration,
//          by default it's 0x100. Refer to IPIF address range array
//          for actual value.
//
// Here's an example procedure in your software application to initiate a 64-byte
// read operation (single data beat) of this master model:
//    1. write 0x09 to the control register to perform write operation.
//    2. write the target address to the address register.
//    3. write valid byte lane value to the be register
//      - note: this value must be aligned with ip2bus address  
//    4. write 0x040 to the length register
//    5. write 0x0a to the go register, this will start the master write operation
//
// Here's an example procedure in your software application to initiate a 64-byte
// write operation (single data beat) of this master model:
//   1. write 0x0A to the control register to perform write operation.
//   2. write the target address to the address register
//   3. write valid byte lane value to the be register
//      - note: this value must be aligned with ip2bus address
//   4. write 0x0040 to the length register
//   5. write 0x0a to the go register, this will start the master write operation
//
//----------------------------------------
  assign mst_reg_write_req = Bus2IP_WrCE[10] || Bus2IP_WrCE[11] || Bus2IP_WrCE[12] || Bus2IP_WrCE[13];
  assign mst_reg_read_req  = Bus2IP_RdCE[10] || Bus2IP_RdCE[11] || Bus2IP_RdCE[12] || Bus2IP_RdCE[13];
  assign mst_reg_write_sel = Bus2IP_WrCE[13 : 10];
  assign mst_reg_read_sel  = Bus2IP_RdCE[13 : 10];
  assign mst_write_ack     = mst_reg_write_req;
  assign mst_read_ack      = mst_reg_read_req;

  // rip control bits from master model registers
  assign mst_cntl_rd_req   = mst_reg[0][0];
  assign mst_cntl_wr_req   = mst_reg[0][1];
  assign mst_cntl_bus_lock = mst_reg[0][2];
  assign mst_cntl_burst    = mst_reg[0][3];
  assign mst_ip2bus_addr   = {mst_reg[7], mst_reg[6], mst_reg[5], mst_reg[4]};
  assign mst_ip2bus_be     = {mst_reg[9], mst_reg[8]};
  assign mst_xfer_reg_len  = {mst_reg[14][3 : 0], mst_reg[13], mst_reg[12]};// changed to 20 bits
  assign mst_xfer_length   = mst_xfer_reg_len[C_LENGTH_WIDTH-1 : 0];

  // implement byte write enable for each byte slice of the master model registers
  always @ (Bus2IP_BE or mst_reg_write_req or mst_reg_write_sel)
    begin
      for ( byte_index = 0; byte_index <= 15; byte_index = byte_index+1 )
        mst_byte_we[byte_index] <= mst_reg_write_req & mst_reg_write_sel[3 - (byte_index/BE_WIDTH)] & Bus2IP_BE[byte_index - ((byte_index/BE_WIDTH)*BE_WIDTH)];
    end // MASTER_REG_BYTE_WR_EN
  // implement master model registers
  // The master registers are written to initialize master transfer.
  always @ ( posedge Bus2IP_Clk)
    begin
    if (Bus2IP_Resetn == 1'b0 )
      begin
        for ( byte_index = 0; byte_index <= 14; byte_index = byte_index+1 )
          mst_reg[byte_index] <= 0;
      end
    else
      begin
          if ( mst_byte_we[0] == 1'b1 )
            begin
              mst_reg[0][7:0] <= Bus2IP_Data[7 : 0];
            end
          
             mst_reg[1][1] <= mst_cmd_sm_busy;  
      
          if (mst_byte_we[1] == 1'b1 )
          // allows a clear of the 'Done'/'error'/'timeout'
            begin
              mst_reg[1][0] <= Bus2IP_Data[(1-(1/BE_WIDTH)*BE_WIDTH)*8];
              mst_reg[1][2] <= Bus2IP_Data[(1-(1/BE_WIDTH)*BE_WIDTH)*8+2];
              mst_reg[1][3] <= Bus2IP_Data[(1-(1/BE_WIDTH)*BE_WIDTH)*8+3];
            end
        else
          // 'Done'/'error'/'timeout' from master control state machine
          begin
             mst_reg[1][0]  <= mst_cmd_sm_set_done | mst_reg[1][0];
             mst_reg[1][2]  <= mst_cmd_sm_set_error | mst_reg[1][2];
             mst_reg[1][3]  <= mst_cmd_sm_set_timeout | mst_reg[1][3];
           end
             // byte 2 and 3 are reserved
             // address register (byte 4 to 7)
             // be register (byte 8 to 9)
             // length register (byte 12 to 13)
             // byte 10, 11 and 14 are reserved
         for ( byte_index = 4; byte_index <= 14; byte_index = byte_index+1 )
           if ( mst_byte_we[byte_index] == 1'b1 )
             begin
               mst_reg[byte_index] <= Bus2IP_Data[(byte_index-(byte_index/BE_WIDTH)*BE_WIDTH)*8 +: 8];
             end
      end
    end // MASTER_REG_WRITE_PROC



Цитата(Golikov A. @ Jun 14 2013, 14:36) *

в примере есть код
Код
STEP_LEN_REG_CE :
                            for ( byte_index = 0; byte_index <= (C_SLV_DWIDTH/8)-1; byte_index = byte_index+1 )
                                if ( Bus2IP_BE[byte_index] == 1 )
                                    step_len[(byte_index*8) +: 8] <= Bus2IP_Data[(byte_index*8) +: 8];

что в результате получается. не конкретно в этом. не понятно в целом. т.е. из неизвестного (так ли это?) Bus2IP_Data,ведь он из другого модуля axi_lite_ipif получается нужный сигнал. этот же вопрос возникает и в MASTER_REG_BYTE_WR_EN.
Golikov A.
сдается мне у кого-то полная путаница в головеsm.gif..


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

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

глобально компонент это

1. Модуль обертка - который вешается на шину внутри содержит:
1.1 вспомогательный модуль который работает с шиной и преобразует ее сложные сигналы в понятный набор сигналов
Bus2IP - бас ту айпи, от шины к вам и
IP2Bus - обратно
клоки чипселекты, и прочие вспомогательные сигналы.
1.2 Пользовательский модуль, куда заведены эти понятные сигналы

Последний сделан для вас, для редактирования. Изначально он не содержит ничего кроме набора регистров с прописанным примером их чтения и записи.

Дальше вы в него пихаете компоненты, написанные вами прочие модули, и все все все что вам надо. И делаете управление всем этим через регистры. И выдачу данных обратно через регистры. и все.

Также не воспрещается добавлять прочие как входные, так и выходные сигналы, их надо добавить и в пользовательском модуле и в модуле обертке, и соединить в модуле обертке...

Также в модуль обертки можно добавить еще пользовательский модуль если это надо...

Только надо понимать что это все для взаимодействия вашего модуля с микроблайзом, а если микроблайза нет, то и с шиной париться не надо, и можно писать обычный плисовый не процессорный модуль, что иногда бывает проще... без регистров, оберток и прочеее
serg_k1
Цитата(Golikov A. @ Jun 14 2013, 17:59) *

ясно, буду разбираться
akorud
Цитата(serg_k1 @ Jun 14 2013, 09:54) *
создал в XPS компонент. выбрал чтобы он имел регистры от 1 до 32. и не нахожу ничего кроме
Код
-- control register (byte 0)
        if ( mst_byte_we(0) = '1' ) then
          mst_reg(0) <= Bus2IP_Data(7 downto 0);
....

я не вижу где здесь регистры?

Ну так mst_reg это и есть регистры.
aabmail
Цитата(akorud @ Jun 17 2013, 00:54) *
Ну так mst_reg это и есть регистры.


Обычно mst_reg используются для конфигурирования мастера, и для пользователей не предназначены.
Если что-то единичное хотите передавать, используйте slv_reg( ). Они там случайно не сгенерились?
serg_k1
Цитата(Golikov A. @ Jun 14 2013, 17:59) *
глобально компонент это

1. Модуль обертка - который вешается на шину внутри содержит:
1.1 вспомогательный модуль который работает с шиной и преобразует ее сложные сигналы в понятный набор сигналов
Bus2IP - бас ту айпи, от шины к вам и
IP2Bus - обратно
клоки чипселекты, и прочие вспомогательные сигналы.
1.2 Пользовательский модуль, куда заведены эти понятные сигналы

Последний сделан для вас, для редактирования. Изначально он не содержит ничего кроме набора регистров с прописанным примером их чтения и записи.

Дальше вы в него пихаете компоненты, написанные вами прочие модули, и все все все что вам надо. И делаете управление всем этим через регистры. И выдачу данных обратно через регистры. и все.

Также не воспрещается добавлять прочие как входные, так и выходные сигналы, их надо добавить и в пользовательском модуле и в модуле обертке, и соединить в модуле обертке...

Также в модуль обертки можно добавить еще пользовательский модуль если это надо...

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

все-таки не понятно.
1. регистры -приемники и задаются через Bus2IP_Data, Bus2IP_BE,Bus2IP_WrCE. а это входы user_logic.
получается что , если делать свою часть в user_logic, то нужно на внешние входы подавать сигналы из самого же блока. значит либо делать их inout(что вроде как запрещено) либо организовать цепочку выход вход.
2.Bus2IP_Data, Bus2IP_BE,Bus2IP_WrCE- эти сигналы формируются в драйвере. значит их нужно отключить оттуда? да и с содержанием Bus2IP_BE не очень понятно.
3.в user_logic есть как бы две части.slave model и master model?
4. для реализации алгоритма записи с помощью этого компонента (только не одиночной как в примере ,а Burst Write Transaction , как Figure 10: Example Burst Write Transaction Timing DS844) нужно пользоваться master model? здесь есть и адрес и длина записи. но тоже непонятно, как всем этим воспользоваться без сигналов Bus2IP_Data, Bus2IP_BE,Bus2IP_WrCE.
akorud
Цитата(aabmail @ Jun 17 2013, 12:09) *
Обычно mst_reg используются для конфигурирования мастера, и для пользователей не предназначены.
Если что-то единичное хотите передавать, используйте slv_reg( ). Они там случайно не сгенерились?

Там все очень условно. У них в примере - да, причем насколько я помню чтобы показать что можно иметь несколько address space в одном pcore.
Но как только вы начнете изменять мастер (не верю чтоб тот из примера - читаем/пишем FIFO - подошел один к одному) - придется изменять и предназначение регистров.
Golikov A.
да ничего там не условноsm.gif.

В модуль входит шина АКСИ - сложная.
Есть компонент от ксалинкса который сложную акси переделывает в Bus2IP и IP2Bus.

Один от шины в компонент, другой от компонента в шину. Зачем их делать 2 направленными то?



serg_k1
Цитата(Golikov A. @ Jun 14 2013, 17:59) *
глобально компонент это
1. Модуль обертка - который вешается на шину внутри содержит:
1.1 вспомогательный модуль который работает с шиной и преобразует ее сложные сигналы в понятный набор сигналов
Bus2IP - бас ту айпи, от шины к вам и
IP2Bus - обратно
клоки чипселекты, и прочие вспомогательные сигналы.
1.2 Пользовательский модуль, куда заведены эти понятные сигналы

Последний сделан для вас, для редактирования. Изначально он не содержит ничего кроме набора регистров с прописанным примером их чтения и записи.

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

помогите разобраться.
1.модуль ,такой как есть, может работать только по командам от процессора?
2.если да и я хочу чтобы он работал полностью извне, то нужно вот этими сигналами управлять работой.
Bus2IP_Clk : in std_logic;
Bus2IP_Resetn : in std_logic;
Bus2IP_Data : in std_logic_vector(C_SLV_DWIDTH-1 downto 0);
Bus2IP_BE : in std_logic_vector(C_SLV_DWIDTH/8-1 downto 0);
Bus2IP_RdCE : in std_logic_vector(C_NUM_REG-1 downto 0);
Bus2IP_WrCE : in std_logic_vector(C_NUM_REG-1 downto 0);
IP2Bus_Data : out std_logic_vector(C_SLV_DWIDTH-1 downto 0);
IP2Bus_RdAck : out std_logic;
IP2Bus_WrAck : out std_logic;
IP2Bus_Error : out std_logic;
и через них получить доступ к регистрам?
akorud
Цитата(serg_k1 @ Jun 19 2013, 14:21) *
помогите разобраться.
1.модуль ,такой как есть, может работать только по командам от процессора?

Если вы о том примере - да
Цитата(serg_k1 @ Jun 19 2013, 14:21) *
2.если да и я хочу чтобы он работал полностью извне, то нужно вот этими сигналами управлять работой.

Можно конечно, но зачем такое извращение?
Если вам нужно извне управлять - заведите свои сигналы управления модуль.
А что касается регистров - все это условно.
Например FSM bus master - ему откуда-то надо знать что можно начинать работу, откуда и сколько писать или читать. В случае если командует процессор - регистры очевидное решение. Но у вас же своя задача и свои сигналы.... У меня например адрес и размер были вообще зафиксированы, команда "старт" приходила от таймера и регистр я оставил один - для подсчета байтов.
Но никто вам не мешает сделать свой мастер который через упомянутые сигналы будет писать/читать регистры.
serg_k1
Цитата(akorud @ Jun 19 2013, 17:25) *
Если вы о том примере - да

Можно конечно, но зачем такое извращение?
Если вам нужно извне управлять - заведите свои сигналы управления модуль.
А что касается регистров - все это условно.
Например FSM bus master - ему откуда-то надо знать что можно начинать работу, откуда и сколько писать или читать. В случае если командует процессор - регистры очевидное решение. Но у вас же своя задача и свои сигналы.... У меня например адрес и размер были вообще зафиксированы, команда "старт" приходила от таймера и регистр я оставил один - для подсчета байтов.
Но никто вам не мешает сделать свой мастер который через упомянутые сигналы будет писать/читать регистры.

я записываю в фифо данные. они не считываются пока нет команды на запуск. и что можно прямо так
mst_reg(0) <= x"0a"; -- Control Register 0x02= single data beat 0x0a=Burst Assertion Control+Write Request Control
mst_reg(1) <= x"01"; -- Status Register
mst_reg(4) <= x"80"; -- Target Address
mst_reg(5) <= x"00";
mst_reg(6) <= x"00";
mst_reg(7) <= x"00";
mst_reg(8) <= x"00"; -- Master BE
mst_reg(9) <= x"00";
mst_reg(12) <= x"04"; -- Length Register -- bit 0-3 - Reserved
mst_reg(13) <= x"00"; -- bit 4-15 - Transfer Length
mst_reg(14) <= x"00";
mst_reg(15) <= x"0a"; -- Go Register



Цитата(akorud @ Jun 19 2013, 17:25) *
Но никто вам не мешает сделать свой мастер который через упомянутые сигналы будет писать/читать регистры.

т.е. именно те сигналы , которые я перечислил? с сигналом Bus2IP_BE не понятно ведь он завязан с Bus2IP_Data при записи в регистры. Не могли бы пояснить как?
akorud
Цитата(serg_k1 @ Jun 19 2013, 16:05) *
т.е. именно те сигналы , которые я перечислил? с сигналом Bus2IP_BE не понятно ведь он завязан с Bus2IP_Data при записи в регистры. Не могли бы пояснить как?

BE - Byte Enable. Т.е. если Bus2IP_Data шире 8 бит, то BE указывает какие из байтов несут данные (если ширина данных < ширины Bus2IP_Data).
Типичные сценарии:
- запись 8-битного значения на 32-битной шине;
- при burst передаче если размер burst в байтах не кратный 4 (на 32-битной шине) - то при передаче последнего 32-битного слова не все биты Bus2IP_BE будут 1.
Если у вас все данные размерности шины можно записать туда все 1 и не париться.
Golikov A.
чет я не понимаю.
вроде бы 2 задачи
1.
У вас модуль висит на АКСе шине и через нее вы хотите писать в ДДР. Для этой части вы делаете регистровый кусок - мастер шины акси, при помощи которого сможете общатся с память.
2.
Сбор внешних данных которые как раз в память и пишутся. Для этой части вам надо сделать свой кусок который примет внешние сигналы обработает их и перепихает в регистры. Вроде так...


1 часть вроде должен был сделать визард компонента. 2 часть пишется руками, все сигналы заводятся какие надо из вне. Я бы сделал визардом первую часть и научился бы писать - читать память. Получить доступ к шине тоже не тривиальная, может в этом случае ДМА готовое было бы проще...

Только не ляпайте заплаток, если сегодня модуль пишет только 32 битными словами, кто вам сказал что завтра не понадобиться 8 битных?


akorud
Цитата(Golikov A. @ Jun 20 2013, 07:01) *
...который примет внешние сигналы обработает их и перепихает в регистры. Вроде так...

Не так. Регистры служат исключительно для управления мастером, из них они читает что делать, сколько и куда. Данных там нет.
В примере - данные в ФИФО. Я у себя тоже так делал. Но не обязательно.
Golikov A.
каким мастером? как можно управлять мастером?
я так понял этот блок сам должен быть мастером?

serg_k1
Цитата(akorud @ Jun 19 2013, 18:27) *
BE - Byte Enable. Т.е. если Bus2IP_Data шире 8 бит, то BE указывает какие из байтов несут данные (если ширина данных < ширины Bus2IP_Data).
Типичные сценарии:
- запись 8-битного значения на 32-битной шине;
- при burst передаче если размер burst в байтах не кратный 4 (на 32-битной шине) - то при передаче последнего 32-битного слова не все биты Bus2IP_BE будут 1.
Если у вас все данные размерности шины можно записать туда все 1 и не париться.

спасибо, у меня 32р. сделал Bus2IP_BE все единицы. в mst_reg все записал, правда кроме 15. и как раз проблемы с mst_go. mst_go в 1 не могу сделать. делаю Bus2IP_Data в старшем байте = X"0A" при mst_byte_we(GO_BYTE_LANE) = '1' и ничего. ?

Цитата(Golikov A. @ Jun 20 2013, 09:01) *
чет я не понимаю.
вроде бы 2 задачи
1.
У вас модуль висит на АКСе шине и через нее вы хотите писать в ДДР. Для этой части вы делаете регистровый кусок - мастер шины акси, при помощи которого сможете общатся с память.
2.
Сбор внешних данных которые как раз в память и пишутся. Для этой части вам надо сделать свой кусок который примет внешние сигналы обработает их и перепихает в регистры. Вроде так...


1 часть вроде должен был сделать визард компонента. 2 часть пишется руками, все сигналы заводятся какие надо из вне. Я бы сделал визардом первую часть и научился бы писать - читать память. Получить доступ к шине тоже не тривиальная, может в этом случае ДМА готовое было бы проще...

Только не ляпайте заплаток, если сегодня модуль пишет только 32 битными словами, кто вам сказал что завтра не понадобиться 8 битных?

задача такая.
принять данные и передать их через 1Gb интернет.
есть микроблэйз связанный с DDR3 через AXI4 через порт P0 MCB_DDR3. он берет оттуда данные . хочется ввести данные в те же области откуда берет микроблэйз. ввести через AXI4 в порт P1 MCB_DDR3. и задавая адрес в DDR. без участия микроблэйза. поэтому и нужно, чтобы все управление было с внешней стороны.
я думал что самый простой путь - это добавить AXI_External_Master_Connector. у него есть m_axi c одной стороны , а с другой внешний порт. но не получилось. не выставляется сигнал разрешения доступа aw_ready.
тогда начал с этим компонентом. допустим что данные есть. их нужно подключить на вход фифо. и запустить мастер в user_logic. в нем задать адрес , количество и запустить чтение из фифо. но только не по программе микроблэйза, чтобы он не терял время.
и вот если с Example code to demonstrate user logic master model functionality мне вроде как понятно. нужно задать самому из самого компонента в mst_reg режим в Control Register, Addrress Register -адрес. Length Register - количество, Status Register , Byte Enable Register и Go Register пока не ясно и запустить чтение. и смотреть чтобы не было переполнения. по окончании новый адрес и новый цикл. и таким образом заполнять те же области, откуда микроблэйз их будет забирать.
а вот с первой часть примера с набором регистров ничего не понятно. кстати получается что в моей версии эта часть не используется вообще.


Цитата(Golikov A. @ Jun 20 2013, 14:13) *
каким мастером? как можно управлять мастером?
я так понял этот блок сам должен быть мастером?

я думаю что да

Цитата(akorud @ Jun 20 2013, 12:18) *
Не так. Регистры служат исключительно для управления мастером, из них они читает что делать, сколько и куда. Данных там нет.
В примере - данные в ФИФО. Я у себя тоже так делал. Но не обязательно.

если про регистры mst_reg , то да. а вот с slv_reg0 не понятно.
Golikov A.
вообщем это делается так.

Есть микроблайз с ДДР, который как я понимаю данные будет в езернет пихать

Есть ваш компонент внутри с ФИФО, в которое будут данные собираться

и есть ДМА контроллер, уже готовый ксалинксом написанный, который соединит выход вашего фифо и ДДР

если совсем извратиться можно даже так настроить чтобы ДМА данные клало в выходной буфер ЛвИП,

Вот в эту сторону я бы копал, это лучше чем делать своего мастера на шине руками
akorud
Не соглашусь, ну на то тут и форум чтобы можно было различные мнения публиковать.
Зачем ДМА? Зачем 2 порта памяти? Насколько я понял речь идет о 1Gbps - это медленно.
Я сам собственноручно написал модуль принимающий пакеты по ethernet и складывающий в ДДР без участия microblaze. Все чудесно работает с однопортовой ДДР, при частоте шины 50MHz. Где-то тут я уже постил скриншот из XPS.


Цитата(serg_k1 @ Jun 20 2013, 15:53) *
задача такая.
принять данные и передать их через 1Gb интернет.

IP/UDP надо по условию задачи? Скорость поступления данных?
Если данные поступают медленнее чем их высылает сеть, то такая задача решается за полдня, делал недавно и думаю вполне смогу поделится кодом.
Golikov A.
Да я что-то уже путаюсь. Мне кажется что топикстартер где то еще что-то подобное уже обсуждал, а может это кто-то другой. То есть задача раскинута по нескольким топикам, или я ошибаюсь...

Если есть данные которые надо просто передать по езернету, и скорость входа их меньше, то естественно тут даже микроблайз по хорошему не нужен. Но что-то мне подсказывает что когда говорят езернет, то имеют ввиду чтобы в компьютер включить и в виндусе получить. А это уже значит IP, а то и ТСР, UDP - край.

Но даже по UDP задача решаема, есть модули которые напрямую формируют пакеты UDP с контрольной суммой и так далее....

Но я так понимаю речь идет о полной системе, которая нормально видится в сети, и с нее можно забрать какие то намеренные показания, отсюда и строю свое понимание, а именно

что надо взять микроблайз с DDR и LwIP, сделать нормальный серверочек данных с протоколом, а то и что-то стандартное выше уровнем типа ФТП, ХТТП...

а к этой системе уже прикрутить модуль сбора, первичной обработки данных, который их уложит аккуратными стопочками в память.

Я бы конечно бы их из модуля в память перекладывал бы Микроблайзом, но ТС хочет его освободить от этого как я понял, и потому фактически старается написать свой модуль ДМА, а я предлагаю взять готовый...


Вот такое мое понимание задачи, хотя я признаю может я все и перепуталsm.gif...
akorud
Цитата(serg_k1 @ Jun 20 2013, 15:53) *
спасибо, у меня 32р. сделал Bus2IP_BE все единицы. в mst_reg все записал, правда кроме 15. и как раз проблемы с mst_go. mst_go в 1 не могу сделать. делаю Bus2IP_Data в старшем байте = X"0A" при mst_byte_we(GO_BYTE_LANE) = '1' и ничего. ?

А чем вы его смотрите? Если микроблейз - то и не увидите, т.к. он устанавливается только на один цикл и сам сбрасывается. Смотреть на регистр статуса.
serg_k1
Цитата(Golikov A. @ Jun 20 2013, 22:41) *
Да я что-то уже путаюсь. Мне кажется что топикстартер где то еще что-то подобное уже обсуждал, а может это кто-то другой. То есть задача раскинута по нескольким топикам, или я ошибаюсь...

да, я начал обсуждение на первый вариант. там не получилось сделать. но потом нашел уже начатое обсуждение здесь. если кто-то подскажет почему, буду очень признателен.
Цитата
Если есть данные которые надо просто передать по езернету, и скорость входа их меньше, то естественно тут даже микроблайз по хорошему не нужен. Но что-то мне подсказывает что когда говорят езернет, то имеют ввиду чтобы в компьютер включить и в виндусе получить. А это уже значит IP, а то и ТСР, UDP - край.

про скорость было здесь. изначально - байт под 66МГц. нужно распознать, определить что и куда и получается 32р под16МГц. т.е. 0.6Гбита.далее 2 варианта оба нужны ТСР и UDP. почему UDP край? я то думал, что как раз он возможен без микроблэйза. и все обсуждение было для ТСР.
Цитата
что надо взять микроблайз с DDR и LwIP, сделать нормальный серверочек данных с протоколом, а то и что-то стандартное выше уровнем типа ФТП, ХТТП...
а к этой системе уже прикрутить модуль сбора, первичной обработки данных, который их уложит аккуратными стопочками в память.
так и есть.
Цитата
Я бы конечно бы их из модуля в память перекладывал бы Микроблайзом, но ТС хочет его освободить от этого как я понял, и потому фактически старается написать свой модуль ДМА, а я предлагаю взять готовый...

я интернетом пока не занимался. но почитал на форуме. и вычитал , что если микроблэйз будет заниматься подготовкой данных , то гигабит не получить. плата спартан6. поэтому и хотелось его исключить. и еще я не очень понимаю- данные о том, куда записывать и сколько, есть только во внешнем блоке. как микроблэйз будет управлять куда и сколько без получения этих данных. ведь он знает откуда и сколько брать для передачи и не более.
Цитата
и есть ДМА контроллер, уже готовый ксалинксом написанный, который соединит выход вашего фифо и ДДР

микроблэйз уже (это значит, что когда я указываю плату , то эта связь изначально присутствует)соединен с DDR по AXI4 через порт P0 MCB_DDR3 и далее на DDR3. почему нельзя наш компонент с фифо и выходом на axi соединить сразу с входом порта P1 MCB_DDR3. у него есть арбитр и он для этого служит. или не так? и нужна связь компонент -> ДМА -> MCB_DDR3 -> DDR3

Цитата(akorud @ Jun 20 2013, 19:51) *
IP/UDP надо по условию задачи? Скорость поступления данных?
Если данные поступают медленнее чем их высылает сеть, то такая задача решается за полдня, делал недавно и думаю вполне смогу поделится кодом.

скорость менее 1Г. изначально думал просто выдывать по UDP .без микроблэйза и без любого IP Ethernet. плата спартан 6 SP605. просто через М88Е1111. но не смог найти информацию для инициализации этой м\с(MDIO). вроде находилась информация, что функциональный аналог DP83865 и можно воспользоваться. в стандарте больно много всего. т.е. в какие именно регистры нужна запись? но такая передача собственно и сейчас интересует. так что буду рад, если можно поделиться кодом.

Цитата(akorud @ Jun 21 2013, 10:58) *
А чем вы его смотрите? Если микроблейз - то и не увидите, т.к. он устанавливается только на один цикл и сам сбрасывается. Смотреть на регистр статуса.

в XPS создан микроблейз с компонентом. далее в ISE его правлю . делаю выходы в user_ligic для my_wrce ,my_Bus2IP_Data , my_Bus2IP_BE завожу их обратно . записываю нужную мне инф. в mst_reg в 0..14, в 15 там не записывается. потом выполняю все условия для выполнения mst_go <= '1'; в MASTER_WRITE_GO_PORT и в ISim смотрю. и хочу увидеть запуск чтения из фифо.
akorud
Как то все очень запутано - кажется ТС пробует "объять необъятное" причем все и сразу.

Цитата(serg_k1 @ Jun 24 2013, 07:43) *
скорость менее 1Г. изначально думал просто выдывать по UDP .без микроблэйза и без любого IP Ethernet. плата спартан 6 SP605. просто через М88Е1111.

Я бы сделал (и уже делал) так:
1. берем IP Ethernet стандартный. У него вход данных AXI-stream, проще некуда;
2. Насколько я помню ничего в PHY изменять не надо, он сам стартует в режиме 1Gb Autoneg, я правда делал на KC705 но даже не интересовался какой там PHY.
3. Пишем свой модуль который будет генерировать фиксированный заголовок Ethernet перед каждыми N (например 1500) байтами полезных данных и высылать по AXI-stream.
4. На PC запускаем простейшую программку под Linux принимающую все это через raw socket и далее можно делать что душе угодно - хоть в файл, хоть в UDP, хоть в TCP.
На все - день работы.
Все усложнения (микроблейз например) должны ясно следовать из условий ТЗ, ну или если поиграться хочется и бюджет есть sm.gif
serg_k1
Цитата(akorud @ Jun 24 2013, 14:03) *
Как то все очень запутано - кажется ТС пробует "объять необъятное" причем все и сразу.


Я бы сделал (и уже делал) так:
1. берем IP Ethernet стандартный. У него вход данных AXI-stream, проще некуда;

я нашел только Tri_mod_Eth с AXI-stream и в нем там масса модулей...? и если это он , то можно поподробней.
akorud
Цитата(serg_k1 @ Jun 24 2013, 16:03) *
я нашел только Tri_mod_Eth с AXI-stream и в нем там масса модулей...? и если это он , то можно поподробней.

Да, он.
Простой рабочий пример (только на передачу).
Сигналы ETHERNET_* - прямо на пины PHY. Не забудьте phy_reset_n установить в 1 так он active low.
clk_125M_tx - ваша забота; clk_125M_rx - придет от PHY.
Код
//----------------------------------------------------------------------------
// Ethernet
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
// TX PHY physical interface interface
//----------------------------------------------------------------------------

wire [7:0] gmii_txd;
wire gmii_tx_en;
wire gmii_tx_er;

always @(posedge clk_125M_tx) begin
    ETHERNET_TXD <= gmii_txd;
    ETHERNET_TX_EN <= gmii_tx_en;
    ETHERNET_TX_ER <= gmii_tx_er;
end    

ODDR #(
    .DDR_CLK_EDGE("OPPOSITE_EDGE"),
    .INIT(1'b0),
    .SRTYPE("SYNC")
) ODDR_inst (
      .Q(ETHERNET_TX_CLK),
      .C(clk_125M_tx),
      .CE(1'b1),
      .D1(1'b0),
      .D2(1'b1),
      .R(1'b0),
      .S(1'b0)
);

//----------------------------------------------------------------------------
// RX PHY physical interface interface
//----------------------------------------------------------------------------

wire clk_125M_rx_io;

BUFIO BUFIO_inst (.I(ETHERNET_RX_CLK), .O(clk_125M_rx_io));
BUFG BUFG_inst (.I(ETHERNET_RX_CLK), .O(clk_125M_rx));

reg [7:0] gmii_rxd;
reg gmii_rx_dv;
reg gmii_rx_er;

always @(posedge clk_125M_rx_io) begin
    gmii_rxd <= ETHERNET_RXD;
    gmii_rx_dv <= ETHERNET_RX_DV;
    gmii_rx_er <= ETHERNET_RX_ER;
end    

//----------------------------------------------------------------------------
// Core itself
//----------------------------------------------------------------------------

wire mac_tx_reset;
reset_sync rsync_mac_tx(.clk(clk_125M_tx), .areset(1'b0), .reset(mac_tx_reset), .resetn());

wire mac_rx_reset;
reset_sync rsync_mac_rx(.clk(clk_125M_rx), .areset(1'b0), .reset(mac_rx_reset), .resetn());

wire [79:0] tx_mac_config_vector = {64'b0, 15'b0010_0000_0000_001, mac_tx_reset};
wire [79:0] rx_mac_config_vector = {64'b0, 15'b0010_0000_0000_001, mac_rx_reset};

tri_mode_eth_mac tri_mode_eth_mac (
    .glbl_rstn(1'b1),
    .rx_axi_rstn(1'b1),
    .tx_axi_rstn(1'b1),
    .rx_axi_clk(clk_125M_rx),
    .rx_reset_out(),
    .rx_axis_mac_tdata(),
    .rx_axis_mac_tvalid(),
    .rx_axis_mac_tlast(),
    .rx_axis_mac_tuser(),
    .rx_statistics_vector(),
    .rx_statistics_valid(),
    .tx_axi_clk(clk_125M_tx),
    .tx_reset_out(),
    .tx_axis_mac_tdata(eth_axis_tdata),
    .tx_axis_mac_tvalid(eth_axis_tvalid),
    .tx_axis_mac_tlast(eth_axis_tlast),
    .tx_axis_mac_tuser(1'b0),
    .tx_axis_mac_tready(eth_axis_tready),
    .tx_ifg_delay(8'b0),
    .tx_statistics_vector(),
    .tx_statistics_valid(),
    .pause_req(1'b0),
    .pause_val(16'b0),
    .speed_is_100(),
    .speed_is_10_100(),
    .gmii_txd(gmii_txd),
    .gmii_tx_en(gmii_tx_en),
    .gmii_tx_er(gmii_tx_er),
    .gmii_rxd(gmii_rxd),
    .gmii_rx_dv(gmii_rx_dv),
    .gmii_rx_er(gmii_rx_er),
    .rx_mac_config_vector(rx_mac_config_vector), // input [79 : 0] rx_mac_config_vector
    .tx_mac_config_vector(tx_mac_config_vector) // input [79 : 0] tx_mac_config_vector
);

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.