// SPDX-FileCopyrightText: 
// 2022 Nguyen Dao
//
// 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

module BlockRAM_1KB (clk, rd_addr, rd_data, wr_addr, wr_data, C0, C1, C2, C3, C4, C5);

	parameter READ_ADDRESS_MSB_FROM_DATALSB = 24; //default 24 means bits wr_data[25:24] will become bits [9:8] of read address
	parameter WRITE_ADDRESS_MSB_FROM_DATALSB = 16; //default 16 means bits wr_data[17:16] will become bits [9:8] of write address
	parameter WRITE_ENABLE_FROM_DATA = 20; //default 20 means bit wr_data[20] will become the dynamic writeEnable input
    input clk;
    input [7:0] rd_addr;
    output [31:0] rd_data;
    
    input [7:0] wr_addr;
    input [31:0] wr_data;
    
    input C0;//naming of these doesnt really matter
    input C1;// C0,C1 select write port width
    input C2;// C2,C3 select read port width
    input C3;
    input C4;//C4 selects the alwaysWriteEnable
    input C5; //C5 selects register bypass
      // NOTE, the read enable is currently constantly ON
      // NOTE, the R/W port on the standard cell is used only in write mode
      // NOTE, enable ports on the primitive RAM are active lows
    wire [1:0] rd_port_configuration;
    wire [1:0] wr_port_configuration;
    wire optional_register_enabled_configuration;
	wire alwaysWriteEnable;
    assign wr_port_configuration = {C0, C1};
    assign rd_port_configuration = {C2, C3};
	assign alwaysWriteEnable = C4;
    assign optional_register_enabled_configuration = C5;
    
    reg memWriteEnable;
    always @ (*) begin // write enable
		if(alwaysWriteEnable) begin
			memWriteEnable = 0; // This RAM primitive is active low.
		end else begin
			memWriteEnable = (!(wr_data[WRITE_ENABLE_FROM_DATA])); // inverting the bit to make it active-high
		end
    end
    reg [3:0] mem_wr_mask;
    reg [31:0] muxedDataIn;
	
	wire [1:0] wr_addr_topbits; 
	assign wr_addr_topbits = wr_data[WRITE_ADDRESS_MSB_FROM_DATALSB+1:WRITE_ADDRESS_MSB_FROM_DATALSB];
    always @ (*) begin //write port config -> mask + write data multiplex
		muxedDataIn = 32'dx;
        if(wr_port_configuration == 0) begin
            mem_wr_mask = 4'b1111;
			muxedDataIn = wr_data;
        end else if(wr_port_configuration == 1) begin
            if(wr_addr_topbits == 0) begin
                mem_wr_mask = 4'b0011;
				muxedDataIn[15:0] = wr_data[15:0];
            end else begin
                mem_wr_mask = 4'b1100;
				muxedDataIn[31:16] = wr_data[15:0];
            end
        end else if(wr_port_configuration == 2) begin
            if(wr_addr_topbits == 0) begin
                mem_wr_mask = 4'b0001;
				muxedDataIn[7:0] = wr_data[7:0];
            end else if(wr_addr_topbits == 1) begin
                mem_wr_mask = 4'b0010;
				muxedDataIn[15:8] = wr_data[7:0];
            end else if(wr_addr_topbits == 2) begin
                mem_wr_mask = 4'b0100;
				muxedDataIn[23:16] = wr_data[7:0];
            end else begin
                mem_wr_mask = 4'b1000;
				muxedDataIn[31:24] = wr_data[7:0];
            end
        end
    end
    wire [31:0] mem_dout;
    sram_1rw1r_32_256_8_sky130 memory_cell(                             //dout0 is unused
    .clk0(clk),.csb0(memWriteEnable),.web0(memWriteEnable),.wmask0(mem_wr_mask),.addr0(wr_addr[7:0]),.din0(muxedDataIn),//.dout0(),
    .clk1(clk),.csb1(1'b0),.addr1(rd_addr[7:0]),.dout1(mem_dout)
    );
    reg [1:0] rd_dout_sel;
    always @ (posedge clk) begin
        rd_dout_sel <= wr_data[READ_ADDRESS_MSB_FROM_DATALSB+1:READ_ADDRESS_MSB_FROM_DATALSB];
    end
    reg [31:0] rd_dout_muxed;
    always @ (*) begin
        rd_dout_muxed[31:0] = mem_dout[31:0]; // a default value. Could be 32'dx if tools support it for logic saving!
        if(rd_port_configuration == 0) begin
            rd_dout_muxed[31:0] = mem_dout[31:0];
        end else if(rd_port_configuration == 1) begin
            if(rd_dout_sel[0] == 0) begin
                rd_dout_muxed[15:0] = mem_dout[15:0];
            end else begin
                rd_dout_muxed[15:0] = mem_dout[31:16];
            end
        end else if(rd_port_configuration == 2) begin
            if(rd_dout_sel == 0) begin
                rd_dout_muxed[7:0] = mem_dout[7:0];
            end else if(rd_dout_sel == 1) begin
                rd_dout_muxed[7:0] = mem_dout[15:8];
            end else if(rd_dout_sel == 2) begin
                rd_dout_muxed[7:0] = mem_dout[23:16];
            end else begin
                rd_dout_muxed[7:0] = mem_dout[31:24];
            end
        end
    end
    reg [31:0] rd_dout_additional_register;
    always @ (posedge clk) begin
        rd_dout_additional_register <= rd_dout_muxed;
    end
    reg [31:0] final_dout;
    assign rd_data = final_dout;
    always @ (*) begin
        if(optional_register_enabled_configuration) begin
            final_dout = rd_dout_additional_register;
        end else begin
            final_dout = rd_dout_muxed;
        end
    end
endmodule


(* blackbox *)
module sram_1rw1r_32_256_8_sky130(
//`ifdef USE_POWER_PINS
//	vdd,
//	gnd,
//`endif
// Port 0: RW
    clk0,csb0,web0,wmask0,addr0,din0,dout0,
// Port 1: R
    clk1,csb1,addr1,dout1
  );

  parameter NUM_WMASKS = 4 ;
  parameter DATA_WIDTH = 32 ;
  parameter ADDR_WIDTH = 8 ;
  parameter RAM_DEPTH = 1 << ADDR_WIDTH;
  // FIXME: This delay is arbitrary.
  parameter DELAY = 3 ;
//`ifdef USE_POWER_PINS
 // inout vdd;
 // inout gnd;
//`endif
  input  clk0; // clock
  input   csb0; // active low chip select
  input  web0; // active low write control
  input [NUM_WMASKS-1:0]   wmask0; // write mask
  input [ADDR_WIDTH-1:0]  addr0;
  input [DATA_WIDTH-1:0]  din0;
  output [DATA_WIDTH-1:0] dout0;
  input  clk1; // clock
  input   csb1; // active low chip select
  input [ADDR_WIDTH-1:0]  addr1;
  output [DATA_WIDTH-1:0] dout1;
endmodule
