# ============================================================================ # cpu21-riscv 回归脚本(Vivado xsim) # # 在工程目录 pipelined-cpu/ 下运行: # powershell -ExecutionPolicy Bypass -File tools\run_regress.ps1 # # 做四件事: # 1) 逐个跑指令测试:muldiv_test / isa_test / lui_test / mmio_test, # 把测试平台打印的 LED 序列与 programs/<名字>.expected 逐值比对; # 2) 跑两个流水基线(默认 ROM):tb_no_intr、tb_cpu21_riscv_redirect_int_bpb, # 只打印 FINAL 统计行,便于和已知基线核对; # 3) 跑板级顶层(-d BOARD_ROM_FAST),检查跑马灯 LED 序列; # 4) 最后汇总 PASS/FAIL 并按失败数设置退出码。 # # 编译与仿真都放在 $env:TEMP\cpu21_regress 下,不会往工程目录写中间文件。 # 需要 xvlog / xelab / xsim 在 PATH 上(Vivado 安装目录的 bin)。 # ============================================================================ $ErrorActionPreference = 'Stop' $proj = Split-Path -Parent $PSScriptRoot # tools/ 的上一级就是工程目录 $projF = ($proj -replace '\\', '/') # Verilog 字符串里要用正斜杠 $sim = Join-Path $env:TEMP 'cpu21_regress' $enc = New-Object System.Text.UTF8Encoding($false) foreach ($tool in 'xvlog', 'xelab', 'xsim') { if (-not (Get-Command $tool -ErrorAction SilentlyContinue)) { Write-Output "ERROR: 找不到 $tool,请把 Vivado 的 bin 目录加到 PATH" exit 1 } } New-Item -ItemType Directory -Force $sim | Out-Null Set-Content -Path "$sim\run.tcl" -Value @('run all', 'quit') -Encoding ascii $RTL = @(Get-ChildItem "$proj\srcs\rtl\*.v" | ForEach-Object FullName) $fail = 0 # TB 里的 ROM_FILE 参数默认是文件名,这里替换成绝对路径(PowerShell 传参有坑, # 直接改副本最稳) function Sim-Top { param($Top, $TbFile, $DefaultRom, $RealRom, $Snap) $txt = [System.IO.File]::ReadAllText($TbFile, $enc) $new = $txt.Replace('"' + $DefaultRom + '"', '"' + $projF + '/srcs/rom/' + $RealRom + '"') [System.IO.File]::WriteAllText("$sim\$Snap.v", $new, $enc) Remove-Item -Recurse -Force "$sim\xsim.dir" -ErrorAction SilentlyContinue & xvlog @RTL "$sim\$Snap.v" 2>&1 | Out-File -Encoding ascii "$sim\xvlog_$Snap.txt" & xelab -top $Top -snapshot $Snap 2>&1 | Out-File -Encoding ascii "$sim\xelab_$Snap.txt" & xsim $Snap -tclbatch run.tcl 2>&1 | Out-File -Encoding ascii "$sim\run_$Snap.txt" $err = Select-String -Path "$sim\xvlog_$Snap.txt", "$sim\xelab_$Snap.txt" -Pattern 'ERROR' | Select-Object -First 1 -ExpandProperty Line if ($err) { Write-Output "!! $Snap : $err"; $script:fail++ } } Push-Location $sim try { Write-Output '===== 1) 指令测试(tb_no_intr,与 programs/*.expected 比对)=====' foreach ($t in 'muldiv_test', 'isa_test', 'lui_test', 'mmio_test') { Sim-Top -Top tb_no_intr -TbFile "$proj\srcs\tb\tb_no_intr.v" ` -DefaultRom 'risc-v-benchmark_ccab.hex' -RealRom "$t.hex" -Snap "sim_$t" $log = "$sim\run_sim_$t.txt" $obs = @(Select-String -Path $log -Pattern 'LEDv=1 LED=([0-9a-fA-F]{8})' -AllMatches | ForEach-Object { $_.Matches[0].Groups[1].Value.ToLower() }) $exp = @(Get-Content "$proj\programs\$t.expected" | ForEach-Object { $_.Trim().ToLower() } | Where-Object { $_ -ne '' }) if (($obs -join ',') -eq ($exp -join ',')) { Write-Output (" {0,-13} PASS ({1} 个 LED 值)" -f $t, $obs.Count) } else { Write-Output (" {0,-13} FAIL 期望 {1} / 观测 {2}" -f $t, $exp.Count, $obs.Count) Write-Output (" 期望: " + ($exp -join ' ')) Write-Output (" 观测: " + ($obs -join ' ')) $fail++ } Write-Output (' ' + (Select-String -Path $log -Pattern 'FINAL:' | Select-Object -First 1 -ExpandProperty Line)) } Write-Output '===== 2) 流水基线(默认 ROM)=====' Sim-Top -Top tb_no_intr -TbFile "$proj\srcs\tb\tb_no_intr.v" ` -DefaultRom 'risc-v-benchmark_ccab.hex' -RealRom 'risc-v-benchmark_ccab.hex' -Snap 'base_no_intr' Write-Output (' tb_no_intr : ' + (Select-String -Path "$sim\run_base_no_intr.txt" -Pattern 'FINAL:' | Select-Object -First 1 -ExpandProperty Line)) Sim-Top -Top tb_cpu21_riscv_redirect_int_bpb -TbFile "$proj\srcs\tb\tb_cpu21_riscv_redirect_int_bpb.v" ` -DefaultRom 'cpu21_riscv_redirect_int_bpb_rom.hex' -RealRom 'cpu21_riscv_redirect_int_bpb_rom.hex' ` -Snap 'base_intr' Write-Output (' tb_intr : ' + (Select-String -Path "$sim\run_base_intr.txt" -Pattern 'FINAL:' | Select-Object -First 1 -ExpandProperty Line)) Write-Output '===== 3) 板级顶层(-d BOARD_ROM_FAST,跑马灯)=====' Remove-Item -Recurse -Force "$sim\xsim.dir" -ErrorAction SilentlyContinue & xvlog -d BOARD_ROM_FAST @RTL "$proj\srcs\board\cpu21_board_top.v" "$proj\srcs\tb\tb_board_top.v" 2>&1 | Out-File -Encoding ascii "$sim\xvlog_board.txt" & xelab -top tb_board_top -snapshot board -d BOARD_ROM_FAST 2>&1 | Out-File -Encoding ascii "$sim\xelab_board.txt" & xsim board -tclbatch run.tcl 2>&1 | Out-File -Encoding ascii "$sim\run_board.txt" $seq = @(Select-String -Path "$sim\run_board.txt" -Pattern 'LED=([0-9a-f]{4})' -AllMatches | ForEach-Object { $_.Matches[0].Groups[1].Value }) Write-Output (' 前 18 个 LED: ' + (($seq[0..17]) -join ' ')) Write-Output (" 变化次数: " + $seq.Count) if (($seq[0..17] -join ' ') -ne '0000 0001 0002 0004 0008 0010 0020 0040 0080 0100 0200 0400 0800 1000 2000 4000 8000 0001') { Write-Output ' FAIL:跑马灯序列与预期不符'; $fail++ } else { Write-Output ' PASS' } } finally { Pop-Location } Write-Output '' if ($fail -eq 0) { Write-Output '全部通过 (所有回归 PASS)' } else { Write-Output "有 $fail 项失败" } exit $fail