这一篇在干嘛?
这一篇带你完整过一遍安路 TD 自带的 Encrypt Tool(对应官方手册 SWUG113 v1.0):它能把你写的 Verilog / SystemVerilog / VHDL 源文件加密成
.vp/.svp/.vhdp文件——别人可以用它做仿真,却看不到(也改不了)里面的代码。写完模块准备交付 IP、或者要把代码发给别人评审又不想公开实现细节时,这套流程就是你的”保险箱”。同系列目录见 固件加密工具首页。
两种加密模式:module all 与 module body
为什么需要源码加密
先想一个场景:你为移远 FPGA 大赛写了一个精心调优的 SDRAM 控制器,队友在另一所学校,需要拿去和他的顶层联调。如果你直接把 sdram_ctrl.vhd 发过去,等于把全部 RTL 实现送了出去——他可以随意复制、改名、甚至当作自己的成果提交。“功能给他用,实现不给他看”,这就是源码加密要解决的核心矛盾。
Encrypt Tool 的思路不是”压缩”也不是”混淆”,而是真正的密钥加密:
- 加密后的文件(如
test.enc.vp)里只有密文,用文本编辑器打开看不到任何原始逻辑。 - 加密文件里内置了公钥信息,只有持有对应密钥的仿真工具才能”解开”它并正常仿真——也就是说,代码功能完全保留,人类可读性归零。
- 支持一次加密多种语言混合的文件:Verilog(
.v)、SystemVerilog(.sv)、VHDL(.vhd/.vhdl)可以同时丢进去一起处理。
和比特流加密区分一下:TD 里另一类”位流加密”是对最终烧进 Flash 的 FPGA 配置文件加密,防止别人用采样线回读你的下载文件;而 Encrypt Tool 处理的是还没综合的 HDL 源码,属于 IP 交付层面的保护。比赛里如果你要对外提供模块,后者才是你常用的那个。
常见坑:加密 ≠ 综合可用
加密文件主要面向仿真场景(配合 ModelSim、QuestaSim、VCS 等第三方仿真器)。如果你打算把加密文件直接加进 TD 工程参与综合实现,先确认你的使用场景是否支持——它更常用于”交付可仿真的 IP 给客户/队友”,而不是作为自己工程里的日常源文件。
打开工具与主界面总览
Encrypt Tool 不用单独安装,它内嵌在 TD 软件里。打开方式:菜单栏 Tools → Encrypt Tool,点一下就弹出独立窗口。
主界面从上到下分四块,先建立整体印象:

- Source file to encrypt(源文件列表):核心区域,里面有
Encrypt module all和Encrypt module body两个标签页,代表两种加密模式(下一节细讲)。要加密的文件加进对应页面,右侧 Add 按钮的下拉菜单里可以选Add Files(逐个加文件)或Add File Lists(加一个.list列表文件,里面记录所有源文件路径,适合批量操作)。选中列表里的文件右键 → delete 可以移除。 - Save path(保存路径):选
Original path(加密文件生成在源文件旁边)或Another path(点 Browse 自选输出目录)。 - Merge(合并输出):勾选后可以把多个同语言文件的加密结果合并成一个文件(有前置条件,后面讲)。
- Vendor Key / Key Seed(密钥与随机种子):决定密文用哪些公钥加密、密文形态是否可复现。
记住一个对应关系:一个文件被哪个标签页”管辖”,就按那个页的模式加密。两个页面可以同时各放一批文件、一次点 Encrypt 全部处理。
常见坑:文件放错标签页
如果你给
Encrypt module body页面添加了 VHDL 文件,或添加了带加密起止语的文件,点 Encrypt 会直接弹窗失败。加文件前先确认模式和语言匹配,详见下文两种模式的对比表。
两种加密模式:module all 与 module body
这是整个工具最重要的概念。两种模式的区别就一句话:加密的范围不同。
| 对比项 | Encrypt module all | Encrypt module body |
|---|---|---|
| 加密范围 | 文件全部内容(或仅用户标记的块) | module 端口声明以外的内容,保留端口 |
| 支持语言 | Verilog / SystemVerilog / VHDL | 仅 Verilog / SystemVerilog,不支持 VHDL |
| 带加密起止语的文件 | 支持,按用户标记加密 | 不支持,会报”起止语嵌套”错误 |
| 典型用途 | 整体保密交付 | 只公开接口签名,隐藏内部实现 |
Encrypt module all(默认页面)的逻辑是”看情况”:
- 源文件里没有加密起止语 → 对整个文件全部加密,一个字符都不留。
- 源文件里有加密起止语 → 只加密起止语标记的块,其余部分(比如端口)保持明文。
Encrypt module body 则完全不需要你在源文件里写任何起止语,工具自动识别 module 结构,把端口声明留下、其余全部加密。这在”告诉别人怎么例化、但不告诉他怎么实现”的场景下非常省事——对方拿到加密文件后,看端口就能写例化代码,仿真也能正常跑。
两种模式可以同时使用:把全加密的文件加到 all 页,把留端口的文件加到 body 页,一次点击统一加密。
块加密起止语:pragma protect 怎么写
如果不想整个文件都加密,只保护某几段核心逻辑,就用块加密:在要加密的内容前后各加一行固定格式的注释式关键字。
Verilog / SystemVerilog 的起止语长这样(注意是反引号 ` 开头,不是单引号):

module SomeModule(
...
);
`pragma protect begin
....
assign o = i;
`pragma protect end
endmodule上面这段代码加密后,begin 到 end 之间的 .... 和 assign o = i; 变成密文,而 module 头、端口、endmodule 保持明文可见。
VHDL 的起止语没有 pragma 前缀,更短:

architecture rtl of SomeModule is
`protect begin
....
`protect end
end rtl;使用起止语有三条铁律:
- 格式固定:关键字必须一字不差,写错了轻则加密行为和预期不符,重则直接报错。
- 同一个源文件里可以有多组独立的起止语,但不能嵌套。
- 多组起止语必须顺序成对出现:第一组
begin...end完整闭合后,才能开始第二组。
正误对比例子(Verilog):

正确(左图):begin → end → begin → end,两组依次闭合。
错误(右图):begin → begin → end → end,内层 begin 出现在外层 end 之前,构成嵌套,加密器会拒绝。
常见坑:起止语写在 module 外面
在
Encrypt module body模式下,工具本来就自动按 module 边界加密;如果这时源文件里还残留了加密起止语(尤其在 module 定义之外),工具会判定为”起止语嵌套使用”并弹窗 Encrypt failed。用 body 模式前,先把源码里手动加的起止语清理干净。
保存路径、Merge 与 Vendor Key 选项详解
点 Encrypt 之前,还有几组选项决定了输出文件的名字、数量和”谁能仿真它”。
Save path(保存路径)
Original path(默认):加密文件生成在源文件同目录。命名规则是在原名后追加后缀:test.v → test.enc.vp,test.sv → test.enc.svp,test.vhd → test.enc.vhdp。一眼就能区分明文和密文文件。Another path:勾选后点 Browse 指定输出文件夹,适合不想让密文和源码混在一个目录的情况。
Merge(合并输出)
勾选后,多个同语言类型文件的加密结果会按添加顺序合并进同一个输出文件,方便交付”一个文件即全部 IP”。三个限制要记住:
- 列表里至少要有 2 个及以上同语言文件,Merge 复选框才可用(否则置灰)。
- 勾选 Merge 后保存路径会自动切换为 Another path,必须指定输出目录。
- 输出文件名默认取”文件列表第一个文件的 module 名 + enc + 后缀”,你也可以手动输入自定义名字;不同语言类型之间不能 Merge。
Vendor Key(加密密钥)
加密用的是 RSA 公钥体系,密文里绑定了允许解密的工具身份。界面上 anlogic-rsa-009 是灰色的必选默认密钥,不可取消。其余可勾选的第三方仿真器密钥包括:
CDS_RSA_KEY_VER_1 (Cadence 系)
MGC-VERIF-SIM-RSA-1 (ModelSim 10.4, QuestaSim 10.4)
MGC-VERIF-SIM-RSA-2 (ModelSim 10.5, QuestaSim 10.5)
SNPS-VCS-RSA-1 (VCS 2014.03)
SNPS-VCS-RSA-2 (VCS 其他版本)要给用 ModelSim 10.4 的队友仿真,就勾上对应的 MGC-VERIF-SIM-RSA-1——密钥勾少了,对方仿真器读不了密文;需要多个环境都能仿真,可以同时勾多个。
如果内置列表里没有你要的密钥(比如自定义公钥),可以改用 TD 主界面 Console 窗口输入 TCL 命令加密:
hdl_encrypt -file "xxx" -key "anlogic-rsa-009.pubkey user.pubkey"-file:要加密的源文件,可以写多个,之间用空格分隔。-key:密钥列表,用空格分隔,必须包含anlogic-rsa-009.pubkey,其后可追加多个user.pubkey自定义公钥。
Key Seed(随机种子)
可填可不填,内容是不限长度的字符串。它的作用是控制密文的”可复现性”:
- 缺省(不填):每次加密生成的密文都不同。
- 填了固定种子:用同一个种子加密同一内容,每次得到的密文完全一致。
什么时候有用?比如你做持续集成,想校验”今天交付的密文和昨天的是不是同一份代码加密出来的”,固定种子就能让哈希比对成立。普通交付场景留空即可。
完整操作示例:从 .v 到 .enc.vp
走一遍完整流程。假设你要交付 4 个源文件:check.v、lvds_rx.v、multi_dual_top.sv、sdram_ctrl.vhd,且对方用 ModelSim 10.4 / QuestaSim 10.4 仿真。
第 1 步:添加文件。 打开 Tools → Encrypt Tool,保持默认 Encrypt module all 页面,点 Add → Add Files,把 4 个文件一起选中加入(混合语言允许)。此时列表里会显示 4 个完整路径。
第 2 步:设置密钥。 在 Vendor Key 区勾选 MGC-VERIF-SIM-RSA-1 (ModelSim 10.4, QuestaSim 10.4)。anlogic-rsa-009 已默认必选。Key Seed 留空。

第 3 步:选择保存路径。 保持 Original path,加密文件将出现在各源文件旁边。
第 4 步:点击 Encrypt。 成功会弹出加密成功提示弹窗;失败则弹加密失败弹窗,按提示回到前面几节检查(最常见:起止语嵌套、body 页放了不支持的文件)。
第 5 步:检查产物。 到源目录确认生成文件:

对照命名规则验证:.v → .enc.vp、.sv → .enc.svp、.vhd → .enc.vhdp,一个不多一个不少。
进阶:Merge 合并输出。 如果只想交付一个文件,只保留同语言的 check.v 和 lvds_rx.v(VHDL 和 SV 各自不能与它们合并),添加后勾选 Merge,输出路径自动切到 Another path,指定目录如 E:/internal/project/test_encrypt_tool/prj/enc,输出名默认 check.enc.v(可改),点 Encrypt 即可得到合并密文。

留端口的交付方式。 若希望对方能看到接口定义,改用 Encrypt module body 页面:切换标签,加入 Verilog/SV 文件(无需任何起止语),其余选项与 all 模式完全一致,点 Encrypt 后得到”端口明文、实现密文”的加密文件。

常见坑与排查
1. body 模式报”起止语嵌套”错误。
原因:Encrypt module body 不允许源文件里存在手动加密起止语(工具自动加密整段实现,再遇到起止语就判定嵌套冲突)。解决办法:切回 Encrypt module all 模式加密该文件,或删除源码中的起止语后再用 body 模式。
2. 起止语写了但没被加密。
检查三处:关键字拼写(Verilog 是 `pragma protect begin/end,VHDL 是 `protect begin/end,反引号不能少);是否嵌套(begin 里套 begin);以及多组起止语是否按 begin→end 顺序成对闭合。任何一条不满足,加密结果都会偏离预期或报错。
3. 对方拿到 .enc.vp 仿真器读不了。
多半是 Vendor Key 勾漏了。问清对方用的仿真器型号和版本:ModelSim 10.5/QuestaSim 10.5 对应 MGC-VERIF-SIM-RSA-2,VCS 2014.03 对应 SNPS-VCS-RSA-1,别勾成相邻版本。必要时用 hdl_encrypt TCL 命令追加自定义公钥重新加密。
4. Merge 复选框是灰的点不了。
确认列表里是否已有 2 个及以上同语言文件。.v 和 .sv 算不同语言类型,VHDL 更不能与它们混合 Merge。只想合并 Verilog 文件时,先把其他语言文件从列表移除。
5. 找不到加密输出文件。
先确认 Save path 选项:选了 Original path 就去源文件目录找,选了 Another path 就去 Browse 指定的目录找。再核对文件名后缀——.enc.vp/.enc.svp/.enc.vhdp,别在文件管理器里只搜 .v 把密文漏掉了。
通关标准:
- 不看手册说出三种后缀对应关系:
.v→.enc.vp、.sv→.enc.svp、.vhd→.enc.vhdp。- 能解释为什么 body 模式遇到起止语会报错,以及两种模式各自适配什么交付场景。
- 独立完成一次带第三方仿真器密钥的加密,并让队友在 ModelSim/QuestaSim 中成功引用密文文件。
Encrypt module all 和 Encrypt module body 最核心的区别是什么?
加密范围。all 模式对整个文件加密(有起止语时只加密标记块);body 模式自动保留 module 端口声明、只加密端口以外的实现,且不需要(也不允许)源文件里出现起止语。body 模式目前不支持 VHDL。
为什么同一个文件里不能嵌套使用两组加密起止语?
加密器按”顺序成对”的规则匹配 begin 和 end:遇到 begin 后必须先出现对应的 end 才允许新的 begin。嵌套(begin 里再写 begin)会让密文边界无法唯一确定,工具直接判错。正确写法是让多组起止语依次独立闭合。
Vendor Key 里灰色的 anlogic-rsa-009 能取消勾选吗?想加自定义公钥怎么办?
不能取消,它是必选默认密钥。要加自定义公钥需绕开图形界面,在 TD 主界面 Console 里执行 TCL 命令:
hdl_encrypt -file "xxx" -key "anlogic-rsa-009.pubkey user.pubkey",注意 -key 列表中必须保留 anlogic-rsa-009.pubkey。
Key Seed 留空和填固定字符串,对加密结果有什么影响?
留空(缺省)时每次加密产生的密文都不同;填入固定字符串后,同一内容用同一种子加密会得到完全一致的密文。需要校验两次交付的密文是否一致时用固定种子,一般交付留空即可。
队友用 QuestaSim 10.5,你应该勾哪个 Vendor Key?勾错了会怎样?
勾
MGC-VERIF-SIM-RSA-2 (ModelSim 10.5, QuestaSim 10.5)。勾错版本(如勾成 RSA-1)后,密文中不包含对方工具可用的公钥信息,QuestaSim 10.5 将无法解密仿真该加密文件。