zoukankan      html  css  js  c++  java
  • Normal synchronous FIFO mode 和 Show-ahead synchronous FIFO mode

    FIFO是先进先出,可以用fifo来处理跨时钟域的数据传输问题,用到的地方特别多,一定要搞会。

    在学习调用fifo的IP核中发现有normal synchronous FIFO mode 和 Show-ahead synchronous FIFO mode这两种模式,就研究一下。

    研究 IP 核最方便的方式就是用 modesim 仿真一下,这样关系就会很明了。

    下面的两幅图是我用 Time_Gen 软件自己总结画的,并不是 modesim 的仿真图。

    假定存入fifo的第一个数是01,第二个数是02,第三个数是03,以此类推。。。

    clk是读时钟,rd是读使能,q是fifo的数据输出端

    normal mode,只有在读使能信号有效的时候,才会在读时钟上升沿来的时候输出第一个数01。

    Show-ahead 模式的输出要比 normal 模式的输出早一拍,意思是只要FIFO中有数据,他就会把第一个数据输出,

    当第一个读使能信号来的时候,则会在读时钟上升沿的时候输出第二个数据02。

     

                              Normal mode                                                     Show-ahead mode

    既然二者的区别是数据输出相差一拍,因此在设计 fifo 的时候就要根据不同的模式进行设计

    下面举个例子,该代码实现了100Mhz 与 80Mhz 不同时钟域的数据传输问题

    因为不同时钟域的频率不同,在进行数据传输的时候如果不进行处理必然会有数据丢失

    FIFO 可以缓存数据,因此我们可以先把数据放在 fifo 里,再进行传输

    当fifo中的数据 resudw>=某个数的时候,就不允许往 fifo 中写入数据,当 FIFO 空的时候也不允许再读数据。


    module fifo(
    rst_n , clk_in ,
    //100Mhz ,fifo写时钟 data_in , //输入的数据 data_in_vld,//输入数据有效指示信号 clk_out , //80Mhz ,fifo读时钟 data_out , //输出的数据 data_out_vld,//输出数据有效指示信号 b_rdy //当为高,表示可以接收从fifo中读的数据,反之则不行 ); input rst_n ,clk_in,clk_out,b_rdy; input [15:0] data_in ; input data_in_vld ; output[15:0] data_out ; output[15:0] data_out_vld; reg wr_ff0; wire wr_ff1; wire[15:0] q; reg[7:0] data_out; reg data_out_vld; reg rd_ff0; wire rdempty ; wire wrfull ; wire[5:0] wrusedw;
    //调用IP核生成位宽为16 位,深度为64的FIFO, Show-ahead模式 my_fifo u1_fifo( .data (data_in), .rdclk(clk_out), .rdreq(rd_ff0), .wrclk(clk_in), .wrreq(wr_ff1), .q (q), .rdempty(rdempty), .wrfull (wrfull ), .wrusedw(wrusedw) );
    //---------------------------------------------------------------------- //写满保护 always @(*)begin if(wrusedw>=61) begin wr_ff0<=0; end else wr_ff0<=1; end assign wr_ff1 = (data_in_vld && wr_ff0)?1'b1:1'b0; //rd_ff0 always @(*)begin if(b_rdy==1&&rdempty==0 )begin rd_ff0<=1; end else rd_ff0<=0; end //-------------------------------------------------------------
    //如果是Show-ahead 模式入,此时data_out与data_out_vld是对齐的
    //如果是normal 模式,则需要将rd_ff0在多打一拍,然后将rd_ff1值给data_out_vld才能对齐
    always @(posedge clk_out or negedge rst_n)begin
    if(rst_n==1'b0)begin data_out<=0; end else begin data_out<=q; end end always @(posedge clk_out or negedge rst_n)begin if(rst_n==1'b0)begin data_out_vld<=0; end else begin data_out_vld<=rd_ff0; end end

    endmodule

     文章出处:http://www.cnblogs.com/aslmer/p/5872412.html

  • 相关阅读:
    无限维
    黎曼流形
    why we need virtual key word
    TOJ 4119 Split Equally
    TOJ 4003 Next Permutation
    TOJ 4002 Palindrome Generator
    TOJ 2749 Absent Substrings
    TOJ 2641 Gene
    TOJ 2861 Octal Fractions
    TOJ 4394 Rebuild Road
  • 原文地址:https://www.cnblogs.com/aslmer/p/5872412.html
Copyright © 2011-2022 走看看