简体   繁体   中英

Weird behavior of registers on Quartus II using Verilog

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

波形 1

波形 2

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM