Jump to content
  • 0

Help With A Zybo Video Design


digicloud14

Question

Hi all,

I have a Zybo Zynq-7000 Development board, and I'm attempting to create a design that uses the bidirectional HDMI port as an input. I want to take the HDMI input (with a desktop or laptop as the source) and write the video stream to memory, and then access the data in a Linux environment (I am using Xilinux, a graphical, Ubuntu 12.04 LTS-based Linux distribution for the Zynq-7000) to eventually send out the data over the internet. I'm having a bit of difficulty understanding how to correctly implement the design in Vivado (2014.4) which is why I'm here. I'm trying to use as many standard Xilinx or Digilent IP cores as possible to make the design straightforward since I am new to FPGA and Vivado. After wading through tons of documentation, I feel like I have a decent understanding of the general design flow for a video design, but as I said I do not have much experience here so I am looking for someone to hopefully point out my mistakes or point me in the right direction.

My current design uses a DVI2RGB IP core provided by Digilent (found here: https://github.com/DigilentInc/vivado-library/tree/master/ip/dvi2rgb_v1_4) which is then interfaced with the Xilinx Video In To AXI4-Stream IP Core (documentation found here: http://www.xilinx.com/support/documentation/ip_documentation/v_vid_in_axi4s/v3_0/pg043_v_vid_in_axi4s.pdf), which then goes to the Xilinx AXI Video Direct Memory Access (VDMA) IP core (documentation found here: http://www.xilinx.com/support/documentation/ip_documentation/axi_vdma/v6_2/pg020_axi_vdma.pdf). Finally, the output of the VDMA is interfaced with an AXI Memory Interconnect to connect it all to the processing system. I do not want to output the video stream that is being written to memory to a display output such as VGA, simply access the video data in Linux and send it out over the internet.

A few questions:

1. First and foremost, does my thought process for the design outlined above make any sense?
2. Do I need to use the Video Timing Controller and subsequently the Video Timing Controller IP cores for a design such as this? My assumption here is NO since the input is providing the clock (which in Vivado is being provided to the Video In To AXI4 and VDMA cores), and nothing is being outputted.

3. The DVI2RGB IP Core takes in TMDS as its input. Do I simply create ports labeled TMDS_Clk_p etc and connect to the input of the IP core? How does Vivado know (and subsequently, how does the board know) those ports I created are supposed to be for the HDMI input port?

4. Assuming my design works and I can successfully write the inputted video stream into memory using the VDMA, is the Xilinx Linux VDMA Driver (found here: http://www.wiki.xilinx.com/DMA+Drivers+-+Soft+IPs) my best bet for accessing the data in the VDMA in Linux? Or is Video4Linux2 (V4L2) something that I should be using here? I've read that V4L2 has compatibility with VLC which seems like a convenient way to then stream the video data over the internet.

Additionally, I was able to import an EDK HDMI_RX IP core into Vivado that is used in a Digilent GoPro Video Filtering Project (found here: https://github.com/LariSan/Digilent-Maker/tree/master/Zybo/zybo_video_demo)Should I be attempting to use this core instead of the DVI2RGB core? I chose the DVI2RGB because it was designed for Vivado rather than EDK, so I assumed it would be easier to use. I would eventually like my design to incorporate audio as well though, which I know DVI doesn't do.

Comments, criticism, advice, help; whatever you've got, it is very welcome here! Anything to steer me in the right direction. Sorry for the long post guys, I've always been a bit verbose :P I'll attach a screenshot of my Vivado block design to hopefully illustrate some of the things I mentioned about my design. http://i.imgur.com/rdXtuOf.png

Thank you,
Chris
 

Link to comment
Share on other sites

Recommended Posts

Hey guy,

I got it working with a little help from Sam.

To simplify the whole thing, I trimmed out all of the zynq associated blocks since this is project isn't using the PS and removed the extra XDCs.  

The DDC channels on the dvi2rgb core need to assigned correctly and it is a bit of a pain.  

  1. Delete all connections
  2. right-click DDC 
  3. Select "make external" 
  4. open the design wrapper and there should be two signals names "ddc_scl_io" and "ddc_sda_io"
  5. modify the Zybo master XDC to reflect those names in the HDMI group.

zybo_passthrough.thumb.png.e94770147e26e

Sam helped me fix the timing errors associated with timing.  The fix was to comment out comment out this the create_clock line in "dvi2rgb.xdc".  The new file should look like this:

####dvi2rgb.xdc####

### Clock constraints ###
# Constrain TMDS clock to the 165 MHz maximum from DVI 1.0 specs
#create_clock -period 6.060 [get_ports TMDS_Clk_p]

### I/O constraints ###
# group data channel IODELAYE2 cells with the IDELAYCTRL

### Clock constraints ###
# Constrain TMDS clock to the 165 MHz maximum from DVI 1.0 specs
#create_clock -period 6.060 [get_ports TMDS_Clk_p]

### I/O constraints ###
# group data channel IODELAYE2 cells with the IDELAYCTRL
set_property IODELAY_GROUP dvi2rgb_iodelay_grp [get_cells DataDecoders[*].DecoderX/InputSERDES_X/InputDelay]
set_property IODELAY_GROUP dvi2rgb_iodelay_grp [get_cells TMDS_ClockingX/IDelayCtrlX]

### Asynchronous clock domain crossings ###
set_false_path -through [get_pins -filter {NAME =~ */SyncAsync*/oSyncStages*/PRE || NAME =~ */SyncAsync*/oSyncStages*/CLR} -hier]
set_false_path -through [get_pins -filter {NAME =~ */SyncAsync*/oSyncStages_reg[0]/D} -hier]
set_false_path -through [get_pins -filter {NAME =~ */SyncBase*/iIn_q*/PRE || NAME =~ */SyncBase*/iIn_q*/CLR} -hier]

set_property IODELAY_GROUP dvi2rgb_iodelay_grp [get_cells DataDecoders[*].DecoderX/InputSERDES_X/InputDelay]
set_property IODELAY_GROUP dvi2rgb_iodelay_grp [get_cells TMDS_ClockingX/IDelayCtrlX]

### Asynchronous clock domain crossings ###
set_false_path -through [get_pins -filter {NAME =~ */SyncAsync*/oSyncStages*/PRE || NAME =~ */SyncAsync*/oSyncStages*/CLR} -hier]
set_false_path -through [get_pins -filter {NAME =~ */SyncAsync*/oSyncStages_reg[0]/D} -hier]
set_false_path -through [get_pins -filter {NAME =~ */SyncBase*/iIn_q*/PRE || NAME =~ */SyncBase*/iIn_q*/CLR} -hier]

The issue is that the "create_clock" command is forcing the TMDS_Clk_p to be a frequency that cannot be supported by FPGA on the Zybo causing the timing error.  Removing it allows the solution in the TMDS clock generate work.

Finally, change the clocking wizard block to be in the PLL instead of the MMCM.  The dvi2rgb core uses an MMCM and the clocking wizard wants to use a MMCM but there is only one MMCM in that section of the FPGA so tell the clocking wizard to use a PLL.

clk_wiz.thumb.png.ba9cd93c8bee0b96fa75d7

I uploaded working directory to my github: here

Hope this helps!

Marshall

Link to comment
Share on other sites

Hey Marshall,

Glad that you help us out, it works very well! Really appreciate! I kept changing the clock constraint on the xdc file but never be brave eoungh to remove that out.:rolleyes: Now I am able to catch up on my project.

Run

Link to comment
Share on other sites

Run,

Thank you, that makes a lot of sense. I'll also switch to the PLL for the clocking wizard.

Marshall,

If you find yourself with time to spare and wouldn't mind doing the design with the PS, I certainly won't say no to that. Thank you!

Thanks,
Chris

Link to comment
Share on other sites

Chris,

You don't need to create additional clock for the TMDS_Clk_p or redo the "create_clock" constraint. The way that clock generate will be done by the HDMI source (I guess). Basically the HDMI source reads the edid file through I2C, finds what resolution Zybo supports (1280x1024 is the one detailed based on the dvi2rgb doc) and generates the correct clock frequency for data transmission. So you just need to have TMDS_Clk connects to the HDMI source (as TMDS_data[2]) and it will work out for you. On my case, the 1280x1024@60Hz resolution produces 108MHz pixel clock. If you have a scope, you could verify that clock frequency. It is the 4th pair of differential signal on the HDMI connector, from left to right.

And yes, use PLL for clocking wizard.

Hope this helps, I could share some of my works with you if you want. Just let me know.

Run

Link to comment
Share on other sites

Hey Marshall and Jieming,

Thank you both for taking the time to help me out. After a few modifications to the XDC and design wrapper, I was able to get the DDC connections properly set up and successfully generated the bitstream for the design. I did get a critical warning stating that my design did not meet timing constraints, so I'm working on correcting those now using the information you posted above. You guys are extremely helpful, it is very much appreciated.

**Question about timing (sorry!)

Just to verify a few things: The Zybo has a max buffer bit clock of 600 MHz, so the recommended TMDS_Clk is 600/5 = 120 MHz. The DVI2RGB core requires a 200 MHz ref clock. In my design I am using the Processing System (PS), so similar to Run's design, I have an FCLK from the PS going into a clocking wizard.

Following Marshall's post, I commented out the timing constraints in the dvi2rgb xdc. When configuring my clocking wizard, do I also need to change mine from MCMM to PLL, even though I am using the Processing System? I'm not sure because Marshall's design does not use the processing system, he instead creates his own clock.

Finally, to constrain the TMDS_Clk to 120 MHz, is this simply done when I connect the inputs to the DVI2RGB core and specify that the signal is a clock and enter 120 MHz, as shown in this image? http://i.imgur.com/SINVpSG.png Or do I need to additionally add something to the Master_Zybo or DVI2RGB XDC? I'm just a bit confused here because Jieming mentioned to add this to my XDC:
create_clock -name sysclk -period 25 -waveform {0 12.5} [get_ports HDMI_CLK_P]

But that gives a frequency of F = 1/25 nanoseconds= 40 MHz, unless I am missing something.

I think my problem lies here. When attempting to generate a bitstream, it does so successfully without any errors, but I am still failing a timing constraint (much better then previously when I was failing several). Here is a view of my timing report http://i.imgur.com/WWZS1iu.png. As you can see, my CLK_OUT_5x_HDMI_clk timing fails with an actual pulse width of 1.212 nanoseconds. That gives a frequency of about 825 MHz, or 165 MHz x 5. So somewhere in the design there is a constraint keeping the TMDS clock at 165 MHz, even though I commented out the timing constraints in the dvi2rgb.xdc. When creating the ports for TMDS_Clk_p and TMDS_Clk_n I set them as 120 MHz clock signals as shown in the first image. But apparently this isn't holding? I'm thinking I need a line in the master xdc such as:

create_clock -name sysclk -period 8.33 -waveform {0 12.5} [get_ports HDMI_CLK_P]

So sorry for all the questions, but you have no idea how much you guys have helped me out.


Thanks,
Chris

Link to comment
Share on other sites

Hey Chris,

I forgot to copy the xdc into the project when I added it.  I updated the github and the xdc is here.

Thanks for catching that.  

Run, 

Can you compare your design file to mine found here:

https://github.com/mwingerson/zybo_720_hdmi_to_vga/blob/master/hdmi_passthrough_720p.srcs/sources_1/bd/design_1/hdl/design_1_wrapper.v

Make sure the  iic_0_scl_io and iic_0_sda_io ports are the same that I am talking about.  I had to click on the bus wire directly to the right of DDC to get the output correctly.  The errors that you are seeing I suspect are caused by making the wrong ports external.

Best of luck!

Marshall

Link to comment
Share on other sites

Dear Chris,

1. Like Run suggested, the error "IO Group: 0 with : SioStd: LVCMOS18   VCCO = 1.8 Termination: 0  TermDir:  BiDi RangeId: 1 Drv: 12  has only 0 sites available on device, but needs 2 sites."  such kind of problem is caused by one or more unconnected external ports on your block diagram. Please check your diagram first to make sure all unused external ports are deleted. (this problem will occur on both  2014.4 and 2015.1)

2. For the DDC part, the HDMI protocol described it clearly that this is a mechanism to let video transmitter and receiver to communicate which each other. By exchanging information, the transmitter could know the detail configuration(ability) of the receiver part (what resolution, frame rate, format of signal the receiver can process). This is a necessary part in HDMI transmission and can not be ignored or deleted.

3. Currently the problem you encountered is how to synthesis the Bi-Directional inner control ports into a signal Bi-Di external port. To solve this problem, first you should understand what is a bi-di port and its mechanism(I am sure you know it). Secondly, in Xilinx ISE, three bi-di control ports can be easily synthesized together by adding a constrain command in the .ucf file. In vivado the goal can't be achieved by only modify the .xdc. In my way, i directly modified the DVI2RGB ip core, the top_module i mentioned is the top module of the ip core (the dvi2rgb.vhd file). The core is written by VHDL, modify the following:

a. In the port description change DDC ports to below

 -- Optional DDC port
      DDC_SDA : inout std_logic;
      DDC_SCL : in std_logic;

b. add HPD and CEC port in the end of port def

      HDMI_HPD : out std_logic;
      HDMI_OUT_EN : out std_logic

c.  in the behavioral part add signal def and logic

architecture Behavioral of dvi2rgb is
.......
signal hpd : std_logic;
.......

begin

DDC_SCL_I <= DDC_SCL;

DDC_SDA <= DDC_SDA_O when DDC_SDA_T = '0' else 'Z';
    DDC_SDA_I <= DDC_SDA;
    
HDMI_OUT_EN <= '0';
HDMI_HPD <= hpd;

.......

d. in the TMDS_ClockingX call add port "hpd"

TMDS_ClockingX: entity work.TMDS_Clocking
   generic map (
      kClkRange => kClkRange)
   port map (

.........

hpd => hpd
   );

f. in the TMDS_ClockingX module(vhd file) add "hpd" def. this will active the HDMI transmittion only after the sink core has been locked

entity TMDS_Clocking is
   Generic (
      kClkRange : natural := 1);  -- MULT_F = kClkRange*5 (choose >=120MHz=1, >=60MHz=2, >=40MHz=3, >=30MHz=4, >=25MHz=5
   Port (
      .........
      hpd : out std_logic);
end TMDS_Clocking;

architecture Behavioral of TMDS_Clocking is
..........

begin

hpd <= aDlyLckd;

.........

the above is all you need to make this core compatible with HDMI. after modification -> save -> repackage ip core

4. All you need in your project xdc file is really sample if modification has been done inside ip core. below is my xdc

set_property PACKAGE_PIN H16 [get_ports HDMI_CLK_P]
set_property PACKAGE_PIN H17 [get_ports HDMI_CLK_N]
set_property PACKAGE_PIN D19 [get_ports {HDMI_D_P[0]}]
set_property PACKAGE_PIN C20 [get_ports {HDMI_D_P[1]}]
set_property PACKAGE_PIN B19 [get_ports {HDMI_D_P[2]}]
set_property PACKAGE_PIN D20 [get_ports {HDMI_D_N[0]}]
set_property PACKAGE_PIN B20 [get_ports {HDMI_D_N[1]}]
set_property PACKAGE_PIN A20 [get_ports {HDMI_D_N[2]}]
set_property IOSTANDARD TMDS_33 [get_ports HDMI_CLK_*]
set_property IOSTANDARD TMDS_33 [get_ports HDMI_D*]

set_property PACKAGE_PIN G17 [get_ports HDMI_SCL]
set_property PACKAGE_PIN G18 [get_ports HDMI_SDA]
set_property IOSTANDARD LVCMOS33 [get_ports HDMI_SCL]
set_property IOSTANDARD LVCMOS33 [get_ports HDMI_SDA]

set_property PACKAGE_PIN E18 [get_ports HDMI_HPD]
set_property IOSTANDARD LVCMOS33 [get_ports HDMI_HPD]
set_property PACKAGE_PIN F17 [get_ports HDMI_OUT_EN]
set_property IOSTANDARD LVCMOS33 [get_ports HDMI_OUT_EN]

create_clock -name sysclk -period 25 -waveform {0 12.5} [get_ports HDMI_CLK_P]

this is all you need for your project.

 

Jieming

Link to comment
Share on other sites

Run,

I've tried every combination of removing the DDC port from the DVI2RGB core and commenting out the ports on the xdc, but I can't seem to get past the error.

 

Jieming, in part 3 of your first post, you mentioned that Vivado no longer handles inout as a single port. I think this is the problem I'm running into currently. You said I need to make changes to the top level module? Something like: 

HDMI_SDA <= HDMI_SDA_O when HDMI_SDA_T = '0' else 'Z';
    HDMI_SDA_I <= HDMI_SDA;

Could you elaborate on this part? I noticed those names match those in the Zybo Master XDC for the HDMI SDA and SCL. Is that what you meant by the top level module? Additionally, if there's anything from your project you could share that you think may help, I would greatly appreciate that!

Link to comment
Share on other sites

Hey Chirs,

I encountered same sort of the problem you have everytime when I forgot to delete the unconnected port on diagram, but have been commented out the port map on xdc file. For example, leave iic_0_scl_io and iic_0_sda_io port float in the diagram, but comment them out on the xdc will trigger this error.

 

Run

Link to comment
Share on other sites

Hey Marshall,

The reason I'm trying to see if I can simply remove the DDC lines is because even after following your instructions (making external, checking the design wrapper and changing the xdc port names) I cannot get the implementation to build properly. I get an error that says:

[Place 30-58] IO placement is infeasible. Number of unplaced terminals (2) is greater than number of available sites (0).
The following Groups of I/O terminals have not sufficient capacity: 
 IO Group: 0 with : SioStd: LVCMOS18   VCCO = 1.8 Termination: 0  TermDir:  BiDi RangeId: 1 Drv: 12  has only 0 sites available on device, but needs 2 sites.
    Term: iic_0_scl_io
    Term:  and iic_0_sda_io

In my design wrapper, I have two signal names iic_0_scl_io, and iic_0_sda_io. I tried modifying the master xdc to reflect those names but I still get the above error. I've also tried without the DDC (disabled it in the customize ip menu as Run suggested) but it would not build either.

I'll probably take a look at your project on the github and see what I can gather from there.

Thank you for your help and enjoy your vacation!

Chris

 

Link to comment
Share on other sites

Hey Chris,

I am out of the office and I cannot confirm what Run said will work but sounds like it might work in the case that you can force the HDMI source to a compatible resolution.

Sam explained what the DDC signals are for to me and here it is a nutshell.  The DDC lines relay to the HDMI source the resolutions that the HDMI sink can utilize.  That is how your laptop knows what resolution to display when you connect to a TV.

I'll try to help with what I can but I am on vacation so I will have bigger delays between posts.

Marshall   

Link to comment
Share on other sites

Hey Marshall,

In your post you mentioned you needed to have the DDC correctly assigned because it was causing problems. In my design, I'm not trying to output the inputted video to a display, it's endpoint is in the VDMA/Linux userspace. In this case, can I just leave the DDC pins on the DVI2RBG core disconnected or will that still cause problems? In my Vivado synthesis it keeps giving me warnings about the unconnected DDC pins.

Thanks,
Chris

Link to comment
Share on other sites

Hey Chris,

I believe you'd better name your port the way dvi2rgb uses which like you mentioned, TMDS_Data_n[2:0], TMDS_Data_p[2:0], TMDS_Clk_p, and TMDS_Clk_n. Otherwise you have to match those names to what you use on the block diagram and of course the names on zybo's port xdc file. So I did the same way you did, name all TMDS ports on block diagram TMDS_Data_n[2:0], TMDS_Data_p[2:0], TMDS_Clk_p, and TMDS_Clk_n. 

That warning comes out because you manually map the TMDS connections to Zybo's ports while the core set them up as an interface connection but that should be OK (not 100% sure). I did the same way while using rgb2dvi, manually map them to Zybo's HDMI connector instead of using interface but still works. 

And I will try to remove the logic tied to HDMI_OUT_EN and see if anything happen. I plan to use another Zybo with HDMI source (rgb2dvi) with output clock and data running forever, to drive another Zybo with HDMI sink (dvi2rgb) and see what would happen. But I don't have another Zybo at this moment. I will update as soon as I have chane to do this.

Keep up Chris, hope you are also getting some progressive outcomes. I have spent too long on this and other classmates are also stuck. It is a part of my class's final project but not sure if I could get it before the end of this quarter. :(

Anyway, good luck!

Run

Link to comment
Share on other sites

Run,

Sam from Digilent mentioned in another post that HDMI_OUT_EN needs to be driven low in order for it to act as a sink. That determines whether the 5V and HPD act as inputs or outputs, so if I'm understanding correctly there is no need for you to manually tie those high or low. I'm not 100% sure however, so if anyone else knows please correct me.

Also, Run, did you run into a problem such as this while making sure that the DVI2RGB port connections matched those in the XDC file:
WARNING: [BD 41-1306] The connection to interface pin /dvi2rgb_0/TMDS_Data_n is being overridden by the user. This pin will not be connected as a part of interface connection TMDS

I opened the XDC file to find the names of the ports, and created ports in the block diagram that matched those. When I connected the ports I just created to the pins of the DVI2RBG core, i received the above warning. Have I done something wrong or is this expected?

 

*Just realized I may have been looking at the wrong XDC file. Run, do you know what the proper names for the ports from the DVI2RGB core XDC are? Are they TMDS_Data_n[2:0], TMDS_Data_p[2:0], TMDS_Clk_p, and TMDS_Clk_n?

Link to comment
Share on other sites

Hi Marshall,

Thank you for your response. I finally figured out that I only need one XDC file for mapping ports instead of including all of those XDC files at the same time, since dvi2rgb core's XDC files will be applied during synthesis. The reason why I need to change dvi2rgb.xdc and dvi2rgb_occ.xdc is because Zybo has a maximum buffer bit clock of 600MHz but those xdc files constrain TMDS_Clk at 165MHz which requires 825MHz buffer bit clock. On the user guide it recommands to constrain TMDS_Clk at 1/5 of the maximum bit clock, which results in 600MHz / 5 = 120MHz pixel clock constraint. Also, 200MHz reference clock is required by the core so I use the clock wizard to feed that 200MHz. 

One thing I am not sure is how that 75MHz should be created? I set up the constraint "create_clock -period 13.334 [get_ports TMDS_Clk_p]" and use report_clock_network tcl command to check. It reported that TMDS_Clk_p = 75MHz but when I probed to the TMDS_Clk_p pin, it was logic forever. I also probed the generated pixel clock but it was garbage. So I am not sure does "create_clock -period 13.334 [get_ports TMDS_Clk_p]" means generating a 75MHz clock at TMDS_Clk_p or just setting up the upper limit. 

Here is the link to dvi2rgb core I mention above, you might be able to take a look into it and help me out if you have time. https://github.com/DigilentInc/vivado-library/tree/master/ip/dvi2rgb_v1_4

For "VDD" and "GND" connection, I mean tie to either logic 1 or 0 instead of physical pins. :)

 

Here is the link to the demo folder but as Chris mentioned, it is built in EDK instead of Vivado and I am not using the cores used by this demo. Check it out if you are interested.

https://github.com/LariSan/Digilent-Maker/tree/master/Zybo/zybo_video_demo

Any help/thought/suggestion would be very welcome and thank you so much for you time of replying my questions!

 

Run

Link to comment
Share on other sites

Hey Run,

Where did you get the demo?  I would like to see what you are working from.

1.  I suspect you just need to change the clocking wizard that feed the dvi2rgb core to 75MHz instead of 200MHz but I cannot be sure without poking around a little.

Although, I have only ever used one ucf/xdc file per design so I am wondering if you are having issues with that.  I could see how using multiple files could work but I don't have any experience with it.  

As for your errors, "[Common 17-55] 'set_property' expects at least one object. " error is caused by a mismatch between the defined port in Vivado and the xdc.  In this case, I would get rid of the "dvi2rgb.xdc" and the "dvi2rgb_ooc.xdc" files and rely on the zybo master xdc.  

Then I would change the zybo xdc to match the port names that are attached to the dvi2rgb core.  

2. I'll ask around but I think you should have one universal XDC.

3. Make sure to change the XDC to reflect the port names you used.

4. Do you mean you tied them by outputting them to a pin and using a wire to put them to VDD or GND?  That isn't a good idea.  Those pins are being driven as outputs and driving them to VDD or GND could short them and damage the pins.  On inputs that would be fine but I like to tie the signals to a switch or button.  On outputs, leave them unconnected.

Hope this helps.

Marshall

 

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...