计算机组成单周期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;	
	 endcase
	  	
end
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 
begin
	for(j=0;j<32;j=j+1)
		datareg[j]=j;		
end
//--------------------------------------------------
always@(negedge clk)//写操作
begin
	if(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 
begin
	for(j=0;j<n;j=j+1)
	datareg[j]=j;
end
//--------------------------
always@(negedge clk)
begin
	if(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)
begin
	if(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

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

一、 设计目标 设计目的: 设计一个含有36条指令的MIPS单周期处理器,并能将指令准确的执行并烧写到试验箱上来验证 设计初衷 1、理解MIPS指令结构,理解MIPS指令集中常用指令的功能和编码,学会对这些指令进行归纳分类。 2、了解熟悉MIPS体系中的处理器结构 3、熟悉并掌握单周期处理器CPU的原理和设计 4、进一步加强Verilog语言进行电路设计的能力 二、实验设备 1、装有xilinx ISE的计算机一台 2、LS-CPU-EXB-002教学系统实验箱一台 三、实验任务 1.、学习 MIPS 指令集,深入理解常用指令的功能和编码,并进行归纳确定处理器各部件的控制码,比如使用何种 ALU 运算,是否写寄存器堆等。 2、单周期 CPU 是指一条指令的所有操作在一个时钟周期内执行完。设计中所有寄存器和存储器都是异步读同步写的,即读出数据不需要时钟控制,但写入数据需时钟控制。 故单周期 CPU 的运作即:在一个时钟周期内,根据 PC 值从指令 ROM 中读出相应的指令,将指令译码后从寄存器堆中读出需要的操作数,送往 ALU 模块,ALU 模块运算得到结果。 如果是 store 指令,则 ALU 运算结果为数据存储的地址,就向数据 RAM 发出写请求,在下一个时钟上升沿真正写入到数据存储器。 如果是 load 指令,则 ALU 运算结果为数据存储的地址,根据该值从数据存 RAM 中读出数据,送往寄存器堆根据目的寄存器发出写请求,在下一个时钟上升沿真正写入到寄存器堆中。 如果非 load/store 操作,若有写寄存器堆的操作,则直接将 ALU 运算结果送往寄存器堆根据目的寄存器发出写请求,在下一个时钟上升沿真正写入到寄存器堆中。 如果是分支跳转指令,则是需要将结果写入到 pc 寄存器中的。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值