概述
前几天是问了我一个小问题,我总结关键点如下:
情形一:
always@(posedge clk) begin
if(ce == 1'b1 && ready == 1'b1)
w_en <= 1'b1;
else
w_en <= 1'b0;
end
情形二:
always@(posedge clk) begin
if(ce == 1'b1 && ready == 1'b1)
if(data <= 8'b1111_1111)
data <= data_in;
else
data <= data; //data_in是上一个模块的时序输出
end
他的问题是:为什么情形一中的w_en在条件满足的时候立马发生变化,也就是在本周期改变;而在情形二中当条件满足的时候,data的值不是立马发生变化,而是在下一周期发生变化?
可以用波形表示如下:
这个问题我当时也没注意过,写程序的时候我大多时候是看着时序图对了就行了,被这一问难倒了!!!
通过分析我明白了。
分析:
情形一:
首先,进入这个过程块的条件是在时序的上升沿,如果满足if条件就会执行 w_en <= 1'b1;
赋值过程是这样的,首先统一计算表达式右边的值,然后在统一的赋给左边的变量,改变是几乎
是立即发生的,也就是在本周期改变。w_en <= 1'b1 语句右边的值可以看做是一个组合逻辑
信号,所以改变是立即发生的。
情形二:
首先,进入这个过程块的条件也是在时序的上升沿,如果满足if条件就会进入到data<=
data_in,否则保持不变。赋值的过程也是先统一计算表达式右边的值,然后在一次性赋给表达
左边的变量data,改变也几乎是立即的,即也是在本周期进行更新。由于data_in是有外部的模
块传输进来的,所以需要看一下data_in是否经过时序驱动,如果经过时序驱动,那data_in就
相当于一个时序逻辑信号,所以data肯定会比data_in晚一个周期。如果data_in是一个组合逻辑信号,那么data和data_in的波形在条件满足之后就会完全对齐。
请看下面的这个式子:
always@(posedge clk)begin
if(条件满足) begin
b <= a;
end
else begin
……
end
end
如果把 a换成data_in,把b换成data可能会更好理解一点。
附录:
顶层模块:
module non_block(
input clk,
input rst,
input ce,
input ready,
input [7:0] data_in,
output reg w_en,
output reg [7:0] data
);
reg [7:0] data_reg = 8'b01010101;
always@(posedge clk)begin
if(!rst)begin
w_en <= 1'b0;
data <= 8'b0;
end
else if(ce ==1'b1 && ready ==1'b1) begin
if(data<=8'b11111111)begin
w_en <= 1'b1;
data <= data_in;
end
end
end
endmodule
tb1:
module tb_non_block(
);
reg clk;
reg rst;
reg ce;
reg ready;
reg [7:0] data_in;
wire w_en;
wire [7:0] data;
initial begin
clk = 1;
forever #10 begin
clk = ~clk;
end
end
initial begin
rst = 0;
ce =0;
ready = 0;
#60;
rst = 1;
#20;
ce = 1'b1;
ready = 1'b1;
end
//data_in是一个时序逻辑信号
always@(posedge clk)begin
if(!rst)
data_in <=0;
else if(data_in<=8'b11111111)
data_in <= data_in +1;
end
non_block non_block0(
.clk(clk),
.rst(rst),
.ce(ce),
.ready(ready),
.data_in(data_in),
.w_en(w_en),
.data(data)
);
endmodule
对应的波形如下:
tb2:
module tb_non_block(
);
reg clk;
reg rst;
reg ce;
reg ready;
reg [7:0] data_in;
wire w_en;
wire [7:0] data;
initial begin
clk = 1;
forever #10 begin
clk = ~clk;
end
end
initial begin
rst = 0;
ce =0;
ready = 0;
data_in = 8'b0;
#60;
rst = 1;
#20;
ce = 1'b1;
ready = 1'b1;
data_in = 8'b00010001; //data_in是一个组合逻辑信号
end
non_block non_block0(
.clk(clk),
.rst(rst),
.ce(ce),
.ready(ready),
.data_in(data_in),
.w_en(w_en),
.data(data)
);
endmodule
对应的波形:
最后
以上就是诚心洋葱为你收集整理的always@(posedge clk)时序赋值延迟一个周期的全部内容,希望文章能够帮你解决always@(posedge clk)时序赋值延迟一个周期所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复