【小罗的hdlbits刷题笔记3】从Edgedetect对阻塞赋值和非阻塞赋值的思考

今天题目刷到Edgedetect时,发现根本看不懂这个题目描述的是什么,先给大家放题来体会一下:

For each bit in an 8-bit vector, detect when the input signal changes from 0 in one clock cycle to 1 the next (similar to positive edge detection). The output bit should be set the cycle after a 0 to 1 transition occurs.
Here are some examples. For clarity, in[1] and pedge[1] are shown separately.
翻译:对于8位向量中的每个位,检测当输入信号从一个时钟周期的0到下一个1(类似于正边缘检测)变化时。输出位应该设置0到1转换后的周期。下面是一些例子。为清楚起见,in[1]和pre[1]分别进行展示。

1
好家伙,这是什么鬼,看到这个问题我首先是懵逼的,但是通过上面给出的例子进行分析还是可以看到一些端倪,比如in[7:0]由2转到e时,即4’b0010变为4’b1110,输出的predge为1100。那么这道问题就显而易见,即检测上一个时刻的输入到本时刻输入的变化,若由0变为1则输出为1,代码实现如下:

module top_module (
    input clk,
    input [7:0] in,
    output [7:0] pedge
);	
    reg [7:0]in_pre;
    always@(posedge clk)begin
        in_pre[7:0]<=in[7:0];
        pedge[7:0]<=(~in_pre[7:0])&in[7:0];
    end       
endmodule

在这里需要说明一下的是,一个module中的不同always块都是并行执行的,在这里的赋值符号发生了改变,即从“=”变成了“<=”,前者为阻塞赋值,而后者为非阻塞赋值。
阻塞赋值是顺序执行的,非阻塞赋值是并行执行的,通过下面这个例子可以更加显而易见的看出其中的区别:(例子选自知乎https://zhuanlan.zhihu.com/p/35442938)

always@(posedge clk)
begin
 a <= ~b;
end

always@(posedge clk)
begin
 c <= ~a;
end

上面的两个always块其实可以合并成一个always块,使代码更加的简洁:

always@(posedge clk)
begin
 a <= ~b;
 c <= ~a;
end

与之对标的是

always@(posedge clk)
begin
 a = ~b;
 c = ~a;
end

那么首先我们假设a,b,c三个值分别为0,1,1
采用非阻塞赋值的情况下,两条语句时同时进行的,第二条语句中的赋值不受第一条语句的影响。那么代码运行之后,a=-1,b=1,c=0;
而采用非阻塞赋值时,两条语句顺序执行,第二条语句中的赋值受第一条语句中的影响,首先第一条语句执行后,a=-1,b=1,c=1,然后执行第二条语句,此时a已经不是原来的0,而是-1.执行结束后a=-1, b=1,c=1;

回到咱们这道题中的代码,通过一个中间寄存器变量in_pre[7:0]将上一时刻的输入值保存起来,并通过非阻塞赋值不影响其变化的方式,与本时刻的输入进行比较,从而实现了检测前后两时刻的输入是否出现0到1的变化的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值