第1章 · RTL设计基础与综合概念
各位同学好,我是老周。在芯片设计这行摸爬滚打了十几年,今天咱们来聊聊最基础但也最容易被忽略的东西——RTL 到底是什么?可综合和不可综合的代码怎么区分?综合工具到底在背后干了啥?
你可能会觉得,这些概念书上都写过。但说实话,我在项目里见过不少工程师,写了几年 Verilog,却搞不清为什么某个写法综合出来一堆奇怪的逻辑。嗯,这一章咱们就把地基打牢。
1.1 到底什么是 RTL?
RTL 全称是 Register Transfer Level,寄存器传输级。说白了,就是描述数据在寄存器之间怎么流动、怎么处理。你写的 Verilog 代码,大部分都是在做这件事:时钟沿来了,数据从寄存器 A 跑到寄存器 B,中间经过一些组合逻辑。
我个人习惯把 RTL 理解成“数字电路的乐高说明书”。你告诉工具:我要一个 D 触发器,我要一个加法器,然后连起来。工具就照着你的描述去生成真正的电路。
1.2 可综合 vs 不可综合代码
这是新手最容易踩的坑。可综合,就是综合工具能把你写的代码变成真实的门级电路。不可综合,就是工具看了直摇头——这东西我没法用硬件实现。
举个例子:
// 可综合 —— 标准的 D 触发器
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
q <= 1'b0;
else
q <= d;
end
// 不可综合 —— 用了 #10 延迟,综合工具直接报错
initial begin
#10 clk = 0;
forever #5 clk = ~clk;
end
为什么会这样?因为 #10 是仿真用的时间延迟,真实芯片里没有“等 10 纳秒”这个操作。你想想看,综合工具怎么把一个 #10 映射到晶体管上?没法弄。
initial块(除了 testbench)#delay时间延迟fork / joinwait语句- 动态数组、类、文件 I/O
- 循环次数非常量的
for/while(综合工具可能展开,但危险)
我记得有一次,团队里一个同事用 while 循环写了一个仲裁器,仿真怎么跑都正确。结果综合时工具直接卡死,因为循环次数取决于输入,工具没法确定边界。从那以后,我们规定:所有循环必须用固定次数,或者用 generate 展开。
1.3 综合工具的基本流程
综合工具(比如 Synopsys Design Compiler、Cadence Genus)到底对你的 RTL 做了什么?我把它拆成三步,简单明了:
| 步骤 | 做什么 | 输出 |
|---|---|---|
| ① 编译 (Compile) | 读入 RTL 代码,解析语法,建立内部数据库 | GTECH 网表(通用逻辑门) |
| ② 优化 (Optimize) | 逻辑化简、资源共享、时序优化、面积优化 | 优化后的逻辑网表 |
| ③ 映射 (Mapping) | 将通用门映射到目标工艺库(比如台积电 7nm) | 门级网表 (Netlist) |
说白了,第一步是“读懂你的代码”,第二步是“想办法让它更快更小”,第三步是“换成真正的标准单元”。
嗯,这一章的内容就是这些。RTL 基础、可综合与不可综合的界限、综合工具的三步走,都是后面所有章节的基石。你把这些搞明白,后面学 Lint 检查、综合约束才会顺手。