基于Verilog的mips指令集单周期/五级流水cpu,modelsim/vivado仿真设计 设计

这篇具有很好参考价值的文章主要介绍了基于Verilog的mips指令集单周期/五级流水cpu,modelsim/vivado仿真设计 设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 文章来源地址https://www.toymoban.com/news/detail-533274.html

一、设计目的

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

2、掌握流水线微处理器的工作原理。

3、理解数据冒险、控制冒险的概念以及流水线冲突的解决方法。

4、掌握流水线微处理器的测试方法。

二、设计要求

设计一种五级流水线的基于MIPS指令集的处理器,其可支持部分指令,能够处理指令相关和数据相关,使流水线能够正常运行。源码q3026159745

三、设计内容

1、各模块设计

1.1、存储器设计

Instruction指令存储器,ROM

存储微处理器的指令,读出对应地址的指令

Regfile寄存器堆

存储各个寄存器的值,0号地址存R0的值,1号地址存储R1的值,以此类推

Data数据存储器,RAM

存储用户的数据,本实验存储器中存储的数据是对应地址的值

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.1存储器设计

 

1.2、ALU设计

ALU有A、B两个输入,F运算类型,Y为输出

F与CU的ALUControl相连,控制ALU的运算

具体功能如下

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开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.2ALU设计

1.3、ALUForward的设计

ALUForward由两个三路选择器和一个二路选择器组成,三路选择器输出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开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.3ALUForward的设计

 

1.4、Control_Unit设计

采用op 和 funct进行译码,产生各个模块的控制信号。

根据操作码译出相应控制信号

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,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、五级流水线clk设计

1.5.1clkPC

(1)取指令阶段,如果复位rst不为低电平,则每次时钟上升沿PCF刷新,若为低电平则PCF赋值为零

(2)StallF停顿,StallF为低电平,则PCF保持不变

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

(4)PCF来源有两个,一个是PC的累加,一个是相对转移地址

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开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.5.1clkPC clkFetch_Decode

1.5.2clkFetch_Decode

时钟上升沿判断

(1)是否有停顿,若有停顿则clk模块输出的信号保持不变;

(2)clr是否为高电平,若是,则将模块输出信号清零

(3)若停顿和清零信后均为低,则模块输入值对应赋给输出值

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

每当时钟信号上升沿判断FLUSH信号是否为高电平,若是,则清零模块的输出信号,若否则输入信号赋给相应的输出信号。

Branch信号单周期在ALU判断Rt和Rs是否相等并转移,而流水线CPU中可以提前判断是否转移

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开发,嵌入式硬件,系统架构,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

我们知道影响流水线性能的有三个冒险:数据冒险,结构冒险,控制冒险。

(1)由于数据存储器和指令存储器分离,所以流水线读指令和写数据可以并行执行,不存在存储器争用问题,寄存器堆采用读写双端口,因此也不会出现资源争用问题。

(2)数据冒险

寄存器的值还没有被写回寄存器,若此时读取寄存器数据并用此数据参与运算就会造成错误。

a.不访存的数据冒险

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.6.1不访存的数据冒险

add $s0,$s2,$s3

add $t0,$s0,$s1

第二条add要用s0的数据进行计算时,也就是execute阶段,可以将第一条正处于memory阶段的AluOutM结果给第二条指令的ALU输入。

这就是所谓的旁路技术

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

then ForwardAE = 10

elseif ((rsE != 0) AND (rsE == WriteRegW) AND RegWriteW)//访问存储器

then ForwardAE = 01

else ForwardAE= 00

 

b.访存造成的数据冒险

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.6.2访存造成的数据冒险

lw $s0,40($0)

add$s0,$s0,$s1

add的execute阶段,需要用到上一条指令写回的$s0的数值,而上一条指令要从存储器取数据,在Writeback阶段才能得到$s0的数值,所以需要停顿一个时钟周期,等到lw指令进入Writeback阶段再通过旁路技术将ResultW引入到add的执行阶段。

本条指令停顿了,后面的指令也要跟着停顿一个时钟周期。

lwstall=

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

 

StallF = StallD = FlushE = lwstall

 

(3)控制冒险

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.6.3控制冒险1

在Memory阶段进行转移判断会造成后面三条不该执行的指令执行,流水线数值改变,所以应该清空流水线。

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.6.4控制冒险2

 

如果在指令译码后直接判断Rs和Rt是否相等,则只有一条不该执行的指令执行了。

如果判断的Rs或者Rt还没有被写入到寄存器堆,则产生新的数据冒险,由于Decode阶段要用到Rs和Rt,而寄存器的值需要在Memory阶段或者Writeback阶段产生,所以不仅要有前向通路,还要有停顿才可以处理此数据相关。

 

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开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.6.5冒险控制单元

 

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

图1.6.6提前获得转移判断

 

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) //上一条指令的写回寄存器(WriteRegM)与本条指令的寄存器一致,

//采用旁路技术,将上一条指令的结果直接送到执行处。

ForwardAE= 2'b10;

else if ((RsE != 0)&& (RsE ==WriteRegW) && RegWriteW) //上上条指令的写回寄存器(WriteRegW)与本条指令的寄存器RS一致

//旁路技术,ResultW送入执行处

ForwardAE = 2'b01;

else ForwardAE= 2'b00;

 

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

ForwardBE <= 2'b10; //上一条指令的写回地址(WriteRegM)与本条指令的操作数地址(寄存器RT)一致,

//采用旁路技术,将上一条指令的结果直接送到执行处。

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

ForwardBE <= 2'b01;

else ForwardBE <= 2'b00;

 

//bne指令,在译码阶段开始判断RS和RT的值,提前判断,防止之后的指令执行

//当上上条指令要写回寄存器参与本次bne比较,通过旁路技解决,RD1/RD2<=ALUOut

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

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

 

branchstall <= (BranchD &&RegWriteE && (WriteRegE == RsD || WriteRegE == RtD) )//上一条指令要写这次比较的操作数

|| (BranchD && MemtoRegM&& (WriteRegM == RsD || WriteRegM == RtD));//上两条指令要写这次比较的操作数

 

//stall

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

StallF <= lwstall || branchstall;

StallD <= StallF;

FlushE <= StallD;//清空流水线防止再次判断并转移

 

 

end

endmodule

 

 

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

表1.6.1、停顿以及前向通路的举例分析

2.Top模块设计

顶层模块全部采用例化连接

顶层模块所有信号和连接代码如下

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;//冒险

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;//冒险

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 五级流水

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);

//各个小模块

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);

//数据冒险和控制冒险

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.代码设计

代码实现从数据存储器1号地址里的数累加到100号地址里的数,再除以100取平均数,由于数据存储器存的数为对应的地址,所以累加和为5050,平均数为50

001000_00000_00001_0000_0000_0000_0001//addiR1,R0,0 R1为变址寄存器X

001000_00000_00010_0000_0000_0000_0000//addiR2,R0,0 R2存放结果

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)数据相关,R1还未加一,旁路技术解决此数据相关

000000_00010_00100_00010_00000_100000//add (R2)+(R4)->(R2) //R4还未写回寄存器堆,停顿加旁路技术解决此数据相关

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

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

 

四、仿真结果

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

控制信号初始状态不定,需要译码后产生。

可以看到取出的第一个数是1,也就是地址1里的数。

第二次取出的数是2,累加结果为3

modelsim单周期cpu,fpga开发,嵌入式硬件,系统架构,windows,Powered by 金山文档

 

结果分析:

每次RtD等于RtE都是R4时会有lwstall,停顿一个时钟周期以便旁路技术将WriteBack阶段

的结果写回到execute

累加结果为5050

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

五、设计心得

5.1遇到的问题

(1)线路连接不对,例化时建议直接将模块名和顶层信号名对应,不需要.(clk)这样比较麻烦

(2)位宽不对,导致出错

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

(4)assign不能对reg赋值

(5)readmemh读十六进制数存十进制数

(6)指令读取后若无停顿及clr,PC自动加4,所以判断不相等转移指令要考虑PC加4了

5.2我的收获

(1)CPU流水线加快了CPU的运行速度,开发了CPU的并行性,若没有停顿,五级流水线的运行速度会是单周期的五倍

(2)数据冒险可以通过前向通路和停顿解决,控制冒险可以通过在Decode阶段提前判断是否符合转移条件提前转移,同时清空流水线,防止流水线数据混乱。

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

(4)verilog语言很好地可以实现硬件的设计,我们要好好掌握,为更复杂的集成电路设计打下坚实基础。

 

以上介绍包含了关键代码,同学们可以参考学习,是我的一个课程设计,不明白的地方可以私信我,评论留言也可

 

到了这里,关于基于Verilog的mips指令集单周期/五级流水cpu,modelsim/vivado仿真设计 设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 实验九 单周期MIPS CPU设计实验(基于Logisim)

    一、实验目的 学生掌握控制器设计的基本原理,能利用硬布线控制器的设计原理在Logisim平台中设计实现MIPS单周期CPU。 二、实验内容 利用运算器实验,存储系统实验中构建的运算器、寄存器文件、存储系统等部件以及Logisim中其它功能部件构建一个32位MIPS CPU单周期处理器。数

    2024年02月05日
    浏览(75)
  • 计组高分笔记:【05】中央处理器 「CPU细节 | 取指周期 | 间址周期 | 执行周期 | 中断周期 | 数据通路 | 硬布线控制器 | 微程序控制器 | 指令流水线 | LOAD | STORE」

    CPU由 运算器 和 控制器 组成。 注意:n位CPU,指机器字长为n,表示一次能够处理的二进制位数。自然与数据总线相等 1.1.1 运算器的基本组成 功能:对数据进行加工 通用寄存器组 :如AX、BX、CX、DX、SP等,用于存放操作数(包括源操作数、目的操作数及中间结果)和各种地址

    2024年02月11日
    浏览(41)
  • MIPS指令集-mars-cpu

    MIPS通用寄存器 MIPS有32个通用寄存器($0-$31),各寄存器的功能及汇编程序中使用约定如下: 下表描述32个通用寄存器的别名和用途 REGISTER NAME USAGE $0 $zero 常量0(constant value 0) $1 $at 保留给汇编器(Reserved for assembler) $2-$3 $v0-$v1 函数调用返回值(values for results and expression evaluation)

    2024年02月08日
    浏览(51)
  • 【计算机硬件系统设计(华科)——单周期MIPS CPU(Logisim 实现)】

    本章继续讲述计算机硬件系统设计的内容,之前已经大概说明了 ALU 和存储系统的设计,本文讲述CPU的设计。对应的有单周期、多周期 CPU 设计,以及流水线设计,中断处理会在后文中详细说明,本文不进行讲述。 即定长指令周期,机器性能取决于最慢的指令,导致时钟周期

    2024年02月02日
    浏览(51)
  • 计算机组成原理3个实验-logisim实现“七段数码管”、“有限状态机控制的8*8位乘法器”、“单周期MIPS CPU设计”。

    目录 标题1.首先是七段数码管   标题二:有限状态机控制的8*8位乘法器 标题三:单周期MIPS CPU设计 1看一下实验要求:    2.接下来就是详细设计: 1. 组合逻辑设计        由于7段数码管由7个发光的数码管构成,因为我们想用二进制将0-9这几个数字表示出来。所以他需要

    2024年01月17日
    浏览(48)
  • 基于mips指令集的处理器设计与实现

    1.mips指令集格式 2.mips寄存器特点 1.ALU模块 2.General_Register模块(通用寄存器) 3.instruction_cache模块(指令cache) 4.program_counter模块(程序计数器) 5.control模块(控制译码) MIPS是(Microcomputer without interlocked pipeline stages)的缩写,含义是无互锁流水级微处理器。MIPS 是最早的,最成功的RISC处

    2024年02月06日
    浏览(43)
  • 计算机组成原理32位MIPS CPU设计实验(指令译码器电路设计 、时序发生器状态机设计、时序发生器输出函数、硬布线控制器)

    这次实验是32位MIPS CPU设计实验(单总线CPU-定长指令周期-3级时序),在头歌当中一共需要我们进行六道题的测试,分别为MIPS指令译码器设计,定长指令周期(时序发生FSM设计,时序发生器输出函数设计,硬布线控制器,单总线CPU设计),硬布线控制器组合逻辑单元。其中由于

    2024年02月02日
    浏览(38)
  • 单总线CPU设计(变长指令周期3级时序)(HUST)(头歌实验)

      利用比较器等功能模块将32位MIPS 指令字译码生成LW、SW、BEQ、SLT、ADDI、OtherInstr信号也就是利用比较器将指令字转换为译码信号,OP与不同信号对应(查询MIPS手册得知)  16 进制 :23 是 2进制: 00100011 ,把获得的OP,Func,和常数比对,相同输出1. 按照题目要求填写表格,使

    2024年02月07日
    浏览(34)
  • 从零开始设计RISC-V处理器——五级流水线之数据通路的设计

    (一)从零开始设计RISC-V处理器——指令系统 (二)从零开始设计RISC-V处理器——单周期处理器的设计 (三)从零开始设计RISC-V处理器——单周期处理器的仿真 (四)从零开始设计RISC-V处理器——ALU的优化 (五)从零开始设计RISC-V处理器——五级流水线之数据通路的设计

    2024年02月08日
    浏览(50)
  • 5.2 FPGA:基于verilog的LED流水灯设计(多种方法)

    目录 设计目标:8个LED灯以每0.5s的速率进行循环闪烁 方法1:移位法实现 设计模块 仿真代码 实验结果  方法2:循环移位方法  设计模块 方法3:使用三八译码器实现流水灯 顶层模块 底层模块 当仿真时时间长,可以减小设计代码的计数次数,对分析移位功能没有影响。 设计

    2024年02月06日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包