单周期CPU实验报告

计算机组成实验报告

实验名称:单周期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

相关推荐