Reset all the ram content in one clock

In the below module, I want to reset all the content of the memory to 0. I write values to the RAM and then in the middle of my code, now I need to reset all the values of the RAM to zero. How can I do that without writing zero to each element of the RAM? In other words, is there any way to reset a RAM in one clk?

module ram 
    (   input clk,       //clock
        input wr_en,         //write enable 
        input resetRam,
        input [9:0] data_in,     //Input data.
        input [3:0] addr,   //address 
        output [9:0] data_out //output data 
    );

//memory declaration.
reg [9:0] ram[0:15];

//writing to the RAM
always@(posedge clk)
begin
    if(wr_en == 1)    
        ram[addr] <= data_in;
end

//reset 
  always @(posedge clk) begin 
    if(resetRam) begin
      for (integer i = 0; i < 16; i = i + 1)
      begin
        ram[i] <= {10{1'b0}};
      end
    end
  end

//always reading from the ram, irrespective of clock.
assign data_out = !wr_en ? ram[addr] : 'hz;   
  
endmodule 

module ram_tb;

    // Inputs
    reg clk;
    reg wr_en;
    reg resetRam;
    wire [9:0] data_in;
    reg [3:0] addr;
    
    // Outputs
    wire [9:0] data_out;

    reg [9:0] tb_data;
    
    integer i;

   
    ram iram2 (.*);
    
    assign data_in = wr_en ? tb_data : 'hz ;

    always
        #5 clk = ~clk;

    initial begin
        $monitor("addrs = %b resetRam=%b Write = %b  dataIn = %b dataOut = %b", addr,resetRam,wr_en,data_in,data_out);
        $dumpfile("ram_tb.vcd");
        $dumpvars(0,ram_tb);
        // Initialize Inputs
        clk <= 0;
        addr <= 0;
        wr_en <= 0;
        resetRam <= 0;
        tb_data <= 0;  
        #20;

        //Write all the locations of RAM  
        wr_en <= 1;
      for(i=1; i <= 16; i = i + 1) begin
            tb_data <= i;
            addr <= i-1;
            #10;
        end
        wr_en <= 0;

        //Read from  all the locations of RAM.
        for(i=1; i <= 16; i = i + 1) begin
            addr <= i-1;
            #10;
        end

        //resetRam
        resetRam <= 1;
        for(i=1; i <= 16; i = i + 1) begin
            addr <= i-1;
            #10;
        end
        resetRam <= 0;

        

    #100
    $finish;
    end
       
endmodule

enter image description here

>Solution :

Your ram module already has the ability to reset all addresses in one cycle, so there is no need to spend 16 cycles in the testbench code to do the reset. Replace:

    //resetRam
    resetRam <= 1;
    for(i=1; i <= 16; i = i + 1) begin
        addr <= i-1;
        #10;
    end
    resetRam <= 0;

with:

    //resetRam
    resetRam <= 1;
    #10;
    resetRam <= 0;

When you look at waveforms of the ram signal, you will see all 16 locations are reset to 0 in one cycle.


A better coding style for the design is to make assignments to the ram signal from the same always block:

module ram
    (   input clk,       //clock
        input wr_en,         //write enable
        input resetRam,
        input [9:0] data_in,     //Input data.
        input [3:0] addr,   //address
        output [9:0] data_out //output data
    );

//memory declaration.
reg [9:0] ram[0:15];

always @(posedge clk) begin
    if (resetRam) begin
        for (integer i = 0; i < 16; i = i + 1) begin
            ram[i] <= {10{1'b0}};
        end
    end else if (wr_en) begin
        ram[addr] <= data_in;
    end
end

//always reading from the ram, irrespective of clock.
assign data_out = !wr_en ? ram[addr] : 'hz;

endmodule

This prioritizes the reset over the write, just in case both inputs were high in the same cycle.

Leave a Reply