FPGA DDR2接口設計

DDR2接口主要實現用戶數據和實際物理接口之間的連接,實現對大容量數據進行高速緩存。處理高低速傳輸問題。

首先要了解DDR2工作原理,熟悉所連接的內存顆粒說明書瞭解適用範圍,產生適合硬件的DDR2 IP核源文件,查閱DOC下的內核說明書,瞭解內核內容結構,然後做出相應的改動,如時鐘匹配,需匹配爲生成核時工作時鐘,針對用戶的接口除了時鐘之外,主要有三部分接口組成,它們分別是地址命令產生器,寫數據FIFO, 讀數據FIFO接口。地址產生器主要給你選定的突發長度類型產生相應的地址偏移,例如以4的突發長度讀寫,在寫數據時一個CLK 內DDR2根據時鐘邊沿跳變次數會產生兩次寫數據,以長度爲4的突發寫,就需要給一次地址,DDR2控制器會自動寫4次數據,地址偏移依用戶給出的地址依次累加(基址+1),所以用戶控制寫數據,只需每兩個CLK給出一個至少偏移爲4的地址,寫數據如下圖一所示,具體詳情見ip核文件下DOC裏說明書。

圖一

DDR2讀數據,則不同於DDR2寫數據,需要用戶在每個CLK都要給出ADDR地址,讀取數據地址還是以突發讀寫長度爲偏移,每次加4,具體的時序過程如下圖二所示,圖中給出他以4爲長度突發讀連續讀出16次數據,地址輸入佔用4個CLK, 讀數據需要至少8個clk週期。

具體實現過程可以參考ip核列化程序,app應用部分example下的ddr2_tb_test等程序及仿真文件觀察波形可看出數據傳輸過程。

以下是一個RGB信號存儲的簡單地址產生器程序供參考。

//****************************************************************

 

`timescale 1ns/1ps

 

module ddr2_tb_addr_gen #

 (

  

  // the test module for actual values.

  parameter BANK_WIDTH = 3,

  parameter COL_WIDTH  = 10,

  parameter ROW_WIDTH  = 14,

         parameterone_rgb_cnt=24 //8:0_4_8   28<*3<32//120000-4     //rgb zhong  ,R de di zhi fan wen ,EXP: (800*600*8)/32

  )

 (

  input             clk,

  input             rst,

//      input             rst1,

  input             addr_ren,

         input             addr_gen,

         input             addr_ben,

  input             wr_addr_en,

 //output reg [2:0]  app_af_cmd,

  output reg [30:0] app_af_addr,

  output reg        app_af_wren

  );

 

 

 localparam r_star_ad=0;

 localparam g_star_ad=41943040;

 localparam b_star_ad=134217700;

 reg             wr_addr_en_r1;

 // reg [2:0]       af_cmd_r;

 reg [30:0]      af_addr_r;

 reg             af_wren_r;

// wire [15:0]     ramb_addr;

 // wire [35:0]     ramb_dout;

 reg             rst_r

                  /* synthesis syn_preserve = 1*/;

 reg             rst_r1

                  /* synthesis syn_maxfan = 10*/;

 reg [30:0]       wr_addr_cnt;

 reg             wr_addr_en_r0;

 reg [30:0]      wr_addr_allcnt;

 

 

 // INIP_OO: read 1

 // INIP_OO: write 0

 //***************************************************************************

 

 // assign ramb_addr = {5'b00000, wr_addr_cnt,5'b00000};

 

 

 

 // register backend enables / FIFO enables

 // write enable for Command/Address FIFO is generated 2 CC afterWR_ADDR_EN

 // (takes 2 CC to come out of test RAM)

 always @(posedge clk)

   if (rst ) begin

      app_af_wren   <= 1'b0;

      wr_addr_en_r0 <= 1'b0;

      wr_addr_en_r1 <= 1'b0;

      af_wren_r     <= 1'b0;

   end else begin

      app_af_wren <= wr_addr_en;

    

     

   end

 

 // address input for RAM

 always @ (posedge clk)

   if (rst)

          begin

      wr_addr_cnt <= 0; //8 'h0000_0000;

                   wr_addr_allcnt<=0; // 9 'h0_0000_0000;

                   end

   else //if (wr_addr_en)

              

                                if (wr_addr_en && addr_ren&& !addr_gen && !addr_ben)

                                  begin

                             

                if(wr_addr_cnt<one_rgb_cnt)   //800*600 R 8 BIT  48_0000*8 //0-R

                                         begin

                                                

                                   app_af_addr<=wr_addr_cnt+r_star_ad;

                                                wr_addr_cnt <= wr_addr_cnt + 4;

                                         end 

              else

                                        begin

                                        wr_addr_cnt <=0;

              app_af_addr<=wr_addr_cnt+r_star_ad; 

               end                                         

             end                                      

                           else

                                       if (wr_addr_en && !addr_ren&& addr_gen && !addr_ben)

                                              begin

                                               if(wr_addr_cnt<one_rgb_cnt)  //40-79

                                                  begin                 

                                                 app_af_addr<=wr_addr_cnt+g_star_ad;

                         wr_addr_cnt <=wr_addr_cnt + 4;                                                                                                             ////41943040;   // R-2R

                                                  end

                      else

                                                                     begin

                                                               wr_addr_cnt <=0;     

                                                                            app_af_addr<=wr_addr_cnt+g_star_ad;

                                                                            end

                     end        

               else                                                           

                                               if(wr_addr_en && !addr_ren && !addr_gen && addr_ben)

                                                       begin

                                                        if (wr_addr_cnt<one_rgb_cnt)//80-119

                                                   begin

                                      app_af_addr<=wr_addr_cnt+b_star_ad; 

                          wr_addr_cnt <= wr_addr_cnt+ 4;   //83886080; //2R-3R

                                                   end

                                                                            else

                                                                             begin

                                                                             wr_addr_cnt <=0;       

                          app_af_addr<=wr_addr_cnt+b_star_ad;

                          end                                                                         

                                                       end

                                     else           

                  app_af_addr<=31'bx;

                                                       

                                                       

endmodule

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章