1. UltraEdit 写 Verilog 顺手,但仿真这一步总卡住
UltraEdit 关联 modelsim 调试,是很多 FPGA/IC 初学者绕不开的一道坎。UltraEdit 本身是个老牌文本编辑器,列编辑、正则替换、大文件打开都很稳,写 Verilog 代码体验不错;ModelSim 则是 Verilog 仿真里最常用的工具之一,能编译、能跑波形、能单步调试。问题在于,这两者默认是各干各的:你在 UltraEdit 里改完代码,还得切到 ModelSim 里手动敲vlog、vsim,来回折腾,效率低还容易漏编译。
这篇就聚焦一件事:怎么把 UltraEdit 和 ModelSim 串起来,让你在 UltraEdit 里点一下工具栏按钮,就能自动编译当前 Verilog 文件、启动仿真、甚至直接看波形。适合刚接触 FPGA/IC 仿真、已经会写简单 Verilog 但还没配过工具链的同学。我会从环境变量、UltraEdit 工具配置、do 脚本、常见报错四个方向讲,最后用一个计数器模块跑通全流程,你能直接照着做。
先说清楚整体思路:UltraEdit 的「工具配置」本质是让你定义一条外部命令,命令里可以调用 ModelSim 的vlog、vsim等可执行文件。只要 ModelSim 的 bin 目录在系统 PATH 里,UltraEdit 就能找到它们。所以配置分三步:让系统认识 ModelSim 命令、在 UltraEdit 里建命令、写一个 do 脚本把编译和仿真串起来。下面一步步来。
2. 前置准备:ModelSim 路径、环境变量与 UltraEdit 工具配置
2.1 确认 ModelSim 安装路径和可执行文件
先找到你的 ModelSim 安装目录。常见路径长这样:
C:\modeltech64_2020.4\win64 C:\intelFPGA\20.1\modelsim_ase\win32aloem进去之后确认这几个文件存在:vlog.exe(编译 Verilog)、vsim.exe(启动仿真)、vlib.exe(建库)。如果只有vsim.exe没有vlog.exe,说明你装的是 ModelSim 的某些精简版,需要换完整版。
2.2 把 ModelSim 的 bin 目录加进 PATH
这一步是很多「vsim 未启动」报错的根源。操作方式:右键「此电脑」→ 属性 → 高级系统设置 → 环境变量 → 在「系统变量」里找到Path→ 编辑 → 新建一行,把 ModelSim 的 win64(或 win32aloem)目录粘进去。
加完之后一定要重开一个命令行窗口验证,因为 PATH 修改对已打开的进程不生效:
where vlog where vsim如果两条命令都能返回路径,说明环境变量生效了。如果返回「找不到文件」,检查是不是加错了目录层级,或者加到了「用户变量」而当前用的是别的账户。
2.3 在 UltraEdit 里新建工具命令
打开 UltraEdit,菜单栏「高级」→「工具配置」(不同版本可能叫「高级」→「配置」→「工具」)。点「添加」新建一条命令,关键字段这样填:
| 字段 | 填写内容 | 说明 |
|---|---|---|
| 命令名 | Compile & Sim | 工具栏显示的名字 |
| 命令行 | vlog -sv "%f" | %f是当前文件名占位符 |
| 工作目录 | %p | 当前文件所在目录 |
| 输出 | 输出到列表框 | 方便看编译报错 |
| 工具栏按钮 | 勾选 | 让它出现在工具栏 |
%f和%p是 UltraEdit 的占位符,分别代表当前文件名和当前文件路径。这样你打开哪个.v文件,它就编译哪个,不用改命令。
2.4 配置语法高亮,让 Verilog 更好读
UltraEdit 默认可能没有 Verilog 高亮。菜单「高级」→「配置」→「编辑器显示」→「语法着色」,在「语言」下拉里找 Verilog 或 Verilog HDL。如果没有,可以点「添加」新建,把关键字列表填进去,比如module、endmodule、always、initial、reg、wire、assign、posedge、negedge。颜色按自己喜好设,关键字一个色、注释一个色、数字一个色,读代码会舒服很多。
这一步不是必须的,但配好之后,写always @(posedge clk)这种语句时一眼能看出结构,排错时省眼睛。
3. 可复制配置:do 脚本 + UltraEdit 命令串起编译与仿真
3.1 写一个通用的 sim.do 脚本
在工程目录下新建sim.do,内容如下。这个脚本负责建库、编译、启动仿真、加波形:
# sim.do - ModelSim 仿真脚本 # 用法:vsim -do sim.do # 退出已有仿真,避免重复加载 quit -sim # 建工作库(已存在会报错,用 catch 忽略) if {[catch {vlib work}]} { puts "work 库已存在,跳过创建" } # 映射工作库 vmap work work # 编译所有 Verilog 源文件 vlog -sv ../src/counter.v vlog -sv ../tb/counter_tb.v # 启动仿真,指定顶层测试平台 vsim -t 1ns work.counter_tb # 添加波形:顶层所有信号 add wave -r /* # 运行 1us run 1us # 波形窗口自动弹出 wave zoom full几个要点:quit -sim放在最前面,防止上一次仿真没关干净导致端口占用;vlog -sv里的-sv表示支持 SystemVerilog 语法,纯 Verilog 也可以加,兼容性更好;add wave -r /*是递归添加所有信号,初学者不用一个个手点。
3.2 在 UltraEdit 里加一条「启动仿真」命令
回到「工具配置」,再添加一条命令:
| 字段 | 填写内容 |
|---|---|
| 命令名 | Run Sim |
| 命令行 | vsim -do sim.do |
| 工作目录 | %p |
| 输出 | 输出到列表框 |
这样工具栏上就有两个按钮:一个编译当前文件,一个启动仿真。实际用的时候,先点编译确认没语法错,再点仿真看波形。
3.3 用 JSON 记录工程配置,方便迁移
如果你经常换电脑或者多人协作,建议把工具配置和工程结构记成一个 JSON,放在工程根目录:
{ "project": "counter_sim", "modelsim_bin": "C:/modeltech64_2020.4/win64", "src_dir": "../src", "tb_dir": "../tb", "top_module": "counter_tb", "sim_script": "sim.do", "run_time": "1us", "time_resolution": "1ns" }这个文件不参与仿真,但换机器时照着它重新配 PATH 和 UltraEdit 命令,几分钟就能恢复环境。注意路径用正斜杠/,ModelSim 的 Tcl 对反斜杠有时会误解析。
3.4 一个可综合的计数器模块和测试平台
src/counter.v:
module counter #( parameter WIDTH = 4 )( input wire clk, input wire rst_n, output reg [WIDTH-1:0] cnt ); always @(posedge clk or negedge rst_n) begin if (!rst_n) cnt <= {WIDTH{1'b0}}; else cnt <= cnt + 1'b1; end endmoduletb/counter_tb.v:
`timescale 1ns/1ps module counter_tb; reg clk; reg rst_n; wire [3:0] cnt; counter #(.WIDTH(4)) u_counter ( .clk (clk), .rst_n (rst_n), .cnt (cnt) ); initial begin clk = 0; rst_n = 0; #20 rst_n = 1; #200 $stop; end always #5 clk = ~clk; endmodule时钟周期 10ns,复位 20ns 后释放,跑 200ns 后$stop暂停。配合前面的sim.do,run 1us会跑满 1us,足够看到计数器从 0 数到 15 再回绕。
4. 验证请求:编译计数器并观察波形输出
4.1 在 UltraEdit 里执行编译
打开counter.v,点工具栏的「Compile & Sim」按钮。UltraEdit 底部输出框应该出现类似内容:
ModelSim vlog 2020.4 -- Compiling module counter Top level modules: counter如果出现** Error,说明语法有问题,按报错行号回去改。编译通过后,打开counter_tb.v,再点一次编译,把测试平台也编进去。
4.2 启动仿真并检查波形
点「Run Sim」按钮,ModelSim 的 GUI 会弹出来,同时执行sim.do。你会看到 transcript 窗口依次输出建库、编译、加载的信息,最后波形窗口自动打开,clk、rst_n、cnt三条信号都在。
重点看cnt:复位期间是 0,rst_n拉高后每个时钟上升沿加 1,到 15 之后回绕到 0。如果cnt一直是红色X,说明复位没生效或者时钟没接对,回去检查initial块和always #5 clk = ~clk。
4.3 用命令行方式二次验证
有时候 GUI 弹不出来,或者你想确认是不是 UltraEdit 配置的问题,可以直接在工程目录开命令行:
vlib work vlog -sv ../src/counter.v ../tb/counter_tb.v vsim -c -do "run 1us; quit -f" work.counter_tb-c是命令行模式,不弹 GUI,适合快速验证编译和仿真能不能跑通。如果命令行能跑、UltraEdit 不能跑,问题就在 UltraEdit 的命令配置或工作目录上。
4.4 观察波形时的几个实用操作
波形窗口里,Ctrl+滚轮可以缩放时间轴;选中信号右键「Radix」可以切换显示进制,cnt切成 unsigned 或 hex 更直观;点「Restart」再「Run」可以重跑,不用关窗口。这些操作在调试计数器、状态机时很常用。
5. 本篇常见错排查:vsim 未启动、路径含空格、401 与 OAuth 类报错
5.1 vsim 未启动 / 命令找不到
报错长这样:
'vsim' 不是内部或外部命令,也不是可运行的程序原因就一个:PATH 没配好,或者配了没重启 UltraEdit。UltraEdit 启动时会继承当时的环境变量,你改完 PATH 必须完全关闭 UltraEdit 再打开。另外检查是不是把路径加到了「用户变量」但 UltraEdit 以管理员身份运行,两者环境变量可能不一致。
5.2 路径含空格导致 vlog 失败
报错:
Error: (vlog-7) Failed to open design unit file "C:/My Project/src/counter.v"路径里有空格,Tcl 把空格当成了参数分隔符。解决办法有两个:一是把工程放到没有空格的路径下,比如D:/fpga/counter_sim;二是在 do 脚本里给路径加引号:
vlog -sv "../my project/src/counter.v"推荐第一种,省事。初学者最容易把工程放在「我的文档」「Desktop」这种带空格或中文的路径下,建议统一放D:/fpga/这种纯英文无空格目录。
5.3 local proxy failed / 连接类报错
如果你在配置过程中用到在线模型对话或 API 调试工具,偶尔会遇到:
local proxy failed: connection refused这类报错通常和本地代理端口没起来有关。检查你配置的 Base URL 和端口是否和实际服务一致,比如本地服务监听 8080,你写成了 8000,就会 refused。如果是用 TaoToken 做模型对话验证,Base URL 填https://taotoken.net/api,Key 在控制台生成,别把端口和路径拼错。
5.4 401 与 OAuth 报错
401 Unauthorized OAuth token expired401 是 Key 不对或没带。检查请求头里Authorization: Bearer <你的Key>格式对不对,Key 有没有多余空格。OAuth 过期就重新走一次授权流程,拿到新 token 再试。这类报错和 ModelSim 本身无关,但如果你在仿真流程里集成了在线工具做代码检查,就会碰到。
5.5 reading choices 报错
Error reading choices: unexpected end of file这种多半是配置文件被截断或格式不对。比如 JSON 少了个右括号,或者 TOML 里引号没闭合。用编辑器打开配置文件,检查括号配对和引号闭合。UltraEdit 的「括号匹配」功能(Ctrl+B)可以快速定位。
5.6 编译通过但波形全红
不是报错,但很常见。cnt全是X,通常是复位信号没初始化,或者测试平台里rst_n一直是 0。检查initial块里有没有rst_n = 0;然后延时后拉高。另一个可能是时钟没翻转,always #5 clk = ~clk;写成了always #5 clk = clk;,自己赋值给自己,永远不变。
6. 把 UltraEdit 和 ModelSim 串成日常流程
配好之后,我自己的习惯是:UltraEdit 里改代码,Ctrl+S保存,点编译按钮看有没有语法错,再点仿真按钮看波形。do 脚本里add wave -r /*省去了每次手加信号的时间,run 1us固定跑一段,看计数器、分频器、状态机都够用。
如果你后面要接在线模型做代码审查或者生成测试平台,可以在 UltraEdit 里再加一条工具命令,调用 API 把当前文件内容发过去。Base URL 用https://taotoken.net/api,Key 在控制台生成,模型 ID 按你用的填。这样编辑、仿真、辅助检查都在一个界面里完成,不用来回切窗口。
最后提醒一句:工程路径别带空格和中文,PATH 改完重启编辑器,do 脚本里路径加引号。这三条做到,九成的「vsim 未启动」和「vlog 失败」都能避开。