同步了 fpga_flash, vivado-prj-create 两个skill
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Steps 4+5: Connect hardware target, configure cfgmem device, and program Flash.
|
||||
|
||||
Calls Vivado with step4_5_program.tcl (located in the same scripts/ directory)
|
||||
via -tclargs so no temporary script files are created.
|
||||
|
||||
Usage:
|
||||
python program_flash.py \
|
||||
--vivado-dir "D:/Xilinx/Vivado/2018.1" \
|
||||
--flash-part "w25q128bv-spi-x1_x2_x4" \
|
||||
--bit-file "E:/project/impl_1/RU_golden_top.bit" \
|
||||
--mcs-file "E:/project/impl_1/RU_golden_smod.mcs" \
|
||||
[--ltx-file "E:/project/impl_1/RU_golden_top.ltx"]
|
||||
|
||||
If the design has no ILA (no .ltx file), omit --ltx-file or pass an
|
||||
empty string; the TCL template will skip the PROBES.FILE settings.
|
||||
|
||||
Supported flash parts:
|
||||
Micron : mt25ql128-spi-x1_x2_x4
|
||||
Winbond : w25q128bv-spi-x1_x2_x4
|
||||
|
||||
Exit codes:
|
||||
0 = success ("End of startup status: HIGH" in output)
|
||||
1 = failure
|
||||
"""
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def norm(path: str) -> str:
|
||||
"""Normalize path to forward slashes (Vivado on Windows accepts both)."""
|
||||
return path.replace("\\", "/")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Program FPGA SPI Flash via Vivado Hardware Manager"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--vivado-dir",
|
||||
required=True,
|
||||
help="Vivado install root, e.g. D:/Xilinx/Vivado/2018.1",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--flash-part",
|
||||
required=True,
|
||||
help="Vivado Flash part name, e.g. w25q128bv-spi-x1_x2_x4",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--bit-file",
|
||||
required=True,
|
||||
help="Full path to the .bit file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--mcs-file",
|
||||
required=True,
|
||||
help="Full path to the .mcs file (from Step 3)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--ltx-file",
|
||||
default="",
|
||||
help="Full path to the .ltx probes file (optional; omit if no ILA)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
vivado_dir = norm(args.vivado_dir)
|
||||
bit_file = norm(args.bit_file)
|
||||
mcs_file = norm(args.mcs_file)
|
||||
ltx_file = norm(args.ltx_file) if args.ltx_file else ""
|
||||
|
||||
# Locate the TCL template alongside this script
|
||||
scripts_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
tcl_template = os.path.join(scripts_dir, "step4_5_program.tcl").replace("\\", "/")
|
||||
|
||||
# Validate inputs
|
||||
vivado_exe = os.path.join(vivado_dir, "bin", "vivado.bat")
|
||||
if not os.path.isfile(vivado_exe):
|
||||
print(f"ERROR: Vivado not found: {vivado_exe}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
for label, path in [("bit", bit_file), ("mcs", mcs_file)]:
|
||||
if not os.path.isfile(path):
|
||||
print(f"ERROR: .{label} file not found: {path}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if ltx_file and not os.path.isfile(ltx_file):
|
||||
print(f"ERROR: .ltx file not found: {ltx_file}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if not os.path.isfile(tcl_template):
|
||||
print(f"ERROR: TCL template not found: {tcl_template}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
cmd = [
|
||||
vivado_exe,
|
||||
"-mode", "batch",
|
||||
"-source", tcl_template,
|
||||
"-tclargs", args.flash_part, bit_file, mcs_file, ltx_file,
|
||||
]
|
||||
print(f"[program_flash] Vivado : {vivado_exe}")
|
||||
print(f"[program_flash] Flash part: {args.flash_part}")
|
||||
print(f"[program_flash] bit : {bit_file}")
|
||||
print(f"[program_flash] mcs : {mcs_file}")
|
||||
if ltx_file:
|
||||
print(f"[program_flash] ltx : {ltx_file}")
|
||||
else:
|
||||
print(f"[program_flash] ltx : (none - no ILA)")
|
||||
print()
|
||||
|
||||
result = subprocess.run(cmd)
|
||||
sys.exit(result.returncode)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user