在验证环境中产生带缺口的时钟

一、背景

在验证环境中已经有了一个不带缺口的时钟,现在需要将这个不带缺口的时钟每隔10拍扣去1拍,然后在这个带缺口的时钟下发送激励给DUT。

二、错误示例

int     cnt_10;
logic   vld;
logic   gap_clk;

initial begin
    cnt_10 = 0;
    forever begin
        @(posedge clk);
        cnt_10++;
        cnt_10 = cnt_10 % 10;
        if(cnt_10 == 0) vld = 0;
        else            vld = 1;
    end
end

assign gap_clk = vld & clk;

把波形dump毛刺的选项(+fsdb+delta)打开后,可以看到这种方式生成的gap_clk是带有毛刺:

如果我们使用该时钟来发送激励,那么在有毛刺的瞬间,仿真器会认为存在gap_clk的跳变,激励也就不满足要求了。

假设激励设置如下:

logic [31:0]    drv_data;

always @(posedge gap_clk) begin
    drv_data <= $urandom();
end

仿真得到的激励:

三、毛刺的分析

int     cnt_10;
logic   vld;
logic   gap_clk;

initial begin                         // process1
    cnt_10 = 0;
    forever begin
        @(posedge clk);
        cnt_10++;
        cnt_10 = cnt_10 % 10;
        if(cnt_10 == 0) vld = 0;
        else            vld = 1;
    end
end

assign gap_clk = vld & clk;           // process2

基于systemverilog的仿真调度机制来分析。假定当前的cnt_10=9,此时clk发生0->1的跳变,clk在跳变后为1,此时会触发process1和process2。process1和process2的计算会得到vld=0和gap_clk=1。因为此时所有的process已经计算完成,所以vld=0和gap_clk=1会被保存。接着由于vld的值发生1->0的跳变,会再一次地触发process2的计算,此时process2的计算会得到gap_clk=0,该结果也会被保存。由于上述的计算都发生在一个时刻点上,所以gap_clk就会呈现出毛刺,该毛刺进一步导致仿真结果不符合预期。

四、正确示例

实现可以参考stdcell中ICG的行为描述,利用负沿来锁存vld。ICG的行为描述如下:

reg E_LAT;
 
always @(*) begin
    if(CP == 1'b0)
        E_LAT = E;
    else
        E_LAT = E_LAT;
end
 
assign Q = CP & E_LAT;

因此只需要将代码中的posedge改成negedge即可,修改后效果如下:

其实这种写法还是偏向于设计的写法。如果是偏向于验证的写法,最好还是不要出现assign语句,直接在一个block中进行行为描述。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值