⁩⁣⁩⁨ ⁩⁤⁢⁢⁢⁥⁩ ⁥⁣⁦⁡ ⁣⁤⁨ ⁡⁨⁠⁤⁠ ⁦⁧⁡⁤⁣⁡⁡⁨⁤ 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)例】 簡易計(jì)算器

發(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 概述

計(jì)算器是(shì)近(jìn)代(dài)人(rén)發(fà)明(míng)的(de)可(kě)以(yǐ)進(jìn)行數字(zì)運算的(de)機(jī)器。現(xiàn)代(dài)的(de)電(diàn)子計(jì)算器能(néng)進(jìn)行數学運算的(de)手(shǒu)持(chí)電(diàn)子機(jī)器,擁有(yǒu)集成(chéng)電(diàn)路(lù)芯片(piàn),但結構比電(diàn)腦簡單得多(duō),可(kě)以(yǐ)说(shuō)是(shì)第(dì)一(yī)代(dài)的(de)電(diàn)子計(jì)算機(jī),且功能(néng)也(yě)較弱(ruò),但較为(wèi)方(fāng)便與(yǔ)廉價,可(kě)廣泛運用(yòng)于(yú)商業交易中(zhōng),是(shì)必備的(de)辦(bàn)公用(yòng)品之一(yī)。除顯示計(jì)算結果(guǒ)外(wài),還(huán)常有(yǒu)溢出(chū)指示、錯誤指示等。計(jì)算器電(diàn)源采用(yòng)交流轉(zhuǎn)換器或(huò)電(diàn)池。为(wèi)了(le)节(jié)省(shěng)電(diàn)能(néng),計(jì)算器都采用(yòng)CMOS工藝制作的(de)大規模集成(chéng)電(diàn)路(lù)。

計(jì)算器一(yī)般由(yóu)運算器、控制器、存儲器、鍵盤、顯示器、電(diàn)源和(hé)一(yī)些可(kě)選外(wài)圍設備及(jí)電(diàn)子配件(jiàn),通(tòng)过(guò)人(rén)工或(huò)機(jī)器設備組成(chéng),抵挡計(jì)算器的(de)運算器、控制器由(yóu)數字(zì)邏輯電(diàn)路(lù)实現(xiàn)簡單的(de)串行運算
計(jì)算器是(shì)最(zuì)早(zǎo)的(de)計(jì)算工具,例如(rú):古代(dài)印(yìn)加人(rén)利用(yòng)许多(duō)顔色(sè)的(de)绳(shéng)結来(lái)計(jì)數或(huò)者(zhě)記(jì)录(lù)曆史,還(huán)有(yǒu)古希臘人(rén)的(de)安(ān)提(tí)凯希拉裝(zhuāng)置,中(zhōng)國(guó)的(de)算盤等。中(zhōng)國(guó)古代(dài)最(zuì)早(zǎo)采用(yòng)的(de)一(yī)種(zhǒng)計(jì)算工具叫籌策,又被(bèi)叫做算籌。

1.1.2 設計(jì)目标(biāo)
簡易計(jì)算器支持(chí)簡單的(de)四(sì)則運算(支持(chí)負數),在(zài)此(cǐ)基礎上(shàng),添加了(le)連(lián)續運算功能(néng)。計(jì)算器面(miàn)板如(rú)下(xià):

1、  計(jì)算器通(tòng)过(guò)矩阵(zhèn)鍵盤模拟按鍵輸入(rù),并通(tòng)过(guò)數碼管(guǎn)顯示。
2、  計(jì)算器有(yǒu)“0、1、2、3、4、5、6、7、8、9、+、-、*、/、C、=”共(gòng)16个(gè)按鍵。
3、  計(jì)算器不(bù)支持(chí)輸入(rù)負數,運算結果(guǒ)支持(chí)負數但不(bù)支持(chí)小數。
4、  運算數1、運算數2以(yǐ)及(jí)運算結果(guǒ)最(zuì)大支持(chí)8位。其中(zhōng),運算數1和(hé)運算結果(guǒ)的(de)位數包(bāo)括符号(hào)位“-”。
5、  運算數1和(hé)運算數2的(de)默認值为(wèi)0.
6、  計(jì)算器支持(chí)連(lián)續運算,允许在(zài)輸入(rù)運算數2後(hòu)按下(xià)運算符,或(huò)者(zhě)得出(chū)運算結果(guǒ)後(hòu)按下(xià)運算符。
7、  當運算結果(guǒ)溢出(chū)时(shí),數碼管(guǎn)顯示8个(gè)F。
8、  當操作數1或(huò)者(zhě)操作數2的(de)长度(dù)溢出(chū)时(shí),蜂鳴器会(huì)響。

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)鍵盤的(de)按鍵檢测功能(néng),并輸出(chū)有(yǒu)效按鍵信(xìn)号(hào)。


工作狀态選擇模块(kuài)实現(xiàn)功能(néng)

1、  根(gēn)據(jù)接收(shōu)的(de)不(bù)同(tóng)的(de)按鍵信(xìn)号(hào),判斷和(hé)決定(dìng)計(jì)算器的(de)工作狀态。共(gòng)有(yǒu)5種(zhǒng)狀态,輸入(rù)運算數1(OP_1)、運算符(OPER)、輸入(rù)運算數2(OP_2)、輸出(chū)結果(guǒ)(RESULT)、結果(guǒ)錯誤(ERROR)

Ø  運算數1模块(kuài)实現(xiàn)功能(néng)
1、  當計(jì)算器处于(yú)運算數1狀态下(xià),任何連(lián)續輸入(rù)的(de)數字(zì)(不(bù)超过(guò)8位)都将存放(fàng)在(zài)該模块(kuài)中(zhōng),作为(wèi)運算數1.
2、  當運算數已經(jīng)到(dào)达(dá)8位时(shí),此(cǐ)时(shí)无論輸入(rù)任何數字(zì),運算數1不(bù)變(biàn)。
3、  當計(jì)算器經(jīng)过(guò)一(yī)次(cì)運算後(hòu)(按下(xià)等号(hào)或(huò)者(zhě)在(zài)運算數2狀态下(xià)按下(xià)運算符),運算數去(qù)存放(fàng)結果(guǒ)result。

Ø  運算符模块(kuài)实現(xiàn)功能(néng)
1、  保存最(zuì)新按下(xià)的(de)運算符。

Ø  運算數2模块(kuài)实現(xiàn)功能(néng)
1、  當計(jì)算器处于(yú)運算數2狀态下(xià),任何連(lián)續輸入(rù)的(de)數字(zì)(不(bù)超过(guò)8位)都将存放(fàng)在(zài)該模块(kuài)中(zhōng),作为(wèi)運算數2,默認值为(wèi)0。
2、  當運算數2已經(jīng)到(dào)达(dá)8(包(bāo)括符号(hào)位“-”),此(cǐ)时(shí)无論輸入(rù)任何數字(zì),運算數2不(bù)變(biàn)。

Ø  運算單元(yuán)模块(kuài)实現(xiàn)功能(néng)
1、  當計(jì)算器处于(yú)運算數2狀态下(xià)按下(xià)運算符或(huò)者(zhě)在(zài)任何狀态下(xià)按下(xià)等号(hào)时(shí),該模块(kuài)根(gēn)據(jù)此(cǐ)时(shí)運算數1、運算數2以(yǐ)及(jí)運算符的(de)值,進(jìn)行運算。
2、  若運算結果(guǒ)溢出(chū),或(huò)者(zhě)长度(dù)大于(yú)8位(包(bāo)括符号(hào)位“-”)或(huò)者(zhě)除數为(wèi)0时(shí),輸出(chū)8个(gè)F。
3、  最(zuì)多(duō)保留運算結果(guǒ)整數部(bù)分(fēn)的(de)8个(gè)有(yǒu)效數字(zì),不(bù)保留任何小數。

Ø  顯示对(duì)象(xiàng)選則模块(kuài)实現(xiàn)功能(néng)
1、  該模块(kuài)的(de)作用(yòng)是(shì)根(gēn)據(jù)當前(qián)計(jì)算器的(de)工作狀态来(lái)選擇數碼管(guǎn)的(de)顯示內(nèi)容。

Ø  數碼管(guǎn)顯示模块(kuài)实現(xiàn)功能(néng)
1、  該模块(kuài)的(de)作用(yòng)是(shì)对(duì)顯示对(duì)象(xiàng)選擇模块(kuài)的(de)顯示數據(jù)輸出(chū)信(xìn)号(hào)進(jìn)行數碼管(guǎn)顯示。

Ø  蜂鳴器模块(kuài)实現(xiàn)功能(néng)
1、  該模块(kuài)的(de)作用(yòng)是(shì)对(duì)各(gè)種(zhǒng)錯誤輸入(rù)或(huò)輸出(chū)進(jìn)行響鈴警告。

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)
Segment
輸出(chū)
8位數碼管(guǎn)段(duàn)選信(xìn)号(hào)
Seg_sel
輸出(chū)
8位數碼管(guǎn)位選信(xìn)号(hào)
beep
輸出(chū)
1位蜂鳴器控制信(xìn)号(hào)

1.1.6參考代(dài)碼
  1. module  calc_project(
  2.     clk     ,
  3.     rst_n   ,
  4.     key_col ,
  5.     key_row ,
  6.     seg_sel ,
  7.     segment ,
  8.     beep   
  9.     );

  10.     parameter   KEY_WID     =   4   ;
  11.     parameter   STATE_WID   =   5   ;
  12.     parameter   NUM_WID     =   27  ;
  13.     parameter   SEG_NUM     =   8   ;
  14.     parameter   SEG_WID     =   8   ;

  15.     input                       clk         ;
  16.     input                       rst_n       ;
  17.     input   [KEY_WID-1:0]       key_col     ;
  18.     output  [KEY_WID-1:0]       key_row     ;
  19.     output  [SEG_NUM-1:0]       seg_sel     ;
  20.     output  [SEG_WID-1:0]       segment     ;
  21.     output                      beep        ;

  22.     wire    [KEY_WID-1:0]       key_num     ;
  23.     wire                        key_vld     ;
  24.     wire    [KEY_WID-1:0]       key_num_out ;
  25.     wire    [KEY_WID-1:0]       key_vld_out ;
  26.     wire    [STATE_WID-1:0]     state_c     ;
  27.     wire    [NUM_WID-1:0]       op_1        ;
  28.     wire                        op_1_err    ;
  29.     wire    [KEY_WID-1:0]       oper        ;
  30.     wire    [NUM_WID-1:0]       op_2        ;
  31.     wire                        op_2_err    ;
  32.     wire    [NUM_WID-1:0]       result      ;
  33.     wire                        result_err  ;
  34.     wire                        result_neg  ;   
  35.     wire    [SEG_NUM*4-1:0]     display     ;
  36.     wire                        display_vld ;

  37.     key_scan   key_scan_prj(
  38.                             .clk        (clk    )   ,
  39.                             .rst_n      (rst_n  )   ,
  40.                             .key_col    (key_col)   ,
  41.                             .key_row    (key_row)   ,
  42.                             .key_out    (key_num)   ,
  43.                             .key_vld    (key_vld)
  44.                             );

  45.     work_state  work_state_prj(
  46.                                 .clk        (clk        )   ,
  47.                                 .rst_n      (rst_n      )   ,
  48.                                 .key_num    (key_num    )   ,
  49.                                 .key_vld    (key_vld    )   ,
  50.                                 .result_err (result_err )   ,
  51.                                 .key_num_out(key_num_out)   ,
  52.                                 .key_vld_out(key_vld_out)   ,
  53.                                 .state_c    (state_c    )
  54.                                 );

  55.     op_1    op_1_prj(
  56.                         .clk        (clk        )   ,
  57.                         .rst_n      (rst_n      )   ,
  58.                         .key_num    (key_num_out)   ,
  59.                         .key_vld    (key_vld_out)   ,
  60.                         .state_c    (state_c    )   ,
  61.                         .result     (result     )   ,
  62.                         .op_1       (op_1       )   ,
  63.                         .op_1_err   (op_1_err   )
  64.                     );

  65.     oper    oper_prj(
  66.                         .clk        (clk        )   ,
  67.                         .rst_n      (rst_n      )   ,
  68.                         .key_num    (key_num_out)   ,
  69.                         .key_vld    (key_vld_out)   ,
  70.                         .state_c    (state_c    )   ,
  71.                         .oper       (oper       )
  72.                     );
  73.    
  74.     op_2    op_2_prj(
  75.                         .clk        (clk        )   ,
  76.                         .rst_n      (rst_n      )   ,
  77.                         .key_num    (key_num_out)   ,
  78.                         .key_vld    (key_vld_out)   ,
  79.                         .state_c    (state_c    )   ,
  80.                         .op_2       (op_2       )   ,
  81.                         .op_2_err   (op_2_err   )
  82.                     );

  83.     result  result_prj(
  84.                         .clk        (clk        )   ,
  85.                         .rst_n      (rst_n      )   ,
  86.                         .key_num    (key_num_out)   ,
  87.                         .key_vld    (key_vld_out)   ,
  88.                         .state_c    (state_c    )   ,
  89.                         .op_1       (op_1       )   ,
  90.                         .oper       (oper       )   ,
  91.                         .op_2       (op_2       )   ,
  92.                         .result     (result     )   ,
  93.                         .result_err (result_err )   ,
  94.                         .result_neg (result_neg )
  95.                     );

  96.     display_sel  display_sel_prj(
  97.                                 .clk        (clk        )   ,
  98.                                 .rst_n      (rst_n      )   ,
  99.                                 .state_c    (state_c    )   ,
  100.                                 .op_1       (op_1       )   ,
  101.                                 .op_2       (op_2       )   ,
  102.                                 .result_neg (result_neg )   ,
  103.                                 .display    (display    )   ,
  104.                                 .display_vld(display_vld)
  105.                                 );

  106.     segment  segment_prj(
  107.                             .rst_n      (rst_n      )   ,
  108.                             .clk        (clk        )   ,
  109.                             .display    (display    )   ,
  110.                             .display_vld(display_vld)   ,
  111.                             .seg_sel    (seg_sel    )   ,
  112.                             .segment    (segment    )  
  113.                         );

  114.     beep    beep_prj(
  115.                         .clk        (clk        )   ,
  116.                         .rst_n      (rst_n      )   ,
  117.                         .op_1_err   (op_1_err   )   ,
  118.                         .op_2_err   (op_2_err   )   ,
  119.                         .result_err (result_err )   ,
  120.                         .beep       (beep       )
  121.                     );

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


1.2 鍵盤掃描模块(kuài)設計(jì)1.2.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)
key_col
輸入(rù)
矩阵(zhèn)鍵盤列輸入(rù)信(xìn)号(hào)
Key_row
輸出(chū)
矩阵(zhèn)鍵盤行輸出(chū)信(xìn)号(hào)
Key_out
輸出(chū)
按鍵位置輸出(chū)信(xìn)号(hào),key_vld有(yǒu)效时(shí),該信(xìn)号(hào)有(yǒu)效。
Key_vld
輸出(chū)
按鍵有(yǒu)效指示信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效


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

在(zài)前(qián)面(miàn)的(de)案(àn)例中(zhōng)已經(jīng)有(yǒu)矩阵(zhèn)鍵盤的(de)介紹,所(suǒ)以(yǐ)这(zhè)里(lǐ)不(bù)在(zài)过(guò)多(duō)介紹,詳细(xì)介紹請看(kàn)下(xià)方(fāng)鍊(liàn)接:
http://fpgabbs.com/forum.php?mod=viewthread&tid=310

1.2.3參考代(dài)碼
  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. always @(posedge clk or negedge rst_n) begin
  85.     if (rst_n==0) begin
  86.         row_index <= 0;
  87.     end
  88.     else if(add_row_index) begin
  89.         if(end_row_index)
  90.             row_index <= 0;
  91.         else
  92.             row_index <= row_index+1 ;
  93.    end
  94.    else if(state_c!=CHK_ROW)begin
  95.        row_index <= 0;
  96.    end
  97. end
  98. assign add_row_index = state_c==CHK_ROW && end_row_cnt;
  99. assign end_row_index = add_row_index  && row_index == 4-1 ;


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



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


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

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



1.3 工作狀态選擇模块(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)
key_vld
輸入(rù)
按鍵按下(xià)指示信(xìn)号(hào)
Key_num
輸入(rù)
按鍵位置輸入(rù)信(xìn)号(hào),key_vld有(yǒu)效时(shí),該信(xìn)号(hào)有(yǒu)效
Result_err
輸入(rù)
運算結果(guǒ)錯誤指示信(xìn)号(hào)
Key_num_out
輸出(chū)
計(jì)算器按下(xià)位置輸出(chū)信(xìn)号(hào),key_vld_out有(yǒu)效时(shí),該信(xìn)号(hào)有(yǒu)效。
Key_vld_out
輸出(chū)
計(jì)算器按鍵按下(xià)有(yǒu)效指示信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效。
State_c
輸出(chū)
計(jì)算器工作狀态指示信(xìn)号(hào)

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

該模块(kuài)的(de)主(zhǔ)要(yào)功能(néng)是(shì)根(gēn)據(jù)按下(xià)的(de)按鍵進(jìn)行不(bù)同(tóng)来(lái)判斷和(hé)決定(dìng)計(jì)算器的(de)工作狀态。一(yī)条(tiáo)等式可(kě)以(yǐ)写成(chéng):運算數1+操作符+運算數2+等号(hào)+結果(guǒ)的(de)形式。考慮到(dào)結果(guǒ)錯誤的(de)情(qíng)況,我(wǒ)将本(běn)模块(kuài)的(de)狀态劃(huà)分(fēn)为(wèi)5个(gè),分(fēn)别是(shì):輸入(rù)運算數1OP_1)、運算符(OPER)、輸入(rù)運算數2OP_2)、輸出(chū)結果(guǒ)(RESULT)、結果(guǒ)錯誤(ERROR

下(xià)图(tú)为(wèi)本(běn)模块(kuài)的(de)狀态跳轉(zhuǎn)图(tú):


複位後(hòu),狀态機(jī)進(jìn)入(rù)OP_1狀态,即初始狀态为(wèi)OP_1

在(zài)OP_1狀态下(xià):
A.  按下(xià)等号(hào),跳到(dào)RESULT狀态;
B.  按下(xià)運算符,跳到(dào)OPER狀态;
在(zài)OPER狀态下(xià):
A.  按下(xià)數字(zì),跳到(dào)OP_2狀态;
B.  按下(xià)等号(hào),跳到(dào)RESULT狀态;
在(zài)OP_2狀态下(xià):
A.  按下(xià)等号(hào),跳到(dào)RESULT狀态;
B.  按下(xià)運算符,跳到(dào)OPER狀态;
在(zài)RESULT狀态下(xià):
A.  按下(xià)數字(zì),跳到(dào)OP_1狀态;
B.  按下(xià)運算符,跳到(dào)OPER狀态;
C.  按下(xià)等号(hào),停留在(zài)RESULT狀态;
在(zài)ERROR狀态下(xià):
A.  按下(xià)數字(zì),跳到(dào)OP_1狀态;
B.  按下(xià)其他(tā)按鍵,停留在(zài)ERROR狀态;
无論當前(qián)处于(yú)什麼(me)狀态,只(zhī)要(yào)檢测到(dào)運算結果(guǒ)錯誤指示信(xìn)号(hào)有(yǒu)效,即刻跳轉(zhuǎn)到(dào)ERROR狀态。

1.3.3參考代(dài)碼
使用(yòng)GVIM,在(zài)命令模式下(xià)輸入(rù)如(rú)下(xià)內(nèi)容,即可(kě)生(shēng)成(chéng)本(běn)模块(kuài)所(suǒ)需要(yào)的(de)狀态機(jī)代(dài)碼。


使用(yòng)明(míng)德揚的(de)狀态機(jī)模板,可(kě)以(yǐ)很快(kuài)速的(de)写出(chū)此(cǐ)模块(kuài)代(dài)碼。

  1. always  @(*)begin
  2.     case(key_num)
  3.         4'd0   :key_num_chg = 4'd7   ;
  4.         4'd1   :key_num_chg = 4'd8   ;
  5.         4'd2   :key_num_chg = 4'd9   ;
  6.         4'd3   :key_num_chg = 4'd10  ;
  7.         4'd7   :key_num_chg = 4'd11  ;
  8.         4'd8   :key_num_chg = 4'd1   ;
  9.         4'd9   :key_num_chg = 4'd2   ;
  10.         4'd10  :key_num_chg = 4'd3   ;
  11.         4'd11  :key_num_chg = 4'd14  ;
  12.         4'd12  :key_num_chg = 4'd0   ;
  13.         4'd13  :key_num_chg = 4'd12  ;
  14.         4'd14  :key_num_chg = 4'd13  ;
  15.         default:key_num_chg = key_num;
  16.     endcase
  17. end

  18. assign  key_num_en = (key_num_chg==0 || key_num_chg==1 || key_num_chg==2 || key_num_chg==3 || key_num_chg==4 || key_num_chg==5 || key_num_chg==6 || key_num_chg==7 || key_num_chg==8 || key_num_chg==9) && key_vld==1;
  19. assign  key_op_en = (key_num_chg==10 || key_num_chg==11 || key_num_chg==12 || key_num_chg==13) && key_vld==1;
  20. assign  key_cal_en = key_num_chg==15 && key_vld==1;
  21. assign  key_back_en = key_num_chg==14 && key_vld==1;



  22. always @(posedge clk or negedge rst_n) begin
  23.     if (rst_n==0) begin
  24.         state_c <= OP_1 ;
  25.     end
  26.     else begin
  27.         state_c <= state_n;
  28.    end
  29. end

  30. always @(*) begin
  31.     if(result_err)begin
  32.        state_n = ERROR;
  33.    end
  34.    else begin
  35.        case(state_c)  
  36.         OP_1 :begin
  37.             if(op_12oper_start)
  38.                 state_n = OPER ;
  39.             else if(op_12result_start)
  40.                 state_n = RESULT ;
  41.             else
  42.                 state_n = state_c ;
  43.         end
  44.         OPER :begin
  45.             if(oper2op_2_start)
  46.                 state_n = OP_2 ;
  47.             else if(oper2result_start)
  48.                 state_n = RESULT ;
  49.             else
  50.                 state_n = state_c ;
  51.         end
  52.         OP_2 :begin
  53.             if(op_22oper_start)
  54.                 state_n = OPER ;
  55.             else if(op_22result_start)
  56.                 state_n = RESULT ;
  57.             else
  58.                 state_n = state_c ;
  59.         end
  60.         RESULT :begin
  61.             if(result2op_1_start)
  62.                 state_n = OP_1 ;
  63.             else if(result2oper_start)
  64.                 state_n = OPER ;
  65.             else
  66.                 state_n = state_c ;
  67.         end
  68.         ERROR :begin
  69.             if(error2op_1_start)
  70.                 state_n = OP_1 ;
  71.             else
  72.                 state_n = state_c ;
  73.         end
  74.         default : state_n = OP_1 ;
  75.     endcase
  76. end
  77. end

  78. assign op_12oper_start   = state_c==OP_1   && key_op_en ;
  79. assign op_12result_start = state_c==OP_1   && key_cal_en;
  80. assign oper2op_2_start   = state_c==OPER   && key_num_en;
  81. assign oper2result_start = state_c==OPER   && key_cal_en;
  82. assign op_22oper_start   = state_c==OP_2   && key_op_en ;
  83. assign op_22result_start = state_c==OP_2   && key_cal_en;
  84. assign result2op_1_start = state_c==RESULT && key_num_en;
  85. assign result2oper_start = state_c==RESULT && key_op_en ;
  86. assign error2op_1_start  = state_c==ERROR  && key_num_en;

  87. always  @(posedge clk or negedge rst_n)begin
  88.     if(rst_n==1'b0)begin
  89.         key_num_out <= 0;
  90.     end
  91.     else begin
  92.         key_num_out <= key_num_chg;
  93.     end
  94. end

  95. always  @(posedge clk or negedge rst_n)begin
  96.     if(rst_n==1'b0)begin
  97.         key_vld_out <= 0;
  98.     end
  99.     else begin
  100.         key_vld_out <= key_vld;
  101.     end
  102. end
複制代(dài)碼



1.4 運算數1模块(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)
rst_n
輸入(rù)
低電(diàn)平複位信(xìn)号(hào)
Key_num_out
輸入(rù)
計(jì)算器按下(xià)位置輸出(chū)信(xìn)号(hào),key_vld_out有(yǒu)效时(shí),該信(xìn)号(hào)有(yǒu)效。
Key_vld_out
輸入(rù)
計(jì)算器按鍵按下(xià)有(yǒu)效指示信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效。
State_c
輸入(rù)
計(jì)算器工作狀态指示信(xìn)号(hào)
Op_1
輸出(chū)
運算數1輸出(chū)信(xìn)号(hào)
Result
輸入(rù)
運算結果(guǒ)輸出(chū)信(xìn)号(hào)
Op_1_err
輸出(chū)
運算數1溢出(chū)信(xìn)号(hào)

1.4.2設計(jì)思(sī)路(lù)
該模块(kuài)主(zhǔ)要(yào)的(de)作用(yòng)是(shì)根(gēn)據(jù)當前(qián)狀态和(hé)輸入(rù)的(de)按鍵,来(lái)決定(dìng)運算數1要(yào)輸出(chū)的(de)結果(guǒ)。由(yóu)于(yú)本(běn)工程需要(yào)实現(xiàn)連(lián)續運算的(de)功能(néng),所(suǒ)以(yǐ)在(zài)这(zhè)个(gè)模块(kuài)中(zhōng)要(yào)區(qū)分(fēn)是(shì)否已經(jīng)得出(chū)了(le)運算結果(guǒ)。

下(xià)面(miàn)是(shì)計(jì)算完成(chéng)指示信(xìn)号(hào)flag_calc的(de)設計(jì)思(sī)路(lù):
1、 該信(xìn)号(hào)为(wèi)高(gāo)时(shí),表(biǎo)示完成(chéng)一(yī)次(cì)計(jì)算过(guò)程得到(dào)了(le)結果(guǒ)。初始狀态为(wèi)低電(diàn)平;
2、 當輸入(rù)操作數2後(hòu)又按下(xià)了(le)等号(hào)或(huò)者(zhě)其他(tā)操作符的(de)时(shí)候,變(biàn)为(wèi)高(gāo)電(diàn)平,所(suǒ)以(yǐ)變(biàn)高(gāo)的(de)条(tiáo)件(jiàn)为(wèi)(state_c_ff==OP_2 && state_c==OPER) || state_c==RESULT;
3、 當处在(zài)操作數1狀态时(shí),为(wèi)低電(diàn)平,所(suǒ)以(yǐ)變(biàn)低的(de)条(tiáo)件(jiàn)为(wèi)state_c==OP_1。其他(tā)情(qíng)況保持(chí)不(bù)變(biàn)。

下(xià)面(miàn)是(shì)運算數1輸出(chū)信(xìn)号(hào)op_1的(de)設計(jì)思(sī)路(lù):
1、 該信(xìn)号(hào)表(biǎo)示運算數1要(yào)輸出(chū)的(de)值。初始狀态为(wèi)0;
2、 在(zài)結果(guǒ)錯誤狀态的(de)时(shí)候,給(gěi)一(yī)个(gè)不(bù)超过(guò)範圍的(de)任意(yì)值,此(cǐ)代(dài)碼中(zhōng)給(gěi)的(de)10;
3、 在(zài)得到(dào)計(jì)算結果(guǒ)或(huò)者(zhě)計(jì)算結果(guǒ)錯誤的(de)时(shí)候,輸入(rù)數字(zì),輸出(chū)为(wèi)按下(xià)按鍵的(de)对(duì)應(yìng)值(key_num_out);
4、 在(zài)輸入(rù)操作數1之後(hòu),按下(xià)退(tuì)格鍵,op_1輸出(chū)的(de)值除以(yǐ)10進(jìn)行取(qǔ)整;
5、 在(zài)輸入(rù)操作數1狀态下(xià)通(tòng)过(guò)鍵盤輸入(rù)數字(zì),需要(yào)判斷是(shì)否超过(guò)顯示範圍,如(rú)果(guǒ)沒(méi)有(yǒu)超过(guò)的(de)話(huà)就(jiù)需要(yào)将當前(qián)op_1的(de)值乘以(yǐ)10,然後(hòu)加上(shàng)按下(xià)的(de)數字(zì)的(de)值,進(jìn)行輸出(chū);
6、 當計(jì)算完成(chéng)时(shí),即flag_calc==1,操作數1輸出(chū)計(jì)算的(de)結果(guǒ)result;
7、 其他(tā)时(shí)侯操作數1保持(chí)不(bù)變(biàn)。

下(xià)面(miàn)是(shì)運算數1溢出(chū)信(xìn)号(hào)op_1_err的(de)設計(jì)思(sī)路(lù):
1、 初始狀态为(wèi)0,表(biǎo)示沒(méi)有(yǒu)溢出(chū)。
2、 當一(yī)直(zhí)处于(yú)操作數1狀态,按下(xià)鍵盤輸入(rù)數字(zì)之後(hòu),操作數1的(de)值溢出(chū)了(le),則将運算數1溢出(chū)信(xìn)号(hào)拉高(gāo)。
3、 其他(tā)时(shí)刻保持(chí)为(wèi)低電(diàn)平。
  1. assign  key_num_en = (key_num==0 || key_num==1 || key_num==2 || key_num==3 || key_num==4 || key_num==5 || key_num==6 || key_num==7 || key_num==8 || key_num==9) && key_vld==1;
  2. assign  key_op_en = (key_num==10 || key_num==11 || key_num==12 || key_num==13) && key_vld==1;
  3. assign  key_cal_en = key_num==15 && key_vld==1;
  4. assign  key_back_en = key_num==14 && key_vld==1;

  5. always  @(posedge clk or negedge rst_n)begin
  6.     if(rst_n==1'b0)begin
  7.         state_c_ff <= 0;
  8.     end
  9.     else begin
  10.         state_c_ff <= state_c;
  11.     end
  12. end

  13. always  @(posedge clk or negedge rst_n)begin
  14.     if(rst_n==1'b0)begin
  15.         op_2 <= 0;
  16.     end
  17.     else if(state_c==OPER)begin
  18.         op_2 <= 0;
  19.     end
  20.     else if(state_c_ff==OPER && state_c==OP_2)begin
  21.         op_2 <= key_num;
  22.     end
  23.     else if(state_c==OP_2 && key_back_en==1)begin
  24.         op_2 <= op_2 / 10;
  25.     end
  26.     else if(state_c==OP_2 && key_num_en==1)begin
  27.         op_2 <= (op_2>9999999) ? op_2 : (op_2*10+key_num);
  28.     end
  29.     else begin
  30.         op_2 <= op_2;
  31.     end
  32. end

  33. always  @(posedge clk or negedge rst_n)begin
  34.     if(rst_n==1'b0)begin
  35.         op_2_err <= 0;
  36.     end
  37.     else if(state_c==OP_2 && key_num_en==1 && op_2>9999999)begin
  38.         op_2_err <= 1'b1;
  39.     end
  40.     else begin
  41.         op_2_err <= 1'b0;
  42.     end
  43. end

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

1.4.3參考代(dài)碼

1.5 運算符模块(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)
Key_num_out
輸入(rù)
計(jì)算器按下(xià)位置輸出(chū)信(xìn)号(hào),key_vld_out有(yǒu)效时(shí),該信(xìn)号(hào)有(yǒu)效。
Key_vld_out
輸入(rù)
計(jì)算器按鍵按下(xià)有(yǒu)效指示信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效。
State_c
輸入(rù)
計(jì)算器工作狀态指示信(xìn)号(hào)
oper
輸出(chū)
運算符輸出(chū)信(xìn)号(hào)

1.5.2設計(jì)思(sī)路(lù)
本(běn)模块(kuài)的(de)設計(jì)思(sī)路(lù)比較簡單,只(zhī)需要(yào)判斷哪些按鍵是(shì)運算符,然後(hòu)再这(zhè)些運算符被(bèi)按下(xià)的(de)时(shí)候,将他(tā)们(men)对(duì)應(yìng)的(de)值輸出(chū)就(jiù)可(kě)以(yǐ)了(le)。
下(xià)面(miàn)是(shì)運算符指示信(xìn)号(hào)設計(jì)思(sī)路(lù):
1、 當“加”“減”“乘”“除”四(sì)个(gè)按鍵的(de)任意(yì)一(yī)个(gè)被(bèi)按下(xià)之後(hòu),該信(xìn)号(hào)置为(wèi)高(gāo)電(diàn)平;
2、 當“加”“減”“乘”“除”四(sì)个(gè)按鍵沒(méi)有(yǒu)一(yī)个(gè)被(bèi)按下(xià)的(de)时(shí)候,該信(xìn)号(hào)置为(wèi)低電(diàn)平。
下(xià)面(miàn)是(shì)運算符輸出(chū)信(xìn)号(hào)oper設計(jì)思(sī)路(lù):
初始狀态,該信(xìn)号(hào)輸出(chū)0
1、 當处于(yú)操作數1狀态时(shí),輸出(chū)0;
2、 當“加”“減”“乘”“除”任意(yì)按鍵被(bèi)按下(xià)之後(hòu),輸出(chū)該按鍵对(duì)應(yìng)的(de)值;
3、 其他(tā)时(shí)候保持(chí)不(bù)變(biàn);

1.5.3參考代(dài)碼
  1. assign  key_op_en = (key_num==10 || key_num==11 || key_num==12 || key_num==13) && key_vld==1;

  2. always  @(posedge clk or negedge rst_n)begin
  3.     if(rst_n==1'b0)begin
  4.         oper <= 0;
  5.     end
  6.     else if(state_c==OP_1)begin
  7.         oper <= 0;
  8.     end
  9.     else if(key_op_en==1)begin
  10.         oper <= key_num;
  11.     end
  12.     else begin
  13.         oper <= oper;
  14.     end
  15. end
複制代(dài)碼


1.6 運算數2模块(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)
Key_num_out
輸入(rù)
計(jì)算器按下(xià)位置輸出(chū)信(xìn)号(hào),key_vld_out有(yǒu)效时(shí),該信(xìn)号(hào)有(yǒu)效。
Key_vld_out
輸入(rù)
計(jì)算器按鍵按下(xià)有(yǒu)效指示信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效。
State_c
輸入(rù)
計(jì)算器工作狀态指示信(xìn)号(hào)
Op_2
輸出(chū)
運算數2輸出(chū)信(xìn)号(hào)
Op_2_err
輸出(chū)
運算數2溢出(chū)信(xìn)号(hào)

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

該模块(kuài)主(zhǔ)要(yào)的(de)作用(yòng)是(shì)根(gēn)據(jù)當前(qián)狀态和(hé)輸入(rù)的(de)按鍵,来(lái)決定(dìng)運算數2要(yào)輸出(chū)的(de)結果(guǒ)。
下(xià)面(miàn)是(shì)運算數2輸出(chū)信(xìn)号(hào)op_2的(de)設計(jì)思(sī)路(lù):

1、 該信(xìn)号(hào)表(biǎo)示運算數2要(yào)輸出(chū)的(de)值。初始狀态为(wèi)0;
2、 在(zài)運算符狀态下(xià),此(cǐ)时(shí)數碼管(guǎn)不(bù)顯示運算數2的(de)值,讓它(tā)輸出(chū)0;
3、 輸入(rù)運算符之後(hòu),之後(hòu)再輸入(rù)的(de)就(jiù)是(shì)運算數2的(de)值,此(cǐ)时(shí)運算數2就(jiù)等于(yú)按下(xià)按鍵所(suǒ)对(duì)應(yìng)的(de)數值。
4、 在(zài)輸入(rù)運算數2之後(hòu),按下(xià)退(tuì)格鍵,運算數2的(de)值除以(yǐ)10進(jìn)行取(qǔ)整;
5、 在(zài)輸入(rù)運算數2狀态下(xià)通(tòng)过(guò)鍵盤輸入(rù)數字(zì),需要(yào)判斷是(shì)否超过(guò)顯示範圍,如(rú)果(guǒ)沒(méi)有(yǒu)超过(guò)的(de)話(huà)就(jiù)需要(yào)将當前(qián)運算數2的(de)值乘以(yǐ)10,然後(hòu)加上(shàng)按下(xià)的(de)數字(zì)的(de)值,進(jìn)行輸出(chū);
6、 其他(tā)时(shí)侯運算數2保持(chí)不(bù)變(biàn)。

下(xià)面(miàn)是(shì)運算數2溢出(chū)信(xìn)号(hào)op_2_err的(de)設計(jì)思(sī)路(lù):

1、 初始狀态为(wèi)0,表(biǎo)示沒(méi)有(yǒu)溢出(chū)。
2、 當一(yī)直(zhí)处于(yú)運算數2狀态,按下(xià)鍵盤輸入(rù)數字(zì)之後(hòu),運算數2的(de)值溢出(chū)了(le),則将運算數2溢出(chū)信(xìn)号(hào)拉高(gāo)。
3、 其他(tā)时(shí)刻保持(chí)为(wèi)低電(diàn)平。

1.6.3參考代(dài)碼
  1. assign  key_num_en = (key_num==0 || key_num==1 || key_num==2 || key_num==3 || key_num==4 || key_num==5 || key_num==6 || key_num==7 || key_num==8 || key_num==9) && key_vld==1;
  2. assign  key_op_en = (key_num==10 || key_num==11 || key_num==12 || key_num==13) && key_vld==1;
  3. assign  key_cal_en = key_num==15 && key_vld==1;
  4. assign  key_back_en = key_num==14 && key_vld==1;

  5. always  @(posedge clk or negedge rst_n)begin
  6.     if(rst_n==1'b0)begin
  7.         state_c_ff <= 0;
  8.     end
  9.     else begin
  10.         state_c_ff <= state_c;
  11.     end
  12. end

  13. always  @(posedge clk or negedge rst_n)begin
  14.     if(rst_n==1'b0)begin
  15.         flag_calc <= 0;
  16.     end
  17.     else if(state_c==OP_1)begin
  18.         flag_calc <= 1'b0;
  19.     end
  20.     else if(state_c_ff==OP_2 && state_c==OPER || state_c==RESULT)begin
  21.         flag_calc <= 1'b1;
  22.     end
  23.     else begin
  24.         flag_calc <= flag_calc;
  25.     end
  26. end

  27. always  @(posedge clk or negedge rst_n)begin
  28.     if(rst_n==1'b0)begin
  29.         op_1 <= 0;
  30.     end
  31.     else if(state_c==ERROR)begin
  32.         op_1 <= 10;
  33.     end
  34.     else if((state_c_ff==RESULT || state_c_ff==ERROR) && state_c==OP_1)begin
  35.         op_1 <= key_num;
  36.     end
  37.     else if(state_c==OP_1 && key_back_en==1)begin
  38.         op_1 <= op_1 / 10;
  39.     end
  40.     else if(state_c==OP_1 && key_num_en==1)begin
  41.         op_1 <= (op_1>9999999) ? op_1 : (op_1*10+key_num);
  42.     end
  43.     else if(flag_calc==1)begin
  44.         op_1 <= result;
  45.     end
  46.     else begin
  47.         op_1 <= op_1;
  48.     end
  49. end

  50. always  @(posedge clk or negedge rst_n)begin
  51.     if(rst_n==1'b0)begin
  52.         op_1_err <= 0;
  53.     end
  54.     else if(state_c==OP_1  && key_num_en==1 && op_1>9999999)begin
  55.         op_1_err <= 1'b1;
  56.     end
  57.     else begin
  58.         op_1_err <= 1'b0;
  59.     end
  60. end
複制代(dài)碼

1.7 運算單元(yuán)模块(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)
Key_num_out
輸入(rù)
計(jì)算器按下(xià)位置輸出(chū)信(xìn)号(hào),key_vld_out有(yǒu)效时(shí),該信(xìn)号(hào)有(yǒu)效。
Key_vld_out
輸入(rù)
計(jì)算器按鍵按下(xià)有(yǒu)效指示信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效。
State_c
輸入(rù)
計(jì)算器工作狀态指示信(xìn)号(hào)
oper
輸出(chū)
運算符輸出(chū)信(xìn)号(hào)
Op_1
輸入(rù)
運算數1輸入(rù)信(xìn)号(hào)
Op_2
輸入(rù)
運算數2輸入(rù)信(xìn)号(hào)
Result
輸出(chū)
運算結果(guǒ)輸出(chū)信(xìn)号(hào)
Result_err
輸出(chū)
運算結果(guǒ)錯誤信(xìn)号(hào),運算結果(guǒ)溢出(chū)或(huò)者(zhě)除數为(wèi)0时(shí),該信(xìn)号(hào)輸出(chū)一(yī)个(gè)时(shí)鐘(zhōng)周期(qī)的(de)高(gāo)電(diàn)平
Result_neg
輸出(chū)
運算結果(guǒ)符号(hào)位指示信(xìn)号(hào),當運算結果(guǒ)为(wèi)負數时(shí),該信(xìn)号(hào)为(wèi)高(gāo)電(diàn)平

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

本(běn)模块(kuài)的(de)作用(yòng)是(shì)根(gēn)據(jù)運算符,对(duì)運算數1和(hé)運算數2進(jìn)行操作得出(chū)結果(guǒ)。
由(yóu)于(yú)再進(jìn)行計(jì)算的(de)时(shí)候考慮小數減去(qù)大數的(de)情(qíng)況,所(suǒ)以(yǐ)運算結果(guǒ)允许为(wèi)負數,因(yīn)此(cǐ)需要(yào)有(yǒu)符号(hào)位指示信(xìn)号(hào),下(xià)面(miàn)是(shì)運算結果(guǒ)符号(hào)位指示信(xìn)号(hào)result_neg的(de)設計(jì)思(sī)路(lù):

1、 只(zhī)有(yǒu)當運算結果(guǒ)为(wèi)負數的(de)时(shí)候,才顯示“負号(hào)”,因(yīn)此(cǐ)初始狀态为(wèi)低電(diàn)平;
2、 當算式輸入(rù)完成(chéng)按下(xià)等号(hào)之後(hòu),如(rú)果(guǒ)運算符是(shì)“減”,并且運算數1小于(yú)運算數2,則運算結果(guǒ)为(wèi)負數,将result_neg信(xìn)号(hào)拉高(gāo)。
3、 由(yóu)于(yú)該計(jì)算器支持(chí)連(lián)續輸入(rù),如(rú)果(guǒ)當前(qián)計(jì)算的(de)結果(guǒ)为(wèi)負數,接着輸入(rù)的(de)運算符为(wèi)“加”,下(xià)一(yī)次(cì)進(jìn)行加法運算,并且運算數1(此(cǐ)时(shí)比較不(bù)考慮符号(hào)位)小于(yú)或(huò)等于(yú)運算數2,則表(biǎo)示運算結果(guǒ)为(wèi)正(zhèng)數,此(cǐ)时(shí)将result_neg信(xìn)号(hào)拉低。
4、 在(zài)進(jìn)行連(lián)續計(jì)算的(de)时(shí)候,如(rú)果(guǒ)得到(dào)的(de)結果(guǒ)超过(guò)顯示上(shàng)限,要(yào)進(jìn)入(rù)錯誤狀态,这(zhè)个(gè)时(shí)候符号(hào)位指示信(xìn)号(hào)應(yìng)該为(wèi)低電(diàn)平。
5、 无論在(zài)計(jì)算中(zhōng)得到(dào)的(de)結果(guǒ)是(shì)正(zhèng)還(huán)是(shì)負,如(rú)果(guǒ)下(xià)次(cì)輸入(rù)的(de)为(wèi)運算數1,都需要(yào)result_neg信(xìn)号(hào)为(wèi)低電(diàn)平。
6、 由(yóu)于(yú)除法不(bù)支持(chí)小數顯示,只(zhī)取(qǔ)整數部(bù)分(fēn),所(suǒ)以(yǐ)當運算結果(guǒ)为(wèi)負數,并進(jìn)行除法運算的(de)时(shí)候,如(rú)果(guǒ)得到(dào)的(de)結果(guǒ)为(wèi)0,不(bù)應(yìng)該顯示为(wèi)“負0”,應(yìng)當将符号(hào)位指示信(xìn)号(hào)置为(wèi)低電(diàn)平。

本(běn)模块(kuài)主(zhǔ)要(yào)的(de)功能(néng)是(shì)实現(xiàn)加減乘除運算,下(xià)面(miàn)是(shì)对(duì)運算結果(guǒ)輸出(chū)信(xìn)号(hào)result的(de)設計(jì)思(sī)路(lù):

1、 初始狀态沒(méi)有(yǒu)經(jīng)过(guò)計(jì)算,自(zì)然輸出(chū)为(wèi)0。
2、 在(zài)進(jìn)行加法的(de)时(shí)候,由(yóu)于(yú)存在(zài)連(lián)續計(jì)算的(de)情(qíng)況,需要(yào)考慮符号(hào)位。當符号(hào)位指示信(xìn)号(hào)为(wèi)0,直(zhí)接将運算數1和(hé)運算數2相加即可(kě);當符号(hào)位指示信(xìn)号(hào)为(wèi)1,則需要(yào)判斷運算數1和(hé)運算數2的(de)大小,确保是(shì)大的(de)減去(qù)小的(de)。
3、 在(zài)進(jìn)行減法的(de)时(shí)候,同(tóng)樣(yàng)需要(yào)考慮符号(hào)位。當符号(hào)位指示信(xìn)号(hào)为(wèi)0的(de)时(shí)候,需要(yào)判斷運算數1和(hé)運算數2的(de)大小,保證大的(de)減去(qù)小的(de);當符号(hào)位指示信(xìn)号(hào)位1的(de)时(shí)候,直(zhí)接将運算數1和(hé)運算數2相加即可(kě)。
4、 乘法運算直(zhí)接将運算數1和(hé)運算數2相乘即可(kě)。
5、 在(zài)進(jìn)行除法運算时(shí),由(yóu)于(yú)无法表(biǎo)示小數,因(yīn)此(cǐ)这(zhè)里(lǐ)需要(yào)采用(yòng)運算數1除以(yǐ)運算數2取(qǔ)整的(de)方(fāng)法,即op_1/op_2。

在(zài)計(jì)算过(guò)程中(zhōng),如(rú)果(guǒ)得到(dào)的(de)結果(guǒ)超过(guò)顯示上(shàng)限或(huò)者(zhě)錯誤的(de)計(jì)算方(fāng)法,需要(yào)做出(chū)錯誤提(tí)示,下(xià)面(miàn)是(shì)对(duì)于(yú)運算結果(guǒ)錯誤信(xìn)号(hào)result_err的(de)設計(jì)思(sī)路(lù):

1、  初始狀态下(xià),該信(xìn)号(hào)为(wèi)0,表(biǎo)示沒(méi)有(yǒu)錯誤。
2、  得到(dào)運算結果(guǒ)後(hòu),若繼續輸入(rù)數字(zì),則会(huì)進(jìn)入(rù)到(dào)運算數1狀态,这(zhè)个(gè)时(shí)候不(bù)進(jìn)行錯誤提(tí)示。
3、  在(zài)運算數2狀态下(xià)輸入(rù)運算符,或(huò)者(zhě)在(zài)結果(guǒ)不(bù)是(shì)錯誤的(de)狀态下(xià)輸出(chū)“等号(hào)”(表(biǎo)示進(jìn)行連(lián)續計(jì)算)。根(gēn)據(jù)輸入(rù)的(de)運算符進(jìn)行相應(yìng)的(de)判斷:
加:如(rú)果(guǒ)運算結果(guǒ)为(wèi)正(zhèng)數,則判斷運算數1加上(shàng)運算數2之後(hòu)会(huì)不(bù)会(huì)溢出(chū),若溢出(chū)則做出(chū)錯誤提(tí)示;如(rú)果(guǒ)運算結果(guǒ)为(wèi)負數,則不(bù)進(jìn)行錯誤提(tí)示。
減:如(rú)果(guǒ)運算結果(guǒ)为(wèi)負數,則判斷運算數1加上(shàng)運算數2之後(hòu)会(huì)不(bù)会(huì)溢出(chū),若溢出(chū)則做出(chū)錯誤提(tí)示;如(rú)果(guǒ)運算結果(guǒ)为(wèi)正(zhèng)數,則判斷两(liǎng)个(gè)數相減之後(hòu)的(de)結果(guǒ)是(shì)否会(huì)溢出(chū)。
乘:无論運算結果(guǒ)为(wèi)何值,都只(zhī)需要(yào)判斷两(liǎng)數相乘之後(hòu)的(de)的(de)結果(guǒ)会(huì)不(bù)会(huì)溢出(chū)就(jiù)可(kě)以(yǐ)了(le)。
除:在(zài)進(jìn)行除法運算的(de)时(shí)候,需要(yào)避免出(chū)現(xiàn)除數为(wèi)0的(de)情(qíng)況,如(rú)果(guǒ)出(chū)現(xiàn)此(cǐ)情(qíng)況,則進(jìn)行錯誤指示。


1.7.3參考代(dài)碼
  1. assign  key_op_en = (key_num==10 || key_num==11 || key_num==12 || key_num==13) && key_vld==1;
  2. assign  key_cal_en = key_num==15 && key_vld==1;
  3. assign  calculate = (state_c_ff==OP_2 && state_c==OPER || key_cal_en==1);

  4. always  @(posedge clk or negedge rst_n)begin
  5.     if(rst_n==1'b0)begin
  6.         state_c_ff <= 0;
  7.     end
  8.     else begin
  9.         state_c_ff <= state_c;
  10.     end
  11. end

  12. always  @(posedge clk or negedge rst_n)begin
  13.     if(rst_n==1'b0)begin
  14.         result <= 0;
  15.     end
  16.     else if(calculate==1)begin
  17.         case(oper)
  18.             ADD:begin
  19.                 if(result_neg==0)
  20.                     result <= op_1 + op_2;
  21.                 else
  22.                     result <= (op_1>op_2) ? (op_1 - op_2) : (op_2 - op_1);
  23.             end
  24.             DEV:begin
  25.                 if(result_neg==0)
  26.                     result <= (op_1>op_2) ? (op_1 - op_2) : (op_2 - op_1);
  27.                 else
  28.                     result <= op_1 + op_2;
  29.             end
  30.             MUL:begin
  31.                 result <= op_1 * op_2;
  32.             end
  33.             DIV:begin
  34.                 result <= op_1 / op_2;
  35.             end
  36.             default:result <= op_1;
  37.         endcase
  38.     end
  39.     else begin
  40.         result <= result;
  41.     end
  42. end

  43. always  @(posedge clk or negedge rst_n)begin
  44.     if(rst_n==1'b0)begin
  45.         result_neg <= 0;
  46.     end
  47.     else if(state_c==OP_1)begin
  48.         result_neg <= 1'b0;
  49.     end
  50.     else if(state_c==ERROR)begin
  51.         result_neg <= 1'b0;
  52.     end
  53.     else if(calculate==1 && oper==DEV && op_1<op_2)begin
  54.         result_neg <= 1'b1;
  55.     end
  56.     else if(calculate==1 && result_neg==1 && oper==ADD && op_1<=op_2)begin
  57.         result_neg <= 1'b0;
  58.     end
  59.     else if(result==0)begin
  60.         result_neg <= 1'b0;
  61.     end
  62.     else begin
  63.         result_neg <= result_neg;
  64.     end
  65. end

  66. always  @(posedge clk or negedge rst_n)begin
  67.     if(rst_n==1'b0)begin
  68.         result_err <= 0;
  69.     end
  70.     else if(state_c==OP_1)begin
  71.         result_err <= 1'b0;
  72.     end
  73.     else if((state_c_ff==OP_2 && state_c==OPER) || (key_cal_en==1 && state_c_ff!=ERROR))begin
  74.         case(oper)
  75.             ADD:begin
  76.                 if(result_neg==0)
  77.                     result_err <= (op_1+op_2)>9999_9999 ? 1'b1 : 1'b0;
  78.                 else
  79.                     result_err <= 1'b0;
  80.             end
  81.             DEV:begin
  82.                 if(result_neg==1)
  83.                     result_err <= (op_1+op_2)>999_9999 ? 1'b1 : 1'b0;
  84.                 else if(op_2>op_1)
  85.                     result_err <= (op_2-op_1)>999_9999 ? 1'b1 : 1'b0;
  86.                 else
  87.                     result_err <= 1'b0;
  88.             end
  89.             MUL:begin
  90.                 if(result_neg==1)
  91.                     result_err <= (op_1*op_2)>999_9999 ? 1'b1 : 1'b0;
  92.                 else
  93.                     result_err <= (op_1*op_2)>9999_9999 ? 1'b1 : 1'b0;
  94.             end
  95.             DIV:begin
  96.                 if(op_2==0)
  97.                     result_err <= 1'b1;
  98.                 else
  99.                     result_err <= 1'b0;
  100.             end
  101.             default:result_err <= 1'b0;
  102.         endcase
  103.     end
  104.     else begin
  105.         result_err <= 1'b0;
  106.     end
  107. end
複制代(dài)碼


1.8 顯示对(duì)象(xiàng)選擇模块(kuài)設計(jì)1.8.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)
Op_1
輸入(rù)
運算數1輸入(rù)信(xìn)号(hào)
Op_2
輸入(rù)
運算數2輸入(rù)信(xìn)号(hào)
State_c
輸入(rù)
計(jì)算器工作狀态指示信(xìn)号(hào)
Result_neg
輸入(rù)
運算結果(guǒ)符号(hào)位指示信(xìn)号(hào)
Disply
輸出(chū)
顯示數據(jù)輸出(chū)信(xìn)号(hào)
Display_vld
輸出(chū)
顯示數據(jù)有(yǒu)效指示信(xìn)号(hào)

1.8.2設計(jì)思(sī)路(lù)
該模块(kuài)的(de)作用(yòng)是(shì)根(gēn)據(jù)當前(qián)計(jì)算器的(de)工作狀态来(lái)選擇數碼管(guǎn)的(de)顯示內(nèi)容。

1、  複位後(hòu),該模块(kuài)輸出(chū)0;
2、  當計(jì)算器处于(yú)OP_1狀态下(xià),該模块(kuài)選擇輸出(chū)運算數1。
3、  當計(jì)算器处于(yú)OPER狀态下(xià),該模块(kuài)選擇輸出(chū)運算數1。
4、  當計(jì)算器处于(yú)OP_2狀态下(xià),該模块(kuài)選擇輸出(chū)運算數2。
5、  當計(jì)算器处于(yú)RESULT狀态下(xià),該模块(kuài)選擇輸出(chū)運算數1。
6、  當計(jì)算器处于(yú)ERROR狀态下(xià),該模块(kuài)選擇輸出(chū)8个(gè)F。

要(yào)将數據(jù)送到(dào)數碼管(guǎn)顯示,需要(yào)将收(shōu)到(dào)的(de)數據(jù)進(jìn)行拆分(fēn),比如(rú)輸入(rù)進(jìn)来(lái)的(de)是(shì)“12”,需要(yào)拆成(chéng)一(yī)个(gè)4bit的(de)“1”和(hé)一(yī)个(gè)4bit的(de)“2”送給(gěi)數碼管(guǎn)顯示模块(kuài)。因(yīn)此(cǐ)設計(jì)一(yī)个(gè)計(jì)數器的(de)架構,如(rú)下(xià)图(tú)所(suǒ)示:

架構中(zhōng)使用(yòng)到(dào)了(le)一(yī)个(gè)时(shí)鐘(zhōng)計(jì)數器dis_cnt、一(yī)个(gè)采集狀态指示信(xìn)号(hào)flag_adddis_sel为(wèi)輸入(rù)要(yào)顯示的(de)數據(jù)、dis_sel_tmp为(wèi)輸入(rù)數據(jù)打(dǎ)一(yī)拍之後(hòu)的(de)數據(jù)、result_neg为(wèi)運算結果(guǒ)符号(hào)位指示信(xìn)号(hào)、result_neg_tmp为(wèi)運算結果(guǒ)符号(hào)位指示信(xìn)号(hào)打(dǎ)一(yī)拍之後(hòu)的(de)信(xìn)号(hào)。下(xià)面(miàn)分(fēn)别介紹一(yī)下(xià)这(zhè)些信(xìn)号(hào)的(de)設計(jì)思(sī)路(lù):

采集狀态指示信(xìn)号(hào)flag_add:初始狀态为(wèi)0,表(biǎo)示不(bù)对(duì)數據(jù)進(jìn)行采集顯示。如(rú)果(guǒ)檢测到(dào)輸入(rù)的(de)數據(jù)或(huò)者(zhě)符号(hào)位發(fà)生(shēng)變(biàn)化(huà),表(biǎo)示要(yào)在(zài)數碼管(guǎn)上(shàng)顯示的(de)數據(jù)有(yǒu)變(biàn)化(huà),該信(xìn)号(hào)拉高(gāo),計(jì)數器可(kě)以(yǐ)進(jìn)行計(jì)數,所(suǒ)以(yǐ)由(yóu)0變(biàn)1的(de)条(tiáo)件(jiàn)为(wèi)dis_sel!=dis_sel_tmp || result_neg!=result_neg_tmp。當計(jì)數器數完之後(hòu),表(biǎo)示要(yào)顯示的(de)數據(jù)已經(jīng)全(quán)部(bù)顯示,則将此(cǐ)信(xìn)号(hào)拉低,所(suǒ)以(yǐ)由(yóu)1變(biàn)0的(de)条(tiáo)件(jiàn)是(shì)end_dis_cnt

顯示數據(jù)dis_sel:該信(xìn)号(hào)根(gēn)據(jù)工作狀态進(jìn)行選擇,當目前(qián)处于(yú)OP_2狀态时(shí),選擇運算數2輸入(rù)數據(jù),其他(tā)情(qíng)況都選擇運算數1輸入(rù)數據(jù)。

顯示數據(jù)打(dǎ)一(yī)拍之後(hòu)的(de)信(xìn)号(hào)dis_sel_tmp:該信(xìn)号(hào)存在(zài)的(de)目的(de)就(jiù)是(shì)为(wèi)了(le)檢测顯示數據(jù)是(shì)否發(fà)生(shēng)變(biàn)化(huà)。

運算結果(guǒ)符号(hào)位指示信(xìn)号(hào)result_neg:輸入(rù)信(xìn)号(hào)。

符号(hào)位指示信(xìn)号(hào)打(dǎ)一(yī)拍之後(hòu)的(de)信(xìn)号(hào)result_neg_tmp:該信(xìn)号(hào)存在(zài)的(de)意(yì)義就(jiù)是(shì)为(wèi)了(le)檢测符号(hào)位是(shì)否發(fà)生(shēng)變(biàn)化(huà)。

时(shí)鐘(zhōng)計(jì)數器dis_cnt:該計(jì)數器的(de)作用(yòng)有(yǒu)两(liǎng)个(gè),延时(shí)和(hé)控制輸入(rù)數據(jù)賦值給(gěi)顯示數據(jù)輸出(chū)信(xìn)号(hào)的(de)对(duì)應(yìng)位。加一(yī)条(tiáo)件(jiàn)为(wèi)flag_add && (dis_sel==dis_sel_tmp &&result_neg==result_neg_tmp),表(biǎo)示处在(zài)采集狀态时(shí),如(rú)果(guǒ)顯示數據(jù)和(hé)符号(hào)位指示信(xìn)号(hào)稳定(dìng),則開(kāi)始計(jì)數。結束(shù)条(tiáo)件(jiàn)为(wèi)數10个(gè),由(yóu)于(yú)計(jì)數器刚開(kāi)始計(jì)數的(de)时(shí)候,顯示數據(jù)存在(zài)變(biàn)化(huà)的(de)可(kě)能(néng),因(yīn)此(cǐ)这(zhè)里(lǐ)選擇延遲两(liǎng)个(gè)时(shí)鐘(zhōng)在(zài)对(duì)顯示數據(jù)輸出(chū)信(xìn)号(hào)進(jìn)行賦值(由(yóu)于(yú)後(hòu)面(miàn)數據(jù)都是(shì)保持(chí)不(bù)變(biàn)的(de),因(yīn)此(cǐ)这(zhè)个(gè)延时(shí)时(shí)間(jiān)不(bù)是(shì)固定(dìng)的(de),可(kě)以(yǐ)多(duō)延时(shí)一(yī)些),共(gòng)有(yǒu)8个(gè)數碼管(guǎn),因(yīn)此(cǐ)要(yào)賦值8次(cì),所(suǒ)以(yǐ)計(jì)數器共(gòng)需要(yào)數10个(gè)。

前(qián)面(miàn)提(tí)到(dào)过(guò),需要(yào)将顯示數據(jù)顯示到(dào)數碼管(guǎn)上(shàng)的(de)話(huà),需要(yào)将每一(yī)个(gè)數字(zì)進(jìn)行拆分(fēn),一(yī)般采用(yòng)除以(yǐ)10取(qǔ)餘和(hé)取(qǔ)整的(de)方(fāng)法,本(běn)工程使用(yòng)除法器的(de)IP核,該IP核的(de)作用(yòng)就(jiù)是(shì)将輸入(rù)的(de)數據(jù)除以(yǐ)10,得到(dào)商和(hé)餘數。生(shēng)成(chéng)过(guò)程如(rú)下(xià):

第(dì)一(yī)步、使用(yòng)软(ruǎn)件(jiàn)为(wèi)Quartus Prime LiteEdition 18.1版本(běn)。首先(xiān)打(dǎ)開(kāi)软(ruǎn)件(jiàn)之後(hòu),在(zài)主(zhǔ)页(yè)面(miàn)的(de)右(yòu)邊(biān)找(zhǎo)到(dào)“IP Catalog”窗(chuāng)口(kǒu),在(zài)搜索欄中(zhōng)輸入(rù)“div”進(jìn)行搜索,然後(hòu)双(shuāng)擊“LPM_DIVIDE”。如(rú)果(guǒ)沒(méi)有(yǒu)找(zhǎo)到(dào)“IP Catalog”窗(chuāng)口(kǒu),可(kě)在(zài)上(shàng)方(fāng)工具欄“Tools”中(zhōng)選擇“IP Catalog”調出(chū)。


第(dì)二(èr)步、選擇IP核生(shēng)成(chéng)的(de)路(lù)徑,并将其命名为(wèi)“div”,注意(yì)这(zhè)里(lǐ)的(de)名字(zì)不(bù)能(néng)有(yǒu)中(zhōng)文(wén)字(zì)符或(huò)者(zhě)全(quán)數字(zì)。在(zài)下(xià)方(fāng)文(wén)件(jiàn)類(lèi)型中(zhōng)選擇“Verilog”,然後(hòu)點(diǎn)擊OK



第(dì)三(sān)步、在(zài)之後(hòu)出(chū)現(xiàn)的(de)IP核設置界面(miàn)中(zhōng),“How wide should the numerator input”表(biǎo)示需要(yào)設置的(de)分(fēn)子的(de)位宽(kuān),这(zhè)里(lǐ)設置为(wèi)27。“How wide should thedenominator input”表(biǎo)示需要(yào)設置的(de)分(fēn)母的(de)位宽(kuān)这(zhè)里(lǐ)設置为(wèi)4。在(zài)下(xià)方(fāng)分(fēn)子和(hé)分(fēn)母的(de)表(biǎo)示都選用(yòng)“Unsigned”无符号(hào)類(lèi)型。然後(hòu)點(diǎn)擊Next


第(dì)四(sì)步、下(xià)图(tú)中(zhōng)的(de)1处表(biǎo)示是(shì)否需要(yào)对(duì)輸出(chū)進(jìn)行打(dǎ)拍,这(zhè)里(lǐ)選擇打(dǎ)一(yī)拍之後(hòu)輸出(chū)。2处表(biǎo)示要(yào)進(jìn)行的(de)优化(huà),这(zhè)里(lǐ)選擇默認优化(huà)。3处表(biǎo)示是(shì)否總(zǒng)是(shì)返回(huí)正(zhèng)餘數,選擇是(shì)。然後(hòu)點(diǎn)擊Next


第(dì)五(wǔ)步、方(fāng)框出(chū)表(biǎo)示該IP核在(zài)仿真(zhēn)的(de)时(shí)候需要(yào)調用(yòng)的(de)庫,直(zhí)接點(diǎn)擊Next即可(kě)。



第(dì)六(liù)步、这(zhè)一(yī)界面(miàn)是(shì)設置需要(yào)生(shēng)成(chéng)的(de)文(wén)件(jiàn),本(běn)工程只(zhī)需要(yào)生(shēng)成(chéng)默認的(de)即可(kě),所(suǒ)以(yǐ)不(bù)用(yòng)勾選。點(diǎn)擊Finish



1.8.3參考代(dài)碼
  1. always  @(posedge clk or negedge rst_n)begin
  2.     if(rst_n==1'b0)begin
  3.         result_neg_tmp <= 0;
  4.     end
  5.     else begin
  6.         result_neg_tmp <= result_neg;
  7.     end
  8. end

  9. always  @(*)begin
  10.     if(state_c==OP_2)begin
  11.         dis_sel = op_2;
  12.     end
  13.     else begin
  14.         dis_sel = op_1;
  15.     end
  16. end

  17. always  @(posedge clk or negedge rst_n)begin
  18.     if(rst_n==1'b0)begin
  19.         dis_sel_tmp <= 0;
  20.     end
  21.     else begin
  22.         dis_sel_tmp <= dis_sel;
  23.     end
  24. end




  25. div div_prj(
  26.             .clock      (clk        )   ,
  27.             .numer      (dis_tmp    )   ,
  28.             .denom      (10         )   ,
  29.             .quotient   (div_quo    )   ,
  30.             .remain     (div_rem    )
  31.             );

  32. always  @(posedge clk or negedge rst_n)begin
  33.     if(rst_n==1'b0)begin
  34.         flag_add <= 0;
  35.     end
  36.     else if(dis_sel!=dis_sel_tmp || result_neg!=result_neg_tmp)begin
  37.         flag_add <= 1;
  38.     end
  39.     else if(end_dis_cnt)begin
  40.         flag_add <= 0;
  41.     end
  42. end


  43. always @(posedge clk or negedge rst_n) begin
  44.     if (rst_n==0) begin
  45.         dis_cnt <= 0;
  46.     end
  47.     else if(add_dis_cnt) begin
  48.         if(end_dis_cnt)
  49.             dis_cnt <= 0;
  50.         else
  51.             dis_cnt <= dis_cnt+1 ;
  52.    end
  53. end
  54. assign add_dis_cnt = flag_add && (dis_sel==dis_sel_tmp && result_neg==result_neg_tmp);
  55. assign end_dis_cnt = add_dis_cnt  && dis_cnt == 10-1 ;


  56. assign  dis_tmp = add_dis_cnt && dis_cnt==1 ? dis_sel : div_quo;

  57. always  @(posedge clk or negedge rst_n)begin
  58.     if(rst_n==1'b0)begin
  59.         display <= 4'b0;
  60.     end
  61.     else if(state_c==ERROR)begin
  62.         display[4*(dis_cnt)-1 -:4] <= 4'b1111;
  63.     end
  64.     else if(end_dis_cnt && result_neg==1 && state_c!=OP_2)begin
  65.         display[31:28] <= 4'b1010;
  66.     end
  67.     else begin
  68.         display[4*(dis_cnt-1)-1 -:4] <= div_rem;
  69.     end
  70. end



  71. always  @(posedge clk or negedge rst_n)begin
  72.     if(rst_n==1'b0)begin
  73.         display_vld <= 0;
  74.     end
  75.     else begin
  76.         display_vld <= (dis_cnt==0 && (dis_sel==dis_sel_tmp)) ? 1'b1 : 1'b0;
  77.     end
  78. end
複制代(dài)碼


1.9 數碼管(guǎn)顯示模块(kuài)設計(jì)1.9.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)
Display
輸入(rù)
顯示數據(jù)輸入(rù)信(xìn)号(hào)
Display_vld
輸入(rù)
顯示數據(jù)有(yǒu)效指示信(xìn)号(hào)
Seg_sel
輸出(chū)
數碼管(guǎn)位選信(xìn)号(hào)
Segment
輸出(chū)
數碼管(guǎn)段(duàn)選信(xìn)号(hào)

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

本(běn)模块(kuài)主(zhǔ)要(yào)实現(xiàn)的(de)功能(néng)是(shì)对(duì)顯示对(duì)象(xiàng)選擇模块(kuài)的(de)顯示數據(jù)輸出(chū)信(xìn)号(hào)(display)進(jìn)行數碼管(guǎn)顯示。
1、  複位後(hòu),數碼管(guǎn)默認顯示運算數1;
2、  當result_err有(yǒu)效时(shí),數碼管(guǎn)顯示8个(gè)F;
3、  當result_neg有(yǒu)效时(shí),第(dì)8个(gè)數碼管(guǎn)顯示“—”;
4、  數碼管(guǎn)顯示display;
由(yóu)于(yú)數碼管(guǎn)顯示在(zài)前(qián)面(miàn)已有(yǒu)案(àn)例介紹,所(suǒ)以(yǐ)这(zhè)个(gè)就(jiù)不(bù)做介紹。感(gǎn)興趣的(de)同(tóng)学可(kě)以(yǐ)看(kàn)一(yī)下(xià)往期(qī)的(de)文(wén)章(zhāng):【每周FPGA案(àn)例】至(zhì)簡設計(jì)系(xì)列_7段(duàn)數碼管(guǎn)顯示

1.9.3參考代(dài)碼
  1. always @(posedge clk or negedge rst_n) begin
  2.     if (rst_n==0) begin
  3.         count_20us <= 0;
  4.     end
  5.     else if(add_count_20us) begin
  6.         if(end_count_20us)
  7.             count_20us <= 0;
  8.         else
  9.             count_20us <= count_20us+1 ;
  10.    end
  11. end
  12. assign add_count_20us = 1;
  13. assign end_count_20us = add_count_20us  && count_20us == TIME_20US-1 ;


  14. always @(posedge clk or negedge rst_n) begin
  15.     if (rst_n==0) begin
  16.         sel_cnt <= 0;
  17.     end
  18.     else if(add_sel_cnt) begin
  19.         if(end_sel_cnt)
  20.             sel_cnt <= 0;
  21.         else
  22.             sel_cnt <= sel_cnt+1 ;
  23.    end
  24. end
  25. assign add_sel_cnt = end_count_20us;
  26. assign end_sel_cnt = add_sel_cnt  && sel_cnt == 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 << sel_cnt);
  33.     end
  34. end

  35. always  @(posedge clk or negedge rst_n)begin
  36.     if(rst_n==1'b0)begin
  37.         display_ff0 <= 0;
  38.     end
  39.     else begin
  40.         for(ii=0;ii<SEG_NUM;ii=ii+1)begin
  41.             if(display_vld==1)begin
  42.                 display_ff0[(ii+1)*4-1 -:4] <= display[(ii+1)*4-1 -:4];
  43.             end
  44.             else begin
  45.                 display_ff0[(ii+1)*4-1 -:4] <= display_ff0[(ii+1)*4-1 -:4];
  46.             end
  47.         end
  48.     end
  49. end

  50. always  @(*)begin
  51.     seg_tmp = display_ff0[(sel_cnt+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.             0 :segment <=NUM_0  ;
  60.             1 :segment <=NUM_1  ;
  61.             2 :segment <=NUM_2  ;
  62.             3 :segment <=NUM_3  ;
  63.             4 :segment <=NUM_4  ;
  64.             5 :segment <=NUM_5  ;
  65.             6 :segment <=NUM_6  ;
  66.             7 :segment <=NUM_7  ;
  67.             8 :segment <=NUM_8  ;
  68.             9 :segment <=NUM_9  ;
  69.             10:segment <=NUM_10 ;
  70.            default:segment <= NUM_ERR;
  71.        endcase
  72.     end
  73. end
複制代(dài)碼


1.10 蜂鳴器模块(kuài)設計(jì)1.10.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)
Op_1_err
輸入(rù)
運算數1溢出(chū)信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效
Op_2_err
輸入(rù)
運算數2溢出(chū)信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效
Result_err
輸入(rù)
運算結果(guǒ)錯誤信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效
Beep
輸出(chū)
蜂鳴輸出(chū)信(xìn)号(hào),高(gāo)電(diàn)平有(yǒu)效

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

該模块(kuài)的(de)主(zhǔ)要(yào)功能(néng)是(shì)根(gēn)據(jù)接收(shōu)到(dào)的(de)各(gè)个(gè)錯誤指示信(xìn)号(hào),進(jìn)行報警提(tí)示。當接收(shōu)到(dào)錯誤信(xìn)号(hào)有(yǒu)效的(de)时(shí)候,蜂鳴器報警,持(chí)續1秒(miǎo)的(de)时(shí)間(jiān),因(yīn)此(cǐ)提(tí)出(chū)一(yī)个(gè)計(jì)數器的(de)架構,如(rú)下(xià)图(tú)所(suǒ)示:



主(zhǔ)要(yào)由(yóu)时(shí)鐘(zhōng)計(jì)數器cnt_1s和(hé)蜂鳴器輸出(chū)組成(chéng),下(xià)面(miàn)时(shí)两(liǎng)个(gè)信(xìn)号(hào)的(de)設計(jì)思(sī)路(lù):
时(shí)鐘(zhōng)計(jì)數器cnt_1s:該計(jì)數器的(de)作用(yòng)是(shì)計(jì)时(shí)1秒(miǎo)的(de)时(shí)間(jiān)。加一(yī)条(tiáo)件(jiàn)为(wèi)flag_add,表(biǎo)示進(jìn)入(rù)報警狀态的(de)时(shí)候便開(kāi)始計(jì)數。結束(shù)条(tiáo)件(jiàn)为(wèi)數5000_0000个(gè),系(xì)統时(shí)鐘(zhōng)为(wèi)50M,一(yī)个(gè)时(shí)鐘(zhōng)周期(qī)为(wèi)20ns5000_0000个(gè)时(shí)鐘(zhōng)周期(qī)就(jiù)是(shì)1秒(miǎo)。
蜂鳴器輸出(chū)信(xìn)号(hào)beep:初始狀态为(wèi)1,表(biǎo)示不(bù)報警。從1變(biàn)0的(de)条(tiáo)件(jiàn)为(wèi)op_1_err || op_2_err ||result_err,表(biǎo)示接收(shōu)到(dào)这(zhè)些錯誤指示信(xìn)号(hào)之後(hòu),開(kāi)始報警。從0變(biàn)1的(de)条(tiáo)件(jiàn)为(wèi)end_cnt_1s,表(biǎo)示報警时(shí)間(jiān)持(chí)續1秒(miǎo),之後(hòu)結束(shù)。

1.10.3參考代(dài)碼
  1. always @(posedge clk or negedge rst_n) begin
  2.     if (rst_n==0) begin
  3.         cnt_1s <= 0;
  4.     end
  5.     else if(add_cnt_1s) begin
  6.         if(end_cnt_1s)
  7.             cnt_1s <= 0;
  8.         else
  9.             cnt_1s <= cnt_1s+1 ;
  10.    end
  11. end
  12. assign add_cnt_1s = beep==0;
  13. assign end_cnt_1s = add_cnt_1s  && cnt_1s == CNT_1S-1 ;


  14. always  @(posedge clk or negedge rst_n)begin
  15.     if(rst_n==1'b0)begin
  16.         beep <= 1'b1;
  17.     end
  18.     else if(op_1_err || op_2_err || result_err)begin
  19.         beep <= 1'b0;
  20.     end
  21.     else if(end_cnt_1s)begin
  22.         beep <= 1'b1;
  23.     end
  24. end
複制代(dài)碼


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


1.11.1db603開(kāi)發(fà)板
由(yóu)于(yú)計(jì)算器的(de)演示是(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.11.2ms980試验(yàn)箱
由(yóu)于(yú)計(jì)算器的(de)演示是(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)德揚論壇学習!


感(gǎn)興趣的(de)朋友也(yě)可(kě)以(yǐ)訪問(wèn)明(míng)德揚論壇(http://www.FPGAbbs.cn/)進(jìn)行FPGA相關(guān)工程設計(jì)学習,也(yě)可(kě)以(yǐ)看(kàn)一(yī)下(xià)我(wǒ)们(men)往期(qī)的(de)文(wén)章(zhāng):

基于(yú)FPGA的(de)密碼鎖設計(jì)
波(bō)形相位頻率可(kě)調DDS信(xìn)号(hào)發(fà)生(shēng)器
基于(yú)FPGA的(de)曼徹斯特(tè)編碼解(jiě)碼設計(jì)
基于(yú)FPGA的(de)出(chū)租車計(jì)費系(xì)統
數電(diàn)基礎與(yǔ)Verilog設計(jì)
基于(yú)FPGA的(de)頻率、電(diàn)壓测量(liàng)
基于(yú)FPGA的(de)漢明(míng)碼編碼解(jiě)碼設計(jì)
關(guān)于(yú)鎖存器問(wèn)題(tí)的(de)讨論
阻塞賦值與(yǔ)非(fēi)阻塞賦值

參數例化(huà)时(shí)自(zì)動(dòng)計(jì)算位宽(kuān)的(de)解(jiě)決辦(bàn)法


1.12 公司簡介
明(míng)德揚是(shì)一(yī)家(jiā)專注于(yú)FPGA領域的(de)專業性(xìng)公司,公司主(zhǔ)要(yào)業务包(bāo)括開(kāi)發(fà)板、教育培訓、項目承接、人(rén)才服(fú)务等多(duō)个(gè)方(fāng)向(xiàng)。點(diǎn)撥開(kāi)發(fà)板——学習FPGA的(de)入(rù)門(mén)之選。
MP801
開(kāi)發(fà)板——千(qiān)兆(zhào)网(wǎng)、ADDA、大容量(liàng)SDRAM等,学習和(hé)項目需求一(yī)步到(dào)位。网(wǎng)絡培訓班——不(bù)管(guǎn)时(shí)間(jiān)和(hé)空間(jiān),明(míng)德揚随时(shí)在(zài)你身(shēn)邊(biān),助你快(kuài)速学習FPGA周末(mò)培訓班——明(míng)天(tiān)的(de)你会(huì)感(gǎn)激現(xiàn)在(zài)的(de)努力進(jìn)取(qǔ),升(shēng)職加薪明(míng)德揚来(lái)助你。就(jiù)業培訓班——七(qī)大企業級項目实訓,獲得豐富的(de)項目經(jīng)验(yàn),高(gāo)薪就(jiù)業。專題(tí)課程——高(gāo)手(shǒu)修煉課:提(tí)升(shēng)設計(jì)能(néng)力;实用(yòng)調試技巧課:提(tí)升(shēng)定(dìng)位和(hé)解(jiě)決問(wèn)題(tí)能(néng)力;FIFO架構設計(jì)課:助你快(kuài)速成(chéng)为(wèi)架構設計(jì)师(shī);时(shí)序約束(shù)、數字(zì)信(xìn)号(hào)处理、PCIE、綜合項目实踐課等你来(lái)選。項目承接——承接企業FPGA研發(fà)項目。人(rén)才服(fú)务——提(tí)供人(rén)才推薦、人(rén)才代(dài)培、人(rén)才派遣等服(fú)务。
上(shàng)一(yī)篇(piān):【案(àn)例】BCD譯碼实現(xià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⁥⁠⁢

⁧⁨⁥⁨