UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor stefanoo
Visitor
496 Views
Registered: ‎06-26-2018

writing VHDL for internal pull-up

Jump to solution

I'm trying to make a tristate buffer work for a MiniZed board because I need to read data from an AD7991.

The tristate buffer is then used as a blackbox by Simulink.

 

The peripheral wasn't responding then I realized my VHDL code is missing the definition of the internal pull-ups on SDA and SCL. At the moment I'm testing with two soldered resistors but that is not really what I want in the end.

 

Can I define the pullups inside this code? (none of the examples I could find seems to use IOBUF)

 

library ieee;
     use ieee.std_logic_1164.all;

library unisim;
     use unisim.vcomponents.all;

entity i2c_bidir 
is Port ( 
     I2C_CLK   : in    std_logic;
     I2C_DATA  : in    std_logic;
     bus_ctl   : in    std_logic;
     I2C_SCL   : out   std_logic; 
     I2C_SDA   : inout std_logic; 
     sda_local : out   std_logic
     );
end i2c_bidir;

architecture Behavioral of i2c_bidir is

begin

 OBUF_inst : OBUF
  generic map (
     IOSTANDARD => "LVCMOS33",
     DRIVE => 12,
     SLEW => "SLOW")
  port map (
     O => I2C_SCL,     -- Buffer out (connect directly to top-level port)
     I => I2C_CLK      -- Buffer in 
  );

 IOBUF_inst : IOBUF
  generic map (
     IOSTANDARD => "LVCMOS33",
     DRIVE => 12,
     SLEW => "SLOW")
  port map (
     O => sda_local,   -- Buffer out
     IO=> I2C_SDA,     -- Buffer inout (connect directly to top-level port)
     I => I2C_DATA,    -- Buffer in
     T => bus_ctl      -- 3-state control: high=input, low=output
  );

end Behavioral;
0 Kudos
1 Solution

Accepted Solutions
Historian
Historian
569 Views
Registered: ‎01-23-2009

Re: writing VHDL for internal pull-up

Jump to solution

Every pin has a weak pull-up (and pull-down) register that can be enabled. This can definitely be done using the PULLUP attribute of the cell, so you can do it in your constraint file (XDC or UCF).

 

I don't think it can be done in the RTL itself.

 

BUT, the pull-up in the IOB is very weak - on a 3.3V signal it is spec'ed at 90uA. At this current, it will take 1.3us to charge a 50pF line to 2.4V (the threshold voltage for most 3.3V CMOS inputs). This is probably far too slow for an I2C - particularly if you are planning to run it at 400kHz - the rise time should be less than 300ns...

 

So you probably do need an external resistor for the I2C pull-up.

 

Avrum

3 Replies
Historian
Historian
570 Views
Registered: ‎01-23-2009

Re: writing VHDL for internal pull-up

Jump to solution

Every pin has a weak pull-up (and pull-down) register that can be enabled. This can definitely be done using the PULLUP attribute of the cell, so you can do it in your constraint file (XDC or UCF).

 

I don't think it can be done in the RTL itself.

 

BUT, the pull-up in the IOB is very weak - on a 3.3V signal it is spec'ed at 90uA. At this current, it will take 1.3us to charge a 50pF line to 2.4V (the threshold voltage for most 3.3V CMOS inputs). This is probably far too slow for an I2C - particularly if you are planning to run it at 400kHz - the rise time should be less than 300ns...

 

So you probably do need an external resistor for the I2C pull-up.

 

Avrum

Visitor stefanoo
Visitor
444 Views
Registered: ‎06-26-2018

Re: writing VHDL for internal pull-up

Jump to solution

I've read about using the XDC file but you made it much more clear, and in fact it works with a trick:

Matlab automatically generates the .xdc constraints so I had to put the PULLUP definition inside this file before generating the bitstream.

 

I'm running my implementation at 100kHz so 1.3ns rise would have been perfect but the signal with the internal pullup appears odd (slow and scaled) similar to what I have experienced before with external 5kOhm resistors.

This graph show the difference between the internal pullup and an external 1kOhm resistor.

 

pullup differences

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

It's a pity I have to put these resistors, the peripheral is not a custom circuit I'm building but a Digilent AD2 (and I will have to modify a bunch of them to be used by students).

 

I've now found many references to Xilinx and 330Ohm external pullups, I will give it a try because the result from 1kOhm is still a little scaled. 

 

Thanks a lot Avrum!!

0 Kudos
Visitor stefanoo
Visitor
425 Views
Registered: ‎06-26-2018

Re: writing VHDL for internal pull-up

Jump to solution

I figured why the response is odd!

 

the PMOD is a two rows header connector and in the peripehral side (Digilent AD2) each pin on top is shorted to the pin below.

 

This is a very unwelcomed redundancy because it shorts the upper ports with the lower ports on the board side.

 

For example I'm using the upper ports and I did not define any behaviour for the lower ports (then I have no idea what impedance they have).

 

Using the internal PULLUP defined in the .xdc file and shifting the connection up one row (fig.) the I2C communication is perfect!!! (no need for external resistors!!)

AD2 PMOD connection

... guess I will let the students define the lower port impedance or shift the connection.... :-D

0 Kudos