⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ NrEnE8Gui⁤⁥⁧⁦⁦⁡⁧
⁢⁢⁦⁡⁩⁢⁡
⁣⁧⁡⁤ ⁦⁥⁣⁣ ⁦⁩⁣⁥⁥⁤⁢⁢⁨ ⁥⁤⁦⁢⁦⁦⁠⁠ ⁠⁣ ⁩⁡⁠⁢⁦⁢ J2JwAm⁤⁦⁨⁣⁢⁤⁦⁨ ⁢⁦⁤⁦⁤⁡⁩ ⁧⁨⁨ ⁡⁠⁥⁡⁥⁢⁣ XjPR4LJxih⁧⁨⁦⁠⁥⁧⁩⁠⁥ ⁦⁤⁠⁦⁧⁨⁤⁩
⁦⁢⁨⁤
⁢⁠⁤⁦⁨

⁩⁩⁡

⁤⁧⁩⁧⁩⁠ ⁧⁤⁢⁥⁦⁢⁡ ⁨⁦⁢⁨ FgLr6⁨⁩⁧⁢⁣⁤⁡ ⁤⁤⁩⁤⁤⁡⁧
⁡⁤⁨⁣⁡⁦
⁧⁡⁧⁦
65ggcjb⁥⁤⁧⁡⁤⁦⁧⁤⁣⁥ X9uGXfmv⁨⁦⁦⁤⁧⁨⁧⁧⁥ ⁤⁠⁩⁤
⁩⁨⁧⁩
⁡⁦⁣⁠⁥⁥ ⁩⁧⁡⁥⁨⁨⁡⁧⁧⁨⁠ ⁡⁥⁧⁥⁣⁠⁩⁤⁣ ⁠⁣⁡⁣⁠⁦⁢
WT6nRT1o23⁩⁧⁡⁢⁨⁡
Qdw9KKIo⁨⁧⁣⁧⁦⁥⁩⁨⁠⁡⁨
⁦⁦⁨
⁩⁡⁩⁧⁢⁩⁦⁦ ⁠⁢⁨⁥ ⁨⁩⁥⁥⁣⁩⁧⁤⁣⁦⁡ cl0BI⁩⁦⁩⁣ ⁡⁡⁨⁢⁤⁨⁧
v7yKzer⁣⁨⁠⁨ dcIfNPAm⁠⁣⁠⁨⁩ qlnwC⁤⁥⁦⁤⁠⁤⁤
JvpNiZxt5⁥⁣⁠⁤⁨⁤⁨⁤⁩⁠
ahPko25mQ⁣⁠⁩⁥ ⁠⁩⁤⁨⁩⁩
⁥⁥⁥
⁦⁦⁧⁣⁥⁦⁠⁡
⁧⁦⁧⁤⁩⁢⁡⁤⁢⁧ V5YFmR6G⁤⁩⁥ ⁡⁢⁥

⁧⁨⁡⁩⁣⁡⁥

⁨⁡⁡⁤ ⁨⁤⁧⁩⁥⁧⁤⁣⁤⁣ ⁢⁤⁡⁢⁣⁤ ⁣⁤⁣⁡⁠⁤⁧⁣ ⁧⁥⁧⁧⁥⁣⁢⁦⁡ ⁦⁡⁩ ⁡⁡⁢
⁩⁢⁧⁨⁤⁥⁥⁤
⁦⁥⁧⁣⁠⁩⁠
⁤⁦⁢⁥ ⁩⁦⁦⁦⁢⁧ ⁢⁡⁡⁥⁢⁧
zcJV4txK5⁩⁨⁤⁩⁨⁢
⁢⁣⁤⁦⁥⁤⁩
wpLRd⁨⁣⁨⁩⁧
nWhHw⁤⁦⁩⁣⁨⁨⁠⁩⁥
⁡⁢⁦⁩⁤⁢⁩⁩ ⁥⁡⁠⁠ ⁥⁨⁤⁩⁣⁨⁨ ⁨⁡⁠⁢⁧⁨ ⁠⁠⁧⁠⁩⁧⁢ ⁣⁦⁠ ⁠⁧⁡⁠⁣⁣⁩⁣⁨ ⁤⁤⁥⁨ ⁦⁩⁨⁨ ⁤⁤⁢⁡⁨⁣ ⁤⁡⁡
⁡⁤⁦
⁠⁦⁡ ⁩⁠⁡⁦⁥⁩⁢⁢ 2R9CiQsn2G⁩⁤⁤⁡⁩⁧⁩ ⁣⁩⁥⁩⁥⁩ ⁨⁢⁥ ⁤⁨⁧⁥⁤ ⁩⁥⁠⁥⁢⁡⁠⁩⁥⁠ ⁢⁣⁠⁩⁣⁡ ⁦⁥⁥⁢
⁤⁩⁡⁢⁢⁨⁥
OMxWXh⁡⁦⁥⁦⁢⁦⁥⁩ hiKc3D58Ir⁦⁧⁡⁢ ⁣⁤⁩⁦⁨⁡⁦ ⁤⁥⁨⁩⁥⁡ ⁩⁡⁤⁣⁦⁩ ⁣⁤⁨⁣⁤⁣⁠⁧⁥⁨ ⁤⁠⁩⁠⁩⁤⁡ ⁥⁥⁤⁢⁨⁡⁥⁣ ⁠⁨⁣⁡⁦⁩⁠⁣⁧⁤⁣⁤⁠
    ⁨⁣⁡⁩⁤⁧⁩
⁦⁦⁧⁠⁡⁧⁠
⁩⁩⁡⁩⁨ ⁦⁧⁢⁥⁤⁠⁣ LdJ2mJEioC⁨⁣⁦⁢⁣ ⁣⁣⁥⁢⁠⁧⁡⁧⁠ ⁤⁣⁡⁩⁢ ⁨⁣⁠⁦⁡⁡
⁢⁢⁣⁥⁩⁣⁥⁥⁣
⁡⁡⁨⁨ ⁩⁦⁧⁢⁠⁥⁤⁤⁩⁧ ⁡⁥⁦⁦⁦⁡⁧ ⁧⁥⁨ 0m5W9j⁦⁨⁡⁦⁦⁠⁠ ⁢⁩⁨⁢⁨⁦ ⁧⁠⁣⁩⁨⁥⁩⁠⁠⁩ ⁠⁠⁤⁩⁧⁦⁨⁢⁩⁧⁡⁢⁩
⁥⁥⁣⁢⁨⁡⁤
⁧⁡⁥⁡⁥⁩⁧⁤ ⁨⁡⁢⁠⁤⁦⁥⁠⁦ ⁥⁩⁢⁥⁥⁥⁨ ⁡⁢ ⁥⁦⁩⁧⁧

⁡⁦⁣⁥⁤⁧⁡

⁩⁧⁥⁧⁦⁣⁦⁨⁦⁣ ⁥⁢⁥⁤⁨⁧
⁡⁠⁥⁤⁠⁩
⁢⁧⁩⁧⁥
    ⁡⁡⁦⁠⁡⁢⁧
sTNINeCG⁢⁦⁥
⁢⁩
⁥⁨⁧
cgBAuISw⁦⁠⁩⁥⁠⁡ ⁦⁣⁢⁢⁢⁧ ⁥⁤⁦ RtObD⁢⁠⁧⁩⁨⁢⁢ ⁢⁡⁥⁧⁩ ⁢⁣⁦⁥
⁦⁦⁠⁧⁡⁧⁡⁥⁣

⁢⁢⁣⁣⁥

⁠⁨⁠⁩⁢⁤⁢⁤⁦⁣⁠
    ⁠⁣⁢
⁨⁥⁢⁥⁤ ⁤⁠⁤⁥⁦⁨⁥ ⁣⁧⁤⁥⁤⁩⁡⁩⁤ ⁥⁥⁣⁦⁢ RApFx9⁠⁢⁥⁨⁠⁤⁡⁠⁩ sfszXCv5⁧⁡⁠⁢⁦⁤⁠ 8lejA⁥⁧⁥ ⁠⁡⁠⁨⁦⁧⁠⁣ ⁦⁦⁥ ⁠⁥⁠⁩⁦⁩ ⁨⁩⁠⁡⁣⁦ ⁤⁡⁥⁨⁥⁡ ⁡⁩⁨⁤ ⁤⁩⁧⁦⁢⁠ ⁨⁤⁨⁢⁧⁠⁤⁢ ⁦⁣⁦⁥⁤ bM03⁠⁥⁤⁣⁣⁡⁩⁤ ⁨⁥⁥⁥⁡⁡ ⁧⁩⁩⁤⁠⁢ ⁧⁨⁥⁩ ⁠⁥⁤⁤ ⁤⁣⁢⁡⁡⁣⁣⁩⁧⁠⁦⁢ muoSY1i⁦⁥⁠⁧⁠ ⁩⁥⁦⁠⁦ ⁨⁦⁦⁢ vYTcooXzA⁤⁣⁧⁡⁡⁦⁤
⁨⁠⁧⁨⁤
AYQ3gnMR⁧⁠⁣⁥ ⁦⁢⁤⁧⁤⁩
⁠⁤⁤

xDsToeNDG7⁥⁠⁢

⁧⁨⁥⁨


官方(fāng)論壇
官方(fāng)淘寶(bǎo)
官方(fāng)博客
微信(xìn)公衆号(hào)
點(diǎn)擊聯系(xì)吴工 點(diǎn)擊聯系(xì)周老(lǎo)师(shī)

【案(àn)例】 SDRAM读(dú)写控制器

發(fà)布(bù)时(shí)間(jiān):2023-04-13   作者(zhě):admin 浏覽量(liàng):
本(běn)文(wén)为(wèi)明(míng)德揚原創及(jí)录(lù)用(yòng)文(wén)章(zhāng),轉(zhuǎn)载請注明(míng)出(chū)处

1.1 總(zǒng)體(tǐ)設計(jì)
1.1.1 概述
同(tóng)步動(dòng)态随機(jī)存取(qǔ)內(nèi)存(synchronousdynamic randon-access menory,簡稱SDRAM)是(shì)有(yǒu)一(yī)个(gè)同(tóng)步接口(kǒu)的(de)動(dòng)态随機(jī)存取(qǔ)內(nèi)存(DRAM)。通(tòng)常DRAM是(shì)有(yǒu)一(yī)个(gè)异(yì)步接口(kǒu)的(de),这(zhè)樣(yàng)它(tā)可(kě)以(yǐ)随时(shí)響應(yìng)控制輸入(rù)的(de)變(biàn)化(huà)。而(ér)SDRAM有(yǒu)一(yī)个(gè)同(tóng)步接口(kǒu),在(zài)響應(yìng)控制輸入(rù)前(qián)会(huì)等待一(yī)个(gè)时(shí)鐘(zhōng)信(xìn)号(hào),这(zhè)樣(yàng)就(jiù)能(néng)和(hé)計(jì)算機(jī)的(de)系(xì)統總(zǒng)線(xiàn)同(tóng)步。时(shí)鐘(zhōng)被(bèi)用(yòng)来(lái)驅動(dòng)一(yī)个(gè)有(yǒu)限狀态機(jī),对(duì)進(jìn)入(rù)的(de)指令進(jìn)行管(guǎn)線(xiàn)操作。这(zhè)使得SDRAM與(yǔ)沒(méi)有(yǒu)同(tóng)步接口(kǒu)的(de)异(yì)步DRAM相比,可(kě)以(yǐ)有(yǒu)一(yī)个(gè)更(gèng)複雜的(de)操作模式。

管(guǎn)線(xiàn)意(yì)味着芯片(piàn)可(kě)以(yǐ)在(zài)处理完之前(qián)的(de)指令前(qián),接受一(yī)个(gè)新的(de)指令。在(zài)一(yī)个(gè)写入(rù)的(de)管(guǎn)線(xiàn)中(zhōng),写入(rù)命令在(zài)另(lìng)一(yī)个(gè)指令執行完之後(hòu)可(kě)以(yǐ)立刻執行,而(ér)不(bù)需要(yào)等到(dào)數據(jù)写入(rù)存儲隊列的(de)时(shí)間(jiān)。在(zài)一(yī)个(gè)读(dú)取(qǔ)的(de)流水(shuǐ)線(xiàn)中(zhōng),需要(yào)的(de)數據(jù)在(zài)读(dú)取(qǔ)指令發(fà)出(chū)之後(hòu)固定(dìng)數量(liàng)的(de)时(shí)鐘(zhōng)頻率後(hòu)到(dào)达(dá),而(ér)这(zhè)个(gè)等待的(de)过(guò)程可(kě)以(yǐ)發(fà)出(chū)其他(tā)附加指令。这(zhè)種(zhǒng)延遲被(bèi)稱为(wèi)等待时(shí)間(jiān)(Latency),在(zài)为(wèi)計(jì)算機(jī)購買(mǎi)內(nèi)存时(shí)是(shì)一(yī)个(gè)很重(zhòng)要(yào)的(de)參數。

SDRAM之所(suǒ)以(yǐ)稱为(wèi)DRAM就(jiù)是(shì)因(yīn)为(wèi)他(tā)要(yào)不(bù)斷進(jìn)行刷新才能(néng)保留住數據(jù),因(yīn)为(wèi)刷新是(shì)DRAM最(zuì)重(zhòng)要(yào)的(de)操作。那(nà)麼(me)要(yào)隔多(duō)长时(shí)間(jiān)重(zhòng)複一(yī)次(cì)刷新,目前(qián)公認的(de)标(biāo)準是(shì),存儲體(tǐ)中(zhōng)電(diàn)容的(de)數據(jù)有(yǒu)效保存期(qī)上(shàng)限是(shì)64ms,也(yě)就(jiù)是(shì)每一(yī)行刷新的(de)循环(huán)周期(qī)是(shì)64ms
SDRAM是(shì)多(duō)Bank結構,例如(rú)在(zài)一(yī)个(gè)具有(yǒu)两(liǎng)个(gè)Bank的(de)SDRAM模組中(zhōng),其中(zhōng)一(yī)个(gè)Bank在(zài)進(jìn)行預充電(diàn)期(qī)間(jiān),另(lìng)一(yī)个(gè)Bank卻马上(shàng)可(kě)以(yǐ)被(bèi)读(dú)取(qǔ),这(zhè)樣(yàng)當進(jìn)行一(yī)次(cì)读(dú)取(qǔ)後(hòu),又马上(shàng)读(dú)取(qǔ)已經(jīng)預充電(diàn)Bank的(de)數據(jù)时(shí),就(jiù)无需等待而(ér)是(shì)可(kě)以(yǐ)直(zhí)接读(dú)取(qǔ)了(le),这(zhè)也(yě)就(jiù)大大提(tí)高(gāo)了(le)存儲器的(de)訪問(wèn)速度(dù)

1.1.2 設計(jì)目标(biāo)

設計(jì)SDRAM读(dú)写控制器来(lái)控制開(kāi)發(fà)板上(shàng)的(de)一(yī)片(piàn)SDRAM進(jìn)行读(dú)写數據(jù)的(de)操作,具體(tǐ)功能(néng)要(yào)求如(rú)下(xià):
1.      SDRAM的(de)读(dú)写分(fēn)别由(yóu)两(liǎng)个(gè)按鍵進(jìn)行控制,每按下(xià)一(yī)次(cì),就(jiù)会(huì)産生(shēng)一(yī)个(gè)读(dú)使能(néng)或(huò)者(zhě)写使能(néng);
2.      SDRAM读(dú)写模式为(wèi)全(quán)页(yè)突發(fà)模式,每次(cì)写入(rù)某个(gè)Bank512个(gè)數據(jù),在(zài)读(dú)此(cǐ)Bank的(de)时(shí)候,也(yě)應(yìng)該读(dú)出(chū)相同(tóng)的(de)512个(gè)數據(jù);
3.      SDRAM读(dú)写地(dì)址都是(shì)從地(dì)址0開(kāi)始;
4.     通(tòng)过(guò)一(yī)个(gè)按鍵控制读(dú)写SDRAM的(de)Bank地(dì)址,按鍵每按下(xià)一(yī)次(cì),Bank地(dì)址加1。

1.1.3 系(xì)統結構框图(tú)
系(xì)統結構框图(tú)如(rú)下(xià)图(tú)一(yī)所(suǒ)示:


图(tú)一(yī)
1.1.4模块(kuài)功能(néng)


  按鍵檢测模块(kuài)实現(xiàn)功能(néng)
1、  将外(wài)来(lái)异(yì)步信(xìn)号(hào)打(dǎ)两(liǎng)拍处理,将异(yì)步信(xìn)号(hào)同(tóng)步化(huà)。
2、  实現(xiàn)20ms按鍵消抖功能(néng)。
3、  实現(xiàn)矩阵(zhèn)鍵盤或(huò)者(zhě)普通(tòng)案(àn)件(jiàn)的(de)檢测功能(néng),并輸出(chū)有(yǒu)效按鍵信(xìn)号(hào)。

鎖相环(huán)
1、産生(shēng)工程所(suǒ)需要(yào)的(de)100M时(shí)鐘(zhōng)。

  數據(jù)産生(shēng)模块(kuài)实現(xiàn)功能(néng)
1、  通(tòng)过(guò)按鍵控制産生(shēng)读(dú)/写請求。
2、  通(tòng)过(guò)按鍵控制Bank地(dì)址選擇。
3、  産生(shēng)地(dì)址和(hé)写數據(jù)。

SDRAM接口(kǒu)模块(kuài)实現(xiàn)功能(néng)
1、  接收(shōu)上(shàng)遊模块(kuài)發(fà)送的(de)读(dú)/写請求、Bank地(dì)址、行地(dì)址和(hé)写數據(jù),産生(shēng)SDRAM的(de)控制时(shí)序。

1.1.5頂层信(xìn)号(hào)
  
信(xìn)号(hào)名
  
I/O
位宽(kuān)
定(dìng)義
clk
I
1
系(xì)統工作时(shí)鐘(zhōng) 50M
rst_n
I
1
系(xì)統複位信(xìn)号(hào),低電(diàn)平有(yǒu)效
Key
I
4
4位按鍵信(xìn)号(hào),開(kāi)發(fà)板按鍵为(wèi)矩阵(zhèn)鍵盤时(shí),不(bù)需要(yào)該信(xìn)号(hào)
Key_col
I
4
4位矩阵(zhèn)鍵盤列信(xìn)号(hào),默認高(gāo)電(diàn)平,開(kāi)發(fà)板按鍵为(wèi)普通(tòng)按鍵时(shí),不(bù)需要(yào)該信(xìn)号(hào)
Key_row
O
4
4位矩阵(zhèn)鍵盤行信(xìn)号(hào),默認低電(diàn)平,開(kāi)發(fà)板按鍵为(wèi)普通(tòng)按鍵时(shí),不(bù)需要(yào)該信(xìn)号(hào)
dq
I/O
16
SDRAM數據(jù)總(zǒng)線(xiàn),既能(néng)作为(wèi)數據(jù)輸出(chū),也(yě)能(néng)作为(wèi)數據(jù)輸入(rù)。
cke
O
1
SDRAM时(shí)鐘(zhōng)使能(néng)信(xìn)号(hào),決定(dìng)是(shì)否啟用(yòng)clk輸入(rù),为(wèi)高(gāo)電(diàn)平时(shí),时(shí)鐘(zhōng)有(yǒu)效。
cs
O
1
SDRAM片(piàn)選信(xìn)号(hào),決定(dìng)設備內(nèi)是(shì)否啟用(yòng)命令輸入(rù),當cs为(wèi)低时(shí)啟用(yòng),當cs为(wèi)高(gāo)时(shí)禁用(yòng)命令輸入(rù)。
ras
O
1
行地(dì)址選通(tòng)信(xìn)号(hào),低電(diàn)平有(yǒu)效
cas
O
1
列地(dì)址選通(tòng)信(xìn)号(hào),低電(diàn)平有(yǒu)效
we
O
1
写使能(néng)信(xìn)号(hào),低電(diàn)平有(yǒu)效
dqm
O
2
數據(jù)掩碼,控制I/O的(de)高(gāo)低字(zì)节(jié),低電(diàn)平有(yǒu)效。例如(rú):2’b10,表(biǎo)示數據(jù)高(gāo)字(zì)节(jié)无效,低字(zì)节(jié)有(yǒu)效。
sd_addr
O
13
SDRAM地(dì)址信(xìn)号(hào)。
sd_bank
O
2
Bank地(dì)址選擇信(xìn)号(hào),通(tòng)过(guò)該信(xìn)号(hào)決定(dìng)哪个(gè)Bank正(zhèng)处于(yú)激活、读(dú)、写、預充電(diàn)等命令期(qī)間(jiān)。
sd_clk
O
1
SDRAM輸入(rù)时(shí)鐘(zhōng),除cke外(wài),SDRAM的(de)所(suǒ)有(yǒu)輸入(rù)與(yǔ)該引脚的(de)上(shàng)升(shēng)沿同(tóng)步獲得。

1.1.6三(sān)态門(mén)

由(yóu)于(yú)SDRAM只(zhī)有(yǒu)一(yī)条(tiáo)數據(jù)總(zǒng)線(xiàn),虽然可(kě)以(yǐ)既當作輸入(rù),又當作輸出(chū)来(lái)用(yòng),但是(shì)輸入(rù)和(hé)輸出(chū)是(shì)不(bù)能(néng)同(tóng)时(shí)進(jìn)行的(de),因(yīn)此(cǐ)需要(yào)在(zài)工程的(de)頂层設計(jì)中(zhōng)采用(yòng)三(sān)态門(mén)。代(dài)碼如(rú)下(xià):


關(guān)于(yú)三(sān)态門(mén)詳细(xì)的(de)介紹可(kě)以(yǐ)看(kàn)明(míng)德揚《FPGA至(zhì)簡設計(jì)原理與(yǔ)應(yìng)用(yòng)》書(shū)中(zhōng)的(de)第(dì)一(yī)篇(piān)第(dì)三(sān)章(zhāng)5.2.4高(gāo)阻态一(yī)节(jié)。

1.1.7參考代(dài)碼
下(xià)面(miàn)是(shì)使用(yòng)工程的(de)頂层代(dài)碼:

  1. module sdram_top(
  2.     clk      ,
  3.     rst_n    ,
  4.     key      ,
  5.     dq       ,
  6.     cke      ,
  7.     cs       ,  
  8.     ras      ,
  9.     cas      ,
  10.     we       ,
  11.     dqm      ,
  12.     sd_addr  ,
  13.     sd_bank  ,
  14.     sd_clk     
  15.     );

  16.     input              clk     ;
  17.     input              rst_n   ;
  18.     input  [3:0]       key     ;
  19.     inout  [15:0]      dq      ;
  20.     output             cke     ;   
  21.     output             cs      ;
  22.     output             ras     ;
  23.     output             cas     ;
  24.     output             we      ;
  25.     output [1 :0]      dqm     ;
  26.     output [12:0]      sd_addr ;
  27.     output [1 :0]      sd_bank ;
  28.     output             sd_clk  ;



  29.     wire               cke     ;
  30.     wire               cs      ;
  31.     wire               ras     ;
  32.     wire               cas     ;
  33.     wire               we      ;
  34.     wire  [1 :0]       dqm     ;
  35.     wire  [12:0]       sd_addr ;
  36.     wire  [1 :0]       sd_bank ;
  37.     wire               sd_clk  ;



  38.     wire              clk_100m ;
  39.     wire              wr_ack   ;
  40.     wire              rd_ack   ;
  41.     wire              wr_req   ;
  42.     wire              rd_req   ;
  43.     wire [1 :0]       bank     ;
  44.     wire [12:0]       addr     ;
  45.     wire [15:0]       wdata    ;
  46.     wire [15:0]       rdata    ;
  47.     wire              rdata_vld;
  48.     wire [3:0 ]       key_vld  ;

  49.     wire [15:0]       dq_in    ;
  50.     wire [15:0]       dq_out   ;
  51.     wire              dq_out_en;

  52.     assign  dq_in = dq;
  53.     assign  dq    = dq_out_en?dq_out:16'hzzzz;
  54.         


  55.     pll_100m uut_pll(
  56.             .inclk0    (clk      ),
  57.             .c0        (clk_100m )
  58.     );

  59.     key_module uut_key(
  60.         .clk       (clk_100m ),
  61.         .rst_n     (rst_n    ),
  62.         .key_in    (key      ),
  63.         .key_vld   (key_vld  ),
  64.     );
  65.         
  66.     data_ctrl uut_ctrl(
  67.         .clk       (clk_100m ),
  68.         .rst_n     (rst_n    ),
  69.         .key_vld   (key_vld  ),
  70.         .wr_ack    (wr_ack   ),   
  71.         .rd_ack    (rd_ack   ),   
  72.         .wr_req    (wr_req   ),   
  73.         .rd_req    (rd_req   ),   
  74.         .bank      (bank     ),   
  75.         .addr      (addr     ),   
  76.         .wdata     (wdata    )   
  77.         );
  78.    
  79.     sdram_intf uut_sdram(
  80.         .clk       (clk_100m ),   
  81.         .rst_n     (rst_n    ),
  82.         .wr_req    (wr_req   ),
  83.         .rd_req    (rd_req   ),
  84.         .bank      (bank     ),
  85.         .addr      (addr     ),
  86.         .wdata     (wdata    ),
  87.         .dq_in     (dq_in    ),
  88.         .dq_out    (dq_out   ),
  89.         .dq_out_en (dq_out_en),
  90.         .wr_ack    (wr_ack   ),
  91.         .rd_ack    (rd_ack   ),
  92.         .rdata     (rdata    ),
  93.         .rdata_vld (rdata_vld),
  94.         .cke       (cke      ),
  95.         .cs        (cs       ),
  96.         .ras       (ras      ),
  97.         .cas       (cas      ),
  98.         .we        (we       ),
  99.         .dqm       (dqm      ),
  100.         .sd_addr   (sd_addr  ),
  101.         .sd_bank   (sd_bank  ),
  102.         .sd_clk    (sd_clk   )  
  103.         
  104.     );



  105.     endmodule
複制代(dài)碼


1.2 按鍵檢测模块(kuài)設計(jì)
1.2.1接口(kǒu)信(xìn)号(hào)
下(xià)面(miàn)为(wèi)使用(yòng)矩阵(zhèn)鍵盤时(shí)的(de)接口(kǒu)信(xìn)号(hào):
  
信(xìn)号(hào)
  
接口(kǒu)方(fāng)向(xiàng)
定(dìng)義
clk
輸入(rù)
系(xì)統时(shí)鐘(zhōng)
rst_n
輸入(rù)
低電(diàn)平複位信(xìn)号(hào)
key_col
輸入(rù)
矩阵(zhèn)鍵盤列輸入(rù)信(xìn)号(hào)
Key_row
輸出(chū)
矩阵(zhèn)鍵盤行輸出(chū)信(xìn)号(hào)
Key_en
輸出(chū)
按鍵按下(xià)位置指示信(xìn)号(hào)

下(xià)面(miàn)是(shì)使用(yòng)普通(tòng)按鍵时(shí)的(de)接口(kǒu)信(xìn)号(hào):

  
信(xìn)号(hào)
  
接口(kǒu)方(fāng)向(xiàng)
定(dìng)義
clk
輸入(rù)
系(xì)統时(shí)鐘(zhōng)
rst_n
輸入(rù)
低電(diàn)平複位信(xìn)号(hào)
Key_in
輸入(rù)
按鍵輸入(rù)信(xìn)号(hào)
Key_vld
輸出(chū)
按鍵按下(xià)指示信(xìn)号(hào)


1.2.2 設計(jì)思(sī)路(lù)
在(zài)前(qián)面(miàn)的(de)按鍵控制數字(zì)时(shí)鐘(zhōng)的(de)案(àn)例中(zhōng)已經(jīng)有(yǒu)介紹,所(suǒ)以(yǐ)这(zhè)里(lǐ)不(bù)在(zài)过(guò)多(duō)介紹,詳细(xì)介紹請看(kàn)下(xià)方(fāng)鍊(liàn)接:


1.2.3 參考代(dài)碼
1.    //矩阵(zhèn)鍵盤
  1. always  @(posedge clk or negedge rst_n)begin
  2.     if(rst_n==1'b0)begin
  3.         key_col_ff0 <= 4'b1111;
  4.         key_col_ff1 <= 4'b1111;
  5.     end
  6.     else begin
  7.         key_col_ff0 <= key_col    ;
  8.         key_col_ff1 <= key_col_ff0;
  9.     end
  10. end


  11. always @(posedge clk or negedge rst_n) begin
  12.     if (rst_n==0) begin
  13.         shake_cnt <= 0;
  14.     end
  15.     else if(add_shake_cnt) begin
  16.         if(end_shake_cnt)
  17.             shake_cnt <= 0;
  18.         else
  19.             shake_cnt <= shake_cnt+1 ;
  20.    end
  21. end
  22. assign add_shake_cnt = key_col_ff1!=4'hf;
  23. assign end_shake_cnt = add_shake_cnt  && shake_cnt == TIME_20MS-1 ;


  24. always  @(posedge clk or negedge rst_n)begin
  25.     if(rst_n==1'b0)begin
  26.         state_c <= CHK_COL;
  27.     end
  28.     else begin
  29.         state_c <= state_n;
  30.     end
  31. end

  32. always  @(*)begin
  33.     case(state_c)
  34.         CHK_COL: begin
  35.                      if(col2row_start )begin
  36.                          state_n = CHK_ROW;
  37.                      end
  38.                      else begin
  39.                          state_n = CHK_COL;
  40.                      end
  41.                  end
  42.         CHK_ROW: begin
  43.                      if(row2del_start)begin
  44.                          state_n = DELAY;
  45.                      end
  46.                      else begin
  47.                          state_n = CHK_ROW;
  48.                      end
  49.                  end
  50.         DELAY :  begin
  51.                      if(del2wait_start)begin
  52.                          state_n = WAIT_END;
  53.                      end
  54.                      else begin
  55.                          state_n = DELAY;
  56.                      end
  57.                  end
  58.         WAIT_END: begin
  59.                      if(wait2col_start)begin
  60.                          state_n = CHK_COL;
  61.                      end
  62.                      else begin
  63.                          state_n = WAIT_END;
  64.                      end
  65.                   end
  66.        default: state_n = CHK_COL;
  67.     endcase
  68. end
  69. assign col2row_start = state_c==CHK_COL  && end_shake_cnt;
  70. assign row2del_start = state_c==CHK_ROW  && row_index==3 && end_row_cnt;
  71. assign del2wait_start= state_c==DELAY    && end_row_cnt;
  72. assign wait2col_start= state_c==WAIT_END && key_col_ff1==4'hf;

  73. always  @(posedge clk or negedge rst_n)begin
  74.     if(rst_n==1'b0)begin
  75.         key_row <= 4'b0;
  76.     end
  77.     else if(state_c==CHK_ROW)begin
  78.         key_row <= ~(1'b1 << row_index);
  79.     end
  80.     else begin
  81.         key_row <= 4'b0;
  82.     end
  83. end



  84. 普通(tòng)鍵盤

  85. always @(posedge clk or negedge rst_n) begin
  86.     if (rst_n==0) begin
  87.         row_index <= 0;
  88.     end
  89.     else if(add_row_index) begin
  90.         if(end_row_index)
  91.             row_index <= 0;
  92.         else
  93.             row_index <= row_index+1 ;
  94.    end
  95.    else if(state_c!=CHK_ROW)begin
  96.        row_index <= 0;
  97.    end
  98. end
  99. assign add_row_index = state_c==CHK_ROW && end_row_cnt;
  100. assign end_row_index = add_row_index  && row_index == 4-1 ;


  101. always @(posedge clk or negedge rst_n) begin
  102.     if (rst_n==0) begin
  103.         row_cnt <= 0;
  104.     end
  105.     else if(add_row_cnt) begin
  106.         if(end_row_cnt)
  107.             row_cnt <= 0;
  108.         else
  109.             row_cnt <= row_cnt+1 ;
  110.    end
  111. end
  112. assign add_row_cnt = state_c==CHK_ROW || state_c==DELAY;
  113. assign end_row_cnt = add_row_cnt  && row_cnt == 16-1 ;



  114. always  @(posedge clk or negedge rst_n)begin
  115.     if(rst_n==1'b0)begin
  116.         key_col_get <= 0;
  117.     end
  118.     else if(state_c==CHK_COL && end_shake_cnt ) begin
  119.         if(key_col_ff1==4'b1110)
  120.             key_col_get <= 0;
  121.         else if(key_col_ff1==4'b1101)
  122.             key_col_get <= 1;
  123.         else if(key_col_ff1==4'b1011)
  124.             key_col_get <= 2;
  125.         else
  126.             key_col_get <= 3;
  127.     end
  128. end


  129. always  @(posedge clk or negedge rst_n)begin
  130.     if(rst_n==1'b0)begin
  131.         key_out <= 0;
  132.     end
  133.     else if(state_c==CHK_ROW && end_row_cnt)begin
  134.         key_out <= {row_index,key_col_get};
  135.     end
  136.     else begin
  137.         key_out <= 0;
  138.     end
  139. end

  140. always  @(posedge clk or negedge rst_n)begin
  141.     if(rst_n==1'b0)begin
  142.         key_vld <= 1'b0;
  143.     end
  144.     else if(state_c==CHK_ROW && end_row_cnt && key_col_ff1[key_col_get]==1'b0)begin
  145.         key_vld <= 1'b1;
  146.     end
  147.     else begin
  148.         key_vld <= 1'b0;
  149.     end
  150. end


  151. always  @(*)begin
  152.     if(rst_n==1'b0)begin
  153.         key_en = 0;
  154.     end
  155.     else if(key_vld && key_out==0)begin
  156.         key_en = 4'b0001;
  157.     end
  158.     else if(key_vld && key_out==1)begin
  159.         key_en = 4'b0010;
  160.     end
  161.     else if(key_vld && key_out==2)begin
  162.         key_en = 4'b0100;
  163.     end
  164.     else begin
  165.         key_en = 0;
  166.     end
  167. end


  168. endmodule
複制代(dài)碼




1.3 鎖相环(huán)
1.3.1 接口(kǒu)信(xìn)号(hào)
  
信(xìn)号(hào)名
  
I/O
位宽(kuān)
定(dìng)義
Inclk0
I
1
輸入(rù)时(shí)鐘(zhōng)50M
C0
O
1
輸出(chū)时(shí)鐘(zhōng)100M

1.3.2 設計(jì)思(sī)路(lù)
此(cǐ)模块(kuài)是(shì)使用(yòng)Quartus生(shēng)成(chéng)的(de)PLL IP核,相關(guān)的(de)生(shēng)成(chéng)步驟、功能(néng)原理等可(kě)以(yǐ)看(kàn)明(míng)德揚論壇中(zhōng)關(guān)于(yú)PLL的(de)介紹。

1.4 數據(jù)産生(shēng)模块(kuài)設計(jì)
1.4.1接口(kǒu)信(xìn)号(hào)
  
信(xìn)号(hào)名
  
I/O
位宽(kuān)
定(dìng)義
clk
I
1
工作时(shí)鐘(zhōng) 100M
rst_n
I
1
系(xì)統複位信(xìn)号(hào),低電(diàn)平有(yǒu)效
Key_vld
I
4
按鍵有(yǒu)效指示信(xìn)号(hào)
Wr_ack
I
1
写數據(jù)響應(yìng)
rd_ack
I
1
读(dú)數據(jù)響應(yìng)
Wr_req
O
1
写數據(jù)請求
rd_req
O
1
读(dú)數據(jù)響應(yìng)
bank
O
2
Bank地(dì)址選擇信(xìn)号(hào)
addr
O
13
SDRAM地(dì)址信(xìn)号(hào)
Wdata
O
16
SDRAM写數據(jù)

1.4.2設計(jì)思(sī)路(lù)

該模块(kuài)主(zhǔ)要(yào)实現(xiàn)的(de)功能(néng)是(shì)根(gēn)據(jù)按鍵,産生(shēng)读(dú)請求、写請求、Bank地(dì)址、写數據(jù)和(hé)SDRAM地(dì)址。下(xià)面(miàn)是(shì)該模块(kuài)主(zhǔ)要(yào)信(xìn)号(hào)的(de)設計(jì)思(sī)路(lù):
写請求wr_req:初始狀态为(wèi)低電(diàn)平,表(biǎo)示沒(méi)有(yǒu)往SDRAM里(lǐ)面(miàn)写數據(jù)的(de)請求;當按下(xià)按鍵key1的(de)时(shí)候,写請求變(biàn)为(wèi)高(gāo)電(diàn)平,表(biǎo)示請求往SDRAM內(nèi)部(bù)写入(rù)數據(jù),因(yīn)此(cǐ)写請求拉高(gāo)的(de)条(tiáo)件(jiàn)为(wèi)key_vld[0]==1;當接收(shōu)到(dào)接收(shōu)到(dào)写響應(yìng)为(wèi)高(gāo)電(diàn)平的(de)时(shí)候,表(biǎo)示同(tóng)意(yì)往SDRAM写入(rù)數據(jù),此(cǐ)时(shí)将写請求置为(wèi)低電(diàn)平,因(yīn)此(cǐ)写請求的(de)拉低条(tiáo)件(jiàn)为(wèi)wr_ack==1

读(dú)請求rd_req:初始狀态为(wèi)低電(diàn)平,表(biǎo)示沒(méi)有(yǒu)读(dú)出(chū)SDRAM中(zhōng)數據(jù)的(de)請求;當按下(xià)按鍵key2的(de)时(shí)候,读(dú)請求變(biàn)为(wèi)高(gāo)電(diàn)平,表(biǎo)示請求读(dú)出(chū)SDRAM內(nèi)部(bù)數據(jù),因(yīn)此(cǐ)读(dú)請求拉高(gāo)的(de)条(tiáo)件(jiàn)为(wèi)key_vld[1]==1;當接收(shōu)到(dào)接收(shōu)到(dào)读(dú)響應(yìng)为(wèi)高(gāo)電(diàn)平的(de)时(shí)候,表(biǎo)示SDRAM同(tóng)意(yì)读(dú)出(chū)數據(jù),此(cǐ)时(shí)将读(dú)請求置为(wèi)低電(diàn)平,因(yīn)此(cǐ)读(dú)請求的(de)拉低条(tiáo)件(jiàn)为(wèi)rd_ack==1

读(dú)写Bank地(dì)址信(xìn)号(hào)bank:初始狀态为(wèi)0,表(biǎo)示默認選擇Bank0進(jìn)行數據(jù)的(de)读(dú)写操作;加一(yī)条(tiáo)件(jiàn)为(wèi)key_vld[2]==1,表(biǎo)示按鍵key3每按下(xià)一(yī)次(cì),Bank地(dì)址就(jiù)加一(yī);結束(shù)条(tiáo)件(jiàn)为(wèi)數4个(gè),因(yīn)为(wèi)一(yī)片(piàn)SDRAM共(gòng)有(yǒu)4个(gè)Bank,數完就(jiù)清(qīng)零(líng)。


SDRAM地(dì)址信(xìn)号(hào)addr:固定(dìng)为(wèi)0即可(kě)。

写數據(jù)wdata:該信(xìn)号(hào)表(biǎo)示要(yào)写入(rù)SDRAM中(zhōng)的(de)數據(jù),在(zài)接收(shōu)到(dào)写響應(yìng)後(hòu)有(yǒu)效。設置时(shí)鐘(zhōng)計(jì)數器cnt2,在(zài)收(shōu)到(dào)写響應(yìng)之後(hòu)開(kāi)始計(jì)數,由(yóu)于(yú)本(běn)工程使用(yòng)SDRAM全(quán)页(yè)突發(fà)模式一(yī)次(cì)写數據(jù)为(wèi)512个(gè),因(yīn)此(cǐ)該計(jì)數器結束(shù)条(tiáo)件(jiàn)为(wèi)數512个(gè),将該計(jì)數器的(de)值作为(wèi)写數據(jù)。



1.4.3參考代(dài)碼
  1. always  @(posedge clk or negedge rst_n)begin
  2.     if(rst_n==1'b0)begin
  3.         wr_req <= 0;
  4.     end
  5.     else if(key_vld[0]==1)begin
  6.         wr_req <= 1;
  7.     end
  8.     else if(wr_ack)begin
  9.         wr_req <= 0;
  10.     end
  11. end


  12. always  @(posedge clk or negedge rst_n)begin
  13.     if(rst_n==1'b0)begin
  14.         rd_req <= 0;
  15.     end
  16.     else if(key_vld[1]==1)begin
  17.         rd_req <= 1;
  18.     end
  19.     else if(rd_ack)begin
  20.         rd_req <= 0;
  21.     end
  22. end


  23. always @(posedge clk or negedge rst_n) begin
  24.     if (rst_n==0) begin
  25.         bank <= 0;
  26.     end
  27.     else if(add_bank) begin
  28.         if(end_bank)
  29.             bank <= 0;
  30.         else
  31.             bank <= bank+1 ;
  32.    end
  33. end
  34. assign add_bank = key_vld[2]==1;
  35. assign end_bank = add_bank  && bank == 4-1 ;


  36. always  @(*)begin
  37.     if(flag_wr)begin
  38.         wdata = {7'b0,cnt2};
  39.     end
  40.     else begin
  41.         wdata = 0;
  42.     end
  43. end


  44. always  @(posedge clk or negedge rst_n)begin
  45.     if(rst_n==1'b0)begin
  46.         flag_wr <= 0;
  47.     end
  48.     else if(wr_ack)begin
  49.         flag_wr <= 1;
  50.     end
  51.     else if(end_cnt2)begin
  52.         flag_wr <= 0;
  53.     end
  54. end


  55. always @(posedge clk or negedge rst_n) begin
  56.     if (rst_n==0) begin
  57.         cnt2 <= 0;
  58.     end
  59.     else if(add_cnt2) begin
  60.         if(end_cnt2)
  61.             cnt2 <= 0;
  62.         else
  63.             cnt2 <= cnt2+1 ;
  64.    end
  65. end
  66. assign add_cnt2 = flag_wr;
  67. assign end_cnt2 = add_cnt2  && cnt2 == 512-1 ;

  68. assign addr = 13'b0;


  69. endmodule
複制代(dài)碼


1.5 SDRAM接口(kǒu)模块(kuài)設計(jì)
1.5.1接口(kǒu)信(xìn)号(hào)
  
信(xìn)号(hào)名
  
I/O
位宽(kuān)
定(dìng)義
clk
I
1
1工作时(shí)鐘(zhōng)  100M
rst_n
I
1
系(xì)統複位信(xìn)号(hào),低電(diàn)平有(yǒu)效
Wr_req
I
1
写請求
rd_req
I
1
读(dú)請求
bank
I
2
輸入(rù)bank地(dì)址
addr
I
13
地(dì)址信(xìn)号(hào)
Wdata
I
16
写數據(jù)
dq_in
I
16
SDRAM數據(jù)輸入(rù)
dq_out
O
16
写SDRAM數據(jù)信(xìn)号(hào)
dq_out_en
O
1
三(sān)态門(mén)使能(néng)
Wr_ack
O
1
写響應(yìng)
rd_ack
O
1
读(dú)響應(yìng)
rdata
O
16
读(dú)數據(jù)
rdata_vld
O
1
读(dú)數據(jù)有(yǒu)效指示信(xìn)号(hào)
Cke
O
1
SDRAM时(shí)鐘(zhōng)使能(néng)信(xìn)号(hào),決定(dìng)是(shì)否啟用(yòng)clk輸入(rù),为(wèi)高(gāo)電(diàn)平时(shí),时(shí)鐘(zhōng)有(yǒu)效。
Cs
O
1
SDRAM片(piàn)選信(xìn)号(hào),決定(dìng)設備內(nèi)是(shì)否啟用(yòng)命令輸入(rù),當cs为(wèi)低时(shí)啟用(yòng),當cs为(wèi)高(gāo)时(shí)禁用(yòng)命令輸入(rù)。
ras
O
1
行地(dì)址選通(tòng)信(xìn)号(hào),低電(diàn)平有(yǒu)效
Cas
O
1
列地(dì)址選通(tòng)信(xìn)号(hào),低電(diàn)平有(yǒu)效
We
O
1
写使能(néng)信(xìn)号(hào),低電(diàn)平有(yǒu)效
dqm
O
2
數據(jù)掩碼,控制I/O的(de)高(gāo)低字(zì)节(jié),低電(diàn)平有(yǒu)效。例如(rú):2’b10,表(biǎo)示數據(jù)高(gāo)字(zì)节(jié)无效,低字(zì)节(jié)有(yǒu)效。
Sd_addr
O
13
SDRAM地(dì)址信(xìn)号(hào)。
Sd_bank
O
2
Bank地(dì)址選擇信(xìn)号(hào),通(tòng)过(guò)該信(xìn)号(hào)決定(dìng)哪个(gè)Bank正(zhèng)处于(yú)激活、读(dú)、写、預充電(diàn)等命令期(qī)間(jiān)。
Sd_clk
O
1
SDRAM輸入(rù)时(shí)鐘(zhōng),除cke外(wài),SDRAM的(de)所(suǒ)有(yǒu)輸入(rù)與(yǔ)該引脚的(de)上(shàng)升(shēng)沿同(tóng)步獲得。

1.5.2SDRAM工作流程


SDRAM初始化(huà)
SDRAM內(nèi)部(bù)有(yǒu)一(yī)个(gè)邏輯控制單元(yuán),并且有(yǒu)一(yī)个(gè)模式寄存器为(wèi)其提(tí)供控制參數。每次(cì)開(kāi)機(jī)时(shí)SDRAM都要(yào)先(xiān)对(duì)这(zhè)个(gè)控制邏輯核心(xīn)進(jìn)行初始化(huà)。SDRAM必須以(yǐ)預定(dìng)義的(de)方(fāng)式啟動(dòng)和(hé)初始化(huà)。在(zài)電(diàn)源同(tóng)时(shí)作用(yòng)于(yú)Vdd和(hé)Vddq後(hòu)開(kāi)始初始化(huà)SDRAM,此(cǐ)时(shí)的(de)时(shí)鐘(zhōng)稳定(dìng)并且将數據(jù)掩碼和(hé)时(shí)鐘(zhōng)使能(néng)信(xìn)号(hào)拉高(gāo)。在(zài)向(xiàng)SDRAM發(fà)送命令之前(qián)需要(yào)有(yǒu)100us的(de)延时(shí),此(cǐ)时(shí)SDRAM不(bù)執行任何操作。在(zài)100us延时(shí)滿足後(hòu),需要(yào)对(duì)Bank進(jìn)行預充電(diàn),在(zài)此(cǐ)期(qī)間(jiān)所(suǒ)有(yǒu)的(de)Bank处于(yú)空閑狀态。預充電(diàn)之後(hòu)会(huì)有(yǒu)至(zhì)少(shǎo)两(liǎng)个(gè)自(zì)刷新操作,完成(chéng)自(zì)刷新便可(kě)以(yǐ)对(duì)SDRAM進(jìn)行模式寄存器配置。下(xià)面(miàn)是(shì)初始化(huà)的(de)时(shí)序图(tú)


從上(shàng)图(tú)中(zhōng)可(kě)以(yǐ)看(kàn)出(chū),上(shàng)電(diàn)後(hòu)等待时(shí)間(jiān)为(wèi)T=100us,預充電(diàn)操作需要(yào)的(de)时(shí)間(jiān)为(wèi)TRP,一(yī)次(cì)自(zì)刷新需要(yào)的(de)时(shí)間(jiān)是(shì)TRC,加载模式寄存器需要(yào)的(de)时(shí)間(jiān)为(wèi)TMRD

在(zài)初始化(huà)中(zhōng)的(de)預充電(diàn)期(qī)間(jiān),地(dì)址線(xiàn)A10定(dìng)義自(zì)動(dòng)預充電(diàn),以(yǐ)确定(dìng)是(shì)否所(suǒ)有(yǒu)Bank都被(bèi)預充電(diàn),也(yě)可(kě)以(yǐ)通(tòng)过(guò)Bank地(dì)址選擇信(xìn)号(hào)BA0和(hé)BA1来(lái)決定(dìng)進(jìn)行預充電(diàn)的(de)Bank地(dì)址。在(zài)加载模式寄存器期(qī)間(jiān),地(dì)址線(xiàn)A0到(dào)A11一(yī)起組成(chéng)命令碼。

SDRAM行激活
初始化(huà)完成(chéng)之後(hòu),在(zài)向(xiàng)SDRAM發(fà)送读(dú)或(huò)者(zhě)写命令之前(qián)必須打(dǎ)開(kāi)該Bank中(zhōng)的(de)一(yī)行,通(tòng)过(guò)ACTIVE命令来(lái)确定(dìng)要(yào)激活的(de)Bank和(hé)行。要(yào)想(xiǎng)对(duì)一(yī)个(gè)Bank中(zhōng)的(de)阵(zhèn)列進(jìn)行尋址,首先(xiān)要(yào)确定(dìng)行(Row),然後(hòu)确定(dìng)列。片(piàn)選信(xìn)号(hào)與(yǔ)Bank選擇信(xìn)号(hào)與(yǔ)行有(yǒu)效同(tóng)时(shí)進(jìn)行,下(xià)面(miàn)是(shì)激活的(de)时(shí)序图(tú)


從上(shàng)图(tú)中(zhōng)可(kě)以(yǐ)看(kàn)出(chū),在(zài)片(piàn)選信(xìn)号(hào)、Bank地(dì)址選定(dìng)的(de)同(tóng)时(shí),行地(dì)址選通(tòng)信(xìn)号(hào)RAS也(yě)处于(yú)有(yǒu)效狀态,此(cǐ)时(shí)An地(dì)址線(xiàn)發(fà)送具體(tǐ)的(de)行地(dì)址。行地(dì)址位宽(kuān)为(wèi)12,共(gòng)可(kě)以(yǐ)指示2^12=4096个(gè)具體(tǐ)的(de)行地(dì)址。當行地(dì)址被(bèi)激活後(hòu),相應(yìng)的(de)Bank也(yě)被(bèi)激活,因(yīn)此(cǐ)行激活又叫L-Bank激活。

列選擇
行地(dì)址确定(dìng)後(hòu),就(jiù)要(yào)对(duì)列地(dì)址進(jìn)行尋址,地(dì)址線(xiàn)仍使用(yòng)A0~A11,即行地(dì)址與(yǔ)列地(dì)址共(gòng)用(yòng)地(dì)址線(xiàn)。當列地(dì)址選通(tòng)後(hòu),就(jiù)需要(yào)对(duì)SDRAM進(jìn)行读(dú)写,而(ér)給(gěi)SDRAM读(dú)命令還(huán)是(shì)写命令由(yóu)WE信(xìn)号(hào)決定(dìng)。當WE信(xìn)号(hào)拉低时(shí),SDRAM接收(shōu)到(dào)的(de)是(shì)写命令;當WE拉高(gāo),SDRAM接收(shōu)读(dú)命令。列尋址信(xìn)号(hào)與(yǔ)读(dú)写命令是(shì)同(tóng)时(shí)發(fà)出(chū)的(de)。虽然地(dì)址線(xiàn)與(yǔ)行尋址共(gòng)用(yòng),但列地(dì)址選通(tòng)脈沖CAS則可(kě)以(yǐ)區(qū)分(fēn)開(kāi)行與(yǔ)列尋址的(de)不(bù)同(tóng),配合A0~A9A11来(lái)确定(dìng)具體(tǐ)的(de)地(dì)址。

在(zài)發(fà)送列读(dú)写命令时(shí)必須要(yào)與(yǔ)有(yǒu)效命令有(yǒu)一(yī)个(gè)时(shí)間(jiān)間(jiān)隔,这(zhè)个(gè)时(shí)間(jiān)間(jiān)隔被(bèi)定(dìng)義为(wèi)TRCD



读(dú)操作
读(dú)命令從輸入(rù)信(xìn)号(hào)BA0BA1中(zhōng)選取(qǔ)要(yào)進(jìn)行读(dú)數據(jù)操作的(de)BANK,并在(zài)已激活的(de)行中(zhōng)進(jìn)行突發(fà)读(dú)写操作。輸入(rù)的(de)A0~A7用(yòng)来(lái)進(jìn)行列尋址。在(zài)選定(dìng)列地(dì)址後(hòu),就(jiù)已經(jīng)确定(dìng)了(le)具體(tǐ)的(de)存儲單元(yuán),剩下(xià)的(de)事(shì)情(qíng)就(jiù)是(shì)數據(jù)通(tòng)过(guò)dq輸出(chū)到(dào)內(nèi)存總(zǒng)線(xiàn)上(shàng)了(le)。但是(shì)再CAS發(fà)出(chū)之後(hòu),仍要(yào)經(jīng)过(guò)一(yī)定(dìng)的(de)时(shí)間(jiān)才能(néng)有(yǒu)數據(jù)輸出(chū),從CAS與(yǔ)读(dú)取(qǔ)命令發(fà)出(chū)到(dào)第(dì)一(yī)个(gè)數據(jù)輸出(chū)的(de)这(zhè)段(duàn)时(shí)間(jiān),被(bèi)定(dìng)義为(wèi)CALLatencyCAS潛伏期(qī))。由(yóu)于(yú)此(cǐ)現(xiàn)象(xiàng)只(zhī)在(zài)读(dú)的(de)时(shí)候出(chū)現(xiàn),所(suǒ)以(yǐ)又稱作读(dú)潛伏期(qī)


由(yóu)于(yú)存儲體(tǐ)中(zhōng)晶體(tǐ)管(guǎn)存在(zài)反(fǎn)應(yìng)时(shí)間(jiān),從而(ér)造成(chéng)數據(jù)不(bù)可(kě)能(néng)與(yǔ)CAS 在(zài)同(tóng)一(yī)上(shàng)升(shēng)沿觸發(fà),因(yīn)此(cǐ)要(yào)延後(hòu)至(zhì)少(shǎo)一(yī)个(gè)时(shí)鐘(zhōng)周期(qī)。考慮到(dào)芯片(piàn)體(tǐ)積較小的(de)因(yīn)素,存儲單元(yuán)中(zhōng)的(de)電(diàn)容容量(liàng)很小,所(suǒ)以(yǐ)信(xìn)号(hào)要(yào)經(jīng)过(guò)放(fàng)大来(lái)保證其有(yǒu)效的(de)識别性(xìng),这(zhè)个(gè)放(fàng)大/驅動(dòng)工作由(yóu) S-AMP 負責,一(yī)个(gè)存儲體(tǐ)对(duì)應(yìng)一(yī)个(gè) S-AMP 通(tòng)道(dào)。但它(tā)要(yào)有(yǒu)一(yī)个(gè)準備时(shí)間(jiān)才能(néng)保證信(xìn)号(hào)的(de)發(fà)送強(qiáng)度(dù)(事(shì)前(qián)還(huán)要(yào)進(jìn)行電(diàn)壓比較以(yǐ)進(jìn)行邏輯電(diàn)平的(de)判斷),因(yīn)此(cǐ)從數據(jù) I/O 總(zǒng)線(xiàn)上(shàng)有(yǒu)數據(jù)輸出(chū)之前(qián)的(de)一(yī)个(gè)时(shí)鐘(zhōng)上(shàng)升(shēng)沿開(kāi)始,數據(jù)即已傳向(xiàng) S-AMP,也(yě)就(jiù)是(shì)说(shuō)此(cǐ)时(shí)數據(jù)已經(jīng)被(bèi)觸發(fà),經(jīng)过(guò)一(yī)定(dìng)的(de)驅動(dòng)时(shí)間(jiān)最(zuì)終(zhōng)傳向(xiàng)數據(jù) I/O 總(zǒng)線(xiàn)進(jìn)行輸出(chū),这(zhè)段(duàn)时(shí)間(jiān)我(wǒ)们(men)稱之为(wèi) tACAccess-Time-from-CLK,时(shí)鐘(zhōng)觸發(fà)後(hòu)的(de)訪問(wèn)时(shí)間(jiān)),單位是(shì) ns。在(zài)突發(fà)读(dú)操作完成(chéng)後(hòu),如(rú)果(guǒ)選擇了(le)自(zì)動(dòng)預充電(diàn)模式,那(nà)麼(me)該行就(jiù)会(huì)直(zhí)接進(jìn)入(rù)充電(diàn)。如(rú)果(guǒ)沒(méi)有(yǒu)選擇此(cǐ)模式,那(nà)麼(me)該行将保持(chí)打(dǎ)開(kāi)狀态,供後(hòu)續訪問(wèn)。自(zì)動(dòng)預充電(diàn)模式的(de)選擇與(yǔ) A10的(de)值有(yǒu)關(guān),A10 为(wèi)高(gāo)时(shí)为(wèi)自(zì)動(dòng)預充電(diàn)命令模式。

写操作
數據(jù)写入(rù)的(de)操作也(yě)是(shì)在(zài) tRCD 之後(hòu)進(jìn)行,但此(cǐ)时(shí)沒(méi)有(yǒu) CLCL 只(zhī)出(chū)現(xiàn)在(zài)读(dú)取(qǔ)操作中(zhōng)),行尋址與(yǔ)列尋址的(de)时(shí)序一(yī)樣(yàng)致(zhì),只(zhī)是(shì)在(zài)列尋址时(shí),WE#为(wèi)有(yǒu)效狀态。由(yóu)于(yú)數據(jù)信(xìn)号(hào)由(yóu)控制端發(fà)出(chū),輸入(rù)时(shí)芯片(piàn)无需做任何調校(xiào),只(zhī)需直(zhí)接傳到(dào)數據(jù)輸入(rù)寄存器中(zhōng),然後(hòu)再由(yóu)写入(rù)驅動(dòng)器進(jìn)行对(duì)存儲電(diàn)容的(de)充電(diàn)操作,因(yīn)此(cǐ)數據(jù)可(kě)以(yǐ)與(yǔ) CAS 同(tóng)时(shí)發(fà)送,也(yě)就(jiù)是(shì)说(shuō)写入(rù)延遲为(wèi) 0。不(bù)过(guò),數據(jù)并不(bù)是(shì)即时(shí)地(dì)写入(rù)存儲電(diàn)容,因(yīn)为(wèi)選通(tòng)三(sān)极(jí)管(guǎn)(就(jiù)如(rú)读(dú)取(qǔ)时(shí)一(yī)樣(yàng))與(yǔ)電(diàn)容的(de)充電(diàn)必須要(yào)有(yǒu)一(yī)段(duàn)时(shí)間(jiān),所(suǒ)以(yǐ)數據(jù)的(de)真(zhēn)正(zhèng)写入(rù)需要(yào)一(yī)定(dìng)的(de)周期(qī)。

突發(fà)读(dú)写
突發(fà)(Burst)是(shì)指在(zài)同(tóng)一(yī)行中(zhōng)相鄰的(de)存儲單元(yuán)連(lián)續進(jìn)行數據(jù)傳輸的(de)方(fāng)式,連(lián)續傳輸所(suǒ)涉及(jí)到(dào)存儲單元(yuán)(列)的(de)數量(liàng)就(jiù)是(shì)突發(fà)长度(dù)(Burst Lengths,簡稱 BL)。前(qián)文(wén)講到(dào)的(de)读(dú)/写操作,都是(shì)一(yī)次(cì)对(duì)一(yī)个(gè)存儲單元(yuán)進(jìn)行尋址,如(rú)果(guǒ)想(xiǎng)要(yào)連(lián)續的(de)向(xiàng) SDRAM 中(zhōng)读(dú)數據(jù)或(huò)者(zhě)写數據(jù),就(jiù)需要(yào)对(duì)當前(qián)存儲單元(yuán)的(de)下(xià)一(yī)个(gè)單元(yuán)進(jìn)行尋址,也(yě)即是(shì)需要(yào)不(bù)停給(gěi) SDRAM 列激活信(xìn)号(hào)以(yǐ)及(jí)读(dú)/写命令(行地(dì)址不(bù)變(biàn),所(suǒ)以(yǐ)不(bù)用(yòng)再对(duì)行尋址)。虽然由(yóu)于(yú)读(dú)/写延遲相同(tóng)可(kě)以(yǐ)讓數據(jù)的(de)傳輸在(zài) I/O 端是(shì)連(lián)續的(de),但它(tā)占用(yòng)了(le)大量(liàng)的(de)內(nèi)存控制資源,在(zài)數據(jù)進(jìn)行連(lián)續傳輸时(shí)无法輸入(rù)新的(de)命令,效率很低。为(wèi)此(cǐ),人(rén)们(men)開(kāi)發(fà)了(le)突發(fà)傳輸技術(shù),只(zhī)要(yào)指定(dìng)起始列地(dì)址與(yǔ)突發(fà)长度(dù),SDRAM 就(jiù)会(huì)不(bù)再需要(yào)控制器連(lián)續地(dì)提(tí)供列地(dì)址,依次(cì)地(dì)自(zì)動(dòng)对(duì)後(hòu)面(miàn)相應(yìng)數量(liàng)的(de)存儲單元(yuán)進(jìn)行读(dú)/写操作。这(zhè)樣(yàng),在(zài)突發(fà)模式读(dú)写中(zhōng),除了(le)第(dì)一(yī)个(gè)數據(jù)的(de)傳輸需要(yào)若干(gàn)个(gè)周期(qī)(主(zhǔ)要(yào)是(shì)之前(qián)的(de)延遲,一(yī)般的(de)是(shì)tRCD+CL),其後(hòu)每个(gè)數據(jù)只(zhī)需一(yī)个(gè)周期(qī)的(de)即可(kě)獲得。至(zhì)于(yú)突發(fà)长度(dù) BL 的(de)數值,也(yě)是(shì)不(bù)能(néng)随便設或(huò)在(zài)數據(jù)進(jìn)行傳輸前(qián)臨时(shí)決定(dìng),而(ér)是(shì)在(zài)上(shàng)文(wén)講到(dào)的(de) SDRAM 初始化(huà)过(guò)程中(zhōng)模式寄存器配置階(jiē)段(duàn)就(jiù)要(yào)对(duì)突發(fà)长度(dù)進(jìn)行設置。目前(qián)可(kě)用(yòng)的(de)選項是(shì) 1248、全(quán)页(yè)(FullPage),常見(jiàn)的(de)突發(fà)长度(dù)設定(dìng)是(shì) BL=4BL=8 或(huò)者(zhě)全(quán)页(yè)突發(fà)模式。



1.5.3設計(jì)思(sī)路(lù)
經(jīng)过(guò)上(shàng)面(miàn)对(duì)SDRAM工作流程的(de)介紹,可(kě)以(yǐ)采用(yòng)狀态機(jī)作为(wèi)本(běn)工程的(de)一(yī)个(gè)架構,根(gēn)據(jù)指令的(de)不(bù)同(tóng),劃(huà)分(fēn)为(wèi)8个(gè)狀态,分(fēn)别为(wèi)空操作(NOP)、預充電(diàn)(PER)、自(zì)刷新(REF)、加载模式寄存器(MOD)、空閑(IDL)、激活(ACT)、读(dú)數據(jù)(RED)和(hé)写數據(jù)(WIR)。
由(yóu)于(yú)每个(gè)操作需要(yào)的(de)时(shí)間(jiān)都不(bù)同(tóng),因(yīn)此(cǐ)需要(yào)一(yī)个(gè)計(jì)數器来(lái)对(duì)每个(gè)操作需要(yào)的(de)时(shí)間(jiān)進(jìn)行計(jì)數。


該計(jì)數器加一(yī)条(tiáo)件(jiàn)为(wèi)state_c!=IDL,表(biǎo)示只(zhī)要(yào)不(bù)是(shì)处于(yú)空閑狀态,就(jiù)進(jìn)行計(jì)數;結束(shù)条(tiáo)件(jiàn)为(wèi)數x个(gè),x根(gēn)據(jù)目前(qián)所(suǒ)处的(de)狀态的(de)不(bù)同(tóng)而(ér)不(bù)同(tóng),具體(tǐ)數據(jù)可(kě)以(yǐ)看(kàn)下(xià)面(miàn)的(de)表(biǎo)格。
  
當前(qián)狀态
  
計(jì)數器數多(duō)少(shǎo)个(gè)
空操作(NOP)
20000
預充電(diàn)(PER)
2
自(zì)刷新(REF)
7
加载模式寄存器(MOD)
2
激活(ACT)
2
读(dú)/写數據(jù)(RED/WIR)
512

由(yóu)于(yú)再初始化(huà)階(jiē)段(duàn),自(zì)刷新需要(yào)連(lián)續進(jìn)行两(liǎng)次(cì),因(yīn)此(cǐ)需要(yào)将初始化(huà)階(jiē)段(duàn)區(qū)分(fēn)出(chū)来(lái),設計(jì)一(yī)个(gè)初始化(huà)指示信(xìn)号(hào)init_flag:該信(xìn)号(hào)初始狀态为(wèi)高(gāo)電(diàn)平,表(biǎo)示上(shàng)電(diàn)之後(hòu)SDRAM处于(yú)初始化(huà)階(jiē)段(duàn);當初始化(huà)完成(chéng)之後(hòu)變(biàn)为(wèi)低電(diàn)平,因(yīn)此(cǐ)從高(gāo)變(biàn)低的(de)条(tiáo)件(jiàn)为(wèi)mod2idl_start

自(zì)刷新計(jì)數器cnt1:該計(jì)數器表(biǎo)示初始化(huà)階(jiē)段(duàn)進(jìn)行自(zì)刷新的(de)次(cì)數。加一(yī)条(tiáo)件(jiàn)为(wèi)(init_flag && state_c==REF && end__cnt),表(biǎo)示在(zài)初始化(huà)階(jiē)段(duàn),如(rú)果(guǒ)當前(qián)狀态为(wèi)自(zì)刷新,則时(shí)鐘(zhōng)計(jì)數器數完一(yī)次(cì)就(jiù)加一(yī);結束(shù)条(tiáo)件(jiàn)为(wèi)數两(liǎng)个(gè),初始化(huà)階(jiē)段(duàn)共(gòng)進(jìn)行两(liǎng)次(cì)自(zì)刷新,因(yīn)此(cǐ)只(zhī)需要(yào)數两(liǎng)个(gè)即可(kě)。

在(zài)初始化(huà)完成(chéng)之後(hòu),需要(yào)進(jìn)行自(zì)刷新、读(dú)數據(jù)和(hé)写數據(jù)等操作,由(yóu)于(yú)自(zì)刷新是(shì)必須進(jìn)行的(de),因(yīn)此(cǐ)自(zì)刷新請求的(de)优先(xiān)級是(shì)最(zuì)高(gāo)的(de),那(nà)麼(me)读(dú)請求和(hé)写請求的(de)优先(xiān)級怎麼(me)确定(dìng)呢?假設設置读(dú)請求的(de)优先(xiān)級高(gāo)于(yú)写請求,读(dú)請求和(hé)写請求一(yī)起来(lái)的(de)时(shí)候,總(zǒng)是(shì)先(xiān)執行读(dú)請求,如(rú)果(guǒ)读(dú)請求一(yī)直(zhí)有(yǒu)效的(de)話(huà),便不(bù)会(huì)執行写操作。反(fǎn)之設置写請求的(de)优先(xiān)級高(gāo)于(yú)读(dú)請求,也(yě)会(huì)出(chū)現(xiàn)这(zhè)樣(yàng)的(de)問(wèn)題(tí),这(zhè)當然是(shì)不(bù)可(kě)以(yǐ)的(de)。因(yīn)此(cǐ)我(wǒ)们(men)設置为(wèi)如(rú)果(guǒ)两(liǎng)个(gè)請求不(bù)是(shì)同(tóng)时(shí)有(yǒu)效,則哪一(yī)个(gè)有(yǒu)效便執行哪一(yī)个(gè)。如(rú)果(guǒ)同(tóng)时(shí)来(lái)的(de)时(shí)候,第(dì)一(yī)次(cì)同(tóng)时(shí)来(lái),先(xiān)執行写操作,第(dì)二(èr)次(cì)同(tóng)时(shí)有(yǒu)效的(de)时(shí)候在(zài)執行写操作,如(rú)此(cǐ)交替進(jìn)行即可(kě)。通(tòng)过(guò)两(liǎng)个(gè)信(xìn)号(hào)進(jìn)行控制:

读(dú)操作指示信(xìn)号(hào)flag_rd:初始狀态为(wèi)低電(diàn)平,表(biǎo)示上(shàng)一(yī)次(cì)執行的(de)写操作;從低變(biàn)高(gāo)的(de)条(tiáo)件(jiàn)为(wèi)state_c==RED,表(biǎo)示如(rú)果(guǒ)執行的(de)是(shì)读(dú)操作,則置为(wèi)高(gāo)電(diàn)平;當執行的(de)是(shì)写操作的(de)时(shí)候,該信(xìn)号(hào)置为(wèi)0,所(suǒ)以(yǐ)變(biàn)0的(de)条(tiáo)件(jiàn)是(shì)state_c==WIR

读(dú)写同(tóng)步指示信(xìn)号(hào)flag_syn:初始狀态为(wèi)0,表(biǎo)示读(dú)写請求沒(méi)有(yǒu)同(tóng)时(shí)有(yǒu)效,如(rú)果(guǒ)當前(qián)处于(yú)激活狀态,并且读(dú)写請求同(tóng)时(shí)有(yǒu)效,則置为(wèi)1,當激活狀态結束(shù),重(zhòng)新變(biàn)为(wèi)0

設計(jì)中(zhōng)的(de)輔助信(xìn)号(hào)已經(jīng)完成(chéng)的(de)差不(bù)多(duō)了(le),下(xià)面(miàn)開(kāi)始進(jìn)行狀态機(jī)的(de)架構,架構图(tú)如(rú)下(xià)图(tú)所(suǒ)示:



下(xià)面(miàn)介紹一(yī)个(gè)各(gè)个(gè)狀态之間(jiān)的(de)跳轉(zhuǎn)条(tiáo)件(jiàn)。

上(shàng)電(diàn)之後(hòu),先(xiān)進(jìn)入(rù)空操作狀态,在(zài)空操作狀态下(xià):

1、  延时(shí)100us之後(hòu),進(jìn)入(rù)到(dào)預充電(diàn)狀态。

當处于(yú)預充電(diàn)狀态的(de)时(shí)候:

1、  如(rú)果(guǒ)处于(yú)初始化(huà)階(jiē)段(duàn),两(liǎng)个(gè)时(shí)鐘(zhōng)周期(qī)之後(hòu),跳轉(zhuǎn)到(dào)自(zì)刷新狀态。
2、  如(rú)果(guǒ)不(bù)是(shì)初始化(huà)階(jiē)段(duàn),两(liǎng)个(gè)时(shí)鐘(zhōng)周期(qī)之後(hòu),跳轉(zhuǎn)到(dào)空閑狀态。

當处于(yú)自(zì)刷新狀态时(shí):

1、  如(rú)果(guǒ)处于(yú)初始化(huà)狀态,7个(gè)时(shí)鐘(zhōng)周期(qī)之後(hòu),跳轉(zhuǎn)到(dào)自(zì)刷新狀态。
2、  如(rú)果(guǒ)处于(yú)初始化(huà)狀态,并且已經(jīng)進(jìn)行过(guò)一(yī)次(cì)初始化(huà),7个(gè)时(shí)鐘(zhōng)周期(qī)之後(hòu),跳轉(zhuǎn)到(dào)加载模式寄存器狀态。
3、  如(rú)果(guǒ)不(bù)是(shì)初始化(huà)階(jiē)段(duàn),7个(gè)时(shí)鐘(zhōng)周期(qī)之後(hòu),跳轉(zhuǎn)到(dào)空閑狀态。

當处于(yú)加载模式寄存器狀态时(shí):

1、  2个(gè)时(shí)鐘(zhōng)周期(qī)之後(hòu),進(jìn)入(rù)到(dào)空閑狀态。
當处于(yú)空閑狀态时(shí):

1、  如(rú)果(guǒ)收(shōu)到(dào)自(zì)刷新請求,則跳轉(zhuǎn)到(dào)自(zì)刷新狀态。
2、  如(rú)果(guǒ)自(zì)刷新請求无效,收(shōu)到(dào)读(dú)/写請求,則跳轉(zhuǎn)到(dào)激活狀态。

當处于(yú)处于(yú)激活狀态时(shí):

1、  當读(dú)写請求不(bù)同(tóng)时(shí)的(de)时(shí)候,接收(shōu)到(dào)读(dú)請求,則跳轉(zhuǎn)到(dào)读(dú)狀态。
2、  當读(dú)写請求不(bù)同(tóng)时(shí)的(de)时(shí)候,接收(shōu)到(dào)写請求,則跳轉(zhuǎn)到(dào)写狀态
3、  當读(dú)写請求同(tóng)时(shí)到(dào)达(dá)的(de)时(shí)候,第(dì)一(yī)次(cì)来(lái)的(de)时(shí)候,首先(xiān)響應(yìng)读(dú)請求,跳轉(zhuǎn)到(dào)读(dú)狀态
4、  當读(dú)写請求同(tóng)时(shí)到(dào)达(dá),但不(bù)是(shì)第(dì)一(yī)次(cì)同(tóng)时(shí)有(yǒu)效的(de)时(shí)候,則根(gēn)據(jù)上(shàng)一(yī)次(cì)執行的(de)操作進(jìn)行判斷,如(rú)果(guǒ)上(shàng)一(yī)次(cì)執行的(de)读(dú)操作,則这(zhè)次(cì)執行写操作,跳轉(zhuǎn)到(dào)写狀态;如(rú)果(guǒ)上(shàng)一(yī)次(cì)執行的(de)写操作,則这(zhè)次(cì)執行读(dú)操作,跳轉(zhuǎn)到(dào)读(dú)狀态。
當处于(yú)写狀态的(de)时(shí)候:

1、  写數據(jù)完成(chéng),就(jiù)進(jìn)入(rù)到(dào)預充電(diàn)狀态。

當处于(yú)读(dú)狀态的(de)时(shí)候:

1、  读(dú)數據(jù)完成(chéng),就(jiù)進(jìn)入(rù)到(dào)預充電(diàn)狀态。

指令集信(xìn)号(hào)conmand:該信(xìn)号(hào)共(gòng)4bit,從最(zuì)高(gāo)位到(dào)最(zuì)低位分(fēn)别表(biǎo)示csrascaswe。在(zài)空操作階(jiē)段(duàn),指令为(wèi)4’b0111;在(zài)預充電(diàn)階(jiē)段(duàn),指令为(wèi)4’b0010;在(zài)自(zì)刷新階(jiē)段(duàn),指令为(wèi)4’b0001;在(zài)加载模式寄存器階(jiē)段(duàn),指令为(wèi)4’b0000;在(zài)激活階(jiē)段(duàn),指令为(wèi)4’b0011;在(zài)读(dú)數據(jù)階(jiē)段(duàn),指令为(wèi)4’b0101;在(zài)写數據(jù)階(jiē)段(duàn),指令为(wèi)4’b0100。这(zhè)些操作对(duì)應(yìng)的(de)指令碼都是(shì)從图(tú)中(zhōng)的(de)表(biǎo)格中(zhōng)查找(zhǎo)得来(lái)。



數據(jù)掩碼dqm:初始狀态为(wèi)2’b11,表(biǎo)示輸入(rù)得两(liǎng)个(gè)字(zì)节(jié)數據(jù)无效。當初始化(huà)完成(chéng)之後(hòu),變(biàn)为(wèi)2’b00,表(biǎo)示輸入(rù)得两(liǎng)个(gè)字(zì)节(jié)數據(jù)有(yǒu)效。

时(shí)鐘(zhōng)使能(néng)cke:複位时(shí)为(wèi)0,表(biǎo)示輸入(rù)时(shí)鐘(zhōng)无效,複位結束(shù)之後(hòu)为(wèi)1,表(biǎo)示輸入(rù)时(shí)鐘(zhōng)有(yǒu)效。

Bank選擇信(xìn)号(hào)sd_bank:初始狀态为(wèi)2’b00,表(biǎo)示選擇Bank0;在(zài)激活階(jiē)段(duàn)、读(dú)階(jiē)段(duàn)和(hé)写階(jiē)段(duàn),該信(xìn)号(hào)由(yóu)輸入(rù)得bank信(xìn)号(hào)決定(dìng)。

SDRAM地(dì)址選擇信(xìn)号(hào)sd_addr:由(yóu)于(yú)本(běn)工程采用(yòng)的(de)預充電(diàn)模式为(wèi)全(quán)Bnak自(zì)動(dòng)預充電(diàn),該模式由(yóu)地(dì)址線(xiàn)A10控制,因(yīn)此(cǐ)在(zài)預充電(diàn)得时(shí)候,地(dì)址指令为(wèi)13’b001_0_00_000_0_000;在(zài)激活的(de)时(shí)候提(tí)供行地(dì)址;在(zài)加载模式寄存器得时(shí)候,地(dì)址線(xiàn)提(tí)供運算碼,这(zhè)时(shí)每个(gè)地(dì)址表(biǎo)示得意(yì)思(sī)入(rù)下(xià)图(tú)所(suǒ)示,A9決定(dìng)读(dú)模式,A6、A5、A4決定(dìng)读(dú)數據(jù)得潛伏期(qī),A3決定(dìng)突發(fà)類(lèi)型,A2、A1、A0決定(dìng)突發(fà)长度(dù)。



由(yóu)于(yú)MP801開(kāi)發(fà)板使用(yòng)得SDRAM有(yǒu)两(liǎng)種(zhǒng)型号(hào),一(yī)種(zhǒng)是(shì)W9812G6KH,共(gòng)4096行,自(zì)刷新周期(qī)为(wèi)1562,另(lìng)一(yī)種(zhǒng)是(shì)H57V2562GTR,共(gòng)8192行,自(zì)刷新周期(qī)为(wèi)780。在(zài)使用(yòng)得时(shí)候需要(yào)注意(yì)開(kāi)發(fà)板型号(hào),这(zhè)里(lǐ)我(wǒ)们(men)以(yǐ)H57V2562GTR为(wèi)例。自(zì)刷新需要(yào)以(yǐ)下(xià)信(xìn)号(hào):

时(shí)鐘(zhōng)計(jì)數器cnt_780:該計(jì)數器主(zhǔ)要(yào)得作用(yòng)是(shì)初始化(huà)結束(shù)之後(hòu),數自(zì)刷新得周期(qī);加一(yī)条(tiáo)件(jiàn)为(wèi)init_flag==0,表(biǎo)示初始化(huà)結束(shù)就(jiù)開(kāi)始計(jì)數;結束(shù)条(tiáo)件(jiàn)为(wèi)數780个(gè),數完就(jiù)清(qīng)零(líng)。

自(zì)刷新請求ref_req:初始狀态为(wèi)0,表(biǎo)示不(bù)需要(yào)進(jìn)行自(zì)刷新,當时(shí)鐘(zhōng)計(jì)數器cnt_780數完得时(shí)候,ref_req拉高(gāo),請求進(jìn)行自(zì)刷新,如(rú)果(guǒ)當前(qián)处于(yú)空閑狀态,則進(jìn)行自(zì)刷新,如(rú)果(guǒ)不(bù)是(shì),則等待。

可(kě)能(néng)有(yǒu)人(rén)会(huì)想(xiǎng),如(rú)果(guǒ)不(bù)是(shì)空閑狀态,就(jiù)要(yào)等待,这(zhè)樣(yàng)会(huì)不(bù)会(huì)对(duì)數據(jù)保存造成(chéng)影響?其实不(bù)会(huì)得,存儲器要(yào)求64ms全(quán)部(bù)刷新一(yī)遍(biàn),但不(bù)需要(yào)每一(yī)行刷新得間(jiān)隔都一(yī)樣(yàng)。當时(shí)鐘(zhōng)計(jì)數器cnt_780數完之後(hòu),産生(shēng)自(zì)刷新請求,同(tóng)时(shí)时(shí)鐘(zhōng)計(jì)數器又会(huì)開(kāi)始計(jì)數,所(suǒ)以(yǐ)可(kě)能(néng)自(zì)刷新得間(jiān)隔不(bù)同(tóng),但每一(yī)行肯定(dìng)能(néng)在(zài)64ms內(nèi)刷新1次(cì)。
写SDRAM數據(jù)信(xìn)号(hào)dq_out:該信(xìn)号(hào)直(zhí)接等于(yú)写數據(jù)wdata(注意(yì),需要(yào)用(yòng)組合邏輯实現(xiàn))。

三(sān)态門(mén)使能(néng)信(xìn)号(hào)dq_out_en:初始狀态为(wèi)0,表(biǎo)示使能(néng)无效,在(zài)写數據(jù)期(qī)間(jiān),變(biàn)为(wèi)高(gāo)電(diàn)平,表(biǎo)示使能(néng)有(yǒu)效。

读(dú)SDRAM數據(jù)信(xìn)号(hào)rdata:直(zhí)接将sdram輸出(chū)數據(jù)dq_in連(lián)接即可(kě)。

读(dú)數據(jù)有(yǒu)效指示信(xìn)号(hào)rdata_vld:由(yóu)于(yú)存在(zài)读(dú)數據(jù)潛伏期(qī),根(gēn)據(jù)設置得潛伏期(qī)得长度(dù),将rdata_vld進(jìn)行相應(yìng)得延时(shí)。

1.5.4參考代(dài)碼
  1.     parameter NOP       = 4'b0000 ;
  2.     parameter PER       = 4'b0001 ;
  3.     parameter REF       = 4'b0010 ;
  4.     parameter MOD       = 4'b0100 ;
  5.     parameter IDL       = 4'b1000 ;
  6.     parameter ACT       = 4'b0011 ;
  7.     parameter RED       = 4'b0110 ;
  8.     parameter WIR       = 4'b1100 ;
  9.    
  10.     parameter NOP_CMD   = 4'b0111 ;
  11.     parameter PER_CMD   = 4'b0010 ;
  12.     parameter REF_CMD   = 4'b0001 ;
  13.     parameter MOD_CMD   = 4'b0000 ;
  14.     parameter ACT_CMD   = 4'b0011 ;
  15.     parameter RED_CMD   = 4'b0101 ;
  16.     parameter WIR_CMD   = 4'b0100 ;
  17.    
  18.     parameter ALL_BANK  = 13'b001_0_00_000_0_000;
  19.     parameter CODE      = 13'b000_0_00_010_0_111;
  20.    
  21.     parameter TIME_780  = 780     ;      
  22.     parameter TIME_WAIT = 10000   ;   
  23.     parameter TIME_TRP  = 2       ;
  24.     parameter TIME_TRC  = 7       ;
  25.     parameter TIME_TMRD = 2       ;
  26.     parameter TIME_TRCD = 2       ;
  27.     parameter TIME_512  = 512     ;

  28.     input            clk          ;
  29.     input            rst_n        ;
  30.     input            wr_req       ;
  31.     input            rd_req       ;
  32.     input  [1 :0]    bank         ;
  33.     input  [12:0]    addr         ;
  34.     input  [15:0]    wdata        ;
  35.     input  [15:0]    dq_in        ;


  36.     output [15:0]    dq_out       ;
  37.     output           dq_out_en    ;
  38.     output           wr_ack       ;
  39.     output           rd_ack       ;
  40.     output [15:0]    rdata        ;
  41.     output           rdata_vld    ;
  42.     output           cke          ;
  43.     output           cs           ;
  44.     output           ras          ;
  45.     output           cas          ;
  46.     output           we           ;
  47.     output [1 :0]    dqm          ;
  48.     output [12:0]    sd_addr      ;
  49.     output [1 :0]    sd_bank      ;
  50.     output           sd_clk       ;

  51.     reg    [15:0]    dq_out       ;
  52.     reg              dq_out_en    ;
  53.     reg              flag_syn     ;
  54.     wire             wr_ack       ;
  55.     wire             rd_ack       ;
  56.     reg    [15:0]    rdata        ;
  57.     reg              rdata_vld    ;
  58.     reg              cke          ;
  59.     wire             cs           ;
  60.     wire             ras          ;
  61.     wire             cas          ;
  62.     wire             we           ;
  63.     reg    [1 :0]    dqm          ;
  64.     reg    [12:0]    sd_addr      ;
  65.     reg    [1 :0]    sd_bank      ;
  66.     wire             sd_clk       ;


  67.     reg    [3:0]     state_c      ;
  68.     reg    [3:0]     state_n      ;
  69.     wire             nop2per_start;
  70.     wire             per2ref_start;
  71.     wire             per2idl_start;
  72.     wire             ref2ref_start;
  73.     wire             ref2mod_start;
  74.     wire             ref2idl_start;
  75.     wire             mod2idl_start;
  76.     wire             idl2ref_start;
  77.     wire             idl2act_start;
  78.     wire             act2red_start;
  79.     wire             act2wir_start;
  80.     wire             red2per_start;
  81.     wire             wir2per_start;
  82.     reg    [3:0]     conmand      ;
  83.     reg    [13:0]    cnt          ;
  84.     wire             add_cnt      ;
  85.     wire             end_cnt      ;
  86.     reg    [1:0]     cnt1         ;
  87.     wire             add_cnt1     ;
  88.     wire             end_cnt1     ;
  89.     reg    [9:0]     cnt_780      ;
  90.     wire             add_cnt_780  ;
  91.     wire             end_cnt_780  ;
  92.     reg    [13:0]    x            ;
  93.     reg              init_flag    ;
  94.     reg              ref_req      ;
  95.     wire             ref_ack      ;
  96.     reg              flag_rd      ;
  97.     wire             rd_en        ;
  98.     reg              rdata_vld_ff0;
  99.     reg              rdata_vld_ff1;
  100.     reg              rdata_vld_ff2;


  101. always  @(posedge clk or negedge rst_n)begin
  102.     if(rst_n==1'b0)begin
  103.         state_c <= NOP;
  104.     end
  105.     else begin
  106.         state_c <= state_n;
  107.     end
  108. end

  109. always @(*)begin
  110.     case(state_c)
  111.         NOP:begin
  112.             if(nop2per_start)begin
  113.                 state_n = PER;
  114.             end
  115.             else begin
  116.                 state_n = state_c;
  117.             end
  118.         end
  119.         PER:begin
  120.             if(per2ref_start)begin
  121.                 state_n = REF;
  122.             end
  123.             else if(per2idl_start)begin
  124.                 state_n = IDL;
  125.             end
  126.             else begin
  127.                 state_n = state_c;
  128.             end
  129.         end
  130.         REF:begin
  131.             if(ref2ref_start)begin
  132.                 state_n = REF;
  133.             end
  134.             else if(ref2mod_start)begin
  135.                 state_n = MOD;
  136.             end
  137.             else if(ref2idl_start)begin
  138.                 state_n = IDL;
  139.             end
  140.             else begin
  141.                 state_n = state_c;
  142.             end
  143.         end
  144.         MOD:begin
  145.             if(mod2idl_start)begin
  146.                 state_n = IDL;
  147.             end
  148.             else begin
  149.                 state_n = state_c;
  150.             end
  151.         end
  152.         IDL:begin
  153.             if(idl2ref_start)begin
  154.                 state_n = REF;
  155.             end
  156.             else if(idl2act_start)begin
  157.                 state_n = ACT;
  158.             end
  159.             else begin
  160.                 state_n = state_c;
  161.             end
  162.         end
  163.         ACT:begin
  164.             if(act2red_start)begin
  165.                 state_n = RED;
  166.             end
  167.             else if(act2wir_start)begin
  168.                 state_n = WIR;
  169.             end
  170.             else begin
  171.                 state_n = state_c;
  172.             end
  173.         end
  174.         RED:begin
  175.             if(red2per_start)begin
  176.                 state_n = PER;
  177.             end
  178.             else begin
  179.                 state_n = state_c;
  180.             end
  181.         end
  182.         WIR:begin
  183.             if(wir2per_start)begin
  184.                 state_n = PER;
  185.             end
  186.             else begin
  187.                 state_n = state_c;
  188.             end
  189.         end
  190.         default:begin
  191.             state_n = IDL;
  192.         end
  193.     endcase
  194. end


  195. assign nop2per_start = state_c==NOP && end_cnt;
  196. assign per2ref_start = state_c==PER && init_flag==1 && end_cnt;
  197. assign per2idl_start = state_c==PER && init_flag==0 && end_cnt;
  198. assign ref2ref_start = state_c==REF && init_flag==1 && cnt1==0 && end_cnt;
  199. assign ref2mod_start = state_c==REF && init_flag==1 && end_cnt1;
  200. assign ref2idl_start = state_c==REF && init_flag==0 && end_cnt;
  201. assign mod2idl_start = state_c==MOD && end_cnt;
  202. assign idl2ref_start = state_c==IDL && ref_req;
  203. assign idl2act_start = state_c==IDL && ref_req==0 && (wr_req || rd_req);
  204. assign act2red_start = state_c==ACT && ((flag_syn==1 && flag_rd==0) || (flag_syn==0 && rd_req)) && end_cnt;
  205. assign act2wir_start = state_c==ACT && ((flag_syn==1 && flag_rd==1) || (flag_syn==0 && wr_req)) && end_cnt;
  206. assign red2per_start = state_c==RED && end_cnt;
  207. assign wir2per_start = state_c==WIR && end_cnt;

  208. always @(posedge clk or negedge rst_n)begin
  209.     if(!rst_n)begin
  210.         cnt <= 0;
  211.     end  
  212.     else if(add_cnt)begin
  213.         if(end_cnt)
  214.             cnt <= 0;
  215.         else
  216.             cnt <= cnt + 1;
  217.     end
  218. end

  219. assign add_cnt = state_c!=IDL;      
  220. assign end_cnt = add_cnt && cnt== x-1;   


  221. always  @(posedge clk or negedge rst_n)begin
  222.     if(rst_n==1'b0)begin
  223.         init_flag <= 1;
  224.     end
  225.     else if(mod2idl_start)begin
  226.         init_flag <= 0;
  227.     end
  228. end


  229. always @(posedge clk or negedge rst_n) begin
  230.     if (rst_n==0) begin
  231.         cnt1 <= 0;
  232.     end
  233.     else if(add_cnt1) begin
  234.         if(end_cnt1)
  235.             cnt1 <= 0;
  236.         else
  237.             cnt1 <= cnt1+1 ;
  238.    end
  239. end
  240. assign add_cnt1 = init_flag && state_c==REF && end_cnt;
  241. assign end_cnt1 = add_cnt1  && cnt1 == 2-1 ;


  242. always  @(posedge clk or negedge rst_n)begin
  243.     if(rst_n==1'b0)begin
  244.         flag_rd <= 0;
  245.     end
  246.     else if(state_c==RED)begin
  247.         flag_rd <= 1;
  248.     end
  249.     else if(state_c==WIR)begin
  250.         flag_rd <= 0;
  251.     end
  252. end


  253. always  @(posedge clk or negedge rst_n)begin
  254.     if(rst_n==1'b0)begin
  255.         flag_syn <= 0;
  256.     end
  257.     else if(state_c==ACT && wr_req && rd_req)begin
  258.         flag_syn <= 1;
  259.     end
  260.     else if(end_cnt)begin
  261.         flag_syn <= 0;
  262.     end
  263. end

  264. assign rd_ack = act2red_start;
  265. assign wr_ack = act2wir_start;

  266. always  @(posedge clk or negedge rst_n)begin
  267.     if(rst_n==1'b0)begin
  268.         conmand <= NOP_CMD;
  269.     end
  270.     else if(nop2per_start || red2per_start || wir2per_start)begin
  271.         conmand <= PER_CMD;
  272.     end
  273.     else if(per2ref_start || ref2ref_start || idl2ref_start)begin
  274.         conmand <= REF_CMD;
  275.     end
  276.     else if(ref2mod_start)begin
  277.         conmand <= MOD_CMD;
  278.     end
  279.     else if(idl2act_start)begin
  280.         conmand <= ACT_CMD;
  281.     end
  282.     else if(act2red_start)begin
  283.         conmand <= RED_CMD;
  284.     end
  285.     else if(act2wir_start)begin
  286.         conmand <= WIR_CMD;
  287.     end
  288.     else begin
  289.         conmand <= NOP_CMD;
  290.     end
  291. end

  292. assign {cs,ras,cas,we} = conmand;
  293. assign sd_clk = ~clk;

  294. always  @(posedge clk or negedge rst_n)begin
  295.     if(rst_n==1'b0)begin
  296.         dqm <= 2'b11;
  297.     end
  298.     else if(mod2idl_start)begin
  299.         dqm <= 2'b00;
  300.     end
  301. end


  302. always  @(posedge clk or negedge rst_n)begin
  303.     if(rst_n==1'b0)begin
  304.         cke <= 0;
  305.     end
  306.     else begin
  307.         cke <= 1;
  308.     end
  309. end


  310. always  @(posedge clk or negedge rst_n)begin
  311.     if(rst_n==1'b0)begin
  312.         sd_addr <= 13'b0;
  313.     end
  314.     else if(nop2per_start || red2per_start || wir2per_start)begin
  315.         sd_addr <= ALL_BANK;
  316.     end
  317.     else if(ref2mod_start)begin
  318.         sd_addr <= CODE;
  319.     end
  320.     else if(idl2act_start)begin
  321.         sd_addr <= addr;
  322.     end
  323.     else begin
  324.         sd_addr <= 13'b0;
  325.     end
  326. end


  327. always  @(posedge clk or negedge rst_n)begin
  328.     if(rst_n==1'b0)begin
  329.         sd_bank <= 2'b00;
  330.     end
  331.     else if(idl2act_start || act2wir_start || act2red_start)begin
  332.         sd_bank <= bank;
  333.     end
  334.     else begin
  335.         sd_bank <= 0;
  336.     end
  337. end


  338. always  @(*)begin
  339.     if(state_c==NOP)begin
  340.         x = TIME_WAIT;
  341.     end
  342.     else if(state_c==PER)begin
  343.         x = TIME_TRP;
  344.     end
  345.     else if(state_c==REF)begin
  346.         x = TIME_TRC;
  347.     end
  348.     else if(state_c==MOD)begin
  349.         x = TIME_TMRD;
  350.     end
  351.     else if(state_c==ACT)begin
  352.         x = TIME_TRCD;
  353.     end
  354.     else begin
  355.         x = TIME_512;
  356.     end
  357. end


  358. always @(posedge clk or negedge rst_n) begin
  359.     if (rst_n==0) begin
  360.         cnt_780 <= 0;
  361.     end
  362.     else if(add_cnt_780) begin
  363.         if(end_cnt_780)
  364.             cnt_780 <= 0;
  365.         else
  366.             cnt_780 <= cnt_780+1 ;
  367.    end
  368. end
  369. assign add_cnt_780 = init_flag==0;
  370. assign end_cnt_780 = add_cnt_780  && cnt_780 == TIME_780-1 ;


  371. always  @(posedge clk or negedge rst_n)begin
  372.     if(rst_n==1'b0)begin
  373.         ref_req <= 0;
  374.     end
  375.     else if(end_cnt_780)begin
  376.         ref_req <= 1;
  377.     end
  378.     else if(ref_ack)begin
  379.         ref_req <= 0;
  380.     end
  381. end


  382. assign ref_ack = state_c==IDL && ref_req;
  383. assign wr_ack  = act2wir_start;
  384. assign rd_ack  = act2red_start;


  385. always  @(*)begin
  386.         dq_out <= wdata;
  387. end


  388. always  @(posedge clk or negedge rst_n)begin
  389.     if(rst_n==1'b0)begin
  390.         dq_out_en <= 1'b0;
  391.     end
  392.     else if(act2wir_start)begin
  393.         dq_out_en <= 1'b1;
  394.     end
  395.     else if(end_cnt)begin
  396.         dq_out_en <= 1'b0;
  397.     end
  398. end


  399. always  @(posedge clk or negedge rst_n)begin
  400.     if(rst_n==1'b0)begin
  401.         rdata <= 16'b0;
  402.     end
  403.     else begin
  404.         rdata <= dq_in;
  405.     end
  406. end


  407. always  @(posedge clk or negedge rst_n)begin
  408.     if(rst_n==1'b0)begin
  409.         rdata_vld_ff0 <= 0;
  410.     end
  411.     else if(act2red_start)begin
  412.         rdata_vld_ff0 <= 1;
  413.     end
  414.     else if(end_cnt)begin
  415.         rdata_vld_ff0 <= 0;
  416.     end
  417. end


  418. always  @(posedge clk or negedge rst_n)begin
  419.     if(rst_n==1'b0)begin
  420.         rdata_vld     <= 0;
  421.         rdata_vld_ff1 <= 0;
  422.         rdata_vld_ff2 <= 0;
  423.     end
  424.     else begin
  425.         rdata_vld_ff1 <= rdata_vld_ff0;
  426.         rdata_vld_ff2 <= rdata_vld_ff1;
  427.         rdata_vld     <= rdata_vld_ff2;
  428.     end
  429. end


  430. endmodule
複制代(dài)碼


1.6 效果(guǒ)和(hé)總(zǒng)結
該工程得上(shàng)板效果(guǒ)使用(yòng)signaltap進(jìn)行捕捉来(lái)观测的(de),因(yīn)此(cǐ)不(bù)同(tóng)開(kāi)發(fà)板的(de)上(shàng)板效果(guǒ)是(shì)一(yī)樣(yàng),那(nà)麼(me)下(xià)面(miàn)就(jiù)只(zhī)介紹mp801的(de)上(shàng)板現(xiàn)象(xiàng)。
下(xià)图(tú)是(shì)写數據(jù)的(de)情(qíng)況,Bank地(dì)址为(wèi)0。写入(rù)SDRAM的(de)數據(jù)为(wèi)0~255


下(xià)图(tú)是(shì)读(dú)數據(jù)的(de)情(qíng)況,Bank地(dì)址为(wèi)0,潛伏期(qī)为(wèi)2,读(dú)出(chū)的(de)數據(jù)为(wèi)0~255


下(xià)图(tú)是(shì)读(dú)數據(jù)的(de)情(qíng)況,Bank地(dì)址为(wèi)1,潛伏期(qī)为(wèi)2,读(dú)出(chū)的(de)數據(jù)不(bù)是(shì)0~255,这(zhè)是(shì)因(yīn)为(wèi)我(wǒ)们(men)写數據(jù)的(de)地(dì)址是(shì)Bank0,而(ér)不(bù)是(shì)Bank1Bank1中(zhōng)是(shì)沒(méi)有(yǒu)數據(jù),所(suǒ)以(yǐ)读(dú)出(chū)的(de)數據(jù)就(jiù)不(bù)是(shì)确定(dìng)的(de)。



設計(jì)教学視頻和(hé)源工程代(dài)碼可(kě)以(yǐ)訪問(wèn)明(míng)德揚論壇(http://www.fpgabbs.cn/)進(jìn)行相關(guān)工程設計(jì)学習:http://www.fpgabbs.cn/thread-1151-1-1.html

上(shàng)一(yī)篇(piān):【案(àn)例】LCD顯示图(tú)片(piàn)
   拓展(zhǎn)閱读(dú)
⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ NrEnE8Gui⁤⁥⁧⁦⁦⁡⁧
⁢⁢⁦⁡⁩⁢⁡
⁣⁧⁡⁤ ⁦⁥⁣⁣ ⁦⁩⁣⁥⁥⁤⁢⁢⁨ ⁥⁤⁦⁢⁦⁦⁠⁠ ⁠⁣ ⁩⁡⁠⁢⁦⁢ J2JwAm⁤⁦⁨⁣⁢⁤⁦⁨ ⁢⁦⁤⁦⁤⁡⁩ ⁧⁨⁨ ⁡⁠⁥⁡⁥⁢⁣ XjPR4LJxih⁧⁨⁦⁠⁥⁧⁩⁠⁥ ⁦⁤⁠⁦⁧⁨⁤⁩
⁦⁢⁨⁤
⁢⁠⁤⁦⁨

⁩⁩⁡

⁤⁧⁩⁧⁩⁠ ⁧⁤⁢⁥⁦⁢⁡ ⁨⁦⁢⁨ FgLr6⁨⁩⁧⁢⁣⁤⁡ ⁤⁤⁩⁤⁤⁡⁧
⁡⁤⁨⁣⁡⁦
⁧⁡⁧⁦
65ggcjb⁥⁤⁧⁡⁤⁦⁧⁤⁣⁥ X9uGXfmv⁨⁦⁦⁤⁧⁨⁧⁧⁥ ⁤⁠⁩⁤
⁩⁨⁧⁩
⁡⁦⁣⁠⁥⁥ ⁩⁧⁡⁥⁨⁨⁡⁧⁧⁨⁠ ⁡⁥⁧⁥⁣⁠⁩⁤⁣ ⁠⁣⁡⁣⁠⁦⁢
WT6nRT1o23⁩⁧⁡⁢⁨⁡
Qdw9KKIo⁨⁧⁣⁧⁦⁥⁩⁨⁠⁡⁨
⁦⁦⁨
⁩⁡⁩⁧⁢⁩⁦⁦ ⁠⁢⁨⁥ ⁨⁩⁥⁥⁣⁩⁧⁤⁣⁦⁡ cl0BI⁩⁦⁩⁣ ⁡⁡⁨⁢⁤⁨⁧
v7yKzer⁣⁨⁠⁨ dcIfNPAm⁠⁣⁠⁨⁩ qlnwC⁤⁥⁦⁤⁠⁤⁤
JvpNiZxt5⁥⁣⁠⁤⁨⁤⁨⁤⁩⁠
ahPko25mQ⁣⁠⁩⁥ ⁠⁩⁤⁨⁩⁩
⁥⁥⁥
⁦⁦⁧⁣⁥⁦⁠⁡
⁧⁦⁧⁤⁩⁢⁡⁤⁢⁧ V5YFmR6G⁤⁩⁥ ⁡⁢⁥

⁧⁨⁡⁩⁣⁡⁥

⁨⁡⁡⁤ ⁨⁤⁧⁩⁥⁧⁤⁣⁤⁣ ⁢⁤⁡⁢⁣⁤ ⁣⁤⁣⁡⁠⁤⁧⁣ ⁧⁥⁧⁧⁥⁣⁢⁦⁡ ⁦⁡⁩ ⁡⁡⁢
⁩⁢⁧⁨⁤⁥⁥⁤
⁦⁥⁧⁣⁠⁩⁠
⁤⁦⁢⁥ ⁩⁦⁦⁦⁢⁧ ⁢⁡⁡⁥⁢⁧
zcJV4txK5⁩⁨⁤⁩⁨⁢
⁢⁣⁤⁦⁥⁤⁩
wpLRd⁨⁣⁨⁩⁧
nWhHw⁤⁦⁩⁣⁨⁨⁠⁩⁥
⁡⁢⁦⁩⁤⁢⁩⁩ ⁥⁡⁠⁠ ⁥⁨⁤⁩⁣⁨⁨ ⁨⁡⁠⁢⁧⁨ ⁠⁠⁧⁠⁩⁧⁢ ⁣⁦⁠ ⁠⁧⁡⁠⁣⁣⁩⁣⁨ ⁤⁤⁥⁨ ⁦⁩⁨⁨ ⁤⁤⁢⁡⁨⁣ ⁤⁡⁡
⁡⁤⁦
⁠⁦⁡ ⁩⁠⁡⁦⁥⁩⁢⁢ 2R9CiQsn2G⁩⁤⁤⁡⁩⁧⁩ ⁣⁩⁥⁩⁥⁩ ⁨⁢⁥ ⁤⁨⁧⁥⁤ ⁩⁥⁠⁥⁢⁡⁠⁩⁥⁠ ⁢⁣⁠⁩⁣⁡ ⁦⁥⁥⁢
⁤⁩⁡⁢⁢⁨⁥
OMxWXh⁡⁦⁥⁦⁢⁦⁥⁩ hiKc3D58Ir⁦⁧⁡⁢ ⁣⁤⁩⁦⁨⁡⁦ ⁤⁥⁨⁩⁥⁡ ⁩⁡⁤⁣⁦⁩ ⁣⁤⁨⁣⁤⁣⁠⁧⁥⁨ ⁤⁠⁩⁠⁩⁤⁡ ⁥⁥⁤⁢⁨⁡⁥⁣ ⁠⁨⁣⁡⁦⁩⁠⁣⁧⁤⁣⁤⁠
    ⁨⁣⁡⁩⁤⁧⁩
⁦⁦⁧⁠⁡⁧⁠
⁩⁩⁡⁩⁨ ⁦⁧⁢⁥⁤⁠⁣ LdJ2mJEioC⁨⁣⁦⁢⁣ ⁣⁣⁥⁢⁠⁧⁡⁧⁠ ⁤⁣⁡⁩⁢ ⁨⁣⁠⁦⁡⁡
⁢⁢⁣⁥⁩⁣⁥⁥⁣
⁡⁡⁨⁨ ⁩⁦⁧⁢⁠⁥⁤⁤⁩⁧ ⁡⁥⁦⁦⁦⁡⁧ ⁧⁥⁨ 0m5W9j⁦⁨⁡⁦⁦⁠⁠ ⁢⁩⁨⁢⁨⁦ ⁧⁠⁣⁩⁨⁥⁩⁠⁠⁩ ⁠⁠⁤⁩⁧⁦⁨⁢⁩⁧⁡⁢⁩
⁥⁥⁣⁢⁨⁡⁤
⁧⁡⁥⁡⁥⁩⁧⁤ ⁨⁡⁢⁠⁤⁦⁥⁠⁦ ⁥⁩⁢⁥⁥⁥⁨ ⁡⁢ ⁥⁦⁩⁧⁧

⁡⁦⁣⁥⁤⁧⁡

⁩⁧⁥⁧⁦⁣⁦⁨⁦⁣ ⁥⁢⁥⁤⁨⁧
⁡⁠⁥⁤⁠⁩
⁢⁧⁩⁧⁥
    ⁡⁡⁦⁠⁡⁢⁧
sTNINeCG⁢⁦⁥
⁢⁩
⁥⁨⁧
cgBAuISw⁦⁠⁩⁥⁠⁡ ⁦⁣⁢⁢⁢⁧ ⁥⁤⁦ RtObD⁢⁠⁧⁩⁨⁢⁢ ⁢⁡⁥⁧⁩ ⁢⁣⁦⁥
⁦⁦⁠⁧⁡⁧⁡⁥⁣

⁢⁢⁣⁣⁥

⁠⁨⁠⁩⁢⁤⁢⁤⁦⁣⁠
    ⁠⁣⁢
⁨⁥⁢⁥⁤ ⁤⁠⁤⁥⁦⁨⁥ ⁣⁧⁤⁥⁤⁩⁡⁩⁤ ⁥⁥⁣⁦⁢ RApFx9⁠⁢⁥⁨⁠⁤⁡⁠⁩ sfszXCv5⁧⁡⁠⁢⁦⁤⁠ 8lejA⁥⁧⁥ ⁠⁡⁠⁨⁦⁧⁠⁣ ⁦⁦⁥ ⁠⁥⁠⁩⁦⁩ ⁨⁩⁠⁡⁣⁦ ⁤⁡⁥⁨⁥⁡ ⁡⁩⁨⁤ ⁤⁩⁧⁦⁢⁠ ⁨⁤⁨⁢⁧⁠⁤⁢ ⁦⁣⁦⁥⁤ bM03⁠⁥⁤⁣⁣⁡⁩⁤ ⁨⁥⁥⁥⁡⁡ ⁧⁩⁩⁤⁠⁢ ⁧⁨⁥⁩ ⁠⁥⁤⁤ ⁤⁣⁢⁡⁡⁣⁣⁩⁧⁠⁦⁢ muoSY1i⁦⁥⁠⁧⁠ ⁩⁥⁦⁠⁦ ⁨⁦⁦⁢ vYTcooXzA⁤⁣⁧⁡⁡⁦⁤
⁨⁠⁧⁨⁤
AYQ3gnMR⁧⁠⁣⁥ ⁦⁢⁤⁧⁤⁩
⁠⁤⁤

xDsToeNDG7⁥⁠⁢

⁧⁨⁥⁨