FIFO是实现多位宽数据的异步跨时钟域操作的常用方法,相比于握手方式,FIFO一方面允许发送端在每个时钟周期都发送数据,另一方面还可以对数据进行缓存。需要注意的是对FIFO控制信号的管理,以避免发生“写满”后继续写或“读空”后继续读的状况。这些控制信号包括写时钟域下的写使能信号(wr_en,输入)和写满标记信号(full,输出),读时钟域下的读使能信号(rd_en,输入)和读空标记信号(empty,输出),如下图所示。图中黑色标记信号为必选信号如输入/输出数据信号2(din/dout),蓝色标记信号为可选信号如快满/快空信号(almost_full/almost_empty)。
无论是通过XPM方式(XPM_FIFO)还是IP方式(FIFO Generator),都需要注意,因为这里针对的是异步跨时钟域情形,所以XPM应选择xpm_fifo_async,使用IP时应选择Independent Clocks,如下图所示。
从约束层面看,无论是XPM_FIFO还是IP方式,都会有自带的约束,如下图所示。这些自带约束包括set_max_delay,set_bus_skew和set_false_path,如图中蓝色方框内容所示。尤其要注意的是set_max_delay约束,由于其优先级较set_clock_groups和set_false_path低,故要避免该约束被其所覆盖,导致约束失效。
具体来说,如果wr_clk和rd_clk两个时钟域下除了通过FIFO隔离的路径外,还有其他跨时钟域路径,对于这些跨时钟域路径,倘若直接采用set_clock_groups进行约束,如下图所示,那么就会导致FIFO自带的set_max_delay被覆盖掉。这可通过命令report_exceptions查看,如下图所示,注意图中红色方框标记。
在这种情形下,显然不能再用set_clock_groups进行约束。那么该如何对这些跨时钟域路径约束呢?我们分情况讨论。如果对这些跨时钟域路径操作使用的是XPM_CDC,那么Vivado会直接使用其自带约束,这些自带约束的作用域仅限于XPM_CDC,所以不会覆盖FIFO自带约束。如果对这些跨时钟域路径操作使用的是用户模块,那么在约束时,若确认为伪路径,应使用set_false_path,同时-from和-to的对象应使用get_cells或get_pins获取,而不能使用get_clocks获取。如果cell较多,而且也无法用通配符完全匹配到,那么可以使用如下方式:即仍使用set_max_delay外加选项-datapath_only,-from和-to的对象仍通过get_clocks获取,而延迟值可以填一个很大的值,如这里的50(代表50ns),这样就等效于set_false_path。report_exceptions的结果也显示FIFO自带约束没有被覆盖,如下图所示。
综上所述,使用异步FIFO完成多位宽数据的跨时钟域操作时,要注意FIFO自带有set_max_delay约束,确保该约束不会被set_false_path或set_clock_groups所覆盖,否则可能发生时序收敛,但系统不能正常工作的情形。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !