使用 Verilog 的 Quartus II 上寄存器的奇怪行为
Weird behavior of registers on Quartus II using Verilog
我正在使用 Quartus II 和 Verilog 创建自己的基于 MIPS32 的处理器。一切正常,直到我的寄存器突然停止工作(我不记得对代码进行过任何修改)。我可能犯了一些错误,但我似乎找不到它。
我已经尝试使用旧版本的代码(100% 有效)但错误仍然存在,即使我正在测试与系统其余部分隔离的寄存器。我也试过删除 Quartus 的临时文件并重新编译但没有成功。
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
我希望最终结果是寄存器 2 上的数字 3 和寄存器 3 上的数字 4,但是,如您所见,寄存器 2 以数字 4 结尾,而寄存器 3 以数字 0 结尾。
我想通了。
在下一个时钟写入和加载新值时出现不一致。
我通过创建两个辅助来修复它。保持 Write_Data 和 Reg_WR 直到写入和更新值之前的变量。我使用了更快的时钟来保持这些辅助。变量已更新。
这是我找到的解决方案:
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
我正在使用 Quartus II 和 Verilog 创建自己的基于 MIPS32 的处理器。一切正常,直到我的寄存器突然停止工作(我不记得对代码进行过任何修改)。我可能犯了一些错误,但我似乎找不到它。
我已经尝试使用旧版本的代码(100% 有效)但错误仍然存在,即使我正在测试与系统其余部分隔离的寄存器。我也试过删除 Quartus 的临时文件并重新编译但没有成功。
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
我希望最终结果是寄存器 2 上的数字 3 和寄存器 3 上的数字 4,但是,如您所见,寄存器 2 以数字 4 结尾,而寄存器 3 以数字 0 结尾。
我想通了。
在下一个时钟写入和加载新值时出现不一致。
我通过创建两个辅助来修复它。保持 Write_Data 和 Reg_WR 直到写入和更新值之前的变量。我使用了更快的时钟来保持这些辅助。变量已更新。
这是我找到的解决方案:
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