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

  發(fà)布(bù)时(shí)間(jiān):2023-10-18  |    作者(zhě):管(guǎn)理員  |  浏覽量(liàng):1343
本(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思(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)接:


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)德揚論壇学習!



温(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⁥⁠⁢

⁧⁨⁥⁨