Jump to content
  • 0

Artix Z7 HDMI ports error as TMDS - I/O port is single ended but can only support differential


White Horse Software

Question

Using Vivado 2020.1, with the Digilent-provided .xdc constraints and a simple .vhdl using HDMI TMDS ports.

The project will not generate a bitstream because it fails with the error: "[DRC IOSTDTYPE-1] IOStandard Type: I/O port hdmi_tx_clk_n is Single-Ended but has an IOStandard of TMDS_33 which can only support Differential". In fact this error shows up for any of the HDMI ports I use.

Does anything special need to be done to configure these ports? I don't see anything in the reference documentation.

Please note this is not a question about how to set up .vhdl for actually using the HDMI ports properly. I'm simply pointing out I don't see how to even configure the ports for TMDS.

The .xdc and .vhdl files are attached.

Arty-Z7-20-Master.xdc test.vhdl

Link to comment
Share on other sites

9 answers to this question

Recommended Posts

  • 0
59 minutes ago, White Horse Software said:

Don't they? Sorry I'm in a rush at the moment, but glancing at the .vhdl and the .xdc, things like "hdmi_tx_clk_n" do in fact match up. Would you mind helping me better understand?

Well I wanted to see your response before getting more explicit.

Due to the limitations of VHDL you are only able to specify signal types as is defined by the IEEE libraries that you use.

You want to use both ieee.std_logic_1164 and ieee.numeric_std libraries. These are not the best combination of choices. I suggest either using ieee.numeric_std, or ieee.std_logic_1164 and either ieee.std_logic_unsigned or ieee.std_logic_signed depending on what format your want to work with. As it stands, you will likely run into conflicts with the synthesis tools as it tries to figure out what you mean by the '+' or '-' operators; if not in this project then in more complex ones.

Let's presume that you comment out ieee.numeric_std and go with the 1164 and unsigned libraries. You are constrained to putting std_logic or std_logic_vector types on your toplevel port list. The problem with this is that Vivado synthesis interprets these as single-ended IO signals requiring single-ended output buffers. You are probably thinking that since your constraints file declares IOSTANDARD TMDS_33, synthesis would understand that it needs to instantiate a differential output buffer. Unfortunately, this isn't how VIvado works. Don' ask me why, ask your tool vendor.  Your only recourse is to explicitly instantiate an appropriate differential output buffer, like OBUFDS, in your code to help out synthesis understand your design.  

While you can get away with letting Vivado synthesis instantiate IO buffers for you, it's a much better idea to do this for yourself.

Read UG472 Series7 Select IO User Manual for more information.

Edited by zygot
Link to comment
Share on other sites

  • 0
9 hours ago, White Horse Software said:

Please note this is not a question about how to set up .vhdl for actually using the HDMI ports properly. I'm simply pointing out I don't see how to even configure the ports for TMDS

This part of your question makes no sense at all. Of course your question is about both your VHDL and constraints; it always is. Your question is about a bitgen error that you have no idea how to resolve. The answer to your question is in your VHDL source.

If your HDL source doesn't explicitly instantiate input or output buffers, then the tool will try and instantiate one for you based on your HDL source. A couple of other hints is that logic IO buffers are distinct from clock IO buffers, and single-ended IO buffers are not the same as differential IO buffers.

Your HDL source and constraints must agree and the port names must match in both places.

 

Edited by zygot
Link to comment
Share on other sites

  • 0

Part of your confusion is that HDLs like VHDL and Verilog were not designed for logic synthesis. You'd think that after 40 years or so of allowing VHDL as a source for tools like Quartus or Vivado or ISE that HDLs would have kept up. They haven't, probably because there isn't much incentive for FPGA vendors to push for it.

The result of all of this is relevant to your problem: VHDL doesn't know anything about differential signalling. This means that you can't specify a differential signal directly in your VHDL source code. VHDL doesn't know anything about IO buffers either. This is all vendor specific. A lot of things that you might want to include in your VHDL are things that VHDL is ignorant about. You have to instantiate vendor specific macros or primitives instead.

Notably, vendors do allow you to put some of their vendor specific specifications, directives, and other information into your source that VHDL doesn't understand but that the tools do. Unfortunately, it's all vendor specific and worse yet completely arbitrary. Timing specifications is another area where HDLs are inadequate.

So, there's a disconnect between what the HDL can do and what is required by FPGA vendor tools. None of them let you put location constraints in your source code, which in my humble opinion, is where they belong.

In other technologies, third parties set definitions for how devices are specified and conform; MSI or LSI logic being an example. The vendors then conform to those standards. In the programmable logic world, this never happened. FPGA vendors would much rather do their own thing and make it hard to change vendors. So, HDLs are still in the 20th century and vendors design their synthesis tools to be unique and hard to port to other vendors tools.

Over the years I've seen a lot of attempts at creating a framework for FPGA design that is vendor agnostic. Some of them have very impressive, but limited, application demos to get people interested. None of the one's that I've come across are suitable alternatives to what the FPGA vendors want the world to look like.

What the world needs is a good 21st century  HDL that lets you do your entire design using the HDL keywords. This would require programmable logic vendors to conform to a 3rd party specification for synthesis. I don't see that happening any time soon.

Edited by zygot
Link to comment
Share on other sites

  • 0
3 hours ago, zygot said:

This part of your question makes no sense at all. Of course your question is about both your VHDL and constraints; it always is. Your question is about a bitgen error that you have no idea how to resolve. The answer to your question is in your VHDL source.

If your HDL source doesn't explicitly instantiate input or output buffers, then the tool will try and instantiate one for you based on your HDL source. A couple of other hints is that logic IO buffers are distinct from clock IO buffers, and single-ended IO buffers are not the same as differential IO buffers.

Your HDL source and constraints must agree and the port names must match in both places.

 

Thanks for the response. This same error is happening in a more substantial project, with other HDMI ports in use and actual (useful) circuit designs - I'm doing it all, no IP, partly as a hobby project. It simulates and even synthesizes with no issues. So my hope was to cut through the noise and recreate in a minimum-viable way for presenting the problem.

> Your HDL source and constraints must agree and the port names must match in both places.

Don't they? Sorry I'm in a rush at the moment, but glancing at the .vhdl and the .xdc, things like "hdmi_tx_clk_n" do in fact match up. Would you mind helping me better understand?

Link to comment
Share on other sites

  • 0
2 minutes ago, zygot said:

Well I wanted to see your response before getting more explicit.

Due to the limitations of VHDL you are only able to specify signal types as is defined by the IEEE libraries that you use.

You want to use both ieee.std_logic_1164 and ieee.numeric_std libraries. These are not the best choices. I suggest either using ieee.numeric_std, or ieee.std_logic_1164 and either ieee.std_logic_unsigned or ieee.std_logic_signed depending on what format your want to work with. As it stands, you will likely run into conflicts with the synthesis tools as it tries to figure out what you mean by the '+' or '-' operators; if not in this project then in more complex ones.

Let's presume that you comment out ieee.numeric_std and go with the 1164 and unsigned libraries. You are constrained to putting std_logic or std_logic_vector types on your toplevel port list. The problem with this is that Vivado synthesis interprets these as single-ended IO signals requiring single-ended output buffers. You are probably thinking that since your constraints file declares IOSTANDARD TMDS_33, synthesis would understand that it needs to instantiate a differential output buffer. Unfortunately, this isn't how VIvado works. Don' ask me why, ask your tool vendor.  Your only recourse is to explicitly instantiate an appropriate differential output buffer, like OBUFDS, in your code to help out synthesis understand your design.  

Read UG472 Series7 Select IO User Manual for more information.

Okay, now I understand better. I was indeed thinking, like you said, that the constraints file would be all that is needed.

I'll give this a shot. Thanks also for the UG472 ref.

Link to comment
Share on other sites

  • 0
On 8/20/2023 at 6:40 AM, D@n said:

If the XDC file is correct, the only thing left missing should be the instantiation of an OBUFDS.

Here's an HDMI example instantiating such an OBUFDS.  (Yes, it's Verilog ... where I don't have to worry about which library I'm using for 10-bit integers.)

Dan

I can muddle through reading Verilog so this is appreciated. I'm at hobby level so I can afford to choose language based on personal preference. I tried getting into Verilog a while back but ended up favoring VHDL... that is, until the day the mysterious "perfect HDL language" materializes from forum discussions into reality.

Link to comment
Share on other sites

  • 0
On 8/19/2023 at 12:52 PM, zygot said:

Well I wanted to see your response before getting more explicit.

Due to the limitations of VHDL you are only able to specify signal types as is defined by the IEEE libraries that you use.

You want to use both ieee.std_logic_1164 and ieee.numeric_std libraries. These are not the best combination of choices. I suggest either using ieee.numeric_std, or ieee.std_logic_1164 and either ieee.std_logic_unsigned or ieee.std_logic_signed depending on what format your want to work with. As it stands, you will likely run into conflicts with the synthesis tools as it tries to figure out what you mean by the '+' or '-' operators; if not in this project then in more complex ones.

Let's presume that you comment out ieee.numeric_std and go with the 1164 and unsigned libraries. You are constrained to putting std_logic or std_logic_vector types on your toplevel port list. The problem with this is that Vivado synthesis interprets these as single-ended IO signals requiring single-ended output buffers. You are probably thinking that since your constraints file declares IOSTANDARD TMDS_33, synthesis would understand that it needs to instantiate a differential output buffer. Unfortunately, this isn't how VIvado works. Don' ask me why, ask your tool vendor.  Your only recourse is to explicitly instantiate an appropriate differential output buffer, like OBUFDS, in your code to help out synthesis understand your design.  

While you can get away with letting Vivado synthesis instantiate IO buffers for you, it's a much better idea to do this for yourself.

Read UG472 Series7 Select IO User Manual for more information.

Wanted to follow up and say thank you, inserting OBUFDS fixed the issue. Bitgen complete! Now on to further challenges...

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...