# PS-\>DMA-\>BRAM data transfer?

**URL:** <https://discuss.pynq.io/t/ps-dma-bram-data-transfer/4823>\
**Category:** Support\
**Created:** [October 24, 2022, 7:27pm UTC](https://discuss.pynq.io/t/ps-dma-bram-data-transfer/4823 "2022-10-24T19:27:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Anirudh\_Itagi](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/anirudh_itagi/32/3853_2.png) [@Anirudh\_Itagi](https://discuss.pynq.io/u/Anirudh_Itagi)\
**Post date:** [October 24, 2022, 7:27pm UTC](https://discuss.pynq.io/t/ps-dma-bram-data-transfer/4823/1 "2022-10-24T19:27:42Z")

</div>

Hi,  
I need to around 200 kB of data from PS-\>PL’s BRAMs  
I initially explored the [mmio tutorial](https://www.youtube.com/watch?v=zbumITJQ2Z8&ab_channel=CathalMcCabe) shared by @cathalmccabe. (thank you for the very well explained video! )  
And while it was working well, I found the transfer speed to slower than what I need.

It takes roughly 24 ms to transfer 200 kB of data:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/7/7b2c5e878f3427fd28e8f316a87ed83a3088d14f.png)

I need to reduce that speed to 1 ms.

and so I began exploring DMA to transfer data from PS to PL. Here is snip of what I implemented:

 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/3/392bc31867a0f8909f4eefd2b763321f9906f022.jpeg)

In the above diagram, I am using the DMA to transfer data into blk\_mem\_gen\_0 (through port A)  
and verifying whether the data is transferred into it by reading from port B with mmio read.

But even though I initiate dma send and recv (without errors), I observe that data is not written into blk\_mem\_gen\_0  
neither is it written into blk\_mem\_gen\_1, I confirm this by reading from blk\_mem\_gen\_1 as well.

Can someone please help me understand what is going wrong?  
how can I transfer data to BRAM using DMA?  
or is there a faster way to transfer data into BRAM (without DMA?)?

Any help would be appreciated.

Regards,  
AI

---

<div class="post-metadata">

**Author:** ![cathalmccabe](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/cathalmccabe/32/3348_2.png) [@cathalmccabe](https://discuss.pynq.io/u/cathalmccabe)\
**Post date:** [October 24, 2022, 8:20pm UTC](https://discuss.pynq.io/t/ps-dma-bram-data-transfer/4823/2 "2022-10-24T20:20:31Z")

</div>

You don’t want to do what you are trying in the block diagram you shared. The DMA is intended to read from PS DRAM and stream data to a peripheral (AXI stream).  
What are you trying to do with the data?

- what is your IP doing and what interfaces does it have?
- what language have you implemented it in - VHDL/Verilog, HLS?

Cathal

---

<div class="post-metadata">

**Author:** ![Anirudh\_Itagi](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/anirudh_itagi/32/3853_2.png) [@Anirudh\_Itagi](https://discuss.pynq.io/u/Anirudh_Itagi)\
**Post date:** [October 24, 2022, 8:27pm UTC](https://discuss.pynq.io/t/ps-dma-bram-data-transfer/4823/3 "2022-10-24T20:27:21Z")

</div>

Hi @cathalmccabe,  
Thank you for replying.

I intend to receive data via ethernet(with the PS) and from there stream the data into BRAM (True Dual Port), and I have an IP which will read from the BRAM’s 2nd port and process it.

I intend to give my IP an interface to access the BRAM and it will be in Verilog.  
Right now I just want to transfer data from PS to PL BRAM [~200 kB of data in 1ms]

---

<div class="post-metadata">

**Author:** ![cathalmccabe](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/cathalmccabe/32/3348_2.png) [@cathalmccabe](https://discuss.pynq.io/u/cathalmccabe)\
**Post date:** [October 25, 2022, 7:49am UTC](https://discuss.pynq.io/t/ps-dma-bram-data-transfer/4823/4 "2022-10-25T07:49:54Z")

</div>

You didn’t say how you are designing your IP.

If you are using HLS, you can add an AXI master interface that can access the PS memory directly. This is probably better than trying to copy to BRAM. No separate DMA required.

See this tutorial:

> [@Tutorial: AXI Master interfaces with HLS IP](https://discuss.pynq.io/t/tutorial-axi-master-interfaces-with-hls-ip/4032):
>
> PYNQ HLS AXI Master tutorial Introduction Previous tutorials show how to build IP with AXI stream interfaces and how they can be connected in a Vivado project to an AXI DMA. The DMA can be controlled from PYNQ to send data to the IP and receive results. AXI stream interfaces are useful if you are connecting multiple IP together in a dataflow type architecture. However, you don’t have to use AXI streams and DMAs with HLS IP. HLS supports AXI master interfaces which can read and write data as r…

Cathal

---

<div class="post-metadata">

**Author:** ![Anirudh\_Itagi](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/anirudh_itagi/32/3853_2.png) [@Anirudh\_Itagi](https://discuss.pynq.io/u/Anirudh_Itagi)\
**Post date:** [November 3, 2022, 7:05pm UTC](https://discuss.pynq.io/t/ps-dma-bram-data-transfer/4823/5 "2022-11-03T19:05:42Z")

</div>

Hi @cathalmccabe, Thank you for the suggestion.  
I tried the AXI Master interface with HLS IP tutorial and I can see the speed of data transfer is much faster.  
I am also able to connect the HLS to a BRAM successfully.

May I ask for one more help? I am new to HLS and I don’t know how to pass an array of data as an argument to the function.

This is the original code in the example:

```auto

void example(volatile int *a, int length, int value){
#pragma HLS INTERFACE m_axi port=a depth=50 offset=slave
#pragma HLS INTERFACE s_axilite port=length
#pragma HLS INTERFACE s_axilite port=value
#pragma HLS INTERFACE s_axilite port=return

	int i;
  int buff[1024];
  
  //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(buff,(const int*)a,length*sizeof(int));
  
  for(i=0; i < length; i++){
    buff[i] = buff[i] + value;
  }
  
  memcpy((int *)a,buff,length*sizeof(int));
}

```

and I want to pass an array (say int value[1024] ) instead. can you please suggest how I can proceed?

This is what I tried:

```auto
void example(volatile int *a, int length, int value[1024]){
#pragma HLS INTERFACE m_axi port=a depth=50 offset=slave
#pragma HLS INTERFACE s_axilite port=length
#pragma HLS INTERFACE s_axilite port=value[1024]
#pragma HLS INTERFACE s_axilite port=return

	int i;
  int buff[1024];
  
  //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(buff,(const int*)a,length*sizeof(int));
  
  for(i=0; i < length; i++){
    buff[i] = buff[i] + value[i];
  }
  
  memcpy((int *)a,buff,length*sizeof(int));
}

```

but this is not working as I intended. it is generating `int value[1024]` as a port of the HLS IP, but I want to assign data to the array within the PS and then have the HLS IP stream content of the array to BRAM
