对于含有脉冲触发的模块,最容易忽视,同时也是最难受的就是与其他不同时钟的模块传输数据时的信号同步问题,因为可能带来数据冲突或者亚稳态状况。
数据冲突
比如这张图:
pulse作为触发信号,上升沿有效,触发时计数器counter+1;
cpu_cs作为并行模块的触发信号,下降沿有效,触发时data_bus读取counter的数据。
当然,触发信号都含有clk(系统时钟),且上升沿有效。
再次看这张图,pulse与cpu_cs同时触发了,但此时counter正处在+1状态,可是我们不能知道data_bus读取的是counter还是counter+1.
造成这一切的原因是实际信号含有上升时间和下降时间,并不是理想的方波。
脉冲检测法获得新的使能信号
verilog写法就不在赘述了,网上很多。下面用简介的话解释怎么做到的,如下图所示:
pos_en与rd_en是新的触发信号(对应原先的pulse和cpu_cs)
pos_en的获得:模块内部存在两个寄存器preg1,preg2。其中,preg1在clk上升沿触发时赋予pulse的值并保持,preg2在clk上升沿触发时延时(下一个周期)赋予pulse的值并保持(preg2相比于preg1延迟了一个时钟周期),时序图可以参考上图,然后两个寄存器的值可以按照下述方法获得pos_en(其他方法自然也可以):
pos_en=preg1&(~preg2)
这样得到的poe_en是新的触发脉冲,注意到这个脉冲是与clk同步的。
rd_en的获得:类似地可以获得rd_en,这个脉冲也是与clk同步的;
由于新的触发信号都与系统时钟同步,所以两个异步时钟域的信号就不会出现读/写冲突的情况了。
Notes:
在FPGA开发中,同步设计可以稳定、可靠地实现既定功能,也可以提高设计的实现、测试、调试及维护效率。