module NV_NVDLA_CDMA_WG_fifo_folded_ram_rws_128x5(
      clk
    , clk_mgated
    , reset_
    , pwrbus_ram_pd
    , wa
    , we
    , di
    , ra
    , re
    , dout
    );
input clk;
input clk_mgated;
input reset_;
input [31 : 0] pwrbus_ram_pd;
input [6:0] wa;
input we;
input [4:0] di;
input [6:0] ra;
input re;
output [4:0] dout;
// Folded Ram
//
// We assume incrementing write addresses.
// The read address could get backed up if there is flow control.
//
// We keep a write collection buffer (buff).
// We don't write it into the ram (we_f) until we write the first datum of the next row.
// The read side may read from the buffer instead of the ram if the data is there (use_buff_d_next).
// When the read side does read from the ram (re_f), it does it once per row.
//
// One special case to worry about is when a write and read are occurring to the
// same address in the same cycle. That is allowed only when -ram_bypass_reg
// is in effect. If -ram_bypass_reg is implemented externally to this module,
// then we just do a dummy use_buff_d_next=1 even though the data will be wrong
// and ignored. If -ram_bypass_reg is implemented internally to this module (default),
// then we use_buff_d_next=1 and also copy di to buff_d. Both cases prevent us
// from doing reads to the underlying ram.
//
// In the near future, we will optimize away some unnecessary assertions of we_f and re_f
// to the ram. We seem to have a general problem at a higher level (even in non-folded
// rams) of having some superfluous assertions of these power-wasting signals.
// Some changes need to be made above this level to fix this. For now, we keep it
// the same as with non-folded rams.
//
// If master clk gating (SLCG) is in effect, then the logic here is gated
// by the mgated clk, but the ram itself is not gated because it has its own SLCG.
//
reg [9:0] buff;
reg [6:0] buff_wa;
wire [5:0] buff_wa_f = buff_wa[6:1];
wire [5:0] ra_f = ra[6:1];
wire same_addr_write_and_read = we && re && wa == ra;
wire use_buff_d_next = (ra_f == buff_wa_f && buff_wa[0:0] >= ra[0:0]) || same_addr_write_and_read;
reg use_buff_d;
wire we_f = we && wa[0:0] == 1'd0;
reg did_re_f;
wire re_f = re && !use_buff_d_next && (ra[0:0] == 1'd0 || !did_re_f);
reg [4:0] buff_d;
wire [9:0] dout_f;
reg [0:0] ro_d;
always @( posedge clk_mgated or negedge reset_ ) begin
    if ( !reset_ ) begin
        buff_wa <= 7'd0;
        did_re_f <= 1'd0;
    end else begin
        if ( we ) begin
            buff_wa <= wa; // note: resettable to avoid ramgen assert during first superfluous write
        end
        did_re_f <= re_f || (!use_buff_d_next && did_re_f && ra[0:0] != 1'd0);
    end
end
always @( posedge clk_mgated ) begin
    if ( we ) begin
        case( wa[0:0] )
            1'd0: buff[4:0] <= di;
            1'd1: buff[9:5] <= di;
// VCS coverage off
            default: buff <= {10{`x_or_0}};
// VCS coverage on
        endcase
    end
    if ( re ) begin
        if ( use_buff_d_next ) begin
            use_buff_d <= 1'b1;
            case( ra[0:0] )
                1'd0: buff_d <= buff[4:0];
                1'd1: buff_d <= buff[9:5];
// VCS coverage off
                default: buff_d <= {5{`x_or_0}};
// VCS coverage on
            endcase
        end else begin
            use_buff_d <= 1'b0;
            ro_d <= ra[0:0];
        end
    end
end
// Adding parameter for fifogen to disable wr/rd contention assertion in ramgen.
// Fifogen handles this by ignoring the data on the ram data out for that cycle.
nv_ram_rws_64x10 #(`FORCE_CONTENTION_ASSERTION_RESET_ACTIVE) ram (
      .clk ( clk )
    , .pwrbus_ram_pd ( pwrbus_ram_pd )
    , .wa ( buff_wa_f )
    , .we ( we_f )
    , .di ( buff )
    , .ra ( ra_f )
    , .re ( re_f )
    , .dout ( dout_f )
    );
reg [4:0] dout_fm;
always @(*) begin
    case( ro_d )
        1'd0: dout_fm = dout_f[4:0];
        1'd1: dout_fm = dout_f[9:5];
// VCS coverage off
        default: dout_fm = {5{`x_or_0}};
// VCS coverage on
    endcase
end
assign dout = use_buff_d ? buff_d : dout_fm;
endmodule