// SPDX-FileCopyrightText: 2020 Efabless Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0

`default_nettype none
module mem_wb (
`ifdef USE_POWER_PINS
    input VPWR,
    input VGND,
`endif
    input wb_clk_i,
    input wb_rst_i,

    input [31:0] wb_adr_i,
    input [31:0] wb_dat_i,
    input [3:0] wb_sel_i,
    input wb_we_i,
    input wb_cyc_i,
    input wb_stb_i,

    output wb_ack_o,
    output [31:0] wb_dat_o
    
);

    localparam ADR_WIDTH = $clog2(`MEM_WORDS);

    wire valid;
    wire ram_wen;
    wire [3:0] wen; // write enable

    assign valid = wb_cyc_i & wb_stb_i;
    assign ram_wen = wb_we_i && valid;

    assign wen = wb_sel_i & {4{ram_wen}} ;

    /*
        Ack Generation
            - write transaction: asserted upon receiving adr_i & dat_i 
            - read transaction : asserted one clock cycle after receiving the adr_i & dat_i
    */ 

    reg wb_ack_read;
    reg wb_ack_o;

    always @(posedge wb_clk_i) begin
        if (wb_rst_i == 1'b 1) begin
            wb_ack_read <= 1'b0;
            wb_ack_o <= 1'b0;
        end else begin
            // wb_ack_read <= {2{valid}} & {1'b1, wb_ack_read[1]};
            wb_ack_o    <= wb_we_i? (valid & !wb_ack_o): wb_ack_read;
            wb_ack_read <= (valid & !wb_ack_o) & !wb_ack_read;
        end
    end

    soc_mem
`ifndef USE_OPENRAM
    #(
        .WORDS(`MEM_WORDS),
        .ADR_WIDTH(ADR_WIDTH)
    )
`endif
     mem (
    `ifdef USE_POWER_PINS
        .VPWR(VPWR),
        .VGND(VGND),
    `endif
        .clk(wb_clk_i),
        .ena(valid),
        .wen(wen),
        .addr(wb_adr_i[ADR_WIDTH+1:2]),
        .wdata(wb_dat_i),
        .rdata(wb_dat_o)
    );

endmodule

module soc_mem 
`ifndef USE_OPENRAM
#(
    parameter integer WORDS = 256,
    parameter ADR_WIDTH = 8
)
`endif
 ( 
`ifdef USE_POWER_PINS
    input VPWR,
    input VGND,
`endif
    input clk,
    input ena,
    input [3:0] wen,
    input [ADR_WIDTH-1:0] addr,
    input [31:0] wdata,
    output[31:0] rdata
);

`ifndef USE_OPENRAM
    DFFRAM #(.WSIZE(`DFFRAM_WSIZE), .USE_LATCH(`DFFRAM_USE_LATCH)) SRAM (
    `ifdef USE_POWER_PINS
        .VPWR(VPWR),
        .VGND(VGND),
    `endif
        .CLK(clk),
        .WE(wen),
        .EN(ena),
        .Di(wdata),
        .Do(rdata),
        // 8-bit address if using the default custom DFF RAM
        .A(addr)
    );
`else
    
    /* Using Port 0 Only - Size: 1KB, 256x32 bits */
    //sram_1rw1r_32_256_8_scn4m_subm 
    sram_1rw1r_32_256_8_sky130 SRAM(
            .clk0(clk), 
            .csb0(~ena), 
            .web0(~|wen),
            .wmask0(wen),
            .addr0(addr[7:0]),
            .din0(wdata),
            .dout0(rdata)
      );

`endif

endmodule
`default_nettype wire
