【設計開發】 典型同步電路設計- 同步FIFO

1、前言異步

  FIFO (First-In-First-Out) 是一種先進先出的數據交互方式,在數字ASIC設計中經常被使用。FIFO按工做時鐘域的不一樣又能夠分爲:同步FIFO和異步FIFO。spa

  同步FIFO的寫時鐘和讀時鐘爲同一個時鐘,FIFO內部全部邏輯都是同步邏輯,經常用於交互數據緩衝。異步FIFO的寫時鐘和讀時鐘爲異步時鐘,FIFO內部的寫邏輯和讀邏輯的交互須要異步處理,異步FIFO經常使用於跨時鐘域交互。設計

  本文介紹同步FIFO的典型設計方法。3d

 

2、原理code

  典型同步FIFO有三部分組成: (1) FIFO寫控制邏輯; (2)FIFO讀控制邏輯; (3)FIFO 存儲實體(如Memory、Reg)。blog

  FIFO寫控制邏輯主要功能:產生FIFO寫地址、寫有效信號,同時產生FIFO寫滿、寫錯等狀態信號;ip

  FIFO讀控制邏輯主要功能:產生FIFO讀地址、讀有效信號,同時產生FIFO讀空、讀錯等狀態信號。input

   

 

  以下圖所示,FIFO讀寫過程的地址控制:同步

  (1)當FIFO初始化(復位)時fifo_write_addr與fifo_read_addr同指到0x0,此時FIFO處於空狀態;it

  (2)當FIFO進行寫操做時,fifo_write_addr遞增(增長到FIFO DEPTH時迴繞),與fifo_read_addr錯開,此時FIFO處於非空狀態;

  (3)當FIFO進行讀操做時,fifo_read_addr遞增;

  

 

  FIFO空滿狀態產生:

  爲產生FIFO空滿標誌,引入FIFO Count計數器,FIFO Count寄數器用於指示FIFO內部存儲數據個數;

  (1)當只有寫操做時,FIFO Count加1;只有讀操做是,FIFO Count減1;其餘狀況下,FIFO Count保持;

  (2)當FIFO Count爲0時,說明FIFO爲空,fifo_empty置位;

  (3)當FIFO Count等於FIFO_DEPTH時,說明FIFO已滿,fifo_full置位;

  

3、代碼

 

  1 //--====================================================================================--
  2 // THIS FILE IS PROVIDED IN SOURCE FORM FOR FREE EVALUATION, FOR EDUCATIONAL USE OR FOR 
  3 // PEACEFUL RESEARCH.  DO NOT USE IT IN A COMMERCIAL PRODUCT . IF YOU PLAN ON USING THIS 
  4 // CODE IN A COMMERCIAL PRODUCT, PLEASE CONTACT JUSTFORYOU200@163.COM TO PROPERLY LICENSE 
  5 // ITS USE IN YOUR PRODUCT. 
  6 // 
  7 // Project      : Verilog Common Module
  8 // File Name    : sync_fifo_ctrl.v
  9 // Creator(s)   : justforyou200@163.com
 10 // Date         : 2015/12/01
 11 // Description  : A sync fifo ctrl
 12 //
 13 // Modification :
 14 // (1) Initial design  2015-12-01
 15 //
 16 //
 17 //--====================================================================================--
 18 
 19 module SYNC_FIFO_CTRL
 20     (  
 21         clk           ,
 22         rst_n         ,
 23         fifo_wr_en    ,     
 24         fifo_rd_en    ,
 25         fifo_wr_data  ,  
 26         fifo_full     ,
 27         fifo_wr_err   ,
 28         fifo_empty    ,
 29         fifo_rd_err   ,
 30         fifo_data_cnt ,
 31         fifo_rd_data 
 32     );
 33  
 34 //PARA   DECLARATION
 35 parameter FIFO_DATA_WIDTH = 32   ; 
 36 parameter FIFO_ADDR_WIDTH = 8    ; 
 37 
 38 //INPUT  DECLARATION
 39 input                           clk          ; //fifo clock 
 40 input                           rst_n        ; //fifo clock reset (0: reset)
 41 input                           fifo_wr_en   ; //fifo write enable(1: enable)
 42 
 43 input                           fifo_rd_en   ; //fifo read enable(1: enable)
 44 input   [FIFO_DATA_WIDTH-1:0]   fifo_wr_data ; //fifo write data
 45 
 46 //OUTPUT DECLARATION
 47 output                          fifo_full    ; //fifo full status
 48 output                          fifo_wr_err  ; //fifo write error status
 49 output                          fifo_empty   ; //fifo empty status
 50 output                          fifo_rd_err  ; //fifo read error status
 51 output  [FIFO_ADDR_WIDTH  :0]   fifo_data_cnt; //fifo valid data cnt
 52 output  [FIFO_DATA_WIDTH-1:0]   fifo_rd_data ; //fifo read data
 53 
 54 //INTER  DECLARATION
 55 wire                            fifo_full    ; //fifo full status
 56 wire                            fifo_wr_err  ; //fifo write error status
 57 wire                            fifo_empty   ; //fifo empty status
 58 wire                            fifo_rd_err  ; //fifo read error status
 59 reg     [FIFO_ADDR_WIDTH  :0]   fifo_data_cnt; //fifo valid data cnt
 60 reg     [FIFO_DATA_WIDTH-1:0]   fifo_rd_data ; //fifo read data
 61 reg     [FIFO_ADDR_WIDTH-1:0]   fifo_wr_addr ; //fifo write addr
 62 reg     [FIFO_ADDR_WIDTH-1:0]   fifo_rd_addr ; //fifo write addr
 63 
 64 //FIFO MEMORY INSTANCE
 65 reg [FIFO_DATA_WIDTH-1:0] fifo_mem [{(FIFO_ADDR_WIDTH){1'b1}}:0] ;
 66 integer i ;
 67 
 68 //--========================MODULE SOURCE CODE==========================--
 69 
 70 //--=========================================--
 71 // SRAM INSTANCE :
 72 // You Can use Reg Memory or Memory model here;
 73 // FIFO Wdata & FIFO Rdata;
 74 //--=========================================--
 75 always @(posedge clk or negedge rst_n)
 76 begin
 77     if(rst_n == 1'b0)
 78     begin
 79         for(i=0;i<= {(FIFO_ADDR_WIDTH){1'b0}};i=i+1)
 80         fifo_mem[i] <= {(FIFO_DATA_WIDTH){1'b0}} ;
 81     end
 82     else if (fifo_wr_en & (~ fifo_full))
 83         fifo_mem[fifo_wr_addr] <= fifo_wr_data ;         
 84 end
 85 
 86 always @(posedge clk or negedge rst_n)
 87 begin
 88     if(rst_n == 1'b0)
 89         fifo_rd_data <= {(FIFO_DATA_WIDTH){1'b0}} ;
 90     else if (fifo_rd_en & (~ fifo_empty))
 91         fifo_rd_data <= fifo_mem[fifo_rd_addr] ;         
 92 end
 93 
 94 //--=========================================--
 95 // READ CONTROL :
 96 // Read address increase when read enable AND
 97 // Not empty;
 98 //--=========================================--
 99 always @(posedge clk or negedge rst_n)
100 begin
101     if(rst_n == 1'b0)
102         fifo_rd_addr <= {(FIFO_ADDR_WIDTH){1'b0}} ;
103     else if (fifo_rd_en & (~ fifo_empty))
104         fifo_rd_addr <= fifo_rd_addr + 1'b1 ;         
105 end
106 
107 //--=========================================--
108 // WRITE CONTROL :
109 // Write address increase when write enable AND
110 // Not full.
111 //--=========================================--
112 always @(posedge clk or negedge rst_n)
113 begin
114     if(rst_n == 1'b0)
115         fifo_wr_addr <= {(FIFO_ADDR_WIDTH){1'b0}} ;
116     else if (fifo_wr_en & (~ fifo_full))
117         fifo_wr_addr <= fifo_wr_addr + 1'b1 ;         
118 end
119 
120 //--=========================================--
121 // FIFO DATA CNT :
122 // Valid Write Only, increase data cnt;
123 // Valid Read Only, decrease data cnt;
124 //--=========================================--
125 always @(posedge clk or negedge rst_n)
126 begin
127     if(rst_n == 1'b0)
128         fifo_data_cnt <= {(FIFO_ADDR_WIDTH + 1){1'b0}} ;
129     else if (fifo_wr_en & (~ fifo_full) & (~(fifo_rd_en & (~fifo_empty)))) //Valid Write Only, increase data cnt;
130         fifo_data_cnt <= fifo_data_cnt + 1'b1 ;   
131     else if (fifo_rd_en & (~ fifo_empty) & (~(fifo_wr_en & (~fifo_full)))) //Valid Read Only, decrease data cnt;
132         fifo_data_cnt <= fifo_data_cnt - 1'b1 ;     
133 end
134 
135 //--=========================================--
136 // FIFO Status :
137 // 1. fifo_empty when cnt ==0 ;
138 // 2. fifo full when cnt == MAX ;
139 //--=========================================--
140 assign fifo_empty  = (fifo_data_cnt == 0 ) ;
141 assign fifo_rd_err = (fifo_data_cnt == 0 ) & fifo_rd_en ;
142 
143 assign fifo_full   = (fifo_data_cnt == ({(FIFO_ADDR_WIDTH){1'b1}} +1) ) ;
144 assign fifo_wr_err = (fifo_data_cnt == ({(FIFO_ADDR_WIDTH){1'b1}} +1) ) & fifo_wr_en ;
145 
146 endmodule

 

4、仿真

相關文章
相關標籤/搜索