2、RTL综合基础:Yosys的基本使用,从Verilog到网表的综合流程
好,咱们开始聊综合。说实话,很多刚入行的朋友觉得综合就是“点一下按钮,Verilog变网表”。嗯,没那么简单,但也没那么玄乎。今天我就带大家用Yosys走一遍这个流程。Yosys是个开源工具,功能很强大,我个人特别喜欢它的透明性——每一步干了什么,你都能看得清清楚楚。
2.1 综合到底在做什么?
综合说白了,就是把你的RTL代码(Verilog/VHDL)翻译成逻辑门级别的连接网表。你写的是 assign c = a & b;,综合工具就给你放一个AND门。但实际项目里哪有这么简单?你想想看,一个芯片里几百万个门,工具得考虑时序、面积、功耗……
我在项目中遇到过最头疼的事:RTL仿真跑得好好的,综合完网表仿真就挂了。后来发现是综合时某个信号被优化掉了。所以理解综合流程,能帮你少走很多弯路。
2.2 Yosys的安装与启动
Yosys安装很简单,Linux下直接:
git clone https://github.com/YosysHQ/yosys.git
cd yosys
make
sudo make install
装好后,终端输入 yosys 就能进入交互模式。你会看到类似这样的提示符:
Yosys 0.33 (git sha1 1234567, g++ 11.3.0 -fPIC -O3)
-->
我个人习惯用脚本模式,也就是写一个.tcl文件,然后 yosys -s script.tcl 跑。这样方便重复使用,也容易版本管理。
2.3 一个最简单的综合流程
咱们先看一个最简单的例子。假设你有一个计数器模块 counter.v:
module counter (
input clk,
input rst_n,
output reg [3:0] count
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
count <= 4'b0;
else
count <= count + 1'b1;
end
endmodule
对应的Yosys综合脚本 syn_counter.tcl:
# 读取设计文件
read_verilog counter.v
# 层次化展开(把模块实例化展开)
hierarchy -check -top counter
# 预处理(比如宏展开、注释去除)
proc
# 优化(常量传播、死逻辑消除)
opt
# 技术映射到标准单元库(这里用内置的通用库)
techmap
# 输出网表
write_verilog counter_synth.v
跑一下:
yosys -s syn_counter.tcl
你就会得到一个 counter_synth.v,里面全是 $and、$ff 之类的通用门级原语。嗯,这里要注意:Yosys默认用的是自己的通用库,不是某个工艺库。真要流片,你得换成厂商的Liberty库。
2.4 关键命令详解
咱们拆开看看每个命令到底干了什么。
| 命令 | 作用 | 我的经验 |
|---|---|---|
read_verilog |
读入Verilog文件 | 支持SystemVerilog的部分语法,但别太花哨 |
hierarchy |
检查并展开模块层次 | 我经常用 -check 参数,能发现未定义模块 |
proc |
将always块转换为逻辑表达式 | 这一步会把时序逻辑和组合逻辑分开处理 |
opt |
逻辑优化 | 比如 assign a = b & 1'b1 会被优化成 a = b |
techmap |
技术映射 | 把通用门映射到目标库的门 |
write_verilog |
输出网表 | 可以输出成.edif格式,方便其他工具读 |
show 命令,Yosys会生成一个图形化的电路图(需要Graphviz支持)。我调试复杂设计时,经常用这个来看优化前后的变化。
2.5 避坑指南:综合中常见的“陷阱”
我曾经在一个项目里,综合出来的网表面积比预期大了30%。查了半天,发现是RTL里写了一个 always @(*) 的敏感列表不完整,导致综合工具推断出了锁存器。嗯,锁存器这东西,能不用就别用。
还有一次,同事的代码里写了 for (i=0; i<100; i=i+1),综合工具直接展开了100份硬件。你想想看,一个简单的循环,面积直接爆炸。所以写RTL时,脑子里要时刻想着“这会被综合成什么电路”。
#10 延时、initial 块里的循环,它都能读进去,但综合出来的网表可能完全不是你想要的。建议综合前先用 verilog -lint 做一次语法检查。
2.6 进阶:使用工艺库进行综合
真正做项目时,你得用厂商的工艺库。假设你有一个 my_lib.lib,里面定义了各种标准单元(AND门、DFF等)的时序和面积信息。Yosys的流程会变成:
# 读取工艺库
read_liberty -lib my_lib.lib
# 读取设计
read_verilog counter.v
hierarchy -check -top counter
proc
opt
# 使用工艺库进行技术映射
dfflibmap -liberty my_lib.lib
abc -liberty my_lib.lib
# 优化
opt
# 输出带工艺信息的网表
write_verilog counter_synth_tech.v
这里 abc 是Yosys集成的逻辑综合工具,它会把通用门映射到工艺库里的具体单元。我建议你多试试不同的 abc 参数,比如 -D 1000 设置延迟目标,-area 让工具优先优化面积。
2.7 综合后的检查
综合完不是就完事了。我一般会做三件事:
- 检查网表语法:用
read_verilog再读一遍输出的网表,确保没有语法错误。 - 逻辑等价性检查:用
yosys -m equiv模块,对比综合前后的逻辑是否一致。这一步能发现很多优化引入的问题。 - 面积和时序报告:用
stat命令看面积,用report_timing看时序(需要工艺库支持)。
核心要点: 综合不是黑盒子。Yosys让你能看到每一步的中间结果,这是它最大的价值。我建议初学者多跑几次,每次只加一个命令,看看电路怎么一步步从RTL变成门级网表。
好了,这一章就到这里。下一章咱们聊聊综合后的网表怎么进行形式验证,确保你的逻辑没被工具“优化”坏掉。记住,工具只是工具,理解它背后的原理,你才能真正用好它。