- fpga_target gains a prog method (proxy_spi/svf/none), set in the registry or inferred when omitted (proxy_bitstream -> proxy_spi; Microsemi/Lattice -> svf); shown by fpga_info/fpga_list and exposed via fpga_prog_method_name() for the future program dispatch - generalise RTCK as a neutral JTAG_RTCK, mirrored to PROBE_FTDI_JTAG_ENABLE_RTCK at open (FTDI-only) - reset abstraction deferred (no clean neutral form yet); the program dispatch command itself lands with the SVF player Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
79 lines
3.1 KiB
C
79 lines
3.1 KiB
C
#ifndef _FPGA_H
|
|
#define _FPGA_H
|
|
|
|
/*
|
|
* Per-target FPGA descriptor and registry.
|
|
*
|
|
* Holds the facts that cannot be derived from the BSDL alone:
|
|
* - IDCODE pattern to match on the chain
|
|
* - private IR opcodes (USER1, CFG_IN, JPROGRAM, …) needed for
|
|
* configuration and for the BSCAN proxy bridge (Phase 2.5)
|
|
* - path to the BSCAN proxy bitstream
|
|
* - per-target caveats (known hardware gotchas)
|
|
*
|
|
* The registry is loaded at runtime from a YAML file (no longer a
|
|
* compile-time array). Adding an FPGA = one entry in the YAML +
|
|
* its .bsd in bsdl_files/ + (optionally) its proxy .bit in
|
|
* bscan_proxies/. See fpga_registry.yaml for the format.
|
|
*/
|
|
|
|
#include "jtag_core/jtag_core.h"
|
|
|
|
typedef enum {
|
|
FPGA_FAMILY_UNKNOWN = 0,
|
|
FPGA_FAMILY_XILINX_7,
|
|
FPGA_FAMILY_XILINX_US,
|
|
FPGA_FAMILY_XILINX_USP,
|
|
FPGA_FAMILY_MICROSEMI_IGLOO2,
|
|
FPGA_FAMILY_MICROSEMI_SMARTFUSION2,
|
|
FPGA_FAMILY_LATTICE_MACHXO2,
|
|
FPGA_FAMILY_LATTICE_MACHXO3,
|
|
} fpga_family;
|
|
|
|
/* Programming method — which backend drives this part. */
|
|
typedef enum {
|
|
FPGA_PROG_NONE = 0, /* no known method */
|
|
FPGA_PROG_PROXY_SPI, /* Xilinx external SPI flash via the BSCAN proxy */
|
|
FPGA_PROG_SVF, /* play a vendor-exported SVF (Lattice/Microsemi/…) */
|
|
} fpga_prog_method;
|
|
|
|
/* Caveat flags: known hardware gotchas for a part. */
|
|
#define FPGA_CAVEAT_CCLK_VIA_STARTUP (1u << 0) /* CCLK not directly drivable in EXTEST */
|
|
|
|
typedef struct {
|
|
const char *name; /* human-readable part name */
|
|
unsigned long idcode; /* IDCODE pattern */
|
|
unsigned long idcode_mask; /* bits to ignore (typically 0x0FFFFFFF for Xilinx — version masked) */
|
|
fpga_family family;
|
|
const char *bsdl_filename; /* basename within bsdl_files/ */
|
|
int ir_length; /* IR width in bits */
|
|
|
|
/* Private IR opcodes (0 = N/A for this family).
|
|
* For Xilinx, these are read from the BSDL INSTRUCTION_OPCODE block. */
|
|
unsigned int ir_cfg_in;
|
|
unsigned int ir_user1;
|
|
unsigned int ir_jprogram;
|
|
unsigned int ir_jstart;
|
|
unsigned int ir_jshutdown;
|
|
unsigned int ir_isc_disable;
|
|
|
|
const char *proxy_bitstream; /* path under bscan_proxies/, NULL if not yet available */
|
|
unsigned int caveats; /* FPGA_CAVEAT_* flags */
|
|
int max_tck_khz; /* max safe JTAG TCK for this part/board, 0 = unspecified */
|
|
fpga_prog_method prog; /* programming backend; inferred when omitted */
|
|
} fpga_target;
|
|
|
|
/* Registry access. The YAML file is loaded lazily on first call to any
|
|
* of these, and cached for the process lifetime. */
|
|
int fpga_get_target_count(void);
|
|
const fpga_target * fpga_get_target_by_index(int index);
|
|
const fpga_target * fpga_lookup_by_idcode(unsigned long idcode);
|
|
const char * fpga_family_name(fpga_family f);
|
|
const char * fpga_prog_method_name(fpga_prog_method m);
|
|
|
|
/* Path the registry was loaded from, or NULL if nothing loaded
|
|
* (file missing / parse error). For diagnostics. */
|
|
const char * fpga_registry_source(void);
|
|
|
|
#endif
|