DEV Community

Hedy
Hedy

Posted on

What is the timing sequence for Xilinx FPGA to load programs through FLASH?

For Xilinx SRAM FPGAs, “load program from Flash” = power-on configuration sequence.
Whether it’s a Spartan-3E, 7-Series or UltraScale, the flow is basically the same, especially in SPI-Flash master mode.

I’ll describe the generic timing sequence using Master SPI Flash as the concrete case (what most boards use).

1. Global power-up & FPGA initialization

After power is applied:

  1. All FPGA supplies ramp (VCCINT, VCCAUX, VCCO_0 etc.).
    When the internal Power-On Reset (POR) circuits see all rails above threshold, they trigger an internal reset.

  2. On POR / configuration restart:

  • PROG_B is (or goes) Low → FPGA clears its configuration memory.
  • DONE and INIT_B are driven Low.
  1. After the internal memory clear finishes:
  • INIT_B is released High (with external pull-up), indicating “ready to accept a bitstream”.
  • At that edge, the FPGA samples mode pins (M[2:0]) and variant pins (VS/FS[2:0]) to decide how to configure (SPI vs BPI, x1 vs x4, which opcode, etc.).

In many designs, the whole “wait for POR + INIT_B high” is < ~50 ms, but Xilinx explicitly treats it as Step 1–2 of configuration.

2. SPI Flash power-up race & gating

At the same time, the SPI NOR Flash also has its own power-on-reset time before it will accept a READ command (tPU in the Flash datasheet).

Xilinx warns about a race condition:

  • FPGA finishes POR quickly and starts issuing a SPI READ.
  • Flash has not finished its own POR → it ignores or mis-interprets the first command.

Typical solutions:

  • Choose a Flash with tPU < FPGA POR + init (so it is always ready in time), or
  • Hold INIT_B Low externally (open-drain) until some delay has passed or until a supervisor says the Flash is ready. XAPP951 explicitly says if Flash needs >2 ms to wake, you can hold INIT_B Low until then.

Once INIT_B is allowed to go High, the FPGA immediately proceeds to the configuration from Flash step.

3. Actual configuration from SPI Flash

Now we’re in SPI master configuration mode:

  1. Mode pins for SPI:
    For Spartan-3E/Virtex-5 example, SPI is M[2:0] = 0 0 1, sampled when INIT_B rises. 7-Series uses a similar encoding (see UG470).

  2. Variant pins VS/FS[2:0] tell the FPGA which SPI opcode to use:

  • e.g. <1:1:1> → FAST READ (0x0B), 24-bit address, 1 dummy byte;
  • <1:0:1> → READ (0x03), 24-bit address, 0 dummy bytes.
  1. Configuration transaction (simplified):
  • FPGA drives CSO_B / FCS_B Low (chip select to Flash).
  • FPGA’s internal oscillator generates CCLK, output on the CCLK pin, which also clocks the Flash.
  • On MOSI the FPGA sends:
  1. 8-bit READ command (0x03 or 0x0B).
  2. 24-bit start address, usually 0x000000.
  3. Required dummy bytes if using fast-read.
  • The Flash responds on MISO → DIN/D_IN pin, streaming the bitstream bits.
  1. The FPGA keeps clocking CCLK and shifting in data until it has received the entire bitstream (recognized by header + sync word + length and CRC).

  2. If the bitstream is valid (CRC ok), the device finishes configuration and moves into startup.

You can estimate the configuration time from:

Xilinx gives this explicitly: bus-width is 1/2/4 for SPI, 8/16 for BPI, etc.

4. Startup sequence & DONE

After the bitstream is loaded and verified, the FPGA executes an internal startup sequence:

Typical order (simplified – exact order is configurable via bitstream options in UG470):

  • Release GSR (global set/reset of FFs)
  • Release GTS (tristate → I/Os become active)
  • Drive DONE High (open-drain with external pull-up)
  • Optionally assert EOS (End-Of-Startup) inside the fabric.

Key external pin behavior:

  • DONE: Low during config, goes High when configuration + startup complete. Needs an external pull-up (often ~330 Ω on older families, kΩ on newer).
  • INIT_B:
    • Low during init and if any CRC/config error occurs.
    • High when initialization is finished and during successful configuration.

If CRC or other error is detected, FPGA can:

  • Drive INIT_B Low,
  • Abort configuration,
  • Optionally support fallback / MultiBoot to another Flash address on next attempt.

5. Putting it all together – text-timing sketch (Master SPI)

Here’s a compact textual timing sketch of a clean power-up:

Power rails:   ----ramp----> [all above POR] ---------------------------
PROG_B:        ---------L (clear config) ---- H ------------------------>
INIT_B:        L (clear mem) ------H (mode pins sampled) ----- H ------->
M[2:0]/VS[2:0]:       (must be stable BEFORE INIT_B rises) -------------
CSO_B/FCS_B:                           H -----L-----------------H------->
CCLK:                                  idle  clock...clock...  idle ---->
MOSI:                                  cmd  + addr + dummy + ...  ------>
DIN(D_IN):                                   <------bitstream data------>
DONE:        L.............................L..............H(user mode)->
Enter fullscreen mode Exit fullscreen mode
  • From INIT_B rising to DONE rising is your bitstream load + startup time.
  • If Flash isn’t ready or the bitstream is corrupt, you’ll see INIT_B drop Low again and DONE never go High.

6. Board-level design tips

When you design or debug your board:

  1. Check the four global steps (Xilinx summary)
  • Wait for POR on all FPGA rails.
  • Wait for INIT_B High.
  • Transfer bitstream from Flash (watch CCLK, CS, MOSI, DIN).
  • Watch DONE go High and user logic start.
  1. Oscilloscope-debug recipe:
  • Probe VCCINT, VCCAUX, VCCO_0, INIT_B, CCLK, CSO_B/FCS_B, DIN, DONE.
  • Confirm:
    • INIT_B rises once rails are good.
    • FPGA actually toggles CCLK and CS.
    • DIN has data.
    • DONE eventually goes High.
  1. If configuration fails:
  • Check Flash contents & address (bitstream must be at the address the FPGA assumes, usually 0x0).
  • Ensure M[2:0]/VS[2:0] correct for your chosen Flash command and bus width.
  • Make sure Flash tPU is fast enough, or gate INIT_B/PROG_B.

Top comments (0)