FPGA VHDL project for the ArtyZ7-20 board driving the NHD-2.4-240320CF TFT display (ST7789S driver IC, inteface 16 bit parallel).
This is a driver for a Newhaven 2.4" TFT display (http://www.newhavendisplay.com/tfts-24-tfts-c-1_590.html). It reads the HDMI IN video signals, extracts a 320x240 pixel area and sends this to the TFT display via the 16 bit parallel interface.
A 320x240 area of the Raspberry Pi's desktop rendered on the TFT
The whole 640x480 desktop (crudely) downscaled to the 320x240 TFT pixels
The driver init code sets up the 16-bit parallel interface to the color mode 65K RGB with 5/6/5 bits for the red/green/blue pixel values.
A write cycle for transferring a single 16 bit display pixel takes a minimum time of 66 ns according to the ST7789S data sheet, page 40. To be on the safe side, the driver implements a write cycle period of 80 ns. Even with the 80 ns we can achieve a refresh rate of 320x240 pixels x 80 ns = 6.144 milliseconds per frame, which is roughly 160 frames per second.
The VHDL project was developed and tested on the Diligent ArtyZ7-20 board, but should run on any FPGA board with a HDMI IN or DVI IN connector that is supported by the Vivado IDE.
The project was created using the free Vivado Webpack Editor 2018.1 and the included Vivado IP:
- clk_wiz / Clocking Wizard v6.0
- blk_mem_gen / Block Memory Generator v8.4 (Rev. 1)
plus the free Diligent IP for Vivado from Github:
- dvi2rgb / DVI to RGB Video Decoder (Sink) v1.9 (Rev. 1)
- rgb2dvi / RGB to DVI Video Encoder (Source) v1.4 (Rev. 7)
- ila / Integrated Logic Analyzer v6.2 (Rev. 6)
Part list:
- Diligent Arty Z7-20 FPGA development board
- NHD-2.4-240320CF-CSXN-F TFT display with ST7789S driver IC
- NHD-FFC40 Breakout-Board (40 pin, 0.5mm pitch)
- Power supplied via USB or REG to the Arty board
- HDMI IN connected to video source, max 1920x1080 @ 60 Hz (I used a Raspberry Pi for testing, resolution set to 640x480)
- HDMI OUT (optional) connected to external monitor, the video data from HDMI IN is passed through to HDMI OUT
- Connect the TFT Pins from the FFC40 breakout to the Arty's IO (I used simple jumper wires) like this:
TFT ARTY
--------- ---------
GND 1 GND
NC 2 -
NC 3 -
NC 4 -
NC 5 -
NC 6 -
VDD 7 3V3
IOVDD 8 3V3 (typical 1.8V, max 3.3V)
NC 9 -
/CS 10 GND (= CS is always enabled)
D/C 11 IO9
/WR 12 IO10
/RD 13 3V3 (the read function is not used)
DB0 14 IO0
DB1 15 IO1
DB2 16 IO2
DB3 17 IO3
DB4 18 IO4
DB5 19 IO5
DB6 20 IO6
DB7 21 IO7
DB8 22 IO26
DB9 23 IO27
DB10 24 IO28
DB11 25 IO29
DB12 26 IO30
DB13 27 IO31
DB14 28 IO32
DB15 29 IO33
/RES 30 IO8
IM0 31 GND (= selects the 16 bit interface)
NC 32 -
GND 33 GND
LED-K1 34 GND
LED-K2 35 GND
LED-K3 36 GND
LED-K4 37 GND
LED-A 38 3V3
GND 39 GND
NC 40 -
-
Download and install the Vivado Webpack Edition
https://xilinx.com/support/download.html -
Download and install the Arty Z7-20 board files
https://github.com/Digilent/vivado-boards -
Download and unzip the Digilent Vivado IP library release "vivado-library-2016.4.zip"
https://github.com/Digilent/vivado-library/releases
To add the unzipped Diligent IP folder to the Vivado Editor's "IP Defaults" settings, go to the "Tools" menu in Vivado, choose "Settings" and then "IP Defaults" in the left column. Then press the "+" button and select the folder you unzipped the Diligent IP to, in my case "C:\Diligent_Vivado_IP". -
Download the files from the "source" folder of this repository onto your harddrive.
I recommend using a short path name that does not contain spaces, in my case "C:\NHD"C:\NHD\ArtyZ7_20Master.xdc
C:\NHD\create_project.tcl
C:\NHD\Driver_16bitParallel.vhd
C:\NHD\Main_wrapper.vhd
C:\NHD\Main.bd
C:\NHD\NHD_24_240320CF_Init.vhd
C:\NHD\NHD_24_240320CF.vhd
C:\NHD\VideoProcessing.vhd -
Create the project by running the included create_project.tcl script
-
Open the create_project.tcl script with a text editor, locate line 158:
set_property "ip_repo_paths" "[file normalize "C:/Diligent_Vivado_IP"]" $obj
changeC:/Diligent_Vivado_IP
to the path where you unzipped your IP to in step (3), using forward slashes in the path name -
Start the Vivado 2018.1 Editor
On the welcome page, you can see the tcl console at the bottom -
Type "cd C:/NHD" (adjust the path to where you put your source files on your harddisk in step (4) - again, using forward slashes instead of backslashes) into the tcl console prompt, then press return
-
Type "source ./create_project.tcl" into the tcl console prompt and press return
The Vivado project "ArtyZ7-20-NHD" is generated and opened in the Vivado Editor.
The block design diagram of the ArtyZ7-20-NHD project
The two switches SW0 and SW1 on the Arty board can be used to configure the display content:
SW0 changes the resolution on the tft
when switched on, only every other pixel is written to the block ram, so an area of 640x320 pixels is (crudely) downscaled to th 240x320 tft size
SW1 can be used for testing the driver functionality without an HDMI signal
when switched off, a full screen red-green-blue sequence is shown on the tft
The 320x240 pixel area that is output to the TFT has its origin by default at the upper left corner (0/0) of the HDMI frame. If you want to move the area to some other location within the HDMI frame, you can change the values of the constants h_start
and v_start
in the VideoProcessing.vhd file at line numbers 42 and 46 respectively.