2
\$\begingroup\$

I'm creating a simple register file in SystemVerilog, 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

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 SystemVerilog, and I'm struggling to figure out where I went wrong; any help is greatly appreciated.

\$\endgroup\$
2
  • \$\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\$ Commented Feb 7, 2017 at 21:10
  • \$\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\$ Commented Feb 7, 2017 at 21:50

1 Answer 1

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 and acknowledge you have read our privacy policy.

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