sync: WIN-BOWEI 2026-08-10 fpga_flash 增 Zynq BOOT.bin/QSPI 脚本,rtl-ip-replace 与 sim-rtl-flow 更新

- fpga_flash: 新增 build_zynq_boot.py / program_zynq_qspi.py(bootgen + program_flash,
  含备份、SHA-256/容量/marker 守卫);vivado_env.py 增 resolve_sdk_dir(SDK_ROOT/SDK_PATH);
  SKILL.md 补 Zynq 烧写流程,示例去掉写死的 D:\Xilinx\SDK\2018.1,改由 skills_env.md 解析。
- rtl-ip-replace: gen_ip.tcl / namespace_ip.py 更新。
- sim-rtl-flow: SKILL.md 与 run_sim_rtl_flow.py 更新。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
bowei
2026-08-19 12:50:44 +08:00
co-authored by Claude Opus 5
parent 7a11bac29d
commit e07cfaa6d1
8 changed files with 712 additions and 31 deletions
+37 -1
View File
@@ -119,6 +119,10 @@ def _bootstrap(project: Path):
SubagentResult,
)
from sim_rtl_flow.graph import WorkflowContext, build_workflow # noqa: E402
from sim_rtl_flow.history import ( # noqa: E402
discover_history_doc,
history_dir_for,
)
from sim_rtl_flow.review import ReviewDecision, ScriptedReviewGate # noqa: E402
return {
@@ -128,6 +132,8 @@ def _bootstrap(project: Path):
"ReviewDecision": ReviewDecision,
"WorkflowContext": WorkflowContext,
"build_workflow": build_workflow,
"discover_history_doc": discover_history_doc,
"history_dir_for": history_dir_for,
}
@@ -395,7 +401,20 @@ def _print_final(state: Any, replayed: list[str]) -> None:
review = state.get(key)
if review:
mark = "批准" if review.get("approved") else "驳回"
if (review.get("metadata") or {}).get("skipped_by_history"):
mark = "按历史设计说明文件跳过"
print(f"{label} : {mark} {review.get('notes', '')}".rstrip())
plan = state.get("history_plan") or {}
print(f"历史文件 · 参考 : {plan.get('history_path') or '(none)'}")
if plan.get("history_path"):
print(
"历史文件 · 沿用 : "
f"重做定点化={plan.get('redo_fixed_point')} "
f"重做功能划分={plan.get('redo_partition')} "
f"沿用子模块={plan.get('reuse_modules')}"
)
written = state.get("history_doc_written")
print(f"历史文件 · 本次 : {written or '(未生成!下次运行将失去跳步依据)'}")
print(f"modules : {state.get('rtl_modules')}")
for item in state.get("module_results", []):
print(
@@ -452,7 +471,20 @@ def _invoke(run: RunDir, api: dict[str, Any], args) -> int:
def cmd_start(args, api) -> int:
payload = json.loads(Path(args.input).read_text(encoding="utf-8"))
payload.pop("outcomes", None)
run = RunDir(_resolve_work_dir(args, payload), args.thread_id)
payload.pop("reviews", None)
work_dir = _resolve_work_dir(args, payload)
# 把"参考哪一份历史设计说明文件"冻结进 input.json:本次运行结束时会写出一份
# 新的 sim-rtl-flow-<date>.md,若每次 resume 都重新扫描目录,replay 就会在
# 半路换掉参考文件,走出一条与已记录 ledger 不同的路。
if "history_path" not in payload:
history_dir = api["history_dir_for"](
payload.get("history_dir"), payload.get("requirements_path", "")
)
payload["history_dir"] = history_dir
payload["history_path"] = api["discover_history_doc"](
str(work_dir), history_dir
)
run = RunDir(work_dir, args.thread_id)
run.set_input(payload)
if not args.keep_ledger:
run.set_ledger({})
@@ -460,6 +492,10 @@ def cmd_start(args, api) -> int:
print(f"work dir : {run.work_dir}")
print(f"run dir : {run.path}")
print(f"thread : {run.thread_id}")
print(
"history : "
+ (payload.get("history_path") or "(none — 首次设计,全部步骤实打实执行)")
)
print("input : " + json.dumps(payload, ensure_ascii=False))
return _invoke(run, api, args)