⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ 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⁥⁠⁢

⁧⁨⁥⁨

明(míng)德揚 · 为(wèi)國(guó)育芯才

至(zhì)簡設計(jì)法發(fà)明(míng)單位 | FPGA软(ruǎn)硬(yìng)件(jiàn)一(yī)站式服(fú)务商

【案(àn)例】斷電(diàn)重(zhòng)加载时(shí)鐘(zhōng)工程

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

案(àn)例編号(hào):00000066

1.1 總(zǒng)體(tǐ)設計(jì)


1.1.1 概述

在(zài)微機(jī)的(de)發(fà)展(zhǎn)初期(qī),BIOS都存放(fàng)在(zài)ROM(只(zhī)读(dú)存儲器)中(zhōng)。ROM內(nèi)部(bù)的(de)資料是(shì)在(zài)ROM的(de)制造工序中(zhōng),在(zài)工廠(chǎng)里(lǐ)用(yòng)特(tè)殊的(de)方(fāng)法燒录(lù)進(jìn)去(qù)的(de),其中(zhōng)的(de)內(nèi)容只(zhī)能(néng)读(dú)不(bù)能(néng)改,一(yī)旦燒录(lù)進(jìn)去(qù),用(yòng)戶只(zhī)能(néng)验(yàn)證写入(rù)的(de)資料是(shì)否正(zhèng)确,不(bù)能(néng)再做任何修改。如(rú)果(guǒ)發(fà)現(xiàn)資料有(yǒu)任何錯誤,則只(zhī)有(yǒu)舍棄不(bù)用(yòng),重(zhòng)新訂做一(yī)份。ROM是(shì)在(zài)生(shēng)産線(xiàn)上(shàng)生(shēng)産的(de),由(yóu)于(yú)成(chéng)本(běn)高(gāo),一(yī)般只(zhī)用(yòng)在(zài)大批量(liàng)應(yìng)用(yòng)的(de)场合。


由(yóu)于(yú)ROM制造和(hé)升(shēng)級的(de)不(bù)便,後(hòu)来(lái)人(rén)们(men)發(fà)明(míng)了(le)PROM(Programmable ROM,可(kě)編程ROM)。最(zuì)初從工廠(chǎng)中(zhōng)制作完成(chéng)的(de)PROM內(nèi)部(bù)并沒(méi)有(yǒu)資料,用(yòng)戶可(kě)以(yǐ)用(yòng)專用(yòng)的(de)編程器将自(zì)己的(de)資料写入(rù),但是(shì)这(zhè)種(zhǒng)機(jī)会(huì)只(zhī)有(yǒu)一(yī)次(cì),一(yī)旦写入(rù)後(hòu)也(yě)无法修改,若是(shì)出(chū)了(le)錯誤,已写入(rù)的(de)芯片(piàn)只(zhī)能(néng)報廢。PROM的(de)特(tè)性(xìng)和(hé)ROM相同(tóng),但是(shì)其成(chéng)本(běn)比ROM高(gāo),而(ér)且写入(rù)資料的(de)速度(dù)比ROM的(de)量(liàng)産速度(dù)要(yào)慢(màn),一(yī)般只(zhī)适用(yòng)于(yú)少(shǎo)量(liàng)需求的(de)场合或(huò)是(shì)ROM量(liàng)産前(qián)的(de)验(yàn)證。


EPROM(Erasable Programmable ROM,可(kě)擦除可(kě)編程ROM)芯片(piàn)可(kě)重(zhòng)複擦除和(hé)写入(rù),解(jiě)決了(le)PROM芯片(piàn)只(zhī)能(néng)写入(rù)一(yī)次(cì)的(de)弊端。EPROM芯片(piàn)有(yǒu)一(yī)个(gè)很明(míng)顯的(de)特(tè)征,在(zài)其正(zhèng)面(miàn)的(de)陶瓷封(fēng)裝(zhuāng)上(shàng),開(kāi)有(yǒu)一(yī)个(gè)玻璃窗(chuāng)口(kǒu),透过(guò)該窗(chuāng)口(kǒu),可(kě)以(yǐ)看(kàn)到(dào)其內(nèi)部(bù)的(de)集成(chéng)電(diàn)路(lù),紫外(wài)線(xiàn)透过(guò)該孔照射內(nèi)部(bù)芯片(piàn)就(jiù)可(kě)以(yǐ)擦除其內(nèi)的(de)數據(jù),完成(chéng)芯片(piàn)擦除的(de)操作要(yào)用(yòng)到(dào)EPROM擦除器。EPROM內(nèi)資料的(de)写入(rù)要(yào)用(yòng)專用(yòng)的(de)編程器,并且往芯片(piàn)中(zhōng)写內(nèi)容时(shí)必須要(yào)加一(yī)定(dìng)的(de)編程電(diàn)壓(VPP=12~24V,随不(bù)同(tóng)的(de)芯片(piàn)型号(hào)而(ér)定(dìng))。EPROM的(de)型号(hào)是(shì)以(yǐ)27開(kāi)头(tóu)的(de),如(rú)27C020(8*256K)是(shì)一(yī)片(piàn)2M Bits容量(liàng)的(de)EPROM芯片(piàn)。EPROM芯片(piàn)在(zài)写入(rù)資料後(hòu),還(huán)要(yào)以(yǐ)不(bù)透光(guāng)的(de)贴紙(zhǐ)或(huò)胶(jiāo)布(bù)把窗(chuāng)口(kǒu)封(fēng)住,以(yǐ)免受到(dào)周圍的(de)紫外(wài)線(xiàn)照射而(ér)使資料受損。


由(yóu)于(yú)EPROM操作的(de)不(bù)便,後(hòu)来(lái)出(chū)的(de)主(zhǔ)板上(shàng)BIOS ROM芯片(piàn)大部(bù)分(fēn)都采用(yòng)EEPROMElectrically Erasable Programmable ROM,電(diàn)可(kě)擦除可(kě)編程ROM)。EEPROM的(de)擦除不(bù)需要(yào)借(jiè)助于(yú)其它(tā)設備,它(tā)是(shì)以(yǐ)電(diàn)子信(xìn)号(hào)来(lái)修改其內(nèi)容的(de),而(ér)且是(shì)以(yǐ)Byte为(wèi)最(zuì)小修改單位,不(bù)必将資料全(quán)部(bù)洗掉才能(néng)写入(rù),徹底擺脫了(le)EPROM Eraser和(hé)編程器的(de)束(shù)缚。EEPROM在(zài)写入(rù)數據(jù)时(shí),仍要(yào)利用(yòng)一(yī)定(dìng)的(de)編程電(diàn)壓,此(cǐ)时(shí),只(zhī)需用(yòng)廠(chǎng)商提(tí)供的(de)專用(yòng)刷新程序就(jiù)可(kě)以(yǐ)輕(qīng)而(ér)易舉地(dì)改写內(nèi)容,所(suǒ)以(yǐ),它(tā)屬于(yú)双(shuāng)電(diàn)壓芯片(piàn)。借(jiè)助于(yú)EEPROM芯片(piàn)的(de)双(shuāng)電(diàn)壓特(tè)性(xìng),可(kě)以(yǐ)使BIOS具有(yǒu)良好(hǎo)的(de)防毒功能(néng),在(zài)升(shēng)級时(shí),把跳線(xiàn)開(kāi)關(guān)打(dǎ)至(zhì)“on”的(de)位置,即給(gěi)芯片(piàn)加上(shàng)相應(yìng)的(de)編程電(diàn)壓,就(jiù)可(kě)以(yǐ)方(fāng)便地(dì)升(shēng)級;平时(shí)使用(yòng)时(shí),則把跳線(xiàn)開(kāi)關(guān)打(dǎ)至(zhì)“off”的(de)位置,防止CIH類(lèi)的(de)病毒对(duì)BIOS芯片(piàn)的(de)非(fēi)法修改。所(suǒ)以(yǐ),仍有(yǒu)不(bù)少(shǎo)主(zhǔ)板采用(yòng)EEPROM作为(wèi)BIOS芯片(piàn)并作为(wèi)自(zì)己主(zhǔ)板的(de)一(yī)大特(tè)色(sè)。

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

整个(gè)工程由(yóu)FPGA、矩阵(zhèn)鍵盤/按鍵、數碼管(guǎn)和(hé)AT93C46組成(chéng),实現(xiàn)一(yī)个(gè)上(shàng)電(diàn)後(hòu)能(néng)重(zhòng)新加载,接着上(shàng)次(cì)計(jì)數的(de)數字(zì)时(shí)鐘(zhōng),詳细(xì)功能(néng)如(rú)下(xià)。

 

1、數碼管(guǎn)顯示时(shí)鐘(zhōng)值,共(gòng)使用(yòng)了(le)6个(gè)數碼管(guǎn),分(fēn)别表(biǎo)示时(shí)十(shí)位、时(shí)个(gè)位、分(fēn)十(shí)位、分(fēn)个(gè)位、秒(miǎo)十(shí)位和(hé)秒(miǎo)个(gè)位。

 

2、 矩阵(zhèn)鍵盤或(huò)者(zhě)按鍵可(kě)以(yǐ)对(duì)數字(zì)时(shí)鐘(zhōng)進(jìn)行时(shí)分(fēn)秒(miǎo)的(de)設置。

 

A、上(shàng)電(diàn)後(hòu),时(shí)鐘(zhōng)默認处于(yú)計(jì)时(shí)狀态,當按鍵1按下(xià),跳到(dào)时(shí)間(jiān)設置狀态,當按鍵1再次(cì)按下(xià),回(huí)到(dào)計(jì)时(shí)狀态。

B、 當处于(yú)时(shí)間(jiān)設置狀态时(shí),默認此(cǐ)刻設置的(de)是(shì)秒(miǎo)个(gè)位,當按鍵2按下(xià),此(cǐ)刻設置秒(miǎo)十(shí)位,以(yǐ)此(cǐ)類(lèi)推,一(yī)次(cì)設置为(wèi)分(fēn)个(gè)位、分(fēn)十(shí)位、时(shí)个(gè)位和(hé)时(shí)十(shí)位。再按下(xià)按鍵2,則重(zhòng)新設置秒(miǎo)个(gè)位。

C、當处于(yú)时(shí)間(jiān)設置狀态时(shí),按下(xià)按鍵3,則設置位的(de)值加1,如(rú)果(guǒ)溢出(chū),則變(biàn)成(chéng)0。例如(rú)當目前(qián)小时(shí)顯示05时(shí),設置时(shí)十(shí)位,按下(xià)按鍵3,變(biàn)成(chéng)15,再按下(xià)按鍵3,則變(biàn)成(chéng)05.當目前(qián)小时(shí)顯示为(wèi)03时(shí),設置时(shí)十(shí)位,按一(yī)下(xià)按鍵3,變(biàn)成(chéng)13,再按一(yī)下(xià)按鍵3,則變(biàn)成(chéng)23,再按則为(wèi)03。

 

3、AT93C46則用(yòng)于(yú)保存时(shí)鐘(zhōng)值,其具有(yǒu)斷電(diàn)保護功能(néng),斷電(diàn)數據(jù)不(bù)丢失。

 

A、AT93C46一(yī)共(gòng)可(kě)以(yǐ)保存128字(zì)节(jié)的(de)數據(jù)。工程将AT93C46分(fēn)成(chéng)空間(jiān)1和(hé)空間(jiān)2。空間(jiān)1占用(yòng)的(de)地(dì)址为(wèi)0~3,空間(jiān)2占用(yòng)的(de)地(dì)址为(wèi)4~7。

 

B、每隔1秒(miǎo),保存當前(qián)时(shí)鐘(zhōng)值。第(dì)一(yī)次(cì)保存到(dào)空間(jiān)1,第(dì)二(èr)次(cì)保存到(dào)空間(jiān)2,第(dì)三(sān)次(cì)保存带(dài)空間(jiān)1,依此(cǐ)類(lèi)推。(如(rú)果(guǒ)只(zhī)有(yǒu)一(yī)个(gè)空間(jiān),則可(kě)能(néng)出(chū)現(xiàn)写數據(jù)过(guò)程中(zhōng)斷電(diàn),從而(ér)得不(bù)到(dào)完整數據(jù)情(qíng)況)

 

C、支持(chí)8位的(de)CRC,生(shēng)成(chéng)多(duō)項式image.png,初始值为(wèi)全(quán)1。

 

D、每次(cì)保存的(de)值,时(shí)十(shí)位、时(shí)个(gè)位、分(fēn)十(shí)位、分(fēn)个(gè)位、秒(miǎo)十(shí)位和(hé)秒(miǎo)个(gè)位各(gè)占4bit,共(gòng)3个(gè)字(zì)节(jié),加上(shàng)1个(gè)字(zì)节(jié)的(de)CRC,一(yī)共(gòng)4个(gè)字(zì)节(jié)。

 

E、上(shàng)電(diàn)後(hòu),FPGA将读(dú)取(qǔ)两(liǎng)个(gè)空間(jiān)的(de)數值,并作CRC檢验(yàn)。如(rú)果(guǒ)两(liǎng)組數據(jù)的(de)CRC檢验(yàn)均失敗,則不(bù)重(zhòng)新加载;如(rú)果(guǒ)有(yǒu)一(yī)組數據(jù)CRC檢验(yàn)失敗,則加载正(zhèng)确的(de)一(yī)組數據(jù);如(rú)果(guǒ)两(liǎng)組數據(jù)CRC檢验(yàn)均正(zhèng)确,則加载數值較大的(de)一(yī)組數據(jù)。

 


1.1.3 系(xì)統結構框图(tú)

系(xì)統結構框图(tú)如(rú)下(xià)所(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)。


时(shí)鐘(zhōng)數據(jù)産生(shēng)模块(kuài)实現(xiàn)功能(néng)

負責産生(shēng)數字(zì)时(shí)鐘(zhōng)需要(yào)的(de)时(shí)鐘(zhōng)信(xìn)息。包(bāo)括:
1、按數字(zì)时(shí)鐘(zhōng)方(fāng)式進(jìn)行計(jì)數
2、設置數字(zì)时(shí)鐘(zhōng)的(de)值
3、将时(shí)鐘(zhōng)數據(jù)輸出(chū)給(gěi)外(wài)部(bù)模块(kuài)使用(yòng)
4、從數據(jù)处理模块(kuài)得到(dào)时(shí)鐘(zhōng)數據(jù),并重(zhòng)新加载


數碼管(guǎn)顯示模块(kuài)实現(xiàn)功能(néng)

1、对(duì)时(shí)鐘(zhōng)數據(jù)進(jìn)行譯碼,然後(hòu)發(fà)到(dào)數碼管(guǎn)顯示
2、逐一(yī)顯示时(shí)分(fēn)秒(miǎo)的(de)值


數據(jù)处理模块(kuài)实現(xiàn)功能(néng)

負責写到(dào)AT93C46的(de)數據(jù),或(huò)者(zhě)從AT93C46读(dú)到(dào)數據(jù)後(hòu)的(de)处理,包(bāo)括:
1、上(shàng)電(diàn)後(hòu),發(fà)送EWEN命令,打(dǎ)開(kāi)AT93C46的(de)写保護。
2、發(fà)送EWEN命令後(hòu),開(kāi)始读(dú)存儲在(zài)AT93C46的(de)两(liǎng)組时(shí)鐘(zhōng)數據(jù);对(duì)數據(jù)進(jìn)行檢验(yàn),然後(hòu)選擇适合的(de)數據(jù)給(gěi)时(shí)鐘(zhōng)數據(jù)産生(shēng)模块(kuài)加载
3、每隔1秒(miǎo)從时(shí)鐘(zhōng)數據(jù)産生(shēng)模块(kuài)獲取(qǔ)时(shí)分(fēn)秒(miǎo)的(de)值,并産生(shēng)CRC值,最(zuì)後(hòu)写道(dào)AT93C46上(shàng)


CRC处理模块(kuài)实現(xiàn)功能(néng)

負責CRC算法的(de)模块(kuài),在(zài)數據(jù)处理模块(kuài)內(nèi)部(bù)使用(yòng)


AT93C46模块(kuài)实現(xiàn)功能(néng)

根(gēn)據(jù)上(shàng)遊模块(kuài)的(de)EWENWRITE和(hé)READ命令,産生(shēng)AT93C46的(de)相應(yìng)时(shí)序,從而(ér)写數據(jù)或(huò)者(zhě)读(dú)到(dào)數據(jù)。至(zhì)于(yú)數據(jù)是(shì)什麼(me)、有(yǒu)什麼(me)用(yòng),不(bù)關(guān)心(xīn),只(zhī)關(guān)心(xīn)AT93C46的(de)时(shí)序。


1.1.5頂层信(xìn)号(hào)

  
信(xìn)号(hào)名
  
接口(kǒu)方(fāng)向(xiàng)
定(dìng)義
clk
輸入(rù)
系(xì)統时(shí)鐘(zhōng),50Mhz
rst_n
輸入(rù)
低電(diàn)平複位信(xìn)号(hào)
Key_col
輸入(rù)
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
輸出(chū)
4位矩阵(zhèn)鍵盤行信(xìn)号(hào),默認低電(diàn)平,開(kāi)發(fà)板按鍵为(wèi)普通(tòng)按鍵时(shí),不(bù)需要(yào)該信(xìn)号(hào)
Key
輸入(rù)
3位按鍵信(xìn)号(hào),開(kāi)發(fà)板按鍵为(wèi)矩阵(zhèn)鍵盤时(shí),不(bù)需要(yào)該信(xìn)号(hào)
Segment
輸出(chū)
8位數碼管(guǎn)段(duàn)選信(xìn)号(hào)
Seg_sel
輸出(chū)
6位數碼管(guǎn)位選信(xìn)号(hào)
Mo
輸出(chū)
At93c46數據(jù)輸出(chū)
Mi
輸入(rù)
At93c46數據(jù)輸入(rù)
Cs
輸出(chū)
At93c46片(piàn)選信(xìn)号(hào)
Sk
輸出(chū)
At93c46时(shí)鐘(zhōng)信(xìn)号(hào)


1.1.6參考代(dài)碼


  1. `define KEY_SCAN

  2. module at93c46_top_scan(

  3.     clk      ,

  4.     rst_n    ,

  5.     key_col  ,

  6.     mo       ,

  7.     cs       ,

  8.     mi       ,

  9.     sk       ,

  10.     key_row  ,

  11.     seg_sel  ,

  12.     seg_data

  13.     );


  14.     parameter    TIME_1S = 50_000_000;



  15.     input               clk          ;

  16.     input               rst_n        ;

  17.     input [3:0]         key_col      ;

  18.     input               mo           ;


  19.     output              cs           ;

  20.     output              mi           ;

  21.     output              sk           ;

  22.     output[3:0]         key_row      ;

  23.     output[5:0]         seg_sel      ;

  24.     output[7:0]         seg_data     ;


  25.     wire                rdy          ;

  26.     wire                rdata_vld    ;

  27.     wire  [3:0]         key_en       ;


  28.     wire  [23:0]        data_load    ;

  29.     wire                data_load_vld;


  30.     wire  [23:0]        clk_data_out ;


  31.     wire  [6:0]         addr         ;

  32.     wire  [1:0]         mode         ;

  33.     wire                start        ;


  34.     wire  [7:0]         wdata        ;

  35.     wire  [7:0]         rdata        ;





  36.              `ifdef KEY_SCAN

  37.     key_scan  u_key_scan(

  38.                 .clk     (clk    ),

  39.                 .rst_n   (rst_n  ),

  40.                 .key_col (key_col),

  41.                 .key_row (key_row),

  42.                 .key_en  (key_en )

  43.              );

  44.             `else            

  45.    key_module  u_key_module(

  46.                 .clk     (clk     ),

  47.                 .rst_n   (rst_n   ),

  48.                 .key_in  (~key_col),

  49.                 .key_vld (key_en  )

  50.              );


  51.             `endif

  52.     clock_data#(.TIME_1S(TIME_1S)) u_clock_data(

  53.                 .clk           (clk           ),

  54.                 .rst_n         (rst_n         ),

  55.                 .data_load     (data_load     ),

  56.                 .data_load_vld (data_load_vld ),

  57.                 .key_en        (key_en        ),

  58.                 .data_out      (clk_data_out  )

  59.     );


  60.     seg_disp#(.SEG_NUM(6)) u_seg_disp(

  61.                 .rst_n       (rst_n       ),

  62.                 .clk         (clk         ),

  63.                 .din         (clk_data_out),

  64.                 .din_vld     ({6{1'b1}}   ),

  65.                 .seg_sel     (seg_sel     ),

  66.                 .segment     (seg_data    )

  67.              );

  68.    

  69.    

  70.    data_processor#(.TIME_1S(TIME_1S)) u_data_pro(

  71.                       .clk        (clk         )  ,

  72.                       .rst_n      (rst_n       )  ,

  73.                       .din        (clk_data_out)  ,

  74.                       .start      (start       )  ,

  75.                       .mode       (mode        )  ,

  76.                       .addr       (addr        )  ,

  77.                       .wdata      (wdata       )  ,

  78.                       .rdata      (rdata       )  ,

  79.                       .rdata_vld  (rdata_vld   )  ,

  80.                       .rdy        (rdy         )  ,

  81.                       .dout       (data_load   )  ,

  82.                       .dout_vld   (data_load_vld )   

  83.    

  84.     );



  85.     at93c46_mix u_at93c46_mix(

  86.                    .clk        (clk        )  ,

  87.                    .rst_n      (rst_n      )  ,

  88.                    .start      (start      )  ,

  89.                    .mode       (mode       )  ,

  90.                    .addr       (addr       )  ,

  91.                    .wdata      (wdata      )  ,

  92.                    .rdata      (rdata      )  ,

  93.                    .rdata_vld  (rdata_vld  )  ,

  94.                    .rdy        (rdy        )  ,

  95.                    .do         (mo         )  ,

  96.                    .di         (mi         )  ,

  97.                    .cs         (cs         )  ,

  98.                    .sk         (sk         )   

  99.     );



  100. endmodule

複制代(dài)碼



本(běn)工程会(huì)應(yìng)用(yòng)于(yú)不(bù)同(tóng)的(de)開(kāi)發(fà)板,主(zhǔ)要(yào)區(qū)别在(zài)于(yú)使用(yòng)普通(tòng)按鍵還(huán)是(shì)矩阵(zhèn)鍵盤,頂层代(dài)碼中(zhōng)針(zhēn)对(duì)这(zhè)一(yī)點(diǎn)進(jìn)行了(le)設計(jì),如(rú)何開(kāi)發(fà)板使用(yòng)的(de)是(shì)矩阵(zhèn)鍵盤,則頂层代(dài)碼不(bù)需要(yào)改,如(rú)果(guǒ)使用(yòng)的(de)是(shì)普通(tòng)按鍵,只(zhī)需要(yào)将頂层代(dài)碼最(zuì)上(shàng)面(miàn)的(de)一(yī)行删除或(huò)者(zhě)注釋掉就(jiù)可(kě)以(yǐ)了(le)。





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. module  key_scan(

  2.                  clk    ,

  3.                  rst_n  ,

  4.                  key_col,

  5.                  key_row,

  6.                  key_en   

  7.                );



  8.     parameter      KEY_W    =   4      ;

  9.     parameter      CHK_COL  =   0      ;

  10.     parameter      CHK_ROW  =   1      ;

  11.     parameter      DELAY    =   2      ;

  12.     parameter      WAIT_END =   3      ;

  13.     parameter      COL_CNT  =   16     ;

  14.     parameter      TIME_20MS=   1000000;


  15.     input               clk              ;

  16.     input               rst_n            ;

  17.     input [3:0]         key_col          ;


  18.     output[3:0]         key_en           ;

  19.     output[KEY_W-1:0]   key_row          ;


  20.     reg   [3:0]         key_out          ;

  21.     reg   [KEY_W-1:0]   key_row          ;

  22.     reg                 key_vld          ;



  23.     reg   [3:0]         key_col_ff0      ;

  24.     reg   [3:0]         key_col_ff1      ;

  25.     reg   [1:0]         key_col_get      ;

  26.     reg   [3:0]         key_en           ;

  27.     wire                end_shake_cnt    ;

  28.     reg                 end_shake_cnt_ff0;

  29.     reg   [3:0]         state_c          ;

  30.     reg   [19:0]        shake_cnt        ;

  31.     reg   [3:0]         state_n          ;

  32.     reg   [1:0]         row_index        ;

  33.     reg   [15:0]        row_cnt          ;

  34.     wire                col2row_start    ;

  35.     wire                row2del_start    ;

  36.     wire                del2wait_start   ;

  37.     wire                wait2col_start   ;

  38.     wire                add_row_cnt      ;

  39.     wire                end_row_cnt      ;

  40.     wire                add_shake_cnt    ;

  41.     wire                add_row_index    ;

  42.     wire                end_row_index    ;



  43. always  @(posedge clk or negedge rst_n)begin

  44.     if(rst_n==1'b0)begin

  45.         key_col_ff0 <= 4'b1111;

  46.         key_col_ff1 <= 4'b1111;

  47.     end

  48.     else begin

  49.         key_col_ff0 <= key_col    ;

  50.         key_col_ff1 <= key_col_ff0;

  51.     end

  52. end



  53. always @(posedge clk or negedge rst_n) begin

  54.     if (rst_n==0) begin

  55.         shake_cnt <= 0;

  56.     end

  57.     else if(add_shake_cnt) begin

  58.         if(end_shake_cnt)

  59.             shake_cnt <= 0;

  60.         else

  61.             shake_cnt <= shake_cnt+1 ;

  62.    end

  63. end

  64. assign add_shake_cnt = key_col_ff1!=4'hf;

  65. assign end_shake_cnt = add_shake_cnt  && shake_cnt == TIME_20MS-1 ;



  66. always  @(posedge clk or negedge rst_n)begin

  67.     if(rst_n==1'b0)begin

  68.         state_c <= CHK_COL;

  69.     end

  70.     else begin

  71.         state_c <= state_n;

  72.     end

  73. end


  74. always  @(*)begin

  75.     case(state_c)

  76.         CHK_COL: begin

  77.                      if(col2row_start )begin

  78.                          state_n = CHK_ROW;

  79.                      end

  80.                      else begin

  81.                          state_n = CHK_COL;

  82.                      end

  83.                  end

  84.         CHK_ROW: begin

  85.                      if(row2del_start)begin

  86.                          state_n = DELAY;

  87.                      end

  88.                      else begin

  89.                          state_n = CHK_ROW;

  90.                      end

  91.                  end

  92.         DELAY :  begin

  93.                      if(del2wait_start)begin

  94.                          state_n = WAIT_END;

  95.                      end

  96.                      else begin

  97.                          state_n = DELAY;

  98.                      end

  99.                  end

  100.         WAIT_END: begin

  101.                      if(wait2col_start)begin

  102.                          state_n = CHK_COL;

  103.                      end

  104.                      else begin

  105.                          state_n = WAIT_END;

  106.                      end

  107.                   end

  108.        default: state_n = CHK_COL;

  109.     endcase

  110. end

  111. assign col2row_start = state_c==CHK_COL  && end_shake_cnt;

  112. assign row2del_start = state_c==CHK_ROW  && row_index==3 && end_row_cnt;

  113. assign del2wait_start= state_c==DELAY    && end_row_cnt;

  114. assign wait2col_start= state_c==WAIT_END && key_col_ff1==4'hf;


  115. always  @(posedge clk or negedge rst_n)begin

  116.     if(rst_n==1'b0)begin

  117.         key_row <= 4'b0;

  118.     end

  119.     else if(state_c==CHK_ROW)begin

  120.         key_row <= ~(1'b1 << row_index);

  121.     end

  122.     else begin

  123.         key_row <= 4'b0;

  124.     end

  125. end






  126. always @(posedge clk or negedge rst_n) begin

  127.     if (rst_n==0) begin

  128.         row_index <= 0;

  129.     end

  130.     else if(add_row_index) begin

  131.         if(end_row_index)

  132.             row_index <= 0;

  133.         else

  134.             row_index <= row_index+1 ;

  135.    end

  136.    else if(state_c!=CHK_ROW)begin

  137.        row_index <= 0;

  138.    end

  139. end

  140. assign add_row_index = state_c==CHK_ROW && end_row_cnt;

  141. assign end_row_index = add_row_index  && row_index == 4-1 ;



  142. always @(posedge clk or negedge rst_n) begin

  143.     if (rst_n==0) begin

  144.         row_cnt <= 0;

  145.     end

  146.     else if(add_row_cnt) begin

  147.         if(end_row_cnt)

  148.             row_cnt <= 0;

  149.         else

  150.             row_cnt <= row_cnt+1 ;

  151.    end

  152. end

  153. assign add_row_cnt = state_c==CHK_ROW || state_c==DELAY;

  154. assign end_row_cnt = add_row_cnt  && row_cnt == 16-1 ;




  155. always  @(posedge clk or negedge rst_n)begin

  156.     if(rst_n==1'b0)begin

  157.         key_col_get <= 0;

  158.     end

  159.     else if(state_c==CHK_COL && end_shake_cnt ) begin

  160.         if(key_col_ff1==4'b1110)

  161.             key_col_get <= 0;

  162.         else if(key_col_ff1==4'b1101)

  163.             key_col_get <= 1;

  164.         else if(key_col_ff1==4'b1011)

  165.             key_col_get <= 2;

  166.         else

  167.             key_col_get <= 3;

  168.     end

  169. end



  170. always  @(posedge clk or negedge rst_n)begin

  171.     if(rst_n==1'b0)begin

  172.         key_out <= 0;

  173.     end

  174.     else if(state_c==CHK_ROW && end_row_cnt)begin

  175.         key_out <= {row_index,key_col_get};

  176.     end

  177.     else begin

  178.         key_out <= 0;

  179.     end

  180. end


  181. always  @(posedge clk or negedge rst_n)begin

  182.     if(rst_n==1'b0)begin

  183.         key_vld <= 1'b0;

  184.     end

  185.     else if(state_c==CHK_ROW && end_row_cnt && key_col_ff1[key_col_get]==1'b0)begin

  186.         key_vld <= 1'b1;

  187.     end

  188.     else begin

  189.         key_vld <= 1'b0;

  190.     end

  191. end



  192. always  @(*)begin

  193.     if(rst_n==1'b0)begin

  194.         key_en = 0;

  195.     end

  196.     else if(key_vld && key_out==0)begin

  197.         key_en = 4'b0001;

  198.     end

  199.     else if(key_vld && key_out==1)begin

  200.         key_en = 4'b0010;

  201.     end

  202.     else if(key_vld && key_out==2)begin

  203.         key_en = 4'b0100;

  204.     end

  205.     else begin

  206.         key_en = 0;

  207.     end

  208. end



複制代(dài)碼




1.3 时(shí)間(jiān)數據(jù)産生(shēng)模块(kuài)設計(jì)
1.3.1接口(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)
Data_load
輸入(rù)
重(zhòng)载的(de)时(shí)鐘(zhōng)數據(jù),每四(sì)个(gè)一(yī)組,共(gòng)6組。由(yóu)高(gāo)位至(zhì)低位,分(fēn)别是(shì)时(shí)十(shí)位、时(shí)个(gè)位、分(fēn)十(shí)位、分(fēn)个(gè)位、秒(miǎo)十(shí)位和(hé)秒(miǎo)个(gè)位
Data_load_vld
輸入(rù)
重(zhòng)载的(de)时(shí)鐘(zhōng)數據(jù)有(yǒu)效指示信(xìn)号(hào),當有(yǒu)效时(shí),采用(yòng)data_load的(de)數據(jù)为(wèi)最(zuì)新的(de)时(shí)鐘(zhōng)數據(jù)
Key_num
輸入(rù)
按鍵位置輸入(rù)信(xìn)号(hào),key_vld有(yǒu)效时(shí),該信(xìn)号(hào)有(yǒu)效
Key_vld
輸入(rù)
按鍵值有(yǒu)效信(xìn)号(hào),为(wèi)1时(shí)表(biǎo)示檢测到(dào)一(yī)个(gè)按鍵
data_out
輸出(chū)
當前(qián)的(de)时(shí)鐘(zhōng)數據(jù),每四(sì)个(gè)1組,共(gòng)六(liù)組,由(yóu)高(gāo)位至(zhì)低位,分(fēn)别是(shì)时(shí)十(shí)位、时(shí)个(gè)位、分(fēn)十(shí)位、分(fēn)个(gè)位、秒(miǎo)十(shí)位和(hé)秒(miǎo)个(gè)位



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

本(běn)模块(kuài)相对(duì)于(yú)前(qián)面(miàn)的(de)按鍵控制數字(zì)时(shí)鐘(zhōng)案(àn)例中(zhōng)的(de)时(shí)間(jiān)數據(jù)産生(shēng)模块(kuài)来(lái)说(shuō),總(zǒng)體(tǐ)的(de)設計(jì)思(sī)路(lù)是(shì)相同(tóng)的(de),只(zhī)是(shì)增加了(le)一(yī)个(gè)重(zhòng)载的(de)时(shí)鐘(zhōng)信(xìn)号(hào),对(duì)于(yú)此(cǐ)信(xìn)号(hào)的(de)設計(jì)也(yě)比較簡單,只(zhī)需要(yào)在(zài)时(shí)分(fēn)秒(miǎo)的(de)个(gè)位和(hé)十(shí)位計(jì)數器中(zhōng)增加一(yī)句(jù):在(zài)重(zhòng)载的(de)时(shí)鐘(zhōng)數據(jù)有(yǒu)效的(de)时(shí)候,使計(jì)數器輸出(chū)重(zhòng)载的(de)时(shí)鐘(zhōng)对(duì)應(yìng)的(de)數據(jù)即可(kě),比如(rú)秒(miǎo)个(gè)位計(jì)數器應(yìng)該輸出(chū)重(zhòng)载时(shí)鐘(zhōng)數據(jù)的(de)第(dì)0到(dào)第(dì)3位數據(jù),秒(miǎo)十(shí)位計(jì)數器應(yìng)該輸出(chū)重(zhòng)载时(shí)鐘(zhōng)數據(jù)的(de)第(dì)4到(dào)第(dì)7位數據(jù),以(yǐ)此(cǐ)類(lèi)推。


其他(tā)詳细(xì)的(de)設計(jì)思(sī)路(lù)可(kě)以(yǐ)看(kàn)一(yī)下(xià)往期(qī)按鍵控制數字(zì)时(shí)鐘(zhōng)的(de)文(wén)章(zhāng):


1.3.3參考代(dài)碼


  1. module clock_data(

  2.     clk          ,

  3.     rst_n        ,

  4.     data_load    ,

  5.     data_load_vld,

  6.     key_en       ,

  7.     data_out   

  8.     );


  9.     parameter      TIME_1S    =       50_000_000   ;


  10.     input               clk          ;

  11.     input               rst_n        ;

  12.     input               data_load_vld;

  13.     input [23:0]        data_load    ;

  14.     input [ 3:0]        key_en       ;

  15.     output[23:0]        data_out     ;

  16.     wire  [23:0]        data_out     ;



  17.     reg   [25:0]        cnt_1s       ;

  18.     reg   [3:0]         miao_ge      ;

  19.     reg   [3:0]         miao_shi     ;

  20.     reg   [3:0]         fen_ge       ;

  21.     reg   [3:0]         fen_shi      ;

  22.     reg   [3:0]         shi_ge       ;

  23.     reg   [3:0]         shi_shi      ;

  24.     reg   [2:0]         set_sel      ;

  25.     reg                 set_flag     ;

  26.     wire                add_set_sel  ;

  27.     wire                add_cnt_1s   ;

  28.     wire                add_miao_ge  ;

  29.     wire                add_miao_shi ;

  30.     wire                add_fen_ge   ;

  31.     wire                add_fen_shi  ;

  32.     wire                add_shi_ge   ;

  33.     wire                add_shi_shi  ;

  34.     wire                end_cnt_1s   ;

  35.     wire                end_set_sel  ;

  36.     wire                end_miao_ge  ;

  37.     wire                end_miao_shi ;

  38.     wire                end_fen_ge   ;

  39.     wire                end_fen_shi  ;

  40.     wire                end_shi_ge   ;

  41.     wire                end_shi_shi  ;

  42.     wire                set_miao_ge  ;

  43.     wire                set_miao_shi ;

  44.     wire                set_fen_ge   ;

  45.     wire                set_fen_shi  ;

  46.     wire                set_shi_ge   ;

  47.     wire                set_shi_shi  ;


  48.     reg  [ 3:0]         x            ;

  49.     reg  [ 2:0]         y            ;


  50.     always  @(posedge clk or negedge rst_n)begin

  51.         if(rst_n==1'b0)begin

  52.             set_flag <= 1'b0;

  53.         end

  54.         else if(key_en[0]) begin

  55.             set_flag <= ~ set_flag;

  56.         end

  57.     end




  58.     always @(posedge clk or negedge rst_n)begin

  59.         if(!rst_n)begin

  60.             set_sel <= 0;

  61.         end

  62.         else if(add_set_sel)begin

  63.             if(end_set_sel)

  64.                 set_sel <= 0;

  65.             else

  66.                 set_sel <= set_sel + 1;

  67.         end

  68.         else if(set_flag==0)begin

  69.             set_sel <= 0;

  70.         end

  71.     end


  72.     assign add_set_sel = set_flag && key_en[1];      

  73.     assign end_set_sel = add_set_sel && set_sel==6-1 ;   


  74.     always @(posedge clk or negedge rst_n)begin

  75.         if(!rst_n)begin

  76.             cnt_1s <= 0;

  77.         end

  78.         else if(add_cnt_1s)begin

  79.             if(end_cnt_1s)

  80.                 cnt_1s <= 0;

  81.             else

  82.                 cnt_1s <= cnt_1s + 1;

  83.         end

  84.     end


  85.     assign add_cnt_1s = set_flag==0 ;      

  86.     assign end_cnt_1s = add_cnt_1s && cnt_1s==TIME_1S-1 ;   






  87.     always @(posedge clk or negedge rst_n)begin

  88.         if(!rst_n)begin

  89.             miao_ge <= 0;

  90.         end

  91.         else if(add_miao_ge)begin

  92.             if(end_miao_ge)

  93.                 miao_ge <= 0;

  94.             else

  95.                 miao_ge <= miao_ge + 1;

  96.         end

  97.         else if(data_load_vld)begin

  98.             miao_ge <=  data_load[3:0];

  99.         end

  100.     end


  101.     assign add_miao_ge = (end_cnt_1s || set_miao_ge) ;      

  102.     assign end_miao_ge = add_miao_ge && miao_ge==10-1 ;

  103.     assign set_miao_ge = set_flag    && set_sel==0 && key_en[2];   




  104.     always @(posedge clk or negedge rst_n)begin

  105.         if(!rst_n)begin

  106.             miao_shi <= 0;

  107.         end

  108.         else if(add_miao_shi)begin

  109.             if(end_miao_shi)

  110.                 miao_shi <= 0;

  111.             else

  112.                 miao_shi <= miao_shi + 1;

  113.         end

  114.         else if(data_load_vld)begin

  115.             miao_shi <= data_load[7:4];

  116.         end

  117.     end


  118.     assign add_miao_shi = (end_miao_ge || set_miao_shi);      

  119.     assign end_miao_shi = add_miao_shi && miao_shi==6-1;

  120.     assign set_miao_shi = set_flag     && set_sel==1 && key_en[2];   



  121.     always @(posedge clk or negedge rst_n)begin

  122.         if(!rst_n)begin

  123.             fen_ge <= 0;

  124.         end

  125.         else if(add_fen_ge)begin

  126.             if(end_fen_ge)

  127.                 fen_ge <= 0;

  128.             else

  129.                 fen_ge <= fen_ge + 1;

  130.         end

  131.         else if(data_load_vld)begin

  132.             fen_ge <= data_load[11:8];

  133.         end

  134.     end


  135.     assign add_fen_ge = (end_miao_shi || set_fen_ge);      

  136.     assign end_fen_ge = add_fen_ge && fen_ge==10-1;

  137.     assign set_fen_ge = set_flag     && set_sel==2 && key_en[2];   



  138.     always @(posedge clk or negedge rst_n)begin

  139.         if(!rst_n)begin

  140.             fen_shi <= 0;

  141.         end

  142.         else if(add_fen_shi)begin

  143.             if(end_fen_shi)

  144.                 fen_shi <= 0;

  145.             else

  146.                 fen_shi <= fen_shi + 1;

  147.         end

  148.         else if(data_load_vld)begin

  149.             fen_shi <= data_load[15:12];

  150.         end

  151.     end


  152.     assign add_fen_shi = (end_fen_ge || set_fen_shi);      

  153.     assign end_fen_shi = add_fen_shi && fen_shi==6-1;

  154.     assign set_fen_shi = set_flag     && set_sel==3 && key_en[2];   


  155.    always @(posedge clk or negedge rst_n)begin

  156.         if(!rst_n)begin

  157.             shi_ge <= 0;

  158.         end

  159.         else if(add_shi_ge)begin

  160.             if(end_shi_ge)

  161.                 shi_ge <= 0;

  162.             else

  163.                 shi_ge <= shi_ge + 1;

  164.         end

  165.         else if(data_load_vld)begin

  166.             shi_ge <= data_load[19:16];

  167.         end

  168.     end


  169.     assign add_shi_ge = (end_fen_shi || set_shi_ge);      

  170.     assign end_shi_ge = add_shi_ge && shi_ge==x-1;

  171.     assign set_shi_ge = set_flag     && set_sel==4 && key_en[2];   



  172.     always @(posedge clk or negedge rst_n)begin

  173.         if(!rst_n)begin

  174.             shi_shi <= 0;

  175.         end

  176.         else if(add_shi_shi)begin

  177.             if(end_shi_shi)

  178.                 shi_shi <= 0;

  179.             else

  180.                 shi_shi <= shi_shi + 1;

  181.         end

  182.         else if(data_load_vld)begin

  183.             shi_shi <= data_load[23:20];

  184.         end

  185.     end


  186.     assign add_shi_shi = (end_shi_ge || set_shi_shi);      

  187.     assign end_shi_shi = add_shi_shi && shi_shi==y-1;

  188.     assign set_shi_shi = set_flag     && set_sel==5 && key_en[2];   


  189.     always  @(*)begin

  190.         if(shi_shi<2)

  191.             x =  10;

  192.         else

  193.             x =   4;

  194.     end


  195.     always  @(*)begin

  196.         if(set_flag && set_sel==5 && shi_ge>=4)

  197.             y = 2;

  198.         else

  199.             y = 3;

  200.     end

  201.     assign data_out = {shi_shi,shi_ge,fen_shi,fen_ge,miao_shi,miao_ge};



  202. endmodule


複制代(dài)碼



1.4 數碼管(guǎn)顯示模块(kuài)設計(jì)

1.4.1接口(kǒu)信(xìn)号(hào)

  
信(xìn)号(hào)
  
接口(kǒu)方(fāng)向(xiàng)
定(dìng)義
clk
輸入(rù)
系(xì)統时(shí)鐘(zhōng),50MHz
rst_n
輸入(rù)
低電(diàn)平複位信(xìn)号(hào)
din
輸入(rù)
當前(qián)的(de)时(shí)鐘(zhōng)數據(jù),每四(sì)位一(yī)組,共(gòng) 6 組。由(yóu)高(gāo)位至(zhì)低位,分(fēn)
  
别是(shì)时(shí)十(shí)位、时(shí)个(gè)位、分(fēn)十(shí)位、分(fēn)个(gè)位、秒(miǎo)十(shí)位和(hé)秒(miǎo)个(gè)位的(de)
  
值。
Seg_sel
輸出(chū)
數碼管(guǎn)位選信(xìn)号(hào)
Segment
輸出(chū)
數碼管(guǎn)段(duàn)選信(xìn)号(hào)



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

數碼管(guǎn)顯示在(zài)前(qián)面(miàn)的(de)案(àn)例文(wén)章(zhāng)已經(jīng)有(yǒu)講述,这(zhè)里(lǐ)不(bù)再進(jìn)行介紹,想(xiǎng)了(le)解(jiě)的(de)可(kě)以(yǐ)看(kàn)一(yī)下(xià)往期(qī)文(wén)章(zhāng):


1.4.3參考代(dài)碼

  1. always @(posedge clk or negedge rst_n)begin

  2.     if(!rst_n)begin

  3.         cnt_2ms <= 0;

  4.     end

  5.     else if(add_cnt_2ms)begin

  6.         if(end_cnt_2ms)

  7.             cnt_2ms <= 0;

  8.         else

  9.             cnt_2ms <= cnt_2ms + 1;

  10.     end

  11. end


  12. assign add_cnt_2ms = 1;      

  13. assign end_cnt_2ms = add_cnt_2ms && cnt_2ms==TIME_2MS-1 ;   


  14. always @(posedge clk or negedge rst_n)begin

  15.     if(!rst_n)begin

  16.         cnt_sel <= 0;

  17.     end

  18.     else if(add_cnt_sel)begin

  19.         if(end_cnt_sel)

  20.             cnt_sel <= 0;

  21.         else

  22.             cnt_sel <= cnt_sel + 1;

  23.     end

  24. end


  25. assign add_cnt_sel = end_cnt_2ms;      

  26. assign end_cnt_sel = add_cnt_sel && cnt_sel== SEG_NUM-1;   




  27. always  @(posedge clk or negedge rst_n)begin

  28.     if(rst_n==1'b0)begin

  29.         seg_sel <= {SEG_NUM{1'b1}};

  30.     end

  31.     else begin

  32.         seg_sel <= ~(1'b1 << cnt_sel);

  33.     end

  34. end


  35. always  @(posedge clk or negedge rst_n)begin

  36.     if(rst_n==1'b0)begin

  37.         din_ff0 <= 0;

  38.     end

  39.     else begin

  40.         for(ii=0;ii<SEG_NUM;ii=ii+1)begin

  41.             if(din_vld[ii]==1'b1)begin

  42.                 din_ff0[(ii+1)*4-1 -:4] <= din[(ii+1)*4-1 -:4];

  43.             end

  44.             else begin

  45.                 din_ff0[(ii+1)*4-1 -:4] <= din_ff0[(ii+1)*4-1 -:4];

  46.             end

  47.         end

  48.     end

  49. end


  50. always  @(*)begin

  51.     seg_tmp = din_ff0[(cnt_sel+1)*4-1 -:4];

  52. end



  53. always@(posedge clk or negedge rst_n)begin

  54.     if(rst_n==1'b0)begin

  55.         segment<=NUM_0;

  56.     end

  57.     else begin

  58.         case(seg_tmp)

  59.             4'd0:segment <= NUM_0;

  60.             4'd1:segment <= NUM_1;

  61.             4'd2:segment <= NUM_2;

  62.             4'd3:segment <= NUM_3;

  63.             4'd4:segment <= NUM_4;

  64.             4'd5:segment <= NUM_5;

  65.             4'd6:segment <= NUM_6;

  66.             4'd7:segment <= NUM_7;

  67.             4'd8:segment <= NUM_8;

  68.             4'd9:segment <= NUM_9;

  69.             default:begin

  70.                 segment <= NUM_ERR;

  71.             end

  72.         endcase

  73.     end

  74. end


  75. endmodul

複制代(dài)碼


1.5 數據(jù)处理模块(kuài)設計(jì)


1.5.1接口(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)
din
輸入(rù)
时(shí)鐘(zhōng)數據(jù),每四(sì)位1組,共(gòng) 6 組。由(yóu)高(gāo)位至(zhì)低位,分(fēn)别是(shì)时(shí)十(shí)位、时(shí)个(gè)位、分(fēn)十(shí)位、分(fēn)个(gè)位、秒(miǎo)十(shí)位和(hé)秒(miǎo)个(gè)位的(de)值
dout
輸出(chū)
用(yòng)于(yú)加载的(de)时(shí)鐘(zhōng)數據(jù),每四(sì)位1組,共(gòng) 6 組。由(yóu)高(gāo)位至(zhì)低位,分(fēn)别是(shì)时(shí)十(shí)位、时(shí)个(gè)位、分(fēn)十(shí)位、分(fēn)个(gè)位、秒(miǎo)十(shí)位和(hé)秒(miǎo)个(gè)位的(de)值
dout_vld
輸出(chū)
时(shí)鐘(zhōng)加载有(yǒu)效指示信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效
Start
輸出(chū)
对(duì)AT93C46進(jìn)行打(dǎ)開(kāi)写保護、写數據(jù)或(huò)者(zhě)读(dú)數據(jù)命令。注意(yì),在(zài)rdy=0时(shí),不(bù)應(yìng)該使start有(yǒu)效
mode
輸出(chū)
对(duì)AT93C46的(de)操作模式,start有(yǒu)效时(shí),此(cǐ)值有(yǒu)效,
  
0:打(dǎ)開(kāi)写保護操作(EWEN)
  
1:写數據(jù)操作(WRITE)
  
2:读(dú)數據(jù)操作(READ)
  
其他(tā):不(bù)應(yìng)該出(chū)現(xiàn)
addr
輸出(chū)
读(dú)写AT93C46的(de)地(dì)址信(xìn)号(hào),同(tóng)时(shí)亦是(shì)EWEN的(de)指示信(xìn)号(hào),使用(yòng)EWEN命令时(shí),此(cǐ)值必須为(wèi)7’b1100000,在(zài)start有(yǒu)效时(shí),此(cǐ)信(xìn)号(hào)有(yǒu)效
Wdata
輸出(chū)
写到(dào)AT93C46的(de)數據(jù),start=1,且mode=1时(shí),此(cǐ)值有(yǒu)效
rdy
輸入(rù)
AT93C46接口(kǒu)模块(kuài)準備好(hǎo)信(xìn)号(hào),只(zhī)有(yǒu)當其为(wèi)1时(shí),才能(néng)向(xiàng)接口(kǒu)模块(kuài)發(fà)送命令
rdata
輸入(rù)
從AT93C46读(dú)取(qǔ)的(de)數據(jù)
rdata_vld
輸入(rù)
從AT93C46读(dú)到(dào)的(de)數據(jù)有(yǒu)效指示信(xìn)号(hào)


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

本(běn)模块(kuài)主(zhǔ)要(yào)負責写到(dào)AT93C46的(de)數據(jù)或(huò)者(zhě)读(dú)出(chū)的(de)數據(jù)的(de)处理,上(shàng)電(diàn)後(hòu),發(fà)送EWEN指令給(gěi)AT93C46接口(kǒu)模块(kuài),打(dǎ)開(kāi)AT93C46的(de)写保護;發(fà)送EWEN命令後(hòu),開(kāi)始读(dú)取(qǔ)存儲在(zài)AT93C46保存的(de)两(liǎng)組时(shí)鐘(zhōng)數據(jù);每隔1秒(miǎo)读(dú)取(qǔ)輸入(rù)时(shí)鐘(zhōng)數據(jù)的(de)值,并産生(shēng)CRC值,写到(dào)AT93C46上(shàng)。
根(gēn)據(jù)上(shàng)面(miàn)的(de)功能(néng)描述,該模块(kuài)采用(yòng)狀态機(jī)進(jìn)行架構,可(kě)劃(huà)分(fēn)四(sì)个(gè)狀态:打(dǎ)開(kāi)写保護狀态(S_EWEN)、读(dú)數據(jù)狀态(S_READ)、空閑狀态(S_IDLE)和(hé)写數據(jù)狀态(S_WRIT),狀态的(de)跳轉(zhuǎn)图(tú)如(rú)下(xià):



由(yóu)于(yú)功能(néng)要(yào)求只(zhī)在(zài)刚上(shàng)電(diàn)或(huò)者(zhě)複位的(de)时(shí)候才读(dú)取(qǔ)AT93C46中(zhōng)的(de)數據(jù),因(yīn)此(cǐ)刚上(shàng)電(diàn)就(jiù)是(shì)写保護打(dǎ)開(kāi)狀态,或(huò)者(zhě)複位有(yǒu)效时(shí),進(jìn)入(rù)写保護打(dǎ)開(kāi)狀态。由(yóu)于(yú)複位是(shì)由(yóu)按鍵控制的(de),因(yīn)此(cǐ)在(zài)按下(xià)的(de)时(shí)候会(huì)産生(shēng)抖動(dòng),可(kě)能(néng)会(huì)導致(zhì)産生(shēng)很多(duō)个(gè)start,因(yīn)此(cǐ)延时(shí)一(yī)段(duàn)时(shí)間(jiān)之後(hòu),如(rú)果(guǒ)AT93C46接口(kǒu)模块(kuài)準備好(hǎo),便進(jìn)入(rù)读(dú)數據(jù)狀态。數據(jù)读(dú)完之後(hòu),就(jiù)進(jìn)入(rù)空閑狀态,等待計(jì)时(shí)1秒(miǎo)之後(hòu),開(kāi)始将輸入(rù)的(de)时(shí)鐘(zhōng)數據(jù)写入(rù)AT93C46中(zhōng),写完四(sì)个(gè)字(zì)节(jié)數據(jù)之後(hòu)重(zhòng)新回(huí)到(dào)空閑狀态,等待計(jì)时(shí)1秒(miǎo),如(rú)此(cǐ)循环(huán)。


下(xià)面(miàn)介紹一(yī)下(xià)該模块(kuài)中(zhōng)其他(tā)信(xìn)号(hào)的(de)設計(jì)思(sī)路(lù):
时(shí)鐘(zhōng)計(jì)數器time_cnt:該計(jì)數器是(shì)計(jì)數1秒(miǎo)的(de)时(shí)間(jiān),從写保護打(dǎ)開(kāi)狀态跳轉(zhuǎn)到(dào)读(dú)數據(jù)狀态需要(yào)的(de)延时(shí)和(hé)空閑狀态跳轉(zhuǎn)写數據(jù)狀态需要(yào)的(de)1秒(miǎo)的(de)时(shí)間(jiān)可(kě)使用(yòng)此(cǐ)計(jì)數器表(biǎo)示;加一(yī)条(tiáo)件(jiàn)为(wèi)1,表(biǎo)示一(yī)直(zhí)計(jì)數;結束(shù)条(tiáo)件(jiàn)为(wèi)數50000000个(gè),表(biǎo)示1秒(miǎo)的(de)时(shí)間(jiān),數完就(jiù)清(qīng)零(líng)。
写數據(jù)計(jì)數器wr_cnt:該計(jì)數器用(yòng)于(yú)对(duì)要(yào)写入(rù)AT93C46的(de)數據(jù)進(jìn)行計(jì)數;加一(yī)条(tiáo)件(jiàn)为(wèi)state_c==S_WRIT&& rdy,表(biǎo)示在(zài)写數據(jù)狀态的(de)时(shí)候,如(rú)果(guǒ)AT93C46接口(kǒu)模块(kuài)準備好(hǎo),就(jiù)開(kāi)始計(jì)數;結束(shù)条(tiáo)件(jiàn)为(wèi)數4个(gè),3个(gè)字(zì)节(jié)的(de)时(shí)鐘(zhōng)數據(jù)加上(shàng)1个(gè)字(zì)节(jié)的(de)CRC校(xiào)验(yàn),共(gòng)四(sì)个(gè)字(zì)节(jié),數完就(jiù)清(qīng)零(líng)。
读(dú)數據(jù)計(jì)數器:該計(jì)數器數的(de)是(shì)從AT93C46读(dú)出(chū),并經(jīng)过(guò)CRC处理的(de)數據(jù)字(zì)节(jié)數;加一(yī)条(tiáo)件(jiàn)为(wèi)state_c==S_READ&& crc_dout_vld,表(biǎo)示在(zài)读(dú)數據(jù)狀态的(de)时(shí)候,CRC处理完就(jiù)計(jì)數一(yī)个(gè);結束(shù)条(tiáo)件(jiàn)为(wèi)數8个(gè),AT93C46两(liǎng)个(gè)區(qū)域內(nèi)共(gòng)存有(yǒu)8个(gè)字(zì)节(jié)的(de)數據(jù),數完就(jiù)清(qīng)零(líng)。
写區(qū)間(jiān)選擇信(xìn)号(hào)write_sel:初始狀态为(wèi)0,表(biǎo)示選擇區(qū)間(jiān)0~3,當写操作完成(chéng)之後(hòu),該信(xìn)号(hào)取(qǔ)反(fǎn),變(biàn)为(wèi)1,表(biǎo)示選擇區(qū)間(jiān)4~7
读(dú)写地(dì)址信(xìn)号(hào)addr:初始狀态为(wèi)0,根(gēn)據(jù)下(xià)方(fāng)的(de)表(biǎo)格(AT93C46的(de)指令集),當处于(yú)写數據(jù)狀态的(de)时(shí)候,地(dì)址为(wèi)7bit,由(yóu)于(yú)本(běn)工程只(zhī)会(huì)使用(yòng)區(qū)間(jiān)0~7来(lái)存儲數據(jù),因(yīn)此(cǐ)地(dì)址为(wèi)4bit0加上(shàng)写區(qū)間(jiān)選擇信(xìn)号(hào)write_sel加上(shàng)写數據(jù)計(jì)數器;當处于(yú)写保護打(dǎ)開(kāi)狀态的(de)时(shí)候,地(dì)址應(yìng)为(wèi)7’b11xxxxx,其中(zhōng)“x”表(biǎo)示不(bù)關(guān)注,工程中(zhōng)設为(wèi)0即可(kě);當处于(yú)读(dú)數據(jù)狀态的(de)时(shí)候,根(gēn)據(jù)读(dú)數據(jù)計(jì)數器的(de)變(biàn)化(huà)選擇地(dì)址即可(kě),即地(dì)址为(wèi)4’b0加上(shàng)rd_cnt



AT93C46指令集


AT93C46開(kāi)始命令start:初始狀态为(wèi)0,表(biǎo)示AT93C46不(bù)工作,當(add_wr_cnt || start_read),也(yě)就(jiù)是(shì)在(zài)写數據(jù)、读(dú)數據(jù)或(huò)者(zhě)写保護打(dǎ)開(kāi)狀态的(de)时(shí)候,該信(xìn)号(hào)拉高(gāo),指示AT93C46工作。


写數據(jù)wdata:該信(xìn)号(hào)表(biǎo)示要(yào)往AT93C46中(zhōng)写入(rù)的(de)數據(jù),初始狀态为(wèi)0。前(qián)三(sān)个(gè)字(zì)节(jié)写入(rù)輸入(rù)的(de)时(shí)鐘(zhōng)數據(jù),第(dì)四(sì)个(gè)字(zì)节(jié)写入(rù)CRC


AT93C46返回(huí)數據(jù)dout_temp:從AT93C46读(dú)出(chū)的(de)8个(gè)字(zì)节(jié)數據(jù),經(jīng)过(guò)串并轉(zhuǎn)換之後(hòu)保存在(zài)該信(xìn)号(hào)中(zhōng)。


第(dì)一(yī)區(qū)間(jiān)CRC錯誤指示信(xìn)号(hào)dout0_err:初始狀态为(wèi)0,表(biǎo)示沒(méi)有(yǒu)錯誤;當读(dú)數據(jù)計(jì)數器數到(dào)第(dì)4个(gè)的(de)时(shí)候,表(biǎo)示CRC模块(kuài)已經(jīng)完成(chéng)了(le)第(dì)一(yī)區(qū)間(jiān)數據(jù)的(de)校(xiào)验(yàn),如(rú)果(guǒ)校(xiào)验(yàn)結果(guǒ)为(wèi)0,表(biǎo)示正(zhèng)确,如(rú)果(guǒ)校(xiào)验(yàn)結果(guǒ)不(bù)等于(yú)0,表(biǎo)示輸出(chū)錯誤。


第(dì)二(èr)區(qū)間(jiān)CRC錯誤指示信(xìn)号(hào)dout1_err:为(wèi)了(le)使錯誤指示信(xìn)号(hào)跟數據(jù)能(néng)对(duì)齊,采用(yòng)組合邏輯設計(jì),當CRC模块(kuài)輸出(chū)數據(jù)为(wèi)0,表(biǎo)示沒(méi)有(yǒu)錯誤,該信(xìn)号(hào)为(wèi)0,如(rú)果(guǒ)CRC模块(kuài)輸出(chū)數據(jù)不(bù)为(wèi)0,表(biǎo)示有(yǒu)錯誤,該信(xìn)号(hào)为(wèi)1


用(yòng)于(yú)加载的(de)时(shí)鐘(zhōng)數據(jù)dout:初始狀态为(wèi)0;當读(dú)數據(jù)計(jì)數器數完的(de)时(shí)候,如(rú)果(guǒ)區(qū)間(jiān)1和(hé)區(qū)間(jiān)2的(de)檢验(yàn)都沒(méi)有(yǒu)錯誤,則比較AT93C46返回(huí)數據(jù)的(de)高(gāo)4字(zì)节(jié)和(hé)低4字(zì)节(jié)的(de)大小,輸出(chū)大的(de);如(rú)果(guǒ)區(qū)間(jiān)1檢验(yàn)正(zhèng)确,區(qū)間(jiān)2檢验(yàn)錯誤,則輸出(chū)高(gāo)4字(zì)节(jié)數據(jù),反(fǎn)之則輸出(chū)低4字(zì)节(jié)數據(jù)。


时(shí)鐘(zhōng)加载有(yǒu)效指示信(xìn)号(hào)dout_vld:初始狀态为(wèi)0,表(biǎo)示时(shí)鐘(zhōng)數據(jù)无效;當读(dú)數據(jù)計(jì)數器數完的(de)时(shí)候,如(rú)果(guǒ)第(dì)一(yī)區(qū)間(jiān)和(hé)第(dì)二(èr)區(qū)間(jiān)有(yǒu)最(zuì)少(shǎo)一(yī)个(gè)正(zhèng)确,該信(xìn)号(hào)就(jiù)拉高(gāo),表(biǎo)示待加载的(de)时(shí)鐘(zhōng)數據(jù)有(yǒu)效,其他(tā)情(qíng)況不(bù)拉高(gāo)。


1.5.3參考代(dài)碼

  1.     always  @(posedge clk or negedge rst_n)begin

  2.         if(rst_n==1'b0)begin

  3.             state_c <= S_EWEN;

  4.         end

  5.         else begin

  6.             state_c <= state_n;

  7.         end

  8.     end


  9.     always  @(*)begin

  10.         case(state_c)

  11.             S_EWEN : begin

  12.                 if(ewen2read_start)begin

  13.                     state_n = S_READ ;

  14.                 end

  15.                 else begin

  16.                     state_n = state_c;

  17.                 end

  18.             end

  19.             S_READ : begin

  20.                 if(read2idle_start)begin

  21.                     state_n = S_IDLE;

  22.                 end

  23.                 else begin

  24.                     state_n = state_c;

  25.                 end

  26.             end

  27.             S_IDLE : begin

  28.                 if(idle2write_start)begin

  29.                     state_n = S_WRITE;

  30.                 end

  31.                 else begin

  32.                     state_n = state_c;

  33.                 end

  34.             end

  35.             S_WRITE : begin

  36.                 if(write2idle_start)begin

  37.                     state_n = S_IDLE;

  38.                 end

  39.                 else begin

  40.                     state_n = state_c;

  41.                 end

  42.             end

  43.             default : begin

  44.                 state_n = S_EWEN;

  45.             end

  46.         endcase

  47.     end



  48.     assign   ewen2read_start  = state_c==S_EWEN  && add_time_cnt && time_cnt==1000-1 && rdy;

  49.     assign   read2idle_start  = state_c==S_READ  && end_rd_cnt      ;

  50.     assign   idle2write_start = state_c==S_IDLE  && end_time_cnt    ;

  51.     assign   write2idle_start = state_c==S_WRITE && end_wr_cnt      ;



  52.     always @(posedge clk or negedge rst_n)begin

  53.         if(!rst_n)begin

  54.             time_cnt <= 0;

  55.         end

  56.         else if(add_time_cnt)begin

  57.             if(end_time_cnt)

  58.                 time_cnt <= 0;

  59.             else

  60.                 time_cnt <= time_cnt + 1;

  61.         end

  62.     end


  63.     assign add_time_cnt = 1;      

  64.     assign end_time_cnt = add_time_cnt && time_cnt==TIME_1S-1 ;   



  65.     always @(posedge clk or negedge rst_n)begin

  66.         if(!rst_n)begin

  67.             wr_cnt <= 0;

  68.         end

  69.         else if(add_wr_cnt)begin

  70.             if(end_wr_cnt)

  71.                 wr_cnt <= 0;

  72.             else

  73.                 wr_cnt <= wr_cnt + 1;

  74.         end

  75.     end


  76.     assign add_wr_cnt = state_c==S_WRITE && rdy;

  77.     assign end_wr_cnt = add_wr_cnt && wr_cnt == WR_NUM-1 ;



  78.     always @(posedge clk or negedge rst_n)begin

  79.         if(!rst_n)begin

  80.             rd_cnt <= 0;

  81.         end

  82.         else if(add_rd_cnt)begin

  83.             if(end_rd_cnt)

  84.                 rd_cnt <= 0;

  85.             else

  86.                 rd_cnt <= rd_cnt + 1;

  87.         end

  88.     end


  89.     assign add_rd_cnt = state_c==S_READ && crc_dout_vld;

  90.     assign end_rd_cnt = add_rd_cnt && rd_cnt == RD_NUM-1 ;



  91.     assign start_read = state_c==S_READ && flag_wait_crc==0 && rdy;


  92.     always  @(posedge clk or negedge rst_n)begin

  93.         if(rst_n==1'b0)begin

  94.             flag_wait_crc <= 0;

  95.         end

  96.         else if(start_read)begin

  97.             flag_wait_crc <= 1;

  98.         end

  99.         else if(crc_dout_vld)begin

  100.             flag_wait_crc <= 0;

  101.         end

  102.     end


  103.     always  @(posedge clk or negedge rst_n)begin

  104.         if(rst_n==1'b0)begin

  105.             mode <= EWEN;

  106.         end

  107.         else if(state_c==S_EWEN) begin

  108.             mode <= EWEN;

  109.         end

  110.         else if(state_c==S_WRITE)begin

  111.             mode <= WRITE;

  112.         end

  113.         else if(state_c==S_READ)begin

  114.             mode <= READ;

  115.         end

  116.     end




  117.     always  @(posedge clk or negedge rst_n)begin

  118.         if(rst_n==1'b0)begin

  119.             crc_din <= 0;

  120.         end

  121.         else if(add_wr_cnt && end_wr_cnt==0) begin

  122.             crc_din <= din[8*(D_LEN-wr_cnt)-1 -:8];

  123.         end

  124.         else begin

  125.             crc_din <= rdata;

  126.         end

  127.     end


  128.     always  @(posedge clk or negedge rst_n)begin

  129.         if(rst_n==1'b0)begin

  130.             crc_din_vld <= 1'b0;

  131.         end

  132.         else if(add_wr_cnt && end_wr_cnt==0) begin

  133.             crc_din_vld <= 1'b1;

  134.         end

  135.         else begin

  136.             crc_din_vld <= rdata_vld;

  137.         end

  138.     end


  139.     always  @(posedge clk or negedge rst_n)begin

  140.         if(rst_n==1'b0)begin

  141.             crc_clr <= 1'b0;

  142.         end

  143.         else if((add_rd_cnt && rd_cnt==4-1)|| read2idle_start || write2idle_start) begin

  144.             crc_clr <= 1'b1;

  145.         end

  146.         else begin

  147.             crc_clr <= 1'b0;

  148.         end

  149.     end


  150.     always  @(posedge clk or negedge rst_n)begin

  151.         if(rst_n==1'b0)begin

  152.             addr <= 0;

  153.         end

  154.         else if(state_c==S_WRITE) begin

  155.             addr <= {4'b0,write_sel,wr_cnt[1:0]};

  156.         end

  157.         else if(state_c==S_EWEN) begin

  158.             addr <= 7'b1100000;

  159.         end

  160.         else begin

  161.             addr <= {4'b0,rd_cnt};

  162.         end

  163.     end


  164.     always  @(posedge clk or negedge rst_n)begin

  165.         if(rst_n==1'b0)begin

  166.             write_sel <= 1'b0;

  167.         end

  168.         else if(write2idle_start) begin

  169.             write_sel <= ~write_sel;

  170.         end

  171.     end


  172.   



  173.     always  @(posedge clk or negedge rst_n)begin

  174.         if(rst_n==1'b0)begin

  175.             wdata <= 0;

  176.         end

  177.         else if(wr_cnt==WR_NUM-1) begin

  178.             wdata <= crc_dout;

  179.         end

  180.         else begin

  181.             wdata <= din[8*(D_LEN-wr_cnt)-1 -:8];

  182.         end

  183.     end


  184.     always  @(posedge clk or negedge rst_n)begin

  185.         if(rst_n==1'b0)begin

  186.             start <= 1'b0;

  187.         end

  188.         else if(add_wr_cnt || start_read || ewen2read_start)begin

  189.             start <= 1'b1;

  190.         end

  191.         else begin

  192.             start <= 1'b0;

  193.         end

  194.     end


  195.     always  @(posedge clk or negedge rst_n)begin

  196.         if(rst_n==1'b0)begin

  197.             dout_temp<= 0;

  198.         end

  199.         else if(rdata_vld) begin

  200.             dout_temp[(8-rd_cnt)*8-1 -:8] <= rdata;

  201.         end

  202.     end


  203.     always  @(posedge clk or negedge rst_n)begin

  204.         if(rst_n==1'b0)begin

  205.             dout0_err <= 1'b0;

  206.         end

  207.         else if(add_rd_cnt && rd_cnt==4-1) begin

  208.             if(crc_dout!=0)

  209.                 dout0_err <= 1'b1;

  210.             else

  211.                 dout0_err <= 1'b0;

  212.         end

  213.     end


  214.     always  @(*)begin

  215.         if(crc_dout!=0)

  216.             dout1_err = 1'b1;

  217.         else

  218.             dout1_err = 1'b0;

  219.     end



  220.     assign dout0_temp = dout_temp[8*8-1 -:24];

  221.     assign dout1_temp = dout_temp[4*8-1 -:24];




  222.    

  223.     always  @(posedge clk or negedge rst_n)begin

  224.         if(rst_n==1'b0)begin

  225.             dout <= 0;

  226.         end

  227.         else if(end_rd_cnt) begin

  228.             if(dout0_err==1'b0 && dout1_err==1'b0)begin

  229.                 if(dout0_temp > dout1_temp)

  230.                     dout <= dout0_temp;

  231.                 else

  232.                     dout <= dout1_temp;

  233.             end

  234.             else if(dout0_err==1'b0)begin

  235.                 dout <= dout0_temp;

  236.             end

  237.             else begin

  238.                 dout <= dout1_temp;

  239.             end

  240.         end

  241.     end



  242.     always  @(posedge clk or negedge rst_n)begin

  243.         if(rst_n==1'b0)begin

  244.             dout_vld <= 1'b0;

  245.         end

  246.         else if(end_rd_cnt) begin

  247.             if(dout0_err && dout1_err)begin

  248.                 dout_vld <= 1'b0;

  249.             end

  250.             else begin

  251.                 dout_vld <= 1'b1;

  252.             end

  253.         end

  254.         else begin

  255.             dout_vld <= 1'b0;

  256.         end

  257.     end



  258.    crc8_d8 u_crc8_d8(

  259.               .clk      (clk          ),

  260.               .rst_n    (rst_n        ),

  261.               .clr      (crc_clr      ),

  262.               .din_vld  (crc_din_vld  ),

  263.               .din      (crc_din      ),

  264.               .dout_vld (crc_dout_vld ),

  265.               .dout     (crc_dout     )      

  266.     );


複制代(dài)碼


1.6 CRC处理模块(kuài)設計(jì)


1.6.1接口(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)
Clr
輸入(rù)
清(qīng)零(líng)信(xìn)号(hào),将當前(qián)的(de)CRC運算複位,重(zhòng)新開(kāi)始新的(de)運算。
din_vld
輸入(rù)
CRC輸入(rù)數據(jù)有(yǒu)效信(xìn)号(hào)
din
輸入(rù)
CRC運算輸入(rù)的(de)數據(jù)
dout
輸出(chū)
CRC運算結果(guǒ)
dout_vld
輸出(chū)
CRC輸出(chū)有(yǒu)效指示信(xìn)号(hào)


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

該模块(kuài)主(zhǔ)要(yào)的(de)作用(yòng)是(shì)負責CRC運算,在(zài)數據(jù)处理模块(kuài)內(nèi)部(bù)使用(yòng),多(duō)項式为(wèi) ,本(běn)模块(kuài)代(dài)碼不(bù)需要(yào)設計(jì),使用(yòng)网(wǎng)上(shàng)的(de)生(shēng)成(chéng)工具(https://www.easics.com/crctool/
),輸入(rù)多(duō)項式即可(kě)生(shēng)成(chéng),具體(tǐ)設置請看(kàn)下(xià)图(tú)。



關(guān)于(yú)CRC的(de)原理和(hé)并行、串行实現(xiàn)的(de)方(fāng)法,有(yǒu)另(lìng)外(wài)的(de)視頻進(jìn)行講解(jiě),这(zhè)里(lǐ)不(bù)在(zài)進(jìn)行介紹。

1.6.3參考代(dài)碼

  1.     assign d   =    din    ;

  2.     assign c   =    dout   ;



  3.     always  @(posedge clk or negedge rst_n)begin

  4.         if(rst_n==1'b0)begin

  5.             dout <= 0;

  6.         end

  7.         else if(clr)begin

  8.             dout <= 0;

  9.         end

  10.         else if(din_vld) begin

  11.             dout[0] <= d[7] ^ d[6] ^ d[0] ^ c[0] ^ c[6] ^ c[7];

  12.             dout[1] <= d[6] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[6];

  13.             dout[2] <= d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[2] ^ c[6];

  14.             dout[3] <= d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[1] ^ c[2] ^ c[3] ^ c[7];

  15.             dout[4] <= d[4] ^ d[3] ^ d[2] ^ c[2] ^ c[3] ^ c[4];

  16.             dout[5] <= d[5] ^ d[4] ^ d[3] ^ c[3] ^ c[4] ^ c[5];

  17.             dout[6] <= d[6] ^ d[5] ^ d[4] ^ c[4] ^ c[5] ^ c[6];

  18.             dout[7] <= d[7] ^ d[6] ^ d[5] ^ c[5] ^ c[6] ^ c[7];

  19.         end

  20.     end


  21.     always  @(posedge clk or negedge rst_n)begin

  22.         if(rst_n==1'b0)begin

  23.             dout_vld <= 0;

  24.         end

  25.         else begin

  26.             dout_vld <= din_vld;

  27.         end

  28.     end


  29. endmodul

複制代(dài)碼


1.7 AT93C46接口(kǒu)模块(kuài)設計(jì)


1.7.1接口(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)
addr
輸入(rù)
地(dì)址信(xìn)号(hào),在(zài)start有(yǒu)效时(shí),此(cǐ)值有(yǒu)效
Wdata
輸入(rù)
写數據(jù)信(xìn)号(hào),在(zài)start有(yǒu)效时(shí),此(cǐ)值有(yǒu)效
start
輸入(rù)
開(kāi)始命令,僅在(zài)rdy=1时(shí)才有(yǒu)效
mode
輸出(chū)
操作模式指示信(xìn)号(hào),start有(yǒu)效时(shí),此(cǐ)值有(yǒu)效
rdy
輸入(rù)
準備好(hǎo)信(xìn)号(hào)。當rdy为(wèi)1时(shí),start才有(yǒu)效。在(zài)rdy为(wèi)0时(shí),不(bù)能(néng)使start有(yǒu)效
rdata
輸入(rù)
從AT93C46读(dú)取(qǔ)的(de)數據(jù)
rdata_vld
輸出(chū)
從AT93C46读(dú)到(dào)的(de)數據(jù)有(yǒu)效指示信(xìn)号(hào)
do
輸出(chū)
AT93C46數據(jù)輸出(chū)
di
輸出(chū)
AT93C46數據(jù)輸入(rù)
cs
輸出(chū)
AT93C46片(piàn)選信(xìn)号(hào)
sk
輸出(chū)
AT93C46时(shí)鐘(zhōng),200KHz


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

參考數據(jù)手(shǒu)册,本(běn)模块(kuài)主(zhǔ)要(yào)实現(xiàn)三(sān)个(gè)命令:打(dǎ)開(kāi)写保護(EWEN)、读(dú)數據(jù)(READ)和(hé)写數據(jù)(WRITE)。


下(xià)面(miàn)时(shí)EWEN命令的(de)时(shí)序图(tú),結合上(shàng)文(wén)提(tí)到(dào)的(de)AT93C46的(de)指令集,打(dǎ)開(kāi)写保護指令的(de)时(shí)序應(yìng)該是(shì)写10bit數據(jù)之後(hòu),等待TCS时(shí)間(jiān),然後(hòu)結束(shù)。


下(xià)面(miàn)是(shì)READ命令的(de)时(shí)序图(tú)。結合上(shàng)文(wén)提(tí)到(dào)的(de)AT93C46的(de)指令集,读(dú)數據(jù)命令对(duì)應(yìng)的(de)时(shí)序應(yìng)該是(shì)写10bit數據(jù)鐘(zhōng)後(hòu),读(dú)8bit數據(jù),等待TCS时(shí)間(jiān),然後(hòu)結束(shù)。



下(xià)面(miàn)是(shì)WRITE命令的(de)时(shí)序图(tú)。結合上(shàng)文(wén)提(tí)到(dào)的(de)AT93C46的(de)指令集,写數據(jù)命令对(duì)應(yìng)的(de)时(shí)序應(yìng)該是(shì)写18bit數據(jù),cs拉低TCS时(shí)間(jiān),等待TWP5ms)时(shí)間(jiān),然後(hòu)結束(shù)。



根(gēn)據(jù)上(shàng)述的(de)时(shí)序介紹,本(běn)模块(kuài)采用(yòng)3个(gè)計(jì)數器的(de)架構,下(xià)面(miàn)是(shì)計(jì)數器的(de)架構图(tú)。



架構中(zhōng)的(de)三(sān)个(gè)計(jì)數器分(fēn)别为(wèi)时(shí)鐘(zhōng)計(jì)數器cnt0、比特(tè)計(jì)數器cnt1和(hé)階(jiē)段(duàn)計(jì)數器cnt2flag_work为(wèi)工作狀态指示信(xìn)号(hào)。


时(shí)鐘(zhōng)計(jì)數器cnt0:該計(jì)數器用(yòng)来(lái)計(jì)數时(shí)鐘(zhōng)的(de)个(gè)數。加一(yī)条(tiáo)件(jiàn)为(wèi)flag_work,表(biǎo)示進(jìn)入(rù)工作狀态就(jiù)開(kāi)始計(jì)數。結束(shù)条(tiáo)件(jiàn)为(wèi)數x个(gè),根(gēn)據(jù)不(bù)同(tóng)的(de)工作模式和(hé)所(suǒ)处的(de)階(jiē)段(duàn)不(bù)同(tóng)而(ér)變(biàn)化(huà)。包(bāo)括SK的(de)时(shí)鐘(zhōng)周期(qī)數、等待时(shí)間(jiān)TCS、等待5ms时(shí)間(jiān)。


比特(tè)計(jì)數器cnt1:該計(jì)數器用(yòng)来(lái)數有(yǒu)多(duō)少(shǎo)bit數據(jù),加一(yī)条(tiáo)件(jiàn)为(wèi)end_cnt0,表(biǎo)示每數完1bit,就(jiù)加1;結束(shù)条(tiáo)件(jiàn)为(wèi)數y个(gè),y分(fēn)别为(wèi)10EWEN)、18READ和(hé)WRITE)、1(等待TCS和(hé)5ms)。


階(jiē)段(duàn)計(jì)數器cnt2:該計(jì)數器用(yòng)来(lái)对(duì)每个(gè)指令需要(yào)的(de)階(jiē)段(duàn)進(jìn)行計(jì)數。加一(yī)条(tiáo)件(jiàn)为(wèi)end_cnt1,表(biǎo)示發(fà)送完一(yī)組數據(jù)就(jiù)加一(yī);結束(shù)条(tiáo)件(jiàn)为(wèi)數u个(gè),u分(fēn)别为(wèi)2EWEN和(hé)READ)、3WRITE)。


除了(le)上(shàng)述的(de)計(jì)數器之外(wài),還(huán)有(yǒu)一(yī)些比較重(zhòng)要(yào)的(de)信(xìn)号(hào),我(wǒ)们(men)来(lái)分(fēn)析一(yī)下(xià)如(rú)何進(jìn)行設計(jì)。


工作狀态指示信(xìn)号(hào)flag_work:初始狀态为(wèi)0,表(biǎo)示处于(yú)空閑狀态;當收(shōu)到(dào)開(kāi)始命令start的(de)时(shí)候,變(biàn)化(huà)變(biàn)为(wèi)1,由(yóu)空閑狀态轉(zhuǎn)为(wèi)工作狀态;當前(qián)指令的(de)时(shí)序結束(shù)之後(hòu),也(yě)就(jiù)是(shì)階(jiē)段(duàn)計(jì)數器cnt2數完,就(jiù)變(biàn)为(wèi)0,進(jìn)入(rù)空閑狀态。


待發(fà)送數據(jù)dout:當接收(shōu)到(dào)開(kāi)始命令的(de)时(shí)候,根(gēn)據(jù)AT93C46的(de)指令集,将SBOpcodeAddress和(hé)data按照順序拼接到(dào)一(yī)起。


模式暫存器mode_reg:为(wèi)保證在(zài)發(fà)送时(shí)序期(qī)間(jiān)保持(chí)不(bù)變(biàn),在(zài)接收(shōu)到(dào)開(kāi)始命令的(de)时(shí)候,将操作模式指示信(xìn)号(hào)進(jìn)行暫存。


AT93C46时(shí)鐘(zhōng)sk:时(shí)鐘(zhōng)頻率为(wèi)200KHz,工程的(de)系(xì)統时(shí)鐘(zhōng)为(wèi)50MHz,因(yīn)此(cǐ)sk一(yī)个(gè)完整的(de)周期(qī)需要(yào)250个(gè)系(xì)統时(shí)鐘(zhōng)周期(qī),初始狀态設为(wèi)低電(diàn)平,當时(shí)鐘(zhōng)計(jì)數器數到(dào)125个(gè)的(de)时(shí)候置为(wèi)高(gāo)電(diàn)平,时(shí)鐘(zhōng)計(jì)數器數完,在(zài)置为(wèi)低電(diàn)平。


AT93C46數據(jù)輸入(rù)di:在(zài)每个(gè)指令时(shí)序的(de)第(dì)一(yī)階(jiē)段(duàn),也(yě)就(jiù)是(shì)cnt2=1-1的(de)时(shí)候,根(gēn)據(jù)比特(tè)計(jì)數器要(yào)數的(de)个(gè)數,将待發(fà)送的(de)數據(jù)dout送給(gěi)di


AT93C46片(piàn)選信(xìn)号(hào)cs:在(zài)写比特(tè)數據(jù)、等待5ms期(qī)間(jiān)为(wèi)高(gāo),其他(tā)时(shí)候都为(wèi)低,所(suǒ)以(yǐ)該信(xìn)号(hào)拉高(gāo)的(de)条(tiáo)件(jiàn)为(wèi)(start_vld==1 || (add_cnt2 && cnt2==2-1 &&end_cnt2==0))。其他(tā)时(shí)候片(piàn)選信(xìn)号(hào)都为(wèi)低,所(suǒ)以(yǐ)拉低的(de)条(tiáo)件(jiàn)为(wèi)((add_cnt2&& cnt2==1-1) || end_cnt2)


读(dú)取(qǔ)數據(jù)rdata:在(zài)读(dú)模式下(xià),处于(yú)第(dì)一(yī)階(jiē)段(duàn),并且在(zài)第(dì)11~18bit的(de)时(shí)候,将AT93C46輸出(chū)數據(jù)do保存到(dào)rdata里(lǐ)面(miàn)。


準備好(hǎo)信(xìn)号(hào)rdy:由(yóu)組合邏輯産生(shēng),當接收(shōu)到(dào)開(kāi)始命令,或(huò)者(zhě)处于(yú)工作狀态的(de)时(shí)候,为(wèi)低電(diàn)平,表(biǎo)示沒(méi)有(yǒu)準備好(hǎo);其他(tā)时(shí)刻为(wèi)高(gāo)電(diàn)平,表(biǎo)示準備好(hǎo)。


1.7.3參考代(dài)碼

  1.     assign start_vld = flag_work==0 && start;


  2.     always  @(*)begin

  3.         if(mode==EWEN)

  4.             opcode = 3'b100;

  5.         else if(mode==WRITE)

  6.             opcode = 3'b101;

  7.         else

  8.             opcode = 3'b110;

  9.     end


  10.     always  @(posedge clk or negedge rst_n)begin

  11.         if(rst_n==1'b0)begin

  12.             dout <= 0;

  13.         end

  14.         else if(start_vld) begin

  15.             dout <={opcode,addr,wdata};

  16.         end

  17.     end



  18.     always  @(posedge clk or negedge rst_n)begin

  19.         if(rst_n==1'b0)begin

  20.             mode_reg <= 0;

  21.         end

  22.         else if(start_vld) begin

  23.             mode_reg <= mode;

  24.         end

  25.     end


  26.     always  @(posedge clk or negedge rst_n)begin

  27.         if(rst_n==1'b0)begin

  28.             flag_work <= 0;

  29.         end

  30.         else if(start_vld) begin

  31.             flag_work <= 1;

  32.         end

  33.         else if(end_cnt2)begin

  34.             flag_work <= 0;

  35.         end

  36.     end



  37.    

  38.     always @(posedge clk or negedge rst_n)begin

  39.         if(!rst_n)begin

  40.             cnt0 <= 0;

  41.         end

  42.         else if(add_cnt0)begin

  43.             if(end_cnt0)

  44.                 cnt0 <= 0;

  45.             else

  46.                 cnt0 <= cnt0 + 1;

  47.         end

  48.     end


  49.     assign add_cnt0 = flag_work;      

  50.     assign end_cnt0 = add_cnt0 && cnt0== x-1;   


  51.     always @(posedge clk or negedge rst_n)begin

  52.         if(!rst_n)begin

  53.             cnt1 <= 0;

  54.         end

  55.         else if(add_cnt1)begin

  56.             if(end_cnt1)

  57.                 cnt1 <= 0;

  58.             else

  59.                 cnt1 <= cnt1 + 1;

  60.         end

  61.     end


  62.     assign add_cnt1 = end_cnt0;      

  63.     assign end_cnt1 = add_cnt1 && cnt1==y-1 ;



  64.     always @(posedge clk or negedge rst_n)begin

  65.         if(!rst_n)begin

  66.              cnt2 <= 0;

  67.          end

  68.          else if(add_cnt2)begin

  69.              if(end_cnt2)

  70.                   cnt2 <= 0;

  71.              else

  72.                   cnt2 <= cnt2 + 1;

  73.           end

  74.     end

  75.    

  76.     assign add_cnt2 = end_cnt1;      

  77.     assign end_cnt2 = add_cnt2 && cnt2==u-1;   



  78.     assign en_sk1 = add_cnt0 && cnt0==x/2-1 && cnt2==1-1;

  79.     assign en_sk0 = end_cnt0                            ;

  80.     always  @(posedge clk or negedge rst_n)begin

  81.         if(rst_n==1'b0)begin

  82.             sk <= 0;

  83.         end

  84.         else if(add_cnt0 && cnt0==x/2-1 && cnt2==1-1)begin

  85.             sk <= 1;

  86.         end

  87.         else if(end_cnt0)begin

  88.             sk <= 0;

  89.         end

  90.     end


  91.     assign en_di = add_cnt0 && cnt0==1-1 && cnt2==1-1;


  92.     always  @(posedge clk or negedge rst_n)begin

  93.         if(rst_n==1'b0)begin

  94.             di <= 0;

  95.         end

  96.         else if(en_di) begin

  97.             di <= dout[17-cnt1];

  98.         end

  99.     end



  100.     always  @(posedge clk or negedge rst_n)begin

  101.         if(rst_n==1'b0)begin

  102.             cs <= 0;

  103.         end

  104.         else if(start_vld==1 || (add_cnt2 && cnt2==2-1 && end_cnt2==0)) begin

  105.             cs <= 1;

  106.         end

  107.         else if((add_cnt2 && cnt2==1-1) || end_cnt2)begin

  108.             cs <= 0;

  109.         end

  110.     end



  111.     always  @(posedge clk or negedge rst_n)begin

  112.         if(rst_n==1'b0)begin

  113.             rdata <= 0;

  114.         end

  115.         else if(end_cnt0 && cnt1 >=10 && cnt2==1-1 && mode_reg==READ ) begin

  116.             rdata[17-cnt1] <= do;

  117.         end

  118.     end


  119.     always  @(posedge clk or negedge rst_n)begin

  120.         if(rst_n==1'b0)begin

  121.             rdata_vld <= 0;

  122.         end

  123.         else begin

  124.             rdata_vld <= end_cnt2 && mode_reg==READ;

  125.         end

  126.     end


  127.     always  @(*)begin

  128.         if(start || flag_work)

  129.             rdy = 1'b0;

  130.         else

  131.             rdy = 1'b1;

  132.     end



  133.     always  @(*)begin

  134.         if(mode_reg==WRITE && cnt2==1-1)begin

  135.             x = 250;

  136.             y =  18;

  137.             u =   3;  

  138.         end

  139.         else if(mode_reg==WRITE && (cnt2==2-1 ))begin

  140.             x = 250 ;

  141.             y =   1 ;

  142.             u =   3 ;  

  143.         end

  144.         else if(mode_reg==WRITE && cnt2==3-1)begin

  145.             x = 500000;  

  146.             y =   1 ;

  147.             u =   3 ;  

  148.         end

  149.         else if(mode_reg==READ && cnt2==1-1)begin

  150.             x = 250;

  151.             y =  18;

  152.             u =   2;  

  153.         end

  154.         else if(mode_reg==READ && cnt2==2-1)begin

  155.             x = 250 ;

  156.             y =   1 ;

  157.             u =   2 ;  

  158.         end

  159.         else if(mode_reg==EWEN && cnt2==1-1)begin

  160.             x = 250;

  161.             y =  10;

  162.             u =   2;  

  163.         end

  164.         else begin

  165.             x = 250 ;  

  166.             y =   1 ;

  167.             u =   2 ;  

  168.         end

  169.     end



  170. endmodul

複制代(dài)碼


1.8 效果(guǒ)和(hé)總(zǒng)結

本(běn)工程上(shàng)板之後(hòu),可(kě)通(tòng)过(guò)複位来(lái)验(yàn)證現(xiàn)象(xiàng),若要(yào)通(tòng)过(guò)斷電(diàn)来(lái)進(jìn)行验(yàn)證,需要(yào)将工程燒录(lù)進(jìn)開(kāi)發(fà)板才行。


1.8.1db603開(kāi)發(fà)板

由(yóu)于(yú)本(běn)工程現(xiàn)象(xiàng)是(shì)一(yī)个(gè)動(dòng)态的(de)过(guò)程,所(suǒ)以(yǐ)從下(xià)面(miàn)图(tú)片(piàn)中(zhōng)看(kàn)不(bù)出(chū)具體(tǐ)实現(xiàn)的(de)效果(guǒ),想(xiǎng)要(yào)看(kàn)上(shàng)板效果(guǒ)的(de)話(huà)可(kě)以(yǐ)看(kàn)一(yī)下(xià)工程上(shàng)板的(de)視頻。



1.8.2mp801開(kāi)發(fà)板

由(yóu)于(yú)本(běn)工程現(xiàn)象(xiàng)是(shì)一(yī)个(gè)動(dòng)态的(de)过(guò)程,所(suǒ)以(yǐ)從下(xià)面(miàn)图(tú)片(piàn)中(zhōng)看(kàn)不(bù)出(chū)具體(tǐ)实現(xiàn)的(de)效果(guǒ),想(xiǎng)要(yào)看(kàn)上(shàng)板效果(guǒ)的(de)話(huà)可(kě)以(yǐ)看(kàn)一(yī)下(xià)工程上(shàng)板的(de)視頻。





1.8.3ms980試验(yàn)箱

由(yóu)于(yú)本(běn)工程現(xiàn)象(xiàng)是(shì)一(yī)个(gè)動(dòng)态的(de)过(guò)程,所(suǒ)以(yǐ)從下(xià)面(miàn)图(tú)片(piàn)中(zhōng)看(kàn)不(bù)出(chū)具體(tǐ)实現(xiàn)的(de)效果(guǒ),想(xiǎng)要(yào)看(kàn)上(shàng)板效果(guǒ)的(de)話(huà)可(kě)以(yǐ)看(kàn)一(yī)下(xià)工程上(shàng)板的(de)視頻。



詳细(xì)的(de)設計(jì)視頻教程和(hé)工程源碼請到(dào)明(míng)德揚論壇学習!

MDY最(zuì)新推出(chū)《FPGA至(zhì)簡設計(jì)案(àn)例200例》項目,每周固定(dìng)更(gèng)新至(zhì)少(shǎo)1个(gè)案(àn)例,可(kě)到(dào)明(míng)德揚論壇www.fpgabbs.cn下(xià)载学習



温(wēn)馨提(tí)示:明(míng)德揚2023推出(chū)了(le)全(quán)新課程——邏輯設計(jì)基本(běn)功修煉課,降低学習FPGA門(mén)檻的(de)同(tóng)时(shí),增加了(le)学習的(de)趣味性(xìng),并組織了(le)考試赢積分(fēn)活動(dòng)

http://www.minyingyiyuan.com/ffkc/415.html

(點(diǎn)擊→了(le)解(jiě)課程詳情(qíng)☝)感(gǎn)興趣請聯系(xì)易老(lǎo)师(shī):13112063618(微信(xìn)同(tóng)步)



本(běn)文(wén)TAG:

Copyright © 2012-2023 版權所(suǒ)有(yǒu):深圳明(míng)德揚科技教育有(yǒu)限公司

粵ICP備17036451号(hào) 穗公网(wǎng)安(ān)備:44010650010086

⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ 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⁥⁠⁢

⁧⁨⁥⁨