Estoy escribiendo código para el archivo de registro (32 registros, cada uno de 32 bits) para el procesador de ciclo único MIPS. Quiero que la escritura suceda en el borde negativo del reloj. Como de costumbre, la lectura puede ocurrir en cualquier momento (tan pronto como obtenga un número de registro adecuado). A continuación se muestra el código para esto:
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
Aquí está el código para el registro de 32 bits:
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
El código para DF/F es:
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
He implementado un banco de pruebas para probar el archivo de registro. Pero estoy obteniendo un resultado inesperado:
Código del banco de pruebas:
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 es el decodificador 5*32. bit32_mux32to1 es mux 32 a 1 (cada entrada es de 32 bits). Los he revisado, funcionan bien. Además, reg_32bit y dff también funcionan bien.
Convertiré mi comentario en una respuesta.
Le sugiero enfáticamente que comience a usar una pantalla de forma de onda para la depuración. No puede depurar el código HDL con declaraciones $display y $write una vez que haya superado ejemplos triviales.
Noté que su reloj y datos tienen el mismo retraso: el reloj cambia cada #5 y sus datos en #10 y #100. Los bordes de su reloj y la señal llegan al mismo tiempo, lo cual es una receta para el desastre.
A menos que esta sea una tarea escolar que lo prohíba, debe usar construcciones HDL (estoy usando nombres diferentes, pero debe entender la esencia)
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];
..
En el ejemplo anterior, puede hacer un reenvío de escritura de esta manera:
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