I'm creating my own processor based on MIPS32 using the Quartus II and Verilog. Everything was working fine until suddenly my Registers stopped working (I don't remember making any modifications to the code). I probably made some mistake but I can't seem to find it.
I've already tried using an older version of the code (that was 100% working) but the error persists, even when I'm testing the registers isolated from the rest of the system. I've also tried deleting Quartus' temporary files and recompiling with no success.
module RegFile
(
output [31:0] Debug2, //Outputs Reg 2
output [31:0] Debug3, //Outputs Reg 3
input Reset, //Makes sure Reg 0 is always 0
input Slow_Clock, //Write Clock
input Fast_Clock, //Read Clock
input Reg_Write, //Write to Reg Flag
input [31:0] Write_Data, //Data that will be written in the Reg selected by Reg_WR
input [5:0] Reg_1, //First Register Selection (Read)
input [5:0] Reg_2, //Second Register Selection (Read)
input [5:0] Reg_WR, //Third Register Selection (Read or Write)
output reg [31:0] Data_1, //Data that will outputted by the Reg selected by Reg_1
output reg [31:0] Data_2, //Data that will outputted by the Reg selected by Reg_2
output reg [31:0] Data_3 //Data that will outputted by the Reg selected by Reg_WR
);
reg [31:0] DataReg[63:0]; //64x 32bit Register
assign Debug2 = DataReg[2]; //Hardwired Reg2 (for testing)
assign Debug3 = DataReg[3]; //Hardwired Reg3 (for testing)
always @ (posedge Fast_Clock) //Reads from Registers at posedge Read Clock
begin
Data_1 <= DataReg[Reg_1];
Data_2 <= DataReg[Reg_2];
Data_3 <= DataReg[Reg_WR];
end
always @ (negedge Slow_Clock) //Writes on Registers at negedge Write Clock
begin
if (Reset)
begin
DataReg[0] <= 32'b00000000_00000000_00000000_00000000; //Forces Reg0 to be 0 when Reset is activated
end
else if (Reg_Write && (Reg_WR != 0)) //If you are writing to some register and this register isn't Reg0...
begin
DataReg[Reg_WR] <= Write_Data; //...write to the register selected by Reg_WR
end
end
endmodule
I expect the ending result to be the number 3 on register 2 and the number 4 on register 3 but, as you can see, register 2 ends with the number 4 and the register 3 ends with the number 0.
I figured it out.
There was an inconsistency when writing and loading the new values in the next clock.
I fixed it by creating two aux. variables that hold Write_Data and Reg_WR until right before writing and updating the values. I used a faster clock to be able to keep these aux. variables updated.
This is the solution I found:
module RegFile
(
//output [31:0] Debug2, //Outputs Reg 2
output [31:0] Debug3, //Outputs Reg 3
input Reset, //Makes sure Reg 0 is always 0
input Slow_Clock, //Write Clock
input Fast_Clock,
input Reg_Write, //Write to Reg Flag
input [31:0] Write_Data, //Data that will be written in the Reg selected by Reg_WR
input [5:0] Reg_1, //First Register Selection (Read)
input [5:0] Reg_2, //Second Register Selection (Read)
input [5:0] Reg_WR, //Third Register Selection (Read or Write)
output [31:0] Data_1, //Data that will outputted by the Reg selected by Reg_1
output [31:0] Data_2, //Data that will outputted by the Reg selected by Reg_2
output [31:0] Data_3 //Data that will outputted by the Reg selected by Reg_WR
);
reg [31:0] RegBank[63:0];
reg [31:0] Aux_WD;
reg [5:0] Aux_Reg;
assign Data_1 = RegBank[Reg_1];
assign Data_2 = RegBank[Reg_2];
assign Data_3 = RegBank[Reg_WR];
//assign Debug2 = RegBank[2];
assign Debug3 = RegBank[3];
always @ (negedge Fast_Clock)
begin
Aux_WD <= Write_Data;
Aux_Reg <= Reg_WR;
end
always @ (negedge Slow_Clock)
begin
if (Reset)
begin
RegBank[0] <= {32{1'b0}};
end
else if (Reg_Write && (Aux_Reg != 6'b000000))
begin
RegBank[Aux_Reg] <= Aux_WD;
end
end
endmodule