clocking时钟块消除采样时信号竞争 —SV,systemverilog

采样时发生竞争delta cycle的存在),会导致采样数据错误。为了避免在RTL仿真中发生信号竞争的问题,建议通过非阻塞赋值或者特定的信号延迟来解决同步问题。这里我们介绍使用时钟块来决定信号的驱动和采样的方式。

什么是delta cycle?

在RTL仿真时,由于无法确定具体电路的延迟时间,默认情况下时钟驱动电路时会添加一个无限最小的时间(delta cycle)的延迟,这个延迟要比最小时间单位精度还要小(可以理解成远小于1ps)。
在一个时间片(time - slot)中可以发生很多的事,例如在仿真时输入run0,即让仿真器运行一个delta-cycle的时间。
由于各种可能性,clk与被采样数据之间如果只存在若干个delta-cycle的延迟,那么采样就会出问题。
例如下代码:

`timescle 1ns/1ns
module tb;
input clk1,clk2;
outout d1;
reg d1;
//产生clk1的时钟周期
initail begin 
	forever #5 clk1 <= !clk1;
end
always@(clk1)   clk2  <= clk1;  // 非阻塞赋值另一个时钟
always@(postedge clk1 )   d1 <= d1 + 1;
endmodule

如果在45ns处,clk1在上升沿处采样的得到d1的值为1,那么clk2在45ns处,采样得到d1的值应该是多少?
表面上看clk1和clk2是同周期变化的时钟信号,我们可能认为在clk1和clk2上升沿采样的结果都是相同的。
但**实际clk1与clk2之间相差一个delta cycle时间片,**也就是clk2要滞后于clk1一个delta cycle的时间, 这就产生了两种不同的采样结果

  • 当仿真器在45ns + 0(delta cycle)处采样,clk1 = 1, clk2 = 0, d1 = 1; 【仿真器采样会取到的d1 = 1
  • 当仿真器在45ns + 1(delta cycle)处采样,clk1 = 1, clk2 = 1, d1 = 2;

也就是说,要想采样真实,需要仿真器在45ns后一点点区域去采样,而不能在45ns处采样

注:如何在EDA工具中看到delta cycle?
将时间轴选在clk1在45ns处的上升沿变化处,打开工具栏expanded time deltas mode --> expanded time at active cursor,就可以看到仿真器的delta cycle

采用clocking时钟块

clocking块基于时钟周期对信号进行驱动或者采样的方式,可以使testbench准确及时地对信号驱动或采样,消除信号竞争的问题。

clocking bus@(posedge clk); //在clk上升沿来驱动和采样
	//在clk上升沿的前2ns对其进行输入采样,在事件的后2ns进行输出驱动
    default input #2ns output #2ns 
endclocking

注意:

  • 如果不使用 default 指定的 input 和 output 的 skew,sv默认指定的 input skew为 1step,output skew 为0。 input skew 和 output skew 如下图所示,
    在这里插入图片描述
  • 如果input 的skew 是 1step,所采样的值是时钟事件发生前最后末尾(Postponed区域)。
  • 如果直接指定default input #0 ,这会在相应地时钟事件发生的 time slot 的Observed区域采样。
  • 如果直接指定default output #0 ,会作为非阻塞事件,在NBA区域进行采样。

一般在接口中定义clocking块,如下:

interface chnl_intf(input clk, input rstn);
  logic [31:0] ch_data; 
  logic        ch_valid;
  logic        ch_ready;
  logic [ 5:0] ch_margin;
  // 定义时钟块
  clocking drv_ck @(posedge clk);
  	//采样时间
    default input #1ns output #1ns;
    //声明变量方向
    output ch_data, ch_valid;
    input ch_ready, ch_margin;
  endclocking
endinterface

  • 20
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
SystemVerilog的听课学习笔记,包括讲义截取、知识点记录、注意事项等细节的标注。 目录如下: 第一章 SV环境构建常识 1 1.1 数据类型 1 四、二值逻辑 4 定宽数组 9 foreach 13 动态数组 16 队列 19 关联数组 21 枚举类型 23 字符串 25 1.2 过程和方法 27 initial和always 30 function逻辑电路 33 task序电路 35 动态 静态变量 39 1.3 设计例化和连接 45 第二章 验证的方法 393 动态仿真 395 静态检查 397 虚拟模型 403 硬件加速 405 效能验证 408 性能验证 410 第三章 SV组件实现 99 3.1 接口 100 什么是interface 101 接口的优势 108 3.2 采样和数据驱动 112 竞争问题 113 接口中的clocking 123 利于clocking的驱动 133 3.3 测试的开始和结束 136 仿真开始 139 program隐式结束 143 program显式结束 145 软件域program 147 3.4 调试方法 150 第四章 验证的计划 166 4.1 计划概述 166 4.2 计划的内容 173 4.3 计划的实现 185 4.4 计划的进程评估 194 第五章 验证的管理 277 6.1 验证的周期检查 277 6.2 管理三要素 291 6.3 验证的收敛 303 6.4 问题追踪 314 6.5 团队建设 321 6.6 验证的专业化 330 第六章 验证平台的结构 48 2.1 测试平台 49 2.2 硬件设计描述 55 MCDF接口描述 58 MCDF接口序 62 MCDF寄存器描述 65 2.3 激励发生器 67 channel initiator 72 register initiator 73 2.4 监测器 74 2.5 比较器 81 2.6 验证结构 95 第七章 激励发生封装:类 209 5.1 概述 209 5.2 类的成员 233 5.3 类的继承 245 三种类型权限 protected/local/public 247 this super 253 成员覆盖 257 5.4 句柄的使用 263 5.5 包的使用 269 第八章 激励发生的随机化 340 7.1 随机约束和分布 340 权重分布 353 条件约束 355 7.2 约束控制 358 7.3 随机函数 366 7.4 数组约束 373 7.5 随机控制 388 第九章 线程与通信 432 9.1 线程的使用 432 9.2 线程的控制 441 三个fork...join 443 等待衍生线程 451 停止线程disable 451 9.3 线程的通信 458 第十章 进程评估:覆盖率 495 10.1 覆盖率类型 495 10.2 功能覆盖策略 510 10.3 覆盖组 516 10.4 数据采样 524 10.5 覆盖选项 544 10.6 数据分析 550 第十一章 SV语言核心进阶 552 11.1 类型转换 552 11.2 虚方法 564 11.3 对象拷贝 575 11.4 回调函数 584 11.5 参数化的类 590 第十二章 UVM简介 392 8.2 UVM简介 414 8.3 UVM组件 420 8.4 UVM环境 425

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小verifier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值