現(xiàn)4位先行進(jìn)位加法器(CLA)完整教程)
1. 項(xiàng)目概述與整體設(shè)計(jì)思路1.1 4位先行進(jìn)位加法器到底要解決什么問題如果你是計(jì)算機(jī)組成原理或者數(shù)字邏輯課程的學(xué)生大概率繞不過加法器這一關(guān)。很多教材先講行波進(jìn)位加法器也就是把4個(gè)全加器串聯(lián)起來低位產(chǎn)生的進(jìn)位慢慢往高位移。這種接法實(shí)現(xiàn)起來非常簡(jiǎn)單但有個(gè)讓人頭疼的問題高位必須等低位的進(jìn)位算完才能工作4位還好要是擴(kuò)展到32位、64位延遲會(huì)讓人絕望。先行進(jìn)位加法器英文叫Carry Look-Ahead Adder簡(jiǎn)稱CLA核心思路就是“不等進(jìn)位慢慢傳”而是直接根據(jù)輸入信號(hào)把每一位的進(jìn)位并行算出來。聽起來很玄乎其實(shí)背后的數(shù)學(xué)推導(dǎo)并不復(fù)雜核心就兩個(gè)信號(hào)——生成信號(hào)G和傳播信號(hào)P。這里我拿生活場(chǎng)景打個(gè)比方行波進(jìn)位就像排隊(duì)傳話第一個(gè)人說給第二個(gè)第二個(gè)再傳給第三個(gè)傳到最后一個(gè)人那邊早就過了半天先行進(jìn)位就像群發(fā)消息一個(gè)信號(hào)發(fā)出去大家同時(shí)收到速度自然快得多。本次項(xiàng)目要做的就是在Logisim里從零開始把4位先行進(jìn)位加法器完整搭出來不用任何高級(jí)語言純靠門電路實(shí)現(xiàn)最終連上輸入輸出驗(yàn)證加減法都能跑通。這套電路圖放在Logisim里可以直接運(yùn)行驗(yàn)證無誤后你還可以繼續(xù)擴(kuò)展成8位、16位甚至為自己的單周期CPU設(shè)計(jì)打基礎(chǔ)。1.2 為什么選Logisim作為搭建平臺(tái)很多同學(xué)問過我加法器用Verilog寫幾行就能搞定為什么還要用Logisim這種圖形化工具折騰半天。我的看法是如果你只是想要一個(gè)能用的電路Verilog確實(shí)快但如果你想把進(jìn)位的產(chǎn)生邏輯徹底搞清楚Logisim的“看得見摸得著”是HDL語言無法替代的。Logisim有幾個(gè)明顯的優(yōu)勢(shì)第一拖拽式的布線方式讓門級(jí)電路的真實(shí)連接關(guān)系一目了然哪個(gè)信號(hào)從哪個(gè)引腳進(jìn)去、經(jīng)過幾級(jí)門延遲、從哪里出來全部可視化第二它自帶LED、數(shù)碼管、隧道標(biāo)簽、時(shí)鐘源這些常用組件調(diào)試起來非常方便第三工程文件是純XML格式和同學(xué)之間交流電路特別方便發(fā)給誰都能直接打開跑第四Logisim完全免費(fèi)并且跨平臺(tái)Windows、macOS、Linux都有對(duì)應(yīng)版本實(shí)驗(yàn)室和自己電腦裝同一個(gè)版本就行。當(dāng)然Logisim的版本選擇有個(gè)小坑官方原版和Logisim-Evolution也就是進(jìn)化版在部分組件命名和導(dǎo)入導(dǎo)出上略有差別。我這次用的是Logisim-Evolution 3.8.0版本界面更現(xiàn)代并且自帶中文字庫(kù)顯示對(duì)新手更友好。如果你手里是原版也不用擔(dān)心下面的搭建步驟核心操作完全一致只是個(gè)別菜單名稱略有差異。1.3 項(xiàng)目完成后的效果預(yù)覽在正式動(dòng)手之前先給你吃一顆定心丸明確最終要搭出來的東西長(zhǎng)什么樣。整個(gè)電路可以拆成三個(gè)層級(jí)來看第一層是輸入部分兩個(gè)4位二進(jìn)制數(shù)A和B各接一組撥動(dòng)開關(guān)或引腳第二層是核心運(yùn)算部分包括4個(gè)全加器單元和一組先行進(jìn)位生成電路這是整個(gè)工程最關(guān)鍵的模塊第三層是輸出部分4位結(jié)果S加上最高位進(jìn)位C4用LED或數(shù)碼管顯示。除了最基本的加法功能這個(gè)電路還能做減法。利用補(bǔ)碼運(yùn)算規(guī)則減去一個(gè)數(shù)等于加上這個(gè)數(shù)的補(bǔ)碼也就是把B的每一位取反再加1。只要在B的輸入端加一排異或門再給最低位進(jìn)位C0送一個(gè)控制信號(hào)就能實(shí)現(xiàn)A加B、A減B兩種模式的切換。測(cè)試時(shí)會(huì)用幾組典型的邊界值比如1111加0001、0111加1000還有減法里可能出現(xiàn)的負(fù)數(shù)結(jié)果確保不同情況下電路輸出都正確。2. 先行進(jìn)位核心原理從真值表到邏輯表達(dá)式2.1 單bit全加器與G、P信號(hào)的含義進(jìn)入實(shí)操之前我建議先把理論基礎(chǔ)夯實(shí)。很多人在Logisim里搭電路搭得飛快但遇到進(jìn)位錯(cuò)誤就不知道從哪里排查根本原因就是G和P這兩個(gè)信號(hào)的含義沒有吃透。回顧一下全加器的真值表輸入有三個(gè)本位的兩個(gè)加數(shù)Ai、Bi以及來自低位的進(jìn)位Ci輸出有兩個(gè)本位和Si、向高位的進(jìn)位Ci1。Si的表達(dá)式很簡(jiǎn)單就是三個(gè)輸入做異或Si Ai ⊕ Bi ⊕ Ci。真正重要的是進(jìn)位的表達(dá)式我們寫成Ci1 Ai·Bi (Ai⊕Bi)·Ci如果你盯著這個(gè)式子看一會(huì)兒會(huì)發(fā)現(xiàn)問題可以拆成兩個(gè)部分。第一部分Ai·Bi意思是只要Ai和Bi同時(shí)為1不管低位進(jìn)位是什么這一位都必然會(huì)產(chǎn)生進(jìn)位給下一位這叫“生成進(jìn)位”記作Gi Ai·Bi。第二部分(Ai⊕Bi)·Ci意思是如果Ai和Bi中恰好有一個(gè)為1那么這一位會(huì)不會(huì)產(chǎn)生進(jìn)位取決于低位的進(jìn)位Ci相當(dāng)于低位進(jìn)位直接穿過這一位繼續(xù)往上傳遞這叫“傳播進(jìn)位”記作Pi Ai⊕Bi。G是“天生就要進(jìn)位”P是“順?biāo)浦蹘湍銈鬟M(jìn)位”。這兩個(gè)信號(hào)就是整個(gè)先行進(jìn)位加法器的靈魂后面的所有計(jì)算都建立在這兩個(gè)信號(hào)的基礎(chǔ)上。請(qǐng)注意這里的Pi用的是異或門而不是或門這個(gè)細(xì)節(jié)后面會(huì)影響和Si的計(jì)算——因?yàn)镾i Pi ⊕ Ci復(fù)用同一個(gè)異或結(jié)果可以少焊幾個(gè)門電路。2.2 4位并行進(jìn)位公式推導(dǎo)現(xiàn)在有了G和P我們可以重新看待每一級(jí)的進(jìn)位。以4位加法器為例從C0開始逐級(jí)寫出C1 G0 P0·C0C2 G1 P1·C1 G1 P1·G0 P1·P0·C0C3 G2 P2·C2 G2 P2·G1 P2·P1·G0 P2·P1·P0·C0C4 G3 P3·C3 G3 P3·G2 P3·P2·G1 P3·P2·P1·G0 P3·P2·P1·P0·C0看得出規(guī)律沒有每一位的進(jìn)位表達(dá)式都只和輸入信號(hào)G、P以及C0有關(guān)它不需要等前一位的進(jìn)位算完。這就是“并行計(jì)算進(jìn)位”的核心每個(gè)C都是通過組合邏輯直接算出來的延遲只取決于邏輯門的級(jí)數(shù)而不是加法器的位數(shù)。當(dāng)然公式展開后項(xiàng)數(shù)越來越多尤其是位數(shù)增大之后門電路的輸入引腳數(shù)會(huì)爆炸——一個(gè)C4表達(dá)式里需要5個(gè)輸入的與門。所以實(shí)際工程里太寬的并行進(jìn)位會(huì)分組建分層結(jié)構(gòu)比如16位加法器用4個(gè)4位CLA模塊組成第二級(jí)先行進(jìn)位但那是后話這里先不做擴(kuò)展。我整理了一張行波進(jìn)位和先行進(jìn)位的延遲對(duì)比表方便你直觀感受類型4位延遲16位延遲32位延遲復(fù)雜度行波進(jìn)位3級(jí)門延遲12級(jí)門延遲24級(jí)門延遲低先行進(jìn)位3級(jí)門延遲3級(jí)門延遲組間傳遞3級(jí)門延遲分組傳遞中這一差距在高位寬場(chǎng)景下非常明顯也是為什么現(xiàn)代CPU里的整數(shù)加法器幾乎都采用某種形式的先行進(jìn)位結(jié)構(gòu)。在Logisim里做性能對(duì)比也很直觀連續(xù)點(diǎn)上好幾組輸入觀察進(jìn)位燈的變化速度行波進(jìn)位明顯會(huì)閃一下才穩(wěn)定而先行進(jìn)位幾乎馬上到位。2.3 群進(jìn)位與模塊化設(shè)計(jì)的思想這一步稍微拔高一點(diǎn)。實(shí)際上4位的CLA已經(jīng)是一個(gè)可以獨(dú)立使用的模塊它有G、P輸出可以給上層使用。這個(gè)設(shè)計(jì)思想和軟件工程里的模塊化如出一轍把單個(gè)4位加法器封裝成“黑盒”盒子只對(duì)外暴露輸入A、B、C0輸出S、C4以及可選的組生成G*、組傳播P*。當(dāng)我們需要16位加法器時(shí)不需要把16位的進(jìn)位公式全部展開那樣太復(fù)雜了。只需要把4個(gè)4位CLA模塊串聯(lián)起來同時(shí)用第二層先行進(jìn)位邏輯去并行計(jì)算每個(gè)4位組的進(jìn)位輸入。這里的組生成信號(hào)G* C4 (相關(guān)P組合)組傳播信號(hào)P* P3·P2·P1·P0。感興趣的可以在Logisim里搭第二層驗(yàn)證但在4位基礎(chǔ)實(shí)驗(yàn)階段先把單層電路跑通更實(shí)際。3. Logisim實(shí)操?gòu)陌爰悠鞯?位CLA完整搭建3.1 準(zhǔn)備工作與工程基礎(chǔ)設(shè)置打開Logisim-Evolution第一步建議新建工程后就保存文件比如命名為“CLA_4bit.circ”。這個(gè)習(xí)慣很重要Logisim偶爾會(huì)在某些操作下異常退出不保存的話半天白干。工具欄里需要熟悉的組件集中在“布線”和“門電路”兩個(gè)分類下。本次工程用到的最基本組件包括與門AND Gate、或門OR Gate、異或門XOR Gate、非門NOT Gate、引腳Pin、常量Constant、隧道標(biāo)簽Tunnel、LED。我建議在開始之前先把工具欄挨個(gè)點(diǎn)一遍至少先搞清楚輸入引腳怎么旋轉(zhuǎn)方向、連線怎么換色后面搭起來就順手很多。顯示效果方面有幾個(gè)我常用的設(shè)置在“項(xiàng)目 → 電路選項(xiàng)”里可以把“電線顏色”改成“按位寬著色”這樣多比特寬的總線會(huì)用粗線條顯示和單比特細(xì)線區(qū)分明顯排錯(cuò)時(shí)一眼就能看出哪里接錯(cuò)位寬。還會(huì)把引腳標(biāo)簽字體調(diào)大一點(diǎn)因?yàn)樽痔】粗M(fèi)眼尤其在門電路密密麻麻的時(shí)候很影響心情。如果你用的是校園實(shí)驗(yàn)室電腦每次開機(jī)可能都是默認(rèn)配置建議直接導(dǎo)出“偏好設(shè)置”保存一份下次導(dǎo)入即可。3.2 搭建半加器驗(yàn)證最小運(yùn)算單元先別急著上去就是4位我習(xí)慣先搭一個(gè)1位半加器練手。半加器接收兩個(gè)輸入A和B輸出本位和S以及進(jìn)位Cout。公式非常簡(jiǎn)單S A⊕BCout A·B。在Logisim中拖入一個(gè)異或門和一個(gè)與門左側(cè)接兩個(gè)輸入引腳右側(cè)接兩個(gè)輸出引腳。連好線之后把輸入引腳調(diào)成“撥動(dòng)開關(guān)”交互方式用“手形工具”點(diǎn)擊引腳即可切換電平。驗(yàn)證四種輸入組合00給出S0、Cout001和10給出S1、Cout011給出S0、Cout1。如果驗(yàn)證不對(duì)優(yōu)先檢查門電路的方向和輸入引腳是否接反。這個(gè)半加器的價(jià)值在于幫助你習(xí)慣Logisim的基本操作。特別是連線過程中的一個(gè)小技巧連線和被連線相交時(shí)如果中間沒有節(jié)點(diǎn)它們是互不相干的當(dāng)需要形成連接節(jié)點(diǎn)時(shí)要將終點(diǎn)連到已有線段上Logisim會(huì)自動(dòng)打點(diǎn)。如果你畫完線發(fā)現(xiàn)兩個(gè)交叉點(diǎn)沒有點(diǎn)那就是沒有真正連通。3.3 全加器子電路搭建與封裝半加器不處理來自低位的進(jìn)位所以只能做最末位的加法。我們真正需要的是全加器輸入有三個(gè)Ai、Bi、Ci輸出有Si、Ci1。公式前面已經(jīng)寫過但這里再?gòu)?qiáng)調(diào)一下適合門級(jí)實(shí)現(xiàn)的兩種寫法Si Ai ⊕ Bi ⊕ CiCi1 Ai·Bi (Ai⊕Bi)·Ci在Logisim里新建一個(gè)子電路命名為“full_adder”。搭建順序建議先做Si線用一個(gè)兩個(gè)輸入的異或門串起來第一步Ai和Bi異或得到內(nèi)部信號(hào)X第二步X和Ci再異或得到Si。然后再做進(jìn)位輸出用一個(gè)與門輸出Ai·Bi再用一個(gè)與門輸出X·Ci最后把這兩個(gè)輸出通過或門得到Ci1。注意在電路圖中使用隧道標(biāo)簽來標(biāo)識(shí)內(nèi)部信號(hào)X比直接拉很長(zhǎng)的線干凈很多。給子電路設(shè)置引腳左側(cè)上方是Ai、下方是Bi和Ci右側(cè)上方是Si、下方是Ci1。設(shè)置好子電路的布局之后以后每次調(diào)用它都是一個(gè)整潔的方塊不再需要重復(fù)搭建內(nèi)部邏輯。全加器搭好后先用真值表逐一驗(yàn)證確保8種輸入組合全部正確再繼續(xù)。3.4 4位CLA進(jìn)位鏈電路逐級(jí)搭建這個(gè)環(huán)節(jié)是整個(gè)項(xiàng)目中最核心、也最容易踩坑的部分。先把前面的公式再列一遍作為對(duì)照C1 G0 P0·C0C2 G1 P1·G0 P1·P0·C0C3 G2 P2·G1 P2·P1·G0 P2·P1·P0·C0C4 G3 P3·G2 P3·P2·G1 P3·P2·P1·G0 P3·P2·P1·P0·C0在Logisim新建子電路“cla_4bit_control”先不急著連線把需要用到的輸入引腳全部放好G0~G3、P0~P3共8個(gè)輸入C0一個(gè)輸入。輸出有4個(gè)C1、C2、C3、C4。搭C1最簡(jiǎn)單一個(gè)或門搞定兩個(gè)輸入分別是G0和P0與C0的輸出。C2需要三項(xiàng)G1直接用P1·G0用一個(gè)與門P1·P0·C0用多輸入與門建議用三輸入與門把三個(gè)信號(hào)接進(jìn)去。把這幾個(gè)結(jié)果接到或門上就得到C2。C3和C4按照同樣的方式逐層展開注意有一些乘積項(xiàng)需要在中間引出P信號(hào)重復(fù)使用這時(shí)候用隧道標(biāo)簽把它連到對(duì)應(yīng)的輸入端口避免一條線拉得特別長(zhǎng)導(dǎo)致圖面太亂。需要特別提醒的一點(diǎn)是Logisim的或門和與門默認(rèn)輸入數(shù)量是2但你可以通過調(diào)整“扇入”屬性修改輸入引腳數(shù)量。為了和公式對(duì)應(yīng)建議直接把或門扇入設(shè)置為公式的項(xiàng)數(shù)比如C3的或門就設(shè)置3個(gè)輸入C4的或門設(shè)置5個(gè)輸入這樣圖面上每個(gè)門的功能和公式一一對(duì)應(yīng)不容易看錯(cuò)。3.5 四位CLA完整電路組裝與連接進(jìn)位控制電路搭好之后把它和全加器組合起來。新建頂層電路或者直接在主電路里操作。布局建議如下左邊是A0~A3、B0~B3共8個(gè)輸入引腳如果是減法擴(kuò)展還有模式控制M中間是4個(gè)full_adder子電路實(shí)例右邊是4位輸出S和進(jìn)位輸出C4。下面說連接邏輯這一步是很多新手會(huì)連錯(cuò)的地方。每個(gè)full_adder的三個(gè)輸入中Ai和Bi直接接對(duì)應(yīng)的輸入引腳Ci則必須來自cla_4bit_control對(duì)應(yīng)輸出的進(jìn)位信號(hào)——注意不是來自低位的進(jìn)位輸出這是和行波加法器的根本區(qū)別。每個(gè)full_adder的進(jìn)位輸出引腳實(shí)際上在這個(gè)設(shè)計(jì)里只作為外層觀察點(diǎn)使用不參與進(jìn)位鏈但為了測(cè)試方便還是保留它并觀察其電平尤其是在驗(yàn)證加法結(jié)果的時(shí)候可以對(duì)照。具體連接關(guān)系如下第一個(gè)全加器的Ci接C0輸出S0它的Gi A0·B0、Pi A0⊕B0分別接cla_4bit_control的G0、P0。第二個(gè)全加器的Ci接C1輸出S1Gi和Pi接控制模塊的G1、P1。第三個(gè)和第四個(gè)以此類推。C4從控制模塊輸出作為最終進(jìn)位輸出引腳或接LED。如果你想要減法功能這一步就加一組異或門每個(gè)Bi和模式控制M異或當(dāng)M1時(shí)Bi被取反同時(shí)把M接到C0相當(dāng)于加1于是實(shí)現(xiàn)A加B的補(bǔ)碼。此時(shí)的C4含義變成“借位”取反也就是無符號(hào)減法的借位標(biāo)志。測(cè)試時(shí)驗(yàn)證A-B若結(jié)果為正則C4為1若結(jié)果為負(fù)則C4為0且輸出S就是差值的補(bǔ)碼形式。我在實(shí)際驗(yàn)證中用的幾組測(cè)試樣例建議你也試試模式AB預(yù)期S預(yù)期C4說明加法0110001110010常規(guī)進(jìn)位測(cè)試加法1111000100001最大值溢出測(cè)試加法0111100011110邊界反差測(cè)試減法0110001100111正數(shù)結(jié)果減法0011011011010負(fù)數(shù)補(bǔ)碼結(jié)果4. 驗(yàn)證測(cè)試與常見問題排查4.1 測(cè)試用例設(shè)計(jì)與逐項(xiàng)驗(yàn)證很多同學(xué)搭完電路看到LED亮了兩下就算完工這種做法我不提倡。一個(gè)組合邏輯電路必須經(jīng)過完整的真值表驗(yàn)證尤其是進(jìn)位鏈的每個(gè)輸出都要逐一確認(rèn)。以4位CLA為例最理想的方法是窮舉所有2^9種輸入組合A的16種乘以B的16種再加上C0的2種在Logisim中逐個(gè)切換輸入引腳并記錄輸出。雖然這工作繁瑣但你可以設(shè)計(jì)成只對(duì)A和B各取幾組典型值再配合進(jìn)位C0做交叉驗(yàn)證將工作量壓縮到十幾次開關(guān)點(diǎn)擊。測(cè)試時(shí)我習(xí)慣把M和C0統(tǒng)一歸到一組“控制輸入”把A和B歸到“數(shù)據(jù)輸入”。界面布局上控制輸入用紅色標(biāo)簽數(shù)據(jù)輸入用藍(lán)色標(biāo)簽輸出LED用單獨(dú)區(qū)域放在最右側(cè)并排好位置這樣一眼就能看清楚當(dāng)前測(cè)試條件是什么。測(cè)試加法時(shí)重點(diǎn)觀察幾個(gè)關(guān)鍵點(diǎn)第一S0到S3的每一位是否符合預(yù)期第二C4引腳是否為預(yù)期值第三如果加了“溢出標(biāo)志”輸出還要檢查V標(biāo)志是否只在正正得負(fù)或負(fù)負(fù)得正的情況下亮起。Logisim里觀察電平變化的辦法是通過LED顏色判斷綠燈亮表示高電平滅表示低電平。為了更直觀可以加一個(gè)“十六進(jìn)制顯示器”組件直接把4位結(jié)果以十六進(jìn)制形式顯示省去手算二進(jìn)制轉(zhuǎn)十六進(jìn)制的麻煩。4.2 關(guān)鍵信號(hào)波形觀察與調(diào)試方法Logisim雖然沒有像示波器那樣強(qiáng)大的波形窗口但通過它自帶的“組合邏輯分析”功能可以生成真值表和化簡(jiǎn)表達(dá)式這一點(diǎn)對(duì)于校準(zhǔn)電路非常有用。選中你要觀察的組合邏輯電路區(qū)域后在“分析”菜單里選擇“組合邏輯分析”Logisim會(huì)自動(dòng)生成一個(gè)真值表方便比對(duì)。如果你需要觀察更長(zhǎng)時(shí)間內(nèi)的信號(hào)變化情況可以依靠“時(shí)鐘”組件和“探針”組件輔助。給輸入端接上時(shí)鐘源配合計(jì)數(shù)器可以產(chǎn)生周期變化的輸入信號(hào)再用輸出端的探針捕捉信號(hào)跳變。不過對(duì)于4位CLA這種純組合邏輯最有效的調(diào)試方法依然是手動(dòng)撥動(dòng)輸入引腳觀察輸出引腳變化。我還發(fā)現(xiàn)一個(gè)很實(shí)用的排查技巧在關(guān)鍵信號(hào)線上設(shè)置探針比如G3、P3、C3、C4這些位置點(diǎn)擊不同的輸入組合時(shí)觀察這些探針的顏色變化。如果C4不正常先看G3、P3是否正確再看C3是否正確逐級(jí)縮小范圍很快就能定位到哪一級(jí)的與門或者或門出了問題。這種“從前級(jí)往后級(jí)推”的方法比盯著整塊電路發(fā)呆有效得多。4.3 常見錯(cuò)誤速查表我整理了搭建過程中遇到頻率最高的幾類問題附上排查思路建議遇到報(bào)錯(cuò)或輸出不對(duì)的時(shí)候先對(duì)號(hào)入座現(xiàn)象可能原因排查方法S輸出全亮或全滅輸入引腳位寬設(shè)置錯(cuò)誤或接反檢查引腳位寬屬性確認(rèn)輸入引腳是1位檢查是否誤連到輸出引腳加法結(jié)果正確但C4恒為0cla_4bit_control的C4輸出沒接到頂層引腳檢查頂層電路C4是否引線到LED而非停在子電路內(nèi)部中間某一級(jí)結(jié)果不對(duì)G或P接錯(cuò)位置對(duì)照公式逐一核對(duì)該級(jí)G、P與公式中乘積項(xiàng)的連線接線圖上出現(xiàn)紅色線兩個(gè)輸出引腳相連或位寬不匹配檢查紅色線段附近是否有兩個(gè)輸出被連在一起或者線的位寬屬性不一致子電路引腳輸入坐標(biāo)錯(cuò)亂引腳方向設(shè)置不對(duì)選中引腳后在屬性欄調(diào)整“朝向”為東、西、南、北輸入統(tǒng)一朝外減法結(jié)果差了1C0在減法模式?jīng)]有接到M信號(hào)減法模式下C0必須和M相連由M控制加1否則就是純?nèi)》礇]加1多位數(shù)輸入引腳被當(dāng)成單個(gè)引腳引腳屬性“位寬”默認(rèn)是1未改為4把A、B輸入引腳位寬改為4輸出引腳S位寬也改為4排查的思路永遠(yuǎn)是從輸出反推輸入用探針鎖定出問題的信號(hào)位置檢查該信號(hào)應(yīng)該等于什么、實(shí)際是什么再去檢查生成該信號(hào)的邏輯門。4.4 關(guān)于“穩(wěn)定”和“競(jìng)爭(zhēng)冒險(xiǎn)”的進(jìn)一步說明你可能在網(wǎng)上看到過有人討論組合邏輯電路的“毛刺”和“競(jìng)爭(zhēng)冒險(xiǎn)”問題。先行進(jìn)位加法器的進(jìn)位鏈由于各級(jí)門延遲不同在實(shí)際物理電路中確實(shí)存在毛刺風(fēng)險(xiǎn)但Logisim是純行為級(jí)仿真它不會(huì)模擬真實(shí)門延遲所以這個(gè)問題在Logisim里看不出來。這對(duì)實(shí)驗(yàn)來說是好事至少不會(huì)因?yàn)槊虒?dǎo)致調(diào)試?yán)щy。但在概念層面你仍然需要理解理論上先行進(jìn)位的速度優(yōu)勢(shì)來自所有進(jìn)位同時(shí)產(chǎn)生實(shí)際中信號(hào)依然要經(jīng)過與門和或門的物理延遲。不同路徑的G、P到達(dá)時(shí)間不同最終C4可能在很短的時(shí)間內(nèi)出現(xiàn)抖動(dòng)。這就是為什么實(shí)際CPU設(shè)計(jì)里常常會(huì)在輸出端加鎖存器或者做流水線寄存而Logisim實(shí)驗(yàn)通常不做這一步畢竟我們驗(yàn)證的是邏輯功能而不是時(shí)序行為。我想額外強(qiáng)調(diào)一點(diǎn)Logisim里設(shè)置的“組合邏輯分析”功能生成的真值表只能用于無反饋的組合電路如果你的電路里有反饋環(huán)比如把輸出引回輸入這個(gè)工具會(huì)無法解析。所以在調(diào)試時(shí)如果點(diǎn)擊分析之后報(bào)錯(cuò)或表里全是X先檢查是否誤加了反饋線。5. 擴(kuò)展思考從4位CLA到更復(fù)雜的CPU設(shè)計(jì)5.1 如何擴(kuò)展到8位、16位搞定4位CLA之后一個(gè)很自然的想法是向高位擴(kuò)展。直接展開8位并行進(jìn)位公式的話C8表達(dá)式會(huì)非常長(zhǎng)而且需要約9輸入的大扇入門這在Logisim中既不美觀也不符合工程實(shí)踐。標(biāo)準(zhǔn)做法是用分組先行進(jìn)位結(jié)構(gòu)將8位分成兩組4位第一組內(nèi)部先行進(jìn)位輸出組進(jìn)位C4第二組接收C4后再做內(nèi)部先行進(jìn)位。這樣第二組仍然需要等待第一組的進(jìn)位但整體延遲遠(yuǎn)小于行波進(jìn)位。如果繼續(xù)追求更高性能可以在組間也使用先行進(jìn)位邏輯也就是所謂的“二級(jí)先行進(jìn)位”。這時(shí)候每個(gè)4位CLA模塊需要額外輸出兩個(gè)信號(hào)組傳播信號(hào)P和組生成信號(hào)G。P* P3·P2·P1·P0G* C4在這個(gè)模塊內(nèi)部產(chǎn)生的進(jìn)位與外部C0無關(guān)時(shí)。上層電路用這些信號(hào)來計(jì)算每個(gè)模塊的進(jìn)位輸入從而讓4個(gè)4位CLA模塊也能并行工作。在Logisim中可以把4位CLA整體再封裝為一個(gè)“黑盒”賦予它P和G的輸出引腳以后搭建16位加法器就像搭積木一樣方便。5.2 CLA在小型CPU設(shè)計(jì)中的位置標(biāo)題里提到了單周期MIPS CPU設(shè)計(jì)這是學(xué)習(xí)計(jì)算機(jī)組成原理的學(xué)生一定會(huì)遇到的項(xiàng)目。在MIPS數(shù)據(jù)通路中ALU負(fù)責(zé)算術(shù)邏輯運(yùn)算加法器是ALU的核心部件。如果你在Logisim里做單周期MIPS建議先將4位CLA驗(yàn)證通過再改成32位版本或者用16位簡(jiǎn)化版并用它實(shí)現(xiàn)add、sub、addi等指令。Logisim里做CPU的常見路線是先搭好ALU再搭建寄存器堆、指令存儲(chǔ)器、數(shù)據(jù)存儲(chǔ)器、控制單元最后串成完整的數(shù)據(jù)通路。加法器在ALU里屬于基礎(chǔ)運(yùn)算單元所以它的正確性和性能直接關(guān)系到整個(gè)CPU項(xiàng)目的成敗。如果加法器使用了行波進(jìn)位那么在運(yùn)行需要連續(xù)加法的程序時(shí)比如循環(huán)累加雖然功能上沒錯(cuò)但課程演示時(shí)會(huì)感覺反應(yīng)遲鈍。用CLA之后ALU的運(yùn)算速度快配合時(shí)鐘和寄存器整體數(shù)據(jù)通路跑起來就大不一樣。很多同學(xué)的CPU項(xiàng)目卡在控制信號(hào)的生成上但回頭發(fā)現(xiàn)是ALU的加法器個(gè)別輸出不對(duì)造成CPU行為完全錯(cuò)亂。所以我堅(jiān)持認(rèn)為先在單獨(dú)工程里把CLA徹底驗(yàn)證完整是后面所有工作的前提。不要圖省事直接抄網(wǎng)上的ALU電路圖一定要親手搭一遍理解了內(nèi)部邏輯后面出了任何問題才有排查能力。這一點(diǎn)在我?guī)н^的所有課程設(shè)計(jì)小組中反復(fù)得到驗(yàn)證凡是自己搭過CLA的同學(xué)后期調(diào)CPU都相對(duì)順利凡是直接復(fù)制粘貼的出問題后完全無從下手。5.3 后續(xù)還能玩出的花樣除了單純做加法器你還可以給這個(gè)CLA工程加一些組件做成一個(gè)可以在Logisim里演示的簡(jiǎn)易ALU加一個(gè)2選1多路選擇器用控制信號(hào)切換加法/減法/與/或/異或等不同運(yùn)算。增加一個(gè)比較器輸出等于、小于、大于用于分支跳轉(zhuǎn)指令的判定。增加一個(gè)零標(biāo)志Z輸出供CPU的條件分支使用。用“移位器”組件擴(kuò)展出左移、右移功能這對(duì)應(yīng)MIPS的sll、srl指令。如果你對(duì)性能分析感興趣還可以在Logisim里接入“時(shí)鐘”組件將加法器結(jié)果鎖存到寄存器再配合計(jì)數(shù)器觀測(cè)每周期運(yùn)算結(jié)果的變化。這已經(jīng)算是一個(gè)非常簡(jiǎn)易的流水線雛形了。更進(jìn)階的玩法是將4位CLA封裝成子電路后反復(fù)例化4次再構(gòu)建16位加法器體會(huì)“模塊復(fù)用”帶來的設(shè)計(jì)效率提升。我個(gè)人的體會(huì)是這個(gè)4位CLA項(xiàng)目雖然看起來只是一個(gè)算術(shù)電路但它隱藏著計(jì)算機(jī)體系結(jié)構(gòu)里最核心的設(shè)計(jì)哲學(xué)把耗費(fèi)時(shí)間的關(guān)鍵路徑找出來用并行計(jì)算加速關(guān)鍵瓶頸。理解了這一點(diǎn)后面學(xué)乘法器、除法器、流水線控制、Cache替換策略的時(shí)候你會(huì)覺得所有硬件設(shè)計(jì)都圍繞著“時(shí)間和空間的權(quán)衡”展開。希望這篇教程能幫你真正跨過“看懂原理”和“親手搭出電路”之間的鴻溝。如果你在搭建過程中還有卡殼的地方把這篇文章反復(fù)對(duì)照一步一步來基本不會(huì)有問題。