這篇文章是計(jì)算機(jī)組成元素的第三章的總結(jié)翩瓜,是接著前一篇寫的携龟。沒看過前一篇的,可以去看下峡蟋。這是鏈接:
我們在之前介紹過的各種邏輯門,比如 Mux, DMux 等等仅乓,都是各種操作組合起來蓬戚。所以由這些門構(gòu)成的 chip 都叫組合 chip。像 CPU 里面的 ALU豫喧,這種提供了一些處理數(shù)據(jù)功能的芯片就是組合芯片的一種。很明顯光這種芯片肯定是不夠構(gòu)成一個(gè)簡單的馮諾伊曼體系的計(jì)算機(jī)系統(tǒng)紧显,我們還需要一種芯片,即時(shí)序芯片涉兽,一種可以維持我們數(shù)據(jù)狀態(tài)的芯片篙程。
這里舉個(gè)例子來理解下時(shí)序芯片的作用,其實(shí)很簡單矿辽,任何一個(gè)高級語言郭厌,例如 C++,Java 都會(huì)聲明變量折柠,然后讓變量來保存一個(gè)值
int a = 10;
就像這樣的扇售,a 的值就永遠(yuǎn)是 10,而且你想用 a 的時(shí)候就直接用就行了承冰。你應(yīng)該會(huì)好奇在底層這種方式是如何實(shí)現(xiàn)的,這些功能就是要靠時(shí)序芯片來實(shí)現(xiàn)了寂屏。
我們先來介紹下背景知識娜搂。像我們前面舉的例子,a = 10 的意思就是對計(jì)算機(jī)說百宇,計(jì)算機(jī)携御,你要記住 a 是 10既绕,也就是說這是一種記憶行為婚苹。
記憶行為很明顯是跟時(shí)間有關(guān)的鸵膏,只有你在某一時(shí)間點(diǎn)告訴我了 a = 10,我才能在之后的時(shí)間內(nèi)知道 a 就是 10谭企。這就引發(fā)出了一個(gè)問題,計(jì)算機(jī)是如何表示時(shí)間這個(gè)概念非区。我們的時(shí)間觀念是年月日時(shí)分秒盹廷,那計(jì)算機(jī)的時(shí)間又是怎么回事?應(yīng)該有很多人都聽說過 CPU 主頻這個(gè)東西吧管怠,CPU的主頻表示在CPU內(nèi)數(shù)字脈沖信號震蕩的速度缸榄,脈沖信號就是這個(gè)東西:
計(jì)算機(jī)有一個(gè)主時(shí)鐘,在不停的發(fā)出連續(xù)的交流信號串她肯。低相位用0代表鹰贵,高相位用1代表,0-1瑞筐,0-1腊瑟,0-1就表示時(shí)間的流逝了。一個(gè)0-1就表示一個(gè)時(shí)鐘周期闰非,主頻就是表示了一秒內(nèi)出現(xiàn)了多少個(gè)時(shí)鐘周期。
計(jì)算機(jī)中的時(shí)間概念介紹完瘪贱,就該介紹 時(shí)序芯片菜秦。首先,我們來介紹一個(gè)最基本的時(shí)序元件尔店,F(xiàn)lip-Flops主慰,所有的高級的時(shí)序芯片,比如 Memory, registers共螺,都是基于此構(gòu)造成的。Flip-Flop 我們這邊都翻譯成觸發(fā)器匀哄。觸發(fā)器有好幾種種類雏蛮,RS 觸發(fā)器,D 觸發(fā)器铸抑,T 觸發(fā)器和 JK 觸發(fā)器等等衷模,具體的可以去維基百科上看詳細(xì)介紹。這里我們主要介紹 D 觸發(fā)器阱冶,簡稱 DFF。DFF 沒什么特別的至耻,它跟我們之前所寫的那些邏輯門都是一樣的镊叁,有輸入位也有輸出位。但是跟那些組合芯片唯一的不同是疤苹,它還有一個(gè) clock bit 輸入位敛腌,正如我們之前的介紹惫皱,時(shí)序邏輯是基于時(shí)間的尤莺,既然組合芯片是一個(gè)基于輸入輸出的函數(shù),那時(shí)序邏輯很明顯就是基于時(shí)間的一個(gè)函數(shù)颤霎。DFF 實(shí)現(xiàn)的時(shí)間函數(shù)就是 :
out(t) = in(t - 1)捷绑,即當(dāng)前時(shí)鐘周期的輸出是上個(gè)時(shí)鐘周期的輸入
DFF 有兩個(gè)特點(diǎn)是需要非常注意的氢妈,也可以說是時(shí)序芯片的兩個(gè)特點(diǎn):
1. 有一個(gè)時(shí)間的延遲(這里的時(shí)間的延遲,我們先暫且認(rèn)為這是 DFF 硬件內(nèi)置的一個(gè)屬性)
2. ?out 值只在一個(gè)周期結(jié)束壮吩,另一個(gè)周期開始的轉(zhuǎn)換點(diǎn)變換
Register
介紹完基礎(chǔ)的時(shí)序元件加缘,D 觸發(fā)器,我們就來看一些基于 D 觸發(fā)器的一些時(shí)序芯片沈贝。首先是 Registers勋乾,我們稱寄存器。寄存器跟 D 觸發(fā)器非常類似辑莫,只是寄存器實(shí)現(xiàn)的時(shí)間函數(shù)是 :
out(t) = out(t - 1)各吨,即當(dāng)前時(shí)鐘周期的輸出是上個(gè)時(shí)鐘周期的輸出
這個(gè)是書上的兩幅圖,第二幅圖描述的是如何基于 DFF 去構(gòu)造 一位的寄存器揭蜒,第一幅圖是錯(cuò)誤的實(shí)現(xiàn)屉更。因?yàn)槲覀冃枰タ刂萍虞d新值的時(shí)間,有可能我們不想在下個(gè)周期去加載新值偶垮,想在下下個(gè)周期去加載新值帝洪,所以我們需要一個(gè) load 位去控制何時(shí)加在新值葱峡。(注意:這里 DFF 中間有個(gè)小的三角形缺口龙助,表示的是我們之前介紹的 clock-bit 輸入位)。
這里說下這個(gè)一位寄存器的實(shí)現(xiàn)的一些提示:
1. 首先是決定是否加在新值提鸟,這個(gè)用 Mux 門很容易實(shí)現(xiàn)
2. ?為賦值的變量默認(rèn)是 0
3. ?DFF 可以輸出上個(gè)周期的值
4. 類似循環(huán)
這里實(shí)現(xiàn)的是一位的寄存器,當(dāng)然要實(shí)現(xiàn)能存儲(chǔ)多位的寄存器就非常簡單了胸哥,一個(gè)寄存器如果擁有 n 個(gè)這樣一位的寄存器赡鲜,我們稱該寄存器的寬度是 n。然后寄存器一次能處理的 in 的位數(shù)又可以構(gòu)成一個(gè)新的計(jì)量單位嘲更,叫 Word (字)揩瞪,大多數(shù)寄存器一個(gè)字長就是表示它的寬度,然而有些寄存器比如說是 32 位寬的宠哄,但是一次只能處理16位的數(shù)喷屋,那該寄存器的一個(gè)字長就是16。 就是然后內(nèi)存 什么的基本都是以字為計(jì)量單位屯曹。
RAM
有了以上這些知識就可以去構(gòu)造一個(gè)我們經(jīng)常所說的 RAM,更準(zhǔn)確的說應(yīng)該是 RAM ?的一個(gè) unit密任。
RAM (Random Access Memory)指的是任何一個(gè)存儲(chǔ)在存儲(chǔ)空間的字偷俭,不管它的物理位置在哪里,我們都能以相同的速度獲取到淹遵, ?
要滿足這樣的條件,RAM是這樣設(shè)計(jì)的:
1. 我們要給 RAM 中的每一個(gè)寄存器的每一個(gè) word 賦一個(gè)地址
2. ?我們要實(shí)現(xiàn)一個(gè)邏輯門济炎,可以輸入一個(gè)地址辐真,就輸出一個(gè)位于該地址的寄存器
這里就可以看出一個(gè) RAM ?的基本參數(shù):
1. 一個(gè)是數(shù)據(jù)寬度:一個(gè)字長是多少位的
2. size:總共是多少個(gè)字
Counters
計(jì)數(shù)器也是一個(gè)時(shí)序芯片。至于為什么介紹這個(gè)芯片耐床,因?yàn)槲覀兯鶎懙哪切┏绦蚋@個(gè)關(guān)系蠻大的楔脯。舉個(gè)例子,一個(gè)典型的 CPU 會(huì)有程序計(jì)數(shù)器钧敞,它的作用是表明下條應(yīng)該被執(zhí)行的指令的地址是什么麸粮。它的時(shí)間函數(shù)是:
out(t) = out(t - 1) + C镜廉,C 經(jīng)常為 1
典型的計(jì)數(shù)器還會(huì)有額外的功能。比如說齐遵,重置為 0塔插,加載一個(gè)新的 Constant等等
總結(jié)
總之,所有的時(shí)序芯片都可以用一幅圖來表示想许,這幅圖是書上的:
問題
我們已經(jīng)知道了兩種類型的芯片流纹,一種是組合芯片,一種是時(shí)序芯片漱凝。那平常計(jì)算機(jī)工作的時(shí)候,肯定是兩種芯片協(xié)同起來一起工作愕乎,當(dāng)兩種芯片協(xié)同起來工作的時(shí)候,就會(huì)有一些問題生成慎玖。
先來舉一個(gè)具體的例子笛粘,用我們之前的 ALU 來計(jì)算 X + Y,并把結(jié)果儲(chǔ)存到 Register A润努。首先我們要去存儲(chǔ) X 的寄存器的地方去獲得 X 的值示括,之后再去獲得 Y 的值,因?yàn)槲锢項(xiàng)l件的約束(比如說有些寄存器離 ALU 比較遠(yuǎn)垛膝,傳輸過程中受到干擾),ALU 有可能會(huì)在不同的時(shí)間點(diǎn)獲得正確的 X 和 Y 的值倚聚。所以想要 ALU 得出正確的結(jié)果是需要一段時(shí)間的凿可,在這段時(shí)間內(nèi)惑折,ALU 產(chǎn)出的結(jié)果都是我們不想要的,稱為 垃圾枯跑。那我們怎么保證寄存器最后存到的值是正確的惨驶?
我們在介紹寄存器曾經(jīng)說過,寄存器的輸出值的改變發(fā)生在每個(gè)周期開始的時(shí)候敛助,并且依賴于上個(gè)周期的值粗卜,所以解決方法就是,一個(gè)時(shí)鐘周期的時(shí)間設(shè)為剛好大于我去最遠(yuǎn)的一個(gè)寄存器去取值所需要花的時(shí)間纳击。這樣在每個(gè)時(shí)鐘周期的結(jié)束和下一個(gè)時(shí)鐘周期開始的轉(zhuǎn)換點(diǎn)续扔,寄存器就能獲取到正確的值。
結(jié)尾
書里评疗,沒有詳細(xì)介紹觸發(fā)器的具體實(shí)現(xiàn),把觸發(fā)器作為基礎(chǔ)元素百匆,如果你有興趣可以自己去探尋一下是怎么實(shí)現(xiàn)的(可能需要懂更多的硬件知識)砌些,我也在研究,歡迎在評論區(qū)一起去討論。最后存璃,書中也提到了仑荐,現(xiàn)代的內(nèi)存芯片都是經(jīng)過仔細(xì)優(yōu)化的,會(huì)去利用硬件的一些物理屬性來實(shí)現(xiàn)存儲(chǔ)技術(shù)纵东。所以很多時(shí)候技術(shù)的實(shí)現(xiàn)粘招,都是一個(gè)性價(jià)比的問題。
這里放我自己寫的那些邏輯門的 Code:
有問題歡迎提 PR偎球,文章有任何問題也歡迎指出洒扎,還有最重要的一點(diǎn),所有的詳細(xì)資料都在: