終於來到了這一步!!
前文裡,我們學習了hack程式語言,大概知道需要實現的hack計算機是什麼樣子,需要實現哪些功能。同時在更早的時候,我們建造了ALU和RAM元件,加上老師內建的ROM和鍵盤螢幕外設,那麼開幹!
等一下,在開始之前,我想先聊聊當今通用計算機的體系結構,也就是大名鼎鼎的馮諾依曼體系,我們的hack計算機也是依據於此
馮諾依曼體系介紹
“有道無術,術尚可求;有術無道,止於術”,三體裡秦始皇欲建造人型計算機,b站裡的大神用excel實現的cpu,當然還有我們這門課程裡將要在模擬器裡實現的hack計算機,他們都遵循著馮諾依曼體系框架。從b站評論裡看來的,“理論上,只要是可以實現與非門和時鐘的,都可以用來用來實現計算機”
這張圖,我記得在大一的計算機組成原理裡看見過,哈哈哈,只記得馮諾依曼這四個字了
我們通常有三種資訊型別在系統間傳遞。資料,當我們進行加法運算時,輸入需要從記憶體移動到暫存器中,再到實際的運算單元,進行計算後返回;地址,實現執行的是什麼指令和需要訪問記憶體中的哪些資料,這些都在地址裡的;控制,系統的每一個組成部分需要知道,在特定的時間點做什麼事情
下面,讓我們看看計算機裡面的不同元件,他們可以接收什麼資訊和發出什麼資訊
CPU
我們的CPU分為兩個元件,一是算術邏輯單元ALU,二是暫存器。算術邏輯單元能夠加減數字,也能夠進行邏輯運算;暫存器則是暫存一些資料,這些資料,在後續的計算中將要使用
ALU需要接入資料匯流排,因為需要拉取資料計算,然後返回;同時,他需要控制匯流排的資訊,告訴他要執行的操作型別是什麼,可能是相加,可能是取反;另一方面,根據計算結果,alu會返回標誌位資訊,如 結果是否大於0,這些需要放在控制匯流排上,告訴系統的其他部分做什麼操作,比如下一個指令是否跳轉
暫存器在概念上很簡單,作為cpu的緩衝單元,理所當然的需要接入資料匯流排;同時暫存器在設計上,還支援指定地址這種來取/設值,這實際是間接定址到RAM或者ROM上,這就需要暫存器連線到地址匯流排上
綜上,cpu需要透過資料匯流排/地址匯流排獲取輸入資料,透過控制匯流排得到運算函式,計算得到的結果輸出至資料/地址匯流排上,同時計算結果標誌位反饋到控制匯流排,等待下一次計算
記憶體
標準的馮洛伊曼體系,應該是使用一塊記憶體,資料和指令均放入其中,這裡簡化處理為資料和指令獨立放在一塊記憶體中(哈佛結構),還有一些別的原因,不在這裡說明了,仍以馮洛伊曼體系介紹
記憶體最直接的需求就是資料讀寫,需要連線在資料匯流排上;同時上面提到的CPU的輸入和輸出均可以是地址,記憶體同樣需要連線到地址匯流排上;其次指令記憶體需要知道下一條待執行的指令內容,這裡cpu輸出的指令地址被歸納進控制匯流排裡
這裡貼兩張資料記憶體和指令記憶體的資料流轉圖,幫助理解記憶體在整個鏈路扮演的角色
綜上,記憶體透過控制控制匯流排取出指令地址,透過地址匯流排取出輸入資料,然後經cpu計算後,透過地址匯流排和資料匯流排寫回輸出資料至記憶體中,同時控制匯流排上返回下一次待執行的地址
這裡,描述的有點亂。三條匯流排只是一個概念模型,理解每個元件做什麼的就好了。知道大概是這樣的思路,重要的還是引出下面的CPU和RAM的輸入輸出引數設計
計算機設計
總體架構
看起來複雜,實際對於計算機來說,只是單純的取指令,執行再取
CPU
想從白紙實現出來,我感覺難度相當高,課程老師估計也知道,直接給了實現結構圖,照著連線就好。我這裡如果說你問我,為什麼這個結構可以實現cpu,我是知道的,但若你問我cpu還有沒有別的實現結構,我就懵了
白板
實現結構圖
實現思路
這裡照著圖實現思路,就很清晰了。把指令裡的每一位取出來,然後進行不同的判斷,稍微複雜一點的就是現在ALU的返回值也需要用到了;這部分詳細可以參照影片
跳轉實現思路
RAM
這裡很簡單,想想怎麼區分不同的地址段即可
ROM
這是內建晶片,提供的介面就是取指
計算機
計算機就是把上面的幾個晶片,組裝起來
hdl實現
這裡還是貼一下程式碼,不要以後自己想看的時候,忘記了 哈哈
cpu
CHIP CPU {
IN inM[16], // M value input (M = contents of RAM[A])
instruction[16], // Instruction for execution
reset; // Signals whether to re-start the current
// program (reset==1) or continue executing
// the current program (reset==0).
OUT outM[16], // M value output
writeM, // Write to M?
addressM[15], // Address in data memory (of M)
pc[15]; // address of next instruction
PARTS:
Mux16(a=instruction[0..15],b=aluout,sel=instruction[15],out=ain);
// allow `A` @x -> set A
Not(in=instruction[15],out=opnot);
Or(a=opnot,b=instruction[5], out=ac);
ARegister(in=ain,load=ac,out=aout,out[0..14]=addressM);
// D only load from `C`
And(a=instruction[15],b=instruction[4], out=dc);
DRegister(in=aluout,load=dc,out=aluin1);
Mux16(a=aout,b=inM,sel=instruction[12],out=aluin2);
ALU(x=aluin1,y=aluin2,zx=instruction[11],nx=instruction[10],zy=instruction[9],ny=instruction[8],f=instruction[7],no=instruction[6],out=aluout,out=outM,zr=zr,ng=ng);
And(a=instruction[15],b=instruction[3],out=writeM);
// PC
Not(in=zr,out=notzr);
Not(in=ng,out=notng);
// great!
DMux8Way(in=instruction[15], sel=instruction[0..2], a=null, b=jgt, c=jeq, d=jge, e=jlt, f=jne, g=jle, h=jmp);
And(a=notzr,b=notng,out=jgt1);
And(a=jgt,b=jgt1,out=jgt2);
And(a=jeq,b=zr,out=jeq1);
And(a=jge,b=notng,out=jge1);
And(a=jlt,b=ng,out=jlt1);
And(a=jne,b=notzr,out=jne1);
Or(a=zr,b=ng,out=jle1);
And(a=jle,b=jle1,out=jle2);
Or8Way(in[0]=false, in[1]=jgt2, in[2]=jeq1, in[3]=jge1, in[4]=jlt1, in[5]=jne1, in[6]=jle2, in[7]=jmp, out=jumpout);
PC(in=aout,inc=true,load=jumpout,reset=reset,out[0..14]=pc);
}
memory
CHIP Memory {
IN in[16], load, address[15];
OUT out[16];
PARTS:
DMux(in=load, sel=address[14], a=m1, b=m2);
RAM16K(in=in, load=m1, address=address[0..13], out=out1);
DMux(in=m2, sel=address[13], a=r1, b=r2);
Screen(in=in, load=r1, address=address[0..12], out=out2);
Keyboard(out=out3);
Mux16(a=out2,b=out3,sel=address[13],out=out4);
Mux16(a=out1,b=out4,sel=address[14],out=out);
}
computer
CHIP Computer {
IN reset;
PARTS:
CPU(inM=inM,instruction=instruction,reset=reset,outM=outM,writeM=writeM,addressM=addressM,pc=pc);
Memory(address=addressM,in=outM,load=writeM,out=inM);
ROM32K(address=pc,out=instruction);
}
總結
到這裡,這門課程其實就結束了,後面還有一章是編譯器,我當時是直接用筆完成的,也沒有寫程式碼。哈哈哈,程式碼寫多了,反而喜歡樸素的方式來實現,還是懶吧。這章是4月做完的,已經過去了5,6,7,三個月了。這學習啊,一放下就會不經意過去好久了。
記得當時學完課程就開始寫這個部落格了,並沒有預期的那麼興奮,總覺得少了什麼,所以一直沒有寫完,這次只是草草貼了幾張圖收尾。現在想來,大概是時鐘這個概念還是沒有理解,這門課程最大的收穫可能就是cpu不再那麼神秘了,它真的是由與非門實現的,這裡還是有很多細節的,不過還是儘快開始下一門課吧。再放下去,今年就過去了。
好讀書,不求甚解;每有會意,便欣然忘食。