近期参与的项目涉及到异步时钟域下多bit位数据传输的问题,解决的最好的办法便是异步FIFO。在网上查了相关的异步FIFO的资料,对于读写侧数据位宽相同情况下的异步FIFO有所了解。若要是读写侧数据位宽不同就再合适不过了,经过自己的一些改变,完成了该实现。理论知识网上介绍的很是详细明了,咱们索性单刀直入,直捣黄龙。
一、总体实现架构图
总体实现架构图并没有变化,依旧包括存储模块、读指针及满生成模块、写指针及空生成模块及其两级数据同步模块。
二、读、写指针生成模块
本次设计的异步FIFO输入、输出数据分别为96bit、192bit。为了方便读写地址的设置,FIFO Memeory的宽度设置为24bit,深度设置为16。这样在数据加载时,每个wclk写指针wptr增加4(96/24),在有足够数据读出时,每个rclk读指针rptr增加8(192/24)。关于宽度及深度的设置也许不是最理想的,但是自己认为能够比较好的说明问题。感兴趣的话,也可以去网上查一下理想的深度设置。
读指针的生成实现架构图。
//-----------wptr---------------------------
always@ (posedge wclk or negedge wrst_n)
begin
if(wrst_n == 1'b0) begin
wptr <= 5'd0;
end
else if(w_en && ~wfull)
wptr <= wptr + 3'b100;
end
写指针生成实现架构图。
//-----------rptr---------------------------------
always@ (posedge rclk or negedge rrst_n)
begin
if(rrst_n == 1'b0) begin
rptr <= 5'd0;
end
else if(r_en && ~rempty && enough_data)
rptr <= rptr + 4'b1000;
end
其中写指针wptr、读指针rptr位宽均为5bit。对于深度为16的Memeory来说,地址宽度4bit即够,增加一位用于判断空满信号的准确生成。
三、满、空信号及其enough_data信号生成
跨时钟域数据必存在亚稳态问题,对于单bit数据传输一般采用双寄存器方法减小发生的概率。这里涉及到读指针rptr同步到写时钟域wclk下,wptr同步到读时钟域rclk下的多bit位宽数据跨时钟域传输的问题。若是二进制编码形式的指针在变化时并不是每次只变换1bit,而双寄存器方法适用于单bit数据变换的情况,这时采用格雷码编码形式可以