Spi on PYNQ-Z2 Pmod

Hi all,

I am currrently using Vivado 2022.1 to set the IP of SPI on PYNQ-Z2’s PMOD ports. Fig. 1 is the block design I built and the attached files are generated by Vivado. Fig. 2 is the Python code on Jupyter so far. However, I am new in this area, so I don’t quite know how to proceed. Please help me with this SPI program.

spi.zip (278.0 KB)


Hi @hsuharry12,
Welcome to pynq forum. You need a driver to initiate and transfer the data through axi quad spi and I am not sure if there is a prebuilt driver for this in pynq. Also, reading and writing on a spi device might be different according to required specification of the device.

I have attached the code I used for transferring data via quad spi quite a long ago (this is not written by me, it was collected from somewhere and I don’t exactly remember from where or from who, all credits go to the original writer), also it might not work as you are using v2022.1.

As far as I remember there was no problem with writing but when you are reading you have to omit two cycles of data. It might be the specific case to my EEPROM.

The main idea is you have to go through the AXI QUAD SPI datasheet and make a driver according to the datasheet in python to send the register’s value via axi-lite interface to control the IP.

spi.py (1.5 KB)

1 Like

Thanks for your reply! Please forgive my ignorance, I have a few questions hope you could help with.

  1. By driver do you mean codes like “spi.py” you attached? If so, I am following the steps in the video below:
    Adding IP to a PYNQ overlay - tutorial - YouTube

  2. When I try to compile “spi = overlay.axi_quad_spi_0” as the attached code using my bit file, an error is shown:

Does this mean I did not build my bit file correctly?

  1. Can you kindly attach the “communication.bit” file used in the attached file or how it’s built if possible?
  1. the functions you need to initialize or communicate with the IP to control its functionality (like transfer and init in spi.py)

  2. Can you please check if the IP name in the bitstream is the same as what you have written here (axi_quad_spi_0)?

If that’s okay, then you might also have to add ignore_version as you are using a different version of the Vivado.
ol = Overlay(“spi.bit”, ignore_version= True)

  1. Communication bit is just a name I have written, there was nothing special than adding the SPI IP.


When I compiled the spi file according to the steps you provided, in the writing part, I could use the z2 board to write data correctly (check through Arduino Uno); but in the reading part, the received data are all 255. I don’t know why, could you help me with this?

as i said, you have to skip two cycle of data to read the value. You can check last line of my program. so recvData will contain an array where 3rd value will be the value for 1st value you have sent. (also, it completely depends on your spi slave device, how to read)

Thanks for your help, I can now read and write data successfully. However, I found that the z2 board is set as “master” originally and I will need to set the board as “slave”, the Mode option in the Vivado IDE is Standard SPI Mode, which allows the board to set as “slave” according to the guide, Documentation Portal. In the guide, I only find the register bit (fig. 1)

that should be set as 0, but the code did not operate correctly after this change (fig. 2).

Could you guide me with the setting or adjustment?

I am now using the pynq z2 board to transfer data in SPI standard mode and the board is set as “master” in the code attached, originally.

However, I will need to use the z2 board in “slave mode” for my project. I have gone through the guide, Documentation Portal, but only find the register bit below that should be set as 0 and the code did not operate correctly after this change.

Please guide me with the settings or adjustments, thanks.

As far as I remember this code is not compatible with slave mode and you have to change FIFO clear settings and might be other registers as well to make it work. Also, there was a bug in this IP (while i was working with it) of receiving inconsistent data (sometimes 1, sometimes 2 cycles) while reading slave, which I could not solve. This might have been fixed by now. I am no help here, I just can suggest going through the documentation and making appropriate changes.

我目前也正在研究使用pynq z2上的spi协议,但是我不知道该怎么继续下去了,我根据[SPI, I2C, UART on PYNQ: a PL approach - MakarenaLabs]里的内容设计了vivado block design,在jupyter内使用其提供的代码,但是我不能收到任何信息。但是通过浏览你的图片等内容,我发现你可以成功运行,你能将将你的设计信息分享出来吗?感谢感谢。



spi.bit (3.9 MB)
spi.hwh (184.1 KB)
spi.tcl (14.8 KB)