commit 1b1a68ae28ca2da93c81cbabfead67136a6c55a4 Author: Administrator Date: Mon Sep 14 20:18:41 2026 +0800 Initial gwin-skill: Gowin ACG525 full toolchain skill for agents. Co-authored-by: Cursor diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ad2fda7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +impl/ +*.fs +*.bin +*.binx +*.db +*.pr +*.p +*.log +.DS_Store +Thumbs.db diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..4681065 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,79 @@ +# AGENTS.md — 让其他 Agent 学会用 gwin-skill + +本文给 **Cursor Agent / 子 Agent / 自动化脚本作者**。人类请看 `README.md`。 + +## 1. 何时加载本 skill + +满足任一条件即应 **Read `SKILL.md` 全文** 再动手: + +- 用户提到:高云、Gowin、GW5A、ACG525、FPGA 综合、下载、烧录、`.gprj`、`gw_sh`、Programmer +- 用户要求改 `proj*` 下 Verilog / `.cst` 并上板 +- 用户要求 TFT / LCD / RGB 刷屏、彩条、显示驱动 +- 父 Agent 把任务描述为 “按 gwin-skill 执行” + +不要用通用 FPGA 经验硬套 Xilinx/Intel 命令。 + +## 2. 最小阅读集 + +| 任务 | 必读 | +|------|------| +| 任意高云任务 | `SKILL.md` | +| 新建/改 RTL 或约束 | + `design-spec.md` | +| 动到 LCD/按键/LED/时钟脚 | + `reference-pins.md` | +| 复现刷屏类 demo | + `examples.md` | +| 写脚本/子 Agent 提示词 | + 本文 | + +## 3. 标准动作序列(不可跳步) + +1. **定位**:确认 `tool-chain/Gowin/...` 与目标工程目录存在 +2. **设计**:按 `design-spec.md` 改 `src/*.v`、`.cst`、`.sdc`、`.gprj` +3. **构建**:`scripts/build.ps1` 或 `type build.tcl | gw_sh.exe` +4. **检查**:`impl/pnr/*.fs` 存在;日志无 ERROR +5. **下载**:板子供电 → `scripts/download.ps1` 或 `programmer_cli -r 2` +6. **汇报**:比特流路径、操作码(SRAM/Flash)、用户应看到的现象 + +失败则停在当前步,贴关键日志行,禁止假装成功。 + +## 4. 子 Agent 提示词模板 + +把下面块交给子 Agent(替换路径与目标): + +```text +你正在操作高云 ACG525 (GW5A-LV25UG324C2/I1)。 +必须先阅读并遵守: + /SKILL.md + /design-spec.md + /reference-pins.md(若涉及 IO) + +工作区:C:\Users\Administrator\Documents\fpga +工具链:tool-chain\Gowin\Gowin_V1.9.11.03_Education_x64 +目标工程: +任务:<一句任务> + +硬性约束: +- 只用 gw_sh pipe / gwin-skill/scripts,不要开 GUI 干等 +- build.tcl 无 UTF-8 BOM +- 下载前确认板子供电;programmer_cli -d GW5A-25A +- 引脚以 reference-pins.md 为准,禁止臆造 IO_LOC +完成后报告:构建结果、.fs 路径、下载结果、预期现象。 +``` + +## 5. 禁止教给 Agent 的错误做法 + +- `gw_sh.exe` 无输入长时间挂起 +- `set_option -verilog_std vlg2001` +- 只插下载线不供电就 `programmer_cli` +- 把 DK_START 官方板引脚当成 ACG525 +- 把 2×18 TFT 当成 RGB888 全接满 + +## 6. 成功判据 + +- `programmer_cli --scan` 见 GW5A +- 下载 `Finished` +- 用户可观察的外部现象与设计一致(LED / 彩条方向 / 按键切色等) + +## 7. 版本与扩展 + +- Skill 名:`gwin-skill`(仓库名同) +- 新外设:只追加 `reference-pins.md` 表格 + `examples.md` 一节 +- 新器件:新建 `reference-.md`,并在 `SKILL.md` 环境表增加一行 diff --git a/README.md b/README.md new file mode 100644 index 0000000..75be87a --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# gwin-skill + +高云(Gowin)ACG525 / GW5A-25A 开发板 **全流程工具链 Skill 仓库**:设计规范、工程组织、CLI 综合、下载,以及如何让 Cursor Agent 按同一套流程操作。 + +## 谁该用 + +| 角色 | 入口 | +|------|------| +| 人类开发者 | 本文 + `scripts/` | +| Cursor Agent | **先读 [`SKILL.md`](SKILL.md)** | +| 其他 Agent / 自动化 | [`AGENTS.md`](AGENTS.md) | + +## 仓库结构 + +``` +gwin-skill/ +├── SKILL.md # Agent 主指令(必读) +├── AGENTS.md # 多 Agent 协作约定 +├── README.md # 本文件 +├── design-spec.md # 设计规范 +├── reference-pins.md # ACG525 / TFT 引脚 +├── examples.md # TFT 刷屏端到端示例 +├── scripts/ # 可执行脚本 +│ ├── build.ps1 +│ ├── build_and_download.ps1 +│ ├── download.ps1 +│ └── new_project.ps1 +└── templates/ # 空工程模板 + ├── template.gprj + ├── build.tcl + └── src/ + ├── top.v + ├── top.cst + └── top.sdc +``` + +## 本机前置 + +1. 工作区示例:`Documents/fpga/` +2. 工具链:`tool-chain/Gowin/Gowin_V1.9.11.03_Education_x64/`(Education 即可) +3. 开发板 ACG525 已供电(DC 或 Type-C + 电源开关),下载线已连接 +4. 可选:将本仓库安装到个人 skills: + +```powershell +# junction / 复制均可 +cmd /c mklink /J "%USERPROFILE%\.cursor\skills\gwin-skill" "C:\Users\Administrator\Documents\fpga\gwin-skill" +``` + +## 30 秒上手 + +```powershell +cd C:\Users\Administrator\Documents\fpga\gwin-skill +.\scripts\new_project.ps1 -Name blink -TargetDir ..\proj_blink +.\scripts\build_and_download.ps1 -ProjectDir ..\proj_blink +``` + +已有工程(如 `proj1`): + +```powershell +.\scripts\build_and_download.ps1 -ProjectDir ..\proj1 +``` + +## 文档索引 + +- [SKILL.md](SKILL.md) — Agent 执行手册 +- [design-spec.md](design-spec.md) — RTL / 约束 / 命名规范 +- [reference-pins.md](reference-pins.md) — 时钟、按键、LED、LCD RGB565 +- [examples.md](examples.md) — 800×480 TFT 刷屏复盘 +- [AGENTS.md](AGENTS.md) — 如何让其他 agent 学会用 + +## 许可 + +随本地教学工程使用;高云 IDE / 器件相关商标归原厂所有。 diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..33a2a5f --- /dev/null +++ b/SKILL.md @@ -0,0 +1,141 @@ +--- +name: gwin-skill +description: >- + Gowin (高云) ACG525 / GW5A-25A FPGA full toolchain: project layout, Verilog/CST/SDC + design rules, gw_sh build, programmer_cli download, TFT RGB pin map. Use when the + user mentions 高云, Gowin, GW5A, ACG525, .gprj, gw_sh, Programmer, TFT/LCD 刷屏, + FPGA 综合下载, or asks an agent to build/flash Gowin board projects. +--- + +# Gwin Skill — 高云 FPGA 全流程 + +**立即阅读本文件后按流程执行。** 细节按需打开同目录参考文档,不要凭记忆猜引脚或命令。 + +## Agent 必做清单 + +``` +- [ ] 确认工作区含 tool-chain/Gowin 与目标工程(如 proj1) +- [ ] 按 design-spec.md 组织/修改 RTL + .cst + .sdc + .gprj +- [ ] 用 scripts 或 pipe 方式跑 gw_sh(禁止 BOM、禁止交互挂起) +- [ ] 确认 impl/pnr/.fs 已生成 +- [ ] 板子供电 + Type-C/下载线;programmer_cli SRAM 下载 +- [ ] 向用户报告比特流路径与验证方式 +``` + +## 环境路径(本机约定) + +相对工作区根 `fpga/`(可按实际调整,改前先 `Test-Path`): + +| 用途 | 路径 | +|------|------| +| IDE / `gw_sh.exe` | `tool-chain/Gowin/Gowin_V1.9.11.03_Education_x64/IDE/bin` | +| Programmer | `tool-chain/Gowin/Gowin_V1.9.11.03_Education_x64/Programmer/bin` | +| ModelSim | `tool-chain/modelSim` | +| 板卡引脚表 | `tool-chain/fpga/ACG525_EDA开发板引脚信息表.xlsx` | +| 例程 | `tool-chain/fpga/gaoyun_fpga/` | + +**器件(ACG525):** + +- Series: `GW5A` / Package: `UBGA324` / Device: `GW5A-25` / Speed: `C2/I1` / Version: **A** +- Part: `GW5A-LV25UG324C2/I1` +- `.gprj` Device 节点示例:`name="GW5A-25A" pn="GW5A-LV25UG324C2/I1"` + +## 工程怎么组织 + +``` +/ +├── .gprj # 工程清单(必须) +├── build.tcl # CLI 构建(UTF-8 无 BOM) +├── build_and_download.bat +└── src/ + ├── .v # 顶层 + ├── *.v # 子模块 + ├── .cst # 管脚约束 + └── .sdc # 时钟约束(建议) +``` + +产物(勿手改):`impl/gwsynthesis/`、`impl/pnr/.fs` + +新建工程:复制 [templates/](templates/) 或运行 `scripts/new_project.ps1`。 +规范细节 → [design-spec.md](design-spec.md) +引脚与 TFT → [reference-pins.md](reference-pins.md) + +## 怎么编译 + +**唯一推荐方式(Windows):** 在工程目录把 `build.tcl` **pipe** 给 `gw_sh`(避免 CLI 挂起、避免 UTF-8 BOM)。 + +```powershell +$gowin = "C:\Users\Administrator\Documents\fpga\tool-chain\Gowin\Gowin_V1.9.11.03_Education_x64" +$env:PATH = "$gowin\IDE\bin;$gowin\Programmer\bin;" + $env:PATH +Set-Location +cmd /c "type build.tcl | gw_sh.exe" +``` + +或直接:`scripts/build.ps1 -ProjectDir ` + +`build.tcl` 最小模板: + +```tcl +open_project .gprj +set_option -output_base_name +set_option -synthesis_tool gowinsynthesis +set_option -top_module +set_option -use_sspi_as_gpio 1 +set_option -use_mspi_as_gpio 1 +set_option -use_ready_as_gpio 1 +set_option -use_done_as_gpio 1 +set_option -use_cpu_as_gpio 1 +run all +exit +``` + +成功标志:日志出现 `Bitstream generation completed`,且存在 `impl/pnr/.fs`。 + +### 禁止事项 + +- 不要直接交互运行 `gw_sh.exe` 后空等(易挂起) +- 不要写 `set_option -verilog_std vlg2001`(非法;用 `v2001` 或省略) +- 不要用带 BOM 的 PowerShell here-string 写 tcl 再 pipe(`open_project` 会变非法命令) +- 下载器不能给板子供电:必须 DC 或 Type-C 供电并拨电源开关 + +## 怎么下载 + +```powershell +programmer_cli.exe -d GW5A-25A --fsFile "\impl\pnr\.fs" -r 2 +``` + +| `-r` | 含义 | +|------|------| +| 2 | SRAM Program(掉电丢失,调试用) | +| 4 | SRAM Program and Verify | +| 5/6 | embFlash 擦写(固化) | + +先扫线:`programmer_cli.exe --scan` +应看到 `Gowin USB Cable` 与 `GW5A-25A`。 + +一键:`scripts/build_and_download.ps1 -ProjectDir ` + +## 设计规范(摘要) + +1. 顶层端口名与 `.cst` 中 `IO_LOC "name"` **完全一致** +2. 时钟默认 `clk` @ **T9** 50 MHz;复位 `rst_n` @ **H5**(KEY5,低有效) +3. IO 标准默认 `LVCMOS33`,`BANK_VCCIO=3.3` +4. 输入按键加 `PULL_MODE=UP`;LCD 数据/时钟 `DRIVE=8` +5. TFT 2×18 口用 **RGB565**:`R[7:3]/G[7:2]/B[7:3]`(见 reference-pins.md) +6. Verilog-2001;同步复位风格与现有例程一致(`posedge clk or negedge rst_n`) +7. 像素时钟:无 PLL 时可用 50 MHz 二分频 ≈25 MHz(800×480 约 45 Hz,可接受) + +完整规范 → [design-spec.md](design-spec.md) + +## 教其他 Agent 怎么用 + +1. **发现本 skill**:路径 `~/.cursor/skills/gwin-skill/SKILL.md` 或仓库根 `gwin-skill/SKILL.md` +2. **触发词**:高云 / Gowin / GW5A / ACG525 / 综合下载 / TFT 刷屏 / `.gprj` +3. **强制步骤**:先读本 `SKILL.md` → 改代码前读 `design-spec.md` → 碰 LCD/按键前读 `reference-pins.md` +4. **执行**:只用 `scripts/*.ps1` 或文档中的 `type build.tcl | gw_sh.exe`;下载用 `programmer_cli` +5. **验证**:`--scan` 有设备;下载 Finished;用户确认现象(LED/彩条等) +6. **扩展新板卡**:在 `reference-pins.md` 增表,勿改命令骨架 + +人类说明 → [README.md](README.md) +Agent 协作约定 → [AGENTS.md](AGENTS.md) +端到端例子 → [examples.md](examples.md) diff --git a/design-spec.md b/design-spec.md new file mode 100644 index 0000000..1c98475 --- /dev/null +++ b/design-spec.md @@ -0,0 +1,109 @@ +# 设计规范 — ACG525 / GW5A-25A + +## 1. 工程与命名 + +| 项 | 规范 | +|----|------| +| 工程目录 | 短名小写/数字:`proj1`、`tft_bar` | +| 顶层模块 | 与主文件名一致:`tft_top.v` → `module tft_top` | +| 约束 | `.cst`、`.sdc` | +| 工程文件 | `.gprj`,Device 固定见下 | +| 输出名 | `set_option -output_base_name` 与目录名一致 | + +`.gprj` 器件行: + +```xml +gw5a25a-008 +``` + +`FileList` 中每个源文件一行,`enable="1"`;类型:`file.verilog` / `file.cst` / `file.sdc`。 + +## 2. RTL 风格 + +- 语言:Verilog-2001(`v2001`);勿写非法 `vlg2001` +- 时钟异步复位(与板载例程一致): + +```verilog +always @(posedge clk or negedge rst_n) begin + if (!rst_n) ... + else ... +end +``` + +- 上电:可用计数器做 POR,再与按键复位相与 +- 禁止在顶层留未约束的输出端口 +- 位宽:常量用足够宽的 localparam,避免截断 WARN +- TFT 像素数据与 DE 对齐:常用 `data_req` 提前一拍取色,再在 DE 有效期输出 + +## 3. 约束 (.cst) + +```text +IO_LOC "port_name" PIN; +IO_PORT "port_name" IO_TYPE=LVCMOS33 PULL_MODE=... DRIVE=... BANK_VCCIO=3.3; +``` + +- `port_name` 与 HDL 端口 **逐字相同**(含 `bus[0]` 写法) +- 默认 `IO_TYPE=LVCMOS33`,`BANK_VCCIO=3.3` +- 按键/复位输入:`PULL_MODE=UP` +- 时钟输入:`PULL_MODE=NONE` +- LCD 高速脚:`DRIVE=8` +- 总线按位分别写 `IO_LOC`(高云 CST 常规写法) + +## 4. 时序 (.sdc) + +最少: + +```tcl +create_clock -name clk -period 20.000 -waveform {0.000 10.000} [get_ports {clk}] +``` + +(50 MHz → period 20 ns) + +分频时钟若时报 `TA1132`,可补 `create_generated_clock`,或接受警告(低频刷屏通常可过)。 + +## 5. GPIO 复用选项 + +教育板调试常用(`build.tcl`): + +```tcl +set_option -use_sspi_as_gpio 1 +set_option -use_mspi_as_gpio 1 +set_option -use_ready_as_gpio 1 +set_option -use_done_as_gpio 1 +set_option -use_cpu_as_gpio 1 +``` + +保留 JTAG 下载:不要把 `use_jtag_as_gpio` 设为 1。 + +## 6. TFT 800×480 时序(TFT_V3.0) + +| 参数 | 值 | +|------|-----| +| H_TOTAL | 1056 | +| H_SYNC | 128 | +| H_BACK | 88 | +| H_DISP | 800 | +| H_FRONT | 40 | +| V_TOTAL | 525 | +| V_SYNC | 2 | +| V_BACK | 33 | +| V_DISP | 480 | +| V_FRONT | 10 | + +- HS/VS:同步区为低(与 VGA 类似) +- DE:有效显示区为高 +- 颜色:2×18 排针 **RGB565**;`lcd_bl=1` 开背光;`lcd_reset` 常置 1 + +理想像素时钟约 33 MHz;无 PLL 时 25 MHz(50/2)可先点亮。 + +## 7. 仿真(可选) + +- ModelSim:`tool-chain/modelSim` +- testbench 命名:`_tb.v`;**不要**把 tb 设为综合 top +- `.gprj` 中可保留 tb,综合前确认 `set_option -top_module` 为可综合顶层 + +## 8. 目录卫生 + +- 不提交密钥;`impl/` 可本地保留,团队仓库可 gitignore +- 脚本与 `build.tcl` 使用 **UTF-8 无 BOM** +- 注释可用中文;tcl/命令行参数保持 ASCII diff --git a/examples.md b/examples.md new file mode 100644 index 0000000..a15c3e3 --- /dev/null +++ b/examples.md @@ -0,0 +1,55 @@ +# 示例:proj1 TFT 800×480 刷屏 + +## 目标 + +ACG525 + 芯路恒 TFT_V3.0(2×18)显示彩条;按键切红/绿/蓝满屏。 + +## 工程文件 + +工作区:`fpga/proj1/` + +| 文件 | 作用 | +|------|------| +| `src/tft_top.v` | 顶层:分频、复位、模式、LED | +| `src/lcd_driver.v` | 1056×525 时序 | +| `src/lcd_display.v` | 彩条/纯色 | +| `src/tft_top.cst` | LCD/KEY/LED 约束 | +| `src/tft_top.sdc` | 50 MHz | +| `build.tcl` | `run all` | +| `impl/pnr/proj1.fs` | 比特流 | + +## 构建与下载 + +```powershell +cd C:\Users\Administrator\Documents\fpga\gwin-skill +.\scripts\build_and_download.ps1 -ProjectDir ..\proj1 +``` + +等价: + +```powershell +$gowin = "C:\Users\Administrator\Documents\fpga\tool-chain\Gowin\Gowin_V1.9.11.03_Education_x64" +$env:PATH = "$gowin\IDE\bin;$gowin\Programmer\bin;" + $env:PATH +cd C:\Users\Administrator\Documents\fpga\proj1 +cmd /c "type build.tcl | gw_sh.exe" +programmer_cli.exe -d GW5A-25A --fsFile "$PWD\impl\pnr\proj1.fs" -r 2 +``` + +## 预期现象 + +- 上电/下载后背光亮,出现彩条 +- KEY0/1/2:红/绿/蓝满屏 +- KEY5:复位 +- LED 有心跳与模式指示 + +## 彩条方向说明 + +- 逻辑 `lcd_x` 递增对应扫描行方向;若屏上表现为「上下变色」,可用 `lcd_y` 分区做「左右竖条」,以目视为准微调 `lcd_display.v` +- 2×18 仅 RGB565,不要接不存在的 R[2:0] 等低位脚 + +## Agent 复盘要点 + +1. 引脚来自 xlsx,不是官方 DK_START 手册 +2. `gw_sh` 必须 pipe + 无 BOM +3. 下载成功日志含 `Finished` 与 Status Code +4. 供电与下载线分离要求见 SKILL.md diff --git a/reference-pins.md b/reference-pins.md new file mode 100644 index 0000000..65f102e --- /dev/null +++ b/reference-pins.md @@ -0,0 +1,98 @@ +# ACG525 引脚参考 + +来源:`tool-chain/fpga/ACG525_EDA开发板引脚信息表.xlsx`。 +器件:`GW5A-LV25UG324C2/I1`。电平默认 3.3 V LVCMOS。 + +## 系统 + +| 信号 | FPGA 管脚 | 说明 | +|------|-----------|------| +| CLK | T9 | 50 MHz 系统时钟 | +| key5 / rst_n | H5 | 独立按键,建议作复位,低有效 | + +## 独立按键 + +| 信号 | 管脚 | +|------|------| +| key0 | D1 | +| key1 | F2 | +| key2 | F1 | +| key3 | H2 | +| key4 | H1 | +| key5 | H5 | + +## LED(部分) + +| 信号 | 管脚 | +|------|------| +| LED0 | C1 | +| LED1 | D3 | +| LED2 | F5 | +| LED3 | G1 | +| LED4 | E1 | +| LED5 | F3 | +| LED6 | H3 | +| LED7 | K5 | + +## TFT / LCD(2×18 RGB565) + +| 信号 | 管脚 | 备注 | +|------|------|------| +| LCD_CLK | N9 | 像素时钟 | +| LCD_HSYNC | R7 | | +| LCD_VSYNC | T7 | | +| LCD_DE | T6 | 数据有效 | +| LCD_BL | V6 | 背光,高亮 | +| LCD_RESET / LCD_GPIO27 | P8 | 常驱高 | +| LCD_R7 | V7 | R[4] in RGB565 port | +| LCD_R6 | U7 | | +| LCD_R5 | V5 | | +| LCD_R4 | U5 | | +| LCD_R3 | T4 | | +| LCD_G7 | P11 | | +| LCD_G6 | N10 | | +| LCD_G5 | V12 | | +| LCD_G4 | T12 | | +| LCD_G3 | V8 | | +| LCD_G2 | U8 | | +| LCD_B7 | M10 | | +| LCD_B6 | T8 | | +| LCD_B5 | R8 | | +| LCD_B4 | N11 | | +| LCD_B3 | M11 | | + +HDL 端口常用打包: + +```text +lcd_r[4:0] ← LCD_R[7:3] +lcd_g[5:0] ← LCD_G[7:2] +lcd_b[4:0] ← LCD_B[7:3] +``` + +## 触摸(可选,刷屏可不接) + +| 信号 | 管脚 | +|------|------| +| TP_CS | R5 | +| TP_SCK | T3 | +| TP_MOSI | T5 | +| TP_MISO | R3 | +| TP_PEN | N6 | + +## VGA(若用 VGA 座,非 TFT 排针) + +| 信号 | 管脚 | +|------|------| +| VGA_HS | N8 | +| VGA_VS | M8 | + +## CST 片段示例(时钟+复位) + +```text +IO_LOC "clk" T9; +IO_PORT "clk" IO_TYPE=LVCMOS33 PULL_MODE=NONE BANK_VCCIO=3.3; +IO_LOC "rst_n" H5; +IO_PORT "rst_n" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; +``` + +完整 TFT 约束见工作区 `proj1/src/tft_top.cst`。 diff --git a/scripts/build.ps1 b/scripts/build.ps1 new file mode 100644 index 0000000..5cf9cff --- /dev/null +++ b/scripts/build.ps1 @@ -0,0 +1,40 @@ +param( + [Parameter(Mandatory = $true)] + [string]$ProjectDir, + [string]$GowinRoot = "" +) + +$ErrorActionPreference = "Stop" + +if (-not $GowinRoot) { + $GowinRoot = Join-Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + "tool-chain\Gowin\Gowin_V1.9.11.03_Education_x64" + if (-not (Test-Path $GowinRoot)) { + $GowinRoot = "C:\Users\Administrator\Documents\fpga\tool-chain\Gowin\Gowin_V1.9.11.03_Education_x64" + } +} + +$ProjectDir = (Resolve-Path $ProjectDir).Path +$gwSh = Join-Path $GowinRoot "IDE\bin\gw_sh.exe" +$buildTcl = Join-Path $ProjectDir "build.tcl" + +if (-not (Test-Path $gwSh)) { throw "gw_sh.exe not found: $gwSh" } +if (-not (Test-Path $buildTcl)) { throw "build.tcl not found: $buildTcl" } + +$env:PATH = "$(Join-Path $GowinRoot 'IDE\bin');$(Join-Path $GowinRoot 'Programmer\bin');$env:PATH" + +Write-Host "Building: $ProjectDir" +Push-Location $ProjectDir +try { + cmd /c "type build.tcl | gw_sh.exe" + if ($LASTEXITCODE -ne 0) { throw "gw_sh failed with exit $LASTEXITCODE" } +} finally { + Pop-Location +} + +$fs = Get-ChildItem (Join-Path $ProjectDir "impl\pnr\*.fs") -ErrorAction SilentlyContinue | + Sort-Object LastWriteTime -Descending | Select-Object -First 1 +if (-not $fs) { throw "No bitstream (.fs) under impl\pnr" } + +Write-Host "OK bitstream: $($fs.FullName)" +return $fs.FullName diff --git a/scripts/build_and_download.ps1 b/scripts/build_and_download.ps1 new file mode 100644 index 0000000..19a2706 --- /dev/null +++ b/scripts/build_and_download.ps1 @@ -0,0 +1,13 @@ +param( + [Parameter(Mandatory = $true)] + [string]$ProjectDir, + [ValidateSet(2, 4, 5, 6)] + [int]$Operation = 2, + [string]$GowinRoot = "" +) + +$ErrorActionPreference = "Stop" +$scripts = $PSScriptRoot + +& (Join-Path $scripts "build.ps1") -ProjectDir $ProjectDir -GowinRoot $GowinRoot +& (Join-Path $scripts "download.ps1") -ProjectDir $ProjectDir -Operation $Operation -GowinRoot $GowinRoot diff --git a/scripts/download.ps1 b/scripts/download.ps1 new file mode 100644 index 0000000..89efdca --- /dev/null +++ b/scripts/download.ps1 @@ -0,0 +1,38 @@ +param( + [Parameter(Mandatory = $true)] + [string]$ProjectDir, + [string]$FsFile = "", + [ValidateSet(2, 4, 5, 6)] + [int]$Operation = 2, + [string]$GowinRoot = "" +) + +$ErrorActionPreference = "Stop" + +if (-not $GowinRoot) { + $GowinRoot = "C:\Users\Administrator\Documents\fpga\tool-chain\Gowin\Gowin_V1.9.11.03_Education_x64" +} + +$ProjectDir = (Resolve-Path $ProjectDir).Path +$cli = Join-Path $GowinRoot "Programmer\bin\programmer_cli.exe" +if (-not (Test-Path $cli)) { throw "programmer_cli.exe not found: $cli" } + +$env:PATH = "$(Join-Path $GowinRoot 'Programmer\bin');$env:PATH" + +Write-Host "Scanning cables..." +& $cli --scan +if ($LASTEXITCODE -ne 0) { throw "scan failed; check USB cable and board power" } + +if (-not $FsFile) { + $fs = Get-ChildItem (Join-Path $ProjectDir "impl\pnr\*.fs") | + Sort-Object LastWriteTime -Descending | Select-Object -First 1 + if (-not $fs) { throw "No .fs found; build first" } + $FsFile = $fs.FullName +} else { + $FsFile = (Resolve-Path $FsFile).Path +} + +Write-Host "Programming GW5A-25A op=$Operation file=$FsFile" +& $cli -d GW5A-25A --fsFile $FsFile -r $Operation +if ($LASTEXITCODE -ne 0) { throw "program failed" } +Write-Host "Download finished." diff --git a/scripts/new_project.ps1 b/scripts/new_project.ps1 new file mode 100644 index 0000000..2b22129 --- /dev/null +++ b/scripts/new_project.ps1 @@ -0,0 +1,61 @@ +param( + [Parameter(Mandatory = $true)] + [string]$Name, + [Parameter(Mandatory = $true)] + [string]$TargetDir, + [string]$TopModule = "top" +) + +$ErrorActionPreference = "Stop" +$templateRoot = Join-Path (Split-Path $PSScriptRoot -Parent) "templates" + +if (Test-Path $TargetDir) { + throw "Target already exists: $TargetDir" +} + +New-Item -ItemType Directory -Force -Path (Join-Path $TargetDir "src") | Out-Null + +# gprj +$gprj = @" + + + + + 5 + gw5a25a-008 + + + + + + +"@ +[System.IO.File]::WriteAllText((Join-Path $TargetDir "$Name.gprj"), $gprj, (New-Object System.Text.UTF8Encoding $false)) + +# build.tcl (ASCII, no BOM) +$tcl = @" +open_project $Name.gprj +set_option -output_base_name $Name +set_option -synthesis_tool gowinsynthesis +set_option -top_module $TopModule +set_option -use_sspi_as_gpio 1 +set_option -use_mspi_as_gpio 1 +set_option -use_ready_as_gpio 1 +set_option -use_done_as_gpio 1 +set_option -use_cpu_as_gpio 1 +run all +exit +"@ +[System.IO.File]::WriteAllText((Join-Path $TargetDir "build.tcl"), $tcl, (New-Object System.Text.UTF8Encoding $false)) + +Copy-Item (Join-Path $templateRoot "src\top.v") (Join-Path $TargetDir "src\$TopModule.v") +Copy-Item (Join-Path $templateRoot "src\top.cst") (Join-Path $TargetDir "src\$TopModule.cst") +Copy-Item (Join-Path $templateRoot "src\top.sdc") (Join-Path $TargetDir "src\$TopModule.sdc") + +# fix module name inside copied files +$v = Get-Content (Join-Path $TargetDir "src\$TopModule.v") -Raw +$v = $v -replace "module top", "module $TopModule" +[System.IO.File]::WriteAllText((Join-Path $TargetDir "src\$TopModule.v"), $v, (New-Object System.Text.UTF8Encoding $false)) + +Write-Host "Created project: $TargetDir" +Write-Host "Next: gwin-skill\scripts\build_and_download.ps1 -ProjectDir $TargetDir" diff --git a/templates/build.tcl b/templates/build.tcl new file mode 100644 index 0000000..e36e3be --- /dev/null +++ b/templates/build.tcl @@ -0,0 +1,11 @@ +open_project template.gprj +set_option -output_base_name template +set_option -synthesis_tool gowinsynthesis +set_option -top_module top +set_option -use_sspi_as_gpio 1 +set_option -use_mspi_as_gpio 1 +set_option -use_ready_as_gpio 1 +set_option -use_done_as_gpio 1 +set_option -use_cpu_as_gpio 1 +run all +exit diff --git a/templates/src/top.cst b/templates/src/top.cst new file mode 100644 index 0000000..fc88f54 --- /dev/null +++ b/templates/src/top.cst @@ -0,0 +1,6 @@ +IO_LOC "clk" T9; +IO_PORT "clk" IO_TYPE=LVCMOS33 PULL_MODE=NONE BANK_VCCIO=3.3; +IO_LOC "rst_n" H5; +IO_PORT "rst_n" IO_TYPE=LVCMOS33 PULL_MODE=UP BANK_VCCIO=3.3; +IO_LOC "led0" C1; +IO_PORT "led0" IO_TYPE=LVCMOS33 PULL_MODE=NONE DRIVE=8 BANK_VCCIO=3.3; diff --git a/templates/src/top.sdc b/templates/src/top.sdc new file mode 100644 index 0000000..e76e122 --- /dev/null +++ b/templates/src/top.sdc @@ -0,0 +1 @@ +create_clock -name clk -period 20.000 -waveform {0.000 10.000} [get_ports {clk}] diff --git a/templates/src/top.v b/templates/src/top.v new file mode 100644 index 0000000..4ecf7c2 --- /dev/null +++ b/templates/src/top.v @@ -0,0 +1,18 @@ +// Minimal ACG525 blink template — LED0 on C1, clk T9, rst_n H5 +module top ( + input wire clk, + input wire rst_n, + output wire led0 +); + + reg [24:0] cnt; + always @(posedge clk or negedge rst_n) begin + if (!rst_n) + cnt <= 25'd0; + else + cnt <= cnt + 1'b1; + end + + assign led0 = cnt[24]; + +endmodule diff --git a/templates/template.gprj b/templates/template.gprj new file mode 100644 index 0000000..b585e09 --- /dev/null +++ b/templates/template.gprj @@ -0,0 +1,12 @@ + + + + + 5 + gw5a25a-008 + + + + + +