數(shù)字系統(tǒng)設(shè)計(jì)-流水線(xiàn)CPU設(shè)計(jì)_第1頁(yè)
數(shù)字系統(tǒng)設(shè)計(jì)-流水線(xiàn)CPU設(shè)計(jì)_第2頁(yè)
數(shù)字系統(tǒng)設(shè)計(jì)-流水線(xiàn)CPU設(shè)計(jì)_第3頁(yè)
數(shù)字系統(tǒng)設(shè)計(jì)-流水線(xiàn)CPU設(shè)計(jì)_第4頁(yè)
數(shù)字系統(tǒng)設(shè)計(jì)-流水線(xiàn)CPU設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩35頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

實(shí)驗(yàn)報(bào)告課程名稱(chēng):數(shù)字系統(tǒng)設(shè)計(jì)實(shí)驗(yàn)Ⅱ?qū)W院:信電系ContentsPart1實(shí)驗(yàn)?zāi)康?3Part2實(shí)驗(yàn)任務(wù) 3Part3實(shí)驗(yàn)原理 4Part4實(shí)驗(yàn)步驟 121.IF級(jí)設(shè)計(jì)……………………122.ID級(jí)設(shè)計(jì)…………………..143.Decode單元設(shè)計(jì)……………………….164.ALU單元設(shè)計(jì)…………….225.EX級(jí)設(shè)計(jì)…………………..276.頂層模塊設(shè)計(jì)……………..29Part5仿真和波形分析…………..371.IF級(jí)仿真分析………………..……………372.Decode單元仿真分析……..………….383.ALU仿真分析………………..……………404.頂層仿真分析………………..…………….41Part6心得…………………………42實(shí)驗(yàn)報(bào)告一、實(shí)驗(yàn)?zāi)康牧私馓岣逤PU性能的方法。理解數(shù)據(jù)冒險(xiǎn)、控制冒險(xiǎn)的概念以及流水線(xiàn)沖突的解決方法。掌握流水線(xiàn)MIPS微處理器的工作原理。掌握流水線(xiàn)MIPS微處理器的測(cè)試方法。二、實(shí)驗(yàn)任務(wù)設(shè)計(jì)一個(gè)32位流水線(xiàn)MIPS微處理器。設(shè)計(jì)要求:至少執(zhí)行以下MIPS32指令。算數(shù)運(yùn)算指令:ADDADDUSUBSUBUADDIADDU邏輯運(yùn)算指令:ANDORNORXORANDIORIXORISLTSLTISLTUSLTIU移位指令:SLLSLLVSRLSRLVSRA條件分支指令:BEQBNEBGEZBGTZBLEZBLTZ無(wú)條件跳轉(zhuǎn)指令:JJR數(shù)據(jù)傳輸指令:LWSW空指令:NOP在用5級(jí)流水線(xiàn)技術(shù),對(duì)數(shù)據(jù)冒險(xiǎn)實(shí)現(xiàn)轉(zhuǎn)發(fā)或阻塞功能。在XUPVietex-IIPro開(kāi)發(fā)系統(tǒng)中實(shí)現(xiàn)MIPS微處理器,要求CPU的運(yùn)行速度大于25MHz.實(shí)驗(yàn)原理1.流水線(xiàn)MIPSCPU總體設(shè)計(jì)與構(gòu)建流水線(xiàn)是數(shù)字系統(tǒng)中一種提高系統(tǒng)穩(wěn)定性和工作速度的方法,廣泛應(yīng)用在高檔CPU的構(gòu)建中。根據(jù)MIPS處理器指令的特點(diǎn),將整體的處理過(guò)程分為取指令〔IF〕、指令譯碼、執(zhí)行、存儲(chǔ)器訪(fǎng)問(wèn)和存放器寫(xiě)回五級(jí),對(duì)應(yīng)多周期CPU的五個(gè)處理階段。如圖1所示,一個(gè)指令的執(zhí)行需要五個(gè)時(shí)鐘周期,每個(gè)時(shí)鐘周期上升沿來(lái)臨時(shí),此指令所代表的一系列數(shù)據(jù)和控制信息轉(zhuǎn)移到下一級(jí)處理,從起步到滿(mǎn)負(fù)荷工作再到停止。圖1流水線(xiàn)流水作業(yè)示意圖一條MIPS指令分為五個(gè)處理步驟,即五級(jí)流水線(xiàn),的具體執(zhí)行過(guò)程如圖2所示。從存儲(chǔ)器中讀

取指令:IF級(jí)指令譯碼的同時(shí)讀取從存儲(chǔ)器中讀

取指令:IF級(jí)指令譯碼的同時(shí)讀取存放器:ID級(jí)執(zhí)行操作或地址計(jì)算:EX級(jí)讀取數(shù)據(jù)存儲(chǔ)器:MEM級(jí)將結(jié)果寫(xiě)回存放器:WB級(jí)圖2五級(jí)流水線(xiàn)MIPSCPU初步原理框圖為了將各級(jí)的數(shù)據(jù)保存和傳遞,需要在上圖中各級(jí)分割線(xiàn)處都參加存放器,此處根據(jù)流水線(xiàn)的性能要求選擇不停種類(lèi)的D觸發(fā)器,具體代碼將在頂層代碼中予以介紹。實(shí)施方案草圖如圖3所示:圖3.在各級(jí)分割線(xiàn)添加存放器后的框圖由于在流水線(xiàn)中,數(shù)據(jù)和控制信息將在時(shí)鐘上升到來(lái)時(shí)轉(zhuǎn)移到下一級(jí),因此沿在流水線(xiàn)中轉(zhuǎn)移的數(shù)據(jù)和控制信號(hào)的命名格式為:變量名_流水線(xiàn)級(jí)名稱(chēng),這樣做使命名方式更加清晰,并且在檢錯(cuò)時(shí)對(duì)迅速定位錯(cuò)誤幫助很大。為從整體上把握流水線(xiàn)設(shè)計(jì),并為正確譯得控制信號(hào),要熟練掌握指令格式即Instruction不同區(qū)間所執(zhí)行的功能。1.MIPS指令格式:①R型指令格式本實(shí)驗(yàn)需要實(shí)現(xiàn)的R型指令有:I)算術(shù)邏輯運(yùn)算指令: ADD、ADDU、SUB、SUBU、AND、OR、NOR、XOR、SLT、SLTUII)移位指令:SLLV、SRLV、SRAVIII)存放器跳轉(zhuǎn)指令:JR②I型指令格式本實(shí)驗(yàn)需要實(shí)現(xiàn)的I型指令有:I)存儲(chǔ)器訪(fǎng)問(wèn)指令:LW、SWII)立即數(shù)算術(shù)邏輯運(yùn)算指令:ADDI、ADDIU、ANDI、ORI、XORI、SLTI、SLTIUIII)分支指令:BEQ、BNE、BGEZ、BGTZ、BLEZ、BLTZ分支地址為:PC+4+(sign-extend(Imm)<<2)③J型指令格式本實(shí)驗(yàn)需要實(shí)現(xiàn)的J型指令只有:無(wú)條件跳轉(zhuǎn)指令:J跳轉(zhuǎn)地址為:{PC[31:28],IR[25:0],2’特別注意:1、存放器跳轉(zhuǎn)指令JR不是J型指令,而是R型指令,其指令格式為:移位指令只有rt一個(gè)源操作數(shù):3、取字指令的操作過(guò)程:rt<=Mem[rs+sign_extend(imm)]存字指令的操作過(guò)程:Mem[rs+sign_extend(imm)]<=rt控制信號(hào)設(shè)置為保證CPU按照指令正常運(yùn)行,分別設(shè)置各個(gè)級(jí)的控制信號(hào):IF級(jí):從ROM中讀取指令,并在下一個(gè)時(shí)鐘到來(lái)時(shí)把指令送到ID級(jí)指令緩沖器中。該級(jí)的控制信號(hào)決定下一個(gè)指令指針PCSoure信號(hào)、阻塞流水線(xiàn)的PC_IFwrite信號(hào)、清空流水線(xiàn)IF_flush信號(hào)。ID級(jí):對(duì)指令進(jìn)行譯碼,產(chǎn)生相應(yīng)的控制信號(hào)。CPU的所有控制信號(hào)根本由此級(jí)產(chǎn)生,且此級(jí)不需要控制信號(hào)。流水線(xiàn)冒險(xiǎn)檢測(cè)也在此級(jí)進(jìn)行,冒險(xiǎn)電路需要MemWrite信號(hào)。EX級(jí):進(jìn)行算數(shù)或邏輯運(yùn)算,LW、SW指令所用的RAM訪(fǎng)問(wèn)地址在此級(jí)產(chǎn)生。這里需要ALUCode、ALUSrcA、ALUSrcB、RegDst確定ALU操作、選擇ALU操作數(shù)A、B,并確定目標(biāo)存放器。此外,數(shù)據(jù)轉(zhuǎn)發(fā)在此級(jí)完成,產(chǎn)生ForwardA、ForwardB兩組控制信號(hào)。MEM級(jí):只執(zhí)行LW、SW指令時(shí)對(duì)存儲(chǔ)器進(jìn)行訪(fǎng)問(wèn),這里只有存儲(chǔ)器讀寫(xiě)控制信號(hào)MemWrite。WB級(jí):把指令執(zhí)行的結(jié)果寫(xiě)回到存放器文件中,控制信號(hào)有Memtoreg、RegWrite。冒險(xiǎn)與解決①數(shù)據(jù)相關(guān)和數(shù)據(jù)轉(zhuǎn)發(fā)流水線(xiàn)工作中不可防止的將要產(chǎn)生競(jìng)爭(zhēng)冒險(xiǎn)現(xiàn)象,為保證正常的讀寫(xiě)操作,引入數(shù)據(jù)轉(zhuǎn)發(fā)功能。數(shù)據(jù)相關(guān):流水線(xiàn)內(nèi)部其中任何一條指令要用到任何其它指令的計(jì)算結(jié)果時(shí),將導(dǎo)致數(shù)據(jù)冒險(xiǎn),數(shù)據(jù)相關(guān)有三種類(lèi)型,設(shè)計(jì)中分別制定解決方案,用數(shù)據(jù)轉(zhuǎn)發(fā)〔數(shù)據(jù)定向〕來(lái)解決此類(lèi)冒險(xiǎn)。舉例分析:一階數(shù)據(jù)相關(guān)〔EX冒險(xiǎn)〕sub指令在第5時(shí)鐘周期寫(xiě)回存放器,而and指令在第4時(shí)鐘周期就對(duì)sub指令的結(jié)果提出了請(qǐng)求,很顯然and指令讀取的數(shù)據(jù)是未被更新的錯(cuò)誤內(nèi)容。這類(lèi)數(shù)據(jù)相關(guān)稱(chēng)之為一階數(shù)據(jù)相關(guān)。圖4一階數(shù)據(jù)相關(guān)仔細(xì)觀察sub指令,可以發(fā)現(xiàn),sub指令的結(jié)果其實(shí)在EX級(jí)結(jié)尾,即第3時(shí)鐘周期末就產(chǎn)生了,存儲(chǔ)在存放器中。而and指令在第4時(shí)鐘周期向sub指令結(jié)果發(fā)出請(qǐng)求。請(qǐng)求時(shí)間晚于結(jié)果產(chǎn)生時(shí)間。所以,只要sub指令結(jié)果產(chǎn)生之后,就可以直接將它“轉(zhuǎn)發(fā)”給and指令,而不需要先寫(xiě)回存放器堆,再由and指令將其讀取出來(lái)。轉(zhuǎn)發(fā)條件:在MEM級(jí)的指令需要寫(xiě)回存放器,即RegWrite_mem=1在MEM級(jí)的指令在寫(xiě)回時(shí),目標(biāo)存放器不能是存放器$0,即RegWriteAddr_mem≠0在MEM級(jí)的指令寫(xiě)回時(shí)的目標(biāo)存放器與在EX級(jí)的指令的源存放器是同一存放器,即RegWriteAddr_mem=RsAddr_ex或RegWriteAddr_mem=RtAddr_ex2〕二階數(shù)據(jù)相關(guān)〔MEM冒險(xiǎn)〕現(xiàn)在討論sub指令和or指令之間的相關(guān)問(wèn)題。如圖5所示:圖5二階數(shù)據(jù)相關(guān)sub指令在第5時(shí)鐘周期寫(xiě)回存放器,而or指令也在第5時(shí)鐘周期對(duì)sub指令的結(jié)果提出了請(qǐng)求,很顯然or指令讀取的數(shù)據(jù)是未被更新的錯(cuò)誤內(nèi)容。這類(lèi)數(shù)據(jù)相關(guān)稱(chēng)之為二階數(shù)據(jù)相關(guān)。如前所述,or指令在第5時(shí)鐘周期向sub指令結(jié)果發(fā)出請(qǐng)求時(shí),sub指令的結(jié)果已經(jīng)產(chǎn)生。所以,我們同樣采用“轉(zhuǎn)發(fā)”,即通過(guò)MEM/WB流水線(xiàn)存放器,將sub指令結(jié)果“轉(zhuǎn)發(fā)”給or指令,而不需要先寫(xiě)回存放器堆。轉(zhuǎn)發(fā)條件:在WB級(jí)的指令需要寫(xiě)回存放器,即RegWrite_wb=1在WB級(jí)的指令在寫(xiě)回時(shí),目標(biāo)存放器不能是存放器$0,即RegWriteAddr_wb≠0在WB級(jí)的指令寫(xiě)回時(shí)的目標(biāo)存放器與在EX級(jí)的指令的源存放器是同一存放器,即RegWriteAddr_wb=RsAddr_ex或RegWriteAddr_wb=RtAddr_exEX冒險(xiǎn)不成立,即RegWriteAddr_mem≠RsAddr_ex或RegWriteAddr_mem≠RtAddr_ex三階數(shù)據(jù)相關(guān)現(xiàn)在討論sub指令和add指令之間的相關(guān)問(wèn)題。這兩條指令在第5時(shí)鐘周期內(nèi)同時(shí)讀寫(xiě)同一個(gè)存放器。這類(lèi)數(shù)據(jù)相關(guān)稱(chēng)之為三階數(shù)據(jù)相關(guān),如圖6所示。假設(shè)存放器的寫(xiě)操作發(fā)生在時(shí)鐘周期的上升沿,而讀操作發(fā)生在時(shí)鐘周期的下降沿,那么讀操作將讀取到最新寫(xiě)入的內(nèi)容。在這種假設(shè)條件下將不會(huì)發(fā)生數(shù)據(jù)冒險(xiǎn)。這就要求流水線(xiàn)中的存放器具有“先寫(xiě)后讀〔ReadAfterWrite〕”的特性。這類(lèi)“寫(xiě)操作發(fā)生在時(shí)鐘周期的上升沿,讀操作發(fā)生在時(shí)鐘周期的下降沿”的存放器雖然在理論上是可實(shí)現(xiàn)的,但是不適合應(yīng)用于同步系統(tǒng),因?yàn)樗坏绊懴到y(tǒng)的運(yùn)行速度,而且影響系統(tǒng)的穩(wěn)定性,是不可取的。因此,采用“轉(zhuǎn)發(fā)”機(jī)制來(lái)解決三階數(shù)據(jù)相關(guān)冒險(xiǎn)。該局部轉(zhuǎn)發(fā)電路我們放在存放器堆的設(shè)計(jì)中完成。圖6三階數(shù)據(jù)相關(guān)轉(zhuǎn)發(fā)條件:在WB級(jí)的指令需要寫(xiě)回存放器,即RegWrite_wb=1在WB級(jí)的指令在寫(xiě)回時(shí),目標(biāo)存放器不能是存放器$0,即RegWriteAddr_wb≠0在WB級(jí)的指令寫(xiě)回時(shí)的目標(biāo)存放器與在ID級(jí)的指令的源存放器是同一存放器,即RegWriteAddr_wb=RsAddr_id或RegWriteAddr_wb=RtAddr_id為了實(shí)現(xiàn)數(shù)據(jù)相關(guān)的判別以及相應(yīng)的數(shù)據(jù)轉(zhuǎn)發(fā)功能,在EX級(jí)中增加ForwardingUnit,原理圖如圖7:圖7數(shù)據(jù)相關(guān)轉(zhuǎn)發(fā)機(jī)制②數(shù)據(jù)冒險(xiǎn)與阻塞當(dāng)一條指令試圖讀取一個(gè)存放器,而它前一條指令是lw指令,并且該lw指令寫(xiě)入的是同一個(gè)存放器時(shí),定向轉(zhuǎn)發(fā)的方法無(wú)法解決問(wèn)題。例如:lw$2,20($1)and$4,$2,$5or$8,$2,$6add$9,$4,$2lw指令只能在第4時(shí)鐘周期從內(nèi)存中讀出數(shù)據(jù),因此它和緊隨其后的and指令之間的依賴(lài)關(guān)系與時(shí)序方向是相反的,這種逆序的冒險(xiǎn)是無(wú)法通過(guò)轉(zhuǎn)發(fā)來(lái)實(shí)現(xiàn)的。這類(lèi)冒險(xiǎn)不同于數(shù)據(jù)相關(guān)冒險(xiǎn),需要單獨(dú)一個(gè)“冒險(xiǎn)檢測(cè)單元〔HazardDetector〕”。它在ID級(jí)完成。冒險(xiǎn)成立的條件:上一條指令是lw指令,即MemRead_ex=1在EX級(jí)的lw指令與在ID級(jí)的指令讀寫(xiě)的是同一個(gè)存放器,即 RegWriteAddr_ex=RsAddr_id或RegWriteAddr_ex=RtAddr_id冒險(xiǎn)的解決:引入流水線(xiàn)阻塞。原理圖如圖8所示,引入HazardDetector檢測(cè)單元:圖8HazardDetector檢測(cè)單元當(dāng)HazardDetector檢測(cè)到冒險(xiǎn)條件成立時(shí),在lw指令和下一條指令之間插入阻塞,即流水線(xiàn)氣泡〔bubble〕,使后一條指令延遲一個(gè)時(shí)鐘周期執(zhí)行,這樣就將該冒險(xiǎn)轉(zhuǎn)化為二階數(shù)據(jù)相關(guān),可用轉(zhuǎn)發(fā)解決。需要注意的是,如果處于ID級(jí)的指令被阻塞,那么處于IF級(jí)的指令也必須阻塞,否那么,處于ID級(jí)的指令就會(huì)喪失。防止這兩條指令繼續(xù)執(zhí)行的方法是:保持PC存放器和IF/ID流水線(xiàn)存放器不變,同時(shí)插入一個(gè)流水線(xiàn)氣泡。保持PC存放器和IF/ID流水線(xiàn)存放器不變: 在ID級(jí)檢測(cè)到冒險(xiǎn)條件時(shí),HazardDetector輸出一個(gè)信號(hào):PC_IFWrite,作為使能信號(hào)同時(shí)送給PC存放器和IF/ID流水線(xiàn)存放器。冒險(xiǎn)成立時(shí),該信號(hào)為低電平,禁止PC存放器和IF/ID流水線(xiàn)存放器接收新數(shù)據(jù)。流水線(xiàn)氣泡的插入:在ID級(jí)檢測(cè)到冒險(xiǎn)條件時(shí),HazardDetector輸出一個(gè)信號(hào):stall,將ID/EX流水線(xiàn)存放器中的EX、MEM和WB級(jí)控制信號(hào)全部清零。這些信號(hào)傳遞到流水線(xiàn)后面的各級(jí),由于控制信號(hào)均為零,所以不會(huì)對(duì)任何存放器和存儲(chǔ)器進(jìn)行寫(xiě)操作。 ③分支冒險(xiǎn)以上各類(lèi)冒險(xiǎn)局限于算術(shù)運(yùn)算和數(shù)據(jù)傳輸中。還有一類(lèi)冒險(xiǎn)就是包含分支的流水線(xiàn)冒險(xiǎn)。流水線(xiàn)每個(gè)時(shí)鐘周期都得取指令才能維持運(yùn)行,但分支指令必須等到MEM級(jí)才能確定是否執(zhí)行分支。這種為了確定預(yù)取正確的指令而導(dǎo)致的延遲叫做控制冒險(xiǎn)或分支冒險(xiǎn)。舉例如圖6:圖9分支冒險(xiǎn)分支冒險(xiǎn)的解決方法:提前分支指令一種比擬普遍的提高分支阻塞速度的方法是假設(shè)分支不發(fā)生,并繼續(xù)執(zhí)行順序的指令流。如果分支發(fā)生的話(huà),就丟棄已經(jīng)預(yù)取并譯碼的指令,指令的執(zhí)行沿著分支目標(biāo)繼續(xù)。由于分支指令直到MEM級(jí)才能確定下一條指令的PC,這就意味著為了丟棄指令必須將流水線(xiàn)中的IF、ID和EX級(jí)的指令都去除掉〔flush〕。這種優(yōu)化方法的代價(jià)較大,效率較低。假設(shè)能在流水線(xiàn)中提前分支指令的執(zhí)行過(guò)程,那么就能減少需要去除的指令數(shù)。這是一種提高分支效率的方法,降低了執(zhí)行分支的代價(jià)。提前分支指令需要提前完成兩個(gè)操作:計(jì)算分支的目的地址由于已經(jīng)有了PC值和IF/ID流水線(xiàn)存放器中的指令值,所以可以很方便地將EX級(jí)的分支地址計(jì)算電路移到ID級(jí)。我們針對(duì)所有指令都執(zhí)行分支地址的計(jì)算過(guò)程,但只有在需要它的時(shí)候才會(huì)用到。b. 判斷分支指令的跳轉(zhuǎn)條件。將用于判斷分支指令成立的Zero信號(hào)檢測(cè)電路〔Ztest〕從ALU中獨(dú)立出來(lái),并將它從EX級(jí)提前至ID級(jí)。具體的設(shè)計(jì)將在ID級(jí)設(shè)計(jì)中介紹。在提前完成以上兩個(gè)操作之外,我們還需丟棄IF級(jí)的指令。具體做法是:參加一個(gè)控制信號(hào)IF_flush,做為IF/ID流水線(xiàn)存放器的清零信號(hào)。當(dāng)分支冒險(xiǎn)成立,即Z=1,那么IF_flush=1,否那么IF_flush=0,故IF_flush=Z??紤]到本系統(tǒng)還要實(shí)現(xiàn)的無(wú)條件跳轉(zhuǎn)指令:J和JR,在執(zhí)行這兩個(gè)指令時(shí)也必須要對(duì)IF/ID流水線(xiàn)存放器進(jìn)行清空,因此,IF_flush的表達(dá)式應(yīng)表示為:IF_flush=Z||J||JR綜合以上分析,最終的無(wú)冒險(xiǎn)的流水線(xiàn)MIPSCPU原理框圖如圖7.圖10無(wú)冒險(xiǎn)的流水線(xiàn)MIPSCPU總體原理框圖四.實(shí)驗(yàn)步驟完成整體設(shè)計(jì)設(shè)想后,并細(xì)致考慮控制信號(hào)和競(jìng)爭(zhēng)冒險(xiǎn)后,開(kāi)始進(jìn)行各個(gè)子模塊的設(shè)計(jì)工作。接下來(lái)的局部將分別介紹IF級(jí),ID級(jí),EX級(jí),Decode單元,ALU單元以及頂層模塊的設(shè)計(jì)。1.IF級(jí)設(shè)計(jì)用XilinxCOREGenerator實(shí)現(xiàn)產(chǎn)生的ROM無(wú)法滿(mǎn)足流水線(xiàn)CPU的指令要求,我們需用VerilogHDL設(shè)計(jì)一個(gè)ROM陣列??紤]到FPGA的資源,指令存儲(chǔ)器可設(shè)計(jì)為容量各為26×32bit的ROM。已設(shè)計(jì)好上述測(cè)試程序機(jī)器碼的指令存儲(chǔ)器,文件名為InstructionROM.v,儲(chǔ)存實(shí)驗(yàn)所需指令。代碼分析moduleIF(clk,reset,Z,J,JR,PC_IFWrite,JumpAddr,JrAddr,BranchAddr,Instruction_if,PC,NextPC_if);inputclk;inputreset;inputZ;inputJ;inputJR;inputPC_IFWrite;input[31:0]JumpAddr;input[31:0]JrAddr;input[31:0]BranchAddr;output[31:0]Instruction_if;output[31:0]PC;//reg[31:0]PC;output[31:0]NextPC_if;//MUXforPCreg[31:0]PC_in;wire[2:0]PCSource;assignPCSource={JR,J,Z};//reg[31:0]PC_temp;always@(*)begincase(PCSource)3'b000:PC_in=NextPC_if;3'b001:PC_in=BranchAddr;3'b010:PC_in=JumpAddr;3'b100:PC_in=JrAddr;endcaseend //PCREGdffre#(32)PC_reg(.d(PC_in),.en(PC_IFWrite),.r(reset),.clk(clk),.q(PC));//AdderforNextPCadder_32bitsIF(.a(PC),.b(32'd4),.ci(1'b0),.s(NextPC_if),.co());//ROMInstructionROMInstructionROM( .addr(PC[7:2]), .dout(Instruction_if)); endmodule//模塊的變量命名//地址變換的標(biāo)志////D觸發(fā)器使能信號(hào),需要時(shí)可阻塞電路//三中待選擇的PC地址//下一時(shí)刻PC的值//PC的三位選擇信號(hào),8選1數(shù)據(jù)選擇器分情況將值賦給中間信號(hào)PC_in//用32位D觸發(fā)器完成每一時(shí)鐘PC值的更新和保持用先前設(shè)計(jì)的32位全加器計(jì)算下一時(shí)刻的PC值,并按PC值在InstructionROM中取出指令用于之后的操作2.ID級(jí)設(shè)計(jì)代碼分析moduleID(clk,Instruction_id,NextPC_id,RegWrite_wb,RegWriteAddr_wb,RegWriteData_wb,MemRead_ex,RegWriteAddr_ex,MemtoReg_id,RegWrite_id,MemWrite_id,MemRead_id,ALUCode_id,ALUSrcA_id,ALUSrcB_id,RegDst_id,Stall,Z,J,JR,PC_IFWrite,BranchAddr,JumpAddr,JrAddr,Imm_id,Sa_id,RsData_id,RtData_id,RsAddr_id,RtAddr_id,RdAddr_id);inputclk; input[31:0]Instruction_id;input[31:0]NextPC_id;inputRegWrite_wb;input[4:0]RegWriteAddr_wb;input[31:0]RegWriteData_wb;inputMemRead_ex;input[4:0]RegWriteAddr_ex;outputMemtoReg_id;outputRegWrite_id;outputMemWrite_id;outputMemRead_id;output[4:0]ALUCode_id;outputALUSrcA_id;outputALUSrcB_id;outputRegDst_id;outputStall;outputregZ;outputJ;outputJR;outputPC_IFWrite;output[31:0]BranchAddr;output[31:0]JumpAddr;output[31:0]JrAddr;output[31:0]Imm_id;output[31:0]Sa_id;output[31:0]RsData_id;output[31:0]RtData_id;output[4:0]RsAddr_id;output[4:0]RtAddr_id;output[4:0]RdAddr_id;//writetheaddressofeachregisterinsegments assignRtAddr_id=Instruction_id[20:16]; assignRdAddr_id=Instruction_id[15:11]; assignRsAddr_id=Instruction_id[25:21]; assignSa_id={27'b0,Instruction_id[10:6]}; assignImm_id={{16{Instruction_id[15]}},Instruction_id[15:0]}; //JumpAddressassignJumpAddr={NextPC_id[31:28],Instruction_id[25:0],2'b00};//BranchAddrresswire[31:0]imm_shift;assignimm_shift=Imm_id<<2;adder_32bitsadd_part(.a(NextPC_id),.b(imm_shift),.ci(1'b0),.s(BranchAddr),.co());//JrAddressassignJrAddr=RsData_id;//Hazarddetectiorparameter alu_beq=5'b01010;parameter alu_bne=5'b01011;parameter alu_bgez=5'b01100;parameter alu_bgtz=5'b01101;parameter alu_blez=5'b01110;parameter alu_bltz=5'b01111;assignStall=((RegWriteAddr_ex==RsAddr_id)||(RegWriteAddr_ex==RtAddr_id))&&MemRead_ex;assignPC_IFWrite=~Stall;//Zerotestalways@(*)begincase(ALUCode_id)alu_beq:Z=&(RsData_id[31:0]~^RtData_id[31:0]); alu_bne:Z=|(RsData_id[31:0]^RtData_id[31:0]); alu_bgez:Z=~RsData_id[31]; alu_bgtz:Z=~RsData_id[31]&&(|RsData_id[31:0]); alu_blez:Z=RsData_id[31]; alu_bltz:Z=RsData_id[31]||~(|RsData_id[31:0]); default:Z=0;endcaseend// DecodeinstDecodeDecode( //Outputs .MemtoReg(MemtoReg_id), .RegWrite(RegWrite_id), .MemWrite(MemWrite_id), .MemRead(MemRead_id), .ALUCode(ALUCode_id), .ALUSrcA(ALUSrcA_id), .ALUSrcB(ALUSrcB_id), .RegDst(RegDst_id), .J(J), .JR(JR), //Inputs .Instruction(Instruction_id)); //Registersinst//MultiRegistersinstwire[31:0]RsData_temp,RtData_temp; MultiRegistersMultiRegisters( //Outputs .RsData(RsData_temp), .RtData(RtData_temp), //Inputs .clk(clk), .WriteData(RegWriteData_wb), .WriteAddr(RegWriteAddr_wb), .RegWrite(RegWrite_wb), .RsAddr(RsAddr_id), .RtAddr(RtAddr_id)); //RsSel&RtSel assignRsSel=RegWrite_wb&&~(RegWriteAddr_wb==0)&&(RegWriteAddr_wb==RsAddr_id);assignRtSel=RegWrite_wb&&~(RegWriteAddr_wb==0)&&(RegWriteAddr_wb==RtAddr_id);//MUXforRsData_id&MUXforRtData_id assignRsData_id=RsSel?RegWriteData_wb:RsData_temp; assignRtData_id=RtSel?RegWriteData_wb:RtData_temp; endmodule擴(kuò)增符號(hào)位WB級(jí)寫(xiě)存放器目標(biāo)地址待寫(xiě)數(shù)據(jù)LW控制信號(hào)選擇數(shù)據(jù)來(lái)源存放器寫(xiě)操控制信號(hào)決定是否對(duì)存儲(chǔ)器進(jìn)行寫(xiě)操作決定是否對(duì)存儲(chǔ)器進(jìn)行讀操作ALU運(yùn)算控制信號(hào)第一源操作數(shù)選擇第二源操作數(shù)選擇選擇目標(biāo)存放器阻塞控制Zero-testJ指令標(biāo)志Jump指令標(biāo)志清零信號(hào)定義存放器地址〔對(duì)應(yīng)于R型指令〕設(shè)定第一源操作數(shù)〔用于移位操作的選擇〕設(shè)定第二源操作數(shù),用于立即數(shù)運(yùn)算定義JumpAddr通過(guò)符號(hào)擴(kuò)增,移位,加法器計(jì)算分支地址設(shè)定JrAddr發(fā)生數(shù)據(jù)冒險(xiǎn)的條件,發(fā)生冒險(xiǎn)時(shí)將Stall變?yōu)楦唠娖桨催壿嬯P(guān)系檢測(cè)各個(gè)分支條件是否成立,比方第一個(gè)判別檢測(cè)兩數(shù)據(jù)的32位是否對(duì)應(yīng)相等Decode單元譯碼〔Decode單元的細(xì)節(jié)將在之后介紹〕從存放器堆中取出數(shù)據(jù)三階數(shù)據(jù)相關(guān),成立時(shí)將選擇信號(hào)置為高電平,Rs與Rt分別判斷選擇取出數(shù)據(jù),假設(shè)相關(guān)條件成立,那么將數(shù)據(jù)旁路的數(shù)據(jù)轉(zhuǎn)發(fā)給RsData,RtData,反之那么取存放器堆中的數(shù)據(jù)3.DecodeUnit設(shè)計(jì)Decode單元的主要任務(wù)是,根據(jù)指令存儲(chǔ)器讀出的指令,確定各個(gè)控制信號(hào)的值。它是一個(gè)組合電路。本實(shí)驗(yàn)需要實(shí)現(xiàn)的指令分成八類(lèi)來(lái)討論:I.讀存儲(chǔ)器指令—LWII.寫(xiě)存儲(chǔ)器指令—SWIII.R型指令〔除移位指令及JR指令〕—R_type1Ⅳ.移位指令—R_type2Ⅴ.存放器跳轉(zhuǎn)指令—JR_typeⅥ.I型指令—I_typeⅦ.跳轉(zhuǎn)指令—J_typeⅧ.分支指令—Branch由指令中的op段、rt段及funct段決定控制ALU執(zhí)行運(yùn)算的ALUcode。映射關(guān)系如表1所示:opfunctionrt運(yùn)算ALUcodeBEQ_opxxxxxxxxxxZ=(A==B)5'd10BNE_opxxxxxxxxxxZ=~(A==B)5'd11BGEZ_opxxxxx5'd1Z=(A>=0)5'd12BGTZ_opxxxxx5'd0Z=(A>0)5'd13BLEZ_opxxxxx5'd0Z=(A<=1)5'd14BLTZ_opxxxxx5'd0Z=(A<0)5'd15R_type_opADD_functxxxxx加5'd0ADDU_functxxxxxAND_functxxxxx與5'd1XOR_functxxxxx異或5'd2OR_functxxxxx或5'd3NOR_functxxxxx或非5'd4SUB_functxxxxx減5'd5SUBU_functxxxxxSLT_OP_functxxxxxA<B?1:05'd19SLTU_OP_functxxxxxA<B?1:0〔無(wú)符號(hào)數(shù)〕5'd20SLL_functxxxxxB>>A5'd16SLLV_functxxxxxSRL_functxxxxxB<<A5'd17SRLV_functxxxxxSRA_functxxxxxB>>>A5'd18ARAV_functxxxxxADDI_opxxxxxxxxxx加5'd0ADDIU_opxxxxxxxxxxANDI_opxxxxxxxxxx與5'd1XORI_opxxxxxxxxxx異或5'd2ORI_opxxxxxxxxxx或5'd3SLTI_opxxxxxxxxxxA<B?1:05'd19SLTIU_opxxxxxxxxxxA<B?1:0〔無(wú)符號(hào)數(shù)〕5'd20SW_opxxxxxxxxxx加〔計(jì)算地址〕5'd0LW_opxxxxxxxxxx表1ALUCode功能表Decode代碼分析moduleDecode( //Outputs MemtoReg,RegWrite,MemWrite,MemRead,ALUCode,ALUSrcA,ALUSrcB, RegDst,J,JR, //InputsInstruction); input[31:0] Instruction; output MemtoReg; output RegWrite; output MemWrite; outputMemRead; output[4:0]ALUCode; output ALUSrcA,ALUSrcB; outputRegDst; outputJ,JR; //instructionfield wire[5:0] op; wire[4:0] rt; wire[5:0] funct; assignop =Instruction[31:26]; assignfunct =Instruction[5:0]; assignrt =Instruction[20:16]; //R_typeinstructiondecode parameterR_type_op=6'b000000;parameterADD_funct=6'b100000; parameterADDU_funct=6'b100001; parameterAND_funct=6'b100100; parameterXOR_funct=6'b100110; parameterOR_funct=6'b100101; parameterNOR_funct=6'b100111; parameterSUB_funct=6'b100010; parameterSUBU_funct=6'b100011; parameterSLT_funct=6'b101010; parameterSLTU_funct=6'b101011; parameterSLL_funct=6'b000000; parameterSLLV_funct=6'b000100; parameterSRL_funct=6'b000010; parameterSRLV_funct=6'b000110; parameterSRA_funct=6'b000011; parameterSRAV_funct=6'b000111; parameterJR_funct=6'b001000;//R_type1instructiondecode wireADD,ADDU,AND,NOR,OR,SLT,SLTU,SUB,SUBU,XOR,SLLV,SRAV,SRLV,R_type1; assignADD =(op==R_type_op)&&(funct==ADD_funct); assignADDU =(op==R_type_op)&&(funct==ADDU_funct); assignAND =(op==R_type_op)&&(funct==AND_funct); assignNOR =(op==R_type_op)&&(funct==NOR_funct); assignOR =(op==R_type_op)&&(funct==OR_funct); assignSLT =(op==R_type_op)&&(funct==SLT_funct); assignSLTU =(op==R_type_op)&&(funct==SLTU_funct); assignSUB =(op==R_type_op)&&(funct==SUB_funct); assignSUBU =(op==R_type_op)&&(funct==SUBU_funct); assignXOR =(op==R_type_op)&&(funct==XOR_funct); assignSLLV =(op==R_type_op)&&(funct==SLLV_funct); assignSRAV =(op==R_type_op)&&(funct==SRAV_funct); assignSRLV =(op==R_type_op)&&(funct==SRLV_funct); assignR_type1=ADD||ADDU||AND||NOR||OR||SLT||SLTU||SUB ||SUBU||XOR|| SLLV||SRAV||SRLV; //R_type2instructiondecode wireSLL,SRA,SRL,R_type2; assignSLL=(op==R_type_op)&&(funct==SLL_funct); assignSRA=(op==R_type_op)&&(funct==SRA_funct); assignSRL=(op==R_type_op)&&(funct==SRL_funct); assignR_type2=SLL||SRA||SRL; //JRinstructiondecode assignJR=(op==R_type_op)&&(funct==JR_funct);//branchinstructionsdecode parameterBEQ_op=6'b000100; parameterBNE_op=6'b000101; parameterBGEZ_op=6'b000001; parameterBGEZ_rt=5'b00001; parameterBGTZ_op=6'b000111; parameterBGTZ_rt=5'b00000; parameterBLEZ_op=6'b000110; parameterBLEZ_rt=5'b00000; parameterBLTZ_op=6'b000001; parameterBLTZ_rt=5'b00000; wireBEQ,BGEZ,BGTZ,BLEZ,BLTZ,BNE,Branch; assignBEQ=(op==BEQ_op); assignBNE=(op==BNE_op); assignBGEZ=(op==BGEZ_op)&&(rt==BGEZ_rt); assignBGTZ=(op==BGTZ_op)&&(rt==BGTZ_rt); assignBLEZ=(op==BLEZ_op)&&(rt==BLEZ_rt); assignBLTZ=(op==BLTZ_op)&&(rt==BLTZ_rt); assignBranch=BEQ||BNE||BGEZ||BGTZ||BLEZ||BLTZ;//Jumpinstructionsdecode parameter J_op=6'b000010; assignJ=(op==J_op); //I_typeinstructiondecode parameterADDI_op=6'b001000; parameterADDIU_op=6'b001001; parameterANDI_op=6'b001100; parameterXORI_op=6'b001110; parameterORI_op=6'b001101; parameterSLTI_op=6'b001010; parameterSLTIU_op=6'b001011; wireADDI,ADDIU,ANDI,XORI,ORI,SLTI,SLTIU,I_type; assignADDI=(op==ADDI_op); assignADDIU=(op==ADDIU_op); assignANDI=(op==ANDI_op); assignXORI=(op==XORI_op); assignSLTI=(op==SLTI_op); assignSLTIU=(op==SLTIU_op); assignORI=(op==ORI_op); assignI_type=ADDI||ADDIU||ANDI||XORI||ORI||SLTI||SLTIU;//SW,LWinstructiondecodeparameterSW_op=6'b101011; parameterLW_op=6'b100011; wireSW,LW; assignSW=(op==SW_op); assignLW=(op==LW_op); //ControlSingal assignMemtoReg=LW; assignMemRead=LW; assignMemWrite=SW; assignRegWrite=LW||R_type1||R_type2||I_type; assignRegDst=R_type1||R_type2; assignALUSrcA=R_type2; assignALUSrcB=I_type||LW||SW;//ALUCode parameter alu_add=5'b00000;parameter alu_and=5'b00001;parameter alu_xor=5'b00010;parameter alu_or=5'b00011;parameter alu_nor=5'b00100;parameter alu_sub=5'b00101;parameter alu_andi=5'b00110; parameter alu_xori=5'b00111; parameter alu_ori=5'b01000; parameteralu_jr=5'b01001; parameter alu_beq=5'b01010;parameter alu_bne=5'b01011; parameter alu_bgez=5'b01100;parameter alu_bgtz=5'b01101;parameter alu_blez=5'b01110;parameter alu_bltz=5'b01111; parameter alu_sll=5'b10000; parameter alu_srl=5'b10001; parameter alu_sra=5'b10010; parameter alu_slt=5'b10011;parameter alu_sltu=5'b10100;reg[4:0]R_ALUCode_Temp; reg[4:0]ALUCode; always@(*) if(op==R_type_op) case(funct) ADD_funct:R_ALUCode_Temp<=alu_add; ADDU_funct:R_ALUCode_Temp<=alu_add; AND_funct:R_ALUCode_Temp<=alu_and; XOR_funct:R_ALUCode_Temp<=alu_xor; OR_funct:R_ALUCode_Temp<=alu_or; NOR_funct:R_ALUCode_Temp<=alu_nor; SUB_funct:R_ALUCode_Temp<=alu_sub; SUBU_funct:R_ALUCode_Temp<=alu_sub; SLT_funct:R_ALUCode_Temp<=alu_slt; SLTU_funct:R_ALUCode_Temp<=alu_sltu; SLL_funct:R_ALUCode_Temp<=alu_sll; SLLV_funct:R_ALUCode_Temp<=alu_sll; SRL_funct:R_ALUCode_Temp<=alu_srl; SRLV_funct:R_ALUCode_Temp<=alu_srl; SRA_funct:R_ALUCode_Temp<=alu_sra; SRAV_funct:R_ALUCode_Temp<=alu_sra; default:R_ALUCode_Temp<=5'bx; endcase always@(*) case(op) BEQ_op:ALUCode<=alu_beq; BNE_op:ALUCode<=alu_bne; BGEZ_op:ALUCode<=alu_bgez; BGTZ_op:ALUCode<=alu_bgtz; BLEZ_op:ALUCode<=alu_blez; BLTZ_op:ALUCode<=alu_bltz; R_type_op:ALUCode<=R_ALUCode_Temp; //determinedbyfunct ADDI_op:ALUCode<=alu_add; ADDIU_op:ALUCode<=alu_add; ANDI_op:ALUCode<=alu_andi; XORI_op:ALUCode<=alu_xori; ORI_op:ALUCode<=alu_ori; SLTI_op:ALUCode<=alu_slt; SLTIU_op:ALUCode<=alu_sltu; SW_op:ALUCode<=alu_add; LW_op:ALUCode<=alu_add; default:ALUCode<=5'bx; endcase endmodule變量聲明待譯碼指令控制信號(hào)〔ID級(jí)設(shè)計(jì)中已做說(shuō)明〕6位op段6位function段,與op共同決定操作為便利賦值與表示,將常用參數(shù)列出列出需要可以完成的指令,根據(jù)op,func段賦值,這些操作均屬于R_type1或邏輯分類(lèi)同理,將SLL,SRA,SR歸類(lèi)到R_type2JR操作跳轉(zhuǎn)操作Jump操作I型指令操作或邏輯歸類(lèi)讀/寫(xiě)操作根據(jù)指令類(lèi)型為各個(gè)控制信號(hào)賦值設(shè)定ALU控制信號(hào)的參數(shù)一次信號(hào)賦值二次信號(hào)賦值R_type_op下分類(lèi)賦值根據(jù)op段賦值二次賦值4.ALUUnit設(shè)計(jì)ALU是提供CPU根本運(yùn)算能力的重要電路。ALU具體執(zhí)行何種運(yùn)算,由Decode單元中譯出的ALU控制器輸出的ALUCode信號(hào)決定。ALU的功能表見(jiàn)下頁(yè)圖11:圖11ALU功能表為了提高運(yùn)算速度,可將各種運(yùn)算并行執(zhí)行,得到的運(yùn)算結(jié)果由ALUCode信號(hào)進(jìn)行挑選。ALU代碼分析moduleALU( //Outputs Result,overflow, //Inputs ALUCode,A,B); input[4:0] ALUCode; input[31:0] A,B; outputreg[31:0] Result; outputregoverflow;//Shiftoperation:">>>"willperformanarithmeticshift,buttheoperand//mustberegsigned regsigned[31:0]B_reg; wireBinvert; wire[31:0]sum; wire[31:0]B_sign; wireCo; reg[31:0]r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14; always@(B)begin B_reg=B; endalways@(*)beginr1=A&B;r2=A^B;r3=A|B;r4=~(A|B);r5=sum;r6=A&{16'd0,B[15:0]};r7=A^{16'd0,B[15:0]};r8=A|{16'd0,B[15:0]};r9=B<<A;r10=B>>A;r11=B_reg>>>A;r12=(A[31]&&(~B[31]))||((A[31]~^B[31])&&sum[31]);r13=(~A[31]&&(B[31]))||((A[31]~^B[31])&&sum[31]);end //DecodedALUoperationselect(ALUsel)signalsparameter alu_add=5'b00000;parameter alu_and=5'b00001;parameter alu_xor=5'b00010;parameter alu_or=5'b00011;parameter alu_nor=5'b00100;parameter alu_sub=5'b00101;parameter alu_andi=5'b00110;parameter alu_xori=5'b00111;parameter alu_ori=5'b01000;parameteralu_jr=5'b01001; parameter alu_beq=5'b01010;parameter alu_bne=5'b01011; parameter alu_bgez=5'b01100;parameter alu_bgtz=5'b01101;parameter alu_blez=5'b01110;parameter alu_bltz=5'b01111; parameteralu_sll=5'b10000; parameter alu_srl=5'b10001; parameter alu_sra=5'b10010; parameter alu_slt=5'b10011;parameter alu_sltu=5'b10100;assignBinvert=~(ALUCode==alu_add);assignB_sign=B^{32{Binvert}};adder_32bitsadder_32bits_inst(.a(A),.b(B_sign),.ci(Binvert),.s(sum),.co(Co));/*always@(*)beginif((A[31]^B_sign[31]==0)&&(A[31]^sum[31]==1)&&((ALUCode==alu_add)||(ALUCode==alu_sub)))overflow=1;elseoverflow=0;end*/always@(*)beginif((Co^sum[31])&&((ALUCode==alu_add)||(ALUCode==alu_sub)))overflow=1;elseoverflow=0;end///ALUResultdatapath/always@(*)begincase(ALUCode)alu_add:Result=sum;alu_and:Result=r1; alu_xor:Result=r2; alu_or:Result=r3;alu_nor:Result=r4; alu_sub:Result=sum;alu_andi:Result=r6; alu_xori:Result=r7; alu_ori:Result=r8; alu_sll:Result=r9; alu_srl:Result=r10; alu_sra:Result=r11; alu_slt:Result=r12; alu_sltu:Result=r13;default:Result=32'b0;endcase endendmodule變量聲明源操作數(shù)">>>"操作必須首先將變量賦為reg型并行結(jié)果命名將B賦為reg型的B_reg并行計(jì)算結(jié)果A<B:A為負(fù)數(shù)、B為0或正數(shù):A[31]&&(~B[31])A、B符號(hào)相同,A-B為負(fù):(A[31]~^B[31])&&sum[31]Decode單元參數(shù)命名補(bǔ)碼標(biāo)志:假設(shè)為負(fù)數(shù)那么將B轉(zhuǎn)換為反碼A補(bǔ)-B補(bǔ)=A補(bǔ)+(-B補(bǔ))=A補(bǔ)+(B補(bǔ))補(bǔ)=A補(bǔ)B補(bǔ)+1Binvert=~(ALUCode==alu_add)加法器完成的功能為:sum=A+B^Binvert+Binvert判斷溢出與否,假設(shè)進(jìn)位與最高位不同那么出現(xiàn)溢出根據(jù)控制信號(hào)選擇ALU的輸出結(jié)果出現(xiàn)錯(cuò)誤那么結(jié)果賦05.EX級(jí)設(shè)計(jì)EX級(jí)實(shí)現(xiàn)檢測(cè)并實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)發(fā),操作數(shù)A和B由數(shù)據(jù)選擇器決定,數(shù)據(jù)選擇器的地址信號(hào)即為ForwardA和ForwardB。數(shù)據(jù)選擇器地址信號(hào)ForwardA、ForwardB的含義如下表:表2:ForwardA、ForwardB的含義EX級(jí)代碼分析moduleEX(RegDst_ex,ALUCode_ex,ALUSrcA_ex,ALUSrcB_ex,Imm_ex,Sa_ex,RsAddr_ex,RtAddr_ex,RdAddr_ex,RsData_ex,RtData_ex,RegWriteData_wb,ALUResult_mem,RegWriteAddr_wb,RegWriteAddr_mem,RegWrite_wb,RegWrite_mem,RegWriteAddr_ex,ALUResult_ex,MemWriteData_ex,ALU_A,ALU_B);inputRegDst_ex;input[4:0]ALUCode_ex;inputALUSrcA_ex;inputALUSrcB_ex;input[31:0]Imm_ex;input[31:0]Sa_ex;input[4:0]RsAddr_ex;input[4:0]RtAddr_ex;input[4:0]RdAddr_ex;input[31:0]RsData_ex;input[31:0]RtData_ex;input[31:0]RegWriteData_wb;input[31:0]ALUResult_mem;input[4:0]RegWriteAddr_wb;input[4:0]RegWriteAddr_mem;inputRegWrite_wb;inputRegWrite_mem;outputreg[4:0]RegWriteAddr_ex;output[31:0]ALUResult_ex;output[31:0]MemWriteData_ex;output[31:0]ALU_A,ALU_B;reg[31:0]MuxA;reg[31:0]MuxB;reg[31:0]ALU_A;reg[31:0]ALU_B;//forwarding wire[1:0]ForwardA,ForwardB; assignForwardA[0]=RegWrite_wb&&(RegWriteAddr_wb!=0)&&(RegWriteAddr_mem!=RsAddr_ex)&&(RegWriteAddr_wb==RsAddr_ex); assignForwardA[1]=RegWrite_mem&&(RegWriteAddr_mem!=0)&&(RegWriteAddr_mem==RsAddr_ex); assignForwardB[0]=RegWrite_wb&&(RegWriteAddr_wb!=0)&&(RegWriteAddr_mem!=RtAddr_ex)&&(RegWriteAddr_wb==RtAddr_ex);assignForwardB[1]=RegWrite_mem&&(RegWriteAddr_mem!=0)&&(RegWriteAddr_mem==RtAddr_ex);//MUXforAalways@(*)begincase(ForwardA)2'b00:MuxA<=RsData_ex;2'b01:MuxA<=RegWriteData_wb;2'b10:MuxA<=ALUResult_mem;default:MuxA<=32'bx;endcaseend//MUXforBalways@(*)begincase(ForwardB)2'b00:MuxB<=RtData_ex;2'b01:MuxB<=RegWriteData_wb;2'b10:MuxB<=ALUResult_mem;default:MuxB<=32'bx;endcaseend//MUXforALU_Aalways@(*)begincase(ALUSrcA_ex)1'b0:ALU_A<=MuxA;1'b1:ALU_A<=Sa_ex;default:ALU_A<=32'bx;endcaseend//MUXforALU_Balways@(*)begincase(ALUSrcB_ex)1'b0:ALU_B<=MuxB;1'b1:ALU_B<=Imm_ex;default:ALU_B<=32'bx;endcaseendassignMemWriteData_ex=MuxB;//ALUinst ALUALU( //Outputs .Result(ALUResult_ex), .overflow(), //Inputs .ALUCode(ALUCode_ex), .A(ALU_A), .B(ALU_B));//MUXforRegWriteAddr_ex//assignALUResult=ALUCode_ex;always@(*)RegWriteAddr_ex<=RegDst_ex?RdAddr_ex:RtAddr_ex;endmodule變量聲明局部源操作數(shù)中可選的立即數(shù)Rs,Rt存放器中讀出的數(shù)據(jù)WB級(jí)寫(xiě)回地址〔二階〕MEM級(jí)寫(xiě)回地址〔一階〕寫(xiě)到儲(chǔ)存器中的數(shù)據(jù)與轉(zhuǎn)發(fā)相關(guān)的源操作數(shù)選擇最終的源操作數(shù)根據(jù)轉(zhuǎn)發(fā)要求寫(xiě)出轉(zhuǎn)發(fā)成立條件判斷源操作數(shù)A是否存在一階或二階轉(zhuǎn)發(fā)并實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)發(fā)判斷源操作數(shù)B是否存在一階或二階轉(zhuǎn)發(fā)并實(shí)現(xiàn)數(shù)據(jù)轉(zhuǎn)發(fā)二次判斷是否采用立即數(shù)用ALU單元計(jì)算出結(jié)果根據(jù)控制信號(hào)決定寫(xiě)回存放器的地址6.頂層模塊設(shè)計(jì)頂層模塊將各級(jí),各單元連接在一起。除上邊介紹的設(shè)計(jì)模塊外,頂層中添加了已有模塊InstructionROM和DataRAM以完成ID級(jí)和MEM級(jí)的設(shè)計(jì),實(shí)現(xiàn)指令的讀取和訪(fǎng)問(wèn)存儲(chǔ)器。在各級(jí)分界參加流水線(xiàn)存放器,流水線(xiàn)存放器負(fù)責(zé)將流水線(xiàn)的各局部分開(kāi),共有IF/ID、ID/EX、EX/MEM、MEM/WB四組。根據(jù)前面的介紹可知,四組流水線(xiàn)存放器要求不完全相同,因此設(shè)計(jì)也有不同考慮。EX/MEM、MEM/WB兩組流水線(xiàn)存放器只是普通D型存放器。當(dāng)流水線(xiàn)發(fā)生數(shù)據(jù)冒險(xiǎn)時(shí),需清空ID/EX流水線(xiàn)存放器而插入一個(gè)氣泡,因此ID/EX流水線(xiàn)存放器是一個(gè)帶同步清零功能的D型存放器,清零信號(hào)為stall。當(dāng)流水線(xiàn)發(fā)生數(shù)據(jù)冒險(xiǎn)時(shí),需保持IF/ID流水線(xiàn)存放器不變,因此IF/ID流水線(xiàn)存放器具有使能信號(hào)輸入,使能信號(hào)為PC_IFWrite;當(dāng)流水線(xiàn)發(fā)生分支冒險(xiǎn)時(shí),需清空IF/ID流水線(xiàn)存放器,清零信號(hào)為IF_flush。因此,IF/ID流水線(xiàn)存放器是一個(gè)帶使能功能、同步清零功能的D型存放器。頂層代碼分析moduleMipsPipelineCPU(clk,reset,JumpFlag,Instruction_id,ALU_A,ALU_B,ALUResult,PC,MemDout_wb,Stall ,DataTest,ControlTest);inputclk;inputreset;output[2:0]JumpFlag;output[31:0]Instruction_id;output[31:0]ALU_A;output[31:0]ALU_B;output[31:0]ALUResult;output[31:0]PC;output[31:0]MemDout_wb;outputStall; //IFmodulewire[31:0]Instruction_id,NextPC_id; wirePC_IFWrite,J,JR,Z,IF_flush; wire[31:0]JumpAddr,JrAddr,BranchAddr,NextPC_if,Instruction_if; assignJumpFlag={JR,J,Z}; assignIF_flush=Z||J||JR; IFIF(//input .clk(clk), .reset(reset), .Z(Z), .J(J), .JR(JR), .PC_IFWrite(PC_IFWrite), .JumpAddr(JumpAddr), .JrAddr(JrAddr), .BranchAddr(BranchAddr),//output .Instruction_if(Instruction_if), .PC(PC), .NextPC_if(NextPC_if));//IF->IDRegisterdffre#(32)dffre1(.d(NextPC_if),.en(PC_IFWrite),.r(IF_flush||reset),.clk(clk),.q(NextPC_id));dffre#(32)dffre2(.d(Instruction_if),.en(PC_IFWrite),.r(IF_flush||reset),.clk(clk),.q(Instruction_id));//IDModule wire[4:0]RtAddr_id,RdAddr_id,RsAddr_id;wireRegWrite_wb,RegWrite_mem,MemRead_ex,MemtoReg_id,RegWrite_id,MemWrite_id;wireMemRead_id,ALUSrcA_id,ALUSrcB_id,RegDst_id,Stall;wire[4:0]RegWriteAddr_wb,RegWriteAddr_ex,ALUCode_id,ALUCode_ex;wire[31:0]RegWriteData_wb,Imm_id,Sa_id,RsData_id,RtData_id,RsData_ex,RtData_ex,Sa_ex,Imm_ex;wire[4:0]RtAddr_ex,RsAddr_ex,RdAddr_ex;IDID( .clk(clk), .Instruction_id(Instruction_id), .NextPC_id(NextPC_id), .RegWrite_wb(RegWrite_wb), .RegWriteAddr_wb(RegWriteAddr_wb), .RegWriteData_wb(RegWriteData_wb), .MemRead_ex(MemRead_ex),.RegWriteAddr_ex(RegWriteAddr_ex), .MemtoReg_id(MemtoReg_id), .RegWrite_id(RegWrite_id), .MemWrite_id(MemWrite_id), .MemRead_id(MemRead_id), .ALUCode_id(ALUCode_id), .ALUSrcA_id(ALUSrcA_id), .ALUSrcB_id(ALUSrcB_id), .RegDst_id(RegDst_id), .Stall(Stall), .Z(Z), .J(J), .JR(JR), .PC_IFWrite(PC_IFWrite), .BranchAddr(BranchAddr), .Jump

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論