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