大三上學期開展了數字系統設計的課程,下學期便要求自己寫一個單周期CPU和一個多周期CPU,既然要學,就記錄一下學習的過程。
CPU——中央處理器,顧名思義,是計算機中最重要的一部分,功能就是周而復始地執行指令。其實開始做這部分之前,想到CPU就覺得很麻煩,畢竟時計算機內部最重要的東西,但其實刨開來細看,也就慢慢地接受了,當然我現在也不能說是了如指掌,說簡單,畢竟自己還處於學習階段,甚至可能還沒有入門。慢慢來吧,先從簡單的開始,一步一個腳印,總能寫成的。今天先寫在具體寫代碼之前的思路和設計方案。
這次的設計是基於FPGA和Verilog設計一個RISC處理器,目前計划指令是14條,最終采用ISE進行代碼編寫與仿真。
14條指令分別如下:
| 指令類型 |
指令名稱 |
指令表示
|
指令 |
指令含義 |
|||||
| R型 |
Add |
0 | 18 | 19 | 17 | 0 | 32 | add rd,rs,rt |
兩個操作數相加 |
| R型 |
Subtract |
0 | 18 | 19 | 17 | 0 | 34 | sub rd,rs,rt |
兩個操作數相減 |
| I型 |
Load word |
35 | 18 | 17 | 100 | lw rt,rs,imm16 |
從內存取一個數寫入到寄存器 |
||
| I型 |
Store word |
43 | 18 | 17 | 100 | sw rt,rs,imm16 |
從寄存器中讀出一個數寫入到內存 |
||
| R型 |
And |
0 | 18 | 19 | 17 | 0 | 36 | and rd,rs,rt |
按位與 |
| R型 |
Or |
0 | 18 | 19 | 17 | 0 | 37 | or rd,rs,rt |
按位或 |
| R型 |
Nor |
0 | 18 | 19 | 17 | 0 | 39 | nor rd,rs,rt |
按位非 |
| I型 |
Ori |
13 | 18 | 17 | 100 | ori rt,rs,imm16 |
寄存器和常數按位或 |
||
| I型 |
Andiu |
12 | 18 | 17 | 100 | addiu rt,rs,imm16 |
寄存器和常數按位與 |
||
| I型 |
Beq |
4 | 18 | 17 | 100 | beq rs,rt,imm16 |
想等則轉移 |
||
| I型 |
Bne |
5 | 18 | 17 | 100 | beq rs,rt,imm16 |
不相等則轉移 |
||
| R型 |
Shift left logical |
0 | 0 | 18 | 17 | 10 | 0 | sll rd,rs,rt |
邏輯左移 |
| R型 |
Shift right logical |
0 | 0 | 18 | 17 | 10 | 2 | srl rd,rs,rt |
邏輯右移 |
| J型 |
J |
2 | 2500 | j target |
跳轉目標地址 |
||||
確定好CPU可以執行的指令后,就可以具體寫設計方案了。從上面的表就可以看出,有三種指令類型,分別是R型、I型和J型,那一個完整的設計方案必須包含這三種指令的執行。下面我給出我的設計方案圖以及各個部件的功能。
PC:存儲當前指令地址。
下地址邏輯:計算下一條指令地址。
指令存儲器:存儲指令。
主控部件:根據操作碼判斷指令類型是I型還是R型還是J型。
寄存器組:保存參加運算的操作數和中間結果。
ALU:算術邏輯單元,通過func選擇操作類型,完成基本的算術運算和邏輯運算。
擴展器:將16位立即數進行符號擴展或零擴展得到32位立即數。
數據選擇器1:根據指令類型選擇相應數據進行算術或邏輯運算。指令類型若為R型,則將busb作為ALU的輸入進行運算;若為I型,則將imm32作為ALU的輸入進行運算。
數據選擇器2:根據指令類型選擇是將ALU運算后的結果寫入寄存器組還是將數據存儲器中的數據存入寄存器組。指令若為R型,則將ALU運算后的結果寫入寄存器組;指令若為I型,則將數據存儲器中的數據存入寄存器組。
數據選擇器3:在overflow的控制下,選擇是將rd作為寄存器組的寫入地址還是將rt作為寄存器組的寫入地址。指令若為R型,則將rd作為寄存器組的寫入地址;指令若為I型,則將rt作為寄存器組的寫入地址。
基本的設計方案就是這樣,看起來部件或許比一些書上的多一些,是因為我將很多大部件拆成了一個個的小部件,這樣看起來會好理解很多。最后給出各個端口的定義。
接口定義如下:
| 接口名稱 |
類型 |
位寬/位 |
備注 |
| addr |
reg |
6 |
指令地址寄存器 |
| rs |
reg |
5 |
源操作數寄存器 |
| rt |
reg |
5 |
源操作數寄存器 |
| rd |
reg |
5 |
目的寄存器 |
| op |
reg |
6 |
操作碼 |
| func |
reg |
6 |
指令操作類型 |
| imm16 |
reg |
16 |
立即數 |
| imm32 |
reg |
32 |
擴展后的立即數 |
| busa |
reg |
32 |
rs內的數據 |
| busb |
reg |
32 |
rt內的數據 |
| R_type |
reg |
1 |
R型指令信號 |
| I_type |
reg |
1 |
I型指令信號 |
| J_type |
reg |
1 |
J型指令信號 |
| data_in |
reg |
32 |
數據選擇器1選擇出來的數據 |
| data_out |
reg |
32 |
ALU操作后的結果 |
| Overflow |
reg |
1 |
溢出信號 |
| data_I |
reg |
32 |
讀出的數據存儲器內的數據 |
| out |
reg |
32 |
寫入到寄存器組內的數據 |
