上圖是terasic公司提供的SDRAM控制器,大部分已經封裝好,我們需要修改其中部分代碼,以此來實現我們自己需要的功能。
1.PLL時鍾設定
首先上面的sdram_pll.v中產生上一篇博客所需要的“驅動時鍾”和“控制時鍾”,這兩個時鍾由於PCB走線延時,兩個時鍾會有一定的時間差,一般會設定在-3ns ~ 1ns之間。如下圖所示:
上圖是對SDRAM的PLL進行的更改,這個時鍾差設定多少沒有嚴格規定,可以先設定一個值,讀取出圖像進行調試,看圖像是否幀錯位或者圖像顯示不正確等原因,多是由於PLL沒有配置好所導致,可以修改此部分進行修改,重新設定。
2.SDRAM_parameter.h 參數設置
之前在VGA顯示一篇博客中,就用到了這種思想,就是將常用的參數設定在一個.h文件或者.v文件,然后利用 `include "Sdram_Params.h"加載進來即可。
在此模塊中,我們需要將常用到的一些參數設置好,主要用到以下一些參數:
(1) SDRAM parameter.h
筆者使用H57V2562GTR和H57V641620E系列,再此以H57V2562GTR為例。
//==================================================
//address space parameters
// 4M x 4 x 16bit = (8192 x 512)x 4 x 16bit = 256Mbit 注意,8192和512分別為行數和列數。
//行和列的地址,行是12位的,列是8位的,所以會用到這樣的乘積。
//宏定義的參數
‘define ROWSIZE 13 //行的寬度在一個bank中
‘define COLSIZE 9 //列的寬度在一個bank中
‘define DSIZE 16 //width of data bus to SDRAM 16bit SDRAM data
‘define BANKSIZE 2 //4 banks in one SDRAM
//所利用宏定義的參數
‘define COLSTART 0
‘define ROWSTART ‘COLSIZE
‘define BANKSTART ‘COLSIZE + ‘ROWSIZE
‘define ASIZE ‘ROWSIZE + ‘ COLSIZE + ’ BANKSIZE
//==================================
//上述是對SDRAM的位寬,行寬,列寬,行起始,列起始,bank數,進行設置。已經最大限度參數化,對
//於同一類hynix這一部分所需要更改的只需更改ROWSIZE和COLSIZE以及DSIZE即可。
//==================================================
(2) 按照SDRAM的驅動流程,那么接下來應該是先200us的SDRAM的穩定啟動。
INIT_PER = 200us / T = 200 x 10^3ns / (1000/CLK) = 200 x CLK;
其中CLK為xxMHz的驅動時鍾頻率,已經轉換為ns狀態下,所以為1000/clk。以上是計算出來的是延時計 數,就是一開始上電之后,先有一個200us的延時。
比如驅動時鍾頻率為100MHz,則INIT_PRE = 20000;
比如驅動時鍾頻率為133MHz,則INIT_PRE = 26600;
//==================================================
(3) 預刷新計數的宏定義
存儲器上面的手冊的信息是64ms必須完成所有邏輯單元的更新,主要是希望保證SDRAM數據不丟失的前提下,盡可能提高SDRAM的有效帶寬,因此設置64ms為刷新間隔上限。
行刷新周期時間 = 64ms / 每個bank的行數.
例如,如果有4096行,則行刷新周期為 64ms / 4096 = 15.625us。
例如,如果有8192行,則行刷新周期為 64ms / 8192 = 7.8125us。
所以REF_PER = 15.625us / (1000/CLK) =15.625 x 10^3 ns / (1000/CLK) = 15.625 x CLK (對應有4096行)
REF_PER = 7.8125us / (1000/CLK) =7.8125 x 10^3 ns / (1000/CLK) = 7.8125x CLK (對應有8192行)
只要至少在預刷新的時間內刷新一次即可,若是有小數部分,可以取最大的整數,忽略小數部分,取最大的整數。
如4096行采用100MHz 時鍾頻率進行驅動,則15.625 x 100 = 1562/1563均可。
//==================================================
(4) SC_CL潛伏期延時的宏定義
SC_CL為SDRAM列選通命令的潛伏期延時設定,手冊規定為2或者3;潛伏期的延時大小直接關系到SDRAM的最高運行速率,因此一般選擇3。
定義SC_CL的宏后,會映射到SDR_CL的宏上,這個直接關系到最終的潛伏期選擇,
parameter SDR_CL = (SC_CL == 2)? 3’b10 : 3’b11;
//==================================================
(5) SC_RCD數據讀取延時定義
保持默認值3
//==================================================
(6) SC_PM突發長度命令宏定義
這里采用了全頁突發讀/寫操作,因此直接設置為A2A1A0 = 1 1 1;
為了便於其他模式修改:通過宏定義選擇突發讀寫長度:
parameter SC_BL = 1;
//SDRAM parameter
parameter SDR_BL = (SC_PM == 1)? 3’b111: //page 256
(SC_BL == 1)? 3’b000: //1
(SC_BL == 2)? 3’b001: //2
(SC_BL == 4)? 3’b010: //4
3’b011; //8
//==================================================
(7) 突發順序/交錯讀/寫宏定義
一般在視頻流的操作中采用順序讀/寫,這里的宏定義如下:
parameter SDR_BT = 1’b0 ; // 順序讀/寫 A3 = 0
// 1’b1; // 交錯讀/寫 A3 = 1;
以上就是所有SDRAM所需要設定的參數。
//==================================================
//下面是terasic 公司的SDRAM參數設置。
// Address Space Parameters
`define ROWSTART 8
`define ROWSIZE 12
`define COLSTART 0
`define COLSIZE 8
`define BANKSTART 20
`define BANKSIZE 2
// Address and Data Bus Sizes
`define ASIZE 23 // total address width of the SDRAM
`define DSIZE 16 // Width of data bus to SDRAMS
//parameter INIT_PER = 100; // For Simulation
// Controller Parameter
//////////// 133 MHz ///////////////
/*
parameter INIT_PER = 32000;
parameter REF_PER = 1536;
parameter SC_CL = 3;
parameter SC_RCD = 3;
parameter SC_RRD = 7;
parameter SC_PM = 1;
parameter SC_BL = 1;
*/
///////////////////////////////////////
//////////// 100 MHz ///////////////
parameter INIT_PER = 24000;
parameter REF_PER = 1024;
parameter SC_CL = 3;
parameter SC_RCD = 3;
parameter SC_RRD = 7;
parameter SC_PM = 1;
parameter SC_BL = 1;
///////////////////////////////////////
//////////// 50 MHz ///////////////
/*
parameter INIT_PER = 12000;
parameter REF_PER = 512;
parameter SC_CL = 3;
parameter SC_RCD = 3;
parameter SC_RRD = 7;
parameter SC_PM = 1;
parameter SC_BL = 1;
*/
///////////////////////////////////////
// SDRAM Parameter
parameter SDR_BL = (SC_PM == 1)? 3'b111 :
(SC_BL == 1)? 3'b000 :
(SC_BL == 2)? 3'b001 :
(SC_BL == 4)? 3'b010 :
3'b011 ;
parameter SDR_BT = 1'b0; // Sequential
// 1'b1: // Interteave
parameter SDR_CL = (SC_CL == 2)? 3'b10:3'b11;
//=======================================
//優化上述各參數如下所示:
// Address and Data Bus Sizes
//(1M * 4) * 16Bit =(4096 * 256) * 4 * 16Bit = 64MBit
`define ROWSIZE 12 //Rows width in one bank
`define COLSIZE 8 //Column width in one bank
`define DSIZE 16 //16Bit SDRAM data
`define BANKSIZE 2 //4 Banks in one SDRAM
`define ASIZE `COLSIZE + `ROWSIZE + `BANKSIZE //SDRAM Total address
// Address Space Parameters -> The new code addres: {Bank, Row, Column}
`define COLSTART 0
`define ROWSTART `COLSIZE
`define BANKSTART `COLSIZE + `ROWSIZE//上述將rowstart和bankstart進行了參數化,只需修改有限幾個參數即可。
//---------------------------------------
//SDRAM Init paramter setting
//`define ROW4096_133MHz
//`define ROW4096_125MHz
`define ROW4096_100MHz
//`define ROW8192_133MHz
//`define ROW8192_125MHz
//`define ROW8192_100MHz//利用命令`define…….`ifdef …….`endif 結構來實現對模式的選擇,可以方便的修改。
`ifdef ROW4096_133MHz
// Controller Parameter for 4096 Rows @ 133MHz
parameter INIT_PER = 16'd26600; //200 * 133
parameter REF_PER = 16'd2078; //15.625*133 = 2078.125
parameter SC_CL = 3;
parameter SC_RCD = 3;
parameter SC_PM = 1;
parameter SC_BL = 1;
`endif
`ifdef ROW4096_125MHz
// Controller Parameter for 4096 Rows @ 125MHz
parameter INIT_PER = 16'd25000; //200 * 125
parameter REF_PER = 16'd1953; //15.625*125 = 1953.125
parameter SC_CL = 3;
parameter SC_RCD = 3;
parameter SC_PM = 1;
parameter SC_BL = 1;
`endif
`ifdef ROW4096_100MHz
// Controller Parameter for 4096 Rows @ 100MHz
parameter INIT_PER = 16'd20000; //200 * 100
parameter REF_PER = 16'd1562; //15.625*100 = 1562.5
parameter SC_CL = 3;
parameter SC_RCD = 3;
parameter SC_PM = 1;
parameter SC_BL = 1;
`endif
`ifdef ROW8192_133MHz
// Controller Parameter for 8192 Rows @ 133MHz
parameter INIT_PER = 16'd26600; //200 * 133
parameter REF_PER = 16'd1039; //7.8125*133 = 1039.0625;
parameter SC_CL = 3;
parameter SC_RCD = 3;
parameter SC_PM = 1;
parameter SC_BL = 1;
`endif
`ifdef ROW8192_125MHz
// Controller Parameter for 8192 Rows @ 125MHz
parameter INIT_PER = 16'd25000; //200 * 125
parameter REF_PER = 16'd976; //7.8125*125 = 976.5625
parameter SC_CL = 3;
parameter SC_RCD = 3;
parameter SC_PM = 1;
parameter SC_BL = 1;
`endif
`ifdef ROW8192_100MHz
// Controller Parameter for 8192 Rows @ 100MHz
parameter INIT_PER = 16'd20000; //200 * 100
parameter REF_PER = 16'd781; //7.8125*100 = 781.25
parameter SC_CL = 3;
parameter SC_RCD = 3;
parameter SC_PM = 1;
parameter SC_BL = 1;
`endif
//-----------------------------------------------------------
// SDRAM Parameter
parameter SDR_BL = (SC_PM == 1)? 3'b111 : //Page 256
(SC_BL == 1)? 3'b000 : //1
(SC_BL == 2)? 3'b001 : //2
(SC_BL == 4)? 3'b010 : //4
3'b011 ; //8
parameter SDR_BT = 1'b0; // Sequential
// 1'b1: // Interteave
parameter SDR_CL = (SC_CL == 2)? 3'b10:
3'b11;
上述就定義完成了SDRAM初始化以及模式配置所需要的各寄存器參數,上述的配置正確與否直接決定了輸出的數據和運行速率。
//=======================================================================
更多詳細的資料下載可以登錄筆者百度網盤:
網址:http://pan.baidu.com/s/1bnwLaqF
密碼:fgtb
//=======================================================================