Registrieren Sie die Datei für den MIPS-Prozessor

Ich schreibe Code für die Registerdatei (32 Register mit jeweils 32 Bit) für den MIPS-Single-Cycle-Prozessor. Ich möchte, dass am negativen Rand der Uhr geschrieben wird. Wie üblich kann das Lesen jederzeit erfolgen (sobald es eine richtige Registernummer erhält). Da unten ist der Code dafür:

module regfile(clk,reset,ReadReg1, ReadReg2, WriteData, WriteReg, RegWrite, ReadData1, ReadData2);
    input clk, reset;
    input [4:0] ReadReg1, ReadReg2, WriteReg;
    input [31:0] WriteData;
    input RegWrite;
    output[31:0] ReadData1, ReadData2;

    //Register File has 32 registers. This module has access to each register through the RegFile array of nets
    wire [32*32-1:0] RegFileAcc;
    wire [0:31] decOut;
    wire [0:31] regClk;
    dec_5to32 dec1(decOut,WriteReg);

    //Creating 32 memory cells, each is a 32 bit register (made up of 32 DFFs)
    genvar j;
    generate for(j=0;j<32;j=j+1)
                begin: regFile
                    assign regClk[j]=(clk & RegWrite & decOut[j]);
                    reg_32bit r1(RegFileAcc[(32*(j+1))-1:32*j],WriteData,regClk[j],reset);
                end
    endgenerate

    //The reading part
    bit32_mux32to1 mux1(ReadData1,RegFileAcc,ReadReg1);
    bit32_mux32to1 mux2(ReadData2,RegFileAcc,ReadReg2);
endmodule

Hier ist der Code für das 32-Bit-Register:

module reg_32bit(q,d,clk,reset);
    input [31:0] d;
    input clk,reset;
    output [31:0] q;
    genvar j;
    generate for(j=0;j<32;j=j+1)
                begin: reg_loop
                dff d1(q[j],d[j],clk,reset);
                end
    endgenerate
endmodule

Der Code für DF/F lautet:

module dff(q,d,clk,reset);
    input d,clk,reset;
    output q;
    reg q;
    //active low reset
    //we can read the dff using q

    always @(negedge clk)
    begin
        if(reset)
            q<=d;
        else
            q<=1'b0;
    end
endmodule

Ich habe eine Testbench implementiert, um die Registerdatei zu testen. Aber ich bekomme eine unerwartete Ausgabe:

Testbench-Code:

module testbench;
    reg [4:0] ReadReg1, ReadReg2, WriteReg;
    reg [31:0] WriteData;
    reg RegWrite,clk,reset;

    wire [31:0] ReadData1, ReadData2;

    regfile rf1(clk,reset,ReadReg1,ReadReg2,WriteData,WriteReg,RegWrite,ReadData1,ReadData2);

    initial
        forever #5 clk=~clk;

    initial 
    begin
        $monitor($time," ReadReg1=%2b ReadReg2=%2b WriteReg=%2b WriteData=%8h ReadData1=%8h ReadData2=%8h \n RegFile=%32h\n",ReadReg1,ReadReg2,WriteReg,WriteData,ReadData1,ReadData2,rf1.RegFileAcc);

                clk=1'b0;
                reset=1'b0;
                RegWrite=1'b0;

        #12     reset=1'b1;
        #6      WriteReg=5'b00000;
                WriteData=32'hAFAFAFAF;
                ReadReg1=5'b00000;
                ReadReg2=5'b00010;
                RegWrite=1'b1;

        #10     WriteReg=5'b00001;
                WriteData=32'hBBBBBBBB;

        #10     WriteReg=5'b00010;
                WriteData=32'hCCCCCCCC;

        #100    $finish;
    end
endmodule

dec_5to32 ist der Decoder 5*32. bit32_mux32to1 ist Mux 32 zu 1 (jeder Eingang hat 32 Bit). Ich habe sie überprüft, sie funktionieren einwandfrei. Auch reg_32bit und dff funktionieren gut.

Das Bild der Simulation von RegFile

Was ist Ihre eigentliche Frage? Debugging-Fragen auf Stack-Exchange-Sites müssen ausdrücklich den Unterschied zwischen der erwarteten Ausgabe und der erzeugten Ausgabe angeben. Außerdem ist Text Text, bitte verwenden Sie keine Screenshots
Clock Gating - SEHR schlechte Praxis, wenn es für FPGA ist ....

Antworten (1)

Ich werde meinen Kommentar in eine Antwort umwandeln.

  1. Ich empfehle Ihnen dringend, eine Wellenformanzeige zum Debuggen zu verwenden. Sie können HDL-Code nicht mehr mit $display- und $write-Anweisungen debuggen, sobald Sie triviale Beispiele hinter sich gelassen haben.

  2. Mir ist aufgefallen, dass Ihre Uhr und Ihre Daten die gleiche Verzögerung haben: Die Uhr ändert sich alle #5 und Ihre Daten bei #10 und #100. Ihre Taktflanken und Ihr Signal kommen zur gleichen Zeit an, was ein Rezept für eine Katastrophe ist.

  3. Sofern dies keine Schulaufgabe ist, die dies verbietet, sollten Sie HDL-Konstrukte verwenden (ich verwende andere Namen, aber Sie sollten das Wesentliche verstehen).

    reg  [31:0] regbank [0:3];
    wire  [1:0] write_index,read1_index,read2_index;
    wire [31:0] write_data;
    ..
       if (WriteReg)
          regbank[write_index] <= write_data;
       read_data1 <= regbank[read1_index];
       read_data2 <= regbank[read2_index];
    ..
  1. Das Entwerfen von Logik für steigende und fallende Flanken sollte nur als letzter Ausweg und nur dann verwendet werden, wenn Sie wirklich wissen, was Sie tun. In normaler Ausführung ist es ein großes NEIN NEIN!

Im obigen Beispiel können Sie die Weiterleitung wie folgt schreiben:

   if (write_index==read1_index)
      read_data1 <= write_data
   else
      read_data1 <= regbank[read1_index];
   if (write_index==read2_index)
   ....
Ja, eigentlich ist es eine Aufgabe (Entwurf eines Single-Cycle-MIPS-Prozessors). Ich habe die Verzögerung für Daten auf #8 geändert, aber ich habe immer noch das gleiche Problem.
Ich kann Ihnen nicht viel mehr raten, ohne für Sie zu arbeiten. Als letzter Tipp: Das Gaten einer Uhr ist generell auch eine schlechte Idee, besonders wenn sie auf einem FPGA laufen muss.regClk[j]=(clk & RegWrite...