0
\$\begingroup\$

I am writing code for Register file (32 registers, each of 32 bit) for MIPS Single Cycle processor. I want writing to happen at the negative edge of the clock. As usual, reading can happen any time (as soon as it gets a proper Register No). Given below is the code for this:

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

Here is the code for the 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

The code for D F/F is:

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

I have implemented a testbench to test the Register File. But I am getting some unexpected output:

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 is the decoder 5*32. bit32_mux32to1 is mux 32 to 1 (each input is of 32 bits). I have checked them, they work fine. Also, reg_32bit and dff are also working fine.

The image of Simulation of RegFile

\$\endgroup\$
  • \$\begingroup\$ What is your actual question? Debugging questions on stack exchange sites must specifically state the difference between the expected output and the output produced. Also, text is text, please don't use screenshots \$\endgroup\$ – Chris Stratton Oct 27 '19 at 14:31
  • \$\begingroup\$ clock gating --VERY bad practise if its for fpga .... \$\endgroup\$ – Mitu Raj Oct 28 '19 at 11:01
0
\$\begingroup\$

I'll turn my comment into an answer.

  1. I strongly suggest you start using a wave-form display for debugging. You can not debug HDL code with $display and $write statements once you get past trivial examples.

  2. I noticed that your clock and data have the same delay: clock changes every #5 and your data at #10 and #100. Your clock edges and signal arrive at the same time which is a recipe for disaster.

  3. Unless this is a school assignment which forbid this, you should use HDL constructs (I am using different names but you should get the gist)

    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. Designing logic on rising and falling edges should be a used only as last resort and only if you really know what you are doing. In normal design it is a big NO NO!

In the example above you can do write forwarding like this:

   if (write_index==read1_index)
      read_data1 <= write_data
   else
      read_data1 <= regbank[read1_index];
   if (write_index==read2_index)
   ....
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Yes actually its an assignment (Designing single cycle MIPS processor). I changed the delay for data to #8, but still I am having the same problem. \$\endgroup\$ – Vipin Baswan Oct 27 '19 at 8:26
  • 1
    \$\begingroup\$ I can't advise you much more then this without doing to work for you. As a last tip: gating a clock is generally also a bad idea, especially if it has to run on an FPGA. regClk[j]=(clk & RegWrite... \$\endgroup\$ – Oldfart Oct 27 '19 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.