SDRAM控制器操作时序
此為學習http://dengkanwen.com/137.html整理的筆記,侵刪!
SDRAM工作原理
內部的狀態跳轉圖
我們所需關注的幾個地方:
1)粗黑線表示在該狀態下會自動跳轉到另一個狀態,細黑線表示需要給命令才會跳轉。
2)我們重點關注的幾個地方:
IDLE 狀態到WRITE 狀態:
? 1) 在IDLE 狀態需要先給ACT 命令激活某一行,此時處于Row Active 狀態;
? 2) 在Row Active 狀態之后,給Write 命令則會進入WRITE 狀態;
? 3) 在WRITE 狀態后,再給一次Write 命令,就可以繼續寫入數據。
WRITE 狀態到IDLE 狀態:
? 1) 在WRITE 狀態給PRE 命令,則SDRAM 將跳出WRITE 狀態進入Precharge狀態;
? 2) 在Precharge 狀態后,就會自動進入IDLE 狀態了。
? 要從WRITE 狀態跳到IDLE 狀態的一個原因是,我們需要進行刷新操作,進
入刷新操作,必須從IDLE 狀態進入。
? 另外一點,可能有些朋友看到了WRITE 狀態下邊還有一個WRITEA 狀態,的
確,但是細心的你有沒有發現當處于WRITEA 狀態時,它會自動的進入Precharge 狀態。也就是說WRITEA 比在WRITE 狀態的工作效率要低很多,所以在某些對數據交互速度較快的場景中,我們使用WRITE 狀態。在本套教程中,我們也只講WRITE 狀態。速度快的都能搞定,那速度慢的操作也是不在話下的。
SDRAM 初始化模塊
首先看一下官方數據手冊給出的初始化時序圖
初始化過程
1)首先需要有200us 的一個延時(對應圖中左下方的T),
2)在延時滿足之后,給一次Precharge 命令,同時需要指定A10及Bank地址;(如果A10為高(All Banks),就意味著是給所有的Bank進行預充電,此時不需要給Bank地址,如果A10為低(SINGLE BANK),就需要指定某一個bank的地址。一般為高)
3)然后再過“tRP”的時間,給“AutoRefresh”命令,然后再過“tRC”的時間,再給“Auto Refresh”命令,(不需要指定bank地址的(大家注意看右下角有說明,灰色部分的數據我們是不需要關心的)。
4)然后再經過“tRP”的時間進行模式寄存器設置。進行模式寄存器設置的時候,需要給的指令會稍微復雜一點,手冊上顯示A0~A11及BA0,BA1都用到了,下面我們來看下模式寄存器應該怎么進行設置,如圖:
? 這里解釋一下突發讀寫:突發長度(A2~A0)設置為4,在我們進行寫操作的時候,數據是每4個數據寫一次的,就是說我們給一次寫指令,就會向SDRAM寫進去4個數據,而且四個地址是連續的(如果突發類型設置的是非連續,則地址不會連續,需要我們寫一個數據給一次地址,比較耗內存)
初始化時序圖中的幾個問題
1)tRC、tRP、tMRD的時間是多少,幾個時鐘周期?
參照官方數據手冊ML0006 0012-2中的AC ELECTRICAL CHARACTERISTICS部分給出
tRC:63ns
tRP:20ns
tMRD:2cycle
若fpga內部頻率為50MHZ,正好是20ns。(4clk、1clk)
2)時序圖中幾個command命令的參數怎樣設置
上述就是整個初始化過程,我們最后以kevin畫的時序圖作為一個總結
具體代碼為sdram_init;
SDRAM 刷新模塊
我們還是先看一下官方數據手冊給出的刷新時序圖
刷新操作的時序圖分析與前面類似。
刷新時序圖中的幾個問題
1)兩次刷新時間間隔有多久呢?
? SDRAM內部電容保存數據的最長時間是64ms,而我們一個BANK有4096行,64ms/4096~=15us,也就是說為了保證SDRAM內部的數據不被丟失,兩次刷新之間的最大時間間隔為15us,所以為了能讓SDRAM有更多的時間進行讀或者寫,我們就設定SDRAM刷新的周期為15us.(若按系統時鐘50MHZ,就是計750個數)
? SDRAM每進行一次刷新,是對每一行進行操作的,并不是單獨針對每一個電容進行充電,所以每進行一次刷新,該行中的電容進行充電我們可以理解為是同步發生的
2)在每次自動刷新時,我們需要給一個“Precharge”命令,這個命令有什么作用呢?
大家可以看下開頭的那張狀態圖,如果此時SDRAM正處于“WRITE”或“READ”狀態時,這個“Precharge”命令可以使SDRAM跳出“WRITE”或“READ”狀態從而入“IDLE”狀態。接下來,過“tRP”的時間,給一個“Auto-Refresh”命令可以進入刷新狀態。
但此時的Precharge命令我們在寫狀態模塊中給出。在刷新模塊中不需要Precharge命令。
SDRAM仲裁模塊
在介紹仲裁模塊前我們先考慮一個問題:
? 如果我正在讓SDRAM寫數據,是不是SDRAM刷新的時間到了,我就必須是讓SDRAM馬上執行刷新操作嗎?這樣的話肯定不是現實的,那必然會把還沒寫的剩下的數據丟失。不能讓我們的數據丟失,又要保證SDRAM進行刷新來保證我們整個SDRAM相應BANK中的數據不被丟失,我們應該怎么來寫代碼呢?
我們可以考慮這樣來做:如果刷新的時間到了,先讓寫操作把正在寫的4個數據(突發長度為4)寫完,然后再去進行刷新操作。而如果在執行讀操作也遇到需要刷新的情況,我們也可以這樣來做,先讓數據讀完,再去執行刷新操作。
為了解決各個模塊之間不方便控制的情況,我們引入一個新的機制 ——“仲裁”機制。“仲裁”用來干什么呢?在這里邊,“仲裁”相當于我們這個SDRAM控制器的老大,對SDRAM的各個操作統一協調:讀、寫及自動刷新都由“仲裁”來控制。
仲裁模塊狀態機示意圖:
仲裁模塊和其他各模塊之間的連線:
注:一定要搞清楚說的是模塊之間連線的關系還是狀態機之間跳轉的關系哦。
仲裁模塊分析
1)初始化操作完成之后便進入到了“ARBIT”仲裁狀態,只有處于仲裁狀態的時候,“仲裁老大”才能進行下命令。
2)當狀態機處于“WRITE”寫狀態時,如果SDRAM刷新的時間到了,刷新模塊同時向寫模塊和仲裁模塊發送刷新請求ref_req信號。
3)當寫模塊接受到ref_req之后,寫模塊在寫完當前4個數據(突發長度為4)之后,寫模塊的寫結束標志flag_wr_end拉高,然后狀態機進入“ARBIT”仲裁狀態。
4)處于仲裁狀態之后,此時有刷新請求ref_req,然后狀態機跳轉到“AREF”狀態并且仲裁模塊發送ref_en刷新使能,刷新模塊將刷新請求信號ref_req拉低并給sdram發送刷新的命令。
5)等刷新完畢之后,刷新模塊給仲裁模塊發送flag_ref_end刷新結束標志,狀態機跳轉到“ARBIT”仲裁狀態。
注意了,當刷新完跳轉到“ARBIT”仲裁狀態之后,如果之前我們的全部數據仍然沒有寫完(Kevin指的是全部數據,并不是一個突發長度的4個數據哦),那么此時我們仍然要給仲裁模塊寫請求“wr_req”,然后仲裁模塊經過一系列判斷之后,如果符合寫操作的時機,那就給寫模塊一個寫使能信號“wr_en”,然后跳轉到“WRITE”寫狀態并且寫模塊開始工作。
SDRAM寫模塊
官方數據手冊給出的寫操作時序圖
該時序圖的分析可以參照前面初始化過程的分析。
現在我們考慮另一個問題:假設我們現在需要往SDRAM 中寫入兩行數據,那什么時候可以退出仲裁狀態機的寫狀態:
1) 數據已經寫完;若我們還想要再寫,就需要外部的Wr_trig觸發
2) SDRAM 需要進行刷新操作;外部有一個刷新請求信號,并且本次數據已經寫完;轉到外部仲裁模塊去執行刷新操作,如果刷新完畢需要繼續寫,寫模塊請求,仲裁模塊使能。
3) 數據未寫完,需要激活下一行繼續寫。本行寫完標志,重新輸入act命令去寫下一行
我們將這三個狀態化成一個狀態機。如圖所示:
注意上圖中的IDLE狀態和前面的初始化中的IDLE狀態不要搞混。這個IDLE就是寫模塊中狀態機的初始化部分。
S_WR:if(wr_data_end == 1'b1) state <= S_PRE; else if(ref_req == 1'b1 && burst_cnt_t == 'd2 && flag_wr == 1'b1) state <= S_PRE; else if(sd_row_end == 1'b1 && flag_wr == 1'b1)state <= S_PRE; S_PRE:if(ref_req == 1'b1 && flag_wr == 1'b1) state <= S_REQ;else if(flag_pre_end == 1'b1 && flag_wr == 1'b1) state <= S_ACT;else if(flag_wr == 1'b0) state <= S_IDLE;我們由以上所述畫出寫模塊時序圖:
分析寫模塊中五個狀態機:
1)IDLE:外部Wr_trig觸發寫信號,進入S_REQ狀態。寫模塊將Flag_wr拉高直到數據完全寫完結束。
2)S_REQ:Flag_wr信號拉高,S_REQ狀態向外部仲裁發出請求寫信號wr_req,外部仲裁模塊判斷可以進行寫操作了并向寫模塊發出wr_en 使能信號,告訴寫模塊可以開始寫了。進入S_ACT狀態。
3)S_ACT:寫模塊在S_ACT狀態,發出ACT命令(command),并且指定bank的行地址。ACT命令結束發出Flag_act_end結束標志。進入S_WR狀態。
4)S_WR:發出寫命令開始寫數據,此時需要指定列地址
一行數據寫完發出Sd_row_end標志信號。刷新請求出現時,該組數據寫完發出Flag_wr_end標志信號。所有數據寫完返回Wr_data_end信號標志。
5)S_PRE:預充電命令 ,進入預充電狀態,充電完畢返回Flag_pre_end標志信號。
SDRAM讀模塊
SDRAM讀模塊與寫模塊一樣在此不再詳述。
讀模塊時序圖:
有一個問題需要注意:
我們再給出讀命令后,數據延時了兩個周期給出,這個時間段叫潛伏期CAS。
寫代碼技巧:
1)先寫主狀態機
2)把時序圖中用到的時序信號標志定義出來;
reg flag_wr ; reg [ 4:0] state ; //----------------------------------------------- reg flag_act_end ; reg flag_pre_end ; reg sd_row_end ; reg [ 1:0] burst_cnt ; reg [ 1:0] burst_cnt_t ; reg wr_data_end ; //----------------------------------------------- reg [ 3:0] act_cnt ; reg [ 3:0] break_cnt ; reg [ 6:0] col_cnt ; //----------------------------------------------- reg [11:0] row_addr ; wire [ 8:0] col_addr ;3)然后按照這個表寫出每個標志信號產生的代碼
總結
以上是生活随笔為你收集整理的SDRAM控制器操作时序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: V7000初始化
- 下一篇: 华为HCNA——配置ssh登陆设备