本(běn)文(wén)为(wèi)明(míng)德揚原創及(jí)录(lù)用(yòng)文(wén)章(zhāng),轉(zhuǎn)载請注明(míng)出(chū)处!
1.1 SDRAM簡介
SDRAM即同(tóng)步動(dòng)态随機(jī)存儲器,英文(wén)为(wèi)Synchronous Dynamic Random Access Memory;具有(yǒu)容量(liàng)大、读(dú)写速度(dù)快(kuài)、價格相对(duì)便宜等优點(diǎn),但同(tóng)时(shí)控制邏輯比較複雜。
1.1.1 SDRAM示意(yì)图(tú)
其管(guǎn)脚图(tú)如(rú)下(xià)所(suǒ)示:
1.1.2 信(xìn)号(hào)说(shuō)明(míng)
|
信(xìn)号(hào)名 |
信(xìn)号(hào)说(shuō)明(míng) |
|
clk |
SDRAM工作时(shí)鐘(zhōng) |
|
cke |
时(shí)鐘(zhōng)使能(néng)信(xìn)号(hào) |
|
cs_n |
用(yòng)于(yú)屏蔽和(hé)使能(néng)所(suǒ)有(yǒu)輸入(rù)端口(kǒu),但不(bù)包(bāo)括CLK,CKE和(hé)DQM,低電(diàn)平有(yǒu)效 |
|
cas_n |
列地(dì)址選通(tòng) |
|
ras_na |
行地(dì)址選通(tòng) |
|
we_n |
写使能(néng),該信(xìn)号(hào)为(wèi)低时(shí),使能(néng)写操作和(hé)預充電(diàn) |
|
ba |
bank地(dì)址 |
|
a |
地(dì)址總(zǒng)線(xiàn) |
|
dqm |
數據(jù)掩碼 |
|
dq |
數據(jù)總(zǒng)線(xiàn) |
1.1.3 SDRAM中(zhōng)心(xīn)对(duì)齊原則
SDRAM的(de)命令與(yǔ)时(shí)鐘(zhōng)上(shàng)升(shēng)沿是(shì)中(zhōng)心(xīn)对(duì)齊的(de),本(běn)設計(jì)采用(yòng)鎖相环(huán)生(shēng)成(chéng)SDRAM工作时(shí)鐘(zhōng),SDRAM與(yǔ)初始化(huà)模块(kuài)工作时(shí)鐘(zhōng)相差180°。这(zhè)樣(yàng)FPGA産生(shēng)的(de)信(xìn)号(hào)到(dào)SDRAM正(zhèng)好(hǎo)中(zhōng)心(xīn)对(duì)齊,如(rú)下(xià)图(tú)所(suǒ)示:
1.1.4 SDRAM初始化(huà)时(shí)序
SDRAM初始化(huà)时(shí)序如(rú)上(shàng)图(tú)所(suǒ)示,sdr_cmd命令由(yóu)sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n組合而(ér)成(chéng);複位後(hòu)要(yào)延时(shí)最(zuì)少(shǎo)100us後(hòu)才能(néng)工作;當A10为(wèi)高(gāo)时(shí)可(kě)以(yǐ)对(duì)所(suǒ)有(yǒu)bank進(jìn)行操作;當到(dào)达(dá)Tp+3时(shí)需要(yào)将init_done拉高(gāo)。
其模式寄存器配置如(rú)上(shàng)图(tú)所(suǒ)示,主(zhǔ)要(yào)參數設置如(rú)下(xià):
a. 模式寄存器的(de)配置是(shì)确定(dìng)SDRAM的(de)工作模式
b. A2、A1、A0用(yòng)作設置突發(fà)长度(dù),本(běn)項目設置为(wèi)4
c. A3用(yòng)作設置突發(fà)類(lèi)型,本(běn)項目設置为(wèi)Sequential順序類(lèi)型
d. A6、A5、A4用(yòng)作設置列選通(tòng)潛伏期(qī),本(běn)項目設置为(wèi)3
e. A8、A7設置操作模式,一(yī)般为(wèi)00
f. A9設置写突發(fà)模式,本(běn)項目为(wèi)0
g. A12、A11、A10設置为(wèi)0
1.2 頂层模块(kuài)設計(jì)
1.2.1 SDRAM頂层模块(kuài)管(guǎn)脚图(tú)
1.2.2 信(xìn)号(hào)说(shuō)明(míng)
|
信(xìn)号(hào) |
说(shuō)明(míng) |
|
local_addr |
本(běn)地(dì)地(dì)址由(yóu)行地(dì)址列地(dì)址bank地(dì)址組合而(ér)成(chéng) |
|
local_data |
写入(rù)數據(jù) |
|
local_q |
读(dú)出(chū)數據(jù) |
|
local_rdreq |
读(dú)請求 |
|
local_wrreq |
写請求 |
|
local_reday |
可(kě)以(yǐ)進(jìn)行读(dú)写信(xìn)号(hào) |
|
local_rdata_valid |
读(dú)數據(jù)有(yǒu)效信(xìn)号(hào) |
|
init_done |
初始化(huà)完成(chéng)信(xìn)号(hào) |
|
clk |
輸入(rù)时(shí)鐘(zhōng) |
|
rst_n |
系(xì)統複位 |
|
sdr_dq |
SDRAM數據(jù)總(zǒng)線(xiàn),双(shuāng)向(xiàng)端口(kǒu) |
|
sdr_clk |
SDRAM工作时(shí)鐘(zhōng) |
|
sdr_cke |
SDRAM时(shí)鐘(zhōng)使能(néng) |
|
sdr_cs_n |
片(piàn)選信(xìn)号(hào) |
|
sdr_cas_n |
列地(dì)址選通(tòng) |
|
sdr_ras_n |
行地(dì)址選通(tòng) |
|
sdr_we_n |
写使能(néng),該信(xìn)号(hào)为(wèi)低时(shí),使能(néng)写操作和(hé)預充電(diàn) |
|
sdr_ba |
SDRAM bank地(dì)址 |
|
sdr_a |
SDRAM地(dì)址總(zǒng)線(xiàn) |
|
sdr_dqm |
數據(jù)掩碼 |
1.2.3 參考代(dài)碼
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
module sdram_top( clk , sys_rst_n , //其他(tā)信(xìn)号(hào),舉例dout local_addr, local_data, local_q, local_rdreq, local_wrreq, local_reday, local_rdata_vaild, init_done, sdr_cke, sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n, sdr_ba, sdr_a, sdr_dq, sdr_dqm, sdr_clk );
input clk; input sys_rst_n; input [24:0] local_addr; input [63:0] local_data; output [63:0] local_q; input local_rdreq; input local_wrreq; output local_reday; output local_rdata_vaild; output init_done; output sdr_cke; output sdr_cs_n; output sdr_ras_n; output sdr_cas_n; output sdr_we_n; output [1:0] sdr_ba; output [12:0] sdr_a; output [15:0] sdr_dq; output [1:0] sdr_dqm; output sdr_clk;
wire phy_clk; wire rst_n; wire [19:0] init_bus;
assign {sdr_cke, sdr_cs_n, sdr_ras_n, sdr_cas_n, sdr_we_n, sdr_ba, sdr_a} = init_bus; assign sdr_dqm = 2'b00;
sdram_init sdram_init_inst( .clk (phy_clk) , .rst_n (rst_n) , //其他(tā)信(xìn)号(hào),舉例dout .init_done (init_done) , .init_bus (init_bus) );
my_pll PLL( .areset (~sys_rst_n) , .inclk0 (clk) , .c0 (phy_clk) , .c1 (sdr_clk) , .locked (rst_n) );
endmodule
|
1.3 初始化(huà)模块(kuài)設計(jì)
1.3.1 SDRAM出(chū)計(jì)劃(huà)模块(kuài)管(guǎn)脚图(tú)
1.3.2 信(xìn)号(hào)说(shuō)明(míng)
|
信(xìn)号(hào) |
说(shuō)明(míng) |
|
clk |
初始化(huà)模块(kuài)工作时(shí)鐘(zhōng)(100MHz) |
|
rst_n |
複位 |
|
init_done |
初始化(huà)完成(chéng)信(xìn)号(hào) |
|
init_bus |
由(yóu)SDRAM信(xìn)号(hào)組成(chéng) |
1.3.3 參考代(dài)碼
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
module sdram_init( clk , rst_n , //其他(tā)信(xìn)号(hào),舉例dout init_done, init_bus );
//參數定(dìng)義 parameter DATA_W = 20 ; parameter T100us = 10_000 ; parameter TRP = 2 ; parameter TRFC = 7 ; parameter TMRD = 2 ; parameter NOP = 4'b0111 ; parameter PRE = 4'b0010 ; parameter REF = 4'b0001 ; parameter LMR = 4'b0000 ; parameter CODE = 13'b000_000_011_0010 ; parameter CNT_MAX = 10_021 ;
//輸入(rù)信(xìn)号(hào)定(dìng)義 input clk ; input rst_n ;
//輸出(chū)信(xìn)号(hào)定(dìng)義 output init_done ; output[DATA_W-1:0] init_bus ;
//輸出(chū)信(xìn)号(hào)reg定(dìng)義 reg init_done ; wire [DATA_W-1:0] init_bus ;
//中(zhōng)間(jiān)信(xìn)号(hào)定(dìng)義 reg [20:0] cnt ; reg sdr_cke ; reg [3:0] sdr_cmd ; reg [1:0] sdr_ba ; reg [12:0] sdr_a ;
wire add_cnt ; wire end_cnt ;
assign init_bus = {sdr_cke, sdr_cmd, sdr_ba, sdr_a};
always @(posedge clk or negedge rst_n)begin if(!rst_n)begin cnt <= 0; end else if(add_cnt)begin if(end_cnt) cnt <= 0; else cnt <= cnt + 1; end end
assign add_cnt = init_done == 0; assign end_cnt = add_cnt && cnt==CNT_MAX - 1 ;
always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin sdr_cke <= 1'b0; end else if(add_cnt&&cnt==10_000-1)begin sdr_cke <= 1'b1; end else sdr_cke <= sdr_cke; end
always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin sdr_cmd <= NOP; end else if(add_cnt&&cnt==10_001-1)begin sdr_cmd <= PRE; end else if(add_cnt&&cnt==10_003-1)begin sdr_cmd <= REF; end else if(add_cnt&&cnt==10_012-1)begin sdr_cmd <= REF; end else if(add_cnt&&cnt==10_019-1)begin sdr_cmd <= LMR; end else if(add_cnt&&cnt==10_020-1)begin sdr_cmd <= NOP; end else begin sdr_cmd <= NOP; end end
always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin sdr_a <= 13'd0; end else if(add_cnt&&cnt==10_001-1)begin sdr_a[10] <= 1'b1; end else if(add_cnt&&cnt==10_019-1)begin sdr_a <= CODE; end else begin sdr_a <= 13'd0; end end
always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin init_done <= 1'b0; end else if(add_cnt&&cnt==10_021-1)begin init_done <= 1'b1; end else begin init_done <= init_done; end end
endmodule
|
1.4 PLL設置
最(zuì)後(hòu)对(duì)代(dài)碼進(jìn)行仿真(zhēn),modelsim生(shēng)成(chéng)的(de)報告如(rú)下(xià)所(suǒ)示,说(shuō)明(míng)初始化(huà)設置成(chéng)功。
以(yǐ)上(shàng)就(jiù)是(shì)SDRAM控制器初始化(huà)設計(jì)的(de)思(sī)考步驟以(yǐ)及(jí)相關(guān)代(dài)碼,更(gèng)多(duō)FPGA資料可(kě)以(yǐ)進(jìn)入(rù)明(míng)德揚論壇進(jìn)行学習交流(http://www.fpgabbs.cn/),明(míng)德揚專注FPGA設計(jì)研究,对(duì)FPGA学習感(gǎn)興趣的(de)朋友快(kuài)快(kuài)聯系(xì)我(wǒ)们(men)吧!















