什么是 可综合 和 不可综合
概要:本文介绍了 Verilog 语言中“可综合”和“不可综合”两个重要概念,解释了综合的定义、流程及其输入输出,并深入探讨了哪些 Verilog 代码结构可以被综合工具转换为实际硬件电路,以及哪些代码仅用于仿真不可综合。文章还列举了具体示例,帮助读者掌握可综合代码的编写规范。
1. 什么是综合(Synthesis)
综合(Synthesis)是将较高层次的设计描述(通常是寄存器传输级 RTL 代码,用 Verilog 或 VHDL 编写),通过专门的软件工具,自动转换成较低层次的、面向特定工艺的门级网表的过程。
- 输入:RTL 代码,描述了数字电路的功能,如模块、寄存器、组合逻辑(如 if-else、case 语句)等。
- 输出:门级网表,由基本逻辑单元(如与门、或门、非门、触发器、查找表 LUT、RAM 等)及其连接关系构成的电路图,针对特定 FPGA 芯片(如 Xilinx Artix-7 或 Intel Cyclone 10)。
- 工具:综合器软件,如 Vivado(Xilinx/AMD)、Quartus(Intel)、Synopsys Synplify 等。
2. 可综合 vs. 不可综合
2.1 核心区别
- 可综合:Verilog 代码能够被综合工具转换为等效的门级网表,可用于 FPGA 或 ASIC 硬件实现。
- 不可综合:Verilog 代码仅用于仿真,无法被综合工具转换为实际硬件结构。
2.2 为什么会有这个区别?
- Verilog 既是一种硬件描述语言,也是硬件验证语言。
- 仿真器支持更高抽象层次和调试功能,因此允许使用复杂语法。
- 综合工具目标是生成可实现的物理电路,因此只能识别能映射为实际硬件结构的代码。
3. 可综合代码的特点
- 描述的是寄存器传输级(RTL)行为。
- 常见结构:
- 使用
always块(组合逻辑或时序逻辑) - 使用
assign连续赋值语句 - 使用
module实例化其他模块或库元件
- 使用
always块中的写法:- 时序逻辑:非阻塞赋值
<=,敏感列表包含posedge clk或negedge clk(可能还有复位信号) - 组合逻辑:阻塞赋值
=,敏感列表包含所有读取的输入信号或使用*
- 时序逻辑:非阻塞赋值
- 条件语句需要完备,否则可能推断出锁存器
- 运算符如
+,-,*,&,|,^,>>,<<等通常可综合,但复杂运算如除法可能依赖目标器件支持 - 有限状态机(FSM)通常可综合
- RAM/ROM 描述需要使用特定方式或调用 IP 核
4. 不可综合代码的示例
以下是一些常见的不可综合 Verilog 代码结构:
- 时间控制语句:如
#10 a = b;,硬件中无法实现精确内部延时 - Initial 块:如
initial begin ... end,用于仿真初始化 - 仿真系统任务:如
$display,$monitor,$write,$finish,$stop,$random,$time - Force/Release:如
force,release - 事件控制(非时钟沿):如
wait(event) - While/Forever 循环(无退出条件或依赖仿真时间)
- 文件 I/O 操作:如
$fopen,$fwrite,$fclose - 纯行为级建模:过于抽象,无法映射到具体硬件结构
5. 关键点总结
- 设计意图:用于硬件实现的代码(RTL)必须遵循可综合编码规范
- 验证代码:Testbench 通常包含不可综合代码,这是正常且必要的
- 工具依赖:不同综合工具或目标器件支持的可综合子集可能不同,应参考相应文档
留下评论