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:
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.On POR / configuration restart:
- PROG_B is (or goes) Low → FPGA clears its configuration memory.
- DONE and INIT_B are driven Low.
- 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:
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).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.
- 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:
- 8-bit READ command (0x03 or 0x0B).
- 24-bit start address, usually 0x000000.
- Required dummy bytes if using fast-read.
- The Flash responds on MISO → DIN/D_IN pin, streaming the bitstream bits.
The FPGA keeps clocking CCLK and shifting in data until it has received the entire bitstream (recognized by header + sync word + length and CRC).
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)->
- 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:
- 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.
- 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.
- 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)