# Pynq custom overlay of multidimensional array calculation using vivado hls

**URL:** <https://discuss.pynq.io/t/pynq-custom-overlay-of-multidimensional-array-calculation-using-vivado-hls/1718>\
**Category:** Support\
**Created:** [September 7, 2020, 3:00am UTC](https://discuss.pynq.io/t/pynq-custom-overlay-of-multidimensional-array-calculation-using-vivado-hls/1718 "2020-09-07T03:00:28Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![TingShen\_Kuo](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/tingshen_kuo/32/914_2.png) [@TingShen\_Kuo](https://discuss.pynq.io/u/TingShen_Kuo)\
**Post date:** [September 7, 2020, 3:00am UTC](https://discuss.pynq.io/t/pynq-custom-overlay-of-multidimensional-array-calculation-using-vivado-hls/1718/1 "2020-09-07T03:00:28Z")

</div>

Hi everyone, I am now writing a code of matrix multiplication with vivado HLS.  
The following is my C code on vivado HLS.

 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/2/2cb4dcf783dea29490deb9e59793fdac89635cc7.png)  
I have exported it into verilog using RTL transfer it into IP.  
 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/c/c3c4ec2b1166be9153590c7e4a907f2e9e0f3c10.png)  
I am now load the tcl file and bit file on my pynq ultra96 v2 board.  
I want to use it with python code, but i met some problem of sending the input matrix into the function.  
I do not know if my C code or python code is wrong, Hope someone can give me some advice!!!  
 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/9/97da5ed123f63a3c5cb56103ba9bfc88d38aba26.png)

---

<div class="post-metadata">

**Author:** ![bartokon](https://avatars.discourse-cdn.com/v4/letter/b/8edcca/32.png) [@bartokon](https://discuss.pynq.io/u/bartokon)\
**Post date:** [September 7, 2020, 4:43pm UTC](https://discuss.pynq.io/t/pynq-custom-overlay-of-multidimensional-array-calculation-using-vivado-hls/1718/2 "2020-09-07T16:43:52Z")

</div>

Hi, I have created similar design for research purposes 😃

```
void MMULT(float array1[8], float array2[8][8], float array3[8][8][8], float array1o[8], float array2o[8][8], float array3o[8][8][8])

```

{  
#pragma HLS INTERFACE ap\_ctrl\_none port=return  
#pragma HLS INTERFACE s\_axilite port=array1  
#pragma HLS INTERFACE s\_axilite port=array2  
#pragma HLS INTERFACE s\_axilite port=array3  
#pragma HLS INTERFACE s\_axilite port=array1o  
#pragma HLS INTERFACE s\_axilite port=array2o  
#pragma HLS INTERFACE s\_axilite port=array3o

```
for(int i = 0; i < 8; i++)
{
	array1o[i]=array1[i];
};

for(int o=0; o < 8; o++)
{
	for(int i = 0; i < 8; i++)
	{
			array2o[i][o]=array2[i][o];
	};
};

for(int p=0; p < 8; p++)
{
	for(int o=0; o < 8; o++)
	{
		for(int i = 0; i < 8; i++)
		{
				array3o[i][o][p]=array3[i][o][p];
		};
	};
};

```

};

And created something like this in jupyter:

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

I can write one value by using base address and incrementing by 4bythes (size of int)  
We could do probably whole array like this, but there must be another way! I will try to search for a solution.  
We could just use DMA and allocate, but this way is more interesting…  
Also, I have find out that PYNQ has some errors with register map if your array is bigger than ?64? units.

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

## MMIO [PS/PL Interfaces — Python productivity for Zynq (Pynq)](https://pynq.readthedocs.io/en/v2.5.1/overlay_design_methodology/pspl_interface.html)

Any IP connected to the AXI Slave GP port will be mapped into the system memory map. MMIO can be used read/write a memory mapped location. A MMIO read or write command is a

> single transaction to transfer 32 bits of data to or from a memory location

. As burst instructions are not supported, MMIO is most appropriate for reading and writing small amounts of data to/from IP connect to the AXI Slave GP ports.

---

<div class="post-metadata">

**Author:** ![TingShen\_Kuo](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/tingshen_kuo/32/914_2.png) [@TingShen\_Kuo](https://discuss.pynq.io/u/TingShen_Kuo)\
**Post date:** [September 14, 2020, 4:07am UTC](https://discuss.pynq.io/t/pynq-custom-overlay-of-multidimensional-array-calculation-using-vivado-hls/1718/3 "2020-09-14T04:07:00Z")

</div>

Hi @bartokon, sorry for late reply. Thanks for giving helpful advice. How can you write the jupyter python code based on your overlay?

Tim

---

<div class="post-metadata">

**Author:** ![bartokon](https://avatars.discourse-cdn.com/v4/letter/b/8edcca/32.png) [@bartokon](https://discuss.pynq.io/u/bartokon)\
**Post date:** [September 14, 2020, 9:23am UTC](https://discuss.pynq.io/t/pynq-custom-overlay-of-multidimensional-array-calculation-using-vivado-hls/1718/4 "2020-09-14T09:23:53Z")

</div>

Maybe something like this:  
As array is square for example A[2][2]  
we could do:  
mmio.write(ADDRESS\_OFFSET+ROW+COLUMN, value)  
COLUMN is just 4bythes (size of float for example)  
and ROW can be COLUMN\*2 because we have 2 float variables in one row.  
You know what I mean? Virtual memory is sequential you just need to calculate distance and send new data.

Give it a try

---

<div class="post-metadata">

**Author:** ![TingShen\_Kuo](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.pynq.io/tingshen_kuo/32/914_2.png) [@TingShen\_Kuo](https://discuss.pynq.io/u/TingShen_Kuo)\
**Post date:** [September 23, 2020, 6:58am UTC](https://discuss.pynq.io/t/pynq-custom-overlay-of-multidimensional-array-calculation-using-vivado-hls/1718/6 "2020-09-23T06:58:12Z")

</div>

Hi bartoken, i just modify your code to the following.  
I just add integer 10 to the array2o.

 ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/7/7f20c89c755fd614082a9ab66fb603d55a264254.png)  
But when i export to RTL, it occurs that there is no use ip.  
Do you know what is going on?  
Tim

---

<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:** [September 23, 2020, 8:32am UTC](https://discuss.pynq.io/t/pynq-custom-overlay-of-multidimensional-array-calculation-using-vivado-hls/1718/7 "2020-09-23T08:32:51Z")

</div>

@TingShen_Kuo In your Python code, what are “A” and “B”?  
The error is that the data type must be int or bytes. You may not have assigned a value to A or B correctly.

Can you post more details about this problem you have?:

> [@TingShen\_Kuo](#):
>
> Hi bartoken, i just modify your code to the following.  
> I just add integer 10 to the array2o.
> 
> ![image](https://us1.discourse-cdn.com/flex019/uploads/pynq1/original/2X/7/7f20c89c755fd614082a9ab66fb603d55a264254.png)
> 
> But when i export to RTL, it occurs that there is no use ip.  
> Do you know what is going on?

@bartokon

> Also, I have find out that PYNQ has some errors with register map if your array is bigger than ?64? units.  
> Depending on the host CPU (32bit/64bit) registers are 32 bit or 64 bit. This is why you see an error if you try to use something larger than this.

> I can write one value by using base address and incrementing by 4bythes (size of int)  
> We could do probably whole array like this, but there must be another way! I will try to search for a solution.

See this post:

> [@MMIO write is too slow](https://discuss.pynq.io/t/mmio-write-is-too-slow/389/2):
>
> The quick fix is to use the underlying numpy array to write the data - instances the MMIO class as a .array which provides direct access to the registers. If I’m doing this I generally take a slice of the array containing the registers I want to update frequently and then I can just directly assign it. input\_registers = mmio.array[0x100:0x200] # address 0x400 to 0x800 input\_registers[:] = input\_data This will be substantially faster than calling write for each entry separately For even better…

Cathal
