Quick Start
- 准备一个简单的 Verilog 模块(如计数器),确保其仅包含
assign、always@(posedge clk)等结构。 - 打开 Vivado(或 Quartus)并创建新工程,选择目标器件(如 xc7a35t)。
- 将代码文件添加至工程,运行“Synthesis”。
- 观察综合日志:若出现
WARNING: [Synth 8-xxx] Unsupported construct或类似错误,则代码中存在不可综合结构。 - 将不可综合部分(如
initial、#delay)移至仿真文件(testbench),保留可综合部分用于顶层模块。 - 重新综合,确认无警告/错误,并查看资源使用报告(如 LUT、FF 数量)。
- 编写 testbench,用仿真验证功能正确性,确保不可综合代码仅在仿真中生效。
- 完成综合与实现,生成比特流并下载至 FPGA 板卡,观察 LED 或波形确认功能。
前置条件与环境
| 项目/推荐值 | 说明 | 替代方案 |
|---|---|---|
| 器件/板卡 | Xilinx Artix-7 (xc7a35t) 或 Altera Cyclone IV | 任何主流 FPGA(如 Lattice、Microchip) |
| EDA 版本 | Vivado 2020.1 或 Quartus Prime 20.1 | ISE、Quartus II、Yosys(开源) |
| 仿真器 | Vivado Simulator (xsim) 或 ModelSim | VCS、Icarus Verilog、Verilator |
| 时钟/复位 | 50MHz 板载时钟,低电平有效复位 | PLL 生成时钟,高电平复位 |
| 接口依赖 | LED 或 UART 用于观察输出 | 逻辑分析仪、虚拟 I/O |
| 约束文件 | XDC(Vivado)或 SDC(Quartus) | 手动引脚分配或默认约束 |
| 代码风格 | RTL 级描述(always、assign) | 行为级描述(仅仿真用) |
目标与验收标准
- 功能点:能够正确区分 Verilog 代码中哪些结构可综合、哪些不可综合;在工程中正确分离可综合与仿真代码。
- 性能指标:综合后资源使用合理(如计数器使用 100MHz 时钟时,LUT/FF 占用在预期范围内)。
- 验收方式:
- 综合日志中无
unsupported construct或not synthesizable错误。 - 仿真波形中,可综合部分的行为与预期一致(如计数器递增)。
- 上板后 LED 闪烁频率符合设计值(如 1Hz)。
- 综合日志中无
实施步骤
阶段一:工程结构设计
- 创建两个文件:
top.v(可综合模块)和tb_top.v(仿真 testbench)。 top.v中仅使用assign、always@(posedge clk)或always@(*),避免使用initial、#delay、fork/join、force/release等。tb_top.v中包含initial、$display、$monitor、#delay等,用于生成激励和检查结果。- 预期结果:综合时只添加
top.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'd0;
else
count <= count + 1'b1;
end
endmodule原因机制分析:always@(posedge clk or negedge rst_n) 是标准的同步时序描述,综合工具能将其映射为 D 触发器和复位逻辑。而 initial 和 #delay 属于行为级仿真构造,综合工具无法找到对应的硬件原语,因此会报错。
落地路径:编写可综合代码时,始终遵循“RTL 级描述”原则——用 always 块描述时序或组合逻辑,用 assign 描述连续赋值。将所有初始化、延时、文件 I/O 操作封装在 testbench 中。
风险边界:某些工具(如 Vivado)支持部分 initial 用于 RAM 初始化,但这不是通用做法。为保可移植性,建议统一将 initial 限制在仿真文件内。
阶段三:综合与验证
- 在 EDA 工具中设置
top.v为顶层模块,运行综合。 - 检查综合日志:确认无
unsupported或not synthesizable警告/错误。 - 查看资源使用报告:记录 LUT、FF、IO 等资源占用,确保在器件容量内。
- 编写 testbench,实例化
top模块,添加时钟激励和复位逻辑,运行仿真。 - 对比仿真波形与预期行为(如计数器从 0 递增至 15 后回卷)。
- 完成实现(布局布线),生成比特流,下载至 FPGA 板卡,观察 LED 闪烁频率。
验证结果
- 综合日志:无
unsupported construct或not synthesizable错误。 - 仿真波形:计数器在时钟上升沿递增,复位时清零,行为与 RTL 描述一致。
- 上板结果:LED 以 1Hz 频率闪烁(若时钟 50MHz,分频系数 25,000,000)。
排障指南
- 综合报错“Unsupported construct”:检查代码中是否包含
initial、#delay、fork/join、force/release、wait、event等结构。将这些语句移至 testbench。 - 仿真结果与上板不一致:确认 testbench 中未使用不可综合结构影响仿真行为;检查时序约束是否正确(如时钟周期、输入输出延迟)。
- 资源占用过高:检查是否意外生成了锁存器(如组合逻辑中缺少
else分支);优化代码结构,避免冗余逻辑。 - LED 不闪烁:确认时钟信号正常(用示波器或逻辑分析仪);检查复位极性是否与板卡匹配;验证分频系数计算是否正确。
扩展实践
- 状态机设计:使用
always@(posedge clk)描述状态寄存器,always@(*)描述次态逻辑和输出逻辑,确保全部可综合。 - RAM/ROM 实现:使用
reg数组描述存储器,综合工具会推断出块 RAM 或分布式 RAM。避免使用$readmemh在综合代码中初始化——应将其放在 testbench 中。 - 跨时钟域处理:使用两级同步器(
always@(posedge clk2))处理异步信号,避免使用#delay进行同步。
参考资源
- IEEE Std 1364-2001 Verilog HDL 标准(可综合子集章节)
- Vivado Design Suite 用户指南:综合 (UG901)
- Quartus Prime 手册:Verilog HDL 支持
- Yosys 开源综合工具文档(
synth_xilinx、synth_ice40等)
附录:常见不可综合结构速查表
| 结构 | 说明 | 替代方案 |
|---|---|---|
initial | 仅仿真初始化 | 在 testbench 中使用 |
#delay | 时间延迟 | 用时钟计数实现延时 |
fork/join | 并行语句块 | 用多个 always 块描述 |
force/release | 强制赋值 | 仅用于仿真调试 |
wait | 事件等待 | 用状态机实现 |
event | 事件触发 | 用信号边沿检测 |
$display / $monitor | 仿真输出 | 仅用于 testbench |
$readmemh / $writememh | 文件 I/O | 在 testbench 中初始化存储器 |



