单周期MIPS处理器指令执行

时间:2016-08-10 00:02:30

标签: mips verilog

我正在这个单周期MIPS处理器中执行六条指令。 我无法在ALU模块中找出错误。 我试图执行的六条指令是:Add,Sub,AND,OR,Load,Store 现在,我只得到正确的结果。

在五位MUX中,我给出了一个输入' a'和' b'。我怎样才能将这些输入联系起来' a'和' b'指令源和引爆寄存器。

另外,如何在执行每条指令后添加4个字节(即我的程序计数器无法递增)。

   //ALU Block
    module ALU (FunctField,ReadData1,out_inALU, ALUOp,ctr1,result);
    input ALUOp;
    input [5:0]FunctField;
    input [31:0] ReadData1;
    input [31:0] out_inALU;
    output  [2:0] ctr1;
    reg [2:0] ctr1;
    output [31:0] result;
    reg  [31:0] result;
    always @(*)
    begin
    if(ALUOp == 1)      //Arithmetic' Type Instructions
    begin
  case(FunctField)        
  //begin
    6'b100000: ctr1 = 3'b010;    //ADDITION in 'R' Type
    6'b100010: ctr1 = 3'b110;    // SUBTRACTION in 'R' Type
    6'b100100: ctr1 = 3'b000;     // AND in 'R' Type
    6'b100101: ctr1 = 3'b001;    //  OR in 'R' Type
  endcase
end

if(ALUOp == 0)
begin     //   LW/SW Type Instructions
    if (ctr1 == 3'b010)
        result = ReadData1 + out_inALU ;
    else if (ctr1 == 3'b110)
        result = ReadData1 - out_inALU ;
    else if (ctr1 == 3'b000)
        result = ReadData1 & out_inALU ;
    else if (ctr1 == 3'b001)
        result = ReadData1 | out_inALU;
    end 
result = ReadData1 | out_inALU ;
end
endmodule


// Data memory
   module data_memory (ReadAddr, WriteAddr, WriteData1, clock, 
            MemWrite, MemRead,ReadData);

   input    [31:0] ReadAddr, WriteAddr, WriteData1;
   input    clock, MemWrite, MemRead;
   reg  [31:0] mem[0:50];       // For simulation this no. is enough
   reg  [31:0] i;           // Temporary variable
   output   [31:0] ReadData;
   reg  [31:0] ReadData;

   initial
   begin
   //   Initial read-out
   ReadData = 0;
   //   Initial memory content for testing purpose
   for ( i = 0; i <= 50; i = i+1)
        mem[i] = i;
   end

  //      Memory content is always fetched with positive edge clock
  always @(posedge clock)
  begin
  wait ( MemRead )
    #10 ReadData = mem[ReadAddr];
  wait ( MemWrite )
    #10 mem[WriteAddr] = WriteData1;
  end

  endmodule


 //   Instruction Memory
   module inst(addr,clock,instruction);
   input clock;
   input [ 31 : 0 ] addr;
   output [ 31 : 0 ] instruction;
   reg [ 31 : 0 ] instruction;
   reg [ 31 : 0 ] MEM[0 :31 ] ;
   initial
   begin
   MEM[ 0 ] <= 32'h10000011;
   MEM[ 1 ] <= 32'h10000011 ;
   MEM[ 2 ] <= 32'h20000022 ;
   MEM[ 3 ] <= 32'h30000033 ;
   MEM[ 4 ] <= 32'h40000044 ;
   MEM[ 5 ] <= 32'h50000055 ;
   MEM[ 6 ] <= 32'h60000066 ;
   MEM[ 7 ] <= 32'h70000077 ;
   MEM[ 8 ] <= 32'h80000088 ;
   MEM[ 9 ] <= 32'h90000099 ;
   end
   always @( posedge clock )
   begin
   instruction <= MEM[ addr ] ;
   end
   endmodule


    //Main module
      module(reset, clock, regwrite,regDst,ALUSrc,MemtoReg,MemWrite,MemRead, input_PC)    
     input  reset,clock;
     input  regWrite;
     input  regDst;
     input  ALUSrc;
     input  MemtoReg;
     input  MemWrite;
     input  MemRead;
     input  [31:0] input_PC;

     wire [4:0] ReadReg1, ReadReg2, WriteReg;
     wire [31:0] WriteData;

    // Instantiation of modules
    //Program Counter

    wire [31:0] addr;
    PC x1(input_PC,clock,reset,addr);

    // Instruction Memory
    wire [31:0] instruction; 
    inst x2(addr,clock,instruction);

    //Multiplexer with regDst
    reg[4:0] inputa,inputb;
    MUX_2to1_5bit x3(inputa,inputb,regDst,WriteReg);

    //Register File

    wire [31:0] ReadData1,ReadData2;
    Register_32 x4 ( ReadReg1, ReadReg2, WriteReg, WriteData, clock,
    RegWrite,ReadData1, ReadData2);


    //Sign Extender

    wire [31:0] out_sign;
    SignExtender_16to32 x5(immediate, out_sign);

     //Multilpexer ALUSrc
     wire [31:0] out_inALU;
    MUX_2to1 x6( ReadData2 , out_sign, ALUSrc,out_inALU );

    //ALU
    wire [31:0] result;
    wire [2:0] ctr1;
    ALU x7 (FunctField,ReadData1,out_inALU, ALUOp,ctr1,result);

    //Data Memory
    reg [31:0]  ReadAddr;
    reg [31:0]  WriteAddr;
    wire [31:0] ReadData;
    data_memory x8(ReadAddr, WriteAddr, WriteData, clock, MemWrite, 

    MemRead,ReadData);

    //Multiplexer MemtoReg
    MUX_2to1_memreg  x9( result,ReadData,MemtoReg,WriteData);
    endmodule

    // Mux2 to 1_32 bit


  module MUX_2to1( ReadData2 , outputData, ALUSrc,out_inALU );
  input [31:0] ReadData2,outputData;
  input ALUSrc;
  output [31:0]out_inALU;
  reg [31:0]out_inALU;

  always @(ReadData2  or outputData or ALUSrc )
    begin
      case(ALUSrc)

          1'b0:   out_inALU=ReadData2;
          1'b1:  out_inALU=outputData;

      endcase
    end
endmodule 

     // Mux 2 to 1 5 bit
    module MUX_2to1_5bit( inputa , inputb, regDst, WriteReg);
      input [4:0] inputa, inputb;
      input regDst;
      output [4:0]WriteReg;
      reg [4:0]WriteReg;

      always @(inputa or inputb or regDst )
        begin 
          case(regDst)

              1'b0:   WriteReg=inputa;
              1'b1:  WriteReg=inputb;

          endcase
        end
     endmodule 



// Mux 2 to 1 for memory register
  module MUX_2to1_memreg( result,ReadData,MemtoReg,WriteData);
  input [31:0] ReadData,result;
  input MemtoReg;
  output [31:0] WriteData;
  reg [31:0]WriteData;

  always @(* )
    begin
      case(MemtoReg)

          1'b0:   WriteData= result ;
          1'b1:  WriteData= ReadData;

      endcase
    end
endmodule 


// Progrma COunter
module PC(input_PC,clock,reset,addr);
input reset,clock;
input [31:0] input_PC;
output reg [31:0] addr;

always @(posedge clock)
begin
if (reset)
addr=0;
else 
addr=input_PC+4;
end
endmodule

//Register

module Register_32 ( ReadReg1, ReadReg2, WriteReg, 
            WriteData, clock, RegWrite,ReadData1, ReadData2);
input [4:0] ReadReg1, ReadReg2, WriteReg;
input [31:0] WriteData;
input   clock, RegWrite;
output  [31:0] ReadData1, ReadData2;
reg [31:0] ReadData1, ReadData2;

reg [31:0] mem[0:31];   // 32 32-bit registers
reg [5:0] i;        // Temporary variable

initial
begin
    //  Initial registers for testing purpose
    for ( i = 0; i <= 31; i = i+1)
        mem[i] = i;
    //  Initial start-up
    ReadData1 = 0;
    ReadData2 = 0;
end

//      Data from register is always fetched with positive edge clock
always @(posedge clock)
begin
    #1 ReadData1 = mem[ReadReg1];
    #1 ReadData2 = mem[ReadReg2];
    if ( RegWrite == 1)
        #1 mem[WriteReg] = WriteData;
end

endmodule


// Sign extender
module SignExtender_16to32(immediate,out_sign);
  input[15:0]  immediate;
  output[31:0] out_sign;
  reg [31:0] out_sign;

  always@(*)
    begin

      out_sign[15:0]  = immediate[15:0];
      out_sign[31:16] = {16{immediate[15]}};

    end
endmodule

1 个答案:

答案 0 :(得分:1)

您可以按如下方式递增程序计数器,但它会包含问题。最好有一个信号来锁存输入地址或复位时add = input_PC;

module PC(input_PC,clock,reset,addr);
input reset,clock;
input [31:0] input_PC;
output reg [31:0] addr;

always @(posedge clock)
begin
if (reset)
addr= 0;
else 
addr=input_PC+4+addr;
end 
endmodule

你会希望mem在读取mem 0之后忽略inst模块中的低2位,它将读取mem [4]。

   instruction <= MEM[ addr[31:2] ] ;

您需要将指令连接到ALU模块,不能提供任何建议,因为我无法确定您的指令解码方案是什么。