计算机组成单周期CPU设计

编程入门 行业动态 更新时间:2024-10-07 02:29:19

计算机组成单<a href=https://www.elefans.com/category/jswz/34/1768715.html style=周期CPU设计"/>

计算机组成单周期CPU设计

根据袁春风老师编写的《计算机组成与系统结构第二版》的课程材料,完成的计组单周期CPU设计,已经完成简单测试。包括五条R型指令(add,sub,subu,slt,sltu),五条I型指令(addu,beq,ori,lw,sw),和一条J型指令(jump)。

我的设计将总体分成了ALU模块、寄存器组部件、存储器部件、取指令部件、控制器和顶层模块;实际上细化的话,还可以将加法器、扩展器、选择器单独列出来;因为该实验用到加法器、扩展器和选择器的次数不是很多,就没有单独列出来。
建议配套测试文件参考:yyy的测试文件

ALU

module ALU(A,B,ALUctr,Result,Zero,Overflow);
parameter n=32;
input [n-1:0]A,B;
input [2:0]ALUctr;
output wire Zero,Overflow;
output reg[n-1:0]Result;
wire [n-1:0]Add_Result;
wire [n-1:0]Less_Result;
wire [n-1:0]Or_Result;
//--------------------------------------------------------------
wire SUBctr=ALUctr[2];
wire OVctr=(!ALUctr[1])&(ALUctr[0]);
wire SIGctr=ALUctr[0];
wire[1:0]OPctr;//四个控制信号
assign OPctr[0]=(!ALUctr[2])&ALUctr[1]&(!ALUctr[0]);
assign OPctr[1]=ALUctr[2]&ALUctr[1]; 
//--------------------------------------------------------------
wire Add_Overflow;
wire Add_Sign;
wire Add_carry;
//----------------------------
wire [n-1:0]Areg=A;
wire [n-1:0]Breg=B^{n{SUBctr}};
wire Cin=SUBctr;
//--------------------------------------------------------------------------------------------------------
assign {Add_carry, Add_Result} = Areg + Breg + Cin;//①加法:A+B+0②减法:A+B各位取反+1;
assign Add_Sign = Add_Result[n-1];
assign Zero=(Add_Result==32'b0)?1:0;
assign Add_Overflow = (Areg[n-1]&Breg[n-1]&(~Add_Result[n-1]))|((~Areg[n-1])&(~Breg[n-1])&Add_Result[n-1]);
assign Overflow = Add_Overflow & OVctr;
//---------------------------------------------------------------------------------------------------------
wire Less1,Less2;
assign Less1=Add_carry^SUBctr;
assign Less2=(Add_Sign^Add_Overflow);
assign Less_Result = (SIGctr == 1'b0)?Less1:Less2;
//------------------------------------------------------------------------------------------
assign Or_Result=(A|B);
always @(*) 
begin	case(OPctr)2'b00:Result = Add_Result;2'b01:Result = Or_Result;2'b10:Result = Less_Result;	endcaseend
endmodule 

寄存器组

module register(clk,Wen,Rw,busW,Ra,Rb,busA,busB);
input clk,Wen;
parameter n=32;
input [n-1:0]busW;
input [5-1:0]Rw,Ra,Rb;
output wire[n-1:0]busA;
output wire[n-1:0]busB;
//---------------------------------------------------------
integer j;
reg[n-1:0]datareg[n-1:0];//32个寄存器组
//始终不管怎么操作,使用的都是这32个寄存器组
//-------------------------------------------------
initial 
beginfor(j=0;j<32;j=j+1)datareg[j]=j;		
end
//--------------------------------------------------
always@(negedge clk)//写操作
beginif(Wen==1'b1)datareg[Rw]<=busW;//
end
//-------------------------------------------------------------------?
assign busA=datareg[Ra];
assign busB=datareg[Rb];
endmodule

数据存储器

module data_cache(data_in,clk,Wen2,address,data_out);
parameter n=32;
input clk,Wen2;
input [n-1:0]data_in;
input [n-1:0]address;
output wire[n-1:0]data_out;
//------------------------------------
reg [n-1:0]datareg[n-1:0];//32个,0-32地址的数据都可以使用和改变
integer j;
//---------------
initial 
beginfor(j=0;j<n;j=j+1)datareg[j]=j;
end
//--------------------------
always@(negedge clk)
beginif(Wen2==1)//写入信号有效时datareg[address]=data_in;
end
assign data_out=datareg[address];
endmodule

取指令部件

module getinstruction(clk,run,Branch,Zero,jump,instruction,address);
parameter n=32;
input clk,run;
input Branch,Zero,jump;
output wire [31:0]instruction;
output wire [31:0]address;
//八位一写
//--------------------------------------------
reg [7:0]mem_ins[256];  //64:8 bits
reg [31:2] PC;
integer i; 
//--------------------------
initial
begin for(i=0;i<256;i=i+1)mem_ins[i]=8'b00000000;//mem_ins[i]=i;
mem_ins[4]=8'h05;mem_ins[5]=8'h00;mem_ins[6]=8'h5D;mem_ins[7]=8'h11;
mem_ins[12]=8'h07;mem_ins[13]=8'h00;mem_ins[14]=8'h00;mem_ins[15]=8'h08;
mem_ins[28]=8'h0C;mem_ins[29]=8'h00;mem_ins[30]=8'h50;mem_ins[31]=8'h25;
mem_ins[32]=8'h0E;mem_ins[33]=8'h00;mem_ins[34]=8'h51;mem_ins[35]=8'h24;
mem_ins[36]=8'h04;mem_ins[37]=8'h00;mem_ins[38]=8'h12;mem_ins[39]=8'h26;
mem_ins[40]=8'h02;mem_ins[41]=8'h00;mem_ins[42]=8'h13;mem_ins[43]=8'h37;
mem_ins[44]=8'h10;mem_ins[45]=8'h00;mem_ins[46]=8'h74;mem_ins[47]=8'h35;
mem_ins[48]=8'h20;mem_ins[49]=8'hA8;mem_ins[50]=8'h74;mem_ins[51]=8'h02;
mem_ins[52]=8'h20;mem_ins[53]=8'hB0;mem_ins[54]=8'h4C;mem_ins[55]=8'h01;
mem_ins[56]=8'h22;mem_ins[57]=8'hB8;mem_ins[58]=8'hD5;mem_ins[59]=8'h02;
mem_ins[60]=8'h22;mem_ins[61]=8'hC0;mem_ins[62]=8'hC8;mem_ins[63]=8'h01;
mem_ins[64]=8'h23;mem_ins[65]=8'hC8;mem_ins[66]=8'hD5;mem_ins[67]=8'h02;
mem_ins[68]=8'h23;mem_ins[69]=8'hD0;mem_ins[70]=8'hC8;mem_ins[71]=8'h01;
mem_ins[72]=8'h2A;mem_ins[73]=8'hD8;mem_ins[74]=8'hF8;mem_ins[75]=8'h02;
mem_ins[76]=8'h2B;mem_ins[77]=8'hE0;mem_ins[78]=8'hF8;mem_ins[79]=8'h02;
mem_ins[80]=8'h0C;mem_ins[81]=8'h00;mem_ins[82]=8'h9D;mem_ins[83]=8'h8C;
mem_ins[84]=8'h01;mem_ins[85]=8'h00;mem_ins[86]=8'h7E;mem_ins[87]=8'h8F;
mem_ins[88]=8'h01;mem_ins[89]=8'h00;mem_ins[90]=8'h9F;mem_ins[91]=8'h8F;
mem_ins[92]=8'h1F;mem_ins[93]=8'h00;mem_ins[94]=8'h1D;mem_ins[95]=8'hAC;
mem_ins[96]=8'h1F;mem_ins[97]=8'h00;mem_ins[98]=8'h0A;mem_ins[99]=8'h8C;
mem_ins[100]=8'h01;mem_ins[101]=8'h00;mem_ins[102]=8'h00;mem_ins[103]=8'h08;
end
//--------------------------------------
assign instruction={{mem_ins[{PC[7:2],2'b11}]},{mem_ins[{PC[7:2],2'b10}]},{mem_ins[{PC[7:2],2'b01}]},{mem_ins[{PC[7:2],2'b00}]}};
wire [15:0]imme=instruction[15:0];
wire [25:0]target=instruction[25:0];
//--------------------------------------
wire [31:2] PC_INC=PC+1'b1;   
wire [31:2] PC_Branch=PC_INC + {{14{imme[15]}},imme}; 
wire [31:2] PC_Jump={PC[29:26],instruction[25:0]};
//-------------------------------------------------
always@(negedge clk)
beginif(jump)PC=PC_Jump;else if(Branch && Zero)PC=PC_Branch;else PC=PC_INC;
end
//--------------------------------------------------------------
assign address={PC,2'b00};
endmodule
//---------------------------------------------------------------------------

控制器

module Topctrl(instruction,Branch,Jump,RegDst,ALUSrc,MemtoReg,MemWr,RegWr, ExtOp,ALUctr);
input[31:0]instruction;
output wire [2:0]ALUctr;
output wire Branch,Jump,RegDst,ALUSrc,MemtoReg,MemWr,RegWr, ExtOp;
//--------------------------------------------------------------------
wire [5:0]op=instruction[31:26];
wire [5:0]func=instruction[5:0];
wire R_type=(op == 6'b000000);
wire [2:0]ALUop1,ALUop2;
//-------------------------------------------------------------------
wire add = (func == 6'b100000);
wire sub = (func == 6'b100010);
wire subu = (func == 6'b100011);
wire slt = (func == 6'b101010);
wire sltu = (func == 6'b101011);
wire ori = (op == 6'b001101);
wire addiu=(op==6'b001001);
wire lw = (op == 6'b100011);
wire sw = (op == 6'b101011);
wire beq1 = (op == 6'b000100);
wire jump = (op == 6'b000010);
//---------------------------------------------------------------------
assign Branch=beq1; 
assign Jump =jump;
assign RegDst =R_type;
assign ALUSrc =ori|addiu|lw|sw;
assign MemtoReg = lw;
assign RegWr =R_type|ori|addiu|lw;
assign MemWr=sw;
assign ExtOp =lw|sw|addiu;
//-----------------------------------------------------------------
assign ALUop1[2]=beq1;
assign ALUop1[1]=ori;
assign ALUop1[0]=0;
assign ALUop2[2]=sub|subu|slt|sltu;
assign ALUop2[1]=slt|sltu;
assign ALUop2[0]=add|sub|slt;
//------------------------------------------------------------------
assign ALUctr=(op == 6'b000000)?ALUop2:ALUop1;
endmodule

顶层模块

module TOP(clk,run,instruction,ALUctr,address,Branch,Jump,Zero,RWD,DWD,Rs_n,Rt_n,Rd_n,Wen1,Wen2);
input clk,run;//输入:clk,run
parameter n=32;
output wire [n-1:0] instruction;
output wire [2:0] ALUctr;
output wire	[n-1:0]address;
output wire Branch,Jump,Zero;
output wire [n-1:0]RWD;
output wire [n-1:0]DWD;
output wire [4:0]Rs_n,Rt_n,Rd_n;
wire RegDst,ALUSrc,MemtoReg,MemWr,RegWr,ExtOp;
Topctrl(instruction,Branch,Jump,RegDst,ALUSrc,MemtoReg,MemWr,RegWr,ExtOp,ALUctr);
//输入:instruction输出:Branch,Jump,RegDst,ALUSrc,MemtoReg,MemWr,RegWr, ExtOp,ALUctr
//-------------------------------------------------------------------------------------------------------
output wire Wen1 = (~Overflow) & RegWr;
output wire Wen2=MemWr;
wire [4:0] Rs = instruction[25:21];
wire [4:0] Rt = instruction[20:16];
wire [4:0] Rd = instruction[15:11];
assign Rs_n=Rs;
assign Rt_n=Rt;
assign Rd_n=Rd;
wire [4:0] Rw = (RegDst)?Rd:Rt;
wire [4:0] shift = instruction[10:6];
wire [15:0] imme = instruction[15:0];
wire [31:0] Extimme = (ExtOp)?{{16{imme[15]}},imme}:{16'b0,imme};
wire [31:0] BusW = (MemtoReg)?RdData:Result;
assign RWD=BusW;
//---------------------------------------------
wire [31:0] BusA;
wire [31:0] BusB;
wire [31:0] Result;
wire [31:0]	RdData;
wire Overflow;
wire [31:0] BusBm = (ALUSrc)?Extimme:BusB;
assign DWD=BusB;
//---------------------------
ALU(BusA,BusBm,ALUctr,Result,Zero,Overflow);//输入BusA,BusB,ALUctr输出:Zero,Overflow,Result
register(clk,Wen1,Rw,BusW,Rs,Rt,BusA,BusB);//输入:clk,Wen,Rw,busW,Ra,Rb输出:BusA,BusB(Ra,Rb需要确认)
getinstruction(clk,run,Branch,Zero,Jump,instruction,address);//输入:clk,run;Branch,Zero,jump;输出:instruction,address
data_cache(BusB,clk,Wen2,Result,RdData);
//--------------------------------------------------
endmodule

希望可以给大家一点帮助~

更多推荐

计算机组成单周期CPU设计

本文发布于:2024-03-14 05:09:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1735700.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:周期   计算机   CPU

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!