1. 为什么还在用 UltraEdit 写 Verilog/VHDL
UltraEdit 23.20.0.34 是一个老版本,但它在 FPGA 和 IC 设计圈里一直有生命力。原因很直接:启动快、大文件不卡、列编辑顺手、正则替换强,而且对 Verilog/VHDL 这种“一个文件几千行、信号名长得离谱”的场景,UltraEdit 的响应速度比很多现代编辑器更稳。你如果正在维护老工程,或者公司内网只能装离线包,这个版本依然是可用的选择。
问题也很明显:装完之后默认只认 C/C++、Java 这些常见语言,Verilog 和 VHDL 的关键字、注释、数字字面量全是黑白文本。always @(posedge clk)和普通注释一个颜色,reg [31:0]和变量名混在一起,读代码全靠眼睛硬扫。更麻烦的是,现在写 RTL 经常需要 AI 帮忙补 testbench、写约束、解释时序,如果编辑器里没有统一的模型接入入口,就得在浏览器和编辑器之间反复切,效率很低。
这篇就按“安装注册 → 补 Verilog/VHDL 高亮 → 接 TaoToken 统一 Key → 验证高亮和 API 都生效”的顺序走一遍。高亮部分给可直接复制的.uew词法配置片段,AI 部分给settings.json的接入骨架和连通性验证命令。适合正在用 UltraEdit 做 RTL 开发、又想把 AI 辅助编码链路补齐的人。
2. TaoToken 前置:统一 Key 与接入地址
TaoToken 在这里的角色是“统一 Key 网关”。你不用在 UltraEdit、脚本、CI 里分别维护不同厂商的 Key,而是拿一个 Key,通过统一的 API 地址调用模型。对 RTL 工程来说,最典型的用法是:选中一段 Verilog,让模型生成对应的 testbench;或者把 VHDL 实体丢过去,让它补 architecture 骨架。
需要先拿到的东西:
- 官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
- API 基地址:https://taotoken.net/api
- API Key 管理页:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
- 接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
- 模型对话验证页:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
注意:API 地址只写
https://taotoken.net/api,不要在后面拼多余的路径。Key 放在请求头里,不要写进会被提交到 Git 的工程文件。
如果你只是偶尔问一句,用模型对话页就够了;如果要在 UltraEdit 里长期做编码辅助,建议走 API Key + 本地脚本的方式,把 Key 存在环境变量或本地配置文件里。长期跑 Agent 或批量生成 testbench 的场景,可以看 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
3. 可复制配置:Verilog/VHDL 高亮与 settings.json 骨架
3.1 找到 wordfiles 目录
UltraEdit 的语法高亮词法文件叫.uew,放在用户配置目录下。23.20.0.34 在 Windows 上通常是:
C:\Users\<你的用户名>\AppData\Roaming\IDMComp\UltraEdit\wordfiles如果你不确定路径,打开 UltraEdit,依次点:高级 → 设置 → 编辑器显示 → 语法高亮,页面上会显示 “Wordfile 路径”,直接复制那个路径到资源管理器打开即可。
3.2 Verilog.uew 词法片段
把下面内容保存为Verilog.uew,放进 wordfiles 目录。这段覆盖了 Verilog-2001 常用关键字、系统任务、数字字面量和注释。
/L20"Verilog" Line Comment = // Block Comment On = /* Block Comment Off = */ Escape Char = \ /Function String = "%[a-zA-Z_][a-zA-Z0-9_]*[ ^t]*(" /Indent Strings = "begin" "case" "fork" /Unindent Strings = "end" "endcase" "join" /Colors = 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 /Colors Back = 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 /Colors Auto Back = 1 /Font Styles = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /Open Brace Strings = "{" "(" "[" /Close Brace Strings = "}" ")" "]" /C1"Keywords" always and assign automatic begin buf bufif0 bufif1 case casex casez cell cmos config deassign default defparam design disable edge else end endcase endconfig endfunction endgenerate endmodule endprimitive endspecify endtable endtask event for force forever fork function generate genvar highz0 highz1 if ifnone incdir include initial inout input instance integer join large liblist library localparam macromodule medium module nand negedge nmos nor noshowcancelled not notif0 notif1 or output parameter pmos posedge primitive pull0 pull1 pulldown pullup pulsestyle_onevent pulsestyle_ondetect rcmos real realtime reg release repeat rnmos rpmos rtran rtranif0 rtranif1 scalared showcancelled signed small specify specparam strong0 strong1 supply0 supply1 table task time tran tranif0 tranif1 tri tri0 tri1 triand trior trireg unsigned use vectored wait wand weak0 weak1 while wire wor xnor xor /C2"System Tasks" $display $write $strobe $monitor $time $stime $realtime $finish $stop $fopen $fclose $fdisplay $fwrite $readmemh $readmemb $signed $unsigned $bits $clog2 $random $test$plusargs $value$plusargs /C3"Numbers" 0 1 2 3 4 5 6 7 8 93.3 VHDL.uew 词法片段
VHDL 的关键字大小写不敏感,但 UltraEdit 的词法匹配默认区分大小写,所以下面把常见大写形式列全,实际写小写时也能靠library、entity这些高频词命中。
/L20"VHDL" Line Comment = -- Block Comment On = /* Block Comment Off = */ Escape Char = \ /Function String = "%[a-zA-Z_][a-zA-Z0-9_]*[ ^t]*(" /Indent Strings = "then" "loop" "generate" "is" /Unindent Strings = "end if" "end loop" "end generate" /Colors = 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 /Colors Back = 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 /Colors Auto Back = 1 /Font Styles = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /Open Brace Strings = "(" "[" /Close Brace Strings = ")" "]" /C1"Keywords" abs access after alias all and architecture array assert attribute begin block body buffer bus case component configuration constant disconnect downto else elsif end entity exit file for function generate generic group guarded if impure in inertial inout is label library linkage literal loop map mod nand new next nor not null of on open or others out package port postponed procedure process pure range record register reject rem report return rol ror select severity shared signal sla sll sra srl subtype then to transport type unaffected units until use variable wait when while with xnor xor /C2"Types" bit bit_vector boolean character integer natural positive real severity_level signed std_logic std_logic_vector std_ulogic std_ulogic_vector string time unsigned /C3"Numbers" 0 1 2 3 4 5 6 7 8 93.4 settings.json 接入骨架
UltraEdit 本身没有原生的 AI 插件配置,但你可以用一个本地脚本(Python 或 Node)做桥接,把选中的代码发给 TaoToken,再把结果贴回编辑器。桥接脚本读的配置文件建议叫settings.json,放在工程根目录或用户目录,骨架如下:
{ "provider": "taotoken", "api_base": "https://taotoken.net/api", "api_key_env": "TAOTOKEN_API_KEY", "model": "claude-sonnet", "timeout_seconds": 60, "max_tokens": 2048, "temperature": 0.2, "language_hint": "verilog", "system_prompt": "你是 RTL 工程师助手,输出可综合的 Verilog/VHDL 代码,不要解释,不要 Markdown 代码块标记。" }Key 不要写进这个文件,用环境变量注入:
# Windows PowerShell $env:TAOTOKEN_API_KEY="你的Key" # Linux / macOS export TAOTOKEN_API_KEY="你的Key"桥接脚本的核心请求逻辑(Python 示例):
import os, json, urllib.request cfg = json.load(open("settings.json", encoding="utf-8")) key = os.environ[cfg["api_key_env"]] payload = { "model": cfg["model"], "max_tokens": cfg["max_tokens"], "temperature": cfg["temperature"], "messages": [ {"role": "system", "content": cfg["system_prompt"]}, {"role": "user", "content": "为下面的 Verilog 模块生成 testbench:\n" + selected_code} ] } req = urllib.request.Request( cfg["api_base"] + "/v1/chat/completions", data=json.dumps(payload).encode("utf-8"), headers={ "Content-Type": "application/json", "Authorization": "Bearer " + key } ) print(json.loads(urllib.request.urlopen(req, timeout=cfg["timeout_seconds"]).read()))4. 验证请求与成功结果
4.1 验证高亮是否生效
把Verilog.uew和VHDL.uew拷进 wordfiles 目录后,完全退出 UltraEdit 再重开(不是关窗口,是托盘也退出)。打开一个.v文件,点底部状态栏的语言选择,应该能看到 “Verilog”。选中后,always、begin、end、module会变成关键字颜色,//注释变绿,$display变系统任务颜色。
如果语言列表里没有 Verilog,检查两点:文件名必须是Verilog.uew,大小写敏感;文件第一行的/L20"Verilog"里的语言名要和你在列表里看到的一致。
4.2 验证 API 连通性
先用 curl 做一次最小请求,确认 Key 和地址都对:
curl -s https://taotoken.net/api/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -d '{ "model": "claude-sonnet", "max_tokens": 64, "messages": [{"role": "user", "content": "用一句话说明 Verilog 中阻塞赋值和非阻塞赋值的区别"}] }'成功时返回 JSON 里会有choices[0].message.content,内容是中文或英文的一句话解释。如果返回 401,说明 Key 没读到;返回 404,检查地址是不是写成了https://taotoken.net/api之外的多余路径。
4.3 在 UltraEdit 里跑通一次 AI 补全
选中一段模块声明,比如:
module counter ( input wire clk, input wire rst_n, output reg [7:0] cnt );运行桥接脚本,把选中内容作为selected_code传进去,请求“生成 testbench”。返回的代码直接贴到新文件里,保存为tb_counter.v。如果返回内容带 Markdown 代码块标记,说明system_prompt没生效,检查 JSON 里system_prompt字段有没有被正确读取。
5. 本篇常见错排查
高亮不生效,文件还是黑白。最常见原因是没重启 UltraEdit,或者.uew文件编码不是 ANSI/UTF-8 无 BOM。用记事本另存为 UTF-8 无 BOM 再试。另一个原因是 wordfiles 目录里已经有同名文件,新文件被覆盖或没覆盖成功,检查修改时间。
语言列表里出现两个 Verilog。说明你之前放过一个Verilog.uew,现在又放了一个,或者文件里/L20的编号和已有文件冲突。把旧的删掉,只留一个,编号改成没被占用的,比如/L21。
curl 返回 401。环境变量没导出到当前 shell。PowerShell 里$env:TAOTOKEN_API_KEY只在当前会话有效,新开窗口要重新设。Linux 下检查echo $TAOTOKEN_API_KEY有没有输出。
返回 429。请求太频繁,等几秒重试,或者把max_tokens调小。批量生成 testbench 时建议在脚本里加time.sleep(1)。
返回内容被截断。max_tokens设太小。生成 testbench 建议至少 2048,复杂模块给 4096。同时检查timeout_seconds,大模块生成慢,60 秒可能不够。
中文注释乱码。UltraEdit 默认编码和文件实际编码不一致。在 UltraEdit 里点“文件 → 转换 → UTF-8 转 ASCII”或反向操作,让编辑器和文件编码对齐。桥接脚本读写文件时统一用encoding="utf-8"。
Key 泄露风险。不要把 Key 写进settings.json后提交到 Git。用.gitignore排除settings.json,或者只提交settings.example.json,真实 Key 走环境变量。如果不小心提交了,立刻去 API Keys 页面吊销重建:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite
6. 把这条链路固定下来
高亮配置是一次性的,配好之后不用再动。真正需要固定的是 AI 接入这条链路:settings.json管模型和参数,环境变量管 Key,桥接脚本管选中代码的收发。三样东西分开,换模型只改model字段,换 Key 只改环境变量,工程文件里不出现任何敏感信息。
如果你后面要批量给多个模块生成 testbench,或者让 Agent 自动跑回归,建议把 Coding Plan 的额度用起来,避免单次请求被限流:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite
日常调试模型输出是否稳定,可以直接在模型对话页里贴同一段 Verilog 对比几次结果:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite
接入细节和请求参数以文档为准:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite
我自己的习惯是:UltraEdit 只负责编辑和高亮,AI 请求全部走本地脚本,脚本读settings.json和环境变量。这样即使换机器,只要把.uew和脚本拷过去,Key 重新设一下,五分钟就能恢复整条链路。