执行单周期 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
的东西。
不过,我也不确定为什么到处都是 PCin
和 PCout
而不是只有一个 PC
。当然,您可能想区分 some 模块中的输入和输出,但在其他情况下,我认为它是同一个寄存器。
我正在尝试使用 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
的东西。
不过,我也不确定为什么到处都是 PCin
和 PCout
而不是只有一个 PC
。当然,您可能想区分 some 模块中的输入和输出,但在其他情况下,我认为它是同一个寄存器。