從觸發器到簡單計算機系統
19年的筆記,上傳一下(●’?’●),參考書籍如下
高等教育出版社《數字電子技識訓礎( 第六版 ) 》 閻石
電子工業出版社《編碼:隱匿在計算機背后的語言》 佩挫
一個可編程的完整微處理系統其本質上還是從觸發器開始,慢慢向上構建而成,
觸發器到鎖存器
上圖為一個電平D型觸發器(又稱D型鎖存器),當Write端置為高電平時,輸出Do將被置為與Di相同的狀態,
試想一下,如果我們需要找些什么東西用來存放一些數字,很自然地,我們使用剛剛介紹過的D觸發器組成下面的結構,我們稱之為8位鎖存器,顯然,我們找到了可以有效存放數字的容器(雖然是二進制數字),(tips:因為這個圖畫起來肥腸麻煩,所以就有了簡化版)
鎖存器到RAM
就是長這樣~
可以注意到上圖中的小框寫了 8x1 RAM 的字樣,實際上,由于框選擇器和譯碼器具有相同的地址埠,譯碼器將決定其中的哪一個D觸發器能夠接收資料輸入;而選擇器將決定輸出其中哪一個D觸發器的資料,經過這種配置下的鎖存器的的確確可以視作為Random Access Memory,即RAM,(上面的這個存盤器就是一個能夠儲存8個獨立位元組的RAM)
因此還可以進行重復組合(妙呀🛫)
經過上面的操作后,可以看到新的RAM可儲存的數任然是8個,但是每個數的位寬變為了2,
繼續套娃
容量不夠咋辦,加譯碼器啊!(媽媽再也不用擔心.jpg)比如上方的例子中,4個256X8的RAM通過2-4譯碼器連接后,我們得到了一個1024X8的RAM,它可以儲存8192位元的資訊,其中,每8個位元一組,共1024組,因此,從計算機組成的角度來講,這個RAM陣列的容量為1024個位元組,也就是1KB(kilobyte);
(注:由于圖片搜尋自網路,不配套的情況在所難免,上方中的左圖輸入輸出復用同一根線,而通過CLK時鐘線來區別讀/寫,右圖中的輸入與輸出線是分立的,)
帶RAM的加法器
在數字電子技術的學習程序中,我們都接觸過一種由邏輯門電路構成的加法器,事實上,正是加法器構成了CPU的基本運算單元(組成CPU的兩個基本單元是運算器和加法器),現在,我們將結合RAM對我們的運算器進一步優化直至組成一個完整的微處理器,
上面是我用畫圖軟體畫的一個簡易加法器的框圖,它使用了振蕩器,計數器,和我們剛剛組成的RAM還有一個加法器以及用作輸出顯示8只LED燈,當然了,它看起來不是那么的好用,(不過它是有重要意義的,具體可看計算機發展史早期的計算機的系統結構…)
讓我們來看看它是怎么作業的吧:
- 首先,想要使用它,必須先將清零信號置1,這樣的目的是清除8位鎖存器的內容并將16位計數器的輸出(RAM接收的地址)置為0000h,接下來,你可以從控制端輸入你需要累加的數,假設你需要累加100個數字,那么這些數將可以從0000h一直存放到0063h,接下來令清零信號置0,電路開始作業,
- 顯然,每當一個時鐘信號后,8位鎖存器都會輸出當前的值給LED顯示;同時,加法器又接收到當前的值等待下一個時鐘信號的到來,
- 這個電路一個巨大缺陷是我們沒有辦法使它自行停下來,在剛才的例子中,如果電路累加完了100個數之后,你可以通過8只LED以二進制方式讀取運算結果,但前提是時鐘信號足夠慢,一旦計數器達到FFFFh后,它會重新回到0000h,可以想見的是,加法器會把剛才加過的數重新加一遍,
- 除此之外,這個電路只能進行加法運算,并且要求RAM中存放的數不能超過255,且運算的結果也不能超過255,如果要求減法運算(用補數代替負數),那么運算范圍將進一步被限制在-128-127之間,而且,這個電路不能保存計算的結果,因為最終的輸出并沒有回到RAM中,為了解決這些問題,我們把輸出的LED指示去掉,將輸出回接到RAM,
帶RAM的加法器改進版
改進后的電路如下圖所示(圖片來自《編碼:隱匿在計算機背后的語言》)
事實上,這個電路仍沒有很好的解決剛才的問題,舉例來說,如果我們要想計算3B3D112Dh和2A3D9CA1h的和,由于一個位元組中只能存放8位資料,我們需要把3BCD11HDh拆成3Bh、3Dh,11h和2Dh四個數,同時被加數也需要被拆成四個數,由于16計數器將順序尋址,因此,一個可行的方案是下面這樣:
如表所示,在電路作業前按表格中的格式在RAM中預先填入好資料,待電路作業后,我們會在0002h中得到最高兩位的結果,不過此時需要外置電路要將8位鎖存器的值清零(這可通過一些基本的邏輯門電路實作),以免后續發生累加,以此類推,我們可以得到運算的結果,和最開始的加法運算電路一樣,這個電路也不能自行停止且當兩數相加發生進位時會導致運算出錯,而且引出了新的問題:我們運算的結果被分配到了不同的地址位上,以至于我們沒法讀取它們,
使用代碼的加法器
那咋搞呢?(?ω?)
咳咳,我想上面的表格是不是給了你一點思路,如果你曾看到過匯編代碼的形式的話,
事實上,為了解決上面的問題,一種使用代碼的機器誕生了,它是怎么誕生的,以及為什么誕生,這就得提到馮·諾依曼(John von Neumann,1903年12月28日-1957年2月8日)
詞條戳這-> 約翰·馮·諾依曼.
美籍匈牙利科學家馮·諾依曼最先提出程式存盤的思想,并成功將其運用在計算機的設計之中,根據這一原理制造的計算機被稱為馮·諾依曼結構計算機,由于他對現代計算機技術的突出貢獻,因此馮·諾依曼又被稱為“現代計算機之父”,
這里還是使用《編碼:隱匿在計算機背后的語言》中的圖片形式(用畫圖軟體畫的)
如圖所示,新的計算器在原來的基礎上增加了1片RAM用來存放代碼,我們省略了加法器以及一些外圍邏輯電路,這樣可以使圖更加清晰易懂,在新的設備中,計數器用來加載代碼,而我們的代碼由3位元組的8位二進制陣列成(2位16進制),其中,第一個位元組用來存放代碼本身;第二個位元組用來存放地址的高八位;第三個位元組用來存放地址的低八位,
以11HDh和112Dh為例,新的機器將像這樣執行他們的相加程序,不過在開始之前,我們需要規定一下我們的代碼,比如我們規定01h為將資料裝入累加器;02h為將累加器上資料填入到RAM;11h為加法;12h為進位加法,假設11HDh按照低位到高位存放在1000h處,112Dh也按照低位到高位存放在2000h處,如果代碼從1000h處開始,那么,下面演示如何將它們相加并保存至3000h處,
//1
1000h:01h //把1001h處的資料裝入累加器 (低位)
1001h:10
1002h:01h
//2
1003h:11h //累加器加上2001h處的資料
1004h:20
1005h:01h
//3
1006h:02h //取出累加器的資料保存到3001h
1007h:30
1008h:01h
//4
1009h:01h //把1000h處的資料裝入累加器 (高位)
1010h:10
1011h:00h
//5
1012h:12h //累加器進位加上2000h處的資料(進位來自上次運算)
1013h:20
1014h:00h
//6
1015h:02h //取出累加器的資料保存到3000h
1016h:30
1017h:00h
至此,我們完成了11HDh和112Dh的加法運算并將結果保存至第二片RAM的3000h處,但這種代碼實在不是給人讀的,所以我們考慮使用貼近人類語言的方式重新描述它,當我們需要使用時,再將其翻譯成機器碼送入處理端,這也就是匯編語言的由來,
| 操作碼 | 代碼 |
|---|---|
| Load | 10h |
| Store | 11h |
| Add | 20h |
| Add with carry | 22h |
| Subtract | 21h |
| Subtract with borrow | 23h |
| Jump if zero | 30h |
| Jump if carry 31h | |
| Jump if no zero | 32h |
| Jump if no carry | 33h |
| Halt | FFh |
書中給出了上表這些操作碼,其中借位減法原理同進位加法類似,關于halt指令和jump指令,正是這兩個指令讓新的設備可以與前述的加法器有了本質的區別,因為在它們的幫助下我們可以實作回圈、跳轉和判斷,而加法器不能,
Halt將停止計數器的計數,我們可以通過在計數器的時鐘信號附加邏輯門電路實作,
jump指令則可以通過計數器的預置實作,條件跳轉則需要附加相應的邏輯門電路,
下面演示如何編碼讓機器進行乘法運算(書上的例子)
假設需要計算A7h和1Ch的乘積,使其在地址這樣放置:
那么使用書上的操作碼實作乘法的程序應該是這樣的~(:—
000h: Load 1005h //裝載預結果的低位到累加器
Add 1001h //加上被乘數的低位
Store 1005h //保存到預結果到1005h
Load 1004h //裝載預結果的高位到累加器
Add with carry 1000h //進位加上被乘數的高位(進位來自低位運算)
Store 1004h //保存到預結果到1004h
Load 1003h //裝載乘數
Add 001Eh //加上001Eh的資料(實際相當于減一)
Store 1003h //保存乘數減一的值
Jump if not zero 1000h //若累加器的輸出不全為0,則跳轉到000h繼續執行
001Eh:Halt(FFh) //停止
在上面的所有的例子中,我們一直使用機器碼或者英文短語來描述機器操作,這也被稱作編碼(coding)或編程(writing program),
但是,沒有人希望使用上面的語言進行實際的操作,于是,匯編語言(assembly language)出現了,不過,匯編語言仍是面向機器的語言,很難從其代碼上理解程式設計意圖,設計出來的程式不易被移植,故不像其他大多數的高級計算機語言一樣被廣泛應用,所以在高級語言高度發展的今天,它通常被用在底層,通常是程式優化或硬體操作的場合,
通常還把除硬體系統之外的其余層稱為虛擬機,各層次之間關系密切,上層是下層的拓展,下層是上層的基礎,各層次之間的劃分也不是絕對的,(唐朔飛 《計算機組成原理》)
總結
至此,我們完成了一個微處理系統中的處理器和RAM部分,但是搭建一個完整的系統還需要外設(peripheral)也就是各種輸入設備和輸出設備(input device&output device),而所有這些器件的通信就通過總線(Bus)實作,通常把這信號分為5類:
- 資料總線(Data Bus):在CPU與RAM之間來回傳送需要處理或是需要儲存的資料,
- 地址總線(Address Bus):用來指定在RAM之中儲存的資料的地址,
- 控制總線(Control Bus):將微處理器控制單元(Control Unit)的信號,傳送到周邊設備,
- 擴展總線(Expansion Bus):外部設備和計算機主機進行資料通信的總線,例如ISA總線,PCI總線,
- 區域總線(Local Bus):取代更高速資料傳輸的擴展總線
學習總線,除了認識到總線的基本分類和總線傳輸的基本原理外,還可以給我們閱讀一些芯片相關檔案提供幫助,方便我們快速了解一款產品具有那些功能和外設,從而快速開發,比如下面這塊典型的MCU(STM32F103xx增強型)的結構框圖:

更具體的總線內容就不放在這里了
結束
byebye~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/282916.html
標籤:其他
上一篇:計算機網路·啥玩意是源MAC地址,目標MAC地址,源ip地址,目標ip地址
下一篇:MCS-51單片機的內部結構





容量不夠咋辦,加譯碼器啊!(媽媽再也不用擔心.jpg)比如上方的例子中,4個256X8的RAM通過2-4譯碼器連接后,我們得到了一個1024X8的RAM,它可以儲存8192位元的資訊,其中,每8個位元一組,共1024組,因此,從計算機組成的角度來講,這個RAM陣列的容量為1024個位元組,也就是1KB(kilobyte);




