# DMA sendchannel.transfer() and wait() stuck with larger buffer

**URL:** https://discuss.pynq.io/t/dma-sendchannel-transfer-and-wait-stuck-with-larger-buffer/7746
**Category:** Support
**Created:** [November 18, 2024, 5:18am UTC](https://discuss.pynq.io/t/dma-sendchannel-transfer-and-wait-stuck-with-larger-buffer/7746 "2024-11-18T05:18:51Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![ja2021](https://avatars.discourse-cdn.com/v4/letter/j/3da27b/32.png) [@ja2021](https://discuss.pynq.io/u/ja2021)
#### Post date: [November 18, 2024, 5:18am UTC](https://discuss.pynq.io/t/dma-sendchannel-transfer-and-wait-stuck-with-larger-buffer/7746/1 "2024-11-18T05:18:51Z")

</div>

Hello, I’m trying to use dma with vitis hls and pynq os to transfer the data and do some kind of simple adding.

My board is ZCU104 board.

When I assign input buffer in pynq (jupyter notebook) with allocate for size of smaller than 256, it have no problem.  
However when I try with larger buffer, it just stuck at dma.sendchannel.wait() line.

I allocate like this  
“allocate(shape=256, dtype=np.float32)”

And when I move on to

> print(cc.sendchannel.idle)  
> cc.sendchannel.transfer(c)  
> print(cc.sendchannel.idle)  
> cc.sendchannel.wait()  
> print(cc.sendchannel.idle)  
> print part always say False and the notebook just stuck at wait().

I don’t understand why this just stuck when allocate shape increase.

I use 2 dma with same setting in vivado.

 ![스크린샷 2024-11-18 141158](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/3/34061af6c8d5e9d275eab9d27067733330f80fa0.png)

This is my header file in hls.

> #include \<stdio.h\>  
> #include \<stdlib.h\>  
> #include \<string.h\>  
> #include \<ap\_fixed.h\>  
> #include “hls\_stream.h”  
> #include “ap\_axi\_sdata.h”
> 
> #ifndef POLY\_H  
> #define POLY\_H
> 
> #define VECTOR\_LEN 30000  
> #define VECTOR\_LEN\_tb 30000
> 
> typedef float f\_data\_type;
> 
> typedef ap\_axis\<32, 0, 0, 0\> stream\_val;  
> typedef hls::stream\<stream\_val\> stream\_val\_data;
> 
> typedef union {  
> uint32\_t iint;  
> float ffloat;  
> } fp\_data;
> 
> void poly(  
> stream\_val\_data &co,  
> stream\_val\_data &i,  
> volatile float \*ii\_t,  
> volatile float \*cc1\_t,  
> volatile float \*cc2\_t,  
> volatile float \*oo1\_t,  
> volatile float \*oo2\_t);
> 
> #endif

This is testbench in hls.

> #include \<stdio.h\>  
> #include \<stdio.h\>  
> #include \<stdlib.h\>  
> #include   
> #include \<math.h\>  
> #include “poly.h”
> 
> unsigned globalSeed;
> 
> int main(void){  
> bool correct = true;
> 
> ```
> f_data_type *ttco = (f_data_type *) malloc(sizeof(f_data_type) * 2*VECTOR_LEN_tb);
> f_data_type *tti = (f_data_type *) malloc(sizeof(f_data_type) * VECTOR_LEN_tb);
> f_data_type *tto = (f_data_type *) malloc(sizeof(f_data_type) * VECTOR_LEN_tb);
> f_data_type *o_t = (f_data_type *) malloc(sizeof(f_data_type) * VECTOR_LEN_tb);
> f_data_type *i_test = (f_data_type *) malloc(sizeof(f_data_type) * VECTOR_LEN_tb);
> f_data_type *c1_test = (f_data_type *) malloc(sizeof(f_data_type) * VECTOR_LEN_tb);
> f_data_type *c2_test = (f_data_type *) malloc(sizeof(f_data_type) * VECTOR_LEN_tb);
> f_data_type *o1_test = (f_data_type *) malloc(sizeof(f_data_type) * VECTOR_LEN_tb);
> f_data_type *o2_test = (f_data_type *) malloc(sizeof(f_data_type) * VECTOR_LEN_tb);
> 
> memset(ttco, 0, sizeof(f_data_type) * 2*VECTOR_LEN_tb);
> memset(tti, 0, sizeof(f_data_type) * VECTOR_LEN_tb);
> memset(tto, 0, sizeof(f_data_type) * VECTOR_LEN_tb);
> memset(o_t, 0, sizeof(f_data_type) * VECTOR_LEN_tb);
> memset(i_test, 0, sizeof(f_data_type) * VECTOR_LEN_tb);
> memset(c1_test, 0, sizeof(f_data_type) * VECTOR_LEN_tb);
> memset(c2_test, 0, sizeof(f_data_type) * VECTOR_LEN_tb);
> memset(o1_test, 0, sizeof(f_data_type) * VECTOR_LEN_tb);
> memset(o2_test, 0, sizeof(f_data_type) * VECTOR_LEN_tb);
> 
> for (int cc=0; cc<2*VECTOR_LEN_tb;cc++){
> ttco[cc] = (float) (rand() % 1024 - 512) / 512;
> }
> for (int cc=0; cc<VECTOR_LEN_tb;cc++){
> tti[cc] = (float) (rand() % 1024 - 512) / 512;
> }
> tto[0] = 0;
> o_t[0] = 0;
> 
> printf("============TESTBENCH============\n");
> printf("a: %f, ", ttco[0]);
> printf("b: %f, ", ttco[1]);
> printf("c: %f, ", ttco[VECTOR_LEN_tb]);
> printf("d: %f, ", ttco[VECTOR_LEN_tb+1]);
> printf("i: %f, ", tti[0]);
> printf("o: %f\n", tto[0]);
> 
> stream_val_data a_stream("coeff input");
> stream_val_data i_stream("input");
> stream_val_data c_stream("output");
> 
> stream_val tmp_input;
> fp_data tmp_input_f;
> 
> for (int i = 0; i < 2*VECTOR_LEN_tb; i++){
> tmp_input_f.ffloat = f_data_type(ttco[i]);
> tmp_input.data = tmp_input_f.iint;
> tmp_input.keep = 1;
> if ((i + 1) % VECTOR_LEN_tb == 0) {
> tmp_input.last = 1;
> } else {
> tmp_input.last = 0;
> }
> a_stream.write(tmp_input);
> }
> 
> stream_val tmp_input2;
> fp_data tmp_input2_f;
> 
> for (int j = 0; j < VECTOR_LEN_tb; j++){
> tmp_input2_f.ffloat = f_data_type (tti[j]);
> tmp_input2.data = tmp_input2_f.iint;
> tmp_input2.keep = 1;
> if(j==VECTOR_LEN_tb-1){
> tmp_input2.last = 1;
> }
> else{
> tmp_input2.last = 0;
> }
> i_stream.write(tmp_input2);
> }
> 
> poly(a_stream, i_stream, i_test, c1_test, c2_test, o1_test, o2_test);
> 
> o_t[0] = tti[0] + ttco[0] + ttco[1] + ttco[VECTOR_LEN_tb] + ttco[VECTOR_LEN_tb+1];
> printf("o_t: %f\n", o_t[0]);
> printf("o: %f\n", tto[0]);
> 
> printf("i_test %f\n", i_test[0]);
> printf("c1_test %f %f \n", c1_test[0], c1_test[1]);
> printf("c2_test %f %f \n", c2_test[0], c2_test[1]);
> printf("o1_test %f \n", o1_test[0]);
> printf("o2_test %f \n", o2_test[0]);
> 
> if (o2_test[0] != o_t[0]){
> correct = false;
> }
> 
> free(ttco);
> free(tti);
> free(tto);
> free(o_t);
> free(i_test);
> free(c1_test);
> free(c2_test);
> free(o1_test);
> free(o2_test);
> 
> if (correct){
> printf("Test successful\n");
> return 0;
> } else{
> printf("Test unsuccessful\n");
> return 0;
> }
> 
> ```
> 
> }

This is my code in hls.

> #include \<stdio.h\>  
> #include \<stdlib.h\>  
> #include \<string.h\>  
> #include \<math.h\>  
> #include “./poly.h”
> 
> void poly(  
> stream\_val\_data &co,  
> stream\_val\_data &i,  
> volatile float \*ii\_t,  
> volatile float \*cc1\_t,  
> volatile float \*cc2\_t,  
> volatile float \*oo1\_t,  
> volatile float \*oo2\_t  
> ){  
> #pragma HLS INTERFACE axis register both port=co  
> #pragma HLS INTERFACE axis register both port=i  
> #pragma HLS INTERFACE m\_axi port = ii\_t depth = 1024 offset = slave bundle = ii\_t\_port  
> #pragma HLS INTERFACE m\_axi port = cc1\_t depth = 1024 offset = slave bundle = cc1\_t\_port  
> #pragma HLS INTERFACE m\_axi port = cc2\_t depth = 1024 offset = slave bundle = cc2\_t\_port  
> #pragma HLS INTERFACE m\_axi port = oo1\_t depth = 1024 offset = slave bundle = oo1\_t\_port  
> #pragma HLS INTERFACE m\_axi port = oo2\_t depth = 1024 offset = slave bundle = oo2\_t\_port
> 
> ```
> #pragma HLS INTERFACE s_axilite port = ii_t bundle = CONTROL_BUS
> #pragma HLS INTERFACE s_axilite port = cc1_t bundle = CONTROL_BUS
> #pragma HLS INTERFACE s_axilite port = cc2_t bundle = CONTROL_BUS
> #pragma HLS INTERFACE s_axilite port = oo1_t bundle = CONTROL_BUS
> #pragma HLS INTERFACE s_axilite port = oo2_t bundle = CONTROL_BUS
> 
> #pragma HLS INTERFACE s_axilite port = return bundle = CONTROL_BUS
> 
> f_data_type cco[30000];
> f_data_type ii[30000];
> f_data_type oo[1];
> f_data_type oo2[1];
> 
> stream_val tmp_co;
> stream_val tmp_co2;
> stream_val tmp_in;
> stream_val tmp_out;
> 
> fp_data tmp_coo;
> fp_data tmp_co2o;
> fp_data tmp_ino;
> fp_data tmp_outo;
> 
> for(int j = 0; j < VECTOR_LEN; j++){
> co.read(tmp_co);
> tmp_coo.iint = tmp_co.data;
> cco[j] = tmp_coo.ffloat;
> cc1_t[j] = cco[j];
> }
> 
> for(int j = 0; j < VECTOR_LEN; j++){
> i.read(tmp_in);
> tmp_ino.iint = tmp_in.data;
> ii[j] = tmp_ino.ffloat;
> ii_t[j] = ii[j];
> // printf("%f\n", cco[j]);
> // printf("a: %s\n", cco[j].to_string(10).c_str());
> 
> // tmp_in.last = (j == VECTOR_LEN-1) ? 1 : 0;
> }
> 
> oo[0] = ii[0] + cco[0] + cco[1];
> oo1_t[0] = oo[0];
> 
> for(int j = 0; j < VECTOR_LEN; j++){
> co.read(tmp_co);
> tmp_coo.iint = tmp_co.data;
> cco[j] = tmp_coo.ffloat;
> cc2_t[j] = cco[j];
> }
> 
> oo2[0] = oo[0] + cco[0] + cco[1];
> oo2_t[0] = oo2[0];
> 
> ```
> 
> }

I want to set allocate shape larger than 30000.

---

<div class="post-metadata">

### Author: ![matthew](https://avatars.discourse-cdn.com/v4/letter/m/ed655f/32.png) [@matthew](https://discuss.pynq.io/u/matthew)
#### Post date: [November 18, 2024, 9:15am UTC](https://discuss.pynq.io/t/dma-sendchannel-transfer-and-wait-stuck-with-larger-buffer/7746/2 "2024-11-18T09:15:41Z")

</div>

Hi,  
Did you check this post?

# [Debugging Common DMA Issues [Part 3]](https://discuss.pynq.io/t/debugging-common-dma-issues-part-3/7157)

---

<div class="post-metadata">

### Author: ![ja2021](https://avatars.discourse-cdn.com/v4/letter/j/3da27b/32.png) [@ja2021](https://discuss.pynq.io/u/ja2021)
#### Post date: [November 18, 2024, 9:29am UTC](https://discuss.pynq.io/t/dma-sendchannel-transfer-and-wait-stuck-with-larger-buffer/7746/3 "2024-11-18T09:29:10Z")

</div>

Yes but it didn’t solved my problem.

---

<div class="post-metadata">

### Author: ![matthew](https://avatars.discourse-cdn.com/v4/letter/m/ed655f/32.png) [@matthew](https://discuss.pynq.io/u/matthew)
#### Post date: [November 18, 2024, 9:32am UTC](https://discuss.pynq.io/t/dma-sendchannel-transfer-and-wait-stuck-with-larger-buffer/7746/4 "2024-11-18T09:32:23Z")

</div>

Can you please send a picture of your block design, to see what is connected to the DMA block?

---

<div class="post-metadata">

### Author: ![ja2021](https://avatars.discourse-cdn.com/v4/letter/j/3da27b/32.png) [@ja2021](https://discuss.pynq.io/u/ja2021)
#### Post date: [November 18, 2024, 11:56pm UTC](https://discuss.pynq.io/t/dma-sendchannel-transfer-and-wait-stuck-with-larger-buffer/7746/5 "2024-11-18T23:56:33Z")

</div>

![스크린샷 2024-11-19 085612](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/3/35a6b9fb9c716f995cd2070fdd64f84277076111.png)  
Here’s the block design

---

<div class="post-metadata">

### Author: ![joshgoldsmith](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/joshgoldsmith/32/5347_2.png) [@joshgoldsmith](https://discuss.pynq.io/u/joshgoldsmith)
#### Post date: [November 21, 2024, 11:14am UTC](https://discuss.pynq.io/t/dma-sendchannel-transfer-and-wait-stuck-with-larger-buffer/7746/6 "2024-11-21T11:14:30Z")

</div>

Hi @ja2021

PYNQ’s `allocate()` function requires the `shape` parameter to be a tuple (e.g. `allocate(shape=(256,), dtype=np.float32)` not `allocate(shape=256, dtype=np.float32)` as you have in your example). The `PynqBuffer` class inherits from `numpy.ndarray`, so its [documentation](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) might be useful in explaining why this is the case.

In terms of debugging beyond that, have you tried simulating the behaviour of different-sized buffers in HLS? If so, I would also advise adding an ILA to your Vivado design and checking the signals coming in and out of your poly IP are as you expect them to be. The tlast signal is a very common problem with DMAs, so make sure it is asserting when you expect it to.

Thanks,

Josh

---

<div class="post-metadata">

### Author: ![1415923](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/1415923/32/6404_2.png) [@1415923](https://discuss.pynq.io/u/1415923)
#### Post date: [June 18, 2025, 6:25am UTC](https://discuss.pynq.io/t/dma-sendchannel-transfer-and-wait-stuck-with-larger-buffer/7746/7 "2025-06-18T06:25:49Z")

</div>

Hi! I’m stucked with the same problem, and it seems several months have been passed since last time you replied, so I;m wondering whether you have solved this problem, could you please help me?
