Reputation: 21
I'm trying to implement single cycle mips processor using Verilog and I'm facing a problem while trying to test the code, it seems like the program counter isn't increasing after the first cycle but I can't figure out what is wrong.
This is my component code of the Program counter and Instruction Memory
Program Counter
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
Instruction Memory
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
And this is the MIPS code that have all the components
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
And this is the test bench that I wrote
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
Now when I look at the simulation, this is how at looks, the program counter only gets initialized the first cycle and then it becomes don't care
Upvotes: 0
Views: 454
Reputation: 26646
In the following PCout <= PCin+4;
— where is PCin
given a value? I don't see that anywhere.
PCin
looks to me like an uninitialized variable, so PCout
becomes uninitialized + 4, which is still unknown. I would have expected to see something like PCin <= PCout
somewhere.
Though alternately, I'm also not sure why there's both PCin
and PCout
everywhere instead of just one PC
. Sure you may want to differentiate between the in and the out in some modules, but in other cases I'm thinking its one and the same register.
Upvotes: 2