Q:

The data_out value is updating in the next clock edge which is supposed to update as soon as b is assigned, why?

    module memory(data_out,address,data_in,write_enable,clk,cs,rst);
        output  [3:0] data_out;
        input [3:0] address;
        input [3:0] data_in; 
        input write_enable;
        input clk;
        input cs;
        input rst;

    reg [3:0] data_out,b;
    reg [3:0] memory [0:15];
    reg [3:0] temp,a;

    always @(posedge clk or posedge rst) begin
       if(rst) begin
         temp<=4'b0000;
         data_out<=4'b0000;
       end
       else 
       begin
         temp<=a;
         data_out<=b;
       end
       end

    always @(posedge clk)begin
       if(cs==1'b1) begin
            if (write_enable==1'b1) begin
                memory[address] <= data_in;
                a<=data_in;
             end
             else begin
               b<=memory[address];
             end
        end
    end

   endmodule

A:

You are updating data_out and b simultaneously on posedge clk which means at every positive edge of clk, data_out will be assigned the value of b and b will be assigned the memory[address], therefore data_out is assigned the old value of b
To get correct results, you can do this:
Do not update data_out <= b in first always block
Instead assign data_out <= memory[address] inside second always block itself.

