FPGA-10:設計個簡單的cpu(真的簡單!)
阿新 • • 發佈:2021-06-12
經過了之前的學習
想必各位對verilog應該有了基本的基礎
那麼,接下來,我們就來造cpu吧!
我們將寫一個簡單的單週期cpu
- 該cpu有一下特點:
- 32位架構
- 單週期執行
- 簡潔實用
- 32位定長指令
- 有手就行
我稱之為 “ant” 核心
就跟螞蟻一樣,“功能弱小”,但也什麼能幹
我也特地為該cpu編寫了個彙編器
包括使用python編寫的bin轉txt工具
連線如下:
下載該專案
即可得到5個檔案
cpu.v: ant核心核心檔案 test.v : ant核心模擬檔案 ant-asm.exe: ant彙編器 binTotxt.py:將bin檔案轉換成verilog可讀取的儲存器填充檔案 demo.ant:ant彙編例程
下面是暫存器說明及指令集:
暫存器: r0~r8 共16個32位暫存器,均可可讀可寫, r0~r14 通用暫存器 r15 pc暫存器 指令集:(總共14條) wh r0,num 寫r0暫存器的高16位 {8{指令},4{暫存器id},16{常數},4{無意義}} wl r0,num 寫r0暫存器的低16位 {8{指令},4{暫存器id},16{常數},4{無意義}} add r0,r1,r2 : r0 = r1 + r2 //整數加法 {8{指令},4{r0暫存器id},4{r1暫存器id},4{r2暫存器id},12{無意義}} sub r0,r1,r2 : r0 = r1 - r2 //整數減法 {8{指令},4{r0暫存器id},4{r1暫存器id},4{r2暫存器id},12{無意義}} or r0,r1,r2 : r0 = r1 | r2 {8{指令},4{r0暫存器id},4{r1暫存器id},4{r2暫存器id},12{無意義}} and r0,r1,r2 : r0 = r1 & r2 {8{指令},4{r0暫存器id},4{r1暫存器id},4{r2暫存器id},12{無意義}} not r0,r1 : r0 = ~r1 {8{指令},4{r0暫存器id},4{r1暫存器id},16{無意義}} sl r0,r1,r2 r0 = r1 << r2 {8{指令},4{r0暫存器id},4{r1暫存器id},4{r2暫存器id},12{無意義}} sr r0,r1,r2 : r0 = r1 >> r2 {8{指令},4{r0暫存器id},4{r1暫存器id},4{r2暫存器id},12{無意義}} mt r0,r1,r2 : r0 = r1 > r2 //比大小 返回0或1 {8{指令},4{r0暫存器id},4{r1暫存器id},16{無意義}} lt r0,r1,r2 : r0 = r1 < r2//同上 {8{指令},4{r0暫存器id},4{r1暫存器id},16{無意義}} rd r0,r1 : r1 = *r0//讀記憶體 {8{指令},4{r0暫存器id},4{r1暫存器id},16{無意義}} wd r0,r1 : *r0 = r1//寫記憶體 {8{指令},4{r0暫存器id},4{r1暫存器id},16{無意義}} if r0 :如果r0為非0,則跳過下一條指令
雖然指令只有短短14條,但也幾乎能夠完成所有事了
接下來我們來寫個簡單的1+2+3+...+100的程式
c程式碼如下:
int main() {
int all = 0;
int i = 1;
int j = 101;
int k = 0;
l1:
k = i < j;
if (!k)
goto l2;
else
all = all + i;
i = i + 1;
goto l1;
l2:
printf("%d", all);
}
c程式碼對應的彙編程式碼
彙編程式碼如下:
//0起始地址 wl r0,0 //恆為0 wh r0,0 wl r1,1 //恆為1 wh r1,0 //累加 wl r2,0 wh r2,0 //i wl r3,1 wh r3,0 //101 wl r4,101 wh r4,0 //k wl r5,0 wh r5,0 //地址16 wl r6,16 wh r6,0 //地址22 wl r7,22 wh r7,0 //地址16: lt r5,r3,r4 if r5//如果r3小於r4 add r15,r7,r0 add r2, r2, r3 add r3,r3,r1 add r15,r6,r0 //地址22: wd r0,r2
將該彙編程式碼儲存進"demo.ant"檔案中
輸入命令:
ant-asm demo.ant
即可得到
out.bin可執行檔案
再執行binTotxt.py指令碼(注意更改裡面的路徑)
得到out.list填充檔案
模擬test.v檔案,將out.list內容填充進rom
執行
模擬效果如下:
可以看到,正確的算出了5050這個值
說明程式碼和ant核心是沒有什麼問題的