0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在testbench中如何使用阻塞赋值和非阻塞赋值

FPGA设计论坛 来源:CSDN技术社区 2025-04-15 09:34 次阅读

本文详细阐述了在一个testbench中,应该如何使用阻塞赋值与非阻塞赋值。首先说结论,建议在testbench中,对时钟信号(包括分频时钟)使用阻塞赋值,对其他同步信号使用非阻塞赋值。

下面是一个简单的D触发器模块,本文将针对它的testbench进行讨论。

moduleDff(inputclk, rst_n, data_in,outputregdata_out);  always@(posedgeclk,negedgerst_n)begin    if(!rst_n)       data_out <= 1'b0;        else             data_out <= data_in;    endendmodule

Verilog仿真时,仿真波形与真实波形是有一定差距的,这体现在同步信号的改变与时钟沿一直是对齐的,而真实情况下,数据信号在时钟沿后需要延迟一段时间才会发生改变。

体现在上面的模块中就是数据信号data_in的改变是与时钟信号clk同步的,data_out的改变也是与时钟信号clk同步的。

图1展示了一个简单的仿真波形,其中信号data_in和信号data_out的改变都与时钟沿同步,需要注意的是在时钟沿处,信号data_out得到的是信号data_in在时钟沿处的原值,而不是改变后的值。

c4aae130-1743-11f0-9310-92fbcf53809c.png

图1 仿真波形

也就是说,一个更加真实的波形可能如图2所示。

c4c06e42-1743-11f0-9310-92fbcf53809c.png

图2 真实波形

下面给出图1所示波形的testbench。

moduleDff_t;  regrst_n =1;  regclk =0;  regdata_in =0;  wiredata_out;   Dff dff(.clk(clk),.rst_n(rst_n),.data_in(data_in),.data_out(data_out));  //时钟产生  alwaysbegin    #10clk = ~clk;  end  //异步复位信号  initialbegin    #3rst_n =0;     #3rst_n =1;  end  //同步数据输入  initialbegin    #10data_in <= 1;         #20 data_in <= 0;         #20 data_in <= 1;         #20 data_in <= 0;    end     endmodule

其中时钟信号和异步复位信号使用了阻塞赋值,而数据信号使用了非阻塞赋值。如果不是这样,就无法保证产生如图1所示的仿真波形,下面将分别讨论。

1、如时钟信号使用非阻塞赋值,数据信号也使用非阻塞赋值

moduleDff_t;  regrst_n =1;  regclk =0;  regdata_in =0;  wiredata_out;   Dff dff(.clk(clk),.rst_n(rst_n),.data_in(data_in),.data_out(data_out));  //时钟产生  alwaysbegin    #10clk <= ~clk;    end      //异步复位信号     initial begin         #3 rst_n = 0;         #3 rst_n = 1;    end      //同步数据输入     initial begin         #10 data_in <= 1;         #20 data_in <= 0;         #20 data_in <= 1;         #20 data_in <= 0;    end     endmodule

c4cfd030-1743-11f0-9310-92fbcf53809c.png

图3 错误的波形(一种可能)

此时进行仿真,可能会出现图3所示的错误波形,信号data_out得到的是信号data_in在时钟沿处改变后的值。

拿第一个时钟上升沿即10ns时举例,此时时钟信号clk被非阻塞赋值,同时data_in被非阻塞赋值。首先说明非阻塞赋值的过程,非阻塞赋值是分两步进行的,第一步是将赋值号<=右表达式求值,在当前仿真时间的所有赋值和非阻塞赋值右表达式求值(活跃事件)完成后,再进行第二步,即非阻塞赋值的赋值(非阻塞赋值的赋值顺序由求值顺序决定),即非阻塞赋值分为两步:求值与赋值,后文仅使用“赋值”一词代表非阻塞赋值中的赋值这个步骤,注意其与阻塞赋值的区别。

由于initial结构和always结构是并行的,因此无法确定哪一个非阻塞赋值的右表达式求值是先进行的,但可以确定的是,信号clk的赋值和信号data_in的赋值以某种先后顺序被调度到之后(非阻塞赋值更新区)执行。当进行第二步时,clk的赋值和data_in的赋值都从非阻塞赋值更新区激活到活跃事件区执行,此时有多种执行方式:

1、如果clk的赋值先执行(即之前clk非阻塞赋值右表达式先求值),则其又触发了@(posedge clk),接着是执行data_out非阻塞赋值右表达式求值,还是执行data_in的赋值,是不确定的,它们都是活跃事件。如果先执行data_out非阻塞赋值右表达式求值,则data_out得到的是data_in的旧值即0;如果先执行data_in的赋值,则data_out得到的是data_in的新值即1(图3可能就是这种情况)。

2、如果data_in的赋值先执行(即之前data_in非阻塞赋值右表达式先求值),则最后data_out得到的一定是data_in的新值即1(图3可能就是这种情况)。

2、如时钟信号使用阻塞赋值,数据信号也使用阻塞赋值

moduleDff_t;  regrst_n =1;  regclk =0;  regdata_in =0;  wiredata_out;   Dff dff(.clk(clk),.rst_n(rst_n),.data_in(data_in),.data_out(data_out));  //时钟产生  alwaysbegin    #10clk = ~clk;  end  //异步复位信号  initialbegin    #3rst_n =0;     #3rst_n =1;  end  //同步数据输入  initialbegin    #10data_in =1;     #20data_in =0;     #20data_in =1;     #20data_in =0;  end  endmodule

c4ed63f2-1743-11f0-9310-92fbcf53809c.png

图4 错误的波形(一种可能)

此时进行仿真,可能会出现图4所示的错误波形,信号data_out得到的是信号data_in在时钟沿处改变后的值。

拿第一个时钟上升沿即10ns时举例,此时时钟信号clk被阻塞赋值,同时data_in被阻塞赋值。由于initial结构和always结构是并行的,因此无法确定哪一个阻塞赋值是先进行的,此时有多种执行方式。

1、如果clk的阻塞赋值先进行,则其又触发了@(posedge clk),接着是执行data_out非阻塞赋值右表达式求值,还是执行data_in的阻塞赋值,是不确定的,它们都是活跃事件。如果先执data_out非阻塞赋值右表达式求值,则data_out首先得到的是data_in的旧值即0;如果先执行data_in的阻塞赋值,则则data_out得到的是data_in的新值即1(图4可能就是这种情况)。

2、如果data_in的阻塞赋值先进行则最后data_out得到的一定是data_in的新值即1(图4可能就是这种情况)。

3、如时钟信号使用非阻塞赋值,数据信号使用阻塞赋值

moduleDff_t;  regrst_n =1;  regclk =0;  regdata_in =0;  wiredata_out;   Dff dff(.clk(clk),.rst_n(rst_n),.data_in(data_in),.data_out(data_out));  //时钟产生  alwaysbegin    #10clk <= ~clk;    end      //异步复位信号     initial begin         #3 rst_n = 0;         #3 rst_n = 1;    end      //同步数据输入     initial begin         #10 data_in = 1;         #20 data_in = 0;         #20 data_in = 1;         #20 data_in = 0;    end     endmodule

c4f947e4-1743-11f0-9310-92fbcf53809c.png

图5 错误的波形

此时进行仿真,一定会出现图5所示的错误波形,信号data_out得到的是信号data_in在时钟沿处改变后的值。

拿第一个时钟上升沿即10ns时举例,此时时钟信号clk被非阻塞赋值,同时data_in被阻塞赋值。由于initial结构和always结构是并行的,因此无法确定是非阻塞赋值的右表达式求值先进行还是阻塞赋值先进行,但是阻塞赋值一定是在非阻塞赋值的赋值前进行的(根据非阻塞赋值的定义),所以不管有多少种执行方式,此时只有一种结果。

1、data_out得到的一定是data_in的新值即1(图5就是这种情况)。

4、时钟信号使用阻塞赋值,数据信号使用非阻塞赋值

moduleDff_t;  regrst_n =1;  regclk =0;  regdata_in =0;  wiredata_out;   Dff dff(.clk(clk),.rst_n(rst_n),.data_in(data_in),.data_out(data_out));  //时钟产生  alwaysbegin    #10clk = ~clk;  end  //异步复位信号  initialbegin    #3rst_n =0;     #3rst_n =1;  end  //同步数据输入  initialbegin    #10data_in <= 1;         #20 data_in <= 0;         #20 data_in <= 1;         #20 data_in <= 0;    end     endmodule

最后分析正确的testbench,拿第一个时钟上升沿即10ns时举例,此时时钟信号clk被阻塞赋值,同时data_in被非阻塞赋值。由于initial结构和always结构是并行的,因此无法确定是非阻塞赋值的右表达式求值先进行还是阻塞赋值先进行。

1、如果clk的阻塞赋值先进行,则其又触发了@(posedge clk),接着是执行data_out非阻塞赋值右表达式求值,还是执行data_in非阻塞赋值右表达式求值,是不确定的,它们都是活跃事件。但是可以肯定的是,data_out得到的一定是data_in的旧值,因为非阻塞赋值的赋值一定在所有非阻塞赋值的求值后进行(根据非阻塞赋值的定义)。

2、如果data_in非阻塞赋值右表达式求值先进行,则在之后clk阻塞赋值进行后,其又触发了@(posedge clk),接着执行data_out非阻塞赋值右表达式求值,但求值时是使用data_in的旧值,因为非阻塞赋值的赋值一定在所有非阻塞赋值的求值后进行(根据非阻塞赋值的定义)。

来源:https://blog.csdn.net/weixin_45791458/article/details/137046594

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 仿真
    +关注

    关注

    51

    文章

    4195

    浏览量

    134960
  • Verilog
    +关注

    关注

    28

    文章

    1363

    浏览量

    111298
  • 阻塞赋值
    +关注

    关注

    0

    文章

    10

    浏览量

    9211
  • 非阻塞赋值
    +关注

    关注

    0

    文章

    11

    浏览量

    10052

原文标题:在testbench中使用阻塞赋值和非阻塞赋值的区别

文章出处:【微信号:gh_9d70b445f494,微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Verilog语言中阻塞阻塞赋值的不同

    赋值何时使用阻塞赋值才能设计出符合要求的电路。 他们也不完全明白电路结构的设计,即可综合风格的Verilog模块的设计
    的头像 发表于 08-17 16:18 6549次阅读

    Verilog阻塞赋值阻塞赋值的正确使用

    [table][tr][td] Verilog中有两种为变量赋值的方法。一种叫做连续赋值,另一种叫做过程赋值。过程赋值又分为阻塞
    发表于 07-03 03:06

    【技巧分享】FPGA至简设计-阻塞赋值阻塞赋值

    阻塞阻塞作者:小黑同学一、 概述1、阻塞赋值对应的电路往往与触发沿没有关系,只与电平的变化有关系。
    发表于 04-24 14:49

    FPGA学习系列:5.阻塞赋值阻塞赋值

    设计背景: 阻塞 (=)和阻塞(=)一直是我们FPGA讨论的问题,资深的学者都是讨论的是赋值
    的头像 发表于 05-31 11:40 7029次阅读
    FPGA学习系列:5.<b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>与<b class='flag-5'>非</b><b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>

    阻塞赋值阻塞赋值的用法一篇文章就够了

    对于VerilogHDL语言中,经常在always模块,面临两种赋值方式:阻塞赋值阻塞
    的头像 发表于 01-30 17:41 2.2w次阅读

    verilog阻塞赋值阻塞赋值到底有什么区别

    1、阻塞赋值操作符用等号(即 = )表示。“阻塞”是指在进程语句(initial和always),当前的赋值语句阻断了其后的语句,也就是说
    发表于 04-25 08:00 0次下载
    verilog<b class='flag-5'>中</b><b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>和<b class='flag-5'>非</b><b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>到底有什么区别

    IEEE Verilog阻塞赋值阻塞赋值的区别

    阻塞赋值对应的电路往往与触发沿没有关系,只与输入电平的变化有关系。阻塞赋值对应的电路结构往往与触发沿有关系,只有
    的头像 发表于 06-17 11:57 1.2w次阅读
    IEEE Verilog<b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>和<b class='flag-5'>非</b><b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>的区别

    VerilogHDL语言:清阻塞赋值阻塞赋值

    对于VerilogHDL语言中,经常在always模块,面临两种赋值方式:阻塞赋值阻塞
    发表于 11-19 15:48 1268次阅读

    简述阻塞赋值阻塞赋值的可综合性

    ,所以基于的C的术语和概念出现在EDA,原本是一个“误打误撞”,但历史造成的现实则是:必须理解和正确掌握它们的用法。 软件阻塞进程,是指调用返回之前,应用进程一直等待: 为了保证应用进程的效率,不至于被子程序的运算过程“挂起
    的头像 发表于 05-12 09:45 2870次阅读
    简述<b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>和<b class='flag-5'>非</b><b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>的可综合性

    时序逻辑阻塞阻塞

    Verilog HDL的赋值语句分为阻塞赋值阻塞赋值两种。
    的头像 发表于 03-15 13:53 3232次阅读

    verilog阻塞赋值阻塞赋值的区别

    阻塞赋值操作符用等号(即 = )表示。“阻塞”是指在进程语句(initial和always),当前的赋值语句阻断了其后的语句,也就是说后面
    发表于 12-19 16:49 7894次阅读

    Verilog阻塞阻塞赋值金规

    对于VerilogHDL语言中,经常在always模块,面临两种赋值方式:阻塞赋值阻塞
    的头像 发表于 06-01 09:21 1681次阅读

    一文了解阻塞赋值阻塞赋值

    今天给大家普及一下阻塞赋值阻塞赋值的相关知识
    的头像 发表于 07-07 14:15 2404次阅读
    一文了解<b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>与<b class='flag-5'>非</b><b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>

    阻塞赋值阻塞赋值

    ”=“阻塞赋值与”
    的头像 发表于 09-12 09:06 1238次阅读
    <b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>与<b class='flag-5'>非</b><b class='flag-5'>阻塞</b><b class='flag-5'>赋值</b>

    verilog同步和异步的区别 verilog阻塞赋值阻塞赋值的区别

    Verilog是一种硬件描述语言,用于设计和模拟数字电路。Verilog,同步和异步是用来描述数据传输和信号处理的两种不同方式,而阻塞赋值
    的头像 发表于 02-22 15:33 2081次阅读