1. 程式人生 > >SDRAM讀寫狀態解析

SDRAM讀寫狀態解析

為什麽 開始 img pga 時也 all 電平 發送 IE

SDRAM的寫狀態流程

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狀態下面還有一個WRITEA狀態,當處於WRITEA狀態時,它會自動進入到Precharge狀態,想要繼續寫入就要再次重復激活行和進行寫操作。也就是說WRITEA狀態的工作效率要低很多,所以在某些對數據交互速度較快的場景中,我們要使用WRITE狀態

在設計寫模塊之前還是有有下面三種情況需要退出當前寫狀態。

(1) 數據已經寫完。

(2) SDRAM需要進行刷新操作。

(3) 數據未寫完,需要激活下一行繼續寫。

利用狀態機實現

技術分享圖片

從寫狀態時序圖上讀出,先給一個Active row命令,激活行地址,A0~A9,A10,A11,A12(A12一般不用)輸入行地址,選擇bank,手冊中查閱Trcd為20ns。

然後給write命令,A10選擇是WRITE狀態(A10高電平),還是WRITEA狀態(A10低電平),由於WRITEA狀態寫完一個burst length的數據後會自動跳轉到預充電命令,(要等突發長度結束後才能退出寫狀態)隨後進入IDLE狀態,所以我們選擇WRITE狀態,可連續寫入數據。所以WRITE狀態適用於高速數據的讀寫,WRITEA狀態適用於低速數據的讀寫。DQM置低電平(數據總線的低字節全為0),輸入列地址(A0~A8),A10置低電平,選擇bank。Tdpl為2個時鐘周期。

進行Precharge命令,對all bank進行操作,一個Trp時間後然後進行下一次的Active row命令,Trp為20ns。

這個模塊我采用的是三段式狀態機,第二段應該采用組合邏輯,不然有些情況會在pre_state和next_state兩個狀態之間不停跳轉。這是剛開始我把第二段用的時序邏輯,後面仿真的時候發現了這個問題。狀態機的狀態轉移圖如下。

技術分享圖片

SDRAM寫模塊的內部時序圖理解,首先需要一個寫觸發信號wr_trig,然後進行write操作,write_flag操作為高進行寫操作,寫數據結束後write_flag置低電平,wr_trig信號觸發後,wr_req(寫請求)信號發出,狀態機由初始狀態進入寫請求狀態,等仲裁狀態機發出寫使能(wr_en)信號,狀態機跳轉到激發行命令操作(S_ACT),有一個flag_act_end激發完成標誌信號,激發完成後狀態機跳轉到WRITE(寫狀態),當Sd_row_end信號置高時表示第一行寫完,換下一行寫。在換下一行寫之前要重弄新激發新的一行地址,所以仲裁狀態機要回到IDLE狀態,再次激發寫狀態,寫模塊內部狀態機跳到PRECHARGE(預充電命令狀態),當預充電完成後flag_pre_end置高,狀態機跳到再次激發行地址命令,等行地址激發完成後,狀態機跳到WRITE(寫狀態),當Ref_req(刷新請求)信號來到時(在寫的同時也要進行自刷新操作),狀態機跳轉到預充電狀態,然後自刷新完成,在即進入寫請求狀態,激發行地址,等激發行地址狀態完成後進行寫狀態,(註意:每一個突發長度完成後都需要進行一次寫命令)

寫操作模塊仿真

技術分享圖片

技術分享圖片

寫操作中,最後有個數重復操作,但是應該是寫不進去,這裏的原因是寫模塊的數據寫完成標誌沒有及時給到仲裁狀態機,導致命令一直停留在寫命令下,這個問題得到解決。

技術分享圖片

技術分享圖片

技術分享圖片

寫入兩行數據後,停止寫,SDRAM每過15us自刷新一次。

讀操作模塊

讀操作模塊和寫操作模塊是完全相同的,這裏可以直接把寫操作模塊的代碼復制過來,頂層添加,修改相關命令和參數即可。

寫完數據之後,激發讀數據

技術分享圖片

中間遇到需要刷新,進行刷新,刷新完成後繼續讀數據

技術分享圖片

一行寫完接著寫下一行

技術分享圖片

寫完之後給個預充電命令,然後每隔15us進行自刷新。

技術分享圖片

如上幾幅截圖,在每次跳到預充電命令,後面緊接著還是正常讀出數據,但是理論上來說應該是讀出數據完全完成後再跳入預充電命令,從代碼和波形分析中沒有找到解決。這個問題是預留。這個問題的原因下面得到解決。

技術分享圖片

為什麽數據會在precharge命令後面出來,這是因為我們設置的潛伏期的緣故,在給讀命令之後,數據會延遲三個時鐘周期出來,所以最後出來的數據,會在precharge命令之後。

寫到這裏其實一個簡易的SDRAM控制器就寫的差不多了,重點是要把這個SDRAM控制器使用起來,設置一個給SDRAM寫數據和讀數據的標誌,使用上位機用串口發送數據到FPGA,當接收到寫指令FPGA將數據緊接著的四個數據寫入到SDRAM,寫完之後給出讀指令,SDRAM已經寫入SDRAM的四個數據再通過串口發送給上位機,這裏需要註意的是因為SDRAM的速度遠比串口傳輸的速度快,如果直接把串口發送過來的數據接到SDRAM的數據端口上,就可能會出現重復寫入或寫入數據錯誤等原因,所以這裏要使用兩個FIFO進行緩沖。

讀寫FIFO

使用讀寫FIFO原因,再給SDRAM寫數據的時候,我們寫入SDRAM的數據的速率,即串口速率,要遠遠小於SDRAM寫入數據的速率,所以這裏需要使用FIFO進行緩存,讀取SDRAM的數據也是如此。

技術分享圖片

通過串口向SDRAM中寫入四個數據,然後再讀取出來發送到上位機。

FIFO的仿真需要在Modelsim中添加庫文件,我使用的是QuartusII進行開發,在生成IP的時候IP Core配置界面會提示你用到了哪個庫文件,把這個庫文件和生成的IP Core頂層文件直接添加到工程裏面就行了,進行充分仿真後就可以下載板子了。

結果完成

技術分享圖片

在做這個實驗的時候博主基本上是仿真完成後直接下板子就成功了,這就體現到充分仿真的重要性,仿真的過程也是十分痛苦的,經過了多次的重復仿真,最後總算是調了出來了。

這個簡易SDRAM控制器的工程我放在GitHub了,歡迎指點批評。

https://github.com/NingHeChuan/Open-FPGA.git

技術分享圖片

轉載請註明出處:NingHeChuan(寧河川)

個人微信訂閱號:開源FPGA

如果你想及時收到個人撰寫的博文推送,可以掃描左邊二維碼(或者長按識別二維碼)關註個人微信訂閱號

知乎ID:NingHeChuan

微博ID:NingHeChuan

原文地址:https://www.cnblogs.com/ninghechuan/p/9095436.html

SDRAM讀寫狀態解析