1、单周期CPU实验报告计算机组成实验报告实验名称:单周期CPUVerilog实现实验日期:2011.4.12-2011.4.19实验人员: 同组者: 一、主要实验内容将已做好的各个模块进行模块合并,实现单周期CPU的各项指令,(注:由于此次设计只是利用verilog硬件编程语言实现具体功能,因此数据寄存器和存储器部件内的内容需由程序设计者自己给出,并不能从计算机中直接读取),下面对各个子模块进行简单的介绍。二、各个子模块的简单介绍此程序将数据通路(SingleDataLoad)设定为顶层模块,下面的模块包括:算术逻辑运算单元(ALU)、数据存储器(DataStore)、数据寄存器(Registe
2、rs)、取指令部件(GetCode)、总控制器(Control),通过顶层模块对各个子模块的调用从而实现了整个单周期CPU。1)数据通路(SingleDataLoad):进行数据的运算、读取以及存储功能,通过总控制器产生的各个控制信号,进而实现对数据的各项操作。2)算术逻辑运算单元(ALU):数据通路调用此模块,根据得到的控制信号对输入数据进行处理,处理功能有:addu、add、or、subu、sub、sltu、slt等。3)数据存储器(DataStore):当WrEn控制信号为1时,此时就将输入数据存储到此存储器中,当WrEn为0时,则根据输入的地址,找到地址对应的单元将单元中的数据输出。4
3、)数据寄存器(Registers):在此程序中功能和实现基本和数据存储器相同,但在实际CPU当中使用的逻辑器件及获取数据的方式还是有所区别的。5)取指令部件(GetCode):指根据PC所提供的地址从指令寄存器中取出要执行的指令,再根据各控制信号,得出下一次要执行的指令的地址。(注:指令寄存器中存放的就是一个程序或一段代码所需要执行的指令,这里也是程序设计者自己给出的一些指令的值。)6)总控制器(Control):总控制器通过从取指令部件获得的指令,进而产生各个控制信号,并将控制信号返回个数据通路,就此实现各项功能。(以上各个模块代码见附录)三、程序截图及说明上图为执行下列指令产生的图像:(此
4、时$1,$2所指的寄存器中存放的值是不同的)(beq rs rt imm16:指令的功能为:CondRrs-Rrt if(Cond eq 0)PCPC+(SignExt(imm16)*4)Mem0=6b000100,5b00001,5b00010,5b00000,5b00000,6b000001; /beq $1,$2,1Mem4=6b000000,5b00001,5b00010,5b00100,5b00000,6b101011; /sltu $4,$1,$2 Mem8=6b000010,5b00000,5b00000,5b00000,5b00000,6b000010; /j 2当$1、$2所
5、指的寄存器的值相同时,执行上述指令,得到的图如下:可以看出CPU跳过了第二条指令,直接执行了第三条,而上图执行了第一条指令后接着执行第二条,最后才执行第三条指令,区别就在于第一幅图表示的是$1、$2中的值不相等所执行的情况,第二幅图表示的是$1、$2中的值相等的情况,由此可以得知测试正确。四、实验收获及感想说实话,关于单周期CPU的设计,我没有能够完全理解,原因是我没有把书上的内容认真看,老师上课讲的时候,并没有能够完全掌握,加之课外由于种种原因,自己没有抓紧时间,没有跟上老师的节奏。希望老师给我一点时间,我会努力跟上的。附件:数据通路(SingleDataLoad)module Single
6、DataLoad(clk,RegWr,RegDst,ExtOp,ALUSrc,Branch,Jump,MemtoReg,MemWr,ALUctr);input clk;/input31:0 Instruction;output RegWr,RegDst,ExtOp,ALUSrc,Branch,Jump,MemtoReg,MemWr;output2:0 ALUctr;wire RegWr,RegDst,ExtOp,ALUSrc,Branch,Jump,MemtoReg,MemWr;wire2:0 ALUctr;wire 31:0 Instruction;wire 4:0 Rd,Rt,Rs;wir
7、e 5:0 op,func;wire4: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=Instruction31:26;assign func=Instruction5:0;assign Rs=Instruction25:21;assign Rt=Instruct
8、ion20:16;assign Rd=Instruction15:11;assign imm16=Instruction15:0;assign P1=P2&RegWr;MUX2 mux2(RegDst,Rt,Rd,Rx);assign busB1=16imm1615 & ExtOp,imm1615: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=!Overflo
9、w;DataStore datas(clk,busB,out14: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;output31:0 Z;reg 31:0 Z;always(op) begin if(op=1) Z=Y; else Z=X; endendmodulemodule MUX2(op,x,y,z);input
10、 op;input 4:0 x,y;output4:0 z;reg 4:0 z;always(op) begin if(op=1) z=y; else z=x; endendmodule算数逻辑运算单元(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,OVct
11、r,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=ALUctr2; assign OVctr=!ALUctr1 & ALUctr0; assign SIGctr=ALUctr0; assign OPctr1=ALUctr2 & ALUctr1; assign OPctr0=!ALUctr2 & ALUctr1 &!ALUctr0; assign H=BnSUBctr; assign M=A|B; Adderk nbit_
12、add(SUBctr,A,H,Add_carry,Add_Sign,Add_Result,Zero); /,Add_Overflow assign Add_Overflow= An-1 & Hn-1 & !Add_Resultn-1 | !An-1 & !Hn-1 & Add_Resultn-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); MUX3
13、to1 nbit_Result(Add_Result,M,N,OPctr,Result);endmodulemodule 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;
14、 /,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_result31=1) Add_sign=1; else Add_sign=0; endendmodulemodule 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 (
15、V or W or U or Selm) case(Selm) 2b00: F = V; 2b01: F = W; 2b10: F=U; endcase endmodule module IMUX2to1 (V,W,SIGctr,Less); input31:0 V,W; input SIGctr; output31:0 Less; reg31:0 Less; always (V or W or SIGctr) if (SIGctr = 0) Less = V; else Less = W;endmodule数据存储器(DataStore):module DataStore(clk,DataI
16、n,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) StoreAdr=DataIn; endalways(Adr or WrEn) if(WrEn=0) Out=StoreAdr; endmodule数据寄存器(Registers): module Registers(clk,busW,wr,Rw,Ra,Rb,busA,busB);input 31:0
17、 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 Regist1=32d25; Regist2=32d25; if(wr=0) RegistRw=busW; endalways(Ra or Rb or wr) begin if(wr=1) begin busA=RegistRa; busB=RegistRb; end endendmodule取指令部件(GetCode):module GetCo
18、de(Branch,Zero,Jump,clk,Instruction);input Zero,Branch,Jump,clk;output31:0 Instruction;reg29:0 PC=25;wire29:0 M,M2;wire 4:0 addmem;wire K;reg reset=1;assign addmem=PC2:0,2b00;wire29:0 O1,O2,O3,O4;wire15:0 imm16;instruct InsMem(addmem,Instruction);always(negedge clk) begin if (reset=1) begin PC =0; r
19、eset=0; end else begin PC = O4; end endassign imm16=Instruction15:0;assign M=PC;assign K=Zero & Branch;Adder adder1(M,1,O1);assign M1=14imm1615,imm1615:0;Adder adder2(O1,M1,O2);MUX2T1 mux1(K,O1,O2,O3);assign M2=M29:26,Instruction25:0;MUX2T1 mux2(Jump,O3,M2,O4);endmodulemodule Adder(M,N,O);input29:0
20、M;input29:0 N;output29:0 O;wire29:0 M,N,O;assign O=M+N;endmodule module MUX2T1(op,X,Y,Z);input op;input 29:0 X,Y;output29:0 Z;reg 29:0 Z;always(op) begin if(op=1) Z=Y; else Z=X; endendmodulemodule instruct(addr,inst); input 4:0 addr; output 31:0 inst; reg 31:0 inst;/ Declare the RAM variable reg 31:
21、0 Mem 31:0;/ write instruction: add 3=(1)+(2),sub 6=(4)-(5),jump 0 always (*) begin/Mem0=6b000000,5b00001,5b00010,5b00011,5b00000,6b100000; /add $3,$1,$2/ Mem4=6b000000,5b00011,5b00001,5b00100,5b00000,6b100010; /sub $4,$3,$1/ Mem0=6b000000,5b00001,5b00010,5b00011,5b00000,6b101010; /slt $3,$1,$2/ Mem
22、4=6b000000,5b00011,5b00001,5b00100,5b00000,6b100011; /subu $4,$3,$1/ Mem0=6b000000,5b00001,5b00010,5b00011,5b00000,6b101010; /slt $3,$1,$2/ Mem4=6b000000,5b00001,5b00010,5b00100,5b00000,6b101011; /sltu $4,$1,$2/Mem0=6b001101,5b00001,5b00011,5b10000,5b00000,6b000101; /ori $3,$1,32773/ Mem4=6b001001,5
23、b00010,5b00100,5b00000,5b00000,6b001000; /addiu $4,$2, 8/ Mem4=6b001001,5b00010,5b00100,5b11111,5b11111,6b111000; /addiu $4,$2, -8/ Mem0=6b101011,5b00001,5b00011,5b00000,5b00000,6b000101; /sw $3,$1,5/ Mem4=6b100011,5b00001,5b00100,5b00000,5b00000,6b000101; /lw $4,$1,5 Mem0=6b000100,5b00001,5b00010,5
24、b00000,5b00000,6b000001; /beq $1,$2,1 Mem4=6b000000,5b00001,5b00010,5b00100,5b00000,6b101011; /sltu $4,$1,$2 Mem8=6b000010,5b00000,5b00000,5b00000,5b00000,6b000010; /j 2 end/ read always (addr) begin inst = Memaddr; endendmodule总控制器(Control):module Control(Instruction,RegWr,ExtOp,ALUSrc,ALUctr,Branc
25、h,Jump,RegDst,MemtoReg,MemWr);output RegWr,RegDst,ExtOp,ALUSrc,Branch,Jump,MemtoReg,MemWr;input31: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=Instruction31:26;assign func=Instruction5:0;parameter S0=6b100000,S
26、1=6b100010,S2=6b100011,S3=6b101010,S4=6b101011,S5=6b001101,S6=6b001001,S7=6b100011,S8=6b101011,S9=6b000100,S10=6b000010;always(op or func)begin if(op=6b000000) begin case(func) S0: begin Branch=0; Jump=0; RegDst=1; ALUSrc=0; ALUctr=3b001; MemtoReg=0; RegWr=1; MemWr=0; end S1: begin Branch=0; Jump=0;
27、 RegDst=1; ALUSrc=0; ALUctr=3b101; MemtoReg=0; RegWr=1; MemWr=0; end S2: begin Branch=0; Jump=0; RegDst=1; ALUSrc=0; ALUctr=3b100; MemtoReg=0; RegWr=1; MemWr=0; end S3: begin Branch=0; Jump=0; RegDst=1; ALUSrc=0; ALUctr=3b111; MemtoReg=0; RegWr=1; MemWr=0; end S4: begin Branch=0; Jump=0; RegDst=1; ALUSrc=0; ALUctr=3b110; MemtoReg=0; RegWr=1; MemWr=0; end endcase end else begin case(op) S5: begin Branch=0; Jump=0; RegDst=0; ALUSrc=1; ALUctr=3b010; MemtoReg=0; RegWr=1; MemWr=0; ExtOp=0; end S6: begin Branch=0; Jump=0;