

module tsmc_dpram #(
   parameter DATAWIDTH = 32
  ,parameter ADDRWIDTH = 14
)(
   input                       PortClk
  ,input  [ADDRWIDTH-1     :0] PortAAddr
  ,input  [DATAWIDTH-1     :0] PortADataIn
  ,input                       PortAWriteEnable      //active low
  ,input                       PortAChipEnable       //active low
  ,input  [(DATAWIDTH/8)-1 :0] PortAByteWriteEnable  //active low
  ,output [DATAWIDTH-1     :0] PortADataOut
  
  ,input  [ADDRWIDTH-1     :0] PortBAddr
  ,input  [DATAWIDTH-1     :0] PortBDataIn
  ,input                       PortBWriteEnable      //active low
  ,input                       PortBChipEnable       //active low
  ,input  [(DATAWIDTH/8)-1 :0] PortBByteWriteEnable  //active low
  ,output [DATAWIDTH-1     :0] PortBDataOut
);
////////////////////////////////////////////////////////////////////////////////
//Function
////////////////////////////////////////////////////////////////////////////////        
function integer clog2(input integer bit_depth);
  begin
    for(clog2=0;bit_depth>0;clog2=clog2+1)
      bit_depth =bit_depth>>1;
  end
endfunction

localparam LSB  = clog2(DATAWIDTH/8 -1);

generate
  if((DATAWIDTH == 512) && (ADDRWIDTH == 19)) begin:spram_512X8192_generation
    genvar i;
    wire [DATAWIDTH-1:0] BWEBA ;
    wire [DATAWIDTH-1:0] BWEBB ;
    for(i = 0; i < DATAWIDTH/8; i = i + 1) begin
      assign BWEBA[8*i +: 8] = {8{PortAByteWriteEnable[i]}};
      assign BWEBB[8*i +: 8] = {8{PortBByteWriteEnable[i]}};
    end
    genvar k;
    wire [1          :0] U_CEBA;
    wire [1          :0] U_CEBB;
    wire [DATAWIDTH-1:0] U_QA[1 :0];
    wire [DATAWIDTH-1:0] U_QB[1 :0];
    reg  [1          :0] AA_1D_MSB;
    reg  [1          :0] AB_1D_MSB;
    for(k = 0; k < 2; k = k + 1) begin
      assign U_CEBA[k] = ~(PortAAddr[ADDRWIDTH-1] == k) | PortAChipEnable;
      assign U_CEBB[k] = ~(PortBAddr[ADDRWIDTH-1] == k) | PortBChipEnable;
      tsdn28hpcpuhdb4096x128m4mw_170a U0_tsdn28hpcpuhdb4096x128m4mw_170a (
        .CLK                                                           ( PortClk                                 )
        ,.CEBA                                                         ( U_CEBA[k]                               )
        ,.WEBA                                                         ( PortAWriteEnable                        )
        ,.BWEBA                                                        ( BWEBA[127:0]                            )
        ,.AA                                                           ( PortAAddr[ADDRWIDTH-2:LSB]              )
        ,.DA                                                           ( PortADataIn[127:0]                      )
        ,.QA                                                           ( U_QA[k][127:0]                          )
        ,.CEBB                                                         ( U_CEBB[k]                               )
        ,.WEBB                                                         ( PortBWriteEnable                        )
        ,.BWEBB                                                        ( BWEBB[127:0]                            )
        ,.AB                                                           ( PortBAddr[ADDRWIDTH-2:LSB]              )
        ,.DB                                                           ( PortBDataIn[127:0]                      )
        ,.QB                                                           ( U_QB[k][127:0]                          )
        ,.RTSEL                                                        ( 2'b00                                   )
        ,.WTSEL                                                        ( 2'b00                                   )
        ,.PTSEL                                                        ( 2'b00                                   )
        ); 
      tsdn28hpcpuhdb4096x128m4mw_170a U1_tsdn28hpcpuhdb4096x128m4mw_170a (
        .CLK                                                           ( PortClk                                 )
        ,.CEBA                                                         ( U_CEBA[k]                               )
        ,.WEBA                                                         ( PortAWriteEnable                        )
        ,.BWEBA                                                        ( BWEBA[255:128]                          )
        ,.AA                                                           ( PortAAddr[ADDRWIDTH-2:LSB]              )
        ,.DA                                                           ( PortADataIn[255:128]                    )
        ,.QA                                                           ( U_QA[k][255:128]                        )
        ,.CEBB                                                         ( U_CEBB[k]                               )
        ,.WEBB                                                         ( PortBWriteEnable                        )
        ,.BWEBB                                                        ( BWEBB[255:128]                          )
        ,.AB                                                           ( PortBAddr[ADDRWIDTH-2:LSB]              )
        ,.DB                                                           ( PortBDataIn[255:128]                    )
        ,.QB                                                           ( U_QB[k][255:128]                        )
        ,.RTSEL                                                        ( 2'b00                                   )
        ,.WTSEL                                                        ( 2'b00                                   )
        ,.PTSEL                                                        ( 2'b00                                   )
        ); 
      tsdn28hpcpuhdb4096x128m4mw_170a U2_tsdn28hpcpuhdb4096x128m4mw_170a (
        .CLK                                                           ( PortClk                                 )
        ,.CEBA                                                         ( U_CEBA[k]                               )
        ,.WEBA                                                         ( PortAWriteEnable                        )
        ,.BWEBA                                                        ( BWEBA[383:256]                          )
        ,.AA                                                           ( PortAAddr[ADDRWIDTH-2:LSB]              )
        ,.DA                                                           ( PortADataIn[383:256]                    )
        ,.QA                                                           ( U_QA[k][383:256]                        )
        ,.CEBB                                                         ( U_CEBB[k]                               )
        ,.WEBB                                                         ( PortBWriteEnable                        )
        ,.BWEBB                                                        ( BWEBB[383:256]                          )
        ,.AB                                                           ( PortBAddr[ADDRWIDTH-2:LSB]              )
        ,.DB                                                           ( PortBDataIn[383:256]                    )
        ,.QB                                                           ( U_QB[k][383:256]                        )
        ,.RTSEL                                                        ( 2'b00                                   )
        ,.WTSEL                                                        ( 2'b00                                   )
        ,.PTSEL                                                        ( 2'b00                                   )
        ); 
      tsdn28hpcpuhdb4096x128m4mw_170a U3_tsdn28hpcpuhdb4096x128m4mw_170a (
        .CLK                                                           ( PortClk                                 )
        ,.CEBA                                                         ( U_CEBA[k]                               )
        ,.WEBA                                                         ( PortAWriteEnable                        )
        ,.BWEBA                                                        ( BWEBA[511:384]                          )
        ,.AA                                                           ( PortAAddr[ADDRWIDTH-2:LSB]              )
        ,.DA                                                           ( PortADataIn[511:384]                    )
        ,.QA                                                           ( U_QA[k][511:384]                        )
        ,.CEBB                                                         ( U_CEBB[k]                               )
        ,.WEBB                                                         ( PortBWriteEnable                        )
        ,.BWEBB                                                        ( BWEBB[511:384]                          )
        ,.AB                                                           ( PortBAddr[ADDRWIDTH-2:LSB]              )
        ,.DB                                                           ( PortBDataIn[511:384]                    )
        ,.QB                                                           ( U_QB[k][511:384]                        )
        ,.RTSEL                                                        ( 2'b00                                   )
        ,.WTSEL                                                        ( 2'b00                                   )
        ,.PTSEL                                                        ( 2'b00                                   )
        ); 
    end
    always @(posedge PortClk) begin
        if(PortAWriteEnable == 1'b1) begin
          AA_1D_MSB <= PortAAddr[ADDRWIDTH-1];
        end
        else begin
          AA_1D_MSB <= AA_1D_MSB;
        end
    end
    always @(posedge PortClk) begin
        if(PortBWriteEnable == 1'b1) begin
          AB_1D_MSB <= PortBAddr[ADDRWIDTH-1];
        end
        else begin
          AB_1D_MSB <= AB_1D_MSB;
        end
    end
    assign PortADataOut = {DATAWIDTH{AA_1D_MSB == 1'h0}} & U_QA[0]
                        | {DATAWIDTH{AA_1D_MSB == 1'h1}} & U_QA[1]
                        ;
    assign PortBDataOut = {DATAWIDTH{AB_1D_MSB == 1'h0}} & U_QB[0]
                        | {DATAWIDTH{AB_1D_MSB == 1'h1}} & U_QB[1]
                        ;    
  end   
  else begin:dpram_model_generation
     dpram_model                                                    #(
      .DATAWIDTH                                                     ( DATAWIDTH                               )
     ,.ADDRWIDTH                                                     ( ADDRWIDTH-LSB                           )             
     ) U_dpram_model                                                 (                                         
      .PortClk                                                       ( PortClk                                 )
     ,.PortAWriteEnable                                              ( PortAWriteEnable                        )
     ,.PortAChipEnable                                               ( PortAChipEnable                         )
     ,.PortAByteWriteEnable                                          ( PortAByteWriteEnable                    )
     ,.PortAAddr                                                     ( PortAAddr[ADDRWIDTH-1:LSB]              )
     ,.PortADataIn                                                   ( PortADataIn                             )
     ,.PortADataOut                                                  ( PortADataOut                            )
     ,.PortBWriteEnable                                              ( PortBWriteEnable                        )
     ,.PortBChipEnable                                               ( PortBChipEnable                         )
     ,.PortBByteWriteEnable                                          ( PortBByteWriteEnable                    )
     ,.PortBAddr                                                     ( PortBAddr[ADDRWIDTH-1:LSB]              )
     ,.PortBDataIn                                                   ( PortBDataIn                             )
     ,.PortBDataOut                                                  ( PortBDataOut                            )
    );
  end
endgenerate
endmodule


