book collections email follower instructable user
Picture of WIDI - Wireless HDMI Using Zybo (Zynq Development Board)

Have you ever wished that you could connect your TV to a PC or laptop as an external monitor, but didn't want to have all those pesky cords in the way? If so, this tutorial is just for you! While there are some products out that achieve this goal, a DIY project is much more satisfying and potentially cheaper.

This concept is different from products like chromecast, as it it's intended to take the place of an HDMI cord connecting to a monitor instead of being a streaming device.

Our project was created as a final project for a Real Time Operating Systems course at California State Polytechnic University, San Luis Obispo.

The goal of the project is to utilize two Digilent Zybo boards to act as the wireless communication interface between a HDMI transmitter device (PC, blu-ray, etc) to a HDMI receiving device (Desktop Monitor, Projector, TV, etc).

One Digilent Zybo will be connected via HDMI to the transmitting device, and the other will be connected via HDMI to the receiving device.

The wireless communication will be made by using a wireless local area network dedicated to the transmitter and receiver, without being routed through a home router or other such device. The wireless module used for this project is the tplink wr802n nanorouter, one of which operates as an access point to establish the network and the other to operate as a client to connect to the network. Each nanorouter will be connected via ethernet cable to either Zybo board. When connected to these routers, the devices will communicate via TCP as though they were connected with a single ethernet cable (meaning the only configuration needed to establish a connection is the IP address of the client).

While the goal of the project was to facilitate a stream of 1080x720 video @ 60Hz, this was not achievable due to bandwidth limitations in the wireless network and the lack of real time video compression to reduce the data required to send. Instead, this project serves as the framework for future development to achieve this goal, as it has severely restricted limitations in frame rate to properly stream HDMI data as intended.

Project Requirements:

2x Digilent Zybo Development Boards (must have at least one HDMI port)

2x HDMI cables

2x microusb cables (to connect Zybo to PC for development)

2x tplink wr802n nanorouters (including adtl. 2x microusb and wall outlet power adapters)

2x ethernet cables

***Note: This tutorial assumes familiarity with the Vivado design suite and experience creating a new project and block design.***

Step 1: Configure Zynq Programmable Logic for Transmitter

Our approach to developing the programmable logic of the transmitter was to perform an hdmi-to-hdmi pass-through from PC to monitor using two Video Direct Memory Access (VDMA) blocks, one for write and one for read.

Both are selected for free-running, 3 frame-buffer mode (0-1-2). Since the video core is optimized for 60 frames per second, this means that the VDMA will write or read to a new frame every 16.67 ms in this order: 0,1,2,0,1,2,0,1,2. The DDR memory locations for each frame are different for the two VDMAs because they are no longer synchronized with each other. Instead, a hardware timer (TTC1), configured for 60 Hz, is used to synchronize the movement of data between the two memory locations.

The image above shows 3 frames, their dimensions and the amount of memory each requires (to the right of the frame). If we assign the write VDMA to these memory locations, then we can assign the read VDMA memory locations beyond this set, say starting with 0x0B000000. Each frame is made up of 1280*720 pixels and each pixel is made up of 8 bits of Red, Green and Blue for a total of 24 bits. This means a frame is made up of 1280*720*3 bytes (2.76 MB).

Inside the timer IRQ, which is described in the VDMA driver setup, will handle copying data between the two VMDA memory locations. The VDMA provides a pointer to the current frame being written to or read from. The frame is represented by a particular gray code, which is converted in software. The gray code definitions for a 3 frame-buffer configuration can be found in the AXI VDMA Product Guide in appendix C.

This allows us to copy the contents being written to memory without reading from a frame currently being written to.

***Note that the read VDMA is not used when sending data across the wireless network. It's only purpose is to verify proper operation of copying memory from the write VMDA. The read VMDA should be disabled.***

Here are the steps to creating the Transmitter Design Block:

  1. When creating a new project, it is a good idea to assign a chip or board to the project. This link describes how to add new board files to the Vivado directory and associate the correct board with your project. It will come in handy when adding the Processing System block and transitioning from hardware to software (SDK side).
  2. Add the following blocks:
    • dvi2rgb
    • Video in to Axi4-stream
    • Timing Controller
    • axi4-stream to vid out
    • rgb2dvi
    • AXI VDMA x2
    • AXI GPIO x2
    • Clock Wizard
    • Constant
    • Zynq Processing System
  3. When adding the Processing System, click "Run Block Automation" from the top green colored bar and make sure the "Apply Board Preset" option is selected. Leave everything else default.
  4. Images of each block configuration window can be found in the images above. If you don't see an image for a particular window, just leave it as default.
  5. Begin Configuring the Zynq Processing system:
    • In PS-PL Configuration --> AXI Non Secure Enable --> GP Master AXI, enable M AXI GP0 Interface
    • In PS-PL Configuration --> HP Slave AXI Interface, enable both HP0 and HP1

    • In MIO Configuration --> Make sure ENET0 is enabled under I/O Peripherals, then --> Application Processor Unit, enable Timer0

    • In Clock Configuration --> PL Fabric Clocks, enable FCLK_CLK0 and set to 100 MHz.

    • Click Ok

  6. Before clicking "Run Connection Automation," be sure to connect the video blocks as seen in the TX block design image above. You will want to rename the constant to VDD and set the value to 1. Connect the video blocks accordingly.
  7. Make the HDMI TMDS clock and data pins external on the rgb2dvi and dvi2rgb blocks

  8. Create an input and output port for the hot plug detect signal (HPD) and connect them together, these are defined in the constraints file

  9. The pixel clock is recovered from the TMDS_Clk_p, which is created in the constraints file. This will be 74.25 MHz in accordance with 720p resolution. It is important to connect the pixel clock (from the dvi2rgb block) to the following pins:
    • vid_io_in_clk (vid in to axi stream block)
    • vid_io_out_clk (axi stream to vid out block)
    • clk (Timing Controller)
    • PixelClk (rgb2dvi)
  10. ***Note: Currently, in order to activate the pixel clock recovery, the HDMI rx and tx connectors must be plugged into an active source/sink. One way around this is to separate the video rx and tx blocks into different clock domains (in other words, generate a new 74.25 MHz clock to feed to the tx block).***
  11. Next set up the clock wizard so that you have a 100 MHz input (global buffer source) and 3 output clocks @ 50 MHz (AXI-Lite clock), 150 MHz (AXI4-Stream clock), 200 MHz (dvi2rgb RefClk pin).
  12. Connect the FCLK_CLK0 processing system pin to the clock wizard input
  13. At this point click "Run Connection Automation" from the green bar at the top of the design window. It is a good idea to do this for one block at a time and follow the TX block design image above.
  14. The tool will attempt to add the AXI Interconnect, which acts as the master/slave interconnect for the blocks that use the AXI-Lite bus (VDMAs and GPIOs).
  15. It will also add AXI SmartConnect, which acts as the master/slave interconnect for the AXI4-Stream and High Performance processor interfaces used by the VDMA (Stream to Memory Map and vice versa).
  16. The tool will also add a Processor System Reset. Make sure this is only connected to the VDMAs, GPIOs and processor related blocks. Do not connect it to any video blocks (i.e. dvi2rgb, timing controller, vid to stream etc.)
  17. Once connection automation has been completed, verify that the connections match that of the TX block design image. You'll notice an extra System ILA block that has not been mentioned. This is for debugging only and is not needed for now. It uses the 150M Processor Reset, so that's not needed either. Anywhere you see small green "bugs" on busses, that is because of the ILA and can be ignored.
  18. The final step is to right click on the block design in the project sources tree and select "Create HDL Wrapper." If you plan on adding logic to the wrapper, it will be overwritten every time this is selected.
  19. See the VDMA Driver Setup section for details on the SDK side.

Clocks and Resets

I've found that the most important aspects of any programmable logic project is careful consideration of clock domains and reset signals. If those are properly configured you have a good shot at getting your design to work.

Pixel Clock and Timing Locked

In order to verify that certain signals are active, it is a good idea to tie these signals to LEDs (clocks, resets, locks etc). Two signals that I found helpful to track on the transmitter board were the pixel clock and the "locked" signal on the AXI4-Stream to video out block, which tells you that the video timing has been synchronized with the timing controller and the video source data. I've added some logic to the design block wrapper that tracks the pixel clock using the PixelClkLocked signal on the dvi2rgb block as a reset. I've attached the file as hdmi_wrapper.v here. The constraints file is also attached here.

jreauclaire9 months ago
Interesting project. Very well written and documented. My question is how is this different from my Apple TV's "mirror" mode?
gada8889 months ago
very complicated,i'd rather to have HDMI cable on,besides,the ZYBO board is very expensive.
JesseM2 gada8889 months ago
Agreed, but, I have to say that it is a very well- written, in-depth 'ible.... just wish there was a cheaper (much, much cheaper) way to do this! Lol, either way, thumbs up from me!
jessyratfink9 months ago
FANTASTIC! What a clever way to do this.