減法器的設計與實現並用解碼器顯示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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...