少于 1 分钟阅读 次阅读

概要:本文介绍了 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 clknegedge 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 通常包含不可综合代码,这是正常且必要的
  • 工具依赖:不同综合工具或目标器件支持的可综合子集可能不同,应参考相应文档

标签:

分类:

更新时间:

留下评论