5时序逻辑之寄存器,阻塞赋值与非阻塞赋值的区别

一、时序逻辑:寄存器
1.组合逻辑中的竞争冒险
竞争(Competition): 在组合逻辑电路中,某个输入变量通过两条或两条以上的途径传到输出端,由于每条途径延迟时间不同,到达输出门的时间就有先有后,这种现象称为竞争。把不会产生错误输出的竞争的现象称为非临界竞争。把产生暂时性的或永久性错误输出的竞争现象称为临界竞争。
冒险(risk):信号在器件内部通过连线和逻辑单元时,都有一定的延时。延时的大小与连线的长短和逻辑单元的数目有关,同时还受器件的制造工艺、工作电压、温度等条件的影响。信号的高低电平转换也需要一定的过渡时间。由于存在这两方面因素,多路信号的电平值发生变化时,在信号变化的瞬间,组合逻辑的输出有先后顺序,并不是同时变化,往往会出现一些不正确的尖峰信号,这些尖峰信号称为"毛刺"。如果一个组合逻辑电路中有"毛刺"出现,就说明该电路存在冒险。
竞争冒险(Competition risk)产生原因:由于延迟时间的存在,当一个输入信号经过多条路径传送后又重新会合到某个门上,由于不同路径上门的级数不同,或者门电路延迟时间的差异,导致到达会合点的时间有先有后,从而产生瞬间的错误输出。

2.寄存器
寄存器具有存储功能,一般由D触发器(D Flip Flop,DFF)构成,由时钟脉冲控制,一个D触发器存储一个二进制
D触发器的工作原理:在一个脉冲信号(一般为晶振产生的时钟脉冲)上升沿或下降沿的作用下,将信号从输入端D送到输出端Q,如果时钟脉冲的边沿信号未出现,即使输入信号改变,输出信号仍然保持原值,且寄存器拥有复位清零功能,其复位又分为同步复位和异步复位。

同步复位:复位信号产生,等下一个时钟上升沿产生执行
异步复位:只要复位信号产生,立即执行
下图表示异步复位与同步复位的rtl
在这里插入图片描述在这里插入图片描述

两者相同的是在复位信号结束的时候,都要等下一个时钟上升沿才恢复
在这里插入图片描述

注:
(1)D触发器能够屏蔽在两个上升沿之间的毛刺,如上图中所示
(2)同步触发和异步触发,主要是复位信号,异步复位不论是在上升沿还是在下降沿输出都是立即执行,而同步复位信号有效时,则在下一个上升沿来临时,输出才会执行。
(3)在组合逻辑电路中,当输入信号为上升沿时,则响应也是立马执行上升沿。而在时许逻辑电路中,当时钟与输入都同时为上升沿时,则默认时钟采集到的数据是在该时钟上升沿前一刻的值。
(4)输出信号会延迟输入信号一拍,即相对输入来说会晚一个周期执行,如上图所示

程序
module flip_flop
(
input wire in,
input wire sys_clk,
input wire sys_rst_n,
output reg out

);

always@(posedge sys_clk or negedge sys_rst_n )
if(sys_rst_n == 1’b0)
out <= 1’b0;//时序逻辑中赋值语句一定要使用非阻塞赋值语句
else
out <= in;

endmodule

测试程序
`timescale 1ns/1ns
module tb_flip_flop();

reg in;
reg sys_clk;
reg sys_rst_n;

wire out;

initial
begin
in <= 1’b1;
sys_clk = 1’b0;
sys_rst_n <= 1’b0;
#20
sys_rst_n = 1’b1;
#210
sys_rst_n = 1’b0;
#40
sys_rst_n = 1’b0;
end

initial
begin
m o n i t o r ( " @ t i m e monitor("@time %t:in=%b,out=%b", monitor("@timetime,in,out);
$timeformat(-9,0,“us”,6);
end

always #10 sys_clk=~sys_clk;

always #20 in <= {$random} % 2;

flip_flop flip_flop1
(
.in (in),
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.out (out)

);

endmodule

二、阻塞赋值与非阻塞赋值
1、阻塞赋值
阻塞赋值的赋值号用“=”表示,对应的电路结构往往与触发沿没有关系,只与输入电平的变化有关系。它的操作可以认为是只有一个步骤的操作,即计算赋值号右边的语句并更新赋值号左边的语句,此时不允许有来自任何其他Verilog语句的干扰,直到现行的赋值完成,才允许下一条的赋值语句的执行。
串行块(begin-end)中,各条阻塞赋值语句将以它们在顺序块中的排列次序依次执行。

程序
module blocking
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [1:0] in ,
output reg [1:0]out

);

reg [1:0] out1;

always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1’b0)
begin
out = 2’b0;
out1 = 2’b0;
end
else
begin
out1 = in;
out = out1;
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’b0;
sys_rst_n <= 1’b0;
in <= 2’b0;
#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);
m o n i t o r ( " @ t i m e monitor("@time %t:in=%b,sys_clk=%b,sys_rst_n=%b,out=%b", monitor("@timetime,in,sys_clk,sys_rst_n,out);
end

blocking blocking_inst
(
.sys_clk (sys_clk) ,
.sys_rst_n (sys_rst_n) ,
.in (in) ,
.out (out)

);

endmodule

从下图中可以看出来,当in变化时,out1与out时同时变化的,out1与out都同时与输入滞后一个周期,因此也不难看出in→out1与out之间有一个D触发器,其rtl电路如下图所示
在这里插入图片描述在这里插入图片描述

2、非阻塞赋值
非阻塞赋值的赋值号用“<=”表示,对应的电路结构往往与触发沿有关系,只有在触发沿的时刻才能进行非阻塞赋值。
它的操作可以看作为两个步骤的过程:在赋值开始时刻,计算赋值号右边的语句。在赋值结束时刻,更新赋值号左边的语句。
在计算非阻塞语句赋值号右边的语句和更新赋值号左边的语句期间,允许其他的Verilog语句同时进行操作。
非阻塞操作只能用于对寄存器类型变量进行赋值,因此只能用于“initial”和“always”块中,不允许用于连续赋值“assign”。

程序
module no_blocking
(
input wire sys_clk ,
input wire sys_rst_n ,
input wire [1:0] in ,
output reg [1:0] out

);

reg [1:0] out1;

always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1’b0)
begin
out1 <= 1’b0;
out <= 1’b0;
end
else
begin
out1 <= in;
out <= out1;
end

endmodule

测试程序
`timescale 1ns/1ns
module tb_no_blocking();

reg sys_clk ;
reg sys_rst_n ;
reg [1:0] in ;

wire [1:0] out ;

initial
begin
sys_clk = 1’b0;
sys_rst_n <= 1’b0;
in <= 2’b0;
#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);
m o n i t o r ( " @ t i m e monitor ("@time %t:in=%b,sys_clk=%b,sys_rst_n=%b,out=%b", monitor("@timetime,in,sys_clk,sys_rst_n,out);
end

no_blocking no_blocking_inst
(
.sys_clk (sys_clk ) ,
.sys_rst_n (sys_rst_n ) ,
.in (in ) ,
.out (out)

);
endmodule

由下图可以看出来非阻塞赋值在out1滞后in一个周期,out滞后out1一个周期,所以不难想到,在in→out1之间存在一个寄存器,在out1→out之间存在一个寄存器,共两个寄存器

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值