element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
FPGA
  • Technologies
  • More
FPGA
Forum Vivado and Zynq: TRI-STATE help
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join FPGA to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Not Answered
  • +1 person also asked this people also asked this
  • Replies 31 replies
  • Subscribers 549 subscribers
  • Views 14591 views
  • Users 0 members are here
  • zynq
  • vivado
Related

Vivado and Zynq: TRI-STATE help

Jan Cumps
Jan Cumps over 3 years ago

I'm trying to write i2c code for Zynq, in VHDL.
I have difficulties creating a TRI-STATE pin.

The output logic should be: the pin is either pulled down to 0, or open-collector.
I have a pull-up resistor between that pin and VCC (3.3 V).
I'm expecting that if I write '0', it is low. When I write 'Z', it's open collector and pulled high by my pullup.
But in my design, the pin stays low. 0.62 V.

I thought, from reading up, that I should be done by:

  • defining the pin as INOUT
  • when you want to drive it low, assign '0'.
  • when you want to drive it open collector, assign 'Z'.
  • put an external pullup between pin and VCC

I created a testbed that puts the pin in "Z' mode, except when reset is asserted (via an external button).
In my testbed I also added a test pin, that I attach to an LED, that is high when the reset is asserted.
I connected a multimeter to the output.

The LED behaves as expected. It lights up when I assert the reset.
But the tri-state pin stays low, whether I write '0' or 'Z' to it. 

entity tristate_test is
    Port ( 
    reset_n: in std_logic;
    reset_out: out std_logic;
    tristate_pin : inout std_logic);
end tristate_test;

architecture Behavioral of tristate_test is

begin

reset_active: process (reset_n) is

begin
  if (reset_n = '0') then
    tristate_pin <= '0';
    reset_out <= '1';
  else
    tristate_pin <= 'Z';
    reset_out <= '0';
  end if;
end process reset_active;

end Behavioral;

Here is how I set the constraint:

image

set_property PACKAGE_PIN Y18 [get_ports tristate_pin_0]
set_property IOSTANDARD LVCMOS33 [get_ports tristate_pin_0]
set_property DRIVE 12 [get_ports tristate_pin_0]

Schema:

image

PMOD A pin 1 is PACKAGE_PIN Y18

What am I doing wrong?

  • Sign in to reply
  • Cancel

Top Replies

  • jc2048
    jc2048 over 3 years ago +4
    It might be a problem with hierarchy with the drag-and-drop stuff. An answer to this support question suggests that you need to set the synthesis to flatten the hierachy so that the tristate-ness can propagate…
  • jc2048
    jc2048 over 3 years ago in reply to bhfletcher +4
    Once you understand that the block-based design is an entity that could be used as part of a larger, more traditional design, the issue with the top-level wrapper becomes clearer. If the user is just using…
  • rachaelp
    rachaelp over 3 years ago +3
    Hi Jan, Just create the tristate in an assignment and not in a process. Not sure why what you have isn't working, have you looked at the schematic for what it's creating in Vivado? I guess maybe it's…
Parents
  • Jan Cumps
    0 Jan Cumps over 3 years ago

    I'm circling on this for two weeks now (there's a preceding post where this one was spawned off). Read a lot, tried a lot. Lost perspective.
    I'm going to let it rest for a while, pick it back up with fresh energy.

    • Cancel
    • Vote Up +1 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Metaforest
    0 Metaforest over 3 years ago in reply to Jan Cumps

    Something  haven't seen discussed in this thread is the importance in Vivado of putting a "wrapper" around your block design. I've also noticed that making changes to the block design, such as wiring or modifying the ports can cause the wrapper to go stale.  You can delete the wrapper from the project and rewrap the block design.

    In the sources panel you should see an orange triangular shape next to an orange rectangle with the name of your block design.  This is what a bare design file looks like in the source panel.   If you right click on the design you should get a menu.  Select 'Create HDL wrapper'  It will create a VHDL module that connects your block design with the board layout.  Creating the wrapper allows Vivado to properly infer i/o mapping and tri_states.

    If you are working from a board that has a correct board definition stored in the board layout section of the Vivado installation, then you should be able to use your block design.  In the Board Support file(Board.xml) Be sure that the device pin you want to use component_pin="<device pin name>"  and three following entries with the suffix '_T' , '_I' , and '_O'  you might be able to explicitly refer to the device pin with the correct suffix to get a direct hold of the tri_state switch.

    if you look in the board.xml file you will also see pin_map_file="<your pin map file" look in that file to see what that device pin maps to in the board design editor.

    Using the name you discovered in the pin_map_file create a port and set it as an output, rather than a INOUT.  Keep the inout definition in your hdl file. Another file to look for is a master constraints file for your board( .XDC) it may have references to other pins on the board that are available for use but don't have a predefined role on the board.   (GPIO)  make sure you have a properly formed constraint entry for the pin.

    EDIT:

    found it:

    in language templates you will find:  Device Primitive Instantiation/<your device family>/IO Components/Bidirectional Buffers/Single-ended Buffer(IOB)

    This gives you the Vivado approved invocation for the IOBUF on the RTL side.

    On the pin_interface side:

    in your block design:

    Right Click on blank space in the canvas:  Select->  Create Interface Port...

    Enter name of the pin you want to use  (declared in the board.xml::pin_table_file, or in the XDC you have added to your project.)

    search gpio

    select gpio_rtl

    Viola! you now have a port pin that has the correct configuration using IOBUF

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • bhfletcher
    0 bhfletcher over 3 years ago in reply to Metaforest

    I'm not sure if this will also be helpful, but I was doing a little research on this area as well. I learned two things:

    1. If you are already using Xilinx IP with tri-state logic, anything additional you add will just mess things up. See community.element14.com/.../basic-pull-up-tri-state-test-trouble
    2. If you are going to add tri-state buffers in HDL, you may need to put it inside that top-level wrapper, at least you did as recently as 2019. See https://support.xilinx.com/s/question/0D52E00006hpJw7SAE/tristate-buffers-in-board-design?language=en_US which in turn references https://support.xilinx.com/s/question/0D52E00006hpJOQSA2/why-does-vivado-reject-my-bidirectional-ports?language=en_US

    Good luck!

    Bryan

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • jc2048
    0 jc2048 over 3 years ago in reply to bhfletcher

    Once you understand that the block-based design is an entity that could be used as part of a larger, more traditional design, the issue with the top-level wrapper becomes clearer. If the user is just using the blocks, then it's desirable for the design software to maintain the wrapper on any changes to the block design. If it's part of a wider design, you probably don't want the block stuff to keep regenerating the wrapper on changes and overwriting stuff that has been added and it's then up to the user to maintain the wrapper [their top-level entity].

    I think that some of the difficulty here might be because it's valid to describe, in VHDL, a tristate internal bus between entities. Doesn't matter whether it can be done any particular hardware or not, the synthesis just has to get on with it and, if necessary, translate it into an equivalent logic form (usually it would constitute a multiplexer in some arrangement). At the top level things are unambiguous - the 'tristateness' must be referring to an IO pin. But a tristate at the top of the blocks, one level (or more) down, might just be forming a bus with other entities in the design and not go anywhere near an IO pin. Alternatively, as another example, there could be an internal tristate bus that simply feeds an output pin. So something extra that clears up the ambiguity is necessary.

    If anyone is interested, there's an historical twist to this because Xilinx FPGAs, once upon a time, did actually include internal tristate busses and they could be designed with quite explicitly.

    Here's how 'long lines' are shown in the 1989 Xilinx databook. Notice the tristate drivers.

    image

    Here's part of an application note showing how the 'long line' could be used for fast multiplexing of the various addresses to implement a DRAM controller.

    image

    I did a design around that time which controlled VRAM and can just about remember using tristate buffers and an internal bus in that way for multiplexing the RAS, CAS, etc (it was done with schematic capture and the part library had a '125' part, ie equivalent functionally to a 74125 tristate buffer, that you could use). Can't remember if I was using 2000 or 3000 series parts.

    I imagine it was a bit of a liability for them at the time because of the way you might disrupt the device operation if you got the control of the buffers wrong.

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Reply
  • jc2048
    0 jc2048 over 3 years ago in reply to bhfletcher

    Once you understand that the block-based design is an entity that could be used as part of a larger, more traditional design, the issue with the top-level wrapper becomes clearer. If the user is just using the blocks, then it's desirable for the design software to maintain the wrapper on any changes to the block design. If it's part of a wider design, you probably don't want the block stuff to keep regenerating the wrapper on changes and overwriting stuff that has been added and it's then up to the user to maintain the wrapper [their top-level entity].

    I think that some of the difficulty here might be because it's valid to describe, in VHDL, a tristate internal bus between entities. Doesn't matter whether it can be done any particular hardware or not, the synthesis just has to get on with it and, if necessary, translate it into an equivalent logic form (usually it would constitute a multiplexer in some arrangement). At the top level things are unambiguous - the 'tristateness' must be referring to an IO pin. But a tristate at the top of the blocks, one level (or more) down, might just be forming a bus with other entities in the design and not go anywhere near an IO pin. Alternatively, as another example, there could be an internal tristate bus that simply feeds an output pin. So something extra that clears up the ambiguity is necessary.

    If anyone is interested, there's an historical twist to this because Xilinx FPGAs, once upon a time, did actually include internal tristate busses and they could be designed with quite explicitly.

    Here's how 'long lines' are shown in the 1989 Xilinx databook. Notice the tristate drivers.

    image

    Here's part of an application note showing how the 'long line' could be used for fast multiplexing of the various addresses to implement a DRAM controller.

    image

    I did a design around that time which controlled VRAM and can just about remember using tristate buffers and an internal bus in that way for multiplexing the RAS, CAS, etc (it was done with schematic capture and the part library had a '125' part, ie equivalent functionally to a 74125 tristate buffer, that you could use). Can't remember if I was using 2000 or 3000 series parts.

    I imagine it was a bit of a liability for them at the time because of the way you might disrupt the device operation if you got the control of the buffers wrong.

    • Cancel
    • Vote Up +4 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
Children
No Data
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube