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.
Ich werde meinen Kommentar in eine Antwort umwandeln.
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.
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.
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];
..
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)
....
regClk[j]=(clk & RegWrite...
Chris Stratton
Mitu Raj