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.

评论

此博客中的热门博文

How To Connect Stm32 To PC?

Detailed Explanation of STM32 HAL Library Clock System

What is JTAG, and how is it used for debugging?