phase 2: add fpga/ module — per-target descriptor & registry
modules/fpga/ holds an fpga_target struct (IDCODE/mask, family, IR length and private opcodes, proxy bitstream path, quirks) and a compile-time registry. Initial entry: Xilinx Kintex UltraScale+ XCKU15P, populated from bsdl_files/xcku15p_ffve1517.bsd (IDCODE 0x04A56093, IR 6, USER1=0x02, CFG_IN=0x05, JPROGRAM=0x0B, JSTART=0x0C, JSHUTDOWN=0x0D, ISC_DISABLE=0x16, quirk CCLK_VIA_STARTUP). Two new script commands: - fpga_list: enumerate the registry - fpga_info: match each device on the JTAG chain against the registry and surface known quirks Adding another FPGA = one entry in fpga_registry[] + its .bsd in bsdl_files/. Proxy .bit will be wired in phase 2.5 (bscan_spi/). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
|
||||
#include "bsdl_parser/bsdl_loader.h"
|
||||
#include "os_interface/os_interface.h"
|
||||
#include "fpga/fpga.h"
|
||||
|
||||
#include "env.h"
|
||||
|
||||
@@ -2723,6 +2724,75 @@ static int cmd_get_pins_list(script_ctx *ctx, char *line)
|
||||
return JTAG_CORE_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
const char *cmd_fpga_list_help[] = {
|
||||
"",
|
||||
"Lists the FPGA targets known to this build (registry in modules/fpga/).",
|
||||
""};
|
||||
static int cmd_fpga_list(script_ctx *ctx, char *line)
|
||||
{
|
||||
int i, n;
|
||||
const fpga_target *t;
|
||||
|
||||
(void)line;
|
||||
|
||||
n = fpga_get_target_count();
|
||||
ctx->script_printf(ctx, MSG_INFO_0, "%d FPGA target(s) registered:\n", n);
|
||||
for (i = 0; i < n; i++) {
|
||||
t = fpga_get_target_by_index(i);
|
||||
ctx->script_printf(ctx, MSG_NONE,
|
||||
" [%d] IDCODE %.8lX/%.8lX %s (%s)\n",
|
||||
i, t->idcode, t->idcode_mask,
|
||||
t->name, fpga_family_name(t->family));
|
||||
ctx->script_printf(ctx, MSG_NONE,
|
||||
" bsdl=%s ir=%d proxy=%s quirks=0x%x\n",
|
||||
t->bsdl_filename, t->ir_length,
|
||||
t->proxy_bitstream ? t->proxy_bitstream : "(none yet)",
|
||||
t->quirks);
|
||||
}
|
||||
return JTAG_CORE_NO_ERROR;
|
||||
}
|
||||
|
||||
const char *cmd_fpga_info_help[] = {
|
||||
"",
|
||||
"Reports, for each device on the JTAG chain, whether its IDCODE",
|
||||
"matches a known FPGA target. Requires jtag_init_scan or jtag_autoinit first.",
|
||||
""};
|
||||
static int cmd_fpga_info(script_ctx *ctx, char *line)
|
||||
{
|
||||
jtag_core *jc;
|
||||
int i, n;
|
||||
unsigned long idcode;
|
||||
const fpga_target *t;
|
||||
|
||||
(void)line;
|
||||
jc = (jtag_core *)ctx->app_ctx;
|
||||
|
||||
n = jtagcore_get_number_of_devices(jc);
|
||||
if (n <= 0) {
|
||||
ctx->script_printf(ctx, MSG_WARNING, "No device on the chain. Run jtag_autoinit first.\n");
|
||||
return JTAG_CORE_NOT_FOUND;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
idcode = jtagcore_get_dev_id(jc, i);
|
||||
t = fpga_lookup_by_idcode(idcode);
|
||||
if (t) {
|
||||
ctx->script_printf(ctx, MSG_INFO_0,
|
||||
"Device %d IDCODE 0x%.8lX -> %s [%s]\n",
|
||||
i, idcode, t->name, fpga_family_name(t->family));
|
||||
if (t->quirks & FPGA_QUIRK_CCLK_VIA_STARTUP) {
|
||||
ctx->script_printf(ctx, MSG_NONE,
|
||||
" quirk: CCLK routed via STARTUP primitive (not drivable in EXTEST)\n");
|
||||
}
|
||||
} else {
|
||||
ctx->script_printf(ctx, MSG_INFO_0,
|
||||
"Device %d IDCODE 0x%.8lX -> not in registry\n",
|
||||
i, idcode);
|
||||
}
|
||||
}
|
||||
return JTAG_CORE_NO_ERROR;
|
||||
}
|
||||
|
||||
cmd_list script_commands_list[] =
|
||||
{
|
||||
{"print", cmd_print, cmd_print_help},
|
||||
@@ -2765,6 +2835,8 @@ cmd_list script_commands_list[] =
|
||||
{"jtag_set_spi_miso_pin", cmd_set_spi_miso_pin, cmd_set_spi_miso_pin_help},
|
||||
{"jtag_set_spi_clk_pin", cmd_set_spi_clk_pin, cmd_set_spi_clk_pin_help},
|
||||
{"jtag_spi_rd_wr", cmd_spi_rd_wr, cmd_spi_rd_wr_help},
|
||||
{"fpga_list", cmd_fpga_list, cmd_fpga_list_help},
|
||||
{"fpga_info", cmd_fpga_info, cmd_fpga_info_help},
|
||||
{0, 0}};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user