当前位置: 首页 > news >正文

[SystemVerilog] Clocking

SystemVerilog Clocking用法详解

SystemVerilog 的 clocking 块(Clocking Block)是一种专门用于定义信号时序行为的构造,主要用于验证环境(如 UVM)中,以精确控制信号的采样和驱动时序。clocking 块通过将信号与特定时钟关联,简化了测试环境中对时序敏感信号的处理,减少了手动时序管理的复杂性。本文将详细介绍 SystemVerilog 中 clocking 块的各种用法,包括基本定义、输入输出信号、时序控制、接口中的使用、以及在验证中的应用,并提供示例代码和最佳实践。

1. Clocking 块概述

clocking 块是 SystemVerilog 中用于封装信号与时钟关系的构造,通常定义在 interface 或模块中。它的主要功能是:

  • 信号采样与驱动:定义信号相对于时钟的采样和驱动时序。
  • 时序抽象:屏蔽底层时序细节,简化测试用例开发。
  • 验证支持:在验证环境中(如 UVM)提供标准化的时序控制接口。
  • 避免竞争:通过明确的采样和驱动时间点,减少仿真中的竞争与冒险。

主要用途

  • 在验证环境中精确控制信号的采样和驱动。
  • 简化测试环境中对 DUT(待测设计)的时序交互。
  • interface 结合,提供模块化的时序接口。

基本语法

clocking clocking_name @(clock_event);input input_signal;output output_signal;
endclocking
  • clocking_name:时钟块的名称。
  • clock_event:触发时钟块的时钟事件(如 @(posedge clk))。
  • input_signal:输入信号,定义采样时序。
  • output_signal:输出信号,定义驱动时序。

2. 基本 Clocking 块定义与使用

clocking 块通过指定信号的采样和驱动时序,简化了验证代码的编写。

示例:基本 Clocking 块

module top;logic clk = 0;logic [7:0] data;logic valid;// 定义 clocking 块clocking cb @(posedge clk);input data;input valid;endclocking// 测试逻辑initial beginforever #5 clk = ~clk;endinitial begin@(cb); // 等待 clocking 块的时钟边沿if (cb.valid)$display("Sampled data: %h", cb.data);end
endmodule

说明

  • clocking cb 定义了一个时钟块,基于 clk 的上升沿。
  • input datainput valid 指定信号在时钟上升沿前采样。
  • 测试逻辑通过 cb.datacb.valid 访问同步信号。

优点

  • 信号采样自动与时钟边沿对齐,避免手动时序控制。
  • 提高了代码的可读性和可维护性。

3. 输入与输出信号的时序控制

clocking 块支持通过 inputoutput 关键字定义信号的采样和驱动时序,并可以通过延迟指定具体的时序偏移。

3.1 输入信号采样

input 信号在时钟边沿前采样,默认采样时间点为时钟边沿前的非阻塞赋值(NBA)区域。可以通过 input #delay 指定采样延迟。

3.2 输出信号驱动

output 信号在时钟边沿后驱动,默认驱动时间点为时钟边沿后的非阻塞赋值区域。可以通过 output #delay 指定驱动延迟。

示例:带时序延迟的 Clocking 块

interface simple_bus (input logic clk);logic [7:0] data;logic valid;logic ready;clocking cb @(posedge clk);input #1ns data, valid; // 采样延迟 1nsoutput #2ns ready;     // 驱动延迟 2nsendclocking
endinterfacemodule receiver (simple_bus bus);always @(bus.cb) beginbus.cb.ready <= 1; // 在时钟边沿后 2ns 驱动 readyif (bus.cb.valid)$display("Received data: %h", bus.cb.data);end
endmodulemodule top;logic clk = 0;always #5 clk = ~clk;simple_bus bus_inst(.clk(clk));receiver u_receiver (.bus(bus_inst));initial beginbus_inst.data = 8'hA5;bus_inst.valid = 1;#20 $finish;end
endmodule

说明

  • input #1ns 表示 datavalid 在时钟上升沿前 1ns 采样。
  • output #2ns 表示 ready 在时钟上升沿后 2ns 驱动。
  • 模块通过 bus.cb 访问同步信号。

注意

  • 延迟值必须为非负,且在仿真中有效(综合通常忽略)。
  • 延迟值应根据 DUT 的时序要求设置。

4. Clocking 块与 Interface 的结合

clocking 块通常定义在 interface 中,与信号和 modport 结合,提供模块化的时序接口。

示例:接口中的 Clocking 块

interface simple_bus (input logic clk);logic [7:0] data;logic valid;logic ready;clocking cb @(posedge clk);input data, valid;output ready;endclockingmodport slave (input data, valid,output ready);
endinterfacemodule receiver (simple_bus.slave bus);always @(bus.cb) beginbus.cb.ready <= 1;if (bus.cb.valid)$display("Received data: %h", bus.cb.data);end
endmodulemodule top;logic clk = 0;always #5 clk = ~clk;simple_bus bus_inst(.clk(clk));receiver u_receiver (.bus(bus_inst));initial beginbus_inst.data = 8'hA5;bus_inst.valid = 1;#20 $finish;end
endmodule

说明

  • clocking cb 定义在 interface 中,与接口信号关联。
  • receiver 模块通过 bus.cb 访问同步信号。
  • modport slave 定义了信号方向,增强接口的模块化。

优点

  • 将时序控制与信号封装结合,简化验证代码。
  • 支持模块化的 DUT 和测试环境连接。

5. 多时钟 Clocking 块

clocking 块支持定义多个时钟块,用于处理多时钟域的信号。

示例:多时钟 Clocking 块

interface multi_clock_bus (input logic clk1, clk2);logic [7:0] data;logic valid;clocking cb1 @(posedge clk1);input data, valid;endclockingclocking cb2 @(posedge clk2);input data, valid;endclocking
endinterfacemodule monitor (multi_clock_bus bus);always @(bus.cb1) beginif (bus.cb1.valid)$display("clk1 domain: data = %h", bus.cb1.data);endalways @(bus.cb2) beginif (bus.cb2.valid)$display("clk2 domain: data = %h", bus.cb2.data);end
endmodulemodule top;logic clk1 = 0, clk2 = 0;always #5 clk1 = ~clk1;always #7 clk2 = ~clk2;multi_clock_bus bus_inst(.clk1(clk1), .clk2(clk2));monitor u_monitor (.bus(bus_inst));initial beginbus_inst.data = 8'hA5;bus_inst.valid = 1;#50 $finish;end
endmodule

说明

  • cb1cb2 分别基于 clk1clk2 定义时钟块。
  • monitor 模块在不同时钟域中采样信号。
  • 支持多时钟域验证。

注意

  • 确保时钟信号正确连接到接口。
  • 在多时钟域中,注意信号的跨时钟域处理。

6. Clocking 块在验证中的应用

clocking 块在验证环境(如 UVM)中广泛使用,用于连接 DUT 和测试环境,提供标准化的时序接口。

示例:UVM 验证中的 Clocking 块

interface simple_bus (input logic clk);logic [7:0] data;logic valid;logic ready;clocking cb @(posedge clk);input data, valid;output ready;endclocking
endinterfacemodule dut (simple_bus bus);always @(posedge bus.clk) beginif (bus.valid && bus.ready)$display("DUT received: %h", bus.data);end
endmoduleprogram testbench;import uvm_pkg::*;`include "uvm_macros.svh"logic clk = 0;always #5 clk = ~clk;simple_bus bus_if(.clk(clk));initial begin// 设置 UVM 接口uvm_config_db#(virtual simple_bus)::set(null, "*", "bus_if", bus_if);run_test();end
endprogram

说明

  • simple_bus 包含 clocking cb,为测试环境提供同步信号访问。
  • UVM 测试环境通过 uvm_config_db 获取虚拟接口。
  • dut 通过接口与测试环境交互。

优点

  • 简化了 UVM 驱动器和监视器的时序控制。
  • 提供标准化的信号访问接口。

7. Clocking 块的高级用法

7.1 默认时钟块

可以使用 default clocking 指定默认的时钟块,简化代码中的时序引用。

interface simple_bus (input logic clk);logic [7:0] data;logic valid;clocking cb @(posedge clk);input data, valid;endclockingdefault clocking cb; // 设置默认时钟块
endinterfacemodule monitor (simple_bus bus);always @(*) beginif (valid) // 直接引用信号,等效于 bus.cb.valid$display("Data: %h", data);end
endmodule

说明

  • default clocking cbcb 设置为默认时钟块。
  • 信号可以直接引用(如 valid),等效于 bus.cb.valid

注意

  • 默认时钟块在复杂接口中可能降低可读性,谨慎使用。

7.2 动态时序调整

clocking 块支持在仿真中动态调整时序(通过属性),但主要用于验证。

interface simple_bus (input logic clk);logic [7:0] data;logic valid;clocking cb @(posedge clk);input #1step data, valid; // 使用 1step 采样endclocking
endinterface

说明

  • #1step 表示在时钟边沿前的最小时间步长采样。
  • 适合需要精确时序控制的验证场景。

8. 注意事项与最佳实践

  1. 时序定义

    • 确保采样和驱动延迟与 DUT 的时序要求一致。
    • 避免过大的延迟值,以免影响仿真性能。
  2. 接口结合

    • clocking 块定义在 interface 中,与信号和 modport 结合。
    • 使用 modport 明确信号方向,增强模块化。
  3. 验证环境

    • 在 UVM 中,使用虚拟接口传递 clocking 块。
    • 结合 clocking 块简化驱动器和监视器的开发。
  4. 综合限制

    • clocking 块主要用于验证,不支持综合。
    • 确保 DUT 代码不依赖 clocking 块。
  5. 多时钟域

    • 为每个时钟域定义独立的 clocking 块。
    • 注意跨时钟域信号的同步。
  6. 代码可读性

    • clocking 块和信号提供清晰的命名。
    • 添加注释说明采样和驱动时序。
  7. 调试与验证

    • 使用仿真工具验证 clocking 块的时序行为。
    • 检查采样和驱动时间点是否符合预期。

9. 总结

SystemVerilog 的 clocking 块是一种强大的验证工具,用于定义信号的采样和驱动时序,简化测试环境的时序管理。通过基本定义、输入输出信号、时序控制、接口结合、多时钟支持等功能,clocking 块在 UVM 等验证环境中发挥了关键作用。特别是在复杂设计中,clocking 块与 interface 的结合提供了模块化的时序接口,显著提高了验证效率和代码质量。遵循最佳实践并根据具体场景选择合适的 clocking 用法,能够有效提升验证的可靠性和可维护性。

10. 设计工具推荐

  • SZ901
    SZ901 是一款基于XVC协议的FPGA网络下载器。
    • 最高支持53M
    • 支持4路JTAG独立使用
    • 支持端口合并
    • 支持国产FLASH烧写
    • 下载器无限扩展
    • 配备专属程序固化软件,一键烧写,能大大减小程序固化时间!

相关文章:

  • 2软考系统架构设计师:第一章系统架构概述 - 练习题附答案及超详细解析
  • 基于libdxfrw库读取样条曲线并离散为点
  • DHCP配置文件详解
  • FreeRTOS事件标志组详解:高效的任务间通知机制
  • 区分PROJECT_SOURCE_DIR, CMAKE_SOURCE_DIR,CMAKE_CURRENT_SOURCE_DIR
  • windows下查看idea运行的进程占的JVM情况工具
  • Agent2Agent
  • 校平机:金属板材加工的核心设备
  • x86系列CPU寄存器和汇编指令总结
  • Kettle学习
  • VSCode远程登录云服务器并设置免密登录全攻略
  • LeetCode --- 446 周赛
  • 2.4.5goweb项目上传到csdn的git仓库
  • Eigen的主要类及其功能
  • 《数据库系统工程师》-B站-视频截图整理-2021-23
  • JavaScript原生实现简单虚拟列表(列表不定高)
  • 【数据结构刷题】顺序表与ArrayList
  • 2025.04.26-美团春招笔试题-第一题
  • 使用 LangGraph 和 Elasticsearch 构建强大的 RAG 工作流
  • JDBC数据库操作中如何保证最后关闭了所占用的资源——try用法的细节控制
  • 最长3个月免费住宿,南昌人才驿站(洪漂驿站)申请指南发布
  • 叙利亚多地遭以色列空袭
  • 准85后青海海北州副州长、州公安局局长李贤荣挂职临沂市副市长
  • 华尔兹转岗与鲁比奥集权:特朗普政府人事震荡背后的深层危机
  • 太空飞梭项目起火,南宁方特东盟神画:明火已扑灭,无人受伤
  • 铁路12306回应“五一前大量放票”传闻:个别方向和区段出现新增票额,均即时进入系统重新发售