国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

基于Verilog的mips指令集單周期/五級(jí)流水cpu,modelsim/vivado仿真設(shè)計(jì) 設(shè)計(jì)

這篇具有很好參考價(jià)值的文章主要介紹了基于Verilog的mips指令集單周期/五級(jí)流水cpu,modelsim/vivado仿真設(shè)計(jì) 設(shè)計(jì)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-533274.html

一、設(shè)計(jì)目的

1、了解提高CPU性能的方法。

2、掌握流水線微處理器的工作原理。

3、理解數(shù)據(jù)冒險(xiǎn)、控制冒險(xiǎn)的概念以及流水線沖突的解決方法。

4、掌握流水線微處理器的測(cè)試方法。

二、設(shè)計(jì)要求

設(shè)計(jì)一種五級(jí)流水線的基于MIPS指令集的處理器,其可支持部分指令,能夠處理指令相關(guān)和數(shù)據(jù)相關(guān),使流水線能夠正常運(yùn)行。源碼q3026159745

三、設(shè)計(jì)內(nèi)容

1、各模塊設(shè)計(jì)

1.1、存儲(chǔ)器設(shè)計(jì)

Instruction指令存儲(chǔ)器,ROM

存儲(chǔ)微處理器的指令,讀出對(duì)應(yīng)地址的指令

Regfile寄存器堆

存儲(chǔ)各個(gè)寄存器的值,0號(hào)地址存R0的值,1號(hào)地址存儲(chǔ)R1的值,以此類(lèi)推

Data數(shù)據(jù)存儲(chǔ)器,RAM

存儲(chǔ)用戶的數(shù)據(jù),本實(shí)驗(yàn)存儲(chǔ)器中存儲(chǔ)的數(shù)據(jù)是對(duì)應(yīng)地址的值

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.1存儲(chǔ)器設(shè)計(jì)

?

1.2、ALU設(shè)計(jì)

ALU有A、B兩個(gè)輸入,F(xiàn)運(yùn)算類(lèi)型,Y為輸出

F與CU的ALUControl相連,控制ALU的運(yùn)算

具體功能如下

module alu(A,B,F,Y);

input [31:0]A;

input [31:0]B;

input [2:0]F;

output reg[31:0]Y;

always@(*)

begin

case(F)

3'b000:Y=A&B;

3'b001:Y=A|B;

3'b010:Y=A+B;

3'b011:Y=A/B;

3'b100:Y=A&~B;

3'b101:Y=A|~B;

3'b110:Y=A-B;

3'b111:Y=(A<B);

default:Y=32'bx;

endcase

end

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.2ALU設(shè)計(jì)

1.3、ALUForward的設(shè)計(jì)

ALUForward由兩個(gè)三路選擇器和一個(gè)二路選擇器組成,三路選擇器輸出SrcAE由ForwardAE控制

具體功能如下

moduleALU_Forward(ForwardAE,ForwardBE,RD1E,

RD2E,SignlmmE,ALUSrcE,ALUOutM,ResultW,

WriteDataE,SrcAE,SrcBE);

input[1:0]ForwardAE,ForwardBE;

inputALUSrcE;

input[31:0]ALUOutM,ResultW,RD1E,RD2E,SignlmmE;

outputreg[31:0]SrcAE,SrcBE,WriteDataE;

always@(*) begin

case(ForwardAE)

2'b00:SrcAE<=RD1E;

2'b01:SrcAE<=ResultW;

2'b10:SrcAE<=ALUOutM;

endcase

case(ForwardBE)

2'b00:WriteDataE<=RD2E;

2'b01:WriteDataE<=ResultW;

2'b10:WriteDataE<=ALUOutM;

endcase

if(ALUSrcE)

SrcBE<=SignlmmE;

else

SrcBE<=WriteDataE;

?

end

endmodule

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.3ALUForward的設(shè)計(jì)

?

1.4、Control_Unit設(shè)計(jì)

采用op 和 funct進(jìn)行譯碼,產(chǎn)生各個(gè)模塊的控制信號(hào)。

根據(jù)操作碼譯出相應(yīng)控制信號(hào)

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.4

moduleControl_Unit(

op,

funct,

RegWriteD,

RegDstD,

AluSrcD,

BranchD,

MemWriteD,

MemtoRegD,

ALUControlD

);

input[5:0]op;

input[5:0]funct;

outputreg RegWriteD;

outputreg RegDstD;

outputreg AluSrcD;

outputreg BranchD;

outputreg MemWriteD;

outputreg MemtoRegD;

outputreg[2:0]ALUControlD;

always@(*)

begin

case (op)

6'b000000:

begin

case (funct)

6'b100000:beginRegWriteD<=1;RegDstD<=1;AluSrcD<=0;BranchD<=0;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b010;end//add

6'b100001:beginRegWriteD<=1;RegDstD<=1;AluSrcD<=0;BranchD<=0;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b110;end//sub

6'b100100:beginRegWriteD<=1;RegDstD<=1;AluSrcD<=0;BranchD<=0;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b000;end//and

6'b100101:beginRegWriteD<=1;RegDstD<=1;AluSrcD<=0;BranchD<=0;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b001;end//or

6'b101010:beginRegWriteD<=1;RegDstD<=1;AluSrcD<=0;BranchD<=0;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b111;end//slt

?

6'b111111:beginRegWriteD<=1;RegDstD<=1;AluSrcD<=0;BranchD<=0;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b011;end//div

default: beginRegWriteD <= 0;RegDstD <= 0;AluSrcD <= 0;BranchD <= 0;MemWriteD<= 0;MemtoRegD <= 0;ALUControlD <= 3'b000;end //NOP

endcase

end

6'b100011:beginRegWriteD<=0;RegDstD<=0;AluSrcD<=1;BranchD<=0;MemWriteD<=1;MemtoRegD<=0;ALUControlD<=3'b010;end //sw

6'b101011:beginRegWriteD<=1;RegDstD<=0;AluSrcD<=1;BranchD<=0;MemWriteD<=0;MemtoRegD<=1;ALUControlD<=3'b010;end //lw

?

6'b001000:beginRegWriteD<=1;RegDstD<=0;AluSrcD<=1;BranchD<=0;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b010;end //addi

6'b001000:beginRegWriteD<=1;RegDstD<=0;AluSrcD<=1;BranchD<=0;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b110;end //subi

6'b000100:beginRegWriteD<=0;RegDstD<=0;AluSrcD<=0;BranchD<=1;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b110;end //beq

6'b000101:beginRegWriteD<=0;RegDstD<=0;AluSrcD<=0;BranchD<=1;MemWriteD<=0;MemtoRegD<=0;ALUControlD<=3'b110;end //bne

default: begin RegWriteD <=0;RegDstD <= 0;AluSrcD <= 0;BranchD <= 0;MemWriteD <= 0;MemtoRegD<= 0;ALUControlD <= 3'b000;end //NOP

endcase

end

endmodule

?

1.5、五級(jí)流水線clk設(shè)計(jì)

1.5.1clkPC

(1)取指令階段,如果復(fù)位rst不為低電平,則每次時(shí)鐘上升沿PCF刷新,若為低電平則PCF賦值為零

(2)StallF停頓,StallF為低電平,則PCF保持不變

(3)PCF的值即為本次取指令的地址,取出Instruction中的指令

(4)PCF來(lái)源有兩個(gè),一個(gè)是PC的累加,一個(gè)是相對(duì)轉(zhuǎn)移地址

moduleclkPC(clk,rst,StallF,PC,PCF);

inputclk,rst,StallF;

input[31:0] PC;

output reg[31:0] PCF;

always @(posedge clk)

begin

if(!rst)

PCF <= 32'b0;

else if(StallF==1'b0)

PCF <= PC;

else

PCF <= PCF;

end

?

endmodule

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.5.1clkPC clkFetch_Decode

1.5.2clkFetch_Decode

時(shí)鐘上升沿判斷

(1)是否有停頓,若有停頓則clk模塊輸出的信號(hào)保持不變;

(2)clr是否為高電平,若是,則將模塊輸出信號(hào)清零

(3)若停頓和清零信后均為低,則模塊輸入值對(duì)應(yīng)賦給輸出值

moduleclkFetch_Decode(clk,clr,StallD,RD,PCPlus4F,InstrD,PCPlus4D);

inputclk,clr,StallD;

input[31:0] RD,PCPlus4F;

outputreg[31:0] InstrD,PCPlus4D;

always @(posedge clk)

begin

if(StallD)begin

InstrD<=InstrD;

PCPlus4D<=PCPlus4D;

end

else if(clr)begin

InstrD <= 32'b0;

PCPlus4D<=32'b0;

end

else begin

InstrD<=RD;

PCPlus4D <= PCPlus4F;

end

end

endmodule

1.5.3 clkDecode_Excute

每當(dāng)時(shí)鐘信號(hào)上升沿判斷FLUSH信號(hào)是否為高電平,若是,則清零模塊的輸出信號(hào),若否則輸入信號(hào)賦給相應(yīng)的輸出信號(hào)。

Branch信號(hào)單周期在ALU判斷Rt和Rs是否相等并轉(zhuǎn)移,而流水線CPU中可以提前判斷是否轉(zhuǎn)移

moduleclkDecode_Excute(clk,clr,RegWriteD,RegDstD,ALUSrcD,

BranchD,MemWriteD,MemtoRegD,

ALUControlD,RD1,RD2,RsD,RtD,RdD,SignlmmD,RegWriteE,RegDstE,ALUSrcE,

MemWriteE,MemtoRegE,ALUControlE,RD1E,RD2E,RtE,RdE,RsE,SignlmmE);

?

inputclk,clr,RegWriteD,RegDstD,ALUSrcD,MemWriteD,MemtoRegD,BranchD;

input[2:0] ALUControlD;

input[4:0] RtD,RdD,RsD;

input[31:0] RD1,RD2,SignlmmD;

?

outputreg RegWriteE,RegDstE,ALUSrcE,MemWriteE,MemtoRegE;

outputreg[2:0] ALUControlE;

outputreg[4:0] RtE,RdE,RsE;

outputreg[31:0] RD1E,RD2E,SignlmmE;

?

always @(posedge clk)

begin

?

if(!clr)

begin

RegWriteE<=RegWriteD;

RegDstE<=RegDstD;

ALUSrcE<=ALUSrcD;

MemWriteE<=MemWriteD;

MemtoRegE<=MemtoRegD;

ALUControlE<=ALUControlD;

?

RD1E<=RD1;

RD2E<=RD2;

RsE<=RsD;

RtE<=RtD;

RdE<=RdD;

SignlmmE<=SignlmmD;

end

?

else

begin//清空流水線

RegWriteE<=0;

RegDstE<=0;

ALUSrcE<=0;

MemWriteE<=0;

MemtoRegE<=0;

ALUControlE<=3'b0;

RD1E<=32'b0;

RD2E<=32'b0;

RsE<=5'b0;

RtE<=5'b0;

RdE<=5'b0;

SignlmmE<=32'b0;

end

end

?

endmodule

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.5.3clkDecode_Excute

?

1.5.4 clkExcude_Memory

moduleclkExcude_Memory(clk,RegWriteE,MemtoRegE,MemWriteE,

ALUResult,WriteDataE,WriteRegE,

RegWriteM,MemtoRegM,MemWriteM,ALUOutM,WriteDataM,WriteRegM);

?

input clk,RegWriteE,MemtoRegE,MemWriteE;

input [4:0] WriteRegE;

input [31:0] ALUResult,WriteDataE;

?

output reg RegWriteM,MemtoRegM,MemWriteM;

output reg[4:0] WriteRegM;

output reg[31:0] ALUOutM,WriteDataM;

always @ (posedge clk)

begin

RegWriteM<=RegWriteE;

MemWriteM<=MemWriteE;

MemtoRegM<=MemtoRegE;

ALUOutM<=ALUResult;

WriteDataM<=WriteDataE;

WriteRegM<=WriteRegE;

end

endmodule

1.5.5 clkMemory_Writeback

moduleclkMemory_Writeback(clk,RegWriteM,MemtoRegM,ALUOutM,RD,WriteRegM,

RegWriteW,MemtoRegW,ALUOutW,ReadDaraW,WriteRegW);

?

input clk,RegWriteM,MemtoRegM;

input [4:0] WriteRegM;

input [31:0] RD,ALUOutM;

output reg RegWriteW,MemtoRegW;

output reg[4:0] WriteRegW;

output reg[31:0] ALUOutW,ReadDaraW;

always @ (posedge clk)

begin

RegWriteW<=RegWriteM;

MemtoRegW<=MemtoRegM;

ALUOutW<=ALUOutM;

ReadDaraW<=RD;

WriteRegW<=WriteRegM;

end

?

endmodule

1.6 HazardUnit

我們知道影響流水線性能的有三個(gè)冒險(xiǎn):數(shù)據(jù)冒險(xiǎn),結(jié)構(gòu)冒險(xiǎn),控制冒險(xiǎn)。

(1)由于數(shù)據(jù)存儲(chǔ)器和指令存儲(chǔ)器分離,所以流水線讀指令和寫(xiě)數(shù)據(jù)可以并行執(zhí)行,不存在存儲(chǔ)器爭(zhēng)用問(wèn)題,寄存器堆采用讀寫(xiě)雙端口,因此也不會(huì)出現(xiàn)資源爭(zhēng)用問(wèn)題。

(2)數(shù)據(jù)冒險(xiǎn)

寄存器的值還沒(méi)有被寫(xiě)回寄存器,若此時(shí)讀取寄存器數(shù)據(jù)并用此數(shù)據(jù)參與運(yùn)算就會(huì)造成錯(cuò)誤。

a.不訪存的數(shù)據(jù)冒險(xiǎn)

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.6.1不訪存的數(shù)據(jù)冒險(xiǎn)

add $s0,$s2,$s3

add $t0,$s0,$s1

第二條add要用s0的數(shù)據(jù)進(jìn)行計(jì)算時(shí),也就是execute階段,可以將第一條正處于memory階段的AluOutM結(jié)果給第二條指令的ALU輸入。

這就是所謂的旁路技術(shù)

if ((rsE != 0) AND (rsE == WriteRegM) AND RegWriteM)

then ForwardAE = 10

elseif ((rsE != 0) AND (rsE == WriteRegW) AND RegWriteW)//訪問(wèn)存儲(chǔ)器

then ForwardAE = 01

else ForwardAE= 00

?

b.訪存造成的數(shù)據(jù)冒險(xiǎn)

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.6.2訪存造成的數(shù)據(jù)冒險(xiǎn)

lw $s0,40($0)

add$s0,$s0,$s1

add的execute階段,需要用到上一條指令寫(xiě)回的$s0的數(shù)值,而上一條指令要從存儲(chǔ)器取數(shù)據(jù),在Writeback階段才能得到$s0的數(shù)值,所以需要停頓一個(gè)時(shí)鐘周期,等到lw指令進(jìn)入Writeback階段再通過(guò)旁路技術(shù)將ResultW引入到add的執(zhí)行階段。

本條指令停頓了,后面的指令也要跟著停頓一個(gè)時(shí)鐘周期。

lwstall=

((rsD==rtE) OR (rtD==rtE))AND MemtoRegE

?

StallF = StallD = FlushE = lwstall

?

(3)控制冒險(xiǎn)

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.6.3控制冒險(xiǎn)1

在Memory階段進(jìn)行轉(zhuǎn)移判斷會(huì)造成后面三條不該執(zhí)行的指令執(zhí)行,流水線數(shù)值改變,所以應(yīng)該清空流水線。

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.6.4控制冒險(xiǎn)2

?

如果在指令譯碼后直接判斷Rs和Rt是否相等,則只有一條不該執(zhí)行的指令執(zhí)行了。

如果判斷的Rs或者Rt還沒(méi)有被寫(xiě)入到寄存器堆,則產(chǎn)生新的數(shù)據(jù)冒險(xiǎn),由于Decode階段要用到Rs和Rt,而寄存器的值需要在Memory階段或者Writeback階段產(chǎn)生,所以不僅要有前向通路,還要有停頓才可以處理此數(shù)據(jù)相關(guān)。

?

Forwardinglogic:

ForwardAD = (rsD!=0) AND (rsD == WriteRegM) AND RegWriteM

ForwardBD = (rtD !=0) AND (rtD == WriteRegM) AND RegWriteM

Stallinglogic:

branchstall = BranchD AND RegWriteEAND

(WriteRegE == rsDOR WriteRegE == rtD)

OR

BranchD AND MemtoRegM AND

(WriteRegM == rsDOR WriteRegM == rtD)

StallF = StallD= FlushE = lwstall OR branchstall

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.6.5冒險(xiǎn)控制單元

?

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

圖1.6.6提前獲得轉(zhuǎn)移判斷

?

moduleHazardUnit(StallF,StallD,

BranchD,ForwardAD,ForwardBD,ForwardAE,ForwardBE,

RsD,RtD,RsE,RtE,FlushE,RegWriteE,MemtoRegE,

WriteRegE,WriteRegM,RegWriteM,RegWriteW,WriteRegW,

MemtoRegM);

?

inputRegWriteE,RegWriteM,RegWriteW,MemtoRegE,MemtoRegM,BranchD;

input[4:0] RsD,RtD,RsE,RtE,WriteRegE,WriteRegM,WriteRegW;

outputreg [1:0] ForwardAE,ForwardBE;

outputreg ForwardAD,ForwardBD,StallF,StallD,FlushE;

?

reglwstall,branchstall;

?

always @( * )

begin

if( (RsE != 0)&& (RsE ==WriteRegM) && RegWriteM) //上一條指令的寫(xiě)回寄存器(WriteRegM)與本條指令的寄存器一致,

//采用旁路技術(shù),將上一條指令的結(jié)果直接送到執(zhí)行處。

ForwardAE= 2'b10;

else if ((RsE != 0)&& (RsE ==WriteRegW) && RegWriteW) //上上條指令的寫(xiě)回寄存器(WriteRegW)與本條指令的寄存器RS一致

//旁路技術(shù),ResultW送入執(zhí)行處

ForwardAE = 2'b01;

else ForwardAE= 2'b00;

?

if((RtE != 0)&&(RtE == WriteRegM)&& RegWriteM)

ForwardBE <= 2'b10; //上一條指令的寫(xiě)回地址(WriteRegM)與本條指令的操作數(shù)地址(寄存器RT)一致,

//采用旁路技術(shù),將上一條指令的結(jié)果直接送到執(zhí)行處。

else if ( (RtE != 0)&&(RtE ==WriteRegW) && (RegWriteW))

ForwardBE <= 2'b01;

else ForwardBE <= 2'b00;

?

//bne指令,在譯碼階段開(kāi)始判斷RS和RT的值,提前判斷,防止之后的指令執(zhí)行

//當(dāng)上上條指令要寫(xiě)回寄存器參與本次bne比較,通過(guò)旁路技解決,RD1/RD2<=ALUOut

ForwardAD <= (RsD != 0)&&(RsD==WriteRegM)&& RegWriteM;

ForwardBD <= (RtD != 0)&&(RtD==WriteRegM)&& RegWriteM;

?

branchstall <= (BranchD &&RegWriteE && (WriteRegE == RsD || WriteRegE == RtD) )//上一條指令要寫(xiě)這次比較的操作數(shù)

|| (BranchD && MemtoRegM&& (WriteRegM == RsD || WriteRegM == RtD));//上兩條指令要寫(xiě)這次比較的操作數(shù)

?

//stall

lwstall <= ((RsD==RtE) || (RtD==RtE))&& MemtoRegE;

StallF <= lwstall || branchstall;

StallD <= StallF;

FlushE <= StallD;//清空流水線防止再次判斷并轉(zhuǎn)移

?

?

end

endmodule

?

?

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

表1.6.1、停頓以及前向通路的舉例分析

2.Top模塊設(shè)計(jì)

頂層模塊全部采用例化連接

頂層模塊所有信號(hào)和連接代碼如下

inputclk,rst;

wireRegWriteD,RegDstD,ALUSrcD,BranchD,MemWriteD,MemtoRegD,PCSrcD;//decode_cu EqualD

wireRegWriteE,RegDstE,ALUSrcE,MemWriteE,MemtoRegE;//excute_cu

wireRegWriteM,MemtoRegM,MemWriteM;//memory_cu

wireMemtoRegW,RegWriteW;//writeback_cu

wire[2:0] ALUControlD,ALUControlE;//cu

wireForwardAD,ForwardBD,StallF,StallD,FlushE;//冒險(xiǎn)

wire[1:0] ForwardAE,ForwardBE;

wire[4:0] WriteRegW,WriteRegE,WriteRegM,RtE,RdE,RsE;

wire[31:0] PC,PCF,A,PCPlus4F,PCPlus4D,PCBranchD,RD,InstrD,WD3,RD1,RD2,SignlmmD,

RD1E,RD2E,SignlmmE,SrcAE,SrcBE,ALUResult,

ReadDataW,ALUOutW,WriteDataE,ALUOutM,WriteDataM,ReadData,ResultW;

module Top(clk,rst);

?

input clk,rst;

wireRegWriteD,RegDstD,ALUSrcD,BranchD,MemWriteD,MemtoRegD,PCSrcD;//decode_cu EqualD

wire RegWriteE,RegDstE,ALUSrcE,MemWriteE,MemtoRegE;//excute_cu

wire RegWriteM,MemtoRegM,MemWriteM;//memory_cu

wire MemtoRegW,RegWriteW;//writeback_cu

wire [2:0] ALUControlD,ALUControlE;//cu

?

wire ForwardAD,ForwardBD,StallF,StallD,FlushE;//冒險(xiǎn)

wire [1:0] ForwardAE,ForwardBE;

wire [4:0] WriteRegW,WriteRegE,WriteRegM,RtE,RdE,RsE;

wire [31:0]PC,PCF,A,PCPlus4F,PCPlus4D,PCBranchD,RD,InstrD,WD3,RD1,RD2,SignlmmD,

RD1E,RD2E,SignlmmE,SrcAE,SrcBE,ALUResult,

ReadDataW,ALUOutW,WriteDataE,ALUOutM,WriteDataM,ReadData,ResultW;

?

//clk 五級(jí)流水

clkPC clkPC(.clk(clk),.rst(rst),.StallF(StallF),.PC(PC),.PCF(PCF));

clkFetch_Decodeclk Fetch_Decode(.clk(clk),.clr(PCSrcD),.StallD(StallD),

.RD(RD),.PCPlus4F(PCPlus4F),.InstrD(InstrD),.PCPlus4D(PCPlus4D));

?

clkDecode_Excuteclk Decode_Excute(.clk(clk),.clr(FlushE),.RegWriteD(RegWriteD),

.RegDstD(RegDstD),.ALUSrcD(ALUSrcD),

.BranchD(BranchD),.MemWriteD(MemWriteD),.MemtoRegD(MemtoRegD),.ALUControlD(ALUControlD),

.RD1(RD1),.RD2(RD2),.RsD(InstrD[25:21]),.RtD(InstrD[20:16]),.RdD(InstrD[15:11]),.SignlmmD(SignlmmD),.RegWriteE(RegWriteE),

.RegDstE(RegDstE),.ALUSrcE(ALUSrcE),.MemWriteE(MemWriteE),.MemtoRegE(MemtoRegE),

.ALUControlE(ALUControlE),.RD1E(RD1E),.RD2E(RD2E),.RtE(RtE),.RdE(RdE),.RsE(RsE),.SignlmmE(SignlmmE));

?

clkExcude_Memory clkExcude_Memory(clk,RegWriteE,MemtoRegE,MemWriteE,

ALUResult,WriteDataE,WriteRegE

RegWriteM,MemtoRegM,MemWriteM,ALUOutM,WriteDataM,WriteRegM);

?

clkMemory_Writeback clkMtoW(clk,RegWriteM,MemtoRegM,ALUOutM,ReadData,

WriteRegM,RegWriteW,MemtoRegW,ALUOutW,ReadDataW,WriteRegW);

//各個(gè)小模塊

PCPlus PCPlus(PCF,PCPlus4F);

instruction instruction(PCF>>2,RD);

regfile regfile(.clk(clk),.a1(InstrD[25:21]),.a2(InstrD[20:16]),.a3(WriteRegW),.we3(RegWriteW),.wd3(ResultW),.rd1(RD1),.rd2(RD2));

PC1 PC1(PCBranchD,PCPlus4F,PCSrcD,PC);

PCBranch PCBranch(PCPlus4D,SignlmmD,PCBranchD);

WriteReg_2to1 WriteReg_2to1(RegDstE,RdE,RtE,WriteRegE);//WriteRegE的選擇

//控制單元

Control_Unit Control_Unit(InstrD[31:26],InstrD[5:0],RegWriteD,RegDstD,

ALUSrcD,BranchD,MemWriteD,MemtoRegD,ALUControlD);

Sign_Extend Sign_Extend(InstrD[15:0],SignlmmD);

?

ALU_Forward ALU_Forward(ForwardAE,ForwardBE,RD1E,RD2E,SignlmmE,

ALUSrcE,ALUOutM,ResultW,WriteDataE,SrcAE,SrcBE);

alu alu(SrcAE,SrcBE,ALUControlE,ALUResult);

data data(ReadData,clk,MemWriteM,ALUOutM,WriteDataM);

EqualD equal(ForwardAD,ForwardBD,ALUOutM,RD1,RD2,BranchD,PCSrcD);

//數(shù)據(jù)冒險(xiǎn)和控制冒險(xiǎn)

HazardUnit HazardUnit(StallF,StallD,BranchD,ForwardAD,ForwardBD,

ForwardAE,ForwardBE,InstrD[25:21],InstrD[20:16],

RsE,RtE,FlushE,RegWriteE,MemtoRegE,WriteRegE,WriteRegM,RegWriteM,RegWriteW,WriteRegW,MemtoRegM);

ResultWritebackResultWriteback(MemtoRegW,ReadDataW,ALUOutW,ResultW);

?

endmodule

圖2.1頂層模塊連接

3.代碼設(shè)計(jì)

代碼實(shí)現(xiàn)從數(shù)據(jù)存儲(chǔ)器1號(hào)地址里的數(shù)累加到100號(hào)地址里的數(shù),再除以100取平均數(shù),由于數(shù)據(jù)存儲(chǔ)器存的數(shù)為對(duì)應(yīng)的地址,所以累加和為5050,平均數(shù)為50

001000_00000_00001_0000_0000_0000_0001//addiR1,R0,0 R1為變址寄存器X

001000_00000_00010_0000_0000_0000_0000//addiR2,R0,0 R2存放結(jié)果

001000_00000_00011_0000_0000_0110_0100//addiR3,R0,100 R3存放100

001000_00001_00001_0000_0000_0000_0001//addiR1,R1,1 R1自加一 即INX

101011_00001_00100_0000_0000_0000_0000//lw M(R1)->(R4)數(shù)據(jù)相關(guān),R1還未加一,旁路技術(shù)解決此數(shù)據(jù)相關(guān)

000000_00010_00100_00010_00000_100000//add (R2)+(R4)->(R2) //R4還未寫(xiě)回寄存器堆,停頓加旁路技術(shù)解決此數(shù)據(jù)相關(guān)

000101_00001_00011_1111_1111_1111_1100 //BNE (R1) (R3) -4

000000_00010_00011_00010_00000_111111//DIV (R2)/(R3)->(R2)

?

四、仿真結(jié)果

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

控制信號(hào)初始狀態(tài)不定,需要譯碼后產(chǎn)生。

可以看到取出的第一個(gè)數(shù)是1,也就是地址1里的數(shù)。

第二次取出的數(shù)是2,累加結(jié)果為3

modelsim單周期cpu,fpga開(kāi)發(fā),嵌入式硬件,系統(tǒng)架構(gòu),windows,Powered by 金山文檔

?

結(jié)果分析:

每次RtD等于RtE都是R4時(shí)會(huì)有l(wèi)wstall,停頓一個(gè)時(shí)鐘周期以便旁路技術(shù)將WriteBack階段

的結(jié)果寫(xiě)回到execute

累加結(jié)果為5050

可以看到仿真最后WriteBack的值是平均值50

五、設(shè)計(jì)心得

5.1遇到的問(wèn)題

(1)線路連接不對(duì),例化時(shí)建議直接將模塊名和頂層信號(hào)名對(duì)應(yīng),不需要.(clk)這樣比較麻煩

(2)位寬不對(duì),導(dǎo)致出錯(cuò)

(3)不加Reg不能在always賦值

(4)assign不能對(duì)reg賦值

(5)readmemh讀十六進(jìn)制數(shù)存十進(jìn)制數(shù)

(6)指令讀取后若無(wú)停頓及clr,PC自動(dòng)加4,所以判斷不相等轉(zhuǎn)移指令要考慮PC加4了

5.2我的收獲

(1)CPU流水線加快了CPU的運(yùn)行速度,開(kāi)發(fā)了CPU的并行性,若沒(méi)有停頓,五級(jí)流水線的運(yùn)行速度會(huì)是單周期的五倍

(2)數(shù)據(jù)冒險(xiǎn)可以通過(guò)前向通路和停頓解決,控制冒險(xiǎn)可以通過(guò)在Decode階段提前判斷是否符合轉(zhuǎn)移條件提前轉(zhuǎn)移,同時(shí)清空流水線,防止流水線數(shù)據(jù)混亂。

(3)do文件可以快速完成文件的編譯,仿真波形添加,大大提升了使用modelsim的效率。

(4)verilog語(yǔ)言很好地可以實(shí)現(xiàn)硬件的設(shè)計(jì),我們要好好掌握,為更復(fù)雜的集成電路設(shè)計(jì)打下堅(jiān)實(shí)基礎(chǔ)。

?

以上介紹包含了關(guān)鍵代碼,同學(xué)們可以參考學(xué)習(xí),是我的一個(gè)課程設(shè)計(jì),不明白的地方可以私信我,評(píng)論留言也可

?

到了這里,關(guān)于基于Verilog的mips指令集單周期/五級(jí)流水cpu,modelsim/vivado仿真設(shè)計(jì) 設(shè)計(jì)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包