Registrar archivo para procesador MIPS

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.

La imagen de Simulación de RegFile

¿Cuál es tu pregunta real? Las preguntas de depuración en los sitios de intercambio de pilas deben indicar específicamente la diferencia entre la salida esperada y la salida producida. Además, el texto es texto, no uses capturas de pantalla.
activación del reloj --MUY mala práctica si es para fpga....

Respuestas (1)

Convertiré mi comentario en una respuesta.

  1. 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.

  2. 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.

  3. 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];
    ..
  1. El diseño de la lógica en los flancos ascendentes y descendentes debe usarse solo como último recurso y solo si realmente sabe lo que está haciendo. ¡En el diseño normal es un gran NO NO!

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)
   ....
Sí, en realidad es una tarea (diseñar un procesador MIPS de ciclo único). Cambié el retraso de los datos al n. ° 8, pero sigo teniendo el mismo problema.
No puedo aconsejarle mucho más que esto sin trabajar para usted. Como último consejo: controlar un reloj generalmente también es una mala idea, especialmente si tiene que ejecutarse en un FPGA.regClk[j]=(clk & RegWrite...