Jump to content

    

DMA IP Core

Доброго дня.

Знает ли кто, чем заменить стандартный Xilinx AXI DMA IP Core?

Реализация от Xilinx устраивает всем кроме объема информации, который можно записать за раз (8 Мб). В идеале, хочется чтобы можно было записать до полугигабайта. DMA используется в single burst mode (не scatter/gather) для записи потока информации в память, прерывания не используются. Программирование DMA происходит прикладной программой из Linux путем записи в регистры. Об окончании записи нужного куска потока становится известно исходя из статуса регистров DMA (программа их периодически опрашивает). IP Core должно работать на Zynq-7000 и Zynq-UltraScale.

Заранее спасибо!

Share this post


Link to post
Share on other sites

Приветствую!

А все же чем  scatter/gather вас не устраивает?   Если же scatter/gather  неприемлем вам по идеологическим причинам то нужен свой самобытный DMA с требуемым характеристиками трансфера. Пишется он относительно не сложно. Либо все полностью самому,  либо используя AXI Data Mover как ядро.

Удачи! Rob.

Share this post


Link to post
Share on other sites

Добрый вечер,

Спасибо за ответ. Проблема тут скорее в моей неопытности и недостаточной образованности. Можете, если не сложно, поделиться ссылкой на то, как писать DMA (с английским вполне дружу)?

Более полная версия проблемы выглядит так. Год назад под технической задание был собран дизайн с парой-тройкой IP собственной разработки (в меру ужасных, ибо это мой первый проект для FPGA), который уже стал частью работающего аппаратно-программного комплекса. Теперь техническое задание изменилось. Хочется выйти из ситуации с минимальными потерями по времени (включая не только время на переработку дизайна, но и время на переработку софта). Вариант готового IP Core за деньги тоже рассматривается, но вот выбрать из имеющегося по неопытности не особо получается.

Заранее спасибо, Михаил.

Share this post


Link to post
Share on other sites

Приветствую!

Книжку  типа "Искусство написания эффективного DMA" я бы и сам почитал :wink2:  А для вашего случая для начала можете почитать datasheet на AXI Data Mover (на нем кстати, и сделан AXI DMA) который фактически и осуществляет трансфер. Вам надо будет прикрутить  к нему простейший FSM который будет запускать Mover несколько раз пока все ваши гигабайты  не утекут в память.  Управление этим FSM сделать через AXI Lite.  При нежелании менять софт можно будет даже повторить структуру регистров управления как в AXI DMA. Ну это уже кому что проще. 

Удачи! Rob.

Share this post


Link to post
Share on other sites

Добавлю сам себе. В Vivade 2019.1 (может и раньше, но не ранее 2018.1)  стандартный Xilinx AXI DMA IP Core умеет писать за раз уже 64 Мб.

Share this post


Link to post
Share on other sites

На HLS такое пишется в несколько строк. 

Share this post


Link to post
Share on other sites
10 minutes ago, fguy said:

На HLS такое пишется в несколько строк. 

А можете показать? Ну т.е. типа вот код на hls, вот соответствующий ему HDL. Ну и приложить оба файла/проекта. 

Спасибо.

PS. Без какого либо стеба, мне действительно это интересно.

Share this post


Link to post
Share on other sites
2 hours ago, des00 said:

А можете показать? Ну т.е. типа вот код на hls, вот соответствующий ему HDL. Ну и приложить оба файла/проекта. 

Спасибо.

PS. Без какого либо стеба, мне действительно это интересно.

 описание https://www.xilinx.com/support/documentation/application_notes/xapp1163.pdf проект во вложении

pid_regulator.zip   Vivado HLS 2016.2

 

описание на xHDL в PID\pid_regulator\pid_regulator\syn

Share this post


Link to post
Share on other sites
1 hour ago, Maverick_ said:

 описание https://www.xilinx.com/support/documentation/application_notes/xapp1163.pdf проект во вложении

pid_regulator.zip   Vivado HLS 2016.2

 

описание на xHDL в PID\pid_regulator\pid_regulator\syn

спасибо, правда это математическое ядро, как там делается, я представляю в принципе. интересно было именно DMA IP)

Share this post


Link to post
Share on other sites
8 hours ago, des00 said:

интересно было именно DMA IP

в хлс все как в обычном си - память как массив - копирование в цикле или мемкопи - весь фокус состоит в том чтобы правильно сформировать берст и выровнять поток со стрима для получения максимально-возможной скорости записи в ддр

Share this post


Link to post
Share on other sites
3 hours ago, fguy said:

в хлс все как в обычном си - память как массив - копирование в цикле или мемкопи - весь фокус состоит в том чтобы правильно сформировать берст и выровнять поток со стрима для получения максимально-возможной скорости записи в ддр

спасибо, на словах я понимаю как это сделано, мне бы код на си и на языке. как я понял, для вас, это не сложно. Код от хилых ПИДовский я отреверсил, реализация тривиальная, довольно забавный у них автомат генерации FSM и обработки состояний, да еще и автор генератора из старых сишников похоже, а вот именно ДМА и его интеграцию в систему, я бы поковырял.

Share this post


Link to post
Share on other sites

Код пишется под конкретную задачу - ширина и скорость входного потока данных на стриме, тип ддр-контролера - процессорный или плис и т.п.. Для ультрацинков будут свои особенности из за более широкого адреса. Фактически решение получается не в одном ядре, а в совокупности ядра на хлс и штатных ядер в блок дизайне с правильной настройкой параметров всех ядер.

Код на си простой

for (i = 0; i < count_word; i++)
{
	Mem[addr++] = data;
}

А весь остальной "обвес" будет зависеть от ваших потребностей.

Edited by fguy

Share this post


Link to post
Share on other sites
3 hours ago, fguy said:

Код пишется под конкретную задачу - ширина и скорость входного потока данных на стриме, тип ддр-контролера - процессорный или плис и т.п.. Для ультрацинков будут свои особенности из за более широкого адреса. Фактически решение получается не в одном ядре, а в совокупности ядра на хлс и штатных ядер в блок дизайне с правильной настройкой параметров всех ядер.

Код на си простой


for (i = 0; i < count_word; i++)
{
	Mem[addr++] = data;
}

А весь остальной "обвес" будет зависеть от ваших потребностей.

да про си код я понял. мне бы верилог/вхдл посмотреть, в самом простом варианте пусть будет. SRAM 32 мегабайта, выкачивание куска 32 мегабайта одной транзакцией. Хочу глянуть какие корки будут задействованы, как он развяжет акси на обоих сторонах, как закеширует данные и т.д.

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

Share this post


Link to post
Share on other sites

В атаче вхдл ядра копировщика между двумя акси-мастерами (64 бит данные) с управлением по акси лайт. Читаемость кода у хлс синтезатора еще та - ну сами напросились.

mem_copy.zip

Share this post


Link to post
Share on other sites

Приветствую!

На скорую руку получилось  во такое 

#include <iomanip>
#include <cstdlib>

#include <stdint.h>

using namespace std;

#define DEPTH 64

void hls_dma (uint32_t dst_len, volatile uint32_t *s_axis,  volatile uint32_t *m_axi) {
  #pragma HLS INTERFACE s_axilite port=return      bundle=BUS_A
  #pragma HLS INTERFACE s_axilite port=dst_len     bundle=BUS_A
  
  #pragma HLS INTERFACE axis port=s_axis depth=64

  #pragma HLS INTERFACE m_axi depth=64 port=m_axi offset=slave \
  num_read_outstanding=4 num_write_outstanding=4 max_read_burst_length=16 max_write_burst_length=16
  
  uint32_t len;
  uint32_t buff[DEPTH];

  while (dst_len>0) {
    len = (dst_len>DEPTH) ? DEPTH : dst_len;

    dst_len = dst_len - len;

    sin : for (int ii=0; ii<len; ++ii) {
      buff[ii]=*s_axis;
    }

    // memcpy creates a burst access to memory
    // multiple calls of memcpy cannot be pipelined and will be scheduled sequentially
    // memcpy requires a local buffer to store the results of the memory transaction
    memcpy((void *)m_axi, (void *)buff, len*sizeof(uint32_t));
    m_axi += len;
  }
}

И даже в симе работает. Но с эффективность 50%. То ест сначала из стрима в буфер,  а потом уж из буфера на m_axi. Чтобы  все в pieline работало надо наверное разносить  чтение из стрима и вывод в m_axi  в отдельные функции которые объединять в основной через flip-floop буфер.  Ну и с pragma возиться.  

Вообще чтобы  на HSL начать писать RTL  эффективный код надо изнасиловать в себе как программиста С/С++ так и RTLщика. :mega_shok:

Удачи! Rob.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now