FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
登录
首页-技术文章/快讯-技术分享-正文

FPGA仿真中时钟与复位信号的正确生成方法

二牛学FPGA二牛学FPGA
技术分享
6小时前
0
0
4

Quick Start

  • 步骤1:创建仿真工程目录,包含顶层测试文件 tb_top.sv 和待测模块文件 dut.v。
  • 步骤2:在 tb_top.sv 中定义时钟周期参数 `CLK_PERIOD = 10ns`(对应100 MHz)。
  • 步骤3:使用 `always` 块生成时钟:always #(CLK_PERIOD/2) clk = ~clk;
  • 步骤4:定义复位信号,使用 `initial` 块实现同步或异步复位:initial begin rst_n = 0; #100ns rst_n = 1; end
  • 步骤5:实例化 DUT,连接时钟和复位端口。
  • 步骤6:编写激励逻辑(如数据输入、使能信号),在复位释放后开始驱动。
  • 步骤7:运行仿真(如 Vivado Simulator 或 ModelSim),观察波形中时钟周期稳定、复位时序正确。
  • 步骤8:验收:时钟占空比50%,无毛刺;复位释放后 DUT 状态机进入 IDLE 状态。

前置条件与环境

项目/推荐值说明替代方案
器件/板卡Xilinx Artix-7 (XC7A35T) 或等效Altera Cyclone IV;仿真无需板卡
EDA 版本Vivado 2022.2 或 ModelSim SE-64 10.7QuestaSim、VCS、iverilog(开源)
仿真器Vivado Simulator (xsim)ModelSim、QuestaSim、Verilator
时钟/复位主时钟 100 MHz;低电平有效异步复位可改用 PLL 生成多相时钟;同步复位
接口依赖无外部接口,纯 RTL 仿真可加入 AXI VIP 或 UART 模型
约束文件仿真无需 XDC,仅需 RTL 和 testbench综合时需 XDC 定义时钟周期

目标与验收标准

功能点:在仿真环境中正确生成时钟和复位信号,确保 DUT 在复位释放后能稳定工作。

性能指标:时钟频率误差 < 1%,占空比 50% ± 5%。

资源/Fmax:仿真不涉及资源,但时钟周期应匹配设计目标(例如 10 ns)。

关键波形/日志

  • 时钟波形:上升沿和下降沿时间点准确,无毛刺或额外跳变。
  • 复位信号:在 0 ns 时有效,持续 100 ns 后释放,释放时刻不在时钟边沿附近(避免亚稳态)。
  • 仿真日志:显示“Reset released at time 100 ns”或类似消息。

实施步骤

工程结构

创建以下文件结构:

sim/
├── tb_top.sv          # 顶层测试文件
├── dut.v              # 待测模块(例如计数器)
├── run_sim.tcl        # 仿真运行脚本(可选)
└── waves.do           # 波形配置文件(可选)

所有文件放在同一目录下,避免路径问题。

关键模块:时钟生成

在 tb_top.sv 中,使用参数化时钟生成

parameter real CLK_PERIOD = 10.0; // 单位 ns,对应 100 MHz
reg clk;
initial begin
    clk = 0;
    forever #(CLK_PERIOD/2.0) clk = ~clk;
end

注意:使用 forever 确保时钟持续运行;initial 块中先赋初值 0,避免未知状态。

关键模块:复位生成

低电平有效异步复位:

reg rst_n;
initial begin
    rst_n = 0;          // 复位有效
    #(100.0);           // 保持 100 ns
    rst_n = 1;          // 释放复位
    $display("Reset released at time %0t", $time);
end

注意:复位释放时间应避开时钟上升沿(例如在时钟下降沿后释放),避免 DUT 中寄存器采样到亚稳态。可在时钟下降沿后 1 ns 释放:@(negedge clk); #1; rst_n = 1;

时序/CDC/约束

仿真阶段无需时序约束,但需注意:

  • 如果 DUT 包含跨时钟域(CDC)逻辑,仿真中应添加同步器模型(如两级触发器),并检查亚稳态传播。
  • 时钟生成中避免使用 #0 延迟,这会导致仿真事件竞争。

验证

编写自检测试:

initial begin
    wait(rst_n == 1);   // 等待复位释放
    @(posedge clk);
    // 发送激励并检查输出
    // 使用 assert 或 $error
end

运行仿真后,检查波形中时钟和复位信号是否符合预期。

上板(如适用)

仿真通过后,上板测试时需确保板级时钟(如晶振)频率与仿真一致,复位按键或上电复位电路行为与 testbench 匹配。

常见坑与排查

  • 坑1:时钟生成中忘记赋初值,导致时钟初始为 X。修复:在 initial 中先赋值 clk = 0
  • 坑2:复位释放与时钟边沿对齐,导致 DUT 中寄存器采样到复位值或非复位值的不确定状态。修复:在时钟边沿后延迟释放。
  • 坑3:使用 always 块生成时钟时未加 forever,导致时钟只跳变一次。修复:确保使用 foreveralways 块。

原理与设计说明

为什么使用参数化时钟周期? 参数化允许在仿真中快速更改频率,无需修改多处代码。例如验证不同时钟频率下的时序裕量。

为什么复位释放要避开时钟边沿? 仿真中如果复位释放时刻与时钟上升沿重合,DUT 中的寄存器可能同时看到复位释放和时钟采样,导致仿真不确定性(竞争)。实际硬件中复位释放是异步的,但仿真需要显式避免这种竞争。

资源 vs Fmax 权衡:仿真不涉及资源,但时钟生成方法影响仿真性能。使用 forever 块比 always 块更高效,因为 foreverinitial 中只执行一次,而 always 会重复触发。

易用性 vs 可移植性:使用 SystemVerilog 的 real 类型参数可提高精度,但若需兼容旧版 Verilog,应使用 integertimescale 指令。例如:`timescale 1ns/1ps 配合 #(CLK_PERIOD/2)

验证与结果

测量项预期值实际值(示例)条件
时钟频率100 MHz100.00 MHzCLK_PERIOD = 10 ns
时钟占空比50%50.0%仿真精度 1 ps
复位持续时间100 ns100.0 ns从 0 ns 到 100 ns
复位释放与时钟边沿间隔> 0 ns1 ns(在下降沿后)使用 @(negedge clk); #1

测量条件:Vivado Simulator,timescale 1ns/1ps,仿真时长 1 us。

故障排查(Troubleshooting)

  • 现象:时钟波形为 X 或 Z。
    原因:未初始化 reg 或驱动冲突。
    检查点:确认 initial 中赋值 clk = 0;检查是否有多个驱动源。
    修复:在 testbench 中只驱动一次时钟。
  • 现象:复位释放后 DUT 状态机仍处于复位状态。
    原因:复位信号未正确连接到 DUT 的复位端口。
    检查点:查看 DUT 实例化中端口连接是否匹配。
    修复:检查端口名和位宽。
  • 现象:仿真运行极慢。
    原因:时钟频率过高或仿真器精度设置过大。
    检查点:检查 timescale 和时钟周期。
    修复:降低时钟频率或使用 timescale 1ns/1ns 减少精度。
  • 现象:复位释放后立即出现 X 状态。
    原因:复位释放与时钟边沿竞争。
    检查点:查看波形中复位释放时刻是否在时钟上升沿。
    修复:在时钟下降沿后延迟释放。
  • 现象:时钟占空比不是 50%。
    原因CLK_PERIOD/2 计算为整数除法。
    检查点:确认 CLK_PERIOD 类型为 real 或使用浮点运算。
    修复:定义为 real 或使用 #(5.0) 硬编码。
  • 现象:仿真日志无输出。
    原因$display 未执行或仿真时间不足。
    检查点:检查 initial 块是否被 wait 阻塞。
    修复:添加 $display 在复位释放后立即执行。
  • 现象:多个时钟域时,时钟相位不对齐。
    原因:未使用相位参数。
    检查点:检查各时钟的 initial 块起始时间。
    修复:使用 #0@(posedge clk_ref) 同步起始。
  • 现象:仿真中时钟出现毛刺。
    原因:在 always 块中使用 #0 延迟。
    检查点:检查代码中是否有 #0 赋值。
    修复:移除 #0,使用 foreveralways 块。

扩展与下一步

  • 参数化时钟生成:支持多时钟域,使用数组或 generate 块生成多个时钟。
  • 加入复位毛刺检测:在 testbench 中添加断言,检查复位释放后是否被意外拉低。
  • 跨平台兼容:使用 ifdef 区分不同仿真器(如 VCS vs ModelSim)的时序精度。
  • 加入断言与覆盖:使用 SystemVerilog Assertion (SVA) 检查时钟和复位时序。
  • 形式验证:使用形式验证工具(如 JasperGold)检查复位释放后的状态机收敛性。

参考与信息来源

  • IEEE Std 1800-2017: SystemVerilog Language Reference Manual
  • Xilinx UG900: Vivado Design Suite User Guide: Logic Simulation
  • Mentor Graphics: ModelSim User’s Manual
  • Clifford E. Cummings: “Clock and Reset Generation in SystemVerilog” (SNUG 2006)

技术附录

术语表

  • Testbench: 测试平台,用于生成激励并验证 DUT。
  • DUT: Design Under Test,待测设计。
  • CDC: Clock Domain Crossing,跨时钟域。
  • SVA: SystemVerilog Assertion,断言。

检查清单

  • 时钟 reg 已初始化。
  • 时钟周期参数化。
  • 复位释放避开时钟边沿。
  • 仿真日志包含关键时间点。
  • 波形中无 X 或 Z 状态。

关键约束速查

`timescale 1ns/1ps   // 时间单位/精度
parameter real CLK_PERIOD = 10.0; // 时钟周期
initial clk = 0;
always #(CLK_PERIOD/2.0) clk = ~clk;
initial begin
    rst_n = 0;
    #(100.0);
    @(negedge clk); #1; // 避开上升沿
    rst_n = 1;
end
标签:
本文原创,作者:二牛学FPGA,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/36931.html
二牛学FPGA

二牛学FPGA

初级工程师
这家伙真懒,几个字都不愿写!
56617.33W3.93W3.67W
分享:
成电国芯FPGA赛事课即将上线
基于FPGA的实时Sobel边缘检测设计指南:实现与优化
基于FPGA的实时Sobel边缘检测设计指南:实现与优化上一篇
Vivado Block Design与RTL设计协同开发实战指南下一篇
Vivado Block Design与RTL设计协同开发实战指南
相关文章
总数:606
数字IC前端工程师校招笔试面试核心考点解析与备考实施指南

数字IC前端工程师校招笔试面试核心考点解析与备考实施指南

本文旨在为有志于投身数字集成电路前端设计领域的应届毕业生,提供一份聚焦2…
技术分享
13天前
0
0
28
0
FPGA静态时序分析(STA)实践指南:建立时间与保持时间的设计验证

FPGA静态时序分析(STA)实践指南:建立时间与保持时间的设计验证

本文旨在为FPGA设计者提供一套关于静态时序分析(StaticTimi…
技术分享
5天前
0
0
10
0
从校园到职场:FPGA、嵌入式、单片机赛道对应的企业岗位与核心技能树

从校园到职场:FPGA、嵌入式、单片机赛道对应的企业岗位与核心技能树

本文旨在为电子、计算机、自动化等相关专业的在校生及初入职场者,提供一份关…
技术分享
4天前
0
0
15
0
评论表单游客 您好,欢迎参与讨论。
加载中…
评论列表
总数:0
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
没有相关内容