一个困扰小弟3个月的FPGA难题,希望高手解答,不胜感激
比如
- module A
- (
- rst,clk,sign1
- );
- input clk;
- input rst;
- output reg sign1;
-
- always @(posedge clk or negedge rst)
- if(!rst)
- sign1<=1'b0;
- else
- sign1<=~sign1;
-
- endmodule
- module B
- (
- rst,clk,sign1,sign2
- );
- input clk;
- input rst;
- input sign1;
- output reg sign2;
-
- always @(posedge clk or negedge rst)
- if(!rst)
- sign2<=1'b0;
- else if(sign1)
- sign2<=1'b1;
- else
- sign2<=1'b0;
- endmodule
- module top
- (
- clk,sign2,rst
- );
- input clk;
- input rst;
- wire sign1;
- output sign2;
- A a1
- (
- .rst(rst),
- .clk(clk),
- .sign1(sign1)
- );
- B B1
- (
- .rst(rst),
- .clk(clk),
- .sign1(sign1),
- .sign2(sign2)
- );
- endmodule
如果按道理来说如果clk同时到达的话,A模块对sign1进行置位的时刻,B已经完成对数据sign1的检测,而sign1物理传输到B还要时间,所以这样本来应该会导致在一个时钟沿不能完成想要的功能,但是结果根据我这几个月做的东西来看,都是满足的。
所以我有以下的猜想
1.有可能是当综合软件检测到有这样行为的时候,会在综合时对布线进行控制,使得clk到达A的时间稍微早于B,那样就可以满足A的信号变化传递到B模块时clk才到B模块,使得模块不出问题。
2.综合软件并不会对布线进行控制,并且clk确实是同时到达,但是因为信号在线上的延时时间远小于寄存器建立时间,所以即使晚传递到B的信号也有足够的寄存器建立时间去建立数据,所以没有问题。
以上就是我自己的猜想,不知道是不是正确,如果都不正确那么究竟是怎么出现这样的情况呢。
希望懂的人能够回答,另外希望能够附上与这个问题相关资料供大家分享
刚开始学FPGA因为什么都不懂,也不懂什么亚稳态什么所以写起模块很容易,觉得很简单,写出来也是好使的,越是学的深了就越觉得无从入手,总是怕出现亚稳态,现在每写模块的时候都要考虑再三但是最后一分析还是存在可能导致亚稳态的问题。
我可以很负责的高速你,你关于综合、布线的猜想全是错误的,而且很明显你现在的知识积累,还没有达到讨论那些程度,你先在把寄存器时序搞清楚了再说吧,你说的问题,是很简单的寄存器时序问题,两个always都同步于clk,比如在前1刻,sign1为0,经过1个clk的上升沿后,sign1为1,那么请问,在这个clk的上升沿,moduleB的always里会检测到sign1为1而导致sign2变成1吗?
答案是no,你自己仿真下就清楚了,它会在下一个clk的上升沿,才会检测到sign1为1,从而把sign2变成1。
你肉眼上看到sign2确实在变化,却没有搞清楚sign1和sign2变化的时钟关系,所以导致你的那些乱猜想,其实是很简单的寄存器时序而已。
或者换个说法,在这个上升沿,sign1任是0,moduleB里在这个上升沿检测到的sign1任然是0,所以sign2根本不会变化,而这个上升沿后,sign1变成了1,所以在下一个上升沿,moduleB检测到sign1变成了1,才会把sign2变成1。
你说对了一点,sign1变成1,和moduleB里检测sign1是否为确实是在同一个clk的上升沿,但是后面全是乱猜哈,你要纠正思路,这是很简单的时序。
哦,想起来了,昨天晚上脑子有点转不过弯就和用
<= 一样,都是我没有表达清楚,是A模块翻转一个电平,另一个模块检测这个电平做出相应的反应,如果这样呢在同一个时钟,都是在沿检测电平,同一个时钟A翻转电平,B检测电平,最后会出现什么样的结果
你说的问题,其实和你的之前的疑惑是一样的,你先要知道你要做的电路,会以寄存器时序逻辑的方式实现,还是以组合逻辑的方式实现,寄存器一定是检测时钟沿前面的状态,而组合逻辑只会跟着电平变化。
比如,把你moduleB里面的always去掉,改为
assign sign2 = sign1 ? 1'b1 : 1'b0;
那么sign2一定跟随sign1的变化而变化,什么时候sign变成1,同时sign2就会变成1,不会晚一个时钟周期,如果按照你现在寄存器方式检测,sign2就会晚一个时钟周期变为1。
就这么简单,自己好好去推敲下吧,这是逻辑设计最基本的东西。
如果要直言回答你的问题,sign2和sign1都以寄存器的方式实现,一个clk上升沿到来时,sign1由1变0,请问这个clk的上升沿后sign2是会变成0还是1,是吧? 答案是,sign2会变1,因为clk上升沿检测到sign之前的状态时1,所以sign2在这个clk的上升沿后会变成1。
你要相信,初学者,其实很难碰到那种亚稳态、布线等等时序问题,要等你的FPGA工程上了一定规模才会碰到,出了问题,多从理论下手解决,如果你连基本的理论都没有掌握好,到了真正的时序问题,你会无从下手。
楼上正解,学习了。
我也思考过类似问题,楼上正解!
楼上正解,初学时候时序最容易乱
楼上的大哥说的很好,受教了
楼上哥们,说的太好了,受益匪浅。
说的很中肯,学习了