減法器的設計與實現並用解碼器顯示16、10進位

来源:https://www.cnblogs.com/xiaoniuhululu/archive/2023/05/25/17431072.html
-Advertisement-
Play Games

大家新年好,我是呼嚕嚕,在上一篇[簡易加法器](https://mp.weixin.qq.com/s/ahuk_JH8iyH8bwh3VQxpOw)里我們瞭解了半加器和全加器的設計與實現,今天我們來看下CPU中減法器是如何實現的。文章比較長,大家可以收藏反覆觀看 ## 電腦為什麼利用反碼來實現減法 ...


大家新年好,我是呼嚕嚕,在上一篇簡易加法器里我們瞭解了半加器和全加器的設計與實現,今天我們來看下CPU中減法器是如何實現的。文章比較長,大家可以收藏反覆觀看

電腦為什麼利用反碼來實現減法?

我們來看一個最常見的例子,2-1 =1這是減法,但它等同於 2+ (-1) =1 這其實是加法。從運算邏輯上來說,減法可以通過加法來實現,這是可行的。
從硬體電路層面說,我們很容易讓電子實現彙總的效果,但是將電子群拆分出多個更小的集群,是不容易的。還有一個好處是利用加法器能實現減法的效果的話,就不需要再為減法器專門設計電路了,降低了電路的複雜度。

由於電腦採用的是二進位,和我們天生熟悉的十進位還是有區別的,那麼二進位能否實現用加法來實現減法效果?

很幸運地是,當初那群電腦那群工程師大拿將二進位玩的是爐火純青,通過原碼->反碼->補碼,一步步實現了二進位通過加法來實現減法效果。其中原理大家感興趣地,可以看看筆者之前的一篇文章 電腦中數值和字元串怎麼用二進位表示?

補碼真的是一個天生完美的奇妙存在,基於補碼的機制,減法可以轉化為加法,也就意味著電腦可以通過加法器實現減法。

看完筆者的那篇文章,我們知道了補碼產生的手動:正數原碼不變,負數的符號位不變, 其餘各位取反, 最後一位+1

image

減法器的實現

要實現原碼到補碼的轉換,需要一個取反器,我們先來寫出減法邏輯的真值表:

image

通過真值表,我們可以很容易發現這其實就是一個異或門(相同為0,不同為1)

我們來實現一個8位的取反器,由於是8位的,所以輸入選這8位輸入,還得連一個8位的分線器,輸出類似。異或門得有8個,每個都需和控制是否取反的輸入相連。

image

我們將之前的全加器和減法器結合起來,需要註意的是補碼需要取反再+1,取反可以將輸入和取反器相連,+1可以將全加器最低位的進位控制取反的輸入相連即可,極簡單又巧妙

image

我們來啟動模擬,看下效果:

image

上圖計算結果,相當於:

1+1 =2
1-1 =0

但是上面有個問題是,1-1=0時,雖然燈泡是0,但是旁邊的溢出標誌顯示溢出了,我們還需改造一下。我們這裡簡單地,就直接讓減法不溢出即可(這種處理方式還是比較粗暴的,但是實現起來比較簡單)
我們來寫出溢出輸入IY,是否取反輸入IF(如果取反,就代表是減法操作),溢出輸出O的真值表關係

IY IF O
0 0 0
1 0 1
0 1 0
0 1 0

我們可以推出公式:O=非IF * IY,所以需要非門和與門

image

這樣就減法時,就不會溢出了。但其實這個加法器只能做正數的減法(也就是輸入A得大於等於輸入B),如果最後結果為負數的,還是有bug的。我們後面有機會再優化

7段數位管16進位顯示

由於用燈泡表示二進位,每次得出的結果,還要我們去換算成10進位,非常不直觀,我們接下來利用數位管,來將二進位數"翻譯"成10進位數。

我們這邊利用的是7段數位管來實現的,數位管其實就是多個LED燈,不同的位控制不同的LED。從第0位到第7位,通過控制不同的LED來組合出數字。第7位比較特殊,數位管顯示的是點

image

我們用上面的電路,一一將0~F16個數顯示出來,各個開關的情況記錄成下麵的表:

數值 開關(2進位) HEX(16進位)
0 0011 1111 0x3F
1 0011 0000 0x06
2 0101 1011 0x5B
3 0100 1111 0x4F
4 0110 0110 0x66
5 0110 1101 0x6D
6 0111 1101 0x7D
7 0000 0111 0x07
8 0111 1111 0x7F
9 0110 1111 0x6F
A 0111 0111 0x77
b 0111 1100 0x7C
C 0011 1001 0x39
D 0101 1100 0x5E
E 0111 1001 0x79
F 0111 0001 0x71

這其實就是7段數位管的共陰極對照表,還有共陽極對照表這裡我們就不展示了。

如果直接用組合電路來封裝8位輸入,7段數位管的16進位顯示,的確是可以的,但如果是16位,32位,64位輸入,電路會異常的複雜,我們這邊用儲存器ROM來實現這個功能

ROM只讀存儲器,是以非破壞性讀出方式工作,它非易失性存儲器,當電源被移除時,其數據內容不會被擦除,它還有個特點就是只能讀出而不能寫入信息,其所存的數據,一般是裝入整機前事先寫好的,整機工作過程中只能讀出。

需要註意的是: 雖然ROM和硬碟有一些共性,但不能簡單地說ROM就是硬碟

常常與ROM相比的還有一個RAM(隨機存取存儲器),也就是我們常說的主存,是與CPU直接交換數據的內部存儲器,它的特點:隨機存取、數據易失、對靜電敏感、訪問速度快、需要刷新。RAM在斷電以後保存在上面的數據會自動消失

我們使用ROM和7段數位管來顯示16進位的數0~F,選用地址位寬為4,數據位寬為8,只需把對應的數據提前寫入對應的地址中即可。

這裡需要註意一下,為什麼我們選用地址位寬為4,數據位寬為8的ROM

首先我們需要明白(1111 1111)2 = (f f)16, 7段數位管可以表示0~F 16進位數,我們可以用2個7段數位管並聯將8位二進位數解碼成16進位數。
我們就先考慮1個7段數位管和ROM的關係,單個"f"也就是第16個數,也就是說4位二進位,即4位輸入,最大值為16

  1. 地址位寬為4, 可以保證定址2^4=16,分別對應十六進位下的0~F
  2. 數據位寬為8,相當於2個7段數位管,一個7段數位管需要4位輸入,2個就是8位輸入

我們想顯示16進位數,0~F,我們需要4位二進位輸入,其最大值1111,就是16(F),結合上面的共陰極對照表,我們就能總結下麵的表:

A3 A2 A1 A0 Number HEX(16進位)
0 0 0 0 0 0x3F
0 0 0 1 1 0x06
0 0 1 0 2 0x5B
0 0 1 1 3 0x4F
0 1 0 0 4 0x66
0 1 0 1 5 0x6D
0 1 1 0 6 0x7D
0 1 1 1 7 0x07
1 0 0 0 8 0x7F
1 0 0 1 9 0x6F
1 0 1 0 A 0x77
1 0 1 1 b 0x7C
1 1 0 0 C 0x39
1 1 0 1 d 0x5E
1 1 1 0 E 0x79
1 1 1 1 F 0x71

根據對應關係,我們把電路和存儲器相應地址數據預先填進去

image

我們啟動模擬看下效果:

image

測試完成後,將4個開關換成4位輸入。接著我們將2個4位16進位解碼器並聯,就成了8位16進位解碼器,並封裝一下:

image

並將它與上文的全加器與減法器結合起來:

image

nice!

7段數位管10進位顯示

通過上一小節,我們成功把8位二進位數,"翻譯"成16進位數,但距離我們更熟悉的十進位還是有點距離的,我們本小節繼續改進7段數位管,實現10進位的解碼

由於(1111 1111)2 = (255)10, 最大值為255

ROM需要8位地址位寬,2^8 = 256,確保能夠將256個數(0 ~255)全部找到;255是3位數,我們至少需要3個數位管(也就是我們上一小節封裝的4位16進位解碼管),1個數位管需要4位輸入,所以ROM數位管的數據位寬為12

更多精彩文章在公眾號「小牛呼嚕嚕

電路實現:我們可以使用8個開關,來表示8位輸入;選用8位地址位寬且數據位寬為12的ROM,通過8位3針腳的分線器和3個4位16進位解碼管相連即可。

由於ROM的查找表有255個數,不能像之前一樣一個個手動填寫,我們可以利用Python來實現(電腦中需要有Python3的環境)。

image

將其另存到桌面上為test.bin文件,用vscode打開該文件(需要安裝 hex editor插件來顯示二進位),以小端顯示:

image

test.py:

with open('test.bin', 'wb') as f:
    for i in range(256):
        var = str(i)
        var = int(var, base=16) //先轉成16進位
        byte = var.to_bytes(2, byteorder='little')// 再轉化成二進位,以顯示小端
        print(byte)
        f.write(byte)

將其放到test.bin 同級目錄後,直接運行命令python test,py後,test.bin就變成了:

image

這種55 02 其實是 25531 02 231 , 像這種55 02 就是小端表示法。

將test.bin 重新載入到ROM中

image

我們來啟動模擬看看:
image

我們將輸入替換開關,然後封裝成8位10進位解碼器電路,接上之前的減法器的電路:
image

21選擇器 增強 10進位顯示

我們現在有個需求,001,前面的0不想要,就想要1,我們藉助21選擇器來實現 高位為零時,數位管不亮

我們先來看一下1位21選擇器,首先有2個輸入,分別為A和B,以及一個有效位EN,一個輸出S。我們的目的是實現:有效輸出A,無效輸出B。根據目的我們可以寫出真值表:

EN A B S
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 1
1 0 0 0
1 0 1 0
1 1 0 1
1 1 1 1

我們可以得出公式 S = EN與A + 非EN與B,進而可以畫出電路圖

image

封裝後,模擬一下:

image

我們繼續畫出8位21選擇器,只需將8個1位21選擇器組合在一起:

image

將其封裝一下,接著模擬測試:
image

7段數位管10進位顯示增強的電路,我們再重新設計一下:

image

更多精彩文章在公眾號「小牛呼嚕嚕

最後把其封裝一下,放到減法器和加法器的電路中,演示一下:

image

完美,這樣就實現了我們的目的。

尾語

本文我們將上一小篇文章中的簡易加法器進行來改進,通過補碼,讓加法器也是運算減法。接著為了讓我們觀察結果更加方便,我們使用了7段數位管實現了 16進位、10進位顯示,最終優化了10進位顯示,使其只顯示有效位的數值。

本系列到目前為止主要是組合邏輯電路的相關知識,後續我們會探究時序邏輯電路的奧秘,來看看開關究竟是如何實現CPU除計算功能外另一個重要的功能"記憶功能"。


參考資料:

  1. 一個8位二進位CPU的設計和實現,躊躇月光
  2. 《編碼:隱匿在電腦軟硬體背後的語言》
  3. 《穿越電腦的迷霧》
  4. 深入淺出電腦組成原理,徐文浩
  5. 運行記憶體,百度百科

全文完,感謝您的閱讀,如果我的文章對你有所幫助的話,還請點個免費的,你的支持會激勵我輸出更高質量的文章,感謝!

原文鏡像:https://mp.weixin.qq.com/s/QXWm-s-v3VuYV7s4-uE7yA

電腦內功、源碼解析、科技故事、項目實戰、面試八股等更多硬核文章,首發於公眾號「小牛呼嚕嚕」,我們下期再見!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • > ML.Net - 開源的跨平臺機器學習框架 > - 支持CPU/GPU訓練 > - 輕鬆簡潔的預測代碼 > - 可擴展其他的機器學習平臺 > - 跨平臺 ![img](https://img2023.cnblogs.com/blog/1339560/202305/1339560-20230524 ...
  • 文件比較平常都是用Beyond Compare,可以說離不開的神器,特別是針對代碼比較這塊,確實挺好用的。 不過Beyond Compare平常拿它主要是用來做代碼比較,用來做一些大批量的二進位文件比較,其實有點不是很方便。 於是造輪子,重新寫了一個簡單的文件夾比較的小工具。 平常主要是拿來做一些N ...
  • 遞歸演算法本質: 1、方法的自我調用 2、有明確的終止條件 3、每次調用時,問題規模在不斷減少。通過遞減,最終到達終止條件 ...
  • Centos7安裝配置 # 一 、 安裝 安裝就不多做詳述,選擇好自己的鏡像設置好路徑即可 # 二 、配置 #### 2.1 網路配置 桌面右鍵進入 `cmd` 命令編輯視窗,在 Linux 中設置網路的相關配置都需要管理員許可權,需要先切換到 root 用戶。 ```markdown vim /et ...
  • # 伺服器磁碟滿了!!! 事發突然,我在給博客的圖片新增的時候,發現上傳文件和下載文件一直報錯。因為我用的是`1Panel`面板去管理伺服器,話不多說看圖: ![image](https://img2023.cnblogs.com/blog/3091176/202305/3091176-202305 ...
  • 目錄 一、shell簡述 二、shell腳本 三、重定向 四、管道符 五、變數 六、shell腳本基本知識 七、預定義變數小實驗 一、shell簡述 概念:shell解釋器,翻譯官功能,與內核進行溝通的應用程式。 把代碼翻譯為二進位,讓內核處理,負責接收用戶輸入的操作指令(命令)併進行解釋,將需要執 ...
  • 需要先安裝svn linux版打開終端執行 sudo pacman -S svn 安裝完成後執行一下 svn --version 出現這個就說明svn已經安裝完成了,這個時候我們可以執行 svn checkout [路徑] 就可以檢出svn伺服器上相關內容了 但是這個有的時候我們打開文件管理器想要看 ...
  • ZBar是一種流行的二維碼掃描和解碼工具,它在嵌入式系統中擁有廣泛的應用。在嵌入式系統中,我們面臨著有限的資源和更嚴格的性能要求,因此,選擇適當的庫來完成特定的任務非常重要。 ZBar適用於各種嵌入式平臺,包括ARM、x86和MIPS等處理器架構。它可以輕鬆地整合到各種嵌入式系統中,如智能家居設備、 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 插件化的需求主要源於對軟體架構靈活性的追求,特別是在開發大型、複雜或需要不斷更新的軟體系統時,插件化可以提高軟體系統的可擴展性、可定製性、隔離性、安全性、可維護性、模塊化、易於升級和更新以及支持第三方開發等方面的能力,從而滿足不斷變化的業務需求和技術挑戰。 一、插件化探索 在WPF中我們想要開 ...
  • 歡迎ReaLTaiizor是一個用戶友好的、以設計為中心的.NET WinForms項目控制項庫,包含廣泛的組件。您可以使用不同的主題選項對項目進行個性化設置,並自定義用戶控制項,以使您的應用程式更加專業。 項目地址:https://github.com/Taiizor/ReaLTaiizor 步驟1: ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • Channel 是乾什麼的 The System.Threading.Channels namespace provides a set of synchronization data structures for passing data between producers and consume ...
  • efcore如何優雅的實現按年分庫按月分表 介紹 本文ShardinfCore版本 本期主角: ShardingCore 一款ef-core下高性能、輕量級針對分表分庫讀寫分離的解決方案,具有零依賴、零學習成本、零業務代碼入侵適配 距離上次發文.net相關的已經有很久了,期間一直在從事java相關的 ...
  • 前言 Spacesniffer 是一個免費的文件掃描工具,通過使用樹狀圖可視化佈局,可以立即瞭解大文件夾的位置,幫助用戶處理找到這些文件夾 當前系統C盤空間 清理後系統C盤空間 下載 Spacesniffer 下載地址:https://spacesniffer.en.softonic.com/dow ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • 一、ReZero簡介 ReZero是一款.NET中間件 : 全網唯一開源界面操作就能生成API , 可以集成到任何.NET6+ API項目,無破壞性,也可讓非.NET用戶使用exe文件 免費開源:MIT最寬鬆協議 , 一直從事開源事業十年,一直堅持開源 1.1 純ReZero開發 適合.Net Co ...
  • 一:背景 1. 講故事 停了一個月沒有更新文章了,主要是忙於寫 C#內功修煉系列的PPT,現在基本上接近尾聲,可以回頭繼續更新這段時間分析dump的一些事故報告,有朋友微信上找到我,說他們的系統出現了大量的http超時,程式不響應處理了,讓我幫忙看下怎麼回事,dump也抓到了。 二:WinDbg分析 ...
  • 開始做項目管理了(本人3年java,來到這邊之後真沒想到...),天天開會溝通整理需求,他們講話的時候忙裡偷閑整理一下常用的方法,其實語言還是有共通性的,基本上看到方法名就大概能猜出來用法。出去打水的時候看到外面太陽好好,真想在外面坐著曬太陽,回來的時候好兄弟三年前送給我的鍵盤D鍵不靈了,在打"等待 ...