How to eeprom auto send when restart FPGA board?

 Short answer: an EEPROM won’t “auto-send” anything by itself. It’s passive. On every restart, your FPGA must actively read it and then transmit the data (UART/SPI/I²C/Ethernet… whatever “send” means for you). Here’s a solid, repeatable way to do that.



What you need to build

  1. Power-on/reset sequencer

  • Hold your logic in reset until clocks are stable (PLL locked).

  • Give the EEPROM a little time to wake (typ. 1–10 ms) or poll for ACK.

  • Optional: debounce a “BOOT” GPIO to force/skip sending.

  1. EEPROM reader

  • Pick the correct bus:

    • I²C (24xx): 7-bit device addr (usually 0b1010xxx), 1- or 2-byte word address.

    • SPI (25xx): opcodes like 0x03 (READ), 24-bit address.

  • Implement a simple burst read FSM that pulls a contiguous region (e.g., header + payload + CRC).

  1. Transport/transmitter

  • Send the bytes where they need to go:

    • UART for logs/host (easy).

    • SPI if you’re feeding another MCU/FPGA.

    • AXI-Stream/FIFO to internal logic.

  • Add a small FIFO between reader and transmitter to decouple timing.

  1. Verifier (optional but recommended)

  • Put a 2–4-byte length and CRC at the start of EEPROM so you can validate before sending.


I²C EEPROM read flow (24xx family)

  1. START

  2. Send device address + W

  3. Send word address (1 or 2 bytes)

  4. REPEATED START

  5. Send device address + R

  6. Read N bytes, ACK each byte, NACK the last

  7. STOP

Notes
• Reads can usually cross page boundaries (page limits apply to writes).
• Some devices need tPU (~ms) after power-up; polling for ACK is the robust way.
• SDA/SCL are open-drain. Use pull-ups (2.2–10 kΩ). Respect bus speed (100/400/1 MHz).

SPI EEPROM read flow (25xx family)

  1. CS↓, send 0x03 (READ)

  2. Send 24-bit address

  3. Clock out N bytes (dummy 0x00 on MOSI)

  4. CS↑


Minimal RTL blueprint (pseudo-Verilog)

// Top-level skeleton module boot_send_top( input wire clk, rst_n, // I2C pins inout wire sda, scl, // UART out output wire uart_tx ); // 1) Reset stretch & power-up wait wire reset_sync; reset_sync u_rst(.clk(clk), .rst_n_in(rst_n), .rst_out(reset_sync)); wire eeprom_ready; powerup_timer #( .MS(5) ) u_pu(.clk(clk), .rst(reset_sync), .ready(eeprom_ready)); // 2) EEPROM reader -> FIFO wire [7:0] rd_data; wire rd_valid; wire rd_last; i2c_eeprom_reader #( .DEV_ADDR(7'h50), // 24xx base .ADDR_BYTES(2), // 16-bit word address .START_ADDR(16'h0000), .BYTE_COUNT(16'd1024) // read 1 KB ) u_rd( .clk(clk), .rst(~eeprom_ready), .sda(sda), .scl(scl), .data_o(rd_data), .valid_o(rd_valid), .last_o(rd_last) ); // Small async FIFO is nice if UART clock differs; here assume same clk wire fifo_rd_en, fifo_empty; byte_fifo u_fifo(.clk(clk), .rst(~eeprom_ready), .din(rd_data), .wr_en(rd_valid), .dout(uart_byte), .rd_en(fifo_rd_en), .empty(fifo_empty)); // 3) UART transmitter (e.g., 115200) uart_tx #(.CLK_HZ(50_000_000), .BAUD(115200)) u_uart( .clk(clk), .rst(~eeprom_ready), .tx_data(uart_byte), .tx_valid(~fifo_empty), .tx_ready(fifo_rd_en), .tx(uart_tx) ); endmodule

That’s the whole idea in ~30 lines: wait → read EEPROM → stream out. Swap uart_tx with your actual destination (SPI master to a companion MCU, AXI-Stream into logic, etc.).


Using a soft CPU (often faster to finish)

If you have Zynq/SoC FPGA or don’t mind a tiny soft core:

  • Start a MicroBlaze / Nios II / PicoRV32 at reset.

  • Use vendor I²C/SPI driver:

    • Read header {len, crc} at address 0.

    • Burst-read payload into BRAM.

    • Validate CRC.

    • Write out via UART/SPI/Ethernet.

  • Pros: fewer HDL corner cases (I²C clock stretching, retries, timeouts) and easier updates later.


Practical bring-up checklist

  • Clocks/reset: Hold everything until PLLs lock; then add an extra few ms or ACK-poll the EEPROM.

  • Pull-ups: I²C needs them. Keep traces short; 4.7 kΩ @ 3.3 V is a safe start.

  • Addressing: 16-bit vs 8-bit word address; 7-bit vs “8-bit” datasheet notation (shifted).

  • Retries: If no ACK after power-up, retry every ~100–500 µs until a timeout.

  • Throughput: UART is slow; if you must send KBs at boot, prefer SPI or a parallel stream.

  • EMI: For SPI, keep SCK clean; for I²C, mind slew rates and bus capacitance.

  • Validation: Add a magic number & CRC in EEPROM to avoid blasting garbage.

评论

此博客中的热门博文

Detailed Explanation of STM32 HAL Library Clock System

How To Connect Stm32 To PC?

How to add a GPS sensor to ESP32 for Wokwi?