// =============================================================================
// Generated by efx_ipmgr
// Version: 2025.1.110.3.16
// IP Version: 6.1
// =============================================================================

////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2013-2025 Efinix Inc. All rights reserved.              
//
// This   document  contains  proprietary information  which   is        
// protected by  copyright. All rights  are reserved.  This notice       
// refers to original work by Efinix, Inc. which may be derivitive       
// of other work distributed under license of the authors.  In the       
// case of derivative work, nothing in this notice overrides the         
// original author's license agreement.  Where applicable, the           
// original license agreement is included in it's original               
// unmodified form immediately below this header.                        
//                                                                       
// WARRANTY DISCLAIMER.                                                  
//     THE  DESIGN, CODE, OR INFORMATION ARE PROVIDED “AS IS” AND        
//     EFINIX MAKES NO WARRANTIES, EXPRESS OR IMPLIED WITH               
//     RESPECT THERETO, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES,  
//     INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF          
//     MERCHANTABILITY, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR    
//     PURPOSE.  SOME STATES DO NOT ALLOW EXCLUSIONS OF AN IMPLIED       
//     WARRANTY, SO THIS DISCLAIMER MAY NOT APPLY TO LICENSEE.           
//                                                                       
// LIMITATION OF LIABILITY.                                              
//     NOTWITHSTANDING ANYTHING TO THE CONTRARY, EXCEPT FOR BODILY       
//     INJURY, EFINIX SHALL NOT BE LIABLE WITH RESPECT TO ANY SUBJECT    
//     MATTER OF THIS AGREEMENT UNDER TORT, CONTRACT, STRICT LIABILITY   
//     OR ANY OTHER LEGAL OR EQUITABLE THEORY (I) FOR ANY INDIRECT,      
//     SPECIAL, INCIDENTAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES OF ANY    
//     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF      
//     GOODWILL, DATA OR PROFIT, WORK STOPPAGE, OR COMPUTER FAILURE OR   
//     MALFUNCTION, OR IN ANY EVENT (II) FOR ANY AMOUNT IN EXCESS, IN    
//     THE AGGREGATE, OF THE FEE PAID BY LICENSEE TO EFINIX HEREUNDER    
//     (OR, IF THE FEE HAS BEEN WAIVED, $100), EVEN IF EFINIX SHALL HAVE 
//     BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES.  SOME STATES DO 
//     NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR            
//     CONSEQUENTIAL DAMAGES, SO THIS LIMITATION AND EXCLUSION MAY NOT   
//     APPLY TO LICENSEE.                                                
//
////////////////////////////////////////////////////////////////////////////////

`define IP_UUID _d8677c67c2bc4276a5dc804aa084ba36
`define IP_NAME_CONCAT(a,b) a``b
`define IP_MODULE_NAME(name) `IP_NAME_CONCAT(name,`IP_UUID)
module Dpbram_efnx_size8kB_a64b64
(
    input addren_a,
    input addren_b,
    input we_a,
    input we_b,
    input [9:0] addr_a,
    input [63:0] wdata_a,
    output [63:0] rdata_a,
    output [63:0] rdata_b,
    input [9:0] addr_b,
    input [63:0] wdata_b,
    input clk_a,
    input clk_b
);
`IP_MODULE_NAME(efx_bram)
#(
    .ADDR_WIDTH_A (10),
    .ADDR_WIDTH_B (10),
    .RESET_A_ENABLE (0),
    .RESET_B_ENABLE (0),
    .RSTA_POLARITY (1),
    .RSTB_POLARITY (1),
    .FAMILY ("TITANIUM"),
    .MEMORY_MODE ("SPEED"),
    .WRITE_MODE_A ("READ_FIRST"),
    .WRITE_MODE_B ("READ_FIRST"),
    .OUTPUT_REG_A (0),
    .OUTPUT_REG_B (0),
    .MEMORY_TYPE ("TDP_RAM"),
    .GROUP_DATA_WIDTH_B (64),
    .BYTEENA_ENABLE (0),
    .BYTEENB_ENABLE (0),
    .BYTEENA_POLARITY (1),
    .BYTEENB_POLARITY (1),
    .BYTEEN_WIDTH_A (1),
    .BYTEEN_WIDTH_B (1),
    .BYTEEN_ENABLE (0),
    .BYTEEN_POLARITY (1),
    .GROUP_DATA_WIDTH (64),
    .BYTEEN_WIDTH (1),
    .WIDTH_RATIO (4),
    .GROUP_DATA_WIDTH_A (64),
    .DATA_WIDTH_A (64),
    .DATA_WIDTH_B (64),
    .ADDREN_ENABLE (1),
    .ADDREN_POLARITY (1),
    .CLK_MODE (2),
    .CLKA_POLARITY (1),
    .CLKB_POLARITY (1),
    .CLKE_POLARITY (1),
    .CLKEA_POLARITY (1),
    .CLKEA_ENABLE (0),
    .RESET_OUTREG_A ("ASYNC"),
    .RESET_OUTREG_B ("ASYNC"),
    .RESET_RAM_B ("ASYNC"),
    .WEA_ENABLE (1),
    .WEA_POLARITY (1),
    .WEB_ENABLE (1),
    .WEB_POLARITY (1),
    .RADDREN_ENABLE (1),
    .RADDREN_POLARITY (1),
    .WADDREN_ENABLE (1),
    .WADDREN_POLARITY (1),
    .RCLK_POLARITY (1),
    .ADDREN_A_ENABLE (1),
    .ADDREN_B_ENABLE (1),
    .ADDRENA_POLARITY (1),
    .ADDRENB_POLARITY (1),
    .WE_ENABLE (1),
    .WE_POLARITY (1),
    .WCLKE_ENABLE (0),
    .WCLKE_POLARITY (1),
    .WCLK_POLARITY (1),
    .RESET_RAM_A ("ASYNC"),
    .RESET_RAM ("ASYNC"),
    .CLK_POLARITY (1),
    .OUTPUT_REG (0),
    .RE_POLARITY (1),
    .RE_ENABLE (1),
    .WRITE_MODE ("READ_FIRST"),
    .RESET_OUTREG ("ASYNC"),
    .RESET_ENABLE (1),
    .RST_POLARITY (1),
    .CLKEB_POLARITY (1),
    .CLKEB_ENABLE (0)
)
u_efx_bram
(
    .addren_a ( addren_a ),
    .addren_b ( addren_b ),
    .we_a ( we_a ),
    .we_b ( we_b ),
    .addr_a ( addr_a ),
    .wdata_a ( wdata_a ),
    .rdata_a ( rdata_a ),
    .rdata_b ( rdata_b ),
    .addr_b ( addr_b ),
    .wdata_b ( wdata_b ),
    .clk_a ( clk_a ),
    .clk_b ( clk_b )
);
endmodule

module `IP_MODULE_NAME(efx_bram) #(

parameter CLK_POLARITY      = 1'b1, 	//clk polarity;  0:falling edge; 1:rising edge
parameter CLKE_POLARITY     = 1'b1, 	//clke polarity for one clk mode; 0:active low; 1:active high
parameter CLKA_POLARITY     = 1'b1, 	//clk A polarity;  0:falling edge; 1:rising edge
parameter CLKEA_POLARITY    = 1'b1, 	//clke A polarity; 0:active low; 1:active high
parameter WEA_POLARITY	    = 1'b1, 	//we A polarity;    0:active low; 1:active high
parameter OUTPUT_REG_A   	= 1'b0, 	// Output register enable; 1:add pipe-line read register
parameter BYTEENA_POLARITY  = 1'b1,     // byteen polarity		0:active low; 1:active high 
parameter CLKB_POLARITY     = 1'b1, 	//clk A polarity;  0:falling edge; 1:rising edge
parameter CLKEB_POLARITY    = 1'b1, 	//clke A polarity; 0:active low; 1:active high
parameter WEB_POLARITY	    = 1'b1, 	//we B polarity;    0:active low; 1:active high
parameter OUTPUT_REG_B   	= 1'b0, 	// Output register enable; 1:add pipe-line read register
parameter BYTEENB_POLARITY  = 1'b1,     // byteen polarity		0:active low; 1:active high 
parameter WCLKE_POLARITY    = 1'b1, 	//wclke polarity; 0:active low; 1:active high
parameter WCLK_POLARITY     = 1'b1, 	//wclk polarity;  0:falling edge; 1:rising edge
parameter RCLK_POLARITY     = 1'b1, 	// rclk polarity; 0:falling edge; 1:rising edge
parameter WE_POLARITY	    = 1'b1, 	//we polarity;    0:active low; 1:active high
parameter RE_POLARITY       = 1'b1, 	// re polarity;	  0:active low  ; 1:active high
parameter OUTPUT_REG        = 1'b0, 	// Output register enable; 1:add pipe-line read register
parameter BYTEEN_POLARITY   = 1'b1,		//byteen polarity;    0:active low; 1:active high   
parameter WCLKE_ENABLE 		= 1'b1, 	//1: Enable  the port for waddren pin  ; 0: disable 
parameter WE_ENABLE 		= 1'b1,		//1: Enable  the port for WE pin ; 0: disable 
parameter RE_ENABLE 		= 1'b1,		//1: Enable  the port for RE pin ; 0: disable 
parameter BYTEEN_ENABLE 	= 1'b1,		//1: Enable  the port for Byteen pins ; 0: disable 
parameter RST_POLARITY 	    = 1'b1,    	// rst polarity
parameter RESET_RAM 	    = "ASYNC", 	// reset mode on ram;  "NONE": RST signals does not affect the RAM output.
										//					  "ASYNC": RAM output resets asynchronously to RCLK.
										//                     "SYNC": RAM output resets synchronously to RCLK. 
parameter RESET_OUTREG 	    = "ASYNC", 	// reset mode on output register
										//					   "NONE": RST signals does not affect the RAM output register		
										//					  "ASYNC": RAM output register resets asynchronously to RCLK.
parameter ADDREN_POLARITY   = 1'b1,    	// addren polarity
parameter RESET_ENABLE 		= 1'b1,		//1: Enable  the port for reset pin  ; 0: disable 
parameter ADDREN_ENABLE 	= 1'b1,		//1: Enable  the port for addren pin  ; 0: disable 
parameter CLK_MODE			= 2,		//1: ONE CLK Mode; CLK pin will provide the clock source to the memory
									    //2: TWO CLK Mode; wclk pin will provide the clock source for write operation ; rclk pin will provide the clock source for read operation
parameter WADDREN_POLARITY  = 1'b1,    	// waddren polarity
parameter RADDREN_POLARITY  = 1'b1,     // raddren polarity
parameter CLKEA_ENABLE 		= 1'b1, 	//1: Enalbe the port for clke_a pin  ; 0: dislable 
parameter WEA_ENABLE 		= 1'b1,		//1: Enable the port for we_a pin ; 0: disable 
parameter BYTEENA_ENABLE 	= 1'b1,		//1: Enable the port for Byteen_a pins ; 0: disable 
                                        //
parameter CLKEB_ENABLE 		= 1'b1, 	//1: Enalbe the port for clke_b pin  ; 0: dislable 
parameter WEB_ENABLE 		= 1'b1,		//1: Enable the port for we_b pin ; 0: disable 
parameter BYTEENB_ENABLE 	= 1'b1,		//1: Enable the port for Byteen_b pins ; 0: disable 
parameter RSTA_POLARITY 	= 1'b1,    	// rst A polarity
parameter RESET_RAM_A 	    = "ASYNC", 	// reset A mode on ram;  "NONE": RST signals does not affect the RAM output.
										//					  "ASYNC": RAM output resets asynchronously to RCLK.
										//                     "SYNC": RAM output resets synchronously to RCLK. 
parameter RESET_OUTREG_A 	= "ASYNC", 	// reset A mode on output register
										//					   "NONE": RST signals does not affect the RAM output register		
										//					  "ASYNC": RAM output register resets asynchronously to RCLK.
parameter ADDRENA_POLARITY  = 1'b1,    	// addrena polarity
parameter RSTB_POLARITY 	= 1'b1,    	// rst A polarity
parameter RESET_RAM_B 	    = "ASYNC", 	// reset A mode on ram;  "NONE": RST signals does not affect the RAM output.
										//					  "ASYNC": RAM output resets asynchronously to RCLK.
										//                     "SYNC": RAM output resets synchronously to RCLK. 
parameter RESET_OUTREG_B 	= "ASYNC", 	// reset A mode on output register
										//					   "NONE": RST signals does not affect the RAM output register		
										//					  "ASYNC": RAM output register resets asynchronously to RCLK.
parameter ADDRENB_POLARITY  = 1'b1,   	// addrenb polarity
parameter RESET_A_ENABLE 	= 1'b1,		//1: Enable the port for reset_a pin  ; 0: disable 
parameter ADDREN_A_ENABLE 	= 1'b1,		//1: Enable the port for addren_a pin  ; 0: disable 
parameter RESET_B_ENABLE 	= 1'b1,		//1: Enable the port for reset_b pin  ; 0: disable 
parameter ADDREN_B_ENABLE 	= 1'b1,		//1: Enable the port for addren_b pin  ; 0: disable 
parameter WADDREN_ENABLE 	= 1'b1,		//1: Enable the port for waddren pin  ; 0: disable 
parameter RADDREN_ENABLE 	= 1'b1,		//1: Enable the port for raddren pin  ; 0: disable 

parameter ADDR_WIDTH_A      = 3,
parameter DATA_WIDTH_A      = 16,
parameter ADDR_WIDTH_B      = 3,
parameter DATA_WIDTH_B      = 16,
parameter BYTEEN_WIDTH      = 2,
parameter BYTEEN_WIDTH_A    = 2,
parameter BYTEEN_WIDTH_B    = 2,
parameter MEMORY_TYPE		= "SP_RAM",  //1:sp_ram, 2:sdp_ram, 3:tdp_ram
parameter WRITE_MODE		= "READ_FIRST",
parameter WRITE_MODE_A		= "READ_FIRST",
parameter WRITE_MODE_B		= "READ_FIRST",
parameter FAMILY            = "TITANIUM",  //1:Titanium, 0:Trion
parameter GROUP_DATA_WIDTH  = 8,
parameter GROUP_DATA_WIDTH_A= 8,
parameter GROUP_DATA_WIDTH_B= 8,
parameter MEMORY_MODE       = "SPEED",  //1:speed, 2:area
parameter WIDTH_RATIO       = 4
)


(
//////////// data input/output ///////////////////
input wire [DATA_WIDTH_A-1:0] wdata_a,
input wire [DATA_WIDTH_B-1:0] wdata_b,
output wire [DATA_WIDTH_A-1:0] rdata_a,
output wire [DATA_WIDTH_B-1:0] rdata_b,

///////// Single Port RAM/ROM ports ////////////
input wire clk,
input wire [ADDR_WIDTH_A-1:0] addr,
input wire wclke,
input wire [BYTEEN_WIDTH-1:0] byteen,
input wire we,
input wire re,
//Titanium extra ports
input wire reset,
input wire addren,

//////////// Simple Dual Port RAM ports ///////////
input wire wclk,
input wire [ADDR_WIDTH_A-1:0] waddr,
input wire rclk,
input wire [ADDR_WIDTH_B-1:0] raddr,
//Titanium extra ports
input wire waddren,
input wire raddren,

//////////True Dual Port RAM/ROM ports ////////////////
input wire clke,
input wire clk_a, 
input wire clke_a,
input wire we_a,
input wire [BYTEEN_WIDTH_A-1:0] byteen_a,
input wire [ADDR_WIDTH_A-1:0 ] addr_a,
input wire clk_b, 
input wire clke_b,
input wire we_b,
input wire [BYTEEN_WIDTH_B-1:0] byteen_b,
input wire [ADDR_WIDTH_B-1:0 ] addr_b,
//Titanium extra ports
input wire reset_a,
input wire addren_a,
input wire reset_b,
input wire addren_b
);

generate
	if (MEMORY_TYPE == "SP_RAM") //Single Port RAM
	begin
		//if (BYTEEN_ENABLE == 1)
		//begin
		
	    `IP_MODULE_NAME(efx_single_port_ram) #(
	      .CLK_POLARITY    	(CLK_POLARITY   ),	
	      .WCLKE_POLARITY  	(WCLKE_POLARITY ),	
	      .WE_POLARITY	 	(WE_POLARITY	),	
	      .WRITE_MODE  	 	(WRITE_MODE  	),	
	      .RE_POLARITY     	(RE_POLARITY    ),	
	      .OUTPUT_REG      	(OUTPUT_REG     ),	
	      .BYTEEN_POLARITY 	(BYTEEN_POLARITY),	
	      .WCLKE_ENABLE 	(WCLKE_ENABLE 	),	
	      .WE_ENABLE 		(WE_ENABLE 		),	
	      .RE_ENABLE 		(RE_ENABLE 		),	
	      .BYTEEN_ENABLE 	(BYTEEN_ENABLE 	),
	      
	      .BYTEEN_WIDTH		(BYTEEN_WIDTH	),
	      .ADDR_WIDTH_A		(ADDR_WIDTH_A	),
	      .DATA_WIDTH_A		(DATA_WIDTH_A	),
	      
	      .FAMILY			(FAMILY			),
             
	         //Titanium extra paramters 
	      .RST_POLARITY 	(RST_POLARITY	), 	
	      .RESET_RAM 	    (RESET_RAM 	    ),
	      .RESET_OUTREG 	(RESET_OUTREG 	),
	      .ADDREN_POLARITY  (ADDREN_POLARITY),
	      .RESET_ENABLE 	(RESET_ENABLE 	),
	      .ADDREN_ENABLE 	(ADDREN_ENABLE 	)
        ) 
	    spram_inst
	    (
	      .clk		(clk	),
	      .addr		(addr	),
	      .wclke	(wclke	),
	      .byteen	(byteen	),
	      .we		(we		),
	      .wdata_a	(wdata_a),
	      .re		(re		),
	      .rdata_a	(rdata_a),
	      .reset	(reset	),
	      .addren	(addren	)
	    );
		//end
		//else if (BYTEEN_ENABLE == 0) 
		//begin
		//	
		//	`IP_MODULE_NAME(efx_single_port_ram) #(
		//      .CLK_POLARITY    	(CLK_POLARITY   ),	
	    //      .WCLKE_POLARITY  	(WCLKE_POLARITY ),	
	    //      .WE_POLARITY	 	(WE_POLARITY	),	
	    //      .WRITE_MODE  	 	(WRITE_MODE  	),	
	    //      .RE_POLARITY     	(RE_POLARITY    ),	
	    //      .OUTPUT_REG      	(OUTPUT_REG     ),	
	    //      .BYTEEN_POLARITY 	(BYTEEN_POLARITY),	
	    //      .WCLKE_ENABLE 	(WCLKE_ENABLE 	),	
	    //      .WE_ENABLE 		(WE_ENABLE 		),	
	    //      .RE_ENABLE 		(RE_ENABLE 		),	
	    //      .BYTEEN_ENABLE 	(BYTEEN_ENABLE 	),
	    //      
	    //      .BYTEEN_WIDTH		(BYTEEN_WIDTH	),
		//      .ADDR_WIDTH_A		(ADDR_WIDTH_A	),
		//      .DATA_WIDTH_A		(DATA_WIDTH_A	),
		//      .DATA_WIDTH_B		(DATA_WIDTH_B	),
		//      
		//      .FAMILY			(FAMILY			),
        //      
	    //      //Titanium extra paramters 
	    //      .RST_POLARITY 	(RST_POLARITY	), 	
	    //      .RESET_RAM 	    (RESET_RAM 	    ),
	    //      .RESET_OUTREG 	(RESET_OUTREG 	),
	    //      .ADDREN_POLARITY  (ADDREN_POLARITY),
	    //      .RESET_ENABLE 	(RESET_ENABLE 	),
	    //      .ADDREN_ENABLE 	(ADDREN_ENABLE 	)
        //    ) 
		//    spram_inst
		//    (
		//      .clk		(clk	),
		//      .addr		(addr	),
		//      .wclke	(wclke	),
		//      .we		(we		),
		//      .wdata_a(wdata_a),
		//      .re		(re		),
		//      .rdata_a(rdata_a),
		//      .reset	(reset	),
		//      .addren	(addren	)
		//    );
		//end
	end
	else if (MEMORY_TYPE == "SDP_RAM") //Simple Dual Port RAM
	begin
		
		`IP_MODULE_NAME(efx_simple_dual_port_ram) #(
	      .CLK_POLARITY    	(CLK_POLARITY   ),
	      .WCLK_POLARITY    (WCLK_POLARITY  ),		
	      .WCLKE_POLARITY  	(WCLKE_POLARITY ),	
	      .WE_POLARITY	 	(WE_POLARITY	),	
	      .WRITE_MODE  	 	(WRITE_MODE  	),	
	      
	      .RCLK_POLARITY    (RCLK_POLARITY  ),	
	      .RE_POLARITY     	(RE_POLARITY    ),	
	      .OUTPUT_REG      	(OUTPUT_REG     ),	
	      .BYTEEN_POLARITY 	(BYTEEN_POLARITY),
	      .CLK_MODE			(CLK_MODE),
	      .WCLKE_ENABLE 	(WCLKE_ENABLE 	),	
	      .WE_ENABLE 		(WE_ENABLE 		),	
	      .RE_ENABLE 		(RE_ENABLE 		),	
	      .BYTEEN_ENABLE 	(BYTEEN_ENABLE 	),
	      
	      .BYTEEN_WIDTH		(BYTEEN_WIDTH	),
		  .ADDR_WIDTH_A		(ADDR_WIDTH_A	),
		  .DATA_WIDTH_A		(DATA_WIDTH_A	),
		  .ADDR_WIDTH_B		(ADDR_WIDTH_B	),
		  .DATA_WIDTH_B		(DATA_WIDTH_B	),
		  
		  .FAMILY			(FAMILY			),
          
	      //Titanium extra paramters 
	      .RST_POLARITY 	(RST_POLARITY	), 	
	      .RESET_RAM 	    (RESET_RAM 	    ),
	      .RESET_OUTREG 	(RESET_OUTREG 	),
	      .RADDREN_POLARITY (RADDREN_POLARITY),
	      .WADDREN_POLARITY (WADDREN_POLARITY),
	      .RESET_ENABLE 	(RESET_ENABLE 	),
	      .RADDREN_ENABLE 	(RADDREN_ENABLE ),
	      .WADDREN_ENABLE 	(WADDREN_ENABLE)
	    )
	      sdpram_inst
		(
		  .clk		(clk		),
		  .wclk		(wclk		),
		  .wclke	(wclke		),
		  .byteen	(byteen		),
		  .we		(we			),
		  .waddr	(waddr		),
		  .wdata_a	(wdata_a	),
		  .rclk		(rclk		),
		  .re		(re			),
		  .raddr	(raddr		),
		  .rdata_b	(rdata_b	),
		  .reset	(reset		),
		  .waddren	(waddren	),
		  .raddren	(raddren	)
		  
		);
		
	end
	else if (MEMORY_TYPE == "TDP_RAM") //True Dual Port RAM
	begin
		
		`IP_MODULE_NAME(efx_true_dual_port_ram) #(
	
	      //Trion and Titanium parameters
	      .CLK_POLARITY    (CLK_POLARITY	),
	      .CLKE_POLARITY   (CLKE_POLARITY	),					
	      .CLKA_POLARITY   (CLKA_POLARITY   ),
	      .CLKEA_POLARITY  (CLKEA_POLARITY  ),
	      .WEA_POLARITY	   (WEA_POLARITY	),
	      .WRITE_MODE_A    (WRITE_MODE_A    ),
	      .OUTPUT_REG_A    (OUTPUT_REG_A    ),
	      .BYTEENA_POLARITY(BYTEENA_POLARITY),
	      .CLKB_POLARITY   (CLKB_POLARITY   ),
	      .CLKEB_POLARITY  (CLKEB_POLARITY  ),
	      .WEB_POLARITY	   (WEB_POLARITY    ),
	      .WRITE_MODE_B    (WRITE_MODE_B    ),
	      .OUTPUT_REG_B    (OUTPUT_REG_B    ),
	      .BYTEENB_POLARITY(BYTEENB_POLARITY),
	      
	      .BYTEEN_WIDTH_A	(BYTEEN_WIDTH_A	),
	      .BYTEEN_WIDTH_B	(BYTEEN_WIDTH_B	),
		  .ADDR_WIDTH_A		(ADDR_WIDTH_A	),
		  .DATA_WIDTH_A		(DATA_WIDTH_A	),
		  .ADDR_WIDTH_B		(ADDR_WIDTH_B	),
		  .DATA_WIDTH_B		(DATA_WIDTH_B	),
		  
		  .FAMILY			(FAMILY			),
	      
	      
	      //Port Enable  
	      .CLK_MODE		  (CLK_MODE		),			
	      .CLKEA_ENABLE   (CLKEA_ENABLE ),
	      .WEA_ENABLE 	  (WEA_ENABLE 	),	
	      .BYTEENA_ENABLE (BYTEENA_ENABLE ),   
	      .CLKEB_ENABLE   (CLKEB_ENABLE ),
	      .WEB_ENABLE 	  (WEB_ENABLE 	),	
	      .BYTEENB_ENABLE (BYTEENB_ENABLE ),
          
	      
	      //Titanium extra paramters 
	      .RSTA_POLARITY 	(RSTA_POLARITY 	   ),
	      .RESET_RAM_A 		(RESET_RAM_A 	   ),		  	
	      .RESET_OUTREG_A 	(RESET_OUTREG_A    ),
	      .ADDRENA_POLARITY (ADDRENA_POLARITY  ),
	      .RSTB_POLARITY 	(RSTB_POLARITY 	   ),
	      .RESET_RAM_B 	    (RESET_RAM_B 	   ),
	      .RESET_OUTREG_B 	(RESET_OUTREG_B    ),
	      .ADDRENB_POLARITY (ADDRENB_POLARITY  ),
          
	      //Port Enable  
	      .RESET_A_ENABLE 	(RESET_A_ENABLE ),
	      .ADDREN_A_ENABLE  (ADDREN_A_ENABLE),
	      .RESET_B_ENABLE 	(RESET_B_ENABLE ),
	      .ADDREN_B_ENABLE  (ADDREN_B_ENABLE)
	    ) 
	      tdpram_inst
		(
		  .clk		(clk	),
		  .clke		(clke	),
		  .clk_a	(clk_a	),
		  .clke_a	(clke_a	),
		  .we_a		(we_a	),
		  .byteen_a	(byteen_a),
		  .addr_a	(addr_a	),
		  .wdata_a	(wdata_a),
		  .rdata_a	(rdata_a),
		  .clk_b	(clk_b	),
		  .clke_b	(clke_b	),
		  .we_b		(we_b	),
		  .byteen_b	(byteen_b),
		  .addr_b	(addr_b	),
		  .wdata_b	(wdata_b),
		  .rdata_b	(rdata_b),
		  .reset_a	(reset_a),
		  .addren_a	(addren_a),
		  .reset_b	(reset_b),
		  .addren_b	(addren_b)
		  
		);
	end
	else if (MEMORY_TYPE == "SP_ROM") //Single Port ROM
	begin
		
		`IP_MODULE_NAME(efx_single_port_rom) #(
		
		  .CLK_POLARITY    	(CLK_POLARITY   ),	
	      .RE_POLARITY     	(RE_POLARITY    ),	
	      .OUTPUT_REG      	(OUTPUT_REG     ),	
	      .RE_ENABLE 		(RE_ENABLE 		),	
	      
	      .BYTEEN_WIDTH		(BYTEEN_WIDTH	),
		  .ADDR_WIDTH_A		(ADDR_WIDTH_A	),
		  .DATA_WIDTH_A		(DATA_WIDTH_A	),
		  .FAMILY           (FAMILY         ),
          
	      //Titanium extra paramters 
	      .RST_POLARITY 	(RST_POLARITY	), 	
	      .RESET_RAM 	    (RESET_RAM 	    ),
	      .RESET_OUTREG 	(RESET_OUTREG 	),
	      .ADDREN_POLARITY  (ADDREN_POLARITY),
	      .RESET_ENABLE 	(RESET_ENABLE 	),
	      .ADDREN_ENABLE 	(ADDREN_ENABLE 	)
	      
	    )
		sprom_inst
		(
		  .clk		(clk	),
		  .addr		(addr	),
		  .re		(re		),
		  .rdata_a	(rdata_a),
		  .reset	(reset	),
		  .addren	(addren)
		  
		);
	end
	else if (MEMORY_TYPE == "DP_ROM") //Dual Port ROM
	begin
		
		`IP_MODULE_NAME(efx_dual_port_rom) #(
	
	      //Trion and Titanium parameters
	      .CLK_POLARITY    ( CLK_POLARITY  ),
	      .CLKE_POLARITY   ( CLKE_POLARITY ),					
	      .CLKA_POLARITY   ( CLKA_POLARITY  ),
	      .CLKEA_POLARITY  ( CLKEA_POLARITY ),
	      
          .OUTPUT_REG_A    ( OUTPUT_REG_A   ),
	      .CLKB_POLARITY   ( CLKB_POLARITY  ),
	      .CLKEB_POLARITY  ( CLKEB_POLARITY ),
	      .OUTPUT_REG_B    ( OUTPUT_REG_B   ),
	      
	      
	      //Port Enable  
	      .CLK_MODE		(CLK_MODE		),			
	      .CLKEA_ENABLE (CLKEA_ENABLE 	),
	      .CLKEB_ENABLE (CLKEB_ENABLE 	),
	      
	      
	      //Titanium extra paramters 
	      .RSTA_POLARITY 	(RSTA_POLARITY 	   ),
	      .RESET_RAM_A 		(RESET_RAM_A 	   ),		  	
	      .RESET_OUTREG_A 	(RESET_OUTREG_A    ),
	      .ADDRENA_POLARITY (ADDRENA_POLARITY  ),
	      .RSTB_POLARITY 	(RSTB_POLARITY 	   ),
	      .RESET_RAM_B 	    (RESET_RAM_B 	   ),
	      .RESET_OUTREG_B 	(RESET_OUTREG_B    ),
	      .ADDRENB_POLARITY (ADDRENB_POLARITY  ),
          
	      //Port Enable  
	      .RESET_A_ENABLE 	(RESET_A_ENABLE ),
	      .ADDREN_A_ENABLE  (ADDREN_A_ENABLE),
	      .RESET_B_ENABLE 	(RESET_B_ENABLE ),
	      .ADDREN_B_ENABLE  (ADDREN_B_ENABLE),
	      
	      //DATA and ADDR
	      .DATA_WIDTH_A    (DATA_WIDTH_A),
	      .DATA_WIDTH_B    (DATA_WIDTH_B),
	      .ADDR_WIDTH_A    (ADDR_WIDTH_A),
	      .ADDR_WIDTH_B    (ADDR_WIDTH_B),
	      .FAMILY          (FAMILY)
	    )  
	      dprom_inst 
		(
		  .clk		(clk	),
		  .clke		(clke	),
		  .clk_a	(clk_a	),
		  .clke_a	(clke_a	),
		  .addr_a	(addr_a	),
		  .rdata_a	(rdata_a),
		  .clk_b	(clk_b	),
		  .clke_b	(clke_b	),
		  .addr_b	(addr_b	),
		  .rdata_b	(rdata_b),
		  .reset_a	(reset_a),
		  .addren_a	(addren_a),	
		  .reset_b	(reset_b),
		  .addren_b	(addren_b)
		  
		);
	end
endgenerate

endmodule























////////////////////////////////////////////////////////////////////////////
//           _____       
//          / _______    Copyright (C) 2013-2022 Efinix Inc. All rights reserved.
//         / /       \   
//        / /  ..    /   tb_top.v
//       / / .'     /    
//    __/ /.'      /     Description:
//   __   \       /    
//  /_/ /\ \_____/ /     
// ____/  \_______/      
//
// *******************************
// Revisions:
// 0.0 Initial rev
//
// *******************************

module `IP_MODULE_NAME(dpbram_primitive) #(
	parameter FAMILY = "TITANIUM",	//0:Trion,  1:Titanium
	
	//Trion and Titanium parameters 
	parameter WRITE_WIDTH_A	 = 8, 			// write width
	parameter CLKA_POLARITY  = 1'b1, 		//clk A polarity,  0:falling edge, 1:rising edge
	parameter CLKEA_POLARITY = 1'b1, 		//clke A polarity, 0:active low, 1:active high
	parameter WEA_POLARITY	 = 1'b1, 		//we A polarity,    0:active low, 1:active high
	parameter WRITE_MODE_A 	 = "READ_FIRST",//write mode A,  "READ_FIRST" 	:Old memory content is read. (default)
											//			  	  "WRITE_FIRST" :Write data is passed to the read port.
											//				  "READ_UNKNOWN": Read and writes are unsynchronized, therefore, the results of the address can conflict.
	parameter READ_WIDTH_A	 = 8,   		// read width A
	parameter OUTPUT_REG_A   = 1'b1, 		// Output register enable, 1:add pipe-line read register

	parameter WRITE_WIDTH_B	 = 8, 			// write width
	parameter CLKB_POLARITY  = 1'b1, 		//clk A polarity,  0:falling edge, 1:rising edge
	parameter CLKEB_POLARITY = 1'b1, 		//clke A polarity, 0:active low, 1:active high
	parameter WEB_POLARITY	 = 1'b1, 		//we A polarity,    0:active low, 1:active high
	parameter WRITE_MODE_B 	 = "READ_FIRST",//write mode A,  "READ_FIRST" 	:Old memory content is read. (default)
											//			  	  "WRITE_FIRST" :Write data is passed to the read port.
											//				  "READ_UNKNOWN": Read and writes are unsynchronized, therefore, the results of the address can conflict.
	parameter READ_WIDTH_B	 = 8,   		// read width A
	parameter OUTPUT_REG_B   = 1'b0, 		// Output register enable, 1:add pipe-line read register

	//Titanium extra paramters 
	parameter RSTA_POLARITY 	= 1'b1,    	// rst A polarity
	parameter RESET_RAM_A 	    = "ASYNC", 	// reset A mode on ram,  "NONE": RST signals does not affect the RAM output.
											//					  "ASYNC": RAM output resets asynchronously to RCLK.
											//                     "SYNC": RAM output resets synchronously to RCLK. 
	parameter RESET_OUTREG_A 	= "ASYNC", 	// reset A mode on output register
											//					   "NONE": RST signals does not affect the RAM output register		
											//					  "ASYNC": RAM output register resets asynchronously to RCLK.
	parameter ADDRENA_POLARITY  = 1'b1,    	// addrena polarity
	
	parameter RSTB_POLARITY 	= 1'b1,    	// rst A polarity
	parameter RESET_RAM_B 	    = "ASYNC", 	// reset A mode on ram,  "NONE": RST signals does not affect the RAM output.
											//					  "ASYNC": RAM output resets asynchronously to RCLK.
											//                     "SYNC": RAM output resets synchronously to RCLK. 
	parameter RESET_OUTREG_B 	= "ASYNC", 	// reset A mode on output register
											//					   "NONE": RST signals does not affect the RAM output register		
											//					  "ASYNC": RAM output register resets asynchronously to RCLK.
	parameter ADDRENB_POLARITY  = 1'b1,   	// addrenb polarity

	//Titanium Option for byte enable in WEN width = 2 when it is Mode 512x16 or  512x20
		
	parameter ini_index	 		= 0
						
)   
(
//Trion and Titanium ports
	CLKA, 		// A-port clk 
	CLKEA, 		// A-port clk enable 
	WEA, 		// A-port write enable 
	ADDRA, 		// A-port address input
	WDATAA, 	// A-port write data input
	RDATAA, 	// A-port read address output
	
	CLKB, 		// B-port clk 
	CLKEB, 		// B-port clk enable 
	WEB, 		// B-port write enable 
	ADDRB, 		// B-port address input
	WDATAB, 	// B-port write data input
	RDATAB, 	// B-port read address output

 //Titanium extra ports
    
	RSTA, // A-port reset 
	ADDRENA, // A-port address enable
	
	RSTB, // B-port reset 
	ADDRENB // B-port address enable
							
 );
function integer address_map;
input integer index;//Input data width parameter 
input integer type_; //Mapped data width, Mapped Address Width for Ram 5K(Trion), Mapped Address Width for Ram 10K(Titanium), WEN width for Ram 5K(Trion),  WEN width for Ram 10K(Titanium)
case (index)
0	: address_map=	(type_==0)?	1	:(type_==1)?	12	:(type_==2)?	13	:1;
1	: address_map=	(type_==0)?	1	:(type_==1)?	12	:(type_==2)?	13	:1;
2	: address_map=	(type_==0)?	2	:(type_==1)?	11	:(type_==2)?	12	:1;
3	: address_map=	(type_==0)?	4	:(type_==1)?	10	:(type_==2)?	11	:1;
4	: address_map=	(type_==0)?	4	:(type_==1)?	10	:(type_==2)?	11	:1;
5	: address_map=	(type_==0)?	5	:(type_==1)?	10	:(type_==2)?	11	:1;
6	: address_map=	(type_==0)?	8	:(type_==1)?	9	:(type_==2)?	10	:1;
7	: address_map=	(type_==0)?	8	:(type_==1)?	9	:(type_==2)?	10	:1;
8	: address_map=	(type_==0)?	8	:(type_==1)?	9	:(type_==2)?	10	:1;
9	: address_map=	(type_==0)?	10	:(type_==1)?	9	:(type_==2)?	10	:1;
10	: address_map=	(type_==0)?	10	:(type_==1)?	9	:(type_==2)?	10	:1;
   endcase
endfunction  

localparam  WRITE_DATA_WIDTH_A		= 	address_map(WRITE_WIDTH_A,0);
localparam  WRITE_ADDRESS_WIDTH_A   = 	address_map(WRITE_WIDTH_A,(FAMILY=="TRION")?1:2);

localparam  WRITE_DATA_WIDTH_B		= 	address_map(WRITE_WIDTH_B,0);
localparam  WRITE_ADDRESS_WIDTH_B   = 	address_map(WRITE_WIDTH_B,(FAMILY=="TRION")?1:2);

//Trion and Titanium ports
input	CLKA; 		// A-port clk 
input	CLKEA; 		// A-port clk enable 
input	[0:0] WEA; 	// A-port write enable 
input	[WRITE_ADDRESS_WIDTH_A-1:0] ADDRA; 	// A-port address input
input	[WRITE_DATA_WIDTH_A-1:0] WDATAA; 	// A-port write data input
output	[WRITE_DATA_WIDTH_A-1:0] RDATAA; 	// A-port read address output
	
input	CLKB; 		// B-port clk 
input	CLKEB; 		// B-port clk enable 
input	[0:0] WEB; 	// B-port write enable 
input	[WRITE_ADDRESS_WIDTH_B-1:0] ADDRB; 		// B-port address input
input	[WRITE_DATA_WIDTH_B-1:0] WDATAB; 	// B-port write data input
output	[WRITE_DATA_WIDTH_B-1:0] RDATAB; 	// B-port read address output

 //Titanium extra ports
    
input RSTA; // A-port reset 
input ADDRENA; // A-port address enable
	
input RSTB; // B-port reset 
input ADDRENB; // B-port address enable


`include "bram_ini.vh"
 
    generate 
		if (FAMILY=="TRION")
		begin
			EFX_DPRAM_5K # (
				.WRITE_WIDTH_A (WRITE_WIDTH_A), 
				.CLKA_POLARITY (CLKA_POLARITY), // clka polarity
				.CLKEA_POLARITY (CLKEA_POLARITY), // clkea polarity
				.WEA_POLARITY (WEA_POLARITY), // wea polarity
				.WRITE_MODE_A (WRITE_MODE_A), // A-port write mode
				
				.READ_WIDTH_A (READ_WIDTH_A), // A-port read width				
				.OUTPUT_REG_A (OUTPUT_REG_A), // A-port output register enable
	

				.WRITE_WIDTH_B (WRITE_WIDTH_B), // B-port write width
				.CLKB_POLARITY (CLKB_POLARITY), // clkb polarity
				.CLKEB_POLARITY(CLKEB_POLARITY), // clkeb polarity
				.WEB_POLARITY  (WEB_POLARITY), // web polarity
				.WRITE_MODE_B  (WRITE_MODE_B), // B-port write mode
				
				.READ_WIDTH_B  (READ_WIDTH_B), // B-port read width
				.OUTPUT_REG_B  (OUTPUT_REG_B), // B-port output register enable
 
			
				.INIT_0  (bram_ini_table(ini_index,16'h0 )), 
				.INIT_1  (bram_ini_table(ini_index,16'h1 )),
				.INIT_2  (bram_ini_table(ini_index,16'h2 )),
				.INIT_3  (bram_ini_table(ini_index,16'h3 )),
				.INIT_4  (bram_ini_table(ini_index,16'h4 )),
				.INIT_5  (bram_ini_table(ini_index,16'h5 )),
				.INIT_6  (bram_ini_table(ini_index,16'h6 )),
				.INIT_7  (bram_ini_table(ini_index,16'h7 )),
				.INIT_8  (bram_ini_table(ini_index,16'h8 )),
				.INIT_9  (bram_ini_table(ini_index,16'h9 )),
				.INIT_A  (bram_ini_table(ini_index,16'hA )),
				.INIT_B  (bram_ini_table(ini_index,16'hB )),
				.INIT_C  (bram_ini_table(ini_index,16'hC )),
				.INIT_D  (bram_ini_table(ini_index,16'hD )),
				.INIT_E  (bram_ini_table(ini_index,16'hE )),
				.INIT_F  (bram_ini_table(ini_index,16'hF )),
				.INIT_10 (bram_ini_table(ini_index,16'h10)),
				.INIT_11 (bram_ini_table(ini_index,16'h11)),
				.INIT_12 (bram_ini_table(ini_index,16'h12)),
				.INIT_13 (bram_ini_table(ini_index,16'h13))
			) 
			 dpram5k (
				//Trion and Titanium ports
				.CLKA (CLKA), // A-port clk 
				.CLKEA (CLKEA), // A-port clk enable 
				.WEA (WEA), // A-port write enable 
				.ADDRA (ADDRA), // A-port address input
				.WDATAA (WDATAA), // A-port write data input
				.RDATAA (RDATAA), // A-port read address output
				
				.CLKB (CLKB), // B-port clk 
				.CLKEB (CLKEB), // B-port clk enable 
				.WEB (WEB), // B-port write enable 
				.ADDRB (ADDRB), // B-port address input
				.WDATAB (WDATAB), // B-port write data input
				.RDATAB (RDATAB) // B-port read address output
			
			);
		end 
		else 
		begin 
			
			EFX_DPRAM10 # (
			
				.WRITE_WIDTH_A (WRITE_WIDTH_A), 
				.CLKA_POLARITY (CLKA_POLARITY), // clka polarity
				.CLKEA_POLARITY (CLKEA_POLARITY), // clkea polarity
				.WEA_POLARITY (WEA_POLARITY), // wea polarity
				.WRITE_MODE_A (WRITE_MODE_A), // A-port write mode
				
				.READ_WIDTH_A (READ_WIDTH_A), // A-port read width				
				.OUTPUT_REG_A (OUTPUT_REG_A), // A-port output register enable
	

				.WRITE_WIDTH_B (WRITE_WIDTH_B), // B-port write width
				.CLKB_POLARITY (CLKB_POLARITY), // clkb polarity
				.CLKEB_POLARITY(CLKEB_POLARITY), // clkeb polarity
				.WEB_POLARITY  (WEB_POLARITY), // web polarity
				.WRITE_MODE_B  (WRITE_MODE_B), // B-port write mode
				
				.READ_WIDTH_B  (READ_WIDTH_B), // B-port read width
				.OUTPUT_REG_B  (OUTPUT_REG_B), // B-port output register enable
			
			
				//Titanium extra paramters 
                .RSTA_POLARITY 	(RSTA_POLARITY), // rsta polarity
				.RESET_RAM_A 	(RESET_RAM_A), // A-port reset mode on ram 
 				.RESET_OUTREG_A 	(RESET_OUTREG_A), // A-port reset mode on output register
				.ADDRENA_POLARITY 	(ADDRENA_POLARITY), // addrena polarity

				.RSTB_POLARITY 		(RSTB_POLARITY), // rstb polarity
				.RESET_RAM_B 		(RESET_RAM_B), // B-port reset mode on ram 
 				.RESET_OUTREG_B 	(RESET_OUTREG_B), // B-port reset mode on output register
 				.ADDRENB_POLARITY 	(ADDRENB_POLARITY), // addrenb polarity
							
				
				.INIT_0  (bram_ini_table(ini_index, 16'h0 )), 
				.INIT_1  (bram_ini_table(ini_index, 16'h1 )),
				.INIT_2  (bram_ini_table(ini_index, 16'h2 )),
				.INIT_3  (bram_ini_table(ini_index, 16'h3 )),
				.INIT_4  (bram_ini_table(ini_index, 16'h4 )),
				.INIT_5  (bram_ini_table(ini_index, 16'h5 )),
				.INIT_6  (bram_ini_table(ini_index, 16'h6 )),
				.INIT_7  (bram_ini_table(ini_index, 16'h7 )),
				.INIT_8  (bram_ini_table(ini_index, 16'h8 )),
				.INIT_9  (bram_ini_table(ini_index, 16'h9 )),
				.INIT_A  (bram_ini_table(ini_index, 16'hA )),
				.INIT_B  (bram_ini_table(ini_index, 16'hB )),
				.INIT_C  (bram_ini_table(ini_index, 16'hC )),
				.INIT_D  (bram_ini_table(ini_index, 16'hD )),
				.INIT_E  (bram_ini_table(ini_index, 16'hE )),
				.INIT_F  (bram_ini_table(ini_index, 16'hF )),
				.INIT_10 (bram_ini_table(ini_index, 16'h10)),
				.INIT_11 (bram_ini_table(ini_index, 16'h11)),
				.INIT_12 (bram_ini_table(ini_index, 16'h12)),
				.INIT_13 (bram_ini_table(ini_index, 16'h13)),
				.INIT_14 (bram_ini_table(ini_index, 16'h14)),
				.INIT_15 (bram_ini_table(ini_index, 16'h15)),
				.INIT_16 (bram_ini_table(ini_index, 16'h16)),
				.INIT_17 (bram_ini_table(ini_index, 16'h17)),
				.INIT_18 (bram_ini_table(ini_index, 16'h18)),
				.INIT_19 (bram_ini_table(ini_index, 16'h19)),
				.INIT_1A (bram_ini_table(ini_index, 16'h1A)),
				.INIT_1B (bram_ini_table(ini_index, 16'h1B)),
				.INIT_1C (bram_ini_table(ini_index, 16'h1C)),
				.INIT_1D (bram_ini_table(ini_index, 16'h1D)),
				.INIT_1E (bram_ini_table(ini_index, 16'h1E)),
				.INIT_1F (bram_ini_table(ini_index, 16'h1F)),
				.INIT_20 (bram_ini_table(ini_index, 16'h20)),
				.INIT_21 (bram_ini_table(ini_index, 16'h21)),
				.INIT_22 (bram_ini_table(ini_index, 16'h22)),
				.INIT_23 (bram_ini_table(ini_index, 16'h23)),
				.INIT_24 (bram_ini_table(ini_index, 16'h24)),
				.INIT_25 (bram_ini_table(ini_index, 16'h25)),
				.INIT_26 (bram_ini_table(ini_index, 16'h26)),
				.INIT_27 (bram_ini_table(ini_index, 16'h27))
		
			)
			dpram10k(
				//Trion and Titanium ports
				.CLKA (CLKA), // A-port clk 
				.CLKEA (CLKEA), // A-port clk enable 
				.WEA (WEA), // A-port write enable 
				.ADDRA (ADDRA), // A-port address input
				.WDATAA (WDATAA), // A-port write data input
				.RDATAA (RDATAA), // A-port read address output
				
				.CLKB (CLKB), // B-port clk 
				.CLKEB (CLKEB), // B-port clk enable 
				.WEB (WEB), // B-port write enable 
				.ADDRB (ADDRB), // B-port address input
				.WDATAB (WDATAB), // B-port write data input
				.RDATAB (RDATAB), // B-port read address output
			
			
				//Titanium extra ports
				
				.RSTA (RSTA), // A-port reset 
				.ADDRENA (ADDRENA), // A-port address enable
				
				.RSTB (RSTB), // B-port reset 
				.ADDRENB (ADDRENB) // B-port address enable
				

			);
		end
	endgenerate 
      
endmodule

////////////////////////////////////////////////////////////////////////////
//           _____       
//          / _______    Copyright (C) 2013-2022 Efinix Inc. All rights reserved.
//         / /       \   
//        / /  ..    /   tb_top.v
//       / / .'     /    
//    __/ /.'      /     Description:
//   __   \       /    
//  /_/ /\ \_____/ /     
// ____/  \_______/      
//
// *******************************
// Revisions:
// 0.0 Initial rev
// 1.0 Fixed No-Change Mode Issue (Addressing More than One Bram from Read Mux),  11 March  2025 A
// *******************************

module `IP_MODULE_NAME(dpram_wrapper_mwm) #(
	//Trion and Titanium parameters 
	parameter CLKA_POLARITY  = 1'b1, 		//clk A polarity,  0:falling edge, 1:rising edge
	parameter CLKEA_POLARITY = 1'b1, 		//clke A polarity, 0:active low, 1:active high
	parameter WEA_POLARITY	 = 1'b1, 		//we A polarity,    0:active low, 1:active high
	parameter WRITE_MODE_A 	 = "READ_FIRST",//write mode A,  "READ_FIRST" 	:Old memory content is read. (default)
											//			  	  "WRITE_FIRST" :Write data is passed to the read port.
											//				  "NO_CHANGE": Previously read data is held.
											
	parameter OUTPUT_REG_A   = 1'b0, 		// Output register enable, 1:add pipe-line read register
	parameter BYTEENA_POLARITY   = 1'b1,     // byteen polarity		0:active low, 1:active high 
	
	parameter CLKB_POLARITY  = 1'b1, 		//clk A polarity,  0:falling edge, 1:rising edge
	parameter CLKEB_POLARITY = 1'b1, 		//clke A polarity, 0:active low, 1:active high
	parameter WEB_POLARITY	 = 1'b1, 		//we B polarity,    0:active low, 1:active high
	parameter WRITE_MODE_B 	 = "READ_FIRST",//write mode A,  "READ_FIRST" 	:Old memory content is read. (default)
											//			  	  "WRITE_FIRST" :Write data is passed to the read port.
											//				  "NO_CHANGE": Previously read data is held.
	
	parameter OUTPUT_REG_B   = 1'b0, 		// Output register enable, 1:add pipe-line read register
	parameter BYTEENB_POLARITY   = 1'b1,     // byteen polarity		0:active low, 1:active high 
	
	//Titanium extra paramters 
	parameter RSTA_POLARITY 	= 1'b1,    	// rst A polarity
	parameter RESET_RAM_A 	    = "ASYNC", 	// reset A mode on ram,  "NONE": RST signals does not affect the RAM output.
											//					  "ASYNC": RAM output resets asynchronously to RCLK.
											//                     "SYNC": RAM output resets synchronously to RCLK. 
	parameter RESET_OUTREG_A 	= "ASYNC", 	// reset A mode on output register
											//					   "NONE": RST signals does not affect the RAM output register		
											//					  "ASYNC": RAM output register resets asynchronously to RCLK.
	parameter ADDRENA_POLARITY  = 1'b1,    	// addrena polarity
	
	parameter RSTB_POLARITY 	= 1'b1,    	// rst A polarity
	parameter RESET_RAM_B 	    = "ASYNC", 	// reset A mode on ram,  "NONE": RST signals does not affect the RAM output.
											//					  "ASYNC": RAM output resets asynchronously to RCLK.
											//                     "SYNC": RAM output resets synchronously to RCLK. 
	parameter RESET_OUTREG_B 	= "ASYNC", 	// reset A mode on output register
											//					   "NONE": RST signals does not affect the RAM output register		
											//					  "ASYNC": RAM output register resets asynchronously to RCLK.
	parameter ADDRENB_POLARITY  = 1'b1,   	// addrenb polarity
	
    parameter DATA_WIDTH_A          = 16,
    parameter DATA_WIDTH_B          = 16,
    parameter ADDR_WIDTH_A          = 4,
    parameter ADDR_WIDTH_B          = 4,
    parameter BYTEEN_WIDTH_A        = 2,
    parameter BYTEEN_WIDTH_B        = 2,
    parameter FAMILY                = "TITANIUM"
	

	//Titanium Option for byte enable in WEN width = 2 when it is Mode 512x16 or  512x20
)   
(
	//Trion and Titanium ports
	clk_a, 		// A-port clk
	clke_a,		// A-port clk enable
    byteen_a,	// A-port Byteen input 
    we_a, 		// A-port write enable 
	addr_a, 	// A-port address input
    wdata_a,	// A-port write data input
	rdata_a, 	// A-port read address output
  
	clk_b, 		// B-port clk
	clke_b,		// B-port clk enable
    byteen_b,	// B-port Byteen input 
    we_b, 		// B-port write enable 
	addr_b, 	// B-port address input
    wdata_b,	// B-port write data input
	rdata_b, 	// B-port read address output
	     
	//Titanium extra ports
	reset_a,	// A-port reset 
	addren_a,	// A-port address enable
	
	reset_b,	// B-port reset 
	addren_b	// B-port address enable
	
 );

`include "bram_decompose.vh"
//`include "bram_feature.vh"

input clk_a; 
input clke_a;
input we_a;
input [BYTEEN_WIDTH_A-1:0] byteen_a;
input [ADDR_WIDTH_A-1:0 ] addr_a; 
input [DATA_WIDTH_A-1:0 ] wdata_a;
output [DATA_WIDTH_A-1:0 ]rdata_a;

input clk_b; 
input clke_b;
input we_b;
input [BYTEEN_WIDTH_B-1:0] byteen_b;
input [ADDR_WIDTH_B-1:0 ] addr_b; 
input [DATA_WIDTH_B-1:0 ] wdata_b;
output [DATA_WIDTH_B-1:0 ]rdata_b;

input reset_a;
input addren_a;

input reset_b;
input addren_b;


localparam MAP_ADDR_WIDTH_A = (address_mapping_table_A_size!=0)?address_mapping_table_A_size:ADDR_WIDTH_A;
localparam MAP_ADDR_WIDTH_B = (address_mapping_table_B_size!=0)?address_mapping_table_B_size:ADDR_WIDTH_B;



wire [MAP_ADDR_WIDTH_A-1:0 ] w_addr_map_a; 
wire [DATA_WIDTH_A-1:0 ] w_wdata_map_a;
wire [DATA_WIDTH_A-1:0 ] w_rdata_map_a;

wire [MAP_ADDR_WIDTH_B-1:0 ] w_addr_map_b; 
wire [DATA_WIDTH_B-1:0 ] w_wdata_map_b;
wire [DATA_WIDTH_B-1:0 ] w_rdata_map_b;

wire clk_a_i;
wire clk_b_i;
assign clk_a_i = clk_a ~^ CLKA_POLARITY;
assign clk_b_i = clk_b ~^ CLKB_POLARITY;


//Reset Support Titanium Only
wire ram_async_rsta; 
wire ram_sync_rsta;
wire outreg_async_rsta;

wire ram_async_rstb; 
wire ram_sync_rstb;
wire outreg_async_rstb;

assign outreg_async_rsta = (RESET_OUTREG_A == "ASYNC") ? (reset_a ~^ RSTA_POLARITY) : 1'b0;
assign ram_async_rsta    = (RESET_RAM_A == "ASYNC")    ? (reset_a ~^ RSTA_POLARITY) : 1'b0;
assign ram_sync_rsta     = (RESET_RAM_A == "SYNC")     ? (reset_a ~^ RSTA_POLARITY) : 1'b0;

assign outreg_async_rstb = (RESET_OUTREG_B == "ASYNC") ? (reset_b ~^ RSTB_POLARITY) : 1'b0;
assign ram_async_rstb    = (RESET_RAM_B == "ASYNC")    ? (reset_b ~^ RSTB_POLARITY) : 1'b0;
assign ram_sync_rstb     = (RESET_RAM_B == "SYNC")     ? (reset_b ~^ RSTB_POLARITY) : 1'b0;


function integer get_current_row_index;
input integer row;//Mode type 
integer x;	
	begin
		get_current_row_index = 0;
		for (x=0; x<bram_mapping_size; x=x+1)
		begin
			if (bram_mapping_table(x,0) < row)
				get_current_row_index = get_current_row_index +1;
		end
	end 
endfunction 

function integer get_current_column_index;
input integer column;//Mode type 
integer x;	
	begin
		get_current_column_index = 0;
		for (x=0; x<bram_mapping_size; x=x+1)
		begin
			if (bram_mapping_table(x,1) < column)
				get_current_column_index = get_current_column_index +1;
		end
	end 
endfunction 


function integer get_max_mux_row_A;
input integer temp;//Mode type
integer x;	
	begin
		get_max_mux_row_A = 0;
		for (x=0; x<bram_mapping_size; x=x+1)
		begin
			if ( get_max_mux_row_A < bram_mapping_table(x,5) )
				get_max_mux_row_A =  bram_mapping_table(x,5);
		end
	end 
endfunction 

function integer get_max_wen_decode_A;
input integer temp;//Mode type
integer x;	
	begin
		get_max_wen_decode_A = 0;
		for (x=0; x<bram_mapping_size; x=x+1)
		begin
			if ( get_max_wen_decode_A < bram_mapping_table(x,6) )
				get_max_wen_decode_A =  bram_mapping_table(x,6);
		end
	end 
endfunction 


function integer get_max_mux_row_B;
input integer temp;//Mode type
integer x;	
	begin
		get_max_mux_row_B = 0;
		for (x=0; x<bram_mapping_size; x=x+1)
		begin
			if ( get_max_mux_row_B < bram_mapping_table(x,12) )
				get_max_mux_row_B =  bram_mapping_table(x,12);
		end
	end 
endfunction 

function integer get_max_wen_decode_B;
input integer temp;//Mode type
integer x;	
	begin
		get_max_wen_decode_B = 0;
		for (x=0; x<bram_mapping_size; x=x+1)
		begin
			if ( get_max_wen_decode_B < bram_mapping_table(x,13) )
				get_max_wen_decode_B =  bram_mapping_table(x,13);
		end
	end 
endfunction 



 //   localparam column_size = (bram_table_loop_mode==1)?bram_table_size:1;
   // wire [DATA_WIDTH_B-1:0] w_rdata [bram_table_size-1:0 ];
   // assign rdata = w_rdata[wdata];
    genvar gen_x;
    genvar gen_y;
	genvar gen_z;
	
    generate
			
		wire [DATA_WIDTH_A-1:0 ] rMux_a [get_max_mux_row_A(0):0]; 
		
		if (rMux_mapping_A_size == 0) 
        begin
			if(WRITE_MODE_A == "NO_CHANGE")
			begin
				wire w_clke_a = clke_a ~^ CLKEA_POLARITY;
				wire w_read_hold_a = (we_a == WEA_POLARITY);
				reg r_read_hold_a_1P = 1'b0;
				reg [DATA_WIDTH_A-1:0 ] r_rMux_hold_a ;
				
				if (OUTPUT_REG_A == 0)
				begin
				
					if (FAMILY == "TRION")
					begin 
						always @ (posedge clk_a_i)
						begin
							if(!r_read_hold_a_1P)
								r_rMux_hold_a <= rMux_a[0];
							
							if (w_clke_a)
								r_read_hold_a_1P <= w_read_hold_a;
						end
					end 
					else 
					begin //TITANIUM
						always @ (posedge clk_a_i or posedge ram_async_rsta)
						begin
							if (ram_async_rsta)
							begin 
								r_rMux_hold_a <= {DATA_WIDTH_A{1'b0}};
								r_read_hold_a_1P  <= 1'b0;
							end 
							else 
							begin 
								if(ram_sync_rsta)
								begin 
									r_rMux_hold_a <= {DATA_WIDTH_A{1'b0}};
									r_read_hold_a_1P  <= 1'b0;
								end 
								else 
								begin 
									if(!r_read_hold_a_1P)
										r_rMux_hold_a <= rMux_a[0];
									
									if (w_clke_a)
										r_read_hold_a_1P <= w_read_hold_a;
										
								end 
							end 
						end
			
					end 
					assign w_rdata_map_a = (r_read_hold_a_1P) ?  r_rMux_hold_a : rMux_a[0];
				
				
				end
				else
				begin//Out Reg = 1
					reg r_read_hold_a_2P = 1'b0;
					
					if (FAMILY == "TRION")
					begin
					
						always @ (posedge clk_a_i)
						begin
							if(!r_read_hold_a_2P)
								r_rMux_hold_a <= rMux_a[0];
							
							if (w_clke_a)
							begin
								r_read_hold_a_1P <= w_read_hold_a;
							end
							
							if ((FAMILY == "TITANIUM" && w_clke_a) || (FAMILY == "TRION"))
							begin
								r_read_hold_a_2P <= r_read_hold_a_1P;
							end
						end
						assign w_rdata_map_a = (r_read_hold_a_2P) ?  r_rMux_hold_a : rMux_a[0];
					end 
					else 
					begin //TITANIUM
						reg [DATA_WIDTH_A-1:0 ] r_rMux_hold_a_1P ;
						always @ (posedge clk_a_i or posedge ram_async_rsta)
						begin
							if (ram_async_rsta)
							begin 
								r_rMux_hold_a <= {DATA_WIDTH_A{1'b0}};
								r_read_hold_a_1P <= 1'b0;
								r_read_hold_a_2P <= 1'b0;
							end 
							else 
							begin 
								if(ram_sync_rsta)
								begin 
									r_rMux_hold_a <= {DATA_WIDTH_A{1'b0}};
									r_read_hold_a_1P <= 1'b0;
									r_read_hold_a_2P <= 1'b0;
								end 
								else 
								begin 
									if(!r_read_hold_a_2P)
										r_rMux_hold_a <= rMux_a[0];
									
									if (w_clke_a)
									begin 
										r_read_hold_a_1P <= w_read_hold_a;
										r_read_hold_a_2P <= r_read_hold_a_1P;

									end 	
								end 
							end 
						end
						always @ (posedge clk_a_i or posedge outreg_async_rsta)
						begin
							if (outreg_async_rsta)
							begin
								r_rMux_hold_a_1P <= {DATA_WIDTH_A{1'b0}};
							end
							else 
							begin
								if (w_clke_a)
									r_rMux_hold_a_1P <= r_rMux_hold_a;
							
							end 
						end 
						
						assign w_rdata_map_a = (r_read_hold_a_2P) ?  r_rMux_hold_a : rMux_a[0];
					
					
					end
					
					
					
				end
			end 
			else 
			begin
				assign w_rdata_map_a = rMux_a[0];
			end 
        end 
        else 
        begin
		
            for (gen_y=0; gen_y<rMux_mapping_A_size; gen_y =gen_y +1)
            begin:rDataMux_a
                localparam ADDR_START = rMux_mapping_table_A(gen_y,1);
                localparam ADDR_END   = rMux_mapping_table_A(gen_y,0);
                
                localparam DATA_START = rMux_mapping_table_A(gen_y,3);
                localparam DATA_END   = rMux_mapping_table_A(gen_y,2);
				
				localparam BYPRASSED  = rMux_mapping_table_A(gen_y,6);
								
                if( BYPRASSED == 0 )
				begin 
				
					wire [ADDR_END:ADDR_START] rdSel = w_addr_map_a[ADDR_END:ADDR_START];
					reg [ADDR_END:ADDR_START] r_rdSel_1P = {(ADDR_END-ADDR_START+1){1'b0}};
					wire w_clke_a = clke_a ~^ CLKEA_POLARITY;
					wire w_addren_a = FAMILY == "TRION" ? 1'b1 : addren_a ~^ ADDRENA_POLARITY;
					reg [DATA_END:DATA_START] r_rMux_hold_a ;
					
					
					if(WRITE_MODE_A == "NO_CHANGE")
					begin
						//Hold Address for read if WE and No-Change Mode. 
						wire w_read_hold_a = (we_a == WEA_POLARITY);  
						reg r_read_hold_a_1P = 1'b0;
						
						
						always @ (posedge clk_a_i)
						begin
							if(w_clke_a & w_addren_a) 
								r_rdSel_1P <= rdSel;
						end
						
						if (OUTPUT_REG_A == 0)
						begin
							if (FAMILY == "TRION")
							begin 
								always @ (posedge clk_a_i)
								begin
									if(!r_read_hold_a_1P)
										r_rMux_hold_a[DATA_END:DATA_START] <= rMux_a[r_rdSel_1P][DATA_END:DATA_START];
							
									if (w_clke_a)
										r_read_hold_a_1P <= w_read_hold_a;
								end
							end 
							else 
							begin //TITANIUM
								always @ (posedge clk_a_i or posedge ram_async_rsta)
								begin
									if (ram_async_rsta)
									begin 
										r_rMux_hold_a <= {(DATA_END-DATA_START+1){1'b0}};
										r_read_hold_a_1P  <= 1'b0;
									end 
									else 
									begin 
										if(ram_sync_rsta)
										begin 
											r_rMux_hold_a <= {(DATA_END-DATA_START+1){1'b0}};
											r_read_hold_a_1P  <= 1'b0;
										end 
										else 
										begin 
											if(!r_read_hold_a_1P)
												r_rMux_hold_a[DATA_END:DATA_START] <= rMux_a[r_rdSel_1P][DATA_END:DATA_START];
											
											if (w_clke_a)
												r_read_hold_a_1P <= w_read_hold_a;
												
										end 
									end 
								end
							end 
							
							assign w_rdata_map_a[DATA_END:DATA_START] = (r_read_hold_a_1P) ?  r_rMux_hold_a[DATA_END:DATA_START] : rMux_a[r_rdSel_1P][DATA_END:DATA_START];
						end
						else
						begin//Out Reg =1
							reg [ADDR_END:ADDR_START] r_rdSel_2P = {(ADDR_END-ADDR_START+1){1'b0}};
							reg r_read_hold_a_2P = 1'b0;
							always @ (posedge clk_a_i)
							begin
							if ((FAMILY == "TITANIUM" && w_clke_a) || (FAMILY == "TRION"))
								r_rdSel_2P <= r_rdSel_1P;
							end
							if (FAMILY == "TRION")
							begin
								always @ (posedge clk_a_i)
								begin
									if(!r_read_hold_a_2P )
										r_rMux_hold_a[DATA_END:DATA_START] <= rMux_a[r_rdSel_2P][DATA_END:DATA_START];
									
									if (w_clke_a)
									begin
										r_read_hold_a_1P <= w_read_hold_a;
									end
									
									if ((FAMILY == "TITANIUM" && w_clke_a) || (FAMILY == "TRION"))
									begin
										r_read_hold_a_2P <= r_read_hold_a_1P;
									end
									
								end
								assign w_rdata_map_a[DATA_END:DATA_START] = (r_read_hold_a_2P) ? r_rMux_hold_a[DATA_END:DATA_START] : rMux_a[r_rdSel_2P][DATA_END:DATA_START];

							end 
							else //TITANIUM
							begin
								reg [DATA_END:DATA_START ] r_rMux_hold_a_1P ;
								always @ (posedge clk_a_i or posedge ram_async_rsta)
								begin
									if (ram_async_rsta)
									begin 
										r_rMux_hold_a[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
										r_read_hold_a_1P <= 1'b0;
										r_read_hold_a_2P <= 1'b0;
									end 
									else 
									begin 
										if(ram_sync_rsta)
										begin 
											r_rMux_hold_a[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
											r_read_hold_a_1P <= 1'b0;
											r_read_hold_a_2P <= 1'b0;
										end 
										else 
										begin 
											if(!r_read_hold_a_2P)
												r_rMux_hold_a[DATA_END:DATA_START] <= rMux_a[r_rdSel_2P][DATA_END:DATA_START];
											
											if (w_clke_a)
											begin 
												r_read_hold_a_1P <= w_read_hold_a;
												r_read_hold_a_2P <= r_read_hold_a_1P;
		
											end 	
										end 
									end 
								end
								always @ (posedge clk_a_i or posedge outreg_async_rsta)
								begin
									if (outreg_async_rsta)
									begin
										r_rMux_hold_a_1P[DATA_END:DATA_START]  <= {(DATA_END-DATA_START+1){1'b0}};
									end
									else 
									begin
										if (w_clke_a)
											r_rMux_hold_a_1P[DATA_END:DATA_START]  <= r_rMux_hold_a[DATA_END:DATA_START];
									
									end 
								end 
								
								assign w_rdata_map_a[DATA_END:DATA_START] = (r_read_hold_a_2P) ? r_rMux_hold_a[DATA_END:DATA_START] : rMux_a[r_rdSel_2P][DATA_END:DATA_START];
					
							end 
						end 
					end 
					else 
					begin
						always @ (posedge clk_a_i)
						begin
							if(w_clke_a & w_addren_a) 
								r_rdSel_1P <= rdSel;
						end
						
						if (OUTPUT_REG_A == 0)
						begin
						
							assign w_rdata_map_a[DATA_END:DATA_START] = rMux_a[r_rdSel_1P][DATA_END:DATA_START];
						end
						else
						begin
							reg [ADDR_END:ADDR_START] r_rdSel_2P = {(ADDR_END-ADDR_START+1){1'b0}};
							always @ (posedge clk_a_i)
							begin
								if ((FAMILY == "TITANIUM" && w_clke_a) || (FAMILY == "TRION"))
								r_rdSel_2P <= r_rdSel_1P;
							end
								assign w_rdata_map_a[DATA_END:DATA_START] = rMux_a[r_rdSel_2P][DATA_END:DATA_START];
						end 
					end 
					
                
				end 
				else 
				begin 
	
					if(WRITE_MODE_A == "NO_CHANGE")
					begin
						wire w_clke_a = clke_a ~^ CLKEA_POLARITY;
						wire w_read_hold_a = (we_a == WEA_POLARITY);
						reg r_read_hold_a_1P = 1'b0;
						reg [DATA_END:DATA_START] r_rMux_hold_a ;
						
						if (OUTPUT_REG_A == 0)
						begin
						
							if (FAMILY == "TRION")
							begin
								always @ (posedge clk_a_i)
								begin
									if(!r_read_hold_a_1P)
										r_rMux_hold_a[DATA_END:DATA_START] <= rMux_a[0][DATA_END:DATA_START];
									
									if (w_clke_a)
										r_read_hold_a_1P <= w_read_hold_a;
								end
							end 
							else 
							begin//TITANIUM
								always @ (posedge clk_a_i or posedge ram_async_rsta)
								begin
									if (ram_async_rsta)
									begin 
										r_rMux_hold_a <= {(DATA_END-DATA_START+1){1'b0}};
										r_read_hold_a_1P  <= 1'b0;
									end 
									else 
									begin 
										if(ram_sync_rsta)
										begin 
											r_rMux_hold_a <= {(DATA_END-DATA_START+1){1'b0}};
											r_read_hold_a_1P  <= 1'b0;
										end 
										else 
										begin 
											if(!r_read_hold_a_1P)
												r_rMux_hold_a[DATA_END:DATA_START] <= rMux_a[0][DATA_END:DATA_START];
											
											if (w_clke_a)
												r_read_hold_a_1P <= w_read_hold_a;
												
										end 
									end 
								end
							end 
							
							assign w_rdata_map_a[DATA_END:DATA_START] = (r_read_hold_a_1P) ?  r_rMux_hold_a[DATA_END:DATA_START] : rMux_a[0][DATA_END:DATA_START];
						end
						else
						begin//Out Reg =1
							reg r_read_hold_a_2P = 1'b0;
							
							if (FAMILY == "TRION")
							begin
								always @ (posedge clk_a_i)
								begin
									if(!r_read_hold_a_2P)
										r_rMux_hold_a[DATA_END:DATA_START] <= rMux_a[0][DATA_END:DATA_START];
									
									if (w_clke_a)
									begin
										r_read_hold_a_1P <= w_read_hold_a;
									end
									
									if ((FAMILY == "TITANIUM" && w_clke_a) || (FAMILY == "TRION"))
									begin
										r_read_hold_a_2P <= r_read_hold_a_1P;
									end
								end
								assign w_rdata_map_a[DATA_END:DATA_START] = (r_read_hold_a_2P) ?  r_rMux_hold_a[DATA_END:DATA_START] : rMux_a[0][DATA_END:DATA_START];
							end 
							else 
							begin //TITANIUM
								reg [DATA_END:DATA_START ] r_rMux_hold_a_1P ;
								always @ (posedge clk_a_i or posedge ram_async_rsta)
								begin
									if (ram_async_rsta)
									begin 
										r_rMux_hold_a[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
										r_read_hold_a_1P <= 1'b0;
										r_read_hold_a_2P <= 1'b0;
									end 
									else 
									begin 
										if(ram_sync_rsta)
										begin 
											r_rMux_hold_a[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
											r_read_hold_a_1P <= 1'b0;
											r_read_hold_a_2P <= 1'b0;
										end 
										else 
										begin 
											if(!r_read_hold_a_2P)
												r_rMux_hold_a[DATA_END:DATA_START] <= rMux_a[0][DATA_END:DATA_START];
											
											if (w_clke_a)
											begin 
												r_read_hold_a_1P <= w_read_hold_a;
												r_read_hold_a_2P <= r_read_hold_a_1P;
		
											end 	
										end 
									end 
								end
								always @ (posedge clk_a_i or posedge outreg_async_rsta)
								begin
									if (outreg_async_rsta)
									begin
										r_rMux_hold_a_1P[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
									end
									else 
									begin
										if (w_clke_a)
											r_rMux_hold_a_1P[DATA_END:DATA_START] <= r_rMux_hold_a[DATA_END:DATA_START];
									
									end 
								end 

								assign w_rdata_map_a[DATA_END:DATA_START] = (r_read_hold_a_2P) ?  r_rMux_hold_a[DATA_END:DATA_START] : rMux_a[0][DATA_END:DATA_START];
							
							end 
						end
					end 
					else 
					begin
						assign w_rdata_map_a[DATA_END:DATA_START] = rMux_a[0][DATA_END:DATA_START];
					end 
			
			


	
				end 
				
            end
        end

		wire [DATA_WIDTH_B-1:0 ] rMux_b [get_max_mux_row_B(0):0]; 
		if (rMux_mapping_B_size == 0) 
        begin
			if(WRITE_MODE_B == "NO_CHANGE")
			begin
				wire w_clke_b = clke_b ~^ CLKEB_POLARITY;
				wire w_read_hold_b = (we_b == WEB_POLARITY);
				reg r_read_hold_b_1P = 1'b0;
				reg [DATA_WIDTH_B-1:0 ] r_rMux_hold_b ;
				
				if (OUTPUT_REG_B == 0)
				begin
				
					if (FAMILY == "TRION")
					begin 
						always @ (posedge clk_b_i)
						begin
							if(!r_read_hold_b_1P)
								r_rMux_hold_b <= rMux_b[0];
							
							if (w_clke_b)
								r_read_hold_b_1P <= w_read_hold_b;
						end
					
					end 
					else 
					begin //TITANIUM
						always @ (posedge clk_b_i or posedge ram_async_rstb)
						begin
							if (ram_async_rstb)
							begin 
								r_rMux_hold_b <= {DATA_WIDTH_B{1'b0}};
								r_read_hold_b_1P  <= 1'b0;
							end 
							else 
							begin 
								if(ram_sync_rstb)
								begin 
									r_rMux_hold_b <= {DATA_WIDTH_B{1'b0}};
									r_read_hold_b_1P  <= 1'b0;
								end 
								else 
								begin 
									if(!r_read_hold_b_1P)
										r_rMux_hold_b <= rMux_b[0];
									
									if (w_clke_b)
										r_read_hold_b_1P <= w_read_hold_b;
										
								end 
							end 
						end
					
					
					end 
					assign w_rdata_map_b = (r_read_hold_b_1P) ?  r_rMux_hold_b : rMux_b[0];
				end
				else
				begin //Out Reg =1
					reg r_read_hold_b_2P = 1'b0;
					if (FAMILY == "TRION")
					begin 
						always @ (posedge clk_b_i)
						begin
							if(!r_read_hold_b_2P)
								r_rMux_hold_b <= rMux_b[0];
							
							if (w_clke_b)
							begin
								r_read_hold_b_1P <= w_read_hold_b;
							end
							
							if ((FAMILY == "TITANIUM" && w_clke_b) || (FAMILY == "TRION"))
							begin
								r_read_hold_b_2P <= r_read_hold_b_1P;
							end
							
						end
						assign w_rdata_map_b = (r_read_hold_b_2P) ?  r_rMux_hold_b : rMux_b[0];
					end 
					else 
					begin //TITANIUM
						reg [DATA_WIDTH_B-1:0 ] r_rMux_hold_b_1P ;
						always @ (posedge clk_b_i or posedge ram_async_rstb)
						begin
							if (ram_async_rstb)
							begin 
								r_rMux_hold_b <= {DATA_WIDTH_B{1'b0}};
								r_read_hold_b_1P <= 1'b0;
								r_read_hold_b_2P <= 1'b0;
							end 
							else 
							begin 
								if(ram_sync_rstb)
								begin 
									r_rMux_hold_b <= {DATA_WIDTH_B{1'b0}};
									r_read_hold_b_1P <= 1'b0;
									r_read_hold_b_2P <= 1'b0;
								end 
								else 
								begin 
									if(!r_read_hold_b_2P)
										r_rMux_hold_b <= rMux_b[0];
									
									if (w_clke_b)
									begin 
										r_read_hold_b_1P <= w_read_hold_b;
										r_read_hold_b_2P <= r_read_hold_b_1P;

									end 	
								end 
							end 
						end
						always @ (posedge clk_b_i or posedge outreg_async_rstb)
						begin
							if (outreg_async_rstb)
							begin
								r_rMux_hold_b_1P <= {DATA_WIDTH_B{1'b0}};
							end
							else 
							begin
								if(w_clke_b)
									r_rMux_hold_b_1P <= r_rMux_hold_b;
							
							end 
						end 
						
						assign w_rdata_map_b = (r_read_hold_b_2P) ?  r_rMux_hold_b : rMux_b[0];		
					end 
				end
			end 
			else 
			begin
				assign w_rdata_map_b = rMux_b[0];
			end	
        end 
        else 
        begin
			
            for (gen_y=0; gen_y<rMux_mapping_B_size; gen_y =gen_y +1)
            begin:rDataMux_b
                localparam ADDR_START = rMux_mapping_table_B(gen_y,1);
                localparam ADDR_END   = rMux_mapping_table_B(gen_y,0);
                
                localparam DATA_START = rMux_mapping_table_B(gen_y,3);
                localparam DATA_END   = rMux_mapping_table_B(gen_y,2);
				
				localparam BYPRASSED  = rMux_mapping_table_B(gen_y,6);
                
				if( BYPRASSED == 0 )
				begin 
				
				
				
					wire [ADDR_END:ADDR_START] rdSel = w_addr_map_b[ADDR_END:ADDR_START];
					reg [ADDR_END:ADDR_START] r_rdSel_1P = {(ADDR_END-ADDR_START+1){1'b0}};
					wire w_clke_b = clke_b ~^ CLKEB_POLARITY;
					wire w_addren_b = FAMILY == "TRION" ? 1'b1 : addren_b ~^ ADDRENB_POLARITY; 
					reg [DATA_END:DATA_START] r_rMux_hold_b;

					if(WRITE_MODE_B == "NO_CHANGE")
					begin
					
					//Hold Address for read if WE and No-Change Mode. 
						wire w_read_hold_b = (we_b == WEB_POLARITY);  
						reg r_read_hold_b_1P = 1'b0;
					
						always @ (posedge clk_b_i)
						begin
							if(w_clke_b & w_addren_b) 
								r_rdSel_1P <= rdSel;
						end
						
						if (OUTPUT_REG_B == 0)
						begin
							if (FAMILY == "TRION")
							begin 
								always @ (posedge clk_b_i)
								begin
									if(!r_read_hold_b_1P)
										r_rMux_hold_b[DATA_END:DATA_START] <= rMux_b[r_rdSel_1P][DATA_END:DATA_START];
									if(w_clke_b)
										r_read_hold_b_1P <= w_read_hold_b;
								end
							end 
							begin//TITANIUM
								always @ (posedge clk_b_i or posedge ram_async_rstb)
								begin
									if (ram_async_rstb)
									begin 
										r_rMux_hold_b <= {(DATA_END-DATA_START+1){1'b0}};
										r_read_hold_b_1P  <= 1'b0;
									end 
									else 
									begin 
										if(ram_sync_rstb)
										begin 
											r_rMux_hold_b <= {(DATA_END-DATA_START+1){1'b0}};
											r_read_hold_b_1P  <= 1'b0;
										end 
										else 
										begin 
											if(!r_read_hold_b_1P)
												r_rMux_hold_b[DATA_END:DATA_START] <= rMux_b[r_rdSel_1P][DATA_END:DATA_START];
											
											if (w_clke_b)
												r_read_hold_b_1P <= w_read_hold_b;
												
										end 
									end 
								end
							
							end 
							assign w_rdata_map_b[DATA_END:DATA_START] = (r_read_hold_b_1P) ?  r_rMux_hold_b[DATA_END:DATA_START] : rMux_b[r_rdSel_1P][DATA_END:DATA_START];
						end 
						else
						begin//Out Reg =1
							reg [ADDR_END:ADDR_START] r_rdSel_2P = {(ADDR_END-ADDR_START+1){1'b0}};
							reg r_read_hold_b_2P = 1'b0;
							always @ (posedge clk_b_i)
							begin
								if ((FAMILY == "TITANIUM" && w_clke_b) || (FAMILY == "TRION"))
								r_rdSel_2P <= r_rdSel_1P;
							end
							
							if (FAMILY == "TRION")
							begin
								always @ (posedge clk_b_i)
								begin
									if(!r_read_hold_b_2P)
										r_rMux_hold_b[DATA_END:DATA_START] <= rMux_b[r_rdSel_2P][DATA_END:DATA_START];
									if(w_clke_b)
									begin
										r_read_hold_b_1P <= w_read_hold_b;
		
									end
									
									if ((FAMILY == "TITANIUM" && w_clke_b) || (FAMILY == "TRION"))
									begin
										r_read_hold_b_2P <= r_read_hold_b_1P;
									end
									
								end
								
								assign w_rdata_map_b[DATA_END:DATA_START] = (r_read_hold_b_2P) ?  r_rMux_hold_b[DATA_END:DATA_START] : rMux_b[r_rdSel_2P][DATA_END:DATA_START];
							end 
							else 
							begin //TITANIUM
								reg [DATA_END:DATA_START ] r_rMux_hold_b_1P ;
								always @ (posedge clk_b_i or posedge ram_async_rstb)
								begin
									if (ram_async_rstb)
									begin 
										r_rMux_hold_b[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
										r_read_hold_b_1P <= 1'b0;
										r_read_hold_b_2P <= 1'b0;
									end 
									else 
									begin 
										if(ram_sync_rstb)
										begin 
											r_rMux_hold_b[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
											r_read_hold_b_1P <= 1'b0;
											r_read_hold_b_2P <= 1'b0;
										end 
										else 
										begin 
											if(!r_read_hold_b_2P)
												r_rMux_hold_b[DATA_END:DATA_START] <= rMux_b[r_rdSel_2P][DATA_END:DATA_START];
											
											if (w_clke_b)
											begin 
												r_read_hold_b_1P <= w_read_hold_b;
												r_read_hold_b_2P <= r_read_hold_b_1P;
		
											end 	
										end 
									end 
								end
								always @ (posedge clk_b_i or posedge outreg_async_rstb)
								begin
									if (outreg_async_rstb)
									begin
										r_rMux_hold_b_1P[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
									end
									else 
									begin
										if(w_clke_b)
											r_rMux_hold_b_1P[DATA_END:DATA_START] <= r_rMux_hold_b[DATA_END:DATA_START];
									
									end 
								end 

								assign w_rdata_map_b[DATA_END:DATA_START] = (r_read_hold_b_2P) ?  r_rMux_hold_b[DATA_END:DATA_START] : rMux_b[r_rdSel_2P][DATA_END:DATA_START];

							end 
						end 
					end 
					else 
					begin
					
						always @ (posedge clk_b_i)
						begin
							if(w_clke_b & w_addren_b) 
								r_rdSel_1P <= rdSel;
						end
						
						if (OUTPUT_REG_B == 0)
						begin
							assign w_rdata_map_b[DATA_END:DATA_START] = rMux_b[r_rdSel_1P][DATA_END:DATA_START];
						end 
						else
						begin
							reg [ADDR_END:ADDR_START] r_rdSel_2P = {(ADDR_END-ADDR_START+1){1'b0}};
							always @ (posedge clk_b_i)
							begin
								if ((FAMILY == "TITANIUM" && w_clke_b) || (FAMILY == "TRION"))
								r_rdSel_2P <= r_rdSel_1P;
							end
								assign w_rdata_map_b[DATA_END:DATA_START] = rMux_b[r_rdSel_2P][DATA_END:DATA_START];
						end 
					
					end 
					
					
                end 
				else 
				begin 
					if(WRITE_MODE_B == "NO_CHANGE")
					begin
						wire w_clke_b = clke_b ~^ CLKEB_POLARITY;
						wire w_read_hold_b = (we_b == WEB_POLARITY);
						reg r_read_hold_b_1P = 1'b0;
						reg [DATA_END:DATA_START] r_rMux_hold_b ;
						
						if (OUTPUT_REG_B == 0)
						begin
							if (FAMILY == "TRION")
							begin 
								always @ (posedge clk_b_i)
								begin
									if(!r_read_hold_b_1P)
										r_rMux_hold_b[DATA_END:DATA_START] <= rMux_b[0][DATA_END:DATA_START];
									
									if (w_clke_b)
										r_read_hold_b_1P <= w_read_hold_b;
								end
							end 
							else 
							begin//TITANIUM
								always @ (posedge clk_b_i or posedge ram_async_rstb)
								begin
									if (ram_async_rstb)
									begin 
										r_rMux_hold_b <= {(DATA_END-DATA_START+1){1'b0}};
										r_read_hold_b_1P  <= 1'b0;
									end 
									else 
									begin 
										if(ram_sync_rstb)
										begin 
											r_rMux_hold_b <= {(DATA_END-DATA_START+1){1'b0}};
											r_read_hold_b_1P  <= 1'b0;
										end 
										else 
										begin 
											if(!r_read_hold_b_1P)
												r_rMux_hold_b[DATA_END:DATA_START] <= rMux_b[0][DATA_END:DATA_START];
											
											if (w_clke_b)
												r_read_hold_b_1P <= w_read_hold_b;
												
										end 
									end 
								end
							
							end 
							assign w_rdata_map_b[DATA_END:DATA_START] = (r_read_hold_b_1P) ?  r_rMux_hold_b[DATA_END:DATA_START] : rMux_b[0][DATA_END:DATA_START];
						end
						else
						begin //Out Reg =1
							reg r_read_hold_b_2P = 1'b0;
							if (FAMILY == "TRION")
							begin
								always @ (posedge clk_b_i)
								begin
									if(!r_read_hold_b_2P)
										r_rMux_hold_b[DATA_END:DATA_START] <= rMux_b[0][DATA_END:DATA_START];
									
									if (w_clke_b)
									begin
										r_read_hold_b_1P <= w_read_hold_b;
									end
									
									if ((FAMILY == "TITANIUM" && w_clke_b) || (FAMILY == "TRION"))
									begin
										r_read_hold_b_2P <= r_read_hold_b_1P;
									end
									
								end
								assign w_rdata_map_b[DATA_END:DATA_START] = (r_read_hold_b_2P) ?  r_rMux_hold_b[DATA_END:DATA_START] : rMux_b[0][DATA_END:DATA_START];
							end 
							else 
							begin //TITANIUM
								reg [DATA_END:DATA_START ] r_rMux_hold_b_1P ;
								always @ (posedge clk_b_i or posedge ram_async_rstb)
								begin
									if (ram_async_rstb)
									begin 
										r_rMux_hold_b[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
										r_read_hold_b_1P <= 1'b0;
										r_read_hold_b_2P <= 1'b0;
									end 
									else 
									begin 
										if(ram_sync_rstb)
										begin 
											r_rMux_hold_b[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
											r_read_hold_b_1P <= 1'b0;
											r_read_hold_b_2P <= 1'b0;
										end 
										else 
										begin 
											if(!r_read_hold_b_2P)
												r_rMux_hold_b[DATA_END:DATA_START] <= rMux_b[0][DATA_END:DATA_START];
											
											if (w_clke_b)
											begin 
												r_read_hold_b_1P <= w_read_hold_b;
												r_read_hold_b_2P <= r_read_hold_b_1P;
		
											end 	
										end 
									end 
								end
								always @ (posedge clk_b_i or posedge outreg_async_rstb)
								begin
									if (outreg_async_rstb)
									begin
										r_rMux_hold_b_1P[DATA_END:DATA_START] <= {(DATA_END-DATA_START+1){1'b0}};
									end
									else 
									begin
										r_rMux_hold_b_1P[DATA_END:DATA_START] <= r_rMux_hold_b[DATA_END:DATA_START];
									
									end 
								end 

								assign w_rdata_map_b[DATA_END:DATA_START] = (r_read_hold_b_2P) ?  r_rMux_hold_b[DATA_END:DATA_START] : rMux_b[0][DATA_END:DATA_START];
							
							
							
							end 
						
						end
					end 
					else 
					begin
						assign w_rdata_map_b[DATA_END:DATA_START] = rMux_b[0][DATA_END:DATA_START];
					end	
				
				end 
            end
        end
		
        
		wire [get_max_wen_decode_A(0):0] wen_decode_a ;
        if (wen_sel_mapping_A_size!=0)
        begin  
			for (gen_y=0; gen_y<wen_sel_mapping_A_size; gen_y =gen_y +1)
			begin:wDataEn_A
				localparam ADDR_START = wen_sel_mapping_table_A(gen_y,1);
				localparam ADDR_END   = wen_sel_mapping_table_A(gen_y,0);
				
				localparam SEL_START = wen_sel_mapping_table_A(gen_y,3);
				localparam SEL_END   = wen_sel_mapping_table_A(gen_y,2);
				
				localparam BYPRASSED  = wen_sel_mapping_table_A(gen_y,4);
				
				if( BYPRASSED == 0 )
				begin 
					wire [ADDR_END:ADDR_START] wrSel;
					reg [ADDR_END:ADDR_START]  r_wrSel = {(ADDR_END-ADDR_START+1){1'b0}};
					wire w_clke_a = clke_a ~^ CLKEA_POLARITY;
					wire w_addren_a = FAMILY =="TRION" ? 1'b1 : addren_a ~^ ADDRENA_POLARITY; 
					wire w_wrSel_mux = w_clke_a && w_addren_a;
					
					always @ (posedge clk_a_i)
					begin
						if(w_clke_a & w_addren_a) 
							r_wrSel <= w_addr_map_a[ADDR_END:ADDR_START];
					end
				
					assign wrSel = (w_wrSel_mux==1'b1) ? w_addr_map_a[ADDR_END:ADDR_START]: r_wrSel;
					


					for (gen_x=SEL_START; gen_x<(SEL_END+1); gen_x = gen_x +1)
					begin
						assign wen_decode_a[gen_x] = (wrSel==(gen_x-SEL_START))?1'b1:1'b0;
					end 
				end 
				else 
				begin
										
					for (gen_x=SEL_START; gen_x<(SEL_END+1); gen_x = gen_x +1)
					begin
						assign wen_decode_a[gen_x] = 1'b1;
					end 
				
				end 
				
			end
		end 
		else 
		begin 
			assign wen_decode_a = {(get_max_wen_decode_A(0)+1){1'b1}};
		end 
		
        
        wire [get_max_wen_decode_B(0):0] wen_decode_b ;
        if (wen_sel_mapping_B_size!=0)
        begin  
			for (gen_y=0; gen_y<wen_sel_mapping_B_size; gen_y =gen_y +1)
			begin:wDataEn_B
				localparam ADDR_START = wen_sel_mapping_table_B(gen_y,1);
				localparam ADDR_END   = wen_sel_mapping_table_B(gen_y,0);
				
				localparam SEL_START = wen_sel_mapping_table_B(gen_y,3);
				localparam SEL_END   = wen_sel_mapping_table_B(gen_y,2);
				
				localparam BYPRASSED  = wen_sel_mapping_table_B(gen_y,4);
				
				
				if( BYPRASSED == 0 )
				begin 
					wire [ADDR_END:ADDR_START] wrSel;
					reg [ADDR_END:ADDR_START]  r_wrSel = {(ADDR_END-ADDR_START+1){1'b0}};
					wire w_clke_b = clke_b ~^ CLKEB_POLARITY;
					wire w_addren_b = FAMILY == "TRION" ? 1'b1 : addren_b ~^ ADDRENB_POLARITY; 
					wire w_wrSel_mux = w_clke_b && w_addren_b;
					
					always @ (posedge clk_b_i)
					begin
						if(w_clke_b & w_addren_b) 
							r_wrSel <= w_addr_map_b[ADDR_END:ADDR_START];
					end
				
					assign wrSel = (w_wrSel_mux==1'b1) ? w_addr_map_b[ADDR_END:ADDR_START]: r_wrSel;
					
					
					for (gen_x=SEL_START; gen_x<(SEL_END+1); gen_x = gen_x +1)
					begin
						assign wen_decode_b[gen_x] = (wrSel==(gen_x-SEL_START))?1'b1:1'b0;
					end
				end 
				else 
				begin
					
					for (gen_x=SEL_START; gen_x<(SEL_END+1); gen_x = gen_x +1)
					begin
						assign wen_decode_b[gen_x] = 1'b1;
					end 
				end 
					
			end
		end 
		else 
		begin 
			assign wen_decode_b = {(get_max_wen_decode_B(0)+1){1'b1}};
		end 
		
		//For Mixed Width Mode 
		if (data_mapping_table_A_size!=0)
        begin  
			for (gen_y=0; gen_y<data_mapping_table_A_size; gen_y = gen_y +1)
			begin
				assign w_wdata_map_a[data_mapping_table_A(gen_y)] =  wdata_a[gen_y] ;
				assign rdata_a[gen_y]  = w_rdata_map_a[data_mapping_table_B(gen_y)] ;
			end
		end 
		else 
		begin 
			assign w_wdata_map_a = wdata_a;
			assign rdata_a = w_rdata_map_a;
		end 
	
		if (address_mapping_table_A_size!=0)
        begin  
			for (gen_y=0; gen_y<address_mapping_table_A_size; gen_y = gen_y +1)
			begin
				if (gen_y < ADDR_WIDTH_A)
					assign w_addr_map_a[address_mapping_table_A(gen_y)] =  addr_a[gen_y] ;
				else 
					assign w_addr_map_a[address_mapping_table_A(gen_y)] = 1'b0;
			end
		end 
		else 
		begin 
			assign w_addr_map_a = addr_a;
		end 
	
	
		if (data_mapping_table_B_size!=0)
        begin  
			for (gen_y=0; gen_y<data_mapping_table_B_size; gen_y = gen_y +1)
			begin
				assign w_wdata_map_b[data_mapping_table_A(gen_y)] =  wdata_b[gen_y] ;
				assign rdata_b[gen_y]  = w_rdata_map_b[data_mapping_table_B(gen_y)] ;
			end
		end 
		else 
		begin 
			assign w_wdata_map_b = wdata_b;
			assign rdata_b = w_rdata_map_b;
		end 
	
		if (address_mapping_table_B_size!=0)
        begin  
			for (gen_y=0; gen_y<address_mapping_table_B_size; gen_y = gen_y +1)
			begin
				if(gen_y<ADDR_WIDTH_B)
					assign w_addr_map_b[address_mapping_table_B(gen_y)] =  addr_b[gen_y] ;
				else 
					assign w_addr_map_b[address_mapping_table_B(gen_y)] = 1'b0;
			end 
		end 
		else 
		begin 
			assign w_addr_map_b = addr_b;
		end 
			
			
		if (bram_table_loop_mode == 0 ) 
		begin:scan_column
			for (gen_x=0; gen_x<bram_table_size; gen_x =gen_x +1)
			begin:column
				localparam bram_mode_a = bram_decompose_table(gen_x,0); 
				localparam bram_mode_b = bram_decompose_table(gen_x,1); 
				localparam row_count = bram_decompose_table(gen_x,2);
			
				localparam ADDR_WIDTH_ROW_A  = bram_feature_table(bram_mode_a,0);
				localparam DATA_WIDTH_ROW_A  = bram_feature_table(bram_mode_a,1); 
				localparam WEN_WIDTH_ROW_A   = bram_feature_table(bram_mode_a,2); 
	
				localparam ADDR_WIDTH_ROW_B  = bram_feature_table(bram_mode_b,0);
				localparam DATA_WIDTH_ROW_B  = bram_feature_table(bram_mode_b,1); 
				localparam WEN_WIDTH_ROW_B   = bram_feature_table(bram_mode_b,2); 	
				
				localparam START_COLUMN_INDEX = get_current_column_index(gen_x);
										
				for (gen_y=0; gen_y<row_count; gen_y =gen_y +1)
				begin:row
					
					localparam DATA_MAP_INDEX = START_COLUMN_INDEX+gen_y;

					localparam DATA_END_A     = bram_mapping_table(DATA_MAP_INDEX,2);					
					localparam DATA_START_A   = bram_mapping_table(DATA_MAP_INDEX,3);
					localparam DATA_REPART_A   = bram_mapping_table(DATA_MAP_INDEX,4);
					localparam WRSEL_INDEX_A   = bram_mapping_table(DATA_MAP_INDEX,6);
					localparam BYTEEN_INDEX_A  = bram_mapping_table(DATA_MAP_INDEX,8);
					localparam RMUX_INDEX_A    = bram_mapping_table(DATA_MAP_INDEX,5);
				
				
					localparam DATA_END_B     = bram_mapping_table(DATA_MAP_INDEX,9);					
					localparam DATA_START_B   = bram_mapping_table(DATA_MAP_INDEX,10);
					localparam DATA_REPART_B   = bram_mapping_table(DATA_MAP_INDEX,11);
					localparam WRSEL_INDEX_B   = bram_mapping_table(DATA_MAP_INDEX,13);
					localparam BYTEEN_INDEX_B  = bram_mapping_table(DATA_MAP_INDEX,15);	
					localparam RMUX_INDEX_B    = bram_mapping_table(DATA_MAP_INDEX,12);
						
					wire [ADDR_WIDTH_ROW_A-1:0] w_addr_a;
					wire [DATA_WIDTH_ROW_A-1:0] w_wdata_a;
					wire [DATA_WIDTH_ROW_A-1:0] w_rdata_a;
					wire [WEN_WIDTH_ROW_A-1:0]   w_we_a;

					wire [ADDR_WIDTH_ROW_B-1:0] w_addr_b;
					wire [DATA_WIDTH_ROW_B-1:0] w_wdata_b;
					wire [DATA_WIDTH_ROW_B-1:0] w_rdata_b;
					wire [WEN_WIDTH_ROW_B-1:0]   w_we_b;
					
					//assign w_addr_a[ADDR_WIDTH_ROW_A-1:0] = w_addr_map_a[ADDR_WIDTH_ROW_A-1:0];
					//assign w_addr_b[ADDR_WIDTH_ROW_B-1:0]  = w_addr_map_b[ADDR_WIDTH_ROW_B-1:0];	
					
					
					for(gen_z=0;gen_z<ADDR_WIDTH_ROW_A; gen_z=gen_z+1)
					begin
						if(gen_z< ADDR_WIDTH_A) 
							assign w_addr_a[gen_z] = w_addr_map_a[gen_z];
						else
							assign w_addr_a[gen_z] = 1'b0;
					end
					
					for(gen_z=0;gen_z<ADDR_WIDTH_ROW_B; gen_z=gen_z+1)
					begin
						if(gen_z< ADDR_WIDTH_B) 
							assign w_addr_b[gen_z] = w_addr_map_b[gen_z];
						else
							assign w_addr_b[gen_z] = 1'b0;			
					
					end
					
					
					if (DATA_REPART_A == 0)
					begin
						assign w_wdata_a[DATA_WIDTH_ROW_A-1:0] = w_wdata_map_a[DATA_END_A:DATA_START_A];
						assign rMux_a[RMUX_INDEX_A][DATA_END_A:DATA_START_A]   = w_rdata_a[DATA_WIDTH_ROW_A-1:0]; 
					end
					else 
					begin
						//for Mixed Width Mode 
						for (gen_z=0; gen_z<DATA_REPART_A; gen_z = gen_z+1)
						begin
							localparam MIXED_DATA_START =  DATA_START_A + gen_z*row_count* (DATA_END_B-DATA_START_B+1); //DATA_WIDTH_ROW_B;
							localparam MIXED_DATA_END   =  DATA_END_A   + gen_z*row_count* (DATA_END_B-DATA_START_B+1); //DATA_WIDTH_ROW_B; 
							
							localparam MAPPED_DATA_START =  DATA_WIDTH_ROW_B* gen_z;
							localparam MAPPED_DATA_END   =  DATA_WIDTH_ROW_B*(gen_z+1) -1; 
							
							assign w_wdata_a[MAPPED_DATA_END: MAPPED_DATA_START]  =  w_wdata_map_a[MIXED_DATA_END:MIXED_DATA_START];
							assign rMux_a[RMUX_INDEX_A][MIXED_DATA_END:MIXED_DATA_START]   = w_rdata_a[MAPPED_DATA_END:MAPPED_DATA_START]; 
						end
					end 
	
					if (DATA_REPART_B == 0)
					begin
						assign w_wdata_b[DATA_WIDTH_ROW_B-1:0] = w_wdata_map_b[DATA_END_B:DATA_START_B];
						assign rMux_b[RMUX_INDEX_B][DATA_END_B:DATA_START_B]   = w_rdata_b[DATA_WIDTH_ROW_B-1:0]; 
					end
					else 
					begin
						//for Mixed Width Mode 
						for (gen_z=0; gen_z<DATA_REPART_B; gen_z = gen_z+1)
						begin
							localparam MIXED_DATA_START =  DATA_START_B + gen_z*row_count*(DATA_END_A-DATA_START_A+1);//DATA_WIDTH_ROW_A;
							localparam MIXED_DATA_END   =  DATA_END_B   + gen_z*row_count*(DATA_END_A-DATA_START_A+1);//DATA_WIDTH_ROW_A; 
							
							localparam MAPPED_DATA_START =  DATA_WIDTH_ROW_A* gen_z;
							localparam MAPPED_DATA_END   =  DATA_WIDTH_ROW_A*(gen_z+1) -1; 
							
							assign w_wdata_b[MAPPED_DATA_END: MAPPED_DATA_START]  =  w_wdata_map_b[MIXED_DATA_END:MIXED_DATA_START];
							assign rMux_b[RMUX_INDEX_B][MIXED_DATA_END:MIXED_DATA_START]   = w_rdata_b[MAPPED_DATA_END:MAPPED_DATA_START]; 
						end
					end 	
							
					assign w_we_a[0] = ( (we_a == WEA_POLARITY) & wen_decode_a[WRSEL_INDEX_A] & (byteen_a[BYTEEN_INDEX_A] == BYTEENA_POLARITY) ) ? WEA_POLARITY: !WEA_POLARITY;
					if ( WEN_WIDTH_ROW_A >1)
					begin
						assign w_we_a[1] = ( (we_a == WEA_POLARITY) & wen_decode_a[WRSEL_INDEX_A] & (byteen_a[BYTEEN_INDEX_A] == BYTEENA_POLARITY) ) ? WEA_POLARITY: !WEA_POLARITY;
					end 	

					assign w_we_b[0] = ( (we_b == WEB_POLARITY) & wen_decode_b[WRSEL_INDEX_B] & (byteen_b[BYTEEN_INDEX_B] == BYTEENB_POLARITY) ) ? WEB_POLARITY: !WEB_POLARITY;
					if ( WEN_WIDTH_ROW_B >1)
					begin
						assign w_we_b[1] =((we_b == WEB_POLARITY) & wen_decode_b[WRSEL_INDEX_B] & (byteen_b[BYTEEN_INDEX_B] == BYTEENB_POLARITY) )? WEB_POLARITY: !WEB_POLARITY ;
					end 	

					`IP_MODULE_NAME(dpbram_primitive) #(
						.FAMILY(FAMILY),	
	
						//Trion and Titanium parameters 
						.WRITE_WIDTH_A(DATA_WIDTH_ROW_A),
						.READ_WIDTH_A(DATA_WIDTH_ROW_A),
						
						.CLKA_POLARITY(CLKA_POLARITY),  
						.CLKEA_POLARITY(CLKEA_POLARITY), 
						.WEA_POLARITY(WEA_POLARITY),	
						.WRITE_MODE_A(WRITE_MODE_A), 	
						.OUTPUT_REG_A(OUTPUT_REG_A),   
						
						.WRITE_WIDTH_B(DATA_WIDTH_ROW_B),	
						.READ_WIDTH_B(DATA_WIDTH_ROW_B),	
						
						.CLKB_POLARITY(CLKB_POLARITY),  
						.CLKEB_POLARITY(CLKEB_POLARITY), 
						.WEB_POLARITY(WEB_POLARITY),	
						.WRITE_MODE_B(WRITE_MODE_B), 	
						.OUTPUT_REG_B(OUTPUT_REG_B),   

						.ini_index(DATA_MAP_INDEX),
						
						//Titanium extra paramters 
						.RSTA_POLARITY(RSTA_POLARITY), 	
						.RESET_RAM_A(RESET_RAM_A), 	
						.RESET_OUTREG_A(RESET_OUTREG_A), 	
						.ADDRENA_POLARITY(ADDRENA_POLARITY),
						
						.RSTB_POLARITY(RSTB_POLARITY), 	
						.RESET_RAM_B(RESET_RAM_B), 	 	
						.RESET_OUTREG_B(RESET_OUTREG_B), 	
						.ADDRENB_POLARITY(ADDRENB_POLARITY)
						
				
						
					) bram (
					//Trion and Titanium ports
						.CLKA  (clk_a), 		// A-port clk 
						.CLKEA (clke_a), 		// A-port clk enable 
						.WEA   (w_we_a), 		// A-port write enable 
						.ADDRA (w_addr_a), 		// A-port address input
						.WDATAA(w_wdata_a), 	// A-port write data input
						.RDATAA(w_rdata_a), 	// A-port read address output
						
						.CLKB  (clk_b), 		// B-port clk 
						.CLKEB (clke_b), 		// B-port clk enable 
						.WEB   (w_we_b), 		// B-port write enable 
						.ADDRB (w_addr_b), 		// B-port address input
						.WDATAB(w_wdata_b), 	// B-port write data input
						.RDATAB(w_rdata_b), 	// B-port read address output
					
					//Titanium extra ports
						
						.RSTA	(reset_a), // A-port reset 
						.ADDRENA(addren_a), // A-port address enable
						
						.RSTB(reset_b), // B-port reset 
						.ADDRENB(addren_b) // B-port address enable							
					);					
				end
			end
			
		end
		else if (bram_table_loop_mode == 1 ) 
		begin:scan_row
			for (gen_y=0; gen_y<bram_table_size; gen_y =gen_y +1)
			begin:row
				
				localparam bram_mode_a = bram_decompose_table(gen_y,0); 
				localparam bram_mode_b = bram_decompose_table(gen_y,1); 
				localparam column_count = bram_decompose_table(gen_y,2);
			
				localparam ADDR_WIDTH_ROW_A  = bram_feature_table(bram_mode_a,0);
				localparam DATA_WIDTH_ROW_A  = bram_feature_table(bram_mode_a,1); 
				localparam WEN_WIDTH_ROW_A   = bram_feature_table(bram_mode_a,2); 
				localparam ADDR_WIDTH_ROW_MAP_A = (ADDR_WIDTH_ROW_A > ADDR_WIDTH_A )? ADDR_WIDTH_A:ADDR_WIDTH_ROW_A;
				
	
				localparam ADDR_WIDTH_ROW_B  = bram_feature_table(bram_mode_b,0);
				localparam DATA_WIDTH_ROW_B  = bram_feature_table(bram_mode_b,1); 
				localparam WEN_WIDTH_ROW_B   = bram_feature_table(bram_mode_b,2); 	
				localparam ADDR_WIDTH_ROW_MAP_B = (ADDR_WIDTH_ROW_B > ADDR_WIDTH_B )? ADDR_WIDTH_B:ADDR_WIDTH_ROW_B;


				
				localparam START_ROW_INDEX = get_current_row_index(gen_y);	
                
         								
				for (gen_x=0; gen_x<column_count; gen_x =gen_x +1)
				begin:column
					localparam DATA_MAP_INDEX = START_ROW_INDEX+gen_x;

					localparam DATA_END_A     = bram_mapping_table(DATA_MAP_INDEX,2);					
					localparam DATA_START_A   = bram_mapping_table(DATA_MAP_INDEX,3);
					localparam DATA_REPART_A   = bram_mapping_table(DATA_MAP_INDEX,4);
					localparam WRSEL_INDEX_A   = bram_mapping_table(DATA_MAP_INDEX,6);
					localparam BYTEEN_INDEX_A  = bram_mapping_table(DATA_MAP_INDEX,8);
					localparam RMUX_INDEX_A    = bram_mapping_table(DATA_MAP_INDEX,5);
				
				
					localparam DATA_END_B     = bram_mapping_table(DATA_MAP_INDEX,9);					
					localparam DATA_START_B   = bram_mapping_table(DATA_MAP_INDEX,10);
					localparam DATA_REPART_B   = bram_mapping_table(DATA_MAP_INDEX,11);
					localparam WRSEL_INDEX_B   = bram_mapping_table(DATA_MAP_INDEX,13);
					localparam BYTEEN_INDEX_B  = bram_mapping_table(DATA_MAP_INDEX,15);	
					localparam RMUX_INDEX_B    = bram_mapping_table(DATA_MAP_INDEX,12);
						
					wire [ADDR_WIDTH_ROW_A-1:0] w_addr_a;
					wire [DATA_WIDTH_ROW_A-1:0] w_wdata_a;
					wire [DATA_WIDTH_ROW_A-1:0] w_rdata_a;
					wire [WEN_WIDTH_ROW_A-1:0]   w_we_a;

					wire [ADDR_WIDTH_ROW_B-1:0] w_addr_b;
					wire [DATA_WIDTH_ROW_B-1:0] w_wdata_b;
					wire [DATA_WIDTH_ROW_B-1:0] w_rdata_b;
					wire [WEN_WIDTH_ROW_B-1:0]   w_we_b;
					
					
					for(gen_z=0;gen_z<ADDR_WIDTH_ROW_A; gen_z=gen_z+1)
					begin
						if(gen_z< ADDR_WIDTH_A) 
							assign w_addr_a[gen_z] = w_addr_map_a[gen_z];
						else
							assign w_addr_a[gen_z] = 1'b0;
					end
					
					for(gen_z=0;gen_z<ADDR_WIDTH_ROW_B; gen_z=gen_z+1)
					begin
						if(gen_z< ADDR_WIDTH_B) 
							assign w_addr_b[gen_z] = w_addr_map_b[gen_z];
						else
							assign w_addr_b[gen_z] = 1'b0;			
					
					end
					
					
					if (DATA_REPART_A == 0)
					begin
						assign w_wdata_a[DATA_WIDTH_ROW_A-1:0] = w_wdata_map_a[DATA_END_A:DATA_START_A];
						assign rMux_a[RMUX_INDEX_A][DATA_END_A:DATA_START_A]   = w_rdata_a[DATA_WIDTH_ROW_A-1:0]; 
					end
					else 
					begin
						//for Mixed Width Mode 
						for (gen_z=0; gen_z<DATA_REPART_A; gen_z = gen_z+1)
						begin
							localparam MIXED_DATA_START =  DATA_START_A + gen_z*column_count* (DATA_END_B-DATA_START_B+1);//DATA_WIDTH_ROW_B;
							localparam MIXED_DATA_END   =  DATA_END_A   + gen_z*column_count* (DATA_END_B-DATA_START_B+1);//DATA_WIDTH_ROW_B; 
							
							localparam MAPPED_DATA_START =  DATA_WIDTH_ROW_B* gen_z;
							localparam MAPPED_DATA_END   =  DATA_WIDTH_ROW_B*(gen_z+1) -1; 
							
							assign w_wdata_a[MAPPED_DATA_END: MAPPED_DATA_START]  =  w_wdata_map_a[MIXED_DATA_END:MIXED_DATA_START];
							assign rMux_a[RMUX_INDEX_A][MIXED_DATA_END:MIXED_DATA_START]   = w_rdata_a[MAPPED_DATA_END:MAPPED_DATA_START]; 
						end
					end 
	
					if (DATA_REPART_B == 0)
					begin
						assign w_wdata_b[DATA_WIDTH_ROW_B-1:0] = w_wdata_map_b[DATA_END_B:DATA_START_B];
						assign rMux_b[RMUX_INDEX_B][DATA_END_B:DATA_START_B]   = w_rdata_b[DATA_WIDTH_ROW_B-1:0]; 
					end
					else 
					begin
						//for Mixed Width Mode 
						for (gen_z=0; gen_z<DATA_REPART_B; gen_z = gen_z+1)
						begin
							localparam MIXED_DATA_START =  DATA_START_B + gen_z*column_count* (DATA_END_A-DATA_START_A+1);//DATA_WIDTH_ROW_A;
							localparam MIXED_DATA_END   =  DATA_END_B   + gen_z*column_count* (DATA_END_A-DATA_START_A+1);//DATA_WIDTH_ROW_A; 
							
							localparam MAPPED_DATA_START =  DATA_WIDTH_ROW_A* gen_z;
							localparam MAPPED_DATA_END   =  DATA_WIDTH_ROW_A*(gen_z+1) -1; 
							
							assign w_wdata_b[MAPPED_DATA_END: MAPPED_DATA_START]  =  w_wdata_map_b[MIXED_DATA_END:MIXED_DATA_START];
							assign rMux_b[RMUX_INDEX_B][MIXED_DATA_END:MIXED_DATA_START]   = w_rdata_b[MAPPED_DATA_END:MAPPED_DATA_START]; 
						end
					end 	
					
					assign w_we_a[0] = ((we_a == WEA_POLARITY) & wen_decode_a[WRSEL_INDEX_A] & (byteen_a[BYTEEN_INDEX_A] == BYTEENA_POLARITY) ) ? WEA_POLARITY: !WEA_POLARITY;
					if ( WEN_WIDTH_ROW_A >1)
					begin
						assign w_we_a[1] = ((we_a == WEA_POLARITY) & wen_decode_a[WRSEL_INDEX_A] & (byteen_a[BYTEEN_INDEX_A] == BYTEENA_POLARITY) ) ?  WEA_POLARITY: !WEA_POLARITY;
					end 	

					assign w_we_b[0] = ((we_b == WEB_POLARITY) & wen_decode_b[WRSEL_INDEX_B] & (byteen_b[BYTEEN_INDEX_B] == BYTEENB_POLARITY)) ?  WEB_POLARITY: !WEB_POLARITY;
					if ( WEN_WIDTH_ROW_B >1)
					begin
						assign w_we_b[1] = ((we_b == WEB_POLARITY) & wen_decode_b[WRSEL_INDEX_B] & (byteen_b[BYTEEN_INDEX_B] == BYTEENB_POLARITY)) ? WEB_POLARITY : !WEB_POLARITY;
					end 
									
					`IP_MODULE_NAME(dpbram_primitive) #(
						.FAMILY(FAMILY),	
	
						//Trion and Titanium parameters 
						.WRITE_WIDTH_A(DATA_WIDTH_ROW_A),
						.READ_WIDTH_A(DATA_WIDTH_ROW_A),
						
						.CLKA_POLARITY(CLKA_POLARITY),  
						.CLKEA_POLARITY(CLKEA_POLARITY), 
						.WEA_POLARITY(WEA_POLARITY),	
						.WRITE_MODE_A(WRITE_MODE_A), 	
						.OUTPUT_REG_A(OUTPUT_REG_A),   
						
						.WRITE_WIDTH_B(DATA_WIDTH_ROW_B),	
						.READ_WIDTH_B(DATA_WIDTH_ROW_B),	
						
						.CLKB_POLARITY(CLKB_POLARITY),  
						.CLKEB_POLARITY(CLKEB_POLARITY), 
						.WEB_POLARITY(WEB_POLARITY),	
						.WRITE_MODE_B(WRITE_MODE_B), 	
						.OUTPUT_REG_B(OUTPUT_REG_B),   

						.ini_index(DATA_MAP_INDEX),
						
						//Titanium extra paramters 
						.RSTA_POLARITY(RSTA_POLARITY), 	
						.RESET_RAM_A(RESET_RAM_A), 	
						.RESET_OUTREG_A(RESET_OUTREG_A), 	
						.ADDRENA_POLARITY(ADDRENA_POLARITY),
						
						.RSTB_POLARITY(RSTB_POLARITY), 	
						.RESET_RAM_B(RESET_RAM_B), 	 	
						.RESET_OUTREG_B(RESET_OUTREG_B), 	
						.ADDRENB_POLARITY(ADDRENB_POLARITY)   											
				
						
					) bram (
					//Trion and Titanium ports
						.CLKA  (clk_a), 		// A-port clk 
						.CLKEA (clke_a), 		// A-port clk enable 
						.WEA   (w_we_a), 		// A-port write enable 
						.ADDRA (w_addr_a), 		// A-port address input
						.WDATAA(w_wdata_a), 	// A-port write data input
						.RDATAA(w_rdata_a), 	// A-port read address output
						
						.CLKB  (clk_b), 		// B-port clk 
						.CLKEB (clke_b), 		// B-port clk enable 
						.WEB   (w_we_b), 		// B-port write enable 
						.ADDRB (w_addr_b), 		// B-port address input
						.WDATAB(w_wdata_b), 	// B-port write data input
						.RDATAB(w_rdata_b), 	// B-port read address output
					
					//Titanium extra ports
						
						.RSTA	(reset_a), // A-port reset 
						.ADDRENA(addren_a), // A-port address enable
						
						.RSTB(reset_b), // B-port reset 
						.ADDRENB(addren_b) // B-port address enable							
					);
					

					
				end
			end
 
		end 
    endgenerate 
 
 
endmodule


////////////////////////////////////////////////////////////////////////////
//           _____       
//          / _______    Copyright (C) 2013-2022 Efinix Inc. All rights reserved.
//         / /       \   
//        / /  ..    /   tb_top.v
//       / / .'     /    
//    __/ /.'      /     Description:
//   __   \       /    
//  /_/ /\ \_____/ /     
// ____/  \_______/      
//
// *******************************
// Revisions:
// 0.0 Initial rev
//
// *******************************

module `IP_MODULE_NAME(efx_true_dual_port_ram) (
	//Trion and Titanium ports
	clk,		// clock input for one clock mode
	clke,		// clk enable
    
	clk_a, 		// A-port clk
	clke_a,		// A-port clk enable
    byteen_a,	// A-port Byteen input 
    we_a, 		// A-port write enable 
	addr_a, 	// A-port address input
    wdata_a,	// A-port write data input
	rdata_a, 	// A-port read address output
  
	clk_b, 		// B-port clk
	clke_b,		// B-port clk enable
    byteen_b,	// B-port Byteen input 
    we_b, 		// B-port write enable 
	addr_b, 	// B-port address input
    wdata_b,	// B-port write data input
	rdata_b, 	// B-port read address output
	     
	//Titanium extra ports
	reset_a,	// A-port reset 
	addren_a,	// A-port address enable
	
	reset_b,	// B-port reset 
	addren_b	// B-port address enable
	
 );

//`include "bram_decompose.vh"
	
//Trion and Titanium parameters
parameter CLK_POLARITY  = 1'b1; 		//clk polarity for one clk mode;  0:falling edge; 1:rising edge 
parameter CLKE_POLARITY = 1'b1; 		//clke polarity for one clk mode; 0:active low; 1:active high

parameter CLKA_POLARITY  = 1'b1; 		//clk A polarity;  0:falling edge; 1:rising edge
parameter CLKEA_POLARITY = 1'b1; 		//clke A polarity; 0:active low; 1:active high
parameter WEA_POLARITY	 = 1'b1; 		//we A polarity;    0:active low; 1:active high

parameter OUTPUT_REG_A   	= 1'b0; 	// Output register enable; 1:add pipe-line read register
parameter BYTEENA_POLARITY  = 1'b1;     // byteen polarity		0:active low; 1:active high 

parameter CLKB_POLARITY  = 1'b1; 		//clk A polarity;  0:falling edge; 1:rising edge
parameter CLKEB_POLARITY = 1'b1; 		//clke A polarity; 0:active low; 1:active high
parameter WEB_POLARITY	 = 1'b1; 		//we B polarity;    0:active low; 1:active high

parameter OUTPUT_REG_B   	= 1'b0; 	// Output register enable; 1:add pipe-line read register
parameter BYTEENB_POLARITY  = 1'b1;     // byteen polarity		0:active low; 1:active high 


//Port Enable  
parameter CLK_MODE			= 2;		//1: ONE CLK Mode; CLK pin will provide the clock source to the memory
										//2: TWO CLK Mode; clk_a and clk_b 
parameter CLKEA_ENABLE 		= 1'b1; 	//1: Enalbe the port for clke_a pin  ; 0: dislable 
parameter WEA_ENABLE 		= 1'b1;		//1: Enable the port for we_a pin ; 0: disable 
parameter BYTEENA_ENABLE 	= 1'b1;		//1: Enable the port for Byteen_a pins ; 0: disable 

parameter CLKEB_ENABLE 		= 1'b1; 	//1: Enalbe the port for clke_b pin  ; 0: dislable 
parameter WEB_ENABLE 		= 1'b1;		//1: Enable the port for we_b pin ; 0: disable 
parameter BYTEENB_ENABLE 	= 1'b1;		//1: Enable the port for Byteen_b pins ; 0: disable 


//Titanium extra paramters 
parameter RSTA_POLARITY 	= 1'b1;    	// rst A polarity
parameter RESET_RAM_A 	    = "ASYNC"; 	// reset A mode on ram;  "NONE": RST signals does not affect the RAM output.
										//					  "ASYNC": RAM output resets asynchronously to RCLK.
										//                     "SYNC": RAM output resets synchronously to RCLK. 
parameter RESET_OUTREG_A 	= "ASYNC"; 	// reset A mode on output register
										//					   "NONE": RST signals does not affect the RAM output register		
										//					  "ASYNC": RAM output register resets asynchronously to RCLK.
parameter ADDRENA_POLARITY  = 1'b1;    	// addrena polarity

parameter RSTB_POLARITY 	= 1'b1;    	// rst A polarity
parameter RESET_RAM_B 	    = "ASYNC"; 	// reset A mode on ram;  "NONE": RST signals does not affect the RAM output.
										//					  "ASYNC": RAM output resets asynchronously to RCLK.
										//                     "SYNC": RAM output resets synchronously to RCLK. 
parameter RESET_OUTREG_B 	= "ASYNC"; 	// reset A mode on output register
										//					   "NONE": RST signals does not affect the RAM output register		
										//					  "ASYNC": RAM output register resets asynchronously to RCLK.
parameter ADDRENB_POLARITY  = 1'b1;   	// addrenb polarity

//Port Enable  
parameter RESET_A_ENABLE 	= 1'b1;		//1: Enable the port for reset_a pin  ; 0: disable 
parameter ADDREN_A_ENABLE 	= 1'b1;		//1: Enable the port for addren_a pin  ; 0: disable 

parameter RESET_B_ENABLE 	= 1'b1;		//1: Enable the port for reset_b pin  ; 0: disable 
parameter ADDREN_B_ENABLE 	= 1'b1;		//1: Enable the port for addren_b pin  ; 0: disable 

parameter WRITE_MODE_A          = "READ_FIRST";
parameter WRITE_MODE_B          = "READ_FIRST";
parameter DATA_WIDTH_A          = 16;
parameter DATA_WIDTH_B          = 16;
parameter ADDR_WIDTH_A          = 4;
parameter ADDR_WIDTH_B          = 4;
parameter BYTEEN_WIDTH_A        = 2;
parameter BYTEEN_WIDTH_B        = 2;
parameter FAMILY                = "TITANIUM";

//Trion and Titanium ports
input clk;
input clke;

input clk_a; 
input clke_a;
input we_a;
input [BYTEEN_WIDTH_A-1:0] byteen_a;
input [ADDR_WIDTH_A-1:0 ] addr_a; 
input [DATA_WIDTH_A-1:0 ] wdata_a;
output [DATA_WIDTH_A-1:0 ]rdata_a;

input clk_b; 
input clke_b;
input we_b;
input [BYTEEN_WIDTH_B-1:0] byteen_b;
input [ADDR_WIDTH_B-1:0 ] addr_b; 
input [DATA_WIDTH_B-1:0 ] wdata_b;
output [DATA_WIDTH_B-1:0 ]rdata_b;

//Titanium extra ports
input reset_a;
input addren_a;

input reset_b;
input addren_b;

////////////////// wires //////////////////
wire w_clk_a;
wire w_clke_a;
wire [BYTEEN_WIDTH_A-1:0] w_byteen_a;
wire w_we_a;

wire w_clk_b;
wire w_clke_b;
wire [BYTEEN_WIDTH_B-1:0] w_byteen_b;
wire w_we_b;

wire w_reset_a;
wire w_addren_a;

wire w_reset_b;
wire w_addren_b;


assign w_clk_a    = (CLK_MODE==2)      ? clk_a : clk;
assign w_clke_a   = (CLKEA_ENABLE==1)  ? ((CLK_MODE==2) ? clke_a : clke) : CLKEA_POLARITY;
assign w_byteen_a = (BYTEENA_ENABLE==1)? byteen_a : {BYTEEN_WIDTH_A{BYTEENA_POLARITY}};
assign w_we_a     = (WEA_ENABLE==1)    ? we_a : WEA_POLARITY;

assign w_clk_b    = (CLK_MODE==2)      ? clk_b : clk;
assign w_clke_b   = (CLKEB_ENABLE==1)  ? ((CLK_MODE==2) ? clke_b : clke)  : CLKEB_POLARITY;
assign w_byteen_b = (BYTEENB_ENABLE==1)? byteen_b : {BYTEEN_WIDTH_B{BYTEENB_POLARITY}};
assign w_we_b     = (WEB_ENABLE==1)    ? we_b : WEB_POLARITY;


//Titanium extra ports
assign w_reset_a  = (RESET_A_ENABLE==1)  ? reset_a   : (RSTA_POLARITY==1'b1) ? 1'b0: 1'b1;
assign w_addren_a = (ADDREN_A_ENABLE==1) ? addren_a  : ADDRENA_POLARITY;

assign w_reset_b  = (RESET_B_ENABLE==1)  ? reset_b   : (RSTB_POLARITY==1'b1) ? 1'b0: 1'b1;
assign w_addren_b = (ADDREN_B_ENABLE==1) ? addren_b  : ADDRENB_POLARITY;


localparam CLKA_POLARITY_LC = (CLK_MODE==2) ? CLKA_POLARITY : CLK_POLARITY;
localparam CLKB_POLARITY_LC = (CLK_MODE==2) ? CLKB_POLARITY : CLK_POLARITY;

localparam CLKEA_POLARITY_LC = (CLK_MODE==2) ? CLKEA_POLARITY : CLKE_POLARITY;
localparam CLKEB_POLARITY_LC = (CLK_MODE==2) ? CLKEB_POLARITY : CLKE_POLARITY;

 	`IP_MODULE_NAME(dpram_wrapper_mwm) #(
		//Trion and Titanium parameters 
		.CLKA_POLARITY(CLKA_POLARITY_LC),
		.CLKEA_POLARITY(CLKEA_POLARITY_LC),
		.WEA_POLARITY(WEA_POLARITY),
		.WRITE_MODE_A(WRITE_MODE_A),
		
		.OUTPUT_REG_A(OUTPUT_REG_A),
		.BYTEENA_POLARITY(BYTEENA_POLARITY), 
		
		.CLKB_POLARITY(CLKB_POLARITY_LC),
		.CLKEB_POLARITY(CLKEB_POLARITY_LC),
		.WEB_POLARITY(WEB_POLARITY),
		.WRITE_MODE_B(WRITE_MODE_B),
		
		.OUTPUT_REG_B(OUTPUT_REG_B),
		.BYTEENB_POLARITY(BYTEENB_POLARITY), 
		
		//Titanium extra paramters  
		.RSTA_POLARITY(RSTA_POLARITY),
		.RESET_RAM_A(RESET_RAM_A),
		.RESET_OUTREG_A(RESET_OUTREG_A),
		.ADDRENA_POLARITY(ADDRENA_POLARITY),
		
		.RSTB_POLARITY(RSTB_POLARITY),
		.RESET_RAM_B(RESET_RAM_B),
		.RESET_OUTREG_B(RESET_OUTREG_B),
		.ADDRENB_POLARITY(ADDRENB_POLARITY),
		
		.DATA_WIDTH_A(DATA_WIDTH_A),
		.DATA_WIDTH_B(DATA_WIDTH_B),
		.ADDR_WIDTH_A(ADDR_WIDTH_A),
		.ADDR_WIDTH_B(ADDR_WIDTH_B),
		.BYTEEN_WIDTH_A(BYTEEN_WIDTH_A),
		.BYTEEN_WIDTH_B(BYTEEN_WIDTH_B),
        
		.FAMILY(FAMILY)

		
	) brams (
		//Trion and Titanium ports
		.clk_a(w_clk_a),
		.clke_a(w_clke_a),		
		.byteen_a(w_byteen_a),	 
		.we_a(w_we_a), 		
		.addr_a(addr_a), 	
		.wdata_a(wdata_a),	
		.rdata_a(rdata_a), 	
  
		.clk_b(w_clk_b),
		.clke_b(w_clke_b),		
		.byteen_b(w_byteen_b),	 
		.we_b(w_we_b), 		
		.addr_b(addr_b), 	
		.wdata_b(wdata_b),	
		.rdata_b(rdata_b), 	
	     
		//Titanium extra ports
		.reset_a(w_reset_a),	
		.addren_a(w_addren_a),	
		.reset_b(w_reset_b),	
		.addren_b(w_addren_b)	
	
	);
	
 
 
endmodule
`undef IP_UUID
`undef IP_NAME_CONCAT
`undef IP_MODULE_NAME
