执行单周期 mips 处理器时出现程序计数器错误

Program counter error while implement single cycle mips processor

我正在尝试使用 Verilog 实现单周期 mips 处理器,但我在尝试测试代码时遇到了问题,似乎程序计数器在第一个周期后没有增加,但我做不到找出问题所在。

这是我的程序计数器和指令存储器的组件代码

程序计数器

module ProgramCounter(
input CLK,
input reset,
input [31:0]PCin,
output reg [31:0]PCout
);

always @(posedge CLK, posedge reset)
    begin
    PCout <= PCin+4;
        if(reset)
            PCout <= 0;
    end
endmodule

指令记忆

module InstructionMemory(
input CLK,
input [31:0] Address,
output reg [31:0] Instr
);

reg [31:0] RAM[16:0];
initial 
    begin
        RAM[0]  <= 32'h22300004; //addi
        RAM[4]  <= 32'h22310003; //add
        RAM[8]  <= 32'h02119020; //and
        RAM[12]  <= 32'h0250a824; //or
        RAM[16]  <= 32'h0211b822; //sub
    end
always @(posedge CLK)
    begin
        Instr <= RAM[Address];
    end
endmodule

这是包含所有组件的 MIPS 代码

    module MIPS(
    input  CLK,
    input  reset,
    output wire [31:0] PCin, 
    output wire [31:0] PCout,
    output wire [31:0] instruction,
    output wire memtoreg,memwrite,branch,alusrc,regdst,regwrite,jump,
    output wire [2:0] alucontrol,
    output wire [4:0] WriteReg,
    output wire[31:0] ReadData1,
    output wire[31:0] ReadData2,
    output wire[31:0] WriteDataReg,
    output wire[31:0] SignExtend,
    output wire[31:0] ALU_B,
    output wire[31:0] ShiftOut,
    output wire[31:0] ALUOut,
    output wire Zero,
    output wire [31:0]Add_ALUOut,
    output wire AndOut,
    output wire [31:0] ReadData
    );
    
//Program Counter
ProgramCounter pc(
    //inputs
        .CLK(CLK),
        .reset(reset),
        .PCin(PCin),
    //outputs
        .PCout(PCout)
);

//Instruction Memory
InstructionMemory instrmem(
    //inputs
    .CLK(CLK),
    .Address(PCout),
    //outputs
    .Instr(instruction)
);

//Control Unit
Control Controller
( 
    //inputs
    .OPcode(instruction[31:26]),
    .func(instruction[5:0]),
    //outputs
    .memtoreg(memtoreg),
    .memwrite(memwrite),
    .branch(branch),
    .alusrc(alusrc),
    .regdst(regdst),
    .regwrite(regwrite),
    .jump(jump),
    .alucontrol(alucontrol)
);

//MUX between instr and reg
MUX1 mux1
(
    //inputs
    .instr1(instruction[20:16]),
    .instr2(instruction[15:11]),
    .regdst(regdst),
    //output
    .WriteReg(WriteReg)
);

//Register File
RegisterFile regfile
(
    //inputs
    .CLK(CLK),
    .WE3(regwrite),
    .RA1(instruction[25:21]),
    .RA2(instruction[20:16]),
    .WA3(WriteReg),
    .WD3(WriteDataReg),
    //outputs
    .RD1(ReadData1),
    .RD2(ReadData2)
);

//Sign Extend
signextend sign_extend
(
    //inputs
    .A(instruction[15:0]),
    //outputs
    .Y(SignExtend)
);

//MUX between reg and ALU
MUX2 mux2
(
    //inputs
    .alusrc(alusrc),
    .RA2(ReadData2),
    .Extend(SignExtend),
    //outputs
    .ALU2(ALU_B)
);

//Shift Left
ShiftLeft Shift_Left
(
    //inputs
    .ShiftIn(SignExtend),
    //outputs
    .ShiftOut(ShiftOut)
);

//ALU
ALU mainALU
(
    //inputs
    .A(ReadData1),
    .B(ALU_B),
    .ALUcontrol(alucontrol),
    //outputs
    .ALUOut(ALUOut),
    .Zero(Zero)
);

//Addition ALU
ALUaddition addALU
(
    //inputs
    .PCout(PCout),
    .ShiftOut(ShiftOut),
    //outputs
    .Add_ALUOut(Add_ALUOut)
);

//And Gate
AND andGate
(
    //inputs
    .Branch(branch),
    .Zero(Zero),
    //outputs
    .Out(AndOut)
);

//MUX for PC
MUX4 mux4
(
    //inputs
    .PCout(PCout),
    .ADD_ALUOut(Add_ALUOut),
    .ANDOut(AndOut),
    //outputs
    .PCin(PCin)
);

//DataMemory
DataMemory datamemory
(
    //inputs
     .CLK(CLK),
     .WE(memwrite),
     .WD(ReadData2),
     .A(ALUOut),
    //outputs
    .RD(ReadData)
);

//MUX after DataMemory
MUX3 mux3
(
    //inputs
    .RD(ReadData),
    .ALUOut(ALUOut),
    .memtoreg(memtoreg),
    //outputs
    .WriteData(WriteDataReg)
);
endmodule

这是我写的测试平台

module Test();
reg CLK;                                                        
reg reset;                                                      
wire [31:0] PCin;                                           
wire [31:0] PCout;                                          
wire [31:0] instruction;                                    
wire memtoreg;
wire memwrite;
wire branch;
wire alusrc;
wire regdst;
wire regwrite;
wire jump;  
wire [2:0] alucontrol;                                      
wire [4:0] WriteReg;                                        
wire[31:0] ReadData1;                                       
wire[31:0] ReadData2;                                       
wire[31:0] WriteDataReg;                                    
wire[31:0] SignExtend;                                      
wire[31:0] ALU_B;                                           
wire[31:0] ShiftOut;                                        
wire[31:0] ALUOut;                                          
wire Zero;                                                  
wire [31:0]Add_ALUOut;                                      
wire AndOut;                                                
wire [31:0] ReadData;

MIPS mips(CLK,reset,PCin,PCout,instruction,memtoreg,memwrite,branch,alusrc,regdst,regwrite,jump,alucontrol,WriteReg,ReadData1,ReadData2,WriteDataReg,SignExtend
,ALU_B,ShiftOut,ALUOut,Zero,Add_ALUOut,AndOut,ReadData);

initial
begin
    CLK = 0;
    reset = 1;
    #5 
    reset = 0;
    #5
    forever #5 CLK = ~CLK;
end                                 
endmodule

现在当我看模拟时,看起来是这样的,程序计数器只在第一个周期初始化,然后就变得无关紧要了

在下面的 PCout <= PCin+4; 中 — PCin 在哪里给定了一个值?我在任何地方都看不到。

PCin 在我看来就像一个未初始化的变量,所以 PCout 变成了未初始化的 + 4,这仍然是未知的。我本来希望在某处看到类似 PCin <= PCout 的东西。

不过,我也不确定为什么到处都是 PCinPCout 而不是只有一个 PC。当然,您可能想区分 some 模块中的输入和输出,但在其他情况下,我认为它是同一个寄存器。