It is not reading the data_in inputs in sequence when I tried to display the output of RAM. The RAM output starts from B as on the 000 address however I'm trying to write A on 000 address and so on Here is the design block code
module task (
input [2:0] address_ram,
input [7:0] data_in,
output [(DATA_WIDTH-1):0] q_ram,
input clk,
input rst,
input we
);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
// RAM content
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addr_r;
always @(posedge clk or negedge rst) begin
if (rst) begin
// Reset condition
addr_r <= 8'b0;
end else begin
// WRITE to RAM
if (we) begin
ram[addr_r] <= data_in;
end
// READ from RAM
addr_r <= address_ram;
end
end
assign q_ram = ram[address_ram];
endmodule
this is the testbench
// Code your testbench here
// or browse Examples
module task_tb;
// Parameters
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
// Inputs and Outputs
reg clk, rst, we;
reg [DATA_WIDTH-1:0] data_in;
reg [2:0] address_ram;
wire [(DATA_WIDTH-1):0] q_ram_out;
// Instantiate the home_task module
home_task uut (
.clk(clk),
.rst(rst),
.we(we),
.address_ram(address_ram),
.data_in(data_in),
.q_ram(q_ram_out)
);
// Clock Generation
always begin
#5 clk = ~clk; // Toggle the clock every 5 time units
end
// Initial Block
initial begin
clk = 0;
rst = 0; // Assert reset initially
we = 0;
data_in = 8'b01000001;
address_ram = 3'b000;
result = 1;
// Apply reset for some time
#10 rst = 0;
#10;
// Write data to RAM
we = 1;
address_ram = 3'b000;
data_in = 8'b01000001; // 'A'
#10;
we = 1;
address_ram = 3'b001;
data_in = 8'b01000010; // 'B'
#10;
we = 1;
address_ram = 3'b010;
data_in = 8'b01000011; // 'C'
#10;
we = 1;
address_ram = 3'b011;
data_in = 8'b01000100; // 'D'
#10;
we = 1;
address_ram = 3'b100;
data_in = 8'b01000101; // 'E'
#10;
we = 1;
address_ram = 3'b101;
data_in = 8'b01000110; // 'F'
#10;
we = 1;
address_ram = 3'b110;
data_in = 8'b01000111; // 'G'
#10;
we = 1;
address_ram = 3'b111;
data_in = 8'b01001000; // 'H'
#10;
address_ram = 3'b000;
repeat (2**3) begin
$display("Read Data from RAM at address %b: %c", address_ram, q_ram_out);
#10;
address_ram = address_ram + 1;
end
// Add more stimulus as needed
#100 $finish;
end
endmodule
I am writing to the RAM ABCDEFGH But the output shows that it started 000 as B, 001 as C and so on... But I want the result to be A as 000 B as 001 and so on.
I think the problem is in the reset. always
statement looks for a negedge rst
but the if (rst)
checks for rst=1'b1
to reset the design.
Also, one thing to point is that you are using a registered version of the ram_address
i.e. addr_r
to write into the RAM. So, the first wren
from testbench is going to use the reset value of addr_r
for writing. But your design's reset condition is wrong.
First of all, release reset from your testbench, I noticed rst
stays 0
. But also, if you are using a registered ram_address
for writing, you should also register we
and data_in
in the code, so that all the signals align properly.
I would rewrite the code as follows:
module task (
input [2:0] address_ram,
input [7:0] data_in,
output [(DATA_WIDTH-1):0] q_ram,
input clk,
input rst,
input we
);
parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 8;
// RAM content
reg [DATA_WIDTH-1:0] ram [2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addr_r;
reg [DATA_WIDTH-1:0] data_in_r;
reg we_r;
always @(posedge clk or negedge rst) begin
if (rst == 1'b0) begin
addr_r <= {ADDR_WIDTH{1'b0}};
data_in_r <= {DATA_WIDTH{1'b0}};
we_r <= 1'b0;
end else begin
addr_r <= address_ram;
data_in_r <= data_in;
we_r <= we;
end
end
always @(posedge clk) begin
if (we_r) begin
ram[addr_r] <= data_in_r;
end
end
assign q_ram = ram[addr_r];
endmodule
By separating the always blocks, that code is much cleaner. And now, the addr_r
, data_in
, and we
are all one clock cycle registered. And your read condition is also using a registered version of ram_address
In your testbench, the rst
should go from 0 to 1 for properly resetting the design. It should work.