# Verilog RAM module with Register File & Testbench

I am designing a RAM module with testbench in Verilog. It is suppose to access a register file (.dat) in the testbench and run it through an ALU module. There are 4 modules (memory.v, alu.v, toplevel.v and testbench.v).

My problem is that when I run the ModelSIM I am not getting the expected results.

timescale 1ns/1ps

module testbench_lab3_reg();

reg clk;
reg write_en;
wire [15:0] DataOut;
reg [15:0] memory [0:15];

always
begin
clk = 1; #10; clk = 0; #10;
end

initial begin
$readmemb("memfile.dat", memory); Read_address = 5'b00000; Write_address = 5'b01001; read_en = 1; write_en = 0; #20; Read_address = 5'b00000; Write_address = 5'b01001; read_en = 0; write_en = 1; #20; Read_address = 5'b00001; Write_address = 5'b01010; read_en = 1; write_en = 0; #20; Read_address = 5'b00001; Write_address = 5'b01010; read_en = 0; write_en = 1; #20; Read_address = 5'b00010; Write_address = 5'b01011; read_en = 1; write_en = 0; #20; Read_address = 5'b00010; Write_address = 5'b01011; read_en = 0; write_en = 1; #20; Read_address = 5'b00011; Write_address = 5'b01100; read_en = 1; write_en = 0; #20; Read_address = 5'b00011; Write_address = 5'b01100; read_en = 0; write_en = 1; #20; Read_address = 5'b00100; Write_address = 5'b01101; read_en = 1; write_en = 0; #20; Read_address = 5'b00100; Write_address = 5'b01101; read_en = 0; write_en = 1; #20; Read_address = 5'b01001; Write_address = 5'b00000; read_en = 1; write_en = 0; #20; Read_address = 5'b01010; Write_address = 5'b00000; read_en = 1; write_en = 0; #20; Read_address = 5'b01011; Write_address = 5'b00000; read_en = 1; write_en = 0; #20; Read_address = 5'b01100; Write_address = 5'b00000; read_en = 1; write_en = 0; #20; Read_address = 5'b01101; Write_address = 5'b00000; read_en = 1; write_en = 0; #20;$stop;

end
endmodule


I know my ALU works because I tested it using a MegaWizard generated RAM. The following is my ram module:

module memory(
input clk,
input [15:0] write_data,
input write_enable,
reg [15:0] memory [0:15];
reg [15:0] data_out;

always @(posedge clk)
begin
if (write_enable)
end

endmodule


The following is my top level module, which instantiates the ALU and the RAM:

module lab3_reg(
input clk,
input write_en,
output [15:0] DataOut
);

wire zero;
wire signed [3:0] y;
alu inst1(DataOut [12:9], DataOut [8:5], DataOut [15:13], y, zero);

wire signed [15:0] y_signed;
assign y_signed = y;

wire [15:0] data;
assign data = DataOut;

endmodule


I'm pretty sure the problem is with my testbench, but I've been racking my brains over this, so any help would be awesome.

memfile.dat

0100000111100000
1100000111100000
1111111000000000
0001111111100000
0010000111100000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000

• "I am not getting the expected results". Care to elaborate? – Tom Carpenter Mar 12 '17 at 23:15
• Yeah. Sorry. So, when I run the simulation in ModelSIM, those last five lines in the testbench module are suppose to read addresses 9 - 13, which should contain the results of the data contained in the 'memfile.dat' file being inputted into the alu/memory modules. The vectors contained in the 'memfile.dat' correspond to the inputs for the ALU, the first five of which have some numerical significance, while the rest of the vectors are 0's which I'm guessing would be used to store the data. I'll post the 'memfile.dat' in the my original posting. – Daniel Pavlovsky Mar 12 '17 at 23:24

May be I misunderstand something, but where is inputs for your ALU module? So I think, the first problem in your structure is, in the case you haven't inputs for ALU you write into the memory unknown values (U or Z, what you have on ALU output) when write_en is active;
The second problem is in the module lab3_reg you have incorrect assignment in line assign data = DataOut;, it should be assign DataOut = data; because data is output of internal module you have "X" on the port (multiple drivers);
And last problem is in the tesbench testbench_lab3_reg module, there you also have bad assignment assign DataOut = (read_en) ? memory[Read_address] : memory[Write_address]; in this line. DataOut is output of your top module, but in the line you assign another value, in the case you also will get "X" on the wire.
P.S. By the way, what do you want to get by the follow assignment assign DataOut = (read_en) ? memory[Read_address] : memory[Write_address]; when DataOut is output? If you want to use bidirectional bus you should declare it like inout in modules.
• @davlovsky make a note that if you want to bring some data to module you should use port with INPUT direction rather than OUTPUT port. In the case you described you should take the data for ALU inputs from data` port, which is output from the memory. Please, check directions of your port in each module. I think there has a big mess. – Roman Mar 13 '17 at 2:28