微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 异步FIFO的跨时钟域同步问题,求大神讲解

异步FIFO的跨时钟域同步问题,求大神讲解

时间:10-02 整理:3721RD 点击:
我自己写了一个FIFO,但是我总是不理解Paper中讲的要把读写指针同步,如果我将两个不同时钟产生的读写地址直接比较,产生读写,请问这个亚稳态是怎么产生的,不要复制网上的那些东西,我都看了买就是不太懂,才问的,下面是我的代码
//asysfifo 8*8bit
module asys_fifo(
                                                                w_clk,r_clk,w_en,r_en,rst,din,dout,empty,full);
input                                                w_clk,r_clk;
input                                                w_en,r_en;//high valid
input                                                rst;      //low valid
input                [7:0]                din;
output        [7:0]                dout;
output                                        empty,full;//empty,full flag bit,high valid
reg                                                        empty,full;
reg                        [7:0]                dout;
//internal signal defenition
reg                        [7:0]                asys_fifo[7:0];        //asys_fifo ram
reg                        [2:0]                w_addr;                                                //write address
reg                        [2:0]                r_addr;                                        //read address
//MSB defenition
reg                                                        w_msb;
reg                                                        r_msb;
//write data read data
always @(posedge w_clk)
        if(w_en&&!full)
                asys_fifo[w_addr]<=din;
always @(posedge r_clk)
        if(r_en&&!empty)
                dout<=asys_fifo[r_addr];
        else
                dout<=8'dz;
//write address read address and w_msb r_msb generation
always @(posedge w_clk,negedge rst)
        if(!rst)
                begin
                w_addr<=3'b000;
                w_msb<=0;
                end
        else if(w_en&&!full)
                                        begin
                                        if(w_addr==3'b111)
                                                begin
                                                w_addr<=3'b000;
                                                w_msb<=!w_msb;        //MSB qu fan
                                                end
                                        else
                                                begin
                                                w_addr<=w_addr+3'd1;
                                                w_msb<=w_msb;
                                                end
                                        end
                        else
                                        begin
                                        w_addr<=w_addr;
                                        w_msb<=w_msb;
                                        end
always @(posedge r_clk,negedge rst)
        if(!rst)
                begin
                r_addr<=3'b000;
                r_msb<=0;
                end
        else if(r_en&&!empty)
                                begin
                                if(r_addr==3'b111)
                                        begin
                                        r_msb<=!r_msb;
                                        r_addr<=3'b000;
                                        end
                                else
                                        begin
                                        r_msb<=r_msb;
                                        r_addr<=r_addr+3'd1;
                                        end
                                end
                        else
                                begin
                                r_msb<=r_msb;
                                r_addr<=r_addr;
                                end
//empty,full flag generation
//empty flag generation
always @(*)
        if(!rst)
                empty<=1;
        else if({r_msb,r_addr}=={w_msb,w_addr})
                                empty<=1;
                        else
                                empty<=0;
//full flag generation
always @(*)
        if(!rst)
                full<=0;
        else if((r_msb!=w_msb)&&(r_addr==w_addr))
                                full<=1;
                        else
                                full<=0;
endmodule
               

自己顶起来,不敢沉底

时钟相位不同步,可能踩不到正确数据

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top