零基礎(chǔ)學(xué)FPGA(十四)第一片IC——精簡指令集RISC_CPU設(shè)計精講
不得不說,SDRAM的設(shè)計是我接觸FPGA以來調(diào)試最困難的一次設(shè)計,早在一個多月以前,我就開始著手想做一個SDRAM方面的教程,受特權(quán)同學(xué)影響,開始學(xué)習(xí)《高手進(jìn)階,終極內(nèi)存技術(shù)指南》這篇論文,大家都知道這篇文章是學(xué)習(xí)內(nèi)存入門的必讀文章,小墨同學(xué)花了一些時間在這上面,說實話看懂這篇文章是沒什么問題的,文件講的比較直白,通俗易懂,很容易入手。當(dāng)了解了SDRAM工作方式之后,我便開始寫代碼,從特權(quán)同學(xué)的那篇經(jīng)典教程里面,我認(rèn)真研讀代碼的來龍去脈,終于搞懂了特權(quán)同學(xué)的設(shè)計思想,并花了一些時間將代碼自己敲一遍,并加上自己的注釋
本文引用地址:http://m.butianyuan.cn/article/269804.htm
然而設(shè)計并沒有像我想象的那么簡單,代碼設(shè)計好之后還要經(jīng)過仿真,時序約束,仿真總體來說還好,但是時序約束我接觸的很少,于是又去學(xué)時序約束方面的知識,由于控制SDRAM時鐘跑到了100MHZ,時序約束對這個設(shè)計來說可以算是關(guān)鍵部分了,之前的設(shè)計由于對時序要求的不高,所以不用約束就可以實現(xiàn)。學(xué)習(xí)時序約束可以算是一個漫長的過程,經(jīng)過這段時間的學(xué)習(xí),小墨同學(xué)也開始反思,是不是自己的跨度有點大,設(shè)計SDRAM的過程確實有些吃力,所以,小墨同學(xué)決定暫時放棄SDRAM的教學(xué),等以后發(fā)Nios II的文章的時候再來談SDRAM。
這次我們先來學(xué)習(xí)一個CPU的設(shè)計,這個設(shè)計看似簡單,但是真要一步步做完還是需要點耐心和精力的。本篇文章我們主要介紹Risc_CPU的設(shè)計過程以及代碼分析,下一篇文章小墨同學(xué)主要和大家分享test bench的書寫與仿真測試,幫助大家一步一步學(xué)會這個cpu的設(shè)計,那么,我們開始今天的教學(xué)吧~
一、 設(shè)計前的準(zhǔn)備
設(shè)計開始之前,我們得先知道什么是CPU,cpu即中央處理器,是計算機(jī)的核心部件。cpu的工作過程,小墨同學(xué)簡單說一下。首先我們計算機(jī)的程序和數(shù)據(jù)是存在我們計算機(jī)的內(nèi)存中的,上電后cpu就需要從第一條指令的地址開始取指令,即取指令。取出的指令需要經(jīng)過指令譯碼來告訴cpu這條指令是用來干什么的,即分析指令。當(dāng)?shù)弥噶顑?nèi)容以后,cpu需要產(chǎn)生操作指令來完成相應(yīng)的操作,即執(zhí)行指令。所以,任何一種CPU內(nèi)部,至少應(yīng)該包含下列這些部件:
1.算數(shù)運算器
2.累加器
3.指令計數(shù)器
4.指令寄存器和譯碼器
5.時序控制器
二. 工作原理
在本次設(shè)計中,我們假設(shè)ROM中裝的是我們的程序指令,等會我們會往里面裝數(shù)據(jù),程序指令是16位的,cpu每次讀取8位,分兩次讀完,讀出來的數(shù)據(jù)存到指令寄存器中。
這16位數(shù)據(jù)的高三位代表指令碼
HLT = 3'b000,
SKZ = 3'b001,
ADD = 3'b010,
AND = 3'b011,
XOR = 3'b100,
LDA = 3'b101,
STO = 3'b110,
JMP = 3'b111;
后13位代表地址碼,指令寄存器將讀回來的數(shù)據(jù)分成指令碼opcode[2:0]和地址碼ir_addr[12:0],狀態(tài)控制器讀回指令碼進(jìn)行譯碼,看是什么指令,然后根據(jù)指令的內(nèi)容操作其他部件,若為寫數(shù)據(jù)則打開RAM進(jìn)行寫數(shù)據(jù),若為計算則將數(shù)據(jù)送到算數(shù)運算器進(jìn)行算數(shù)運算,若為跳轉(zhuǎn)指令則地址指向下一地址,下次讀取指令的時候就跳過一個地址執(zhí)行等等
三、各模塊精講
本次設(shè)計的cpu共包含8個模塊,下面我來一一講解
1.時鐘發(fā)生器
本模塊的用來產(chǎn)生分頻信號,外部50M的時鐘,做8分頻輸出,此8分頻信號用來控制地址多路器的輸出,由于之后我們要用到8狀態(tài)的狀態(tài)機(jī),因此這里做成8分頻,至于具體原因,我們后面再講,然后是一個算數(shù)運算器的使能信號,每一個8分頻信號到來之前有一個算術(shù)運算器使能信號的高脈沖,意思就是,每一此狀態(tài)機(jī)循環(huán)開始之前做一次運算
才有狀態(tài)機(jī)的方式來設(shè)計分頻信號避免了使用計數(shù)器計數(shù)的方法來延時,提高了程序的可讀性和速度
2.指令寄存器
本模塊的作用是將來自ROM的16位數(shù)據(jù)寄存并分為高三位的指令碼和低13位的地址碼
指令寄存器分兩次讀取ROM中的數(shù)據(jù)
3.累加器
算數(shù)運算器的初值位0,來自ROM的數(shù)據(jù)經(jīng)算數(shù)運算器處理之后輸出到累加器,累加器使能信號到來時,再將這份數(shù)據(jù)送到算數(shù)運算器作為初值,與下次從ROM中讀回的數(shù)據(jù)進(jìn)行算數(shù)運算
4.算數(shù)運算器
算術(shù)運算器先判斷來自ROM的高三位指令碼是何種指令,然后將來自ROM中的數(shù)據(jù)和來自累加器中的數(shù)據(jù)進(jìn)行算數(shù)運算,并將結(jié)果輸出。如果算數(shù)運算器中的數(shù)據(jù)是0的話,那么有一個高脈沖zero輸出
5.數(shù)據(jù)控制器
如果想將算數(shù)運算器的結(jié)果保存起來,輸出到RAM,那么可以選通數(shù)據(jù)控制器,將數(shù)據(jù)輸出到RAM,配合指令STO
6.地址多路器
8分頻時鐘的前半周期用來讀取ROM中指定地址的數(shù)據(jù),后半周期用來進(jìn)行指令操作,所以前半個周期需要從指定ROM中讀數(shù)據(jù),所以輸出地址應(yīng)為pc_addr,后半個周期用來處理指令,那么要操作的肯定是從ROM中讀回的13位地址,即ir_addr,并將其輸出
7.程序計數(shù)器
剛開始從ROM中讀取數(shù)據(jù)的地址是pc_addr,是0地址,若為跳轉(zhuǎn)指令,則需要將從ROM中讀回的13位地址碼作為新地址給pc_addr,等下一個8分頻時鐘到來時就讀取該地址的指令,實現(xiàn)跳轉(zhuǎn)指令的目的。如果不是跳轉(zhuǎn)指令,那么pc_addr加1指向下一地址,繼續(xù)執(zhí)行
8.狀態(tài)控制器
狀態(tài)控制器,即我們的狀態(tài)機(jī),使我們本次設(shè)計的核心部件,狀態(tài)機(jī)共用了8個狀態(tài)
前兩個狀態(tài)用來讀取ROM中的16位數(shù)據(jù),需要兩個時鐘,也就是需要兩個狀態(tài)。
第三個狀態(tài)等待一個時鐘周期,目的是要湊夠8個狀態(tài),因為8分頻時鐘的后半個周期需要4個狀態(tài)來完成,故前半周期也需要4個狀態(tài),由于前半周期只需要讀取數(shù)據(jù)和地址指向下一地址即可,故需湊一個狀態(tài)
第四個狀態(tài)地址加1 ,指向下一地址
第五到八個狀態(tài)用來分析指令和執(zhí)行指令,若為跳轉(zhuǎn)指令,則控制程序計數(shù)器改變目標(biāo)地址,若為跳過下一條指令,則控制程序計數(shù)器pc_addr地址加4,若為運算指令,則將控算數(shù)運算器進(jìn)行相應(yīng)的邏輯運算,若為LDA寫入指令,則將讀回的數(shù)據(jù)放入累加器中等等,具體操作指令的含義見下圖
各個模塊設(shè)計好之后將其組裝便完成了我們的cpu設(shè)計,組裝后的頂層模塊見下圖
這樣,我們的cpu就設(shè)計完成了,當(dāng)然設(shè)計完成之后還要進(jìn)行仿真,要仿真就還需要外圍電路,包括存期指令程序ROM,存取數(shù)據(jù)的RAM,地址譯碼器等,由于ROM和RAM是不可綜合的,但是我們可以在仿真的時候模擬。
由于每篇文章最多只能上傳20張圖片,所以今天的教程就到此為止吧,具體的仿真過程和ROM、RAM的設(shè)計小墨同學(xué)將在下一篇文章中介紹,下一篇文章中將會提到modolsim SE的使用,test bench的書寫,前面的博客中雖然也略有提及,但并不系統(tǒng),下一篇文章將會以本次設(shè)計為例,給大家介紹仿真的全過程,希望大家大力支持,下面附上部分仿真的圖片和測試結(jié)果供大家參考
波形仿真
謝謝各位大神的支持,這篇文章寫了幾個小時,純手打~
fpga相關(guān)文章:fpga是什么
負(fù)離子發(fā)生器相關(guān)文章:負(fù)離子發(fā)生器原理 塵埃粒子計數(shù)器相關(guān)文章:塵埃粒子計數(shù)器原理 離子色譜儀相關(guān)文章:離子色譜儀原理
評論