How to drive an externally pulled up with fpga pin?

 To drive a line that has an external pull-up from an FPGA, treat the pin as open-drain/open-collector:

  • Never drive a ‘1’.

  • Drive ‘0’ to pull the line low.

  • Otherwise put the pin in Hi-Z so the external resistor pulls it high.

That’s it—plus a few electrical + HDL details below.




HDL patterns

1) Simple open-drain output (Verilog)

// pad goes low when drive_low=1, otherwise Hi-Z (external R pulls high) wire drive_low; assign PAD = drive_low ? 1'b0 : 1'bz;

2) Bidirectional, e.g., I²C SDA (Verilog)

inout wire SDA; wire sda_pull_low; // 1 = pull low, 0 = release assign SDA = sda_pull_low ? 1'b0 : 1'bz; // never drive '1' wire sda_read = SDA; // read the line

3) Using vendor I/O buffers

Xilinx (IOBUF):

wire sda_in; wire sda_pull_low; // 1 = pull low IOBUF #(.IOSTANDARD("LVCMOS33")) iobuf_sda ( .IO(SDA), .I(1'b0), // we only ever drive 0 .O(sda_in), // readback .T(~sda_pull_low) // T=1 => Hi-Z (release), T=0 => drive 0 );

Intel/Altera (Quartus) assignment (example):

set_instance_assignment -name OPEN_DRAIN ON -to SDA

(Or instantiate ALT_IOBUF; behavior is the same—drive 0 or Hi-Z only.)

VHDL idea:

SDA <= '0' when pull_low='1' else 'Z'; sda_in <= SDA;

Electrical checklist

  1. Pull-up value (speed vs current):

    • Rise time ≈ 0.85 · Rpull · Cbus (RC step).

    • Common choices at 3.3 V: 4.7 kΩ–10 kΩ. Faster edges → 2.2–4.7 kΩ.

    • Sink current when low: I = Vpull / Rpull (e.g., 3.3 V/4.7 kΩ ≈ 0.7 mA).

    • Keep within the FPGA pin’s IOL rating and your VOL target.

  2. Disable internal pulls/bus-keepers on that pin, or they’ll fight the bus.

  3. IO standard & pad settings:

    • Use your bank voltage (e.g., LVCMOS33).

    • SLEW = SLOW and minimal DRIVE (you’re only sinking) to reduce noise.

  4. 5 V pull-ups caution:

    • Most FPGA I/Os are not 5 V tolerant. A line pulled to 5 V can forward-bias clamp diodes even if you “never drive high”.

    • If the bus must be 5 V, use a level-shifting open-drain translator (e.g., PCA9306/BSS138 circuit) or ensure the specific FPGA/bank is genuinely 5 V tolerant in input/Hi-Z.

  5. Multiple drivers (wired-AND):

    • Safe because all drivers only pull low or release.

    • Ensure your logic never asserts two conflicting push-pull drivers—keep everything open-drain style.

  6. EMI/line integrity:

    • Keep the pull-up physically near the bus, route short, and add small RC if you need edge-rate control on long lines.


Quick test pattern (Verilog)

// Blink the line low for 10 ms, release for 10 ms reg [23:0] cnt; always @(posedge clk) cnt <= cnt + 1; assign PAD = (cnt[19]) ? 1'bz : 1'b0; // 0 = pull down, z = release

TL;DR

Configure the FPGA pin as open-drain: drive 0 or Z only. Size the pull-up for your rise-time and sink-current budget. Avoid 5 V pull-ups unless the pin is truly 5 V tolerant or you add a level shifter.

评论

此博客中的热门博文

Detailed Explanation of STM32 HAL Library Clock System

How To Connect Stm32 To PC?

How to add a GPS sensor to ESP32 for Wokwi?