diff --git a/pipelined-cpu/create_project.tcl b/pipelined-cpu/create_project.tcl index 087f0ca..5580901 100644 --- a/pipelined-cpu/create_project.tcl +++ b/pipelined-cpu/create_project.tcl @@ -64,6 +64,10 @@ add_files -norecurse -fileset sources_1 [list \ set_property file_type {Verilog Header} \ [get_files "$origin_dir/srcs/board/cpu21_board_rom.vh"] +# 默认跑哪个内置程序:1 = 扫雷(定义宏 SAOLEI_ROM),0 = 走马灯 demo。 +# 只有 cpu21_saolei_rom.vh 存在且 use_saolei = 1 时才会定义宏。 +set use_saolei 1 + # 扫雷程序的 ROM 初始化(由 saolei/tools/build.ps1 生成,可能还不存在)。 # 综合/仿真时定义宏 SAOLEI_ROM 就会用它替换上面的跑马灯 ROM。 set saolei_rom "$origin_dir/srcs/board/cpu21_saolei_rom.vh" @@ -74,6 +78,15 @@ if {[file exists $saolei_rom]} { puts "NOTE: 还没有 $saolei_rom —— 需要先跑 saolei/tools/build.ps1 生成" } +# 关键:sources_1 定义 SAOLEI_ROM,cpu21_board_top.v 里的 `ifdef 链才会用扫雷 ROM +# (该宏只影响综合用的 sources_1,仿真 fileset 仍各自用 tb 自带的 ROM) +if {$use_saolei && [file exists $saolei_rom]} { + set_property verilog_define {SAOLEI_ROM} [get_filesets sources_1] + puts "NOTE: sources_1 已定义 SAOLEI_ROM —— 上板跑扫雷;想跑走马灯把本脚本里 use_saolei 改成 0" +} else { + puts "NOTE: 未定义 SAOLEI_ROM —— 上板跑走马灯 demo" +} + # 约束(cpu21_board_top.xdc 是引脚与分频时钟约束) add_files -norecurse -fileset constrs_1 [glob "$origin_dir/srcs/constrs/*.xdc"] @@ -109,6 +122,7 @@ foreach fs {sim_1 sim_2} { # ---------------------------------------------------------------- 结果汇总 puts "工程已创建:$origin_dir/$proj_name.xpr" puts " sources_1 顶层 = cpu21_board_top(上板:时钟分频 + 片内 ROM/RAM + 引脚)" +puts " sources_1 程序 = [expr {$use_saolei && [file exists $saolei_rom] ? {扫雷 (SAOLEI_ROM)} : {走马灯 demo}}]" puts " sim_1 顶层 = tb_cpu21_riscv_redirect_int_bpb(中断/分支预测)" puts " sim_2 顶层 = tb_no_intr(指令集测试,ROM 镜像在 srcs/rom/)" puts " 下一步:Run Synthesis → Run Implementation → Generate Bitstream,或 Run Simulation" diff --git a/pipelined-cpu/srcs/board/cpu21_board_top.v b/pipelined-cpu/srcs/board/cpu21_board_top.v index dde1bb8..ce58225 100644 --- a/pipelined-cpu/srcs/board/cpu21_board_top.v +++ b/pipelined-cpu/srcs/board/cpu21_board_top.v @@ -344,8 +344,7 @@ generate .ps2_clk_oe_o (), .ps2_data_i (ps2_data), .ps2_data_oe_o(), - Tcl 一键重建 -valid_o (ev_valid), + .ev_valid_o (ev_valid), .ev_dx_o (ev_dx), .ev_dy_o (ev_dy), .ev_btn_o (ev_btn), diff --git a/pipelined-cpu/tools/check_rtl_text.ps1 b/pipelined-cpu/tools/check_rtl_text.ps1 index 49d33e4..99745cd 100644 --- a/pipelined-cpu/tools/check_rtl_text.ps1 +++ b/pipelined-cpu/tools/check_rtl_text.ps1 @@ -18,6 +18,11 @@ # powershell -ExecutionPolicy Bypass -File pipelined-cpu\tools\check_rtl_text.ps1 # Exit code 0 = clean, 1 = found something. # ============================================================================= +param( + # -Fix: 自动删除"整行都是粘贴进来的正文"的坏行(保守:只删不含 ; ( ) = 等代码标点的整行)。 + # 被部分覆盖的行(例如某个端口行被改坏)只报告,需手工或 git 修。 + [switch]$Fix +) $ErrorActionPreference = 'Stop' $srcs = Join-Path (Split-Path -Parent $PSScriptRoot) 'srcs' @@ -28,31 +33,37 @@ $files = Get-ChildItem -Recurse -Path $srcs -Include *.v, *.vh, *.xdc -File foreach ($f in $files) { $rel = $f.FullName.Substring($srcs.Length).TrimStart('\', '/') - $lines = @(Get-Content -LiteralPath $f.FullName) - $inBlockComment = $false + # 用 .NET 按 UTF-8 读原始字节:PS 5.1 的 Get-Content 会按 GBK 解码,中文会乱。 + # 按行切开时保留行尾(\r\n / \n),写回时逐字节保持原样,不归一化换行/编码/BOM。 + $bytes = [System.IO.File]::ReadAllBytes($f.FullName) + $text = [System.Text.Encoding]::UTF8.GetString($bytes) + $lines = @([regex]::Split($text, "(?<=\n)")) + $drop = @() for ($i = 0; $i -lt $lines.Count; $i++) { - $line = $lines[$i] + $line = $lines[$i].TrimEnd("`r", "`n") $lineNo = $i + 1 - # ---- strip comments so we only look at code positions ---- + # ---- 只去掉 // (或 .xdc 的 #) 之后的部分,其余按代码位置检查 ---- + # 注意:这里不处理 /* */ 块注释(srcs 里没有块注释,之前因此漏报过坏行) $code = $line if ($f.Extension -eq '.xdc') { $h = $code.IndexOf('#'); if ($h -ge 0) { $code = $code.Substring(0, $h) } } else { $c = $code.IndexOf('//'); if ($c -ge 0) { $code = $code.Substring(0, $c) } - if ($inBlockComment) { $code = '' } - if ($line -match '/\*') { $inBlockComment = $true } - if ($line -match '\*/') { $inBlockComment = $false } } $trim = $line.Trim() # ---- check 1: non-ASCII in code position ---- if ($code -match '[^\x00-\x7F]') { - Write-Output ("!! $rel`:$lineNo non-ASCII text in code position:") + # 整行只有正文(不含 ; ( ) = ` ' " 之类代码标点)⇒ 可以安全整行删掉 + $onlyProse = ($trim -notmatch '[;()=`''"]') + $tag = if ($onlyProse) { ' [整行正文,可用 -Fix 删掉]' } else { ' [部分覆盖,需手工/git 修]' } + Write-Output ("!! $rel`:$lineNo non-ASCII text in code position${tag}:") Write-Output (" " + $trim) + if ($Fix -and $onlyProse) { $drop += $i } $bad++ continue } @@ -64,6 +75,12 @@ foreach ($f in $files) { $bad++ } } + + if ($Fix -and $drop.Count -gt 0) { + $kept = for ($i = 0; $i -lt $lines.Count; $i++) { if ($drop -notcontains $i) { $lines[$i] } } + [System.IO.File]::WriteAllText($f.FullName, ($kept -join ''), (New-Object System.Text.UTF8Encoding($false))) + Write-Output (" -Fix: 已从 $rel 删除 " + $drop.Count + " 行(编码/换行保持不变),请重跑自检确认") + } } Write-Output "" @@ -73,5 +90,7 @@ if ($bad -eq 0) { exit 0 } Write-Output ("RTL text check: FAILED, " + $bad + " suspicious line(s) - fix them before synthesis.") -Write-Output "Hint: such lines are usually injected by an editor/tool; remove them, then re-run this script." +Write-Output "Hint1: 这类行通常是编辑器/工具粘贴进来的正文;整行正文可以用 -Fix 删掉:" +Write-Output " powershell -ExecutionPolicy Bypass -File tools\check_rtl_text.ps1 -Fix" +Write-Output "Hint2: 若报的是 [部分覆盖],对照 git diff 手工修(被编辑器保存覆盖时,先关掉那个标签页再改)。" exit 1