SDRAM读写一字(上)
SDRAM讀寫一字
系統設計
SDRAM指令
| 指令 | 常量名 | CKE | CSn | RAS | CASn | WEn | 備注 |
| 空操作 | NOP | 1 | 0 | 1 | 1 | 1 | ? |
| 行激活 | ACTIVE | 1 | 0 | 0 | 1 | 1 | ? |
| 讀操作 | READ | 1 | 0 | 1 | 0 | 1 | ? |
| 寫操作 | WRITE | 1 | 0 | 1 | 0 | 0 | ? |
| 預充電 | PR | 1 | 0 | 0 | 1 | 0 | ? |
| 自刷新 | AR | 1 | 0 | 0 | 0 | 1 | ? |
| 設置寄存器 | LMR | 1 | 0 | 0 | 0 | 0 | ? |
| 突發停止 | BURST_STOP | 1 | 0 | 1 | 1 | 0 | 1 |
SDRAM初始化
????SDRAM控制模塊發送初始化使能信號,使能SDRAM初始化模塊,然后進行初始化操作,初始化操作完成后,發出初始化完成信號到SDRAM控制模塊,SDRAM控制模塊進入下一步操作。
????Init_start用于啟動SDRAM初始化模塊進行初始化,done_init用于反饋SDRAM初始化模塊初始化完成。在SDRAM初始化的過程中,根據初始化的每一個步驟,進行輸出指令和SDRAM_address信號。
初始化時序
?
初始化操作流程圖
SDRAM初始化代碼
該工程的時鐘頻率為20MHz
module sdram_init(
clk,
reset_n,
init_start,
init_done,
sdram_command,
sdram_address
);
//參數定義
parameter T200US = 12'd3999; //上電延遲200us
?
//端口定義
input clk; //時鐘信號20MHz
input reset_n; //復位信號
input init_start; //初始化開始信號,高電平有效
output init_done; //初始化完成信號,輸出,高電平有效
output [4:0] sdram_command; //cke、cs_n、ras、cas_n、we_n,SDRAM指令信號
output [13:0] sdram_address; //[13:12]BA , [11:0]Addr,SDRAM地址信號
//常量定義
parameter NOP = 5'b10111, //空操作
ACTIVE = 5'b10011, //行激活
READ = 5'b10101, //讀操作
WRITE = 5'b10100, //寫操作
PR = 5'b10010, //預充電
AR = 5'b10001, //自刷新
LMR = 5'b10000; //設置寄存器
parameter SET_MODE_REG = {4'd0, 1'b0, 2'd0, 3'b010, 1'b0, 3'b011};
//突發讀寫,潛伏期為2,順序操作,突發長度為8
//寄存器定義
reg [11:0] time_cnt; //上電延遲計數寄存器
reg [4:0] sdram_command_reg; //SDRAM指令寄存器
reg [13:0] sdram_address_reg; //SDRAM地址信號寄存器,{bank,address}
reg init_done_reg; //初始化完成信號寄存器
reg [3:0] state_cnt; //狀態機計數器,用于控制狀態跳轉
?
//*****************************************************************************
// 模塊名稱:SDRAM初始化模塊
// 功能描述:在初始化開始控制信號的控制下進行初始化操作,操作完成后發出初始化完成信號
//*****************************************************************************
always @(posedge clk or negedge reset_n)
begin
if(reset_n == 1'b0)
begin
time_cnt <= #1 12'd0; //上電延遲計數寄存器清零
state_cnt <= #1 4'd0; //狀態計數器初始化
init_done_reg <= #1 1'b0; //初始化完成寄存器清零
sdram_command_reg <= #1 NOP; //SDRAM指令寄存器初始化
sdram_address_reg <= #1 14'h3fff; //SDRAM地址信號寄存器進行置高
end
else
begin
if(init_start == 1'b1)
case (state_cnt)
4'd0://上電延遲200us
begin
if(time_cnt == T200US) //判斷200us延遲是否結束
begin
state_cnt <= #1 state_cnt + 1'b1;
time_cnt <= #1 12'd0;
end
else
time_cnt <= #1 time_cnt + 1'b1;
end
4'd1://預充電操作
begin
sdram_command_reg <= #1 PR;
sdram_address_reg <= #1 14'h3fff;
state_cnt <= #1 state_cnt + 1'b1;
end
4'd2://空操作
begin
sdram_command_reg <= #1 NOP;
state_cnt <= #1 state_cnt + 1'b1;
end
4'd3://自動刷新
begin
sdram_command_reg <= #1 AR;
state_cnt <= #1 state_cnt + 1'b1;
end
4'd4,4'd5://空操作
begin
sdram_command_reg <= #1 NOP;
state_cnt <= #1 state_cnt + 1'b1;
end
4'd6://自動刷新
begin
sdram_command_reg <= #1 AR;
state_cnt <= #1 state_cnt + 1'b1;
end
4'd7,4'd8://空操作
begin
sdram_command_reg <= #1 NOP;
state_cnt <= #1 state_cnt + 1'b1;
end
4'd9://設置寄存器
begin
sdram_command_reg <= #1 LMR;
state_cnt <= #1 state_cnt + 1'b1;
sdram_address_reg <= #1 SET_MODE_REG;
end
4'd10,4'd11://空操作
begin
sdram_command_reg <= #1 NOP;
state_cnt <= #1 state_cnt + 1'b1;
end
4'd12://設置初始化完成信號
begin
init_done_reg <= #1 1'b1;
state_cnt <= #1 state_cnt + 1'b1;
end
4'd14://恢復初始化完成信號
begin
state_cnt <= #1 4'd0;
end
default://其他狀態,恢復到初始狀態
begin
state_cnt <= #1 4'd0;
sdram_command_reg <= #1 NOP;
end
endcase
end
end
//*****************************************************************************
assign init_done = init_done_reg;
assign sdram_command = sdram_command_reg;
assign sdram_address = sdram_address_reg;
endmodule
SDRAM讀寫模塊
state_signal: 狀態信號,用于控制對SDRAM進行讀寫和自刷新;
sdram_bank_addr:SDRAM最小單元地址,[21:20]塊地址+[19:8]行地址Row+[7:0]列地址Column;
write_data: 寫入SDRAM的數據;
rw_done_signal: 讀寫完成信號;
ar_done_signal: 自動刷新完成信號;
read_data: 從SDRAM讀出的數據;
sdram_command:SDRAM指令,cke、cs_n、ras、cas_n、we_n,SDRAM指令信號;
sdram_address: SDRAM讀寫地址;
sdram_dqm: SDRAM數據掩碼;
sdram_data: SDRAM讀寫數據;
?
????state_signal有四種狀態,分別為自刷新、讀、寫、空操作。Sdram讀寫控制模塊根據state_signal的信號對SDRAM發出控制信息,同時接收數據和發送數據、地址。
????當處于自刷新狀態時,向SDRAM發送自刷新命令,自刷新完成后ar_done_signal信號有效,表明自刷新操作完成。
????當處于讀狀態時,向SDRAM發送讀數據命令、讀取數據的地址sdram_bank_addr,讀操作完成后rw_done_signal信號有效,表明讀操作完成,這時可以從read_data讀取從sdram讀取的數據。
????當處于寫狀態時,向SDRAM發送寫數據命令,同時將寫入的數據送往write_data,寫入的地址送往sdram_bank_addr,寫操作完成后rw_done_signal信號有效,表明寫操作完成。
????當處于空操作時向sdram發送NOP指令。
????sdram_dqm為sdram的數據掩碼信號,在對sdram進行讀寫操作時,其電平狀態要與指令sdram_command相配合操作。
自刷新操作
存儲體中電容的數據有效保存期上限是64ms,也就是說每一行刷新的循環周期是64ms。這樣刷新速度就是:行數量/64ms 。我們在看內存規格時,經常會看到4096 Refresh Cycles/64ms 或8192 Refresh Cycles/64ms的標識,這里的4096與8192就代表這個芯片中每個L-Bank的行數。刷新命令一次對一行有效,發送間隔也是隨總行數而變化,4096行時為15.625 μs。
由此每隔15us需要自刷新一次。
刷新操作采樣簡單的操作:
自刷新時序:
自刷新代碼:
讀操作
?
讀操作過程
?
讀操作代碼
寫操作
操作過程
時序圖
寫操作代碼
?
大西瓜FPGA-->https://daxiguafpga.taobao.com
?
博客資料、代碼、圖片、文字等屬大西瓜FPGA所有,切勿用于商業! 若引用資料、代碼、圖片、文字等等請注明出處,謝謝!
?
每日推送不同科技解讀,原創深耕解讀當下科技,敬請關注微信公眾號“科乎”。
轉載于:https://www.cnblogs.com/logic3/p/5239338.html
總結
以上是生活随笔為你收集整理的SDRAM读写一字(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编写一个函数itob(int n,cha
- 下一篇: Java删除文件和目录