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