寄存器reg延迟问题
always @(posedge clk) begin
if(reset) data_out<=0;
else data_out<=data_in;
end
然而如果在代码中增加一个clk二分频时钟clk_2,并用该信号来驱动data_out,则不会产生延迟,即仿真软件会把posedge clk_2后一时刻的data_in赋给data_out:
always @(posedge clk) begin
if(reset) clk_2<=0;
else clk_2<=~clk_2;
end
always @(posedge clk_2) begin
if(reset) data_out<=0;
else data_out<=data_in;
end
问先问了下公司的一个前辈,他说有可能是使用clk_2会产生亚稳态,于是我用了一个reg来对clk_2打一个节拍产生clk_2_d,并用该时钟来触发data_out,但问题依旧。请问各位看官,是我处理亚稳态的方法不对,还是上述问题并不是由亚稳态引起的?如果不是亚稳态,那又是什么问题引起的?
注:上述例子是为了方便说明进行的简化,实际上还有一些其他的信号。
看我画的图,帮助你理解
参考波形
谢谢你的回复,不过我看得还不是特别明白,能不能解释的再详细点,谢谢
用的是上升沿有效,你看clk信号是多久一个上升沿,而clk_2是多久一个上升沿,周期clk = 两倍的clk_2
我个人觉得跟clk_2的周期没太大关系,因为看了你的回复之后,我回去分别将clk_2的周期修改为与clk相同或者是clk的2倍(利用pll),但得到的结果都是一样的,即模块无延迟地将reg_shift的结果赋值给data_out。所以我觉得应该回到寄存器触发上寻找答案,一般来说,模块会在时钟触发沿到来时将触发沿前一刻对应的数据赋给触发器输出端口(同一个clk进行触发的情况下),当用别的时钟进行触发时(clk_2),模块会将触发沿后一时刻对应的数据赋给触发器输出端口。这种情况是由亚稳态造成的还是说理论上就是如此?
是在时钟的上升沿捕获的,图片是我仿真的结果。
你输入的数据datain怎么变化的?如果是在上升沿的话,当前clk的上升沿采到的是前一个时钟的数据。
我觉得当你分频之后,时钟是有延时的,这时采样到的数据就像是当前的数据,其实只是时钟变化比数据变化慢而已
我也觉得和输入的数据怎么变化有关系。
我告诉你,在默认参数设置情况下,仿真软件是绝对不会给你什么延时的,比如你第一段代码,data_in会在clk上升沿的时候赋给data_out,要刚好对齐于clk的上升沿,这才是对的。
什么亚稳态,在仿真环境下,除非你设置了非常专业的仿真延时参数,否则亚稳态什么的都是扯蛋,好好理解下自己的写的HDL,看看寄存器赋值该是什么样的,这是个很基础的问题,被你扯远了。