FPGA学习笔记:阻塞与非阻塞的时钟延迟对比

本教程要求对数字电路中的寄存器(边沿D触发器)具有一定的了解,并熟悉基本的verilog语法。

首先利用非阻塞赋值编写一个异步寄存器:

module blocking
(
    input  wire                         sys_clk                    ,
    input  wire                         sys_rst_n                  ,
    input  wire           [1:0]         in                         ,

    output reg            [1:0]         out                         
);
reg                       [1:0]         in_reg                     ;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)
begin
    in_reg<=sys_rst_n;
    out<=in_reg;
end
else
begin
    in_reg<=in;
    out<=in_reg;
end
endmodule

编写仿真代码:

`timescale 1ns/1ns
module tb_blocking();
reg                                     sys_clk                    ;
reg                                     sys_rst_n                  ;
reg                       [1:0]         in                         ;
wire                      [1:0]         out                        ;
initial
begin
    sys_clk=1'b1;
    sys_rst_n<=1'b0;
    in<=2'b00;
    #20
    sys_rst_n<=1'b1;
end
always #10 sys_clk=~sys_clk;
always #20 in<={$random}%4;
initial
begin
    $timeformat(-9,0,"ns",6);
    $monitor("@time %t sys_clk=%b sys_rst_n=%b in=%b out=%b",
    $time,sys_clk,sys_rst_n,in,out);
end
blocking blocking_inst
(
    .sys_clk                            (sys_clk)                  ,
    .sys_rst_n                          (sys_rst_n)                ,
    .in                                 (in)                       ,
    .out                                (out)                   
);
endmodule

运行该代码进行仿真得到波形:

 

从图中可以看出输出out相对于输入in延迟了两个时钟周期。从而说明<=非阻塞赋值在begin end中是并行执行。其rtl视图如下,从图中可以看出对于每一个bit分别由两组寄存器组成,故进行了两个时钟周期的延迟。

 对于阻塞赋值将<=改为=即可,仿真代码不变:

module blocking
(
    input  wire                         sys_clk                    ,
    input  wire                         sys_rst_n                  ,
    input  wire           [1:0]         in                         ,

    output reg            [1:0]         out                         
);
reg                       [1:0]         in_reg                     ;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n==1'b0)
begin
    in_reg=sys_rst_n;
    out=in_reg;
end
else
begin
    in_reg=in;
    out=in_reg;
end
endmodule

 对应的波形和rtl视图如下,从图中可以看出输出out相对于输入in只有一个时钟周期延迟,reg_in和out是同步的,从而说明阻塞赋值在begin end中是顺序执行的。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值