在一个时钟周期内重置所有 RAM 内容

Reset all the RAM content in one clock cycle

在下面的模块中,我想将内存的所有内容重置为 0。我将值写入 RAM,然后在我的代码中间,现在我需要将 RAM 的所有值重置为零。如果不向 RAM 的每个元素写入零,我该怎么做?换句话说,有没有办法在一个时钟内重置RAM?

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

您的 ram 模块已经具备在一个周期内重置所有地址的能力,因此无需在测试台代码中花费 16 个周期来进行重置。替换:

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

与:

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

当您查看 ram 信号的波形时,您会看到所有 16 个位置在一个周期内重置为 0。


更好的设计编码风格是对来自同一 always 块的 ram 信号进行分配:

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

这使重置优先于写入,以防两个输入在同一周期内都为高电平。