0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于FPGA的電子計(jì)算器系統(tǒng)設(shè)計(jì)(附代碼)

FPGA技術(shù)江湖 ? 來(lái)源:FPGA技術(shù)江湖 ? 作者:FPGA技術(shù)江湖 ? 2022-11-15 09:24 ? 次閱讀

大俠好,歡迎來(lái)到FPGA技術(shù)江湖,江湖偌大,相見(jiàn)即是緣分。大俠可以關(guān)注FPGA技術(shù)江湖,在“闖蕩江湖”、"行俠仗義"欄里獲取其他感興趣的資源,或者一起煮酒言歡。

今天給大俠帶來(lái)基于FPGA的電子計(jì)算器設(shè)計(jì)。話不多說(shuō),上貨。

導(dǎo)讀

本篇介紹了一個(gè)簡(jiǎn)單計(jì)算器的設(shè)計(jì),基于 FPGA 硬件描述語(yǔ)言 Verilog HDL,系統(tǒng)設(shè)計(jì)由計(jì)算部分、顯示部分和輸入部分四個(gè)部分組成,計(jì)算以及存儲(chǔ)主要用狀態(tài)機(jī)來(lái)實(shí)現(xiàn)。顯示部分由六個(gè)七段譯碼管組成,分別來(lái)顯示輸入數(shù)字,輸入部分采用4*4矩陣鍵盤,由0-9一共十個(gè)數(shù)字按鍵,加減乘除四個(gè)運(yùn)算符按鍵,一個(gè)等號(hào)按鍵組成的。通過(guò)外部的按鍵可以完成加、減、乘、除四種功能運(yùn)算,其結(jié)構(gòu)簡(jiǎn)單,易于實(shí)現(xiàn)。本篇為本人畢業(yè)設(shè)計(jì)部分整理,各位大俠可依據(jù)自己的需要進(jìn)行閱讀,參考學(xué)習(xí)。

前言

在國(guó)外,電子計(jì)算器在集成電路發(fā)明后,只用短短幾年時(shí)間就完成了技術(shù)飛躍,經(jīng)過(guò)激烈的市場(chǎng)競(jìng)爭(zhēng),現(xiàn)在的計(jì)算器技術(shù)己經(jīng)相當(dāng)成熟。計(jì)算器已慢慢地脫離原來(lái)的“輔助計(jì)算工具”的功能定位,正在向著多功能化、可編程化方向發(fā)展,在各個(gè)領(lǐng)域都得到了廣泛的應(yīng)用。用計(jì)算器不僅可以實(shí)現(xiàn)各種各樣復(fù)雜的數(shù)學(xué)計(jì)算還可以用來(lái)編制、運(yùn)行程序,甚至解方程組,圖形計(jì)算器還可以進(jìn)行圖形處理。計(jì)算器內(nèi)置的軟件允許用戶進(jìn)行類似于對(duì)計(jì)算機(jī)的文件和目錄管理等操作,允許用戶對(duì)圖形界面進(jìn)行定制,同時(shí)各種新技術(shù)也被應(yīng)用到計(jì)算器里使計(jì)算器功能越來(lái)越強(qiáng)大??梢哉f(shuō),計(jì)算器就是一個(gè)“微微型”的計(jì)算機(jī)。國(guó)內(nèi)也有廠商利用計(jì)算器芯片開(kāi)發(fā)新的產(chǎn)品,但對(duì)計(jì)算器技術(shù)的研究、計(jì)算器芯片的設(shè)計(jì)還處于起步階段。計(jì)算器的主要功能還是在于“計(jì)算”,不妨稱之為“低檔計(jì)算器”。即便是對(duì)這種計(jì)算器,很多廠商也只從事計(jì)算器的組裝、銷售業(yè)務(wù)。一些IC設(shè)計(jì)公司、芯片提供商也開(kāi)始研究計(jì)算器技術(shù)。

本次設(shè)計(jì)基于現(xiàn)場(chǎng)可編程邏輯器件FPGA進(jìn)行設(shè)計(jì),應(yīng)用硬件描述語(yǔ)言Verilog編程并在Altera公司的QuartusⅡ軟件上實(shí)現(xiàn)仿真。需要進(jìn)行計(jì)算器的常用運(yùn)算功能的實(shí)現(xiàn),通過(guò)外接鍵盤輸入、LED數(shù)碼顯示來(lái)達(dá)成運(yùn)算目的。

一、緒論

Verilog HDL 是一種硬件描述語(yǔ)言(HDL:Hardware Description Language),以文本形式來(lái)描述數(shù)字系統(tǒng)硬件的結(jié)構(gòu)和行為的語(yǔ)言,用它可以表示邏輯電路圖、邏輯表達(dá)式,還可以表示數(shù)字邏輯系統(tǒng)所完成的邏輯功能。Verilog HDL和VHDL是世界上最流行的兩種硬件描述語(yǔ)言,都是在20世紀(jì)80年代中期開(kāi)發(fā)出來(lái)的。前者由Gateway Design Automation公司(該公司于1989年被Cadence公司收購(gòu)開(kāi)發(fā))。兩種HDL均為IEEE標(biāo)準(zhǔn)。

1.1 Verilog HDL的發(fā)展

Verilog是由Gateway設(shè)計(jì)自動(dòng)化公司的工程師于1983年末創(chuàng)立的。當(dāng)時(shí)Gateway設(shè)計(jì)自動(dòng)化公司還叫做自動(dòng)集成設(shè)計(jì)系統(tǒng)(Automated Integrated Design Systems),1985年公司將名字改成了前者。該公司的菲爾·莫比(Phil Moor by)完成了Verilog的主要設(shè)計(jì)工作。1990年,Gateway設(shè)計(jì)自動(dòng)化被Cadence公司收購(gòu)。

1990年代初,開(kāi)放Verilog國(guó)際(Open Verilog International,OVI)組織(即現(xiàn)在的Accellera)成立,Verilog面向公有領(lǐng)域開(kāi)放。1992年,該組織尋求將Verilog納入電氣電子工程師學(xué)會(huì)標(biāo)準(zhǔn)。最終,Verilog成為了電氣電子工程師學(xué)會(huì)1364-1995標(biāo)準(zhǔn),即通常所說(shuō)的Verilog-95。

設(shè)計(jì)人員在使用這個(gè)版本的Verilog的過(guò)程中發(fā)現(xiàn)了一些可改進(jìn)之處。為了解決用戶在使用此版本Verilog過(guò)程中反映的問(wèn)題,Verilog進(jìn)行了修正和擴(kuò)展,這部分內(nèi)容后來(lái)再次被提交給電氣電子工程師學(xué)會(huì)。這個(gè)擴(kuò)展后的版本后來(lái)成為了電氣電子工程學(xué)會(huì)1364-2001標(biāo)準(zhǔn),即通常所說(shuō)的Verilog-2001。Verilog-2001是對(duì)Verilog-95的一個(gè)重大改進(jìn)版本,它具備一些新的實(shí)用功能,例如敏感列表、多維數(shù)組、生成語(yǔ)句塊、命名端口連接等。目前,Verilog-2001是Verilog的最主流版本,被大多數(shù)商業(yè)電子設(shè)計(jì)自動(dòng)化軟件包支持。

2005年,Verilog再次進(jìn)行了更新,即電氣電子工程師學(xué)會(huì)1364-2005標(biāo)準(zhǔn)。該版本只是對(duì)上一版本的細(xì)微修正。這個(gè)版本還包括了一個(gè)相對(duì)獨(dú)立的新部分,即Verilog-AMS。這個(gè)擴(kuò)展使得傳統(tǒng)的Verilog可以對(duì)集成的模擬和混合信號(hào)系統(tǒng)進(jìn)行建模。容易與電氣電子工程師學(xué)會(huì)1364-2005標(biāo)準(zhǔn)混淆的是加強(qiáng)硬件驗(yàn)證語(yǔ)言特性的SystemVerilog(電氣電子工程師學(xué)會(huì)1800-2005標(biāo)準(zhǔn)),它是Verilog-2005的一個(gè)超集,它是硬件描述語(yǔ)言、硬件驗(yàn)證語(yǔ)言(針對(duì)驗(yàn)證的需求,特別加強(qiáng)了面向?qū)ο筇匦裕┑囊粋€(gè)集成。

2009年,IEEE 1364-2005和IEEE 1800-2005一共兩個(gè)部分合并為IEEE 1800-2009,成為了一個(gè)新的、統(tǒng)一的SystemVerilog硬件描述驗(yàn)證語(yǔ)言(hardware description and verification language,HDVL)。

1.2VerilogHDL的特點(diǎn)

描述復(fù)雜的硬件電路,設(shè)計(jì)人員總是將復(fù)雜的功能劃分為簡(jiǎn)單的功能,模塊是提供每個(gè)簡(jiǎn)單功能的基本結(jié)構(gòu)。設(shè)計(jì)人員可以采取“自頂向下”的思路,將復(fù)雜的功能模塊劃分為低層次的模塊。這一步通常是由系統(tǒng)級(jí)的總設(shè)計(jì)師完成,而低層次的模塊則由下一級(jí)的設(shè)計(jì)人員完成。自頂向下的設(shè)計(jì)方式有利于系統(tǒng)級(jí)別層次劃分和管理,并提高了效率、降低了成本?!白缘紫蛏稀狈绞绞恰白皂斚蛳隆狈绞降哪孢^(guò)程。

1.3VerilogHDL的語(yǔ)言結(jié)構(gòu)

Verilog的設(shè)計(jì)初衷是成為一種基本語(yǔ)法與C語(yǔ)言相近的硬件描述語(yǔ)言。這是因?yàn)镃語(yǔ)言在Verilog設(shè)計(jì)之初,已經(jīng)在許多領(lǐng)域得到廣泛應(yīng)用,C語(yǔ)言的許多語(yǔ)言要素已經(jīng)被許多人習(xí)慣。一種與C語(yǔ)言相似的硬件描述語(yǔ)言,可以讓電路設(shè)計(jì)人員更容易學(xué)習(xí)和接受。不過(guò),Verilog與C語(yǔ)言還是存在許多差別。另外,作為一種與普通計(jì)算機(jī)編程語(yǔ)言不同的硬件描述語(yǔ)言,它還具有一些獨(dú)特的語(yǔ)言要素,例如向量形式的線網(wǎng)和寄存器、過(guò)程中的非阻塞賦值等。總的來(lái)說(shuō),具備C語(yǔ)言的設(shè)計(jì)人員將能夠很快掌握Verilog硬件描述語(yǔ)言。下面介紹Verilog語(yǔ)言基本規(guī)范:

1)空白符

空白符是指代碼中的空格(對(duì)應(yīng)的轉(zhuǎn)義標(biāo)識(shí)符為)、制表符( )和換行( )。如果這些空白符出現(xiàn)在字符串里,那么它們不可忽略。除此之外,代碼中的其他空白符在編譯的時(shí)候都將會(huì)被視為分隔標(biāo)識(shí)符,即使用2個(gè)空格或者1個(gè)空格并無(wú)影響。不過(guò),在代碼中使用合適的空格,可以讓上下行代碼的外觀一致(例如使賦值運(yùn)算符位于同一個(gè)豎直列),從而提高代碼的可讀性。

2)注釋

為了方便代碼的修改或其他人的閱讀,設(shè)計(jì)人員通常會(huì)在代碼中加入注釋。與C語(yǔ)言一樣,有兩種方式書(shū)寫(xiě)注釋。第一種為多行注釋,即注釋從/*開(kāi)始,直到*/才結(jié)束;另一種為單行注釋,注釋從//開(kāi)始,從這里到這一行末尾的內(nèi)容會(huì)被系統(tǒng)識(shí)別為注釋。

3)某些電子設(shè)計(jì)自動(dòng)化工具,會(huì)識(shí)別出代碼中以特殊格式書(shū)寫(xiě)、含有某些預(yù)先約定關(guān)鍵詞的注釋,并從這些注釋所提取有用的信息。這些注釋不是供人閱讀,而是向第三方工具提供有關(guān)設(shè)計(jì)項(xiàng)目的額外信息。例如,某些邏輯綜合工具可以從注釋中讀取綜合的約束信息。

4)大小寫(xiě)敏感性

Verilog是一種大小寫(xiě)敏感的硬件描述語(yǔ)言。其中,它的所有系統(tǒng)關(guān)鍵字都是小寫(xiě)的。

5)標(biāo)識(shí)符及保留字

Verilog代碼中用來(lái)定義語(yǔ)言結(jié)構(gòu)名稱的字符稱為標(biāo)識(shí)符,包括變量名、端口名、模塊名等等。標(biāo)識(shí)符可以由字母、數(shù)字、下劃線以及美元符($)來(lái)表示。但是標(biāo)識(shí)符的第一個(gè)字符只能是字母、數(shù)字或者下劃線,不能為美元符,這是因?yàn)橐悦涝_(kāi)始的標(biāo)識(shí)符和系統(tǒng)任務(wù)的保留字沖突。

和其他許多編程語(yǔ)言類似,Verilog也有許多保留字(或稱為關(guān)鍵字),用戶定義的標(biāo)識(shí)符不能夠和保留字相同。Verilog的保留字均為小寫(xiě)。變量類型中的wire、reg、integer等、表示過(guò)程的initial、always等,以及所有其他的系統(tǒng)任務(wù)、編譯指令,都是關(guān)鍵字??梢圆殚喒俜轿墨I(xiàn)以完整的關(guān)鍵字的列表。

1.4 FPGA開(kāi)發(fā)環(huán)境簡(jiǎn)介

系統(tǒng)電路的軟件設(shè)計(jì)可采用工具軟件Quartus Ⅱ,用該工具軟件所支持的語(yǔ)言——硬件描述語(yǔ)言,以文本的方式進(jìn)行編程輸入。在編程時(shí)分別對(duì)控制、計(jì)數(shù)、鎖存、譯碼等電路模塊進(jìn)行Verilog文本描述,使每個(gè)電路模塊以及器件都以文本的形式出現(xiàn),然后通過(guò)編譯、波形分析、仿真、調(diào)試來(lái)完善每個(gè)器件的功能。單個(gè)器件制作完成后,然后將它們生成庫(kù)文件,并產(chǎn)生相應(yīng)的符號(hào),最后用語(yǔ)言將各個(gè)已生成庫(kù)文件的器件的各個(gè)端口連接在一起,從而形成了系統(tǒng)主電路的軟件結(jié)構(gòu)。在連接器件時(shí),也可以采用圖形輸入方式,即在圖形輸入界面中調(diào)出先制作好的庫(kù)文件器件符號(hào),再將每個(gè)器件符號(hào)的各端口直接連線,從而構(gòu)成系統(tǒng)主電路。在上述工作的基礎(chǔ)上,再進(jìn)行波形分析、仿真調(diào)試便完成整個(gè)軟件設(shè)計(jì)。

二、現(xiàn)場(chǎng)可編程門陣列(FPGA)簡(jiǎn)介

2.1可編程邏輯器件簡(jiǎn)介

可編程邏輯器件(PLD——Programmable Logic Devices)是一種由用戶編程以實(shí)現(xiàn)某種邏輯功能的新型邏輯器件。它誕生于20世紀(jì)70年代,在20世紀(jì)80年代以后,隨著集成電路技術(shù)和計(jì)算機(jī)技術(shù)的發(fā)展而迅速發(fā)展起來(lái)的??删幊踢壿嬈骷詥?wèn)世以來(lái),PLD經(jīng)歷了從PROM、PLA、PAL、GAL到FPGA、ispLSI等高密度PLD的發(fā)展過(guò)程。在此期間,PLD的集成度、速度不斷提高,功能不斷增強(qiáng),結(jié)構(gòu)趨于更合理,使用變得更靈活方便。PLD的出現(xiàn)打破了由中小型通用型集成電路和大規(guī)模專用集成電路壟斷的局面。與中小規(guī)模通用型集成電路相比,用PLD實(shí)現(xiàn)數(shù)字系統(tǒng),有研制周期短、先期投資少、無(wú)風(fēng)險(xiǎn)、修改邏輯設(shè)計(jì)方便、小批量生產(chǎn)成本低等優(yōu)勢(shì)。

隨著可編程邏輯器件性能價(jià)格比的不斷提高,EDA開(kāi)發(fā)軟件的不斷完善,現(xiàn)代電子系統(tǒng)的設(shè)計(jì)將越來(lái)越多地使用可編程邏輯器件,特別是大規(guī)??删幊踢壿嬈骷?。如果說(shuō)一個(gè)電子系統(tǒng)可以像積木堆積起來(lái)的話,那么現(xiàn)在構(gòu)成許多電子系統(tǒng)僅僅需要3種標(biāo)準(zhǔn)的積木塊——微處理器、存儲(chǔ)器和可編程邏輯器件,甚至只需一塊大規(guī)??删幊踢壿嬈骷?。PAL(Programmable Array Logic)器件是20世紀(jì)70年代末期出現(xiàn)的一種低密度、一次性可編程邏輯器件。GAL(Generic Array Logic)器件是繼PAL器件之后,在20世紀(jì)80年代中期推出的一種低密度可編程邏輯器件。它在結(jié)構(gòu)上采用了輸出邏輯宏單元(OLMC——Output Logic Macro Cell)結(jié)構(gòu)形式,在工藝上吸收EEPROM的浮柵技術(shù),從而使GAL器件具有可擦除、可重新編程、數(shù)據(jù)可長(zhǎng)期保存的結(jié)構(gòu)特點(diǎn)。CPLD(Complex Programmable Logic Device)是萬(wàn)門以上的復(fù)雜可編程邏輯器件,采用CMOS EPROM、EEPROM、快閃存儲(chǔ)器和SRAM等編程技術(shù),從而構(gòu)成高密度、高速度和低功耗的可編程邏輯器件。

2.2現(xiàn)場(chǎng)可編程門陣列(FPGA)

FPGA是現(xiàn)場(chǎng)可編程門陣列(Field Programmable Gate Array)的簡(jiǎn)稱。FPGA器件及其開(kāi)發(fā)系統(tǒng)是開(kāi)發(fā)大規(guī)模數(shù)字集成電路的新技術(shù)。它利用計(jì)算機(jī)輔助設(shè)計(jì),繪制出實(shí)現(xiàn)用戶邏輯的原理圖、編輯布爾方程或用硬件描述語(yǔ)言等方式作為設(shè)計(jì)輸入;然后經(jīng)一系列轉(zhuǎn)換程序、自動(dòng)布局布線、模擬仿真的過(guò)程;最后生成配置FPGA器件的數(shù)據(jù)文件,對(duì)FPGA器件初始化。這樣就實(shí)現(xiàn)了滿足用戶要求的專用集成電路,真正達(dá)到了用戶自行設(shè)計(jì)、自行研制和自行生產(chǎn)集成電路的目的。

FPGA是一種半定制的集成電路,其特點(diǎn)是直接面向用戶,具有極大的靈活性和通用性,開(kāi)發(fā)效率高,硬件測(cè)試和實(shí)現(xiàn)快捷,工作可靠性好而且技術(shù)維護(hù)簡(jiǎn)單。

FPGA相對(duì)于CPLD而言,其結(jié)構(gòu)特點(diǎn)在于FPGA是基于查找表look-up-table的。查找表(look-up-table)簡(jiǎn)稱為L(zhǎng)UT,LUT本質(zhì)上是一個(gè)RAM。FPGA使用4輸入的LUT,所以每一個(gè)LUT 可以看成一個(gè)有4位地址線的16*1的RAM。當(dāng)用戶通過(guò)原理圖或HDL語(yǔ)言描述了一個(gè)邏輯電路后,PLD/FPGA開(kāi)發(fā)軟件會(huì)自動(dòng)計(jì)算邏輯電路的所有可能的結(jié)果,并把結(jié)果事先寫(xiě)入RAM,這樣,每輸入一個(gè)信號(hào)進(jìn)行邏輯運(yùn)算就等于輸入一個(gè)地址進(jìn)行查表,找出地址對(duì)應(yīng)的內(nèi)容,然后輸出即可。

2.2.1FPGA的器件結(jié)構(gòu)與工作原理

FPGA(Field Programmable Gate Array)即現(xiàn)場(chǎng)可編程邏輯陣列,是大規(guī)??删幊碳呻娐返闹髁髌骷PGA一般由三種可編程電路和一個(gè)用于存放編程數(shù)據(jù)的SRAM(靜態(tài)隨機(jī)存儲(chǔ)器)組成,這三種可編程電路是:可編程邏輯陣列LAB(Logic Array Block),輸入輸出模塊IOB(I/O Block)和互連資源IR(Interconnect Resource)。FPGA可編程邏輯形成的方法是基于查找表LUT(Look Up Table)結(jié)構(gòu)的,LUT是可編程的最小邏輯構(gòu)成單元。

1)可編程邏輯陣列LAB

可編程邏輯陣列是由一系列相鄰的邏輯單元LE(Logic Element)構(gòu)成的,每個(gè)LAB包括八個(gè)邏輯單元LE、相連的進(jìn)位鏈和級(jí)聯(lián)鏈,LAB控制信號(hào)和LAB局部互連。LAB的構(gòu)成、ACEK系列芯片的“粗粒度(coarse-grained)”結(jié)構(gòu),有利于EDA軟件進(jìn)行布局布線,優(yōu)化器件的利用進(jìn)而提高整個(gè)數(shù)字系統(tǒng)的性。

其中的邏輯單元LE是一種基于查找表的函數(shù)發(fā)生器。它能夠?qū)崿F(xiàn)4輸入1輸出的任意邏輯函數(shù)。每個(gè)LE包含一個(gè)4輸入的查找表、一個(gè)帶有同步使能的可編程觸發(fā)器、一個(gè)進(jìn)位鏈和一個(gè)級(jí)聯(lián)鏈。每個(gè)LE有兩個(gè)輸出分別可以驅(qū)動(dòng)局部互連和快速通道互連。LE有兩個(gè)輸出驅(qū)動(dòng)內(nèi)部互連,一個(gè)是驅(qū)動(dòng)局部互連輸出,另一個(gè)驅(qū)動(dòng)行或列的快速通道Fast Track的互連輸出,這兩個(gè)輸出可以單獨(dú)控制。因此在一個(gè)邏輯單元LE中的觸發(fā)器和查找表能夠用來(lái)完成不相關(guān)的功能,從而提高LE的資源利用率。

在ACEK系列芯片的結(jié)構(gòu)中還提供了兩種專用的高速數(shù)據(jù)通道,用于連接相鄰的LE,但不占用局部互連通路,它們是進(jìn)位鏈和級(jí)聯(lián)鏈。進(jìn)位鏈用來(lái)支持高速計(jì)數(shù)器和加法器,它提供了LE之間的快速向前進(jìn)位功能。來(lái)自低位的進(jìn)位信號(hào)經(jīng)進(jìn)位鏈向前直接送到高位,同時(shí)反饋入查找表和進(jìn)位鏈的下一段。這種特點(diǎn)使得ACEK結(jié)構(gòu)能夠?qū)崿F(xiàn)高速計(jì)數(shù)器、加法器和寬位比較器。級(jí)聯(lián)鏈可以用來(lái)實(shí)現(xiàn)多輸入數(shù)的邏輯函數(shù)。相鄰的查找表并行地完成部分邏輯功能,級(jí)聯(lián)鏈把中間結(jié)果拼接起來(lái)。進(jìn)位鏈和級(jí)聯(lián)鏈的使用有利于提高器件的工作速度,但是大量使用進(jìn)位鏈和級(jí)聯(lián)鏈會(huì)限制布局布線的靈活性,導(dǎo)致資源的浪費(fèi)。因此在設(shè)計(jì)過(guò)程應(yīng)該權(quán)衡考慮,在FPGA芯片資源利用和工作速度之間尋求平衡。

2)輸入/輸出模塊IOB

ACEK器件的I/O引腳是由一些I/O單元驅(qū)動(dòng)的。IOE(I/O Element)位于快速通道的行和列末端,包含一個(gè)雙向的緩沖器和一個(gè)寄存器。這個(gè)寄存器可以用作需要快速建立時(shí)間的外部數(shù)據(jù)輸入寄存器,也可以作為需要快速“時(shí)鐘到輸出”性能的數(shù)據(jù)輸出寄存器。IOE可以配置成輸入、輸出或雙向口。

ACEK器件中的IOE具有許多特性,支持JTAG編程、三態(tài)緩沖和漏極開(kāi)路輸出等等。每個(gè)IOE的時(shí)鐘、清零、時(shí)鐘使能和輸出使能的控制均由I/O控制信號(hào)網(wǎng)絡(luò)提供,采用高速驅(qū)動(dòng)以減小通過(guò)器件的時(shí)間偏差。此外,ACEK器件還提供了若干專用輸入引腳,這些引腳用來(lái)驅(qū)動(dòng)IOE寄存器的控制端,使用了專用的布線通道,以便具有比快速通道更短的延遲和更小的偏差。

3)互連資源IR

可編程的互連資源包括各種長(zhǎng)度的金屬連線線段和一些可編程的連線開(kāi)關(guān),它們將各個(gè)邏輯陣列之間、及其與IO模塊之間互相連接起來(lái),構(gòu)成各種功能復(fù)雜的系統(tǒng)。

在ACEK中互連結(jié)構(gòu)是通過(guò)快速通道(Fast Track)實(shí)現(xiàn)的。Fast Track遍布于整個(gè)ACEK器件,是一系列水平和垂直走向的連續(xù)式布線通道。每一行的LAB都有一個(gè)專用的“行互連”,“行互連”可以驅(qū)動(dòng)。I/O引腳或饋送到器件中的其LAB;“列互連”連接各行,也能驅(qū)動(dòng)I/O引腳。這種布線結(jié)構(gòu)能夠有效提高布線效率,使得即使非常復(fù)雜的設(shè)計(jì)也能夠測(cè)定其延時(shí)性。

4)嵌入式陣列塊EAB

嵌入式陣列塊EAB是在輸入輸出口上帶有寄存器的靈活的RAM塊,是由一系列嵌式RAM單元組成的。EAB的邏輯功能是在配置期間,用只讀模式對(duì)EAB編程產(chǎn)生一個(gè)大型查找表來(lái)實(shí)現(xiàn)的。采用查找表實(shí)現(xiàn)組合邏輯比一般算法快,EAB的快速時(shí)間通道使得這一先進(jìn)性能進(jìn)一步得到加強(qiáng)。當(dāng)要實(shí)現(xiàn)存儲(chǔ)器功能時(shí),每個(gè)EAB提供2048比特位,每一個(gè)EAB是一個(gè)獨(dú)立的結(jié)構(gòu),它具有共同的輸入、互連和控制信號(hào)。每個(gè)EAB含有一個(gè)行互連饋端,EAB的輸出能夠同時(shí)驅(qū)動(dòng)行互連通道和列互連通道。這一特性增加了EAB的可利用布線資源。因此,EAB可以非常方便地用于實(shí)現(xiàn)一些規(guī)模不大的RAM、ROM、FIFO等功能模塊;同時(shí)在實(shí)現(xiàn)地址譯碼器、狀態(tài)機(jī)、微控制器等復(fù)雜邏輯時(shí)也具備了一定優(yōu)勢(shì)。

2.2.2基于EDA平臺(tái)的FPGA開(kāi)發(fā)流程

一個(gè)完整、典型的EDA設(shè)計(jì)流程即是自頂向下設(shè)計(jì)方法的具體實(shí)施過(guò)程,也是EDA軟件本身的組成結(jié)構(gòu)。在實(shí)踐中進(jìn)一步了解支持這一個(gè)設(shè)計(jì)流程的諸多設(shè)計(jì)工具,有利于排解設(shè)計(jì)中的具體問(wèn)題,提高設(shè)計(jì)質(zhì)量。

1)設(shè)計(jì)輸入

基于EDA軟件平臺(tái)的FPGA開(kāi)發(fā)流程,一般有兩種設(shè)計(jì)輸入方式:圖形輸入和硬件描述語(yǔ)言文本輸入。下面將重點(diǎn)介紹采用Verilog硬件描述語(yǔ)言進(jìn)行設(shè)計(jì)輸入方法,這是我們?cè)谠O(shè)計(jì)開(kāi)發(fā)過(guò)程中采用的主要方法。Verilog作為電子工程主流硬件描述語(yǔ)言,是EDA技術(shù)的重要組成部分。它于1983年由美國(guó)國(guó)防部創(chuàng)建,由IEEE協(xié)會(huì)進(jìn)一步發(fā)展并在1987年成為IEEE國(guó)際標(biāo)準(zhǔn)。自IEEE協(xié)會(huì)公布了Verilog標(biāo)準(zhǔn)版本(IEEE Std 1076)之后,各大EDA公司相繼推出支持Verilog語(yǔ)言的開(kāi)發(fā)環(huán)境。從此Verilog作為硬件描述語(yǔ)言的業(yè)界標(biāo)準(zhǔn)之一,在電子設(shè)計(jì)領(lǐng)域得到廣泛應(yīng)用,并逐步成為事實(shí)上的通用硬件描述語(yǔ)言。

Verilog語(yǔ)言具有很強(qiáng)的電路建模能力,具有良好的電路行為描述和系統(tǒng)描述的能力,能從多個(gè)層次對(duì)數(shù)字系統(tǒng)進(jìn)行建模和描述;Verilog語(yǔ)言還具有與硬件電路無(wú)關(guān)和設(shè)計(jì)平臺(tái)無(wú)關(guān)的特性,并且在語(yǔ)言易讀性和層次化結(jié)構(gòu)化設(shè)計(jì)方面表現(xiàn)了強(qiáng)大的生命力和應(yīng)用潛力。這些特性使得Verilog語(yǔ)言在支持自頂向下的EDA設(shè)計(jì)流程方面顯得游刃有余。因此,采用Verilog進(jìn)行電子系統(tǒng)設(shè)計(jì)可以讓設(shè)計(jì)者專心致力于其功能的實(shí)現(xiàn),而不需要對(duì)不影響功能的與工藝相關(guān)的問(wèn)題花費(fèi)過(guò)多的時(shí)間和精力,提高了設(shè)計(jì)效率和可靠性。

采用Verilog文本設(shè)計(jì)輸入與傳統(tǒng)的計(jì)算機(jī)軟件語(yǔ)言編輯輸入基本上一樣,就是使用Verilog描述數(shù)字系統(tǒng)的功能,進(jìn)行文本編輯輸入。事實(shí)上,純粹的Verilog設(shè)計(jì)輸入方法仍然是最基本、最有效和最普遍的設(shè)計(jì)輸入方法。

2)設(shè)計(jì)綜合

在電子設(shè)計(jì)領(lǐng)域“綜合”的概念可以表示為:將行為和功能層次表達(dá)的電子系統(tǒng)轉(zhuǎn)化為低層次的便于具體實(shí)現(xiàn)的模塊組合裝配而成的過(guò)程。事實(shí)上,設(shè)計(jì)過(guò)程通常從高層次的行為描述開(kāi)始,直到最底層的結(jié)構(gòu)描述結(jié)束,每一個(gè)步驟都是上一個(gè)層次的綜合轉(zhuǎn)換。在FPGA設(shè)計(jì)開(kāi)發(fā)過(guò)程中,整個(gè)綜合過(guò)程就是設(shè)計(jì)者在EDA軟件平臺(tái)上編輯輸入Verilog文本,依據(jù)給定電路結(jié)構(gòu)組件和約束控制條件進(jìn)行編譯、優(yōu)化、轉(zhuǎn)換和綜合,最終獲得門級(jí)電路甚至更底層的電路描述網(wǎng)表文件。因此設(shè)計(jì)綜合的過(guò)程就是將軟件設(shè)計(jì)的Verilog描述文本與硬件結(jié)構(gòu)掛鉤,是軟件描述轉(zhuǎn)化為硬件電路的關(guān)鍵步驟,是文本描述與硬件實(shí)現(xiàn)之間的一座橋梁。

3)結(jié)構(gòu)適配

適配器也稱為結(jié)構(gòu)綜合器,它的功能是將綜合器產(chǎn)生的網(wǎng)表文件配置于指定的FPGA目標(biāo)器件中,使之產(chǎn)生最終的下載文件。適配過(guò)程中所選定的FPGA目標(biāo)器件必須屬于綜合器原來(lái)指定的目標(biāo)器件系列,這是因?yàn)檫m配器的適配對(duì)象是直接與器件的結(jié)構(gòu)細(xì)節(jié)相對(duì)應(yīng)的。邏輯綜合通過(guò)后必須利用適配器將綜合后的網(wǎng)表文件針對(duì)某一具體目標(biāo)器件進(jìn)行邏輯映射操作,其中包括底層器件配置、邏輯分割、邏輯優(yōu)化、邏輯布局布線操作。適配完成后可以利用適配所產(chǎn)生的仿真文件作精確的時(shí)序仿真,同時(shí)產(chǎn)生可用于編程下載文件。

4)功能仿真和時(shí)序仿真

在編程下載前必須利用EDA工具對(duì)配置生成的結(jié)果進(jìn)行模擬分析,這就是所謂的仿真。仿真的過(guò)程就是讓計(jì)算機(jī)根據(jù)一定的算法和一定的仿真庫(kù)對(duì)EDA設(shè)計(jì)進(jìn)行模擬,以驗(yàn)證設(shè)計(jì),排除錯(cuò)誤。仿真包括功能仿真和時(shí)序仿真。

功能仿真:不經(jīng)過(guò)綜合和適配階段,在設(shè)計(jì)項(xiàng)目編譯后直接進(jìn)入門級(jí)仿真器進(jìn)行模擬測(cè)試。主要用于測(cè)試設(shè)計(jì)項(xiàng)目的邏輯功能,用以了解其實(shí)現(xiàn)的功能是否滿足設(shè)計(jì)要求,在功能仿真的過(guò)程不涉及任何具體器件的硬件特性。

時(shí)序仿真:當(dāng)設(shè)計(jì)項(xiàng)目通過(guò)功能仿真初步確定滿足設(shè)計(jì)要求后,需要綁定具體器件進(jìn)行時(shí)序仿真。時(shí)序仿真就是接近真實(shí)器件運(yùn)行特性的仿真,仿真文件包含了器件硬件特性參數(shù),因而仿真精度高。

5)編程下載

把適配后生成的下載或配置文件,通過(guò)編程器或編程電纜向FPGA進(jìn)行下載,以便進(jìn)行硬件調(diào)試和驗(yàn)證,從而實(shí)現(xiàn)滿足設(shè)計(jì)要求的電子系統(tǒng)。

三、整體設(shè)計(jì)原理介紹

FPGA具有運(yùn)算速度快,編程簡(jiǎn)易等優(yōu)點(diǎn),它是在PAL、GAL、CPLD等可編程器件的基礎(chǔ)上進(jìn)一步發(fā)展的產(chǎn)物。它還是作為專用集成電路領(lǐng)域中的一種半定制電路而出現(xiàn)的,既解決了定制電路的不足,又克服了原有可編程器件門電路數(shù)有限的缺點(diǎn)。所以我采用FPGA原理設(shè)計(jì)了本次計(jì)算器,主要包括數(shù)碼管部分,按鍵電路部分以及運(yùn)算器部分,設(shè)計(jì)方案基本原理如下。

3.1數(shù)碼管顯示

數(shù)碼管的顯示分為兩種,靜態(tài)顯示和動(dòng)態(tài)顯示,在這里我們使用的是動(dòng)態(tài)顯示。動(dòng)態(tài)顯示的特點(diǎn)是將所有位數(shù)碼管的段選并聯(lián)在一起,由位選線控制是哪一位數(shù)碼管是有效的。這樣一來(lái),就沒(méi)有為每一位數(shù)碼管配置一個(gè)鎖存器的必要,從而就會(huì)大大簡(jiǎn)化了硬件電路。選亮的數(shù)碼管采用動(dòng)態(tài)掃描顯示。所謂的動(dòng)態(tài)掃描顯示就是輪流向各位數(shù)碼管送出字形碼和相應(yīng)的位選,利用發(fā)光管的余輝和人眼視覺(jué)暫留作用,使人的感覺(jué)好像各位數(shù)碼管在同時(shí)都在顯示。動(dòng)態(tài)的顯示的亮度要比靜態(tài)的顯示略差了一些,因而我們?cè)谶x擇需要的限流電阻應(yīng)小于靜態(tài)顯示電路中的。

3.2按鍵部分原理

我們采用了4*4矩陣鍵盤掃描在鍵盤中按鍵數(shù)量較多時(shí),為了減少I/O口的占用,通常將按鍵排列成矩陣形式。在矩陣式鍵盤中,每條水平線和垂直線在交叉處不直接連通,而是通過(guò)一個(gè)按鍵加以連接。這樣,一個(gè)端口就可以構(gòu)成4*4=16個(gè)按鍵,比之直接將端口線的應(yīng)用于鍵盤多出了一倍,而且線數(shù)越多,區(qū)別越明顯,比如再多加一條線就可以構(gòu)成20鍵的鍵盤,而直接用端口線則只能多出一鍵(9鍵)。由此可見(jiàn),我們?cè)谛枰逆I數(shù)比較多時(shí),采用矩陣法來(lái)做鍵盤是合理的。

矩陣式結(jié)構(gòu)的鍵盤顯然比直接法要復(fù)雜一些,識(shí)別也要復(fù)雜一些,列線通過(guò)了電阻連接正電源,并將行線所接的I/O口作為輸出端,而列線所接的I/O口則作為輸入。這樣,當(dāng)按鍵沒(méi)有按下時(shí),所有的輸入端都是高電平,代表無(wú)鍵按下。行線輸出是低電平,一旦有鍵按下,則輸入線就會(huì)被拉低,這樣,通過(guò)讀入輸入線的狀態(tài)就可得知是否有鍵按下了。下面我們介紹行掃描法。

行掃描法又稱為逐行(或列)掃描查詢法,是一種最常用的按鍵識(shí)別方法,介紹過(guò)程如下。

首先判斷鍵盤中有無(wú)鍵按下:將全部行線置低電平,然后檢測(cè)列線的狀態(tài)。只要有一列的電平為低,則表示鍵盤中有鍵被按下,而且閉合的鍵位于低電平線與4根行線相交叉的4個(gè)按鍵之中。若所有的列線均是高電平,則鍵盤中無(wú)鍵按下。

其次判斷閉合鍵所存在的位置:在確認(rèn)有鍵按下后,即可進(jìn)入確定具體閉合鍵的過(guò)程。其方法是:依次將行線置為低電平,就是在置某根行線為低電平時(shí),其它線為高電平。在確定某根行線位置為低電平后,再逐行檢測(cè)各列線的電平狀態(tài)。若某列為低,則該列線與置為低電平的行線交叉處的按鍵就是閉合的按鍵。

3.3狀態(tài)機(jī)原理

運(yùn)算部分我們主要應(yīng)用了狀態(tài)機(jī)進(jìn)行運(yùn)算和存儲(chǔ)的,主要是有限狀態(tài)機(jī),下面對(duì)有限狀態(tài)機(jī)進(jìn)行簡(jiǎn)單的介紹。

狀態(tài)機(jī)簡(jiǎn)寫(xiě)為FSM(Finite State Machine),主要分為2大類:第一類,若輸出只和狀態(tài)有關(guān)而與輸入無(wú)關(guān),則稱為Moore狀態(tài)機(jī);第二類,輸出不僅和狀態(tài)有關(guān)而且和輸入有關(guān)系,則稱為Mealy狀態(tài)機(jī)。要特別注意的是,因?yàn)镸ealy狀態(tài)機(jī)和輸入有關(guān),輸出會(huì)受到輸入的干擾,所以可能會(huì)產(chǎn)生毛刺(Glitch)現(xiàn)象,使用時(shí)應(yīng)當(dāng)注意。事實(shí)上現(xiàn)在市面上有很多EDA工具可以很方便的將狀態(tài)圖的描述轉(zhuǎn)換成可以綜合的Verilog程序代碼。

關(guān)于狀態(tài)機(jī)的一個(gè)極度確切的描述是它是一個(gè)有向圖形,由一組節(jié)點(diǎn)和一組相應(yīng)的轉(zhuǎn)移函數(shù)組成。狀態(tài)機(jī)通過(guò)響應(yīng)一系列事件而“運(yùn)行”。每個(gè)事件都在屬于“當(dāng)前”節(jié)點(diǎn)的轉(zhuǎn)移函數(shù)的控制范圍內(nèi),其中函數(shù)的范圍是節(jié)點(diǎn)的一個(gè)子集。函數(shù)返回“下一個(gè)”(也許是同一個(gè))節(jié)點(diǎn)。這些節(jié)點(diǎn)中至少有一個(gè)必須是終態(tài)。當(dāng)?shù)竭_(dá)終態(tài),狀態(tài)機(jī)停止。

包含一組狀態(tài)集(states)、一個(gè)起始狀態(tài)(start state)、一組輸入符號(hào)集(alphabet)、一個(gè)映射輸入符號(hào)和當(dāng)前狀態(tài)到下一狀態(tài)的轉(zhuǎn)換函數(shù)(transition function)的計(jì)算模型。當(dāng)輸入符號(hào)串,模型隨即進(jìn)入起始狀態(tài)。它要改變到新的狀態(tài),依賴于轉(zhuǎn)換函數(shù)。在有限狀態(tài)機(jī)中,會(huì)有有許多變量,例如,狀態(tài)機(jī)有很多與動(dòng)作(actions)轉(zhuǎn)換(Mealy機(jī))或狀態(tài)(摩爾機(jī))關(guān)聯(lián)的動(dòng)作,多重起始狀態(tài),基于沒(méi)有輸入符號(hào)的轉(zhuǎn)換,或者指定符號(hào)和狀態(tài)(非定有限狀態(tài)機(jī))的多個(gè)轉(zhuǎn)換,指派給接收狀態(tài)(識(shí)別者)的一個(gè)或多個(gè)狀態(tài),等等。

傳統(tǒng)應(yīng)用程序的控制流程基本是順序的:遵循事先設(shè)定的邏輯,從頭到尾地執(zhí)行。很少有事件能改變標(biāo)準(zhǔn)執(zhí)行流程;而且這些事件主要涉及異常情況?!懊钚袑?shí)用程序”是這種傳統(tǒng)應(yīng)用程序的典型例子。

另一類應(yīng)用程序由外部發(fā)生的事件來(lái)驅(qū)動(dòng)——換言之,事件在應(yīng)用程序之外生成,無(wú)法由應(yīng)用程序或程序員來(lái)控制。具體需要執(zhí)行的代碼取決于接收到的事件,或者它相對(duì)于其他事件的抵達(dá)時(shí)間。所以,控制流程既不能是順序的,也不能是事先設(shè)定好的,因?yàn)樗蕾囉谕獠渴录J录?qū)動(dòng)的GUI應(yīng)用程序是這種應(yīng)用程序的典型例子,它們由命令和選擇(也就是用戶造成的事件)來(lái)驅(qū)動(dòng)。

Web應(yīng)用程序由提交的表單和用戶請(qǐng)求的網(wǎng)頁(yè)來(lái)驅(qū)動(dòng),它們也可劃歸到上述類別。但是,GUI應(yīng)用程序?qū)τ诮邮盏降氖录杂幸欢ǔ潭鹊目刂?,因?yàn)檫@些事件要依賴于向用戶顯示的窗口和控件,而窗口和控件是由程序員控制的。Web應(yīng)用程序則不然,因?yàn)橐坏┯脩舨扇〔辉陬A(yù)料之中的操作(比如使用瀏覽器的歷史記錄、手工輸入鏈接以及模擬一次表單提交等等),就很容易打亂設(shè)計(jì)好的應(yīng)用程序邏輯。

顯然,必須采取不同的技術(shù)來(lái)處理這些情況。它能處理任何順序的事件,并能提供有意義的響應(yīng),即使這些事件發(fā)生的順序和預(yù)計(jì)的不同。有限狀態(tài)機(jī)正是為了滿足這方面的要求而設(shè)計(jì)的。

有限狀態(tài)機(jī)是一種概念性機(jī)器,它能采取某種操作來(lái)響應(yīng)一個(gè)外部事件。具體采取的操作不僅能取決于接收到的事件,還能取決于各個(gè)事件的相對(duì)發(fā)生順序。之所以能夠做到這一點(diǎn),是因?yàn)闄C(jī)器能跟蹤一個(gè)內(nèi)部狀態(tài),它會(huì)在收到事件后進(jìn)行更新。為一個(gè)事件而響應(yīng)的行動(dòng)不僅取決于事件本身,還取決于機(jī)器的內(nèi)部狀態(tài)。另外,采取的行動(dòng)還會(huì)決定并更新機(jī)器的狀態(tài)。這樣一來(lái),任何邏輯都可建模成一系列事件/狀態(tài)組合。

狀態(tài)機(jī)可歸納為4個(gè)要素,即現(xiàn)態(tài)、條件、動(dòng)作、次態(tài)。這樣的歸納,主要是出于對(duì)狀態(tài)機(jī)的內(nèi)在因果關(guān)系的考慮。“現(xiàn)態(tài)”和“條件”是因,“動(dòng)作”和“次態(tài)”是果。

有限狀態(tài)機(jī)用于描述電路模型的時(shí)序行為,所有的輸入都可以看成是模型的激勵(lì),所有的輸出可以看成是模型對(duì)激勵(lì)的響應(yīng)。CLK提供時(shí)間基準(zhǔn)。

50165bd6-6482-11ed-8abf-dac502259ad0.png

圖3-1 抽象時(shí)序電路的行為模型 Figure 3-1 abstract behavior model of sequential circuits

時(shí)序電路模型可以表示為:R=F(t),這里F(t)是模型行為的描述。當(dāng)電路的輸出僅僅與狀態(tài)時(shí)間有關(guān)時(shí)候,所描述的模型為摩爾型狀態(tài)機(jī);當(dāng)電路的輸出不僅與時(shí)間有關(guān),也與當(dāng)前的輸入信號(hào)有關(guān)時(shí),稱為米利型狀態(tài)機(jī)。

四、計(jì)算器設(shè)計(jì)的電路部分

4.1 FPGA的最小系統(tǒng)

FPGA最小系統(tǒng)是可以使FPGA正常工作的最簡(jiǎn)單的系統(tǒng)。它的外圍電路盡量最少,只包括FPGA必要的控制電路。一般我們所說(shuō)的FPGA的最小系統(tǒng)主要包括:FPGA芯片,下載電路,外部時(shí)鐘,復(fù)位電路和電源。

4.1.1 電源時(shí)鐘復(fù)位

我們采用了低電平復(fù)位電路,電路圖如下

50531e68-6482-11ed-8abf-dac502259ad0.png

圖4-1 復(fù)位電路 Figure 4-1 reset circuit

4.1.2 JTAG接口

JTAG最初是用來(lái)對(duì)芯片進(jìn)行測(cè)試的,JTAG的基本原理是在器件內(nèi)部定義一個(gè)TAP(Test Access Port;測(cè)試訪問(wèn)口)通過(guò)專用的JTAG測(cè)試工具對(duì)內(nèi)部節(jié)點(diǎn)進(jìn)行測(cè)試。JTAG測(cè)試允許多個(gè)器件通過(guò)JTAG接口串聯(lián)在一起,形成一個(gè)JTAG鏈,能實(shí)現(xiàn)對(duì)各個(gè)器件分別測(cè)試。如今,JTAG接口還常用于實(shí)現(xiàn)ISP(In——System Programmer,在系統(tǒng)編程),對(duì)FLASH等器件進(jìn)行編程。

JTAG編程方式是在線編程,傳統(tǒng)生產(chǎn)流程中先對(duì)芯片進(jìn)行預(yù)編程然后再裝到板上,簡(jiǎn)化的流程為先固定器件到電路板上,再用JTAG編程,從而大大加快工程進(jìn)度。JTAG接口可對(duì)DSP芯片內(nèi)部的所有部件進(jìn)行編程。

JTAG(Joint Test Action Group,聯(lián)合測(cè)試行動(dòng)小組)是一種國(guó)際標(biāo)準(zhǔn)測(cè)試協(xié)議,主要用于芯片內(nèi)部測(cè)試及對(duì)系統(tǒng)進(jìn)行仿真、調(diào)試,JTAG技術(shù)是一種嵌入式調(diào)試技術(shù),它在芯片內(nèi)部封裝了專門的測(cè)試電路TAP(Test Access Port,測(cè)試訪問(wèn)口),通過(guò)專用的JTAG測(cè)試工具對(duì)內(nèi)部節(jié)點(diǎn)進(jìn)行測(cè)試。

如今大多數(shù)比較復(fù)雜的器件都支持JTAG協(xié)議,如ARM、DSP、FPGA器件等。標(biāo)準(zhǔn)的JTAG接口是4線:TMS、TCK、TDI、TDO,分別為測(cè)試模式選擇、測(cè)試時(shí)鐘、測(cè)試數(shù)據(jù)輸入和測(cè)試數(shù)據(jù)輸出。如今JTAG接口的連接有兩種標(biāo)準(zhǔn),即14針接口和20針接口。

支持邊界掃描的邏輯元器件與測(cè)試相關(guān)的所有外部通信都采用串行通信方式,允許測(cè)試指令及相關(guān)的測(cè)試數(shù)據(jù)串行送給元器件,然后允許把測(cè)試指令的執(zhí)行結(jié)果從元器件中串行讀出。為了完成這樣的功能,邊界掃描技術(shù)包含了一個(gè)與元器件的每個(gè)引腳相接,包含在邊界掃描寄存器單元中的寄存器鏈,這樣元器件的邊界信號(hào)可以用掃描測(cè)試原理進(jìn)行控制和觀察,這也是邊界掃描的含義。

50677e80-6482-11ed-8abf-dac502259ad0.png

圖4-2 JTAG配置接口電路 Figure 4-2 the JTAG configuration interface circuit

4.1.3 FLASH

閃存存儲(chǔ)器是一類非易失性存儲(chǔ)器,即使在供電電源關(guān)閉后仍能保持片內(nèi)信息。數(shù)字電路中經(jīng)常需要使用大容量存儲(chǔ)器,串行Flash存儲(chǔ)速度快,體積小,功耗低,在FPGA中設(shè)計(jì)中發(fā)揮的作用也越來(lái)越大,廣泛應(yīng)用于實(shí)現(xiàn)系統(tǒng)及功能驗(yàn)證。FPGA的靈活性和串行Flash的體積小的特點(diǎn)相結(jié)合,具有靈活性強(qiáng)實(shí)用性強(qiáng)等特點(diǎn)。我們的Flash程序存儲(chǔ)電路如圖4-3所示。

50729176-6482-11ed-8abf-dac502259ad0.png

圖4-3 Flash程序存儲(chǔ)電路 Figure 4-3 Flash program memory circuit

4.2 數(shù)碼管電路

我們應(yīng)用的LED數(shù)碼管段數(shù)為7段,就是7個(gè)發(fā)光二極管,任意一個(gè)阿拉伯?dāng)?shù)字0-9都是可以通過(guò)亮滅組合來(lái)實(shí)現(xiàn)的。LED數(shù)碼管根據(jù)LED的接法不同分為共陰和共陽(yáng)兩類,共陰極數(shù)碼管公共端接地,共陽(yáng)極數(shù)碼管公共端接電源,另一個(gè)非公共端的引腳留給用戶的I/O直接控制了,在這里我們采用共陽(yáng)極數(shù)碼管。我們?cè)谶@個(gè)應(yīng)用中,把公共端連接到了FPGA的I/O引腳上,這就是我們數(shù)碼管的片選信號(hào)。如果我們FPGA的I/O引腳輸出低電平0,那么這個(gè)數(shù)碼管就是可以顯示數(shù)字的,如果我們這個(gè)I/O輸出高電平1。那么即使不管數(shù)碼管的段選端輸出0還是1,都沒(méi)有辦法將這7個(gè)發(fā)光二極管的任意一個(gè)點(diǎn)亮,這也達(dá)到了關(guān)閉數(shù)碼管顯示的效果。一旦這樣,這個(gè)數(shù)碼管的公共端被當(dāng)作數(shù)碼管片選引腳使用了,雖然不是名副其實(shí)的“片選”,也是可以達(dá)到我們想要的效果。了解LED的這些特性,對(duì)編程是很重要的,不同類型的數(shù)碼管,除了它們的硬件電路有差異外,方法也是不同的。

508b5c1a-6482-11ed-8abf-dac502259ad0.png

圖4-4數(shù)碼管電路圖 Figure 4-4 digital tube circuit diagram

4.3 按鍵輸入電路

我們要實(shí)現(xiàn)一個(gè)計(jì)算器,首先需要有計(jì)算器的輸入信號(hào),通常是使用連接在FPGA的GPIO接口上的pushbutton作為輸入信號(hào)。簡(jiǎn)易計(jì)算器的輸入信號(hào)比較少,只需要數(shù)字和運(yùn)算符號(hào)。我們可以將其各自使用一個(gè)按鍵來(lái)表示,然后都連接在FPGA的通用接口上。此時(shí),我們便引入了矩陣鍵盤構(gòu)造計(jì)算器的輸入。

我們采用的是4*4矩陣鍵盤電路,矩陣鍵盤又稱行列式鍵盤,它是用4條I/O線作為行線,4條I/O線作為列線組成的鍵盤。在行線和列線的每一個(gè)交叉點(diǎn)上,設(shè)置一個(gè)按鍵。這樣鍵盤中的按鍵的個(gè)數(shù)就是4*4=16個(gè)。這種行列式鍵盤結(jié)構(gòu)能夠有效地提高單片機(jī)系統(tǒng)中I/O口的利用率。其中的ROW0,ROW1,ROW2,ROW3,以及COL0,COL1,COL2,COL3信號(hào)分別連接到了FPGA上,使用一種獨(dú)特的方法,這8個(gè)信號(hào)能夠表示出16個(gè)按鍵各自按下的狀態(tài)。即這16個(gè)按鍵只占用了FPGA的8個(gè)管腳,而使用每個(gè)按鍵都連接到了FPGA的輸入管腳需要占用16個(gè)管腳。

行列矩陣采用了掃描的形式,其8個(gè)連接到FPGA上的信號(hào)是4個(gè)輸入4個(gè)輸出的。我們一般使用的其他按鍵方法都是將按鍵產(chǎn)生的信號(hào)作為輸入。在這里,ROW0-ROW3為FPGA的輸入信號(hào),COL0-COL3是FPGA的輸出信號(hào);電路上,ROW0-ROW3還要連接一個(gè)上拉電阻。

如果左上方第一個(gè)按鍵被按下,ROW0和COL0連接在一起;如果不按下,兩個(gè)信號(hào)則沒(méi)有連接。16個(gè)按鍵表示16種連接的關(guān)系,在沒(méi)有按鍵按下的時(shí)候,輸出的COL信號(hào)就懸空了,輸入的4個(gè)ROW信號(hào)收到上拉電阻的影響都是高電平1。如果說(shuō)連接COL3與ROW2的按鍵被按下,那么FPGA的輸入信號(hào)ROL2就等于輸出信號(hào)COL3的值,其他的ROW輸入信號(hào)則全部為1。

我們?cè)贔PGA內(nèi)部使輸出的COL0信號(hào)為0而其他的COL是1,那么不管其他的列上對(duì)應(yīng)的按鍵都怎么按下,都有輸入的FPGA的ROW為全1;僅僅當(dāng)?shù)谝涣械?個(gè)按鍵中有一個(gè)按下時(shí),對(duì)應(yīng)的行值為0,其余3個(gè)的行值為1,這樣的話第一列所對(duì)應(yīng)的按鍵就唯一確定下來(lái)了。在這樣的輸出狀態(tài)下(COL[3:0]=1110),4個(gè)輸入只能確定出來(lái)第一列的4個(gè)按鍵。要是按下的不是第一行的4個(gè)按鍵,那么輸入值ROW[3:0]為1111,表示第一列沒(méi)有按鍵被按下。于是我們開(kāi)始掃描第二列,就是令COL[3:0]輸出1101,然后查看ROW上是否有值為0。如果此列上仍然沒(méi)有掃描到,就繼續(xù)掃描下一列。

對(duì)于一組數(shù)碼管動(dòng)態(tài)掃描顯示需要由兩組信號(hào)來(lái)控制:一組是輸出口輸出的字形代碼,用來(lái)控制顯示的字形,稱為段碼;另一組是位輸出口輸出的控制信號(hào),用來(lái)選擇第幾位數(shù)碼管的工作,稱為位碼。

由于各位數(shù)碼管的段線并聯(lián),段碼的輸出對(duì)各位數(shù)碼管來(lái)說(shuō)都是相同的。因此,同一時(shí)刻如果各位數(shù)碼管的位選線都處于選通狀態(tài)的話,位數(shù)碼管將顯示相同的字符。若要各位數(shù)碼管能夠顯示出與本位相應(yīng)的字符,就必須采用掃描顯示方式。即在某一時(shí)刻,只讓某一位的選線處于導(dǎo)通狀態(tài),而其他各位的位選線處于關(guān)閉狀態(tài)。同時(shí),段線上輸出相應(yīng)位要顯示字符的字形碼。這樣同一時(shí)刻,只有選通的那一位顯示出字符,而其它各位則是熄滅的,如此循環(huán)下去,就可以使各位數(shù)碼管顯示出將要顯示的字符。

雖然這些字符是在不同時(shí)刻出現(xiàn)的,而且同一時(shí)刻只有一位顯示,其它各位熄滅,但是由于數(shù)碼管具有余輝特性和人眼有視覺(jué)暫留現(xiàn)象,只要每位數(shù)碼管顯示間隔足夠短,給人眼的視覺(jué)印象就會(huì)是連續(xù)穩(wěn)定地顯示。

50aadc34-6482-11ed-8abf-dac502259ad0.png

圖4-5鍵盤電路 Figure 4-5 The keyboard circuit

4.4 電源電路設(shè)計(jì)

我們使用的是LM1117,LM1117是一個(gè)低壓差電壓調(diào)節(jié)器系列。其壓差在1.2V輸出,負(fù)載電流為800mA時(shí)為1.2V。它與國(guó)家半導(dǎo)體工業(yè)標(biāo)準(zhǔn)器件LM317有相同的管腳排列。LM1117有可調(diào)電壓的版本,通過(guò)2個(gè)外部電阻可實(shí)現(xiàn)1.25~13.8V輸出電壓范圍。另外還有5個(gè)固定電壓輸出(1.8V、2.5V、2.85V、3.3V和5V)的型號(hào)。

LM1117提供電流限制和熱保護(hù)。電路包含1個(gè)齊納調(diào)節(jié)的帶隙參考電壓以確保輸出電壓的精度在±1%以內(nèi)。LM1117系列具有LLP、TO-263、SOT-223、TO-220和TO-252 D-PAK封裝。輸出端需要一個(gè)至少10μF的鉭電容來(lái)改善瞬態(tài)響應(yīng)和穩(wěn)定性。

50ccc574-6482-11ed-8abf-dac502259ad0.png

圖4-6 5V轉(zhuǎn)數(shù)字3.3V電路 Figure 4-6 5V to3.3V circuit

50d4a4ce-6482-11ed-8abf-dac502259ad0.png

圖4-7 5V轉(zhuǎn)數(shù)字2.5V電路 Figure 4-7 5V to2.5V circuit

50ddfe70-6482-11ed-8abf-dac502259ad0.png

圖4-8 5V轉(zhuǎn)數(shù)字1.2V電路 Figure 4-8 5V to1.2V circuit

50e684e6-6482-11ed-8abf-dac502259ad0.png

圖4-9 電源插座電路 Figure 4-9 power socket circuit

50f0869e-6482-11ed-8abf-dac502259ad0.png

圖4-10 電源開(kāi)關(guān)電路 Figure 4-10 power switch circuit

五、總體代碼設(shè)計(jì)

系統(tǒng)總體設(shè)計(jì)框圖如圖5-1所示。此設(shè)計(jì)由計(jì)算部分、存儲(chǔ)部分、顯示部分和輸入部分組成。

510997ce-6482-11ed-8abf-dac502259ad0.png
圖5-1 計(jì)算器的系統(tǒng)組成框圖 Figure 5-1 calculator system composition block diagram

5111e9ba-6482-11ed-8abf-dac502259ad0.png

圖5-2 RTL視圖 Figure 5-2 RTL view

5.1 計(jì)算器的輸入部分

計(jì)算器輸入部分的設(shè)計(jì)最主要的是按鍵譯碼電路的設(shè)計(jì)和實(shí)現(xiàn)。計(jì)算器的輸入部分是由0—9十個(gè)數(shù)字按鍵、加減乘除四則運(yùn)算的運(yùn)算符按鍵、一個(gè)等號(hào)按鍵和一個(gè)清零按鍵組成的,設(shè)計(jì)所要做的是對(duì)按鍵信息進(jìn)行譯碼,使其在計(jì)算器內(nèi)部可以使用。這里使用的是4*4鍵盤矩陣作為輸入。數(shù)字按鍵譯碼電路的主體部分Verilog語(yǔ)言描述如下。

5121bcd2-6482-11ed-8abf-dac502259ad0.png

圖5-3 數(shù)字電路譯碼部分代碼 Figure 5-3 digital tube display program code

設(shè)計(jì)的鍵盤矩陣輸入模塊如圖:

51311268-6482-11ed-8abf-dac502259ad0.png

圖5-4 鍵盤矩陣驅(qū)動(dòng)模塊

Figure 5-4 matrix keyboard driver module

在輸入鍵盤矩陣驅(qū)動(dòng)模塊中,我們有三個(gè)輸入,四個(gè)輸出,其中clk為主時(shí)鐘輸入,rst_n為復(fù)位信號(hào),row為4*4鍵盤的行輸入信號(hào),輸出col列信號(hào),data為鍵入的數(shù)字(0-15),valid為數(shù)字的脈沖信號(hào),clk_1k為給計(jì)算模塊輸出的時(shí)鐘。

5.2 計(jì)算器的運(yùn)算和存儲(chǔ)部分

存儲(chǔ)部分用狀態(tài)機(jī)和寄存器來(lái)實(shí)現(xiàn),我們輸入的數(shù)字應(yīng)用了移位拼接的原理,若第一個(gè)輸入的是數(shù)字鍵,則保存下來(lái),第二次輸入還是輸入的是數(shù)字鍵時(shí),第一個(gè)數(shù)值左移變?yōu)槭唬诙蔚臑閭€(gè)位,第三次若還是數(shù)字鍵,那么第一個(gè)數(shù)值將變?yōu)榘傥?,第二個(gè)為十位,第三個(gè)為個(gè)位,以此類推,直到有符號(hào)鍵輸入。

當(dāng)進(jìn)行第一次計(jì)算時(shí),第一個(gè)數(shù)字存放在num1里面。按下運(yùn)算符以后,第二個(gè)數(shù)字放在bin_data里面。當(dāng)再按下運(yùn)算符號(hào)或者等號(hào)時(shí),第一次計(jì)算的結(jié)果將存放在ans里面,同時(shí)reg清零,等待下一個(gè)數(shù)字的輸入。進(jìn)行第二次運(yùn)算時(shí),將num1里面的結(jié)果與reg里面新輸入的數(shù)字進(jìn)行運(yùn)算,再將運(yùn)算結(jié)果存放在num1里面,直到最后按下等號(hào)按鍵的時(shí)候,顯示最終的運(yùn)算結(jié)果。

程序框圖如下:

51477710-6482-11ed-8abf-dac502259ad0.png

圖5-5 狀態(tài)1程序框圖

Figure 5-5 state 1 program block diagram

51552b12-6482-11ed-8abf-dac502259ad0.png

圖5-6 狀態(tài)2程序框圖

Figure 5-6 state 2 program block diagram

計(jì)算部分驅(qū)動(dòng)模塊如圖5-7所示,共有4個(gè)輸入部分,一個(gè)輸出。其中clk為時(shí)鐘,flag為數(shù)字脈沖信號(hào),rst_n為復(fù)位,key_data為按鍵數(shù)據(jù)輸入,bin_data為二進(jìn)制中間數(shù)據(jù)輸出。

5160ee2a-6482-11ed-8abf-dac502259ad0.png

圖5-7 計(jì)算部分驅(qū)動(dòng)模塊

Figure 5-7 calculation part of the driver module

4fbf4bca-6482-11ed-8abf-dac502259ad0.png

5.3 計(jì)算器的顯示部分

顯示部分是系統(tǒng)的輸出部分,用于顯示按鍵值及計(jì)算結(jié)果,由于數(shù)字系統(tǒng)的數(shù)據(jù)運(yùn)算都是二進(jìn)制的,而輸出表達(dá)式都是BCD碼,為了滿足BCD碼的譯碼顯示,最方便的方法就是利用譯碼程序在FPGA中實(shí)現(xiàn)。本文采用的是共陽(yáng)極7段數(shù)碼管,顯示數(shù)字時(shí)需要將對(duì)應(yīng)管腳置為低電平,輸出時(shí),從左到右,按從高到低位的順序依次接g、f、e、d、c、b、a,小數(shù)點(diǎn)為h,為最高位。七段譯碼器的基本結(jié)構(gòu)如圖5-8所示。

5175bb66-6482-11ed-8abf-dac502259ad0.png

圖5-8 七段譯碼器的結(jié)構(gòu)

Figure5-8 The structure of the seven-segment decoder

Verilog硬件位選信號(hào)描述性語(yǔ)言描述如下圖5-9所示:

517d24e6-6482-11ed-8abf-dac502259ad0.png

圖5-9 數(shù)碼管顯示位選程序代碼

Figure 5-9 digital tube display program code

Verilog硬件段選信號(hào)描述性語(yǔ)言描述如下圖5-10所示:

5187df3a-6482-11ed-8abf-dac502259ad0.png

圖5-10 數(shù)碼管顯示段選程序代碼

Figure 5-10 digital tube display program code segment

5190ccd0-6482-11ed-8abf-dac502259ad0.png

圖5-11 數(shù)碼管顯示驅(qū)動(dòng)模塊

Figure 5-11 digital tube display driver module

圖5-11為數(shù)碼管顯示驅(qū)動(dòng)模塊,一共三個(gè)輸入,兩個(gè)輸出,其中clk為時(shí)鐘,rst_n為復(fù)位,data_in數(shù)據(jù)輸入,sel為位選信號(hào),seg為段選信號(hào)。

六、仿真驗(yàn)證設(shè)計(jì)

6.1 ModelSim簡(jiǎn)介

在仿真設(shè)計(jì)時(shí),用到了Mentor公司的Modelsim,這是一款硬件描述語(yǔ)言仿真軟件,該款軟件不單單能提供十分友好的仿真環(huán)境,而且它也是我們業(yè)界第一個(gè)也是僅此一個(gè)的單內(nèi)核支持VHDL和Verilog語(yǔ)言混合仿真的軟件。它采用直接優(yōu)化的編譯技術(shù)、Tcl/Tk技術(shù)、和單一內(nèi)核仿真技術(shù),從而達(dá)到令人編譯仿真速度快的效果,而且編譯代碼和整個(gè)平臺(tái)沒(méi)有關(guān)系,這樣就更容易保護(hù)IP核,它是FPGA/ASIC設(shè)計(jì)的首選仿真軟件。

Modelsim有不同版本,例如:SE、PE、LE和OEM,其中最高級(jí)的版本是SE,而集成在 ActelAtmel以及Lattice等FPGA廠商設(shè)計(jì)工具中的都是其OEM版本。

Modelsim SE支持PC、UNIX和LINUX的混合平臺(tái);能給出十分全面到位以及高性能的驗(yàn)證功能;全面支持業(yè)界設(shè)定的廣泛標(biāo)準(zhǔn);同時(shí)Mentor Graphics公司提供了整個(gè)行業(yè)最出色的技術(shù)支持與服務(wù)。

Modelsim的主要特點(diǎn)有:

1)支持單內(nèi)核的VHDL和Verilog混合在一起進(jìn)行仿真處理;

2)具有源代碼模版、助手以及項(xiàng)目管理功能;

3)匯聚了性能考核、波形參考、代碼覆蓋、數(shù)據(jù)流Chase X、Signal Spy、虛擬對(duì)象Virtual Object、Assertion窗口、Memory窗口、源碼窗口顯示信號(hào)值、信號(hào)條件斷點(diǎn)等眾多調(diào)試功能;

4)C和Tcl/Tk接口,C調(diào)試;

5)能夠?qū)崿F(xiàn)對(duì)System C的直接支持功能,同時(shí)可以和HDL任意混合使用;

6)能夠?qū)崿F(xiàn)System Verilog的設(shè)計(jì)功能;

7)可以做到對(duì)系統(tǒng)級(jí)描述語(yǔ)言進(jìn)行最全面的支持;

8)可以單獨(dú)或同時(shí)進(jìn)行行為(behavioral)、RTL級(jí)、和門級(jí)(gate-level)的代碼。

9)能夠?qū)崿F(xiàn)RTL和門級(jí)優(yōu)化,編譯仿真速率非??欤缙脚_(tái)跨版本的仿真。

6.2 模塊仿真驗(yàn)證分析

FPGA設(shè)計(jì)流程包括設(shè)計(jì)輸入,仿真,綜合,生成,板級(jí)驗(yàn)證等很多階段。在整個(gè)設(shè)計(jì)流程中,完成設(shè)計(jì)輸入并成功進(jìn)行編譯僅僅能說(shuō)明設(shè)計(jì)符合一定的語(yǔ)法規(guī)范,并不能說(shuō)明設(shè)計(jì)功能的正確性,這時(shí),我們就需要通過(guò)仿真對(duì)設(shè)計(jì)進(jìn)行驗(yàn)證。我們主要進(jìn)行的是功能仿真,又叫邏輯仿真,是指在不考慮器件延時(shí)和布線延時(shí)的理想情況下對(duì)源代碼進(jìn)行邏輯功能驗(yàn)證;而時(shí)序仿真是在布局布線后進(jìn)行。我們仿真是為了保證設(shè)計(jì)的正確性。

6.2.1 矩陣按鍵模塊

矩陣鍵盤測(cè)試程序流程框圖如下:

51d119d4-6482-11ed-8abf-dac502259ad0.png

圖6-1 按鍵測(cè)試程序流程圖

Figure 6-1 key testing program flow chart

首先,我們要先進(jìn)行按鍵檢測(cè),判斷是否有按鍵閉合,如果沒(méi)有說(shuō)明沒(méi)有按鍵鍵入,那么返回就是我們常說(shuō)的消抖,重新進(jìn)行按鍵檢測(cè),直到有按鍵閉合。接下來(lái)會(huì)有10ms的延遲,保存鍵值;再繼續(xù)判斷按鍵是否松開(kāi),如果是則又會(huì)產(chǎn)生10ms的延遲,否則返回判斷直到按鍵有松開(kāi)為止,最后返回鍵值。

我們需要編譯一個(gè)模擬鍵盤定義data0-15,然后模擬輸入給FPGA一個(gè)行信號(hào),F(xiàn)PGA接收行信號(hào),同時(shí)輸出給模擬鍵盤一個(gè)列信號(hào),如果輸出的列信號(hào)不存在低電平,那么行信號(hào)為4‘b1111,代表輸入的按鍵不在本列上,繼續(xù)掃描下一列直到找到相應(yīng)的行信號(hào)為止。部分代碼如圖所示。

51e1d56c-6482-11ed-8abf-dac502259ad0.png

圖6-2 鍵盤掃描部分代碼

Figure 6-2 keyboard scan code

圖6-3為鍵盤掃描仿真圖,當(dāng)我們按下1時(shí),數(shù)據(jù)顯示1,按下10顯示10,按下2顯示的是2,按下15顯示15,仿真結(jié)果有效,程序編譯正確。

51eefddc-6482-11ed-8abf-dac502259ad0.png

圖6-3 鍵盤掃描仿真

Figure 6-3 keyboard scanning simulation

6.2.2 計(jì)算仿真舉例

加法計(jì)算舉例,首先pnumber輸入1,data_in輸入也為1,掃描結(jié)果為1;然后輸入10;pnumber輸入為2,data_in輸入為2,掃描結(jié)果為2;最后按鍵“=”,顯示結(jié)果即為3。仿真顯示結(jié)果正確,說(shuō)明我們的編譯代碼沒(méi)有問(wèn)題,計(jì)算有效,計(jì)算器結(jié)果可信。

51f8b480-6482-11ed-8abf-dac502259ad0.png

圖6-4 1+2=3程序仿真圖 Figure 6-4 1+2=3 process simulation diagram

七、結(jié)論

本次電子計(jì)算器的設(shè)計(jì)是基于FPGA設(shè)計(jì)的,計(jì)算器基本上可以實(shí)現(xiàn)的加減乘除的功能。系統(tǒng)的計(jì)算部分、存儲(chǔ)部分、顯示部分和輸入部分四個(gè)部分都可以完成設(shè)計(jì)要求,輸入部分采用鍵盤矩陣原理,存儲(chǔ)部分用狀態(tài)機(jī)來(lái)實(shí)現(xiàn),并進(jìn)行了仿真。實(shí)現(xiàn)了防消抖的要求,計(jì)算結(jié)果較精確。達(dá)到了預(yù)期的要求目標(biāo)。

附錄:設(shè)計(jì)主體源代碼

二進(jìn)制轉(zhuǎn)BCD代碼:

module bin2bcd_12bit(bin, bcd);


  input [19:0] bin;
  output reg [23:0] bcd;
  
  always @ (*)
    begin
      bcd[3:0] = bin%10;
      bcd[7:4] = bin/10%10;
      bcd[11:8] = bin/100%10;
      bcd [15:12] = bin/1000%10;
      bcd[19:16] = bin/10000%10;
      bcd[23:20] = bin/100000%10;
    end


endmodule

計(jì)算模塊代碼:

module calculator (clk, rst_n, flag, key_data, bin_data);


  input clk;
  input rst_n;
  input flag;
  input [3:0] key_data;
  
  output reg [19:0] bin_data;


  reg [1:0] state;
  reg [19:0] num1;
  reg [3:0] opcode;
  
  always @ (posedge clk or negedge rst_n)
    begin
      if (!rst_n)
        begin
          state <= 0;
          num1 <= 0;
          bin_data <= 0;
          opcode <= 0;
        end
      else
        begin
          case (state)
            0 : begin
                if (flag)
                  begin
                    if (key_data < 10)
                      begin
                        bin_data <= bin_data * 10 + key_data;
                      end
                    else
                      begin
                        if (key_data == 14)
                          begin
                            state <= 0;
                          end
                        else
                          begin
                            opcode <= key_data;
                            state <= 1;
                            num1 <= bin_data;
                            bin_data <= 0;
                          end
                      end
                  end
                else
                  begin
                    state <= 0;
                  end
              end
            
            1 : begin
                if (flag)
                  begin
                    if (key_data < 10)
                      begin
                        bin_data <= bin_data * 10 + key_data;
                      end
                    else
                      begin
                        if (key_data == 14)
                          begin
                            case (opcode)
                              10 :  begin bin_data <= num1 + bin_data; state <= 2; end
                              11 :  begin bin_data <= num1 - bin_data; state <= 2; end
                              12 :  begin bin_data <= num1 * bin_data; state <= 2; end
                              13 :   begin bin_data <= num1 / bin_data; state <= 2; end
                              default : bin_data <= 0;
                            endcase 
                          end
                        else
                          begin
                            state <= 1;
                          end
                      end
                  end
                else
                  begin
                    state <= 1;
                  end
              end
          
            2 : begin
                if (flag)
                  begin
                    if (key_data < 10)
                      begin
                        bin_data <= {16'd0,key_data};
                        state <= 0;
                      end
                    else
                      begin
                        if (key_data == 14)
                          begin
                            state <= 2;
                          end
                        else
                          begin
                            num1 <= bin_data;
                            opcode <= key_data;
                            bin_data <= 0;
                            state <=1;
                          end
                      end
                  end
                else
                  begin
                    state <= 2;
                  end
              end
          endcase
        end
    end




endmodule

輸入部分代碼:

module key_board (clk, rst_n, row, col, data, valid, clk_1k);


  input clk;
  input rst_n;
  input [3:0] row;
  
  output reg [3:0] col;
  output reg [3:0] data;
  output reg valid;
  output reg clk_1k;


  reg [14:0] cnt;
  
  parameter T1ms = 24999;
  
  always @ (posedge clk or negedge rst_n)
    begin
      if (!rst_n)
        begin
          clk_1k <= 1'b1;
          cnt <= 15'd0;
        end
      else
        begin
          if (cnt < T1ms)
            begin
              cnt <= cnt + 15'd1;
            end
          else
            begin
              cnt <= 15'd0;
              clk_1k <= ~clk_1k;
            end
        end  
    end


  reg [7:0] row_col;
  reg [1:0] state;
  reg [4:0] count;
  
  always @ (posedge clk_1k or negedge rst_n)
    begin
      if (!rst_n)
        begin
          col <= 4'b0000;
          row_col <= 8'd0;
          state <= 0;
          valid <= 0;
          count <= 0;
        end
      else
        begin
          case (state)
            0 : begin
                if (row == 4'b1111)
                  begin
                    col <= 4'b0000;
                  end
                else
                  begin
                    state <= 1;
                  end
              end
            
            1 : begin
                if (row == 4'b1111)
                  begin
                    state <= 0;
                    count <= 0;
                  end
                else
                  begin
                    if (count < 19)
                      begin
                        count <= count + 1;
                      end
                    else
                      begin
                        count <= 0;
                        state <= 2;
                        col <= 4'b0111;
                      end
                  end  
              end
              
            2 : begin
                if (row == 4'b1111)
                  begin
                    col <= {col[2:0],col[3]};
                    state <= 2;
                  end
                else
                  begin
                    row_col <= {row,col};
                    state <= 3;
                    valid <= 1;
                  end
              end
              
            3 : begin
                if (row == 4'b1111)
                  begin
                    state <= 0;
                    valid <= 0;
                  end
                else
                  begin
                    valid <= 0;
                    state <= 3;
                  end
              end
            
              
            default : state <= 0;
            
          endcase
        end
    end  


  always @ (*)
    begin
      case (row_col)
        8'b0111_0111 : data = 4'hf;
        8'b0111_1011 : data = 4'he;
        8'b0111_1101 : data = 4'hd;
        8'b0111_1110 : data = 4'hc;
        
        8'b1011_0111 : data = 4'hb;
        8'b1011_1011 : data = 4'ha;
        8'b1011_1101 : data = 4'h9;
        8'b1011_1110 : data = 4'h8;
        
        8'b1101_0111 : data = 4'h7;
        8'b1101_1011 : data = 4'h6;
        8'b1101_1101 : data = 4'h5;
        8'b1101_1110 : data = 4'h4;
        
        8'b1110_0111 : data = 4'h3;
        8'b1110_1011 : data = 4'h2;
        8'b1110_1101 : data = 4'h1;
        8'b1110_1110 : data = 4'h0;
        
        default : data = 4'h0;
      endcase
    end




endmodule

數(shù)碼管頂層代碼:

module seven_seg (clk, rst_n, data_in, sel, seg);


  input clk;
  input rst_n;
  input [23:0] data_in;
  
  output [2:0] sel;
  output [7:0] seg;


  wire clk_1k;
  
  freq freq_dut(
      .clk(clk), 
      .rst_n(rst_n),
      .clk_1k(clk_1k)
    );


  sel_seg_encode sel_seg_encode_dut(
      .clk(clk_1k), 
      .rst_n(rst_n), 
      .data_in(data_in), 
      .sel(sel), 
      .seg(seg)
    );
    
    
endmodule

分頻部分代碼:

module freq (clk, rst_n, clk_1k);


  input clk;
  input rst_n;
  
  output reg clk_1k;


  reg [14:0] cnt;
  
  always @ (posedge clk or negedge rst_n)
    begin
      if (!rst_n)
        begin
          clk_1k <= 1;
          cnt <= 0;
        end
      else
        begin
          if (cnt < 24_999)
            begin
              cnt <= cnt + 1;
            end
          else
            begin
              cnt <= 0;
              clk_1k <= ~clk_1k;
            end
        end
    end
    
endmodule

位選段選連接代碼:

module sel_seg_encode (clk, rst_n, data_in, sel, seg);
  
  input clk;
  input rst_n;
  input [23:0] data_in;
  
  output [2:0] sel;
  output [7:0] seg;


  wire [3:0] num;
  
  seg_encode seg_encode_dut(
        .rst_n(rst_n),
        .num(num),
        .seg(seg)
      );
  
  sel_encode sel_encode_dut(
        .clk(clk),
        .rst_n(rst_n),
        .data_in(data_in),
        .num(num),
        .sel(sel)
      );




endmodule

段選部分代碼:

module seg_encode (rst_n, num, seg);


  input rst_n;
  input [3:0] num;
  
  output reg [7:0] seg;


  always @ (*)
    begin
      if (!rst_n)
        begin
          seg = 8'b0000_0000;
        end
      else
        begin
          case (num)
            0 : seg = 8'b1100_0000;
            1 : seg = 8'b1111_1001;
            2 : seg = 8'b1010_0100;
            3 : seg = 8'b1011_0000;
            4 : seg = 8'b1001_1001;
            5 : seg = 8'b1001_0010;
            6 : seg = 8'b1000_0010;
            7 : seg = 8'b1111_1000;
            8 : seg = 8'b1000_0000;
            9 : seg = 8'b1001_0000;
            default : seg = 8'b0000_0000;
          endcase
        end
    end


endmodule

位選部分代碼:

module sel_encode (clk, rst_n, data_in, num, sel);


  input clk;
  input rst_n;
  input [23:0] data_in;
  
  output reg [3:0] num;
  output reg [2:0] sel;


  always @ (posedge clk or negedge rst_n)
    begin
      if (!rst_n)
        begin
          sel <= 0;
        end
      else
        begin
          if (sel < 5)
            begin
              sel <= sel + 1;
            end
          else
            begin
              sel <= 0;
            end
        end
    end


  always @ (*)
    begin
      if (!rst_n)
        begin
          num = 0;
        end
      else
        begin
          case (sel)
            0 : num = data_in[23:20];
            1 : num = data_in[19:16];
            2 : num = data_in[15:12];
            3 : num = data_in[11:8];
            4 : num = data_in[7:4];
            5 : num = data_in[3:0];
            default : num = 0;
          endcase
        end
    end


endmodule

本篇到此結(jié)束,各位大俠,有緣再見(jiàn)!

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1624

    文章

    21539

    瀏覽量

    600518
  • 電子計(jì)算器
    +關(guān)注

    關(guān)注

    1

    文章

    7

    瀏覽量

    7675

原文標(biāo)題:基于FPGA的電子計(jì)算器系統(tǒng)設(shè)計(jì)(附代碼)

文章出處:【微信號(hào):HXSLH1010101010,微信公眾號(hào):FPGA技術(shù)江湖】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    電子計(jì)算軟件,讓電子計(jì)算不在是問(wèn)題

    電子計(jì)算軟件,讓電子計(jì)算不在是問(wèn)題。。。。。
    發(fā)表于 08-12 13:53

    電子計(jì)算器。喜歡的可以下載

    `電子計(jì)算器。喜歡的可以下載0`
    發(fā)表于 11-11 21:04

    一種新的電子計(jì)算器

    大小的計(jì)算器進(jìn)入電子計(jì)算器市場(chǎng),這不僅提供了“通常的”四個(gè)功能,而且它是第一個(gè)提供完整對(duì)數(shù)和三角函數(shù)的計(jì)算器。該計(jì)算器包括由AMI *和Mostek Inc.制造的五個(gè)MOS芯片。*安
    發(fā)表于 10-16 08:48

    如何實(shí)現(xiàn)基于FPGA電子計(jì)算器設(shè)計(jì)

    今天給大俠帶來(lái)基于FPGA電子計(jì)算器設(shè)計(jì),由于篇幅較長(zhǎng),分三篇。今天帶來(lái)第二篇,中篇,話不多說(shuō),上貨。導(dǎo)讀本篇介紹了一個(gè)簡(jiǎn)單計(jì)算器的設(shè)計(jì),基于 FPGA 硬件描述語(yǔ)言 Verilog
    發(fā)表于 11-11 08:31

    基于FDSJ86/FDSJ88實(shí)現(xiàn)的電子計(jì)算器

    基于FDSJ86/88實(shí)現(xiàn)的電子計(jì)算器 摘要: 本文旨在介紹一種用FDSJ86/88電子實(shí)驗(yàn)箱實(shí)現(xiàn)的能夠進(jìn)行加減乘除運(yùn)算的簡(jiǎn)易電子計(jì)算器系統(tǒng)電子
    發(fā)表于 06-21 09:29 ?26次下載

    攜帶式電子計(jì)算器

    攜帶式電子計(jì)算器   社會(huì)發(fā)展,計(jì)算工具也隨著發(fā)展。從算盤開(kāi)始,經(jīng)歷了手搖式、機(jī)械式和電動(dòng)式計(jì)算機(jī),并發(fā)展到今天的電子計(jì)算機(jī)。小型攜帶式電子計(jì)算器
    發(fā)表于 12-24 18:38 ?1520次閱讀
    攜帶式<b class='flag-5'>電子計(jì)算器</b>

    eTools 2.63多功能電子計(jì)算器軟件

    電子發(fā)燒友網(wǎng)站提供《eTools 2.63多功能電子計(jì)算器軟件.exe》資料免費(fèi)下載
    發(fā)表于 10-23 20:02 ?45次下載

    基于AT89C51單片機(jī)的電子計(jì)算器設(shè)計(jì)

    基于AT89C51單片機(jī)的電子計(jì)算器設(shè)計(jì) 有需要的看一看,不收積分。
    發(fā)表于 11-20 16:48 ?134次下載

    簡(jiǎn)易電子計(jì)算器

    1602LCD做的電子計(jì)算器有仿真與源碼,是你調(diào)試與學(xué)習(xí)的好幫手!
    發(fā)表于 02-28 23:09 ?25次下載

    基于AT89C51的電子計(jì)算器設(shè)計(jì)

    基于AT89C51的電子計(jì)算器設(shè)計(jì)-畢業(yè)設(shè)計(jì)
    發(fā)表于 06-03 10:06 ?82次下載

    電子計(jì)算器的使用,卡西歐的fx-CG50還能3D繪圖演示

    計(jì)算器能進(jìn)行簡(jiǎn)單的數(shù)學(xué)運(yùn)算的手持機(jī)器,擁有集成電路芯片,但結(jié)構(gòu)簡(jiǎn)單,比現(xiàn)代電腦結(jié)構(gòu)簡(jiǎn)單得多,也是最為電腦的最基本的辦公設(shè)備之一。據(jù)報(bào)道,近日,卡西歐推出了新款彩色電子計(jì)算器fx-CG50,并號(hào)稱這是目前最強(qiáng)的電子計(jì)算器,因?yàn)榫鼓?/div>
    發(fā)表于 10-16 11:33 ?6979次閱讀

    淺談基于FPGA電子計(jì)算器系統(tǒng)設(shè)計(jì)(代碼

    導(dǎo)讀 本篇介紹了一個(gè)簡(jiǎn)單計(jì)算器的設(shè)計(jì),基于 FPGA 硬件描述語(yǔ)言 Verilog HDL,系統(tǒng)設(shè)計(jì)由計(jì)算部分、顯示部分和輸入部分四個(gè)部分組成,計(jì)算
    的頭像 發(fā)表于 04-23 11:44 ?5714次閱讀
    淺談基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>電子計(jì)算器</b><b class='flag-5'>系統(tǒng)</b>設(shè)計(jì)(<b class='flag-5'>附</b><b class='flag-5'>代碼</b>)

    基于C51單片機(jī)的簡(jiǎn)易電子計(jì)算器的制作

    基于C51單片機(jī)的簡(jiǎn)易電子計(jì)算器的制作方法說(shuō)明。
    發(fā)表于 04-28 11:22 ?97次下載

    基于FPGA電子計(jì)算器設(shè)計(jì)(中)

    今天給大俠帶來(lái)基于FPGA電子計(jì)算器設(shè)計(jì),由于篇幅較長(zhǎng),分三篇。今天帶來(lái)第二篇,中篇,話不多說(shuō),上貨。導(dǎo)讀本篇介紹了一個(gè)簡(jiǎn)單計(jì)算器的設(shè)計(jì),基于 FPGA 硬件描述語(yǔ)言 Verilog
    發(fā)表于 11-06 17:36 ?17次下載
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>電子計(jì)算器</b>設(shè)計(jì)(中)

    基于FPGA電子計(jì)算器設(shè)計(jì)

    在國(guó)外,電子計(jì)算器在集成電路發(fā)明后,只用短短幾年時(shí)間就完成了技術(shù)飛躍,經(jīng)過(guò)激烈的市場(chǎng)競(jìng)爭(zhēng),現(xiàn)在的計(jì)算器技術(shù)己經(jīng)相當(dāng)成熟。
    的頭像 發(fā)表于 02-13 09:11 ?5375次閱讀