1
\$\begingroup\$

I'm creating a simple register file in system verilog, with a total of 6 registers that can be written to/read from. When I run a simulation in ModelSim, the output never shows the correct data - it stays at 0 and ignores any read signals. This led me to believe that either a) the values I'm writing to the registers may not be getting stored, so when I try to read a value from one of the registers they don't output anything, or b) data is being written to the registers, but I'm not pulling the data from those registers correctly.

Here is my .sv file:

module register_file#(parameter bits = 16, registers = 6)(clock, write_enable, write_reg, data_in, read_reg0, read_reg1, data_out0, data_out1);

    input clock, write_enable;
    input [2:0] write_reg, read_reg0, read_reg1;
    input [bits-1:0] data_in;
    output [bits-1:0] data_out0, data_out1;

    wire [bits-1:0] data_out0_wire, data_out1_wire;
    reg [bits-1:0] data_out0_reg, data_out1_reg;
    reg [bits-1:0] r1, r2, r3, r4, r5, r6;

    assign data_out0 = data_out0_reg;
    assign data_out1 = data_out1_reg;

    always @(posedge clock)
        begin
            if(write_enable)
                case(write_reg)
                    1: r1 = data_in;
                    2: r2 = data_in;
                    3: r3 = data_in;
                    4: r4 = data_in;
                    5: r5 = data_in;
                    6: r6 = data_in;
                endcase
            data_out0_reg <= data_out0_wire;
            data_out1_reg <= data_out1_wire;
        end

    always @(read_reg0)
        case(read_reg0)
            1: data_out0_wire = r1;
            2: data_out0_wire = r2;
            3: data_out0_wire = r3;
            4: data_out0_wire = r4;
            5: data_out0_wire = r5;
            6: data_out0_wire = r6;
        endcase

    always @(read_reg1)
        case(read_reg1)
            1: data_out1_wire = r1;
            2: data_out1_wire = r2;
            3: data_out1_wire = r3;
            4: data_out1_wire = r4;
            5: data_out1_wire = r5;
            6: data_out1_wire = r6;
        endcase

endmodule

Edit And here is my testbench:

`timescale 1ns / 1ps
module test_partC();

   reg  clk,write_enable;
   reg [2:0] write_reg, read_reg0, read_reg1;
   reg [15:0] data_in;
   reg [15:0] data_out0, data_out1;
   register_file dut (clock, write_enable, write_reg, data_in, read_reg0, read_reg1, data_out0, data_out1);

   // Toggle the clock every 10 ns
   initial
     begin
        clk = 0;
        forever #10 clk = !clk;
     end

   initial
     begin
        write_reg = 1;
          write_enable = 1;
          data_in = 10;
        #20;
        write_reg = 2;
          write_enable = 1;
          data_in = 15;
        #20;
        write_reg = 3;
          write_enable = 1;
          data_in = 20;
        #20;
        read_reg0 = 1;
          write_enable = 0;
        #20;
        read_reg0 = 2;
          read_reg1 = 3;
        #20;
        read_reg0 = 1;
          write_reg = 1;
          write_enable = 1;
          data_in = 30;
     end

endmodule

I added an extra set of registers from the data_out signals in trying to find a potential solution to the problem I'm having, but I'm not sure if that changes anything.

What I was trying to do was, based on the number from the read_reg signal, read the value from the corresponding register, which sends the signal down the data_out_wire, stores it in a data_out register, and then sends the signal out via a wire (output data_out).

I'm new to system verilog and I'm struggling to figure out where I went wrong, any help is greatly appreciated.

\$\endgroup\$
  • \$\begingroup\$ Your code does not compile for me on 2 different simulators. If I change wire to reg for data_out0_wire, data_out1_wire, it compiles. \$\endgroup\$ – toolic Feb 7 '17 at 20:53
  • \$\begingroup\$ I've added the testbench - also, I'm not sure why I'm not getting a compile error with the wire.. Is it even required for me to have the extra wires/reg for the output variables? Or could I have just passed the register values to the output signals in the case blocks? (i.e. 1: data_out0 = r1;) That is what I originally had, but the simulation didn't behave any differently. \$\endgroup\$ – Nick Borisenko Feb 7 '17 at 21:10
  • \$\begingroup\$ What simulator are you using? Did you try your code on edaplayground? \$\endgroup\$ – toolic Feb 7 '17 at 21:31
  • \$\begingroup\$ Oh wow that's really concerning.. it shouldn't be compiling but it still is on my end - I even created a new project and files, because I've had a similar problem before. I'm using Quartus Lite and ModelSim-Altera for simulations. \$\endgroup\$ – Nick Borisenko Feb 7 '17 at 21:50
0
\$\begingroup\$

I get a compile warning:

implicit wire has no fanin (test_partC.clock)

You should connect the clk signal to the design instance in your testbench:

register_file dut (clk, write_enable, write_reg, data_in, read_reg0, read_reg1, data_out0, data_out1);

When I run the simulation, I see non-zero values on your outputs.

\$\endgroup\$

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.