计算机组成实验报告
实验名称:单周期CPUVerilog实现
实验日期:2011.4.12-2011.4.19
实验人员:
同组者:
一、 主要实验内容
将已做好的各个模块进行模块合并,实现单周期CPU的各项指令,(注:由于此次设计只是利用verilog硬件编程语言实现具体功能,因此数据寄存器和存储器部件内的内容需由程序设计者自己给出,并不能从计算机中直接读取),下面对各个子模块进行简单的介绍。
二、各个子模块的简单介绍
此程序将数据通路(SingleDataLoad)设定为顶层模块,下面的模块包括:算术逻辑运算单元(ALU)、数据存储器(DataStore)、数据寄存器(Registers)、取指令部件(GetCode)、总控制器(Control),通过顶层模块对各个子模块的调用从而实现了整个单周期CPU。
1) 数据通路(SingleDataLoad):进行数据的运算、读取以及存储功能,通过总控制器产生的各个控制信号,进而实现对数据的各项操作。
2) 算术逻辑运算单元(ALU):数据通路调用此模块,根据得到的控制信号对输入数据进行处理,处理功能有:addu、add、or、subu、sub、sltu、slt等。
3) 数据存储器(DataStore):当WrEn控制信号为1时,此时就将输入数据存储到此存储器中,当WrEn为0时,则根据输入的地址,找到地址对应的单元将单元中的数据输出。
4) 数据寄存器(Registers):在此程序中功能和实现基本和数据存储器相同,但在实际CPU当中使用的逻辑器件及获取数据的方式还是有所区别的。
5) 取指令部件(GetCode):指根据PC所提供的地址从指令寄存器中取出要执行的指令,再根据各控制信号,得出下一次要执行的指令的地址。(注:指令寄存器中存放的就是一个程序或一段代码所需要执行的指令,这里也是程序设计者自己给出的一些指令的值。)
6) 总控制器(Control):总控制器通过从取指令部件获得的指令,进而产生各个控制信号,并将控制信号返回个数据通路,就此实现各项功能。
(以上各个模块代码见附录)
三、程序截图及说明
上图为执行下列指令产生的图像:
(此时$1,$2所指的寄存器中存放的值是不同的)
(beq rs rt imm16:指令的功能为:CondßR[rs]-R[rt] if(Cond eq 0)PCßPC+(SignExt(imm16)*4)
Mem[0]<={6'b000100,5'b00001,5'b00010,5'b00000,5'b00000,6'b000001}; //beq $1,$2,1
Mem[4]<={6'b000000,5'b00001,5'b00010,5'b00100,5'b00000,6'b101011}; //sltu $4,$1,$2
Mem[8]<={6'b000010,5'b00000,5'b00000,5'b00000,5'b00000,6'b000010}; //j 2
当$1、$2所指的寄存器的值相同时,执行上述指令,得到的图如下:
可以看出CPU跳过了第二条指令,直接执行了第三条,而上图执行了第一条指令后接着执行第二条,最后才执行第三条指令,区别就在于第一幅图表示的是$1、$2中的值不相等所执行的情况,第二幅图表示的是$1、$2中的值相等的情况,由此可以得知测试正确。
四、实验收获及感想
说实话,关于单周期CPU的设计,我没有能够完全理解,原因是我没有把书上的内容认真看,老师上课讲的时候,并没有能够完全掌握,加之课外由于种种原因,自己没有抓紧时间,没有跟上老师的节奏。希望老师给我一点时间,我会努力跟上的。
附件:
①数据通路(SingleDataLoad)
module SingleDataLoad(clk,RegWr,RegDst,ExtOp,ALUSrc,Branch,Jump,MemtoReg,MemWr,ALUctr);
input clk;
//input[31:0] Instruction;
output RegWr,RegDst,ExtOp,ALUSrc,Branch,Jump,MemtoReg,MemWr;
output[2:0] ALUctr;
wire RegWr,RegDst,ExtOp,ALUSrc,Branch,Jump,MemtoReg,MemWr;
wire[2:0] ALUctr;
wire [31:0] Instruction;
wire [4:0] Rd,Rt,Rs;
wire [5:0] op,func;
wire[4:0] Rx;
wire P1,P2,Zero,Overflow;
wire [31:0] busW,busA,busB,out1,dataout,busB1,busBo;
wire [15:0] imm16;
Control con(Instruction,RegWr,ExtOp,ALUSrc,ALUctr,Branch,Jump,RegDst,MemtoReg,MemWr);
assign op=Instruction[31:26];
assign func=Instruction[5:0];
assign Rs=Instruction[25:21];
assign Rt=Instruction[20:16];
assign Rd=Instruction[15:11];
assign imm16=Instruction[15:0];
assign P1=P2&RegWr;
MUX2 mux2(RegDst,Rt,Rd,Rx);
assign busB1={{16{imm16[15] & ExtOp}},imm16[15:0]};
MUX2TO1 mux1(ALUSrc,busB,busB1,busBo);
Registers Reg(clk,busW,P1,Rx,Rs,Rt,busA,busB);
ALU alu(busA,busBo,ALUctr,out1,Overflow,Zero);
assign P2=!Overflow;
DataStore datas(clk,busB,out1[4:0],MemWr,dataout);
MUX2TO1 mux3(MemtoReg,out1,dataout,busW);
GetCode get(Branch,Zero,Jump,clk,Instruction);
endmodule
module MUX2TO1(op,X,Y,Z);
input op;
input [31:0] X,Y;
output[31:0] Z;
reg [31:0] Z;
always@(op)
begin
if(op==1)
Z=Y;
else
Z=X;
end
endmodule
module MUX2(op,x,y,z);
input op;
input [4:0] x,y;
output[4:0] z;
reg [4:0] z;
always@(op)
begin
if(op==1)
z=y;
else
z=x;
end
endmodule
②算数逻辑运算单元(ALU)
module ALU(A,B,ALUctr,Result,Overflow,Zero);
parameter n=32;
input [n-1:0] A,B;
input [2:0] ALUctr;
output [n-1:0] Result;
output Overflow,Zero;
wire Zero,Overflow;
wire [n-1:0] Result;
wire SUBctr,OVctr,SIGctr;
wire [1:0] OPctr;
wire [n-1:0] H,M,N,Add_Result;
wire K,G,I,Add_Sign,Add_Overflow,Add_carry;
assign SUBctr=ALUctr[2];
assign OVctr=!ALUctr[1] & ALUctr[0];
assign SIGctr=ALUctr[0];
assign OPctr[1]=ALUctr[2] & ALUctr[1];
assign OPctr[0]=!ALUctr[2] & ALUctr[1] &!ALUctr[0];
assign H=B^{n{SUBctr}};
assign M=A|B;
Adderk nbit_add(SUBctr,A,H,Add_carry,Add_Sign,Add_Result,Zero); //,Add_Overflow
assign Add_Overflow= A[n-1] & H[n-1] & !Add_Result[n-1] | !A[n-1] & !H[n-1] & Add_Result[n-1];
assign K=SUBctr ^ Add_carry;
assign I=Add_Sign ^ Add_Overflow;
assign Overflow=OVctr & Add_Overflow;
IMUX2to1 YN(K,I,SIGctr,G);
IMUX2to1 yn(0,1,G,N);
MUX3to1 nbit_Result(Add_Result,M,N,OPctr,Result);
endmodule
module Adderk (Cin, X, Y,Add_carry,Add_sign,Add_result,Zero); //Add_Overflow,
parameter k = 32;
input [k-1:0] X, Y;
input Cin;
output [k-1:0] Add_result;
output Add_carry,Add_sign,Zero; //,Add_Overflow
reg [k-1:0] Add_result;
reg Add_carry,Zero,Add_sign; //,Add_Overflow
always@(X or Y or Cin)
begin
{Add_carry, Add_result} = X + Y + Cin;
if(Add_result==0)
Zero=1;
else
Zero=0;
if(Add_result[31]==1)
Add_sign=1;
else
Add_sign=0;
end
endmodule
module MUX3to1 (V,W,U,Selm,F);
parameter k = 32;
input [k-1:0] V,W,U;
input [1:0] Selm;
output [k-1:0] F;
reg [k-1:0] F;
always @(V or W or U or Selm)
case(Selm)
2'b00: F <= V;
2'b01: F <= W;
2'b10: F<=U;
endcase
endmodule
module IMUX2to1 (V,W,SIGctr,Less);
input[31:0] V,W;
input SIGctr;
output[31:0] Less;
reg[31:0] Less;
always @(V or W or SIGctr)
if (SIGctr == 0)
Less <= V;
else
Less <= W;
endmodule
③数据存储器(DataStore):
module DataStore(clk,DataIn,Adr,WrEn,Out);
input [31:0] DataIn;
input [4:0] Adr;
input WrEn,clk;
output [31:0] Out;
reg [31:0] Out;
reg [31:0] Store [31:0];
always@(negedge clk)
begin
if(WrEn==1)
Store[Adr]=DataIn;
end
always@(Adr or WrEn)
if(WrEn==0)
Out=Store[Adr];
endmodule
④数据寄存器(Registers):
module Registers(clk,busW,wr,Rw,Ra,Rb,busA,busB);
input [31:0] busW;
input clk,wr;
input [4:0] Rw,Ra,Rb;
output [31:0] busA,busB;
reg [31:0] busA,busB;
reg [31:0] Regist [31:0];
always@(negedge clk)
begin
Regist[1]=32'd25;
Regist[2]=32'd25;
if(wr==0)
Regist[Rw]=busW;
end
always@(Ra or Rb or wr)
begin
if(wr==1)
begin
busA=Regist[Ra];
busB=Regist[Rb];
end
end
endmodule
⑤取指令部件(GetCode):
module GetCode(Branch,Zero,Jump,clk,Instruction);
input Zero,Branch,Jump,clk;
output[31:0] Instruction;
reg[29:0] PC=25;
wire[29:0] M,M2;
wire [4:0] addmem;
wire K;
reg reset=1;
assign addmem={PC[2:0],2'b00};
wire[29:0] O1,O2,O3,O4;
wire[15:0] imm16;
instruct InsMem(addmem,Instruction);
always@(negedge clk)
begin
if (reset==1)
begin
PC <=0;
reset<=0;
end
else
begin
PC <= O4;
end
end
assign imm16=Instruction[15:0];
assign M=PC;
assign K=Zero & Branch;
Adder adder1(M,1,O1);
assign M1={{14{imm16[15]}},imm16[15:0]};
Adder adder2(O1,M1,O2);
MUX2T1 mux1(K,O1,O2,O3);
assign M2={M[29:26],Instruction[25:0]};
MUX2T1 mux2(Jump,O3,M2,O4);
endmodule
module Adder(M,N,O);
input[29:0] M;
input[29:0] N;
output[29:0] O;
wire[29:0] M,N,O;
assign O=M+N;
endmodule
module MUX2T1(op,X,Y,Z);
input op;
input [29:0] X,Y;
output[29:0] Z;
reg [29:0] Z;
always@(op)
begin
if(op==1)
Z=Y;
else
Z=X;
end
endmodule
module instruct(addr,inst);
input [4:0] addr;
output [31:0] inst;
reg [31:0] inst;
// Declare the RAM variable
reg [31:0] Mem [31:0];
// write instruction: add 3<=(1)+(2),sub 6<=(4)-(5),jump 0
always @(*)
begin
//Mem[0]<={6'b000000,5'b00001,5'b00010,5'b00011,5'b00000,6'b100000}; //add $3,$1,$2
// Mem[4]<={6'b000000,5'b00011,5'b00001,5'b00100,5'b00000,6'b100010}; //sub $4,$3,$1
// Mem[0]<={6'b000000,5'b00001,5'b00010,5'b00011,5'b00000,6'b101010}; //slt $3,$1,$2
// Mem[4]<={6'b000000,5'b00011,5'b00001,5'b00100,5'b00000,6'b100011}; //subu $4,$3,$1
// Mem[0]<={6'b000000,5'b00001,5'b00010,5'b00011,5'b00000,6'b101010}; //slt $3,$1,$2
// Mem[4]<={6'b000000,5'b00001,5'b00010,5'b00100,5'b00000,6'b101011}; //sltu $4,$1,$2
//Mem[0]<={6'b001101,5'b00001,5'b00011,5'b10000,5'b00000,6'b000101}; //ori $3,$1,32773
// Mem[4]<={6'b001001,5'b00010,5'b00100,5'b00000,5'b00000,6'b001000}; //addiu $4,$2, 8
// Mem[4]<={6'b001001,5'b00010,5'b00100,5'b11111,5'b11111,6'b111000}; //addiu $4,$2, -8
// Mem[0]<={6'b101011,5'b00001,5'b00011,5'b00000,5'b00000,6'b000101}; //sw $3,$1,5
// Mem[4]<={6'b100011,5'b00001,5'b00100,5'b00000,5'b00000,6'b000101}; //lw $4,$1,5
Mem[0]<={6'b000100,5'b00001,5'b00010,5'b00000,5'b00000,6'b000001}; //beq $1,$2,1
Mem[4]<={6'b000000,5'b00001,5'b00010,5'b00100,5'b00000,6'b101011}; //sltu $4,$1,$2
Mem[8]<={6'b000010,5'b00000,5'b00000,5'b00000,5'b00000,6'b000010}; //j 2
end
// read
always @(addr)
begin
inst <= Mem[addr];
end
endmodule
⑥总控制器(Control):
module Control(Instruction,RegWr,ExtOp,ALUSrc,ALUctr,Branch,Jump,,RegDst,MemtoReg,MemWr);
output RegWr,RegDst,ExtOp,ALUSrc,Branch,Jump,MemtoReg,MemWr;
input[31:0] Instruction;
reg RegWr,RegDst,ExtOp,ALUSrc,Branch,Jump,clk,MemtoReg,MemWr;
output [2:0] ALUctr;
reg [2:0] ALUctr;
wire [5:0] op,func;
assign op=Instruction[31:26];
assign func=Instruction[5:0];
parameter S0=6'b100000,S1=6'b100010,S2=6'b100011,S3=6'b101010,S4=6'b101011,S5=6'b001101,S6=6'b001001,S7=6'b100011,S8=6'b101011,S9=6'b000100,S10=6'b000010;
always@(op or func)
begin
if(op==6'b000000)
begin
case(func)
S0:
begin
Branch=0;
Jump=0;
RegDst=1;
ALUSrc=0;
ALUctr=3'b001;
MemtoReg=0;
RegWr=1;
MemWr=0;
end
S1:
begin
Branch=0;
Jump=0;
RegDst=1;
ALUSrc=0;
ALUctr=3'b101;
MemtoReg=0;
RegWr=1;
MemWr=0;
end
S2:
begin
Branch=0;
Jump=0;
RegDst=1;
ALUSrc=0;
ALUctr=3'b100;
MemtoReg=0;
RegWr=1;
MemWr=0;
end
S3:
begin
Branch=0;
Jump=0;
RegDst=1;
ALUSrc=0;
ALUctr=3'b111;
MemtoReg=0;
RegWr=1;
MemWr=0;
end
S4:
begin
Branch=0;
Jump=0;
RegDst=1;
ALUSrc=0;
ALUctr=3'b110;
MemtoReg=0;
RegWr=1;
MemWr=0;
end
endcase
end
else
begin
case(op)
S5:
begin
Branch=0;
Jump=0;
RegDst=0;
ALUSrc=1;
ALUctr=3'b010;
MemtoReg=0;
RegWr=1;
MemWr=0;
ExtOp=0;
end
S6:
begin
Branch=0;
Jump=0;
RegDst=0;
ALUSrc=1;
ALUctr=3'b000;
MemtoReg=0;
RegWr=1;
MemWr=0;
ExtOp=1;
end
S7:
begin
Branch=0;
Jump=0;
RegDst=0;
ALUSrc=1;
ALUctr=3'b000;
MemtoReg=1;
RegWr=1;
MemWr=0;
ExtOp=1;
end
S8:
begin
Branch=0;
Jump=0;
ALUSrc=1;
ALUctr=3'b000;
RegWr=0;
MemWr=1;
ExtOp=1;
end
S9:
begin
Branch=1;
Jump=0;
ALUSrc=0;
ALUctr=3'b100;
RegWr=0;
MemWr=0;
end
S10:
begin
Branch=0;
Jump=1;
RegWr=0;
MemWr=0;
end
endcase
end
end
endmodule
一交易品种和合约的选择1股指期货我选了IF1101作为我的交易对象2商品期货我选了a1109和y1109作为我的交易对象二基本面分…
郑州航空工业管理学院实验报告课程名称期货交易模拟实验班级1103092学号110407343姓名赵志磊20xx4实验目的1通过赢顺…
期货投资模拟操盘实验报告姓名学号班级系部专业指导教师XxxxxxxxxxxxXxxxxxx金融系金融学胡朝晖20xx年12月广东金…
股指期货模拟交易实验报告股指期货模拟交易实验报告姓名班级学号成绩一实验目的了解股指期货的交易方法交易手段以及一些股指期货交易的常识…
证券期货投资模拟试验报告商学院04级会计学3班张三0415030329一实验名称证券期货投资模拟实习报告二实验时间20xx年630…
行为习惯养成教育工作总结学生时期是人生成长过程中的一个关键时期。这一阶段养成的良好习惯对人的一生有积极影响。班主任在培养学生良好习…
问题总结本人自大学毕业以来至今参加工作已有一个月的时间,在此期间,通过自身的不断学习及领导前辈的批评帮助,逐渐发现了自己在工作作风…
拔河比赛为了体现我们青春的热情,加强锻炼,增强全系同学们的身体素质,活跃校园文化生活,公卫系学生会体育部特此举办了xx年公卫系拔河…
教育学院“学长学姐帮帮学”活动总结结合大院学习部安排,教育学院特此举办了“学长学姐帮帮学”讲座活动。活动于20xx年x月x日晚七点…
尊敬的xxx总、店委会委员、全体员工同志们:伴随着xx大酒店新年联谊晚会上嘹亮的歌声,我们以愉悦的心情,迎来了新世纪的又一个新年。…