0
\$\begingroup\$

I wrote some fairly simple code in Verilog to implement a 32-bit deep, 8-bit wide register file. However, when I actually run a behavioral simulation of the thing the two data-read lines (rd0_data and rd1_data, respectively) seem to be utterly nonreactive.

I think it's possible I made some mistake in how I built out the inputs and outputs or the "mem" variable, but after fiddling with it for hours I'm sort of lost.

module reg_file#(
 parameter DATA_WIDTH = 8,
 parameter ADDR_WIDTH = 5
 )(
 input rst, clk, wr_en,
 input [ADDR_WIDTH-1:0] rd0_addr,
 input [ADDR_WIDTH-1:0] rd1_addr,
 input [ADDR_WIDTH-1:0] wr_addr,
 input [DATA_WIDTH-1:0] wr_data,
 output [DATA_WIDTH-1:0] rd0_data,
 output [DATA_WIDTH-1:0] rd1_data
 );
 integer i; //For the reset operation
 reg [DATA_WIDTH-1:0] mem [0:31];
 assign rd0_data = mem[rd0_addr];
 assign rd1_data = mem[rd1_addr];
 //Update w. synchronus reset
 always @(posedge clk) begin
 if(rst) begin 
 for (i = 0; i < 32; i = i + 1) mem[i] <= 0;
 end else begin
 if(wr_en) begin
 mem[wr_addr] <= wr_data;
 end
 end
 end
endmodule

Behavioral Simulation output:

Behavioral Simulation

My test bench code is as follows:

module reg_file_tb;
 reg rst, wr_en, clk;
 reg [4:0] rd0_addr, rd1_addr, wr_addr;
 reg [7:0] wr_data;
 wire [7:0] rd0_data, rd1_data;
 // Instantiate the register file (using positional-association for instantiation)
 reg_file dut
 (
 rst, wr_en, clk, rd0_addr, rd1_addr, wr_addr, wr_data, rd0_data, rd1_data
 );
 integer i;
 initial begin
 // Initial values
 wr_en = 1;
 rd0_addr = 5'd0;
 rd1_addr = 5'd0;
 wr_addr = 5'd0;
 wr_data = 8'd255;
 i = 0;
 // Pulse the reset signal for only one clock cycle
 clk = 0;
 rst = 1;
 #20;
 clk = 1;
 #20;
 clk = 0;
 rst = 0;
 for (i = 0; i < 16; i = i + 1)
 begin
 // Sample conditional stimulus: if i equals 4, set the write enable to HIGH
 /*if (i == 32'd4)
 begin
 wr_en = 1;
 end*/
 // Sample conditional stimulus: when i equals 5, change the rd1_addr to 10
 if (i == 32'd5)
 begin
 rd1_addr = 5'd10;
 end
 // Pulse the clock in this for-loop
 clk = 0;
 #20;
 clk = 1;
 #20;
 wr_addr = wr_addr + 5'd1;
 rd0_addr = rd0_addr + 5'd1;
 end
 end
endmodule

Any helpful guesses or tips would be very much appreciated.

asked Oct 9, 2019 at 1:35
\$\endgroup\$
5
  • \$\begingroup\$ How are you testing it? What results are you actually getting? \$\endgroup\$ Commented Oct 9, 2019 at 3:34
  • 1
    \$\begingroup\$ mem should only be assigned in one always block. Separate is not synthesizible and prone to race conditions in behavioral simulations. \$\endgroup\$ Commented Oct 9, 2019 at 4:45
  • \$\begingroup\$ @Greg: While it's true that that's an issue, the actual question is about simulation. \$\endgroup\$ Commented Oct 9, 2019 at 12:41
  • \$\begingroup\$ @DaveTweed I added the output of my behavioral simulation and the test bench that resulted in it to the post. Sorry for not thinking to include it earlier. \$\endgroup\$ Commented Oct 9, 2019 at 16:26
  • \$\begingroup\$ @Greg Re-coded the always block to reflect your advice. Although it didn't resolve the issue at hand, I appreciate you catching my mistake. \$\endgroup\$ Commented Oct 9, 2019 at 16:27

1 Answer 1

0
\$\begingroup\$

I accidentally swapped "wr_en" and "clk" when instantiating a module of the register in the test bench. The module itself is fine, I'm just dumb.

Thanks to everyone who looked at it though.

answered Oct 9, 2019 at 17:12
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.