
/*verilator lint_off IMPLICIT*/
/*verilator lint_off WIDTH*/
/*verilator lint_off LITENDIAN*/
/* verilator lint_off COMBDLY*/

/*
 *******************************************************************************
 *
 * FIFO Generator - Verilog Behavioral Model
 *
 *******************************************************************************
 *
 * (c) Copyright 1995 - 2009 Xilinx, Inc. All rights reserved.
 *
 * This file contains confidential and proprietary information
 * of Xilinx, Inc. and is protected under U.S. and
 * international copyright and other intellectual property
 * laws.
 *
 * DISCLAIMER
 * This disclaimer is not a license and does not grant any
 * rights to the materials distributed herewith. Except as
 * otherwise provided in a valid license issued to you by
 * Xilinx, and to the maximum extent permitted by applicable
 * law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
 * WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
 * AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
 * BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
 * INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
 * (2) Xilinx shall not be liable (whether in contract or tort,
 * including negligence, or under any other theory of
 * liability) for any loss or damage of any kind or nature
 * related to, arising under or in connection with these
 * materials, including for any direct, or any indirect,
 * special, incidental, or consequential loss or damage
 * (including loss of data, profits, goodwill, or any type of
 * loss or damage suffered as a result of any action brought
 * by a third party) even if such damage or loss was
 * reasonably foreseeable or Xilinx had been advised of the
 * possibility of the same.
 *
 * CRITICAL APPLICATIONS
 * Xilinx products are not designed or intended to be fail-
 * safe, or for use in any application requiring fail-safe
 * performance, such as life-support or safety devices or
 * systems, Class III medical devices, nuclear facilities,
 * applications related to the deployment of airbags, or any
 * other applications that could lead to death, personal
 * injury, or severe property or environmental damage
 * (individually and collectively, "Critical
 * Applications"). Customer assumes the sole risk and
 * liability of any use of Xilinx products in Critical
 * Applications, subject only to applicable laws and
 * regulations governing limitations on product liability.
 *
 * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
 * PART OF THIS FILE AT ALL TIMES.
 *
 *******************************************************************************
 *******************************************************************************
 *
 * Filename: fifo_generator_vlog_beh.v
 *
 * Author     : Xilinx
 *
 *******************************************************************************
 * Structure:
 * 
 * fifo_generator_vlog_beh.v
 *    |
 *    +-fifo_generator_v12_0_bhv_ver_as
 *    |
 *    +-fifo_generator_v12_0_bhv_ver_ss
 *    |
 *    +-fifo_generator_v12_0_bhv_ver_preload0
 * 
 *******************************************************************************
 * Description:
 *
 * The Verilog behavioral model for the FIFO Generator.
 *
 *   The behavioral model has three parts:
 *      - The behavioral model for independent clocks FIFOs (_as)
 *      - The behavioral model for common clock FIFOs (_ss)
 *      - The "preload logic" block which implements First-word Fall-through
 * 
 *******************************************************************************
 * Description:
 *  The verilog behavioral model for the FIFO generator core.
 *
 *******************************************************************************
 */

//`timescale 1ps/1ps
`ifndef TCQ
 `define TCQ 0.1
`endif


/*******************************************************************************
 * Declaration of top-level module
 ******************************************************************************/
module fifo_generator_vlog_beh
  #(
    //-----------------------------------------------------------------------
    // Generic Declarations
    //-----------------------------------------------------------------------
    parameter C_COMMON_CLOCK                 = 0,
    parameter C_COUNT_TYPE                   = 0,
    parameter C_DATA_COUNT_WIDTH             = 2,
    parameter C_DEFAULT_VALUE                = "",
    parameter C_DIN_WIDTH                    = 8,
    parameter C_DOUT_RST_VAL                 = "",
    parameter C_DOUT_WIDTH                   = 8,
    parameter C_ENABLE_RLOCS                 = 0,
    parameter C_FAMILY                       = "",
    parameter C_FULL_FLAGS_RST_VAL           = 1,
    parameter C_HAS_ALMOST_EMPTY             = 0,
    parameter C_HAS_ALMOST_FULL              = 0,
    parameter C_HAS_BACKUP                   = 0,
    parameter C_HAS_DATA_COUNT               = 0,
    parameter C_HAS_INT_CLK                  = 0,
    parameter C_HAS_MEMINIT_FILE             = 0,
    parameter C_HAS_OVERFLOW                 = 0,
    parameter C_HAS_RD_DATA_COUNT            = 0,
    parameter C_HAS_RD_RST                   = 0,
    parameter C_HAS_RST                      = 1,
    parameter C_HAS_SRST                     = 0,
    parameter C_HAS_UNDERFLOW                = 0,
    parameter C_HAS_VALID                    = 0,
    parameter C_HAS_WR_ACK                   = 0,
    parameter C_HAS_WR_DATA_COUNT            = 0,
    parameter C_HAS_WR_RST                   = 0,
    parameter C_IMPLEMENTATION_TYPE          = 0,
    parameter C_INIT_WR_PNTR_VAL             = 0,
    parameter C_MEMORY_TYPE                  = 1,
    parameter C_MIF_FILE_NAME                = "",
    parameter C_OPTIMIZATION_MODE            = 0,
    parameter C_OVERFLOW_LOW                 = 0,
    parameter C_PRELOAD_LATENCY              = 1,
    parameter C_PRELOAD_REGS                 = 0,
    parameter C_PRIM_FIFO_TYPE               = "4kx4",
    parameter C_PROG_EMPTY_THRESH_ASSERT_VAL = 0,
    parameter C_PROG_EMPTY_THRESH_NEGATE_VAL = 0,
    parameter C_PROG_EMPTY_TYPE              = 0,
    parameter C_PROG_FULL_THRESH_ASSERT_VAL  = 0,
    parameter C_PROG_FULL_THRESH_NEGATE_VAL  = 0,
    parameter C_PROG_FULL_TYPE               = 0,
    parameter C_RD_DATA_COUNT_WIDTH          = 2,
    parameter C_RD_DEPTH                     = 256,
    parameter C_RD_FREQ                      = 1,
    parameter C_RD_PNTR_WIDTH                = 8,
    parameter C_UNDERFLOW_LOW                = 0,
    parameter C_USE_DOUT_RST                 = 0,
    parameter C_USE_ECC                      = 0,
    parameter C_USE_EMBEDDED_REG             = 0,
    parameter C_USE_PIPELINE_REG             = 0,
    parameter C_POWER_SAVING_MODE            = 0,
    parameter C_USE_FIFO16_FLAGS             = 0,
    parameter C_USE_FWFT_DATA_COUNT          = 0,
    parameter C_VALID_LOW                    = 0,
    parameter C_WR_ACK_LOW                   = 0,
    parameter C_WR_DATA_COUNT_WIDTH          = 2,
    parameter C_WR_DEPTH                     = 256,
    parameter C_WR_FREQ                      = 1,
    parameter C_WR_PNTR_WIDTH                = 8,
    parameter C_WR_RESPONSE_LATENCY          = 1,
    parameter C_MSGON_VAL                    = 1,
    parameter C_ENABLE_RST_SYNC              = 1,
    parameter C_ERROR_INJECTION_TYPE         = 0,
    parameter C_SYNCHRONIZER_STAGE           = 2,

    // AXI Interface related parameters start here
    parameter C_INTERFACE_TYPE               = 0, // 0: Native Interface, 1: AXI4 Stream, 2: AXI4/AXI3
    parameter C_AXI_TYPE                     = 0, // 1: AXI4, 2: AXI4 Lite, 3: AXI3
    parameter C_HAS_AXI_WR_CHANNEL           = 0,
    parameter C_HAS_AXI_RD_CHANNEL           = 0,
    parameter C_HAS_SLAVE_CE                 = 0,
    parameter C_HAS_MASTER_CE                = 0,
    parameter C_ADD_NGC_CONSTRAINT           = 0,
    parameter C_USE_COMMON_UNDERFLOW         = 0,
    parameter C_USE_COMMON_OVERFLOW          = 0,
    parameter C_USE_DEFAULT_SETTINGS         = 0,

    // AXI Full/Lite
    parameter C_AXI_ID_WIDTH                 = 0,
    parameter C_AXI_ADDR_WIDTH               = 0,
    parameter C_AXI_DATA_WIDTH               = 0,
    parameter C_AXI_LEN_WIDTH                = 8,
    parameter C_AXI_LOCK_WIDTH               = 2,
    parameter C_HAS_AXI_ID                   = 0,
    parameter C_HAS_AXI_AWUSER               = 0,
    parameter C_HAS_AXI_WUSER                = 0,
    parameter C_HAS_AXI_BUSER                = 0,
    parameter C_HAS_AXI_ARUSER               = 0,
    parameter C_HAS_AXI_RUSER                = 0,
    parameter C_AXI_ARUSER_WIDTH             = 0,
    parameter C_AXI_AWUSER_WIDTH             = 0,
    parameter C_AXI_WUSER_WIDTH              = 0,
    parameter C_AXI_BUSER_WIDTH              = 0,
    parameter C_AXI_RUSER_WIDTH              = 0,

    // AXI Streaming
    parameter C_HAS_AXIS_TDATA               = 0,
    parameter C_HAS_AXIS_TID                 = 0,
    parameter C_HAS_AXIS_TDEST               = 0,
    parameter C_HAS_AXIS_TUSER               = 0,
    parameter C_HAS_AXIS_TREADY              = 0,
    parameter C_HAS_AXIS_TLAST               = 0,
    parameter C_HAS_AXIS_TSTRB               = 0,
    parameter C_HAS_AXIS_TKEEP               = 0,
    parameter C_AXIS_TDATA_WIDTH             = 1,
    parameter C_AXIS_TID_WIDTH               = 1,
    parameter C_AXIS_TDEST_WIDTH             = 1,
    parameter C_AXIS_TUSER_WIDTH             = 1,
    parameter C_AXIS_TSTRB_WIDTH             = 1,
    parameter C_AXIS_TKEEP_WIDTH             = 1,

    // AXI Channel Type
    // WACH --> Write Address Channel
    // WDCH --> Write Data Channel
    // WRCH --> Write Response Channel
    // RACH --> Read Address Channel
    // RDCH --> Read Data Channel
    // AXIS --> AXI Streaming
    parameter C_WACH_TYPE                    = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logic
    parameter C_WDCH_TYPE                    = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie
    parameter C_WRCH_TYPE                    = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie
    parameter C_RACH_TYPE                    = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie
    parameter C_RDCH_TYPE                    = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie
    parameter C_AXIS_TYPE                    = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie

    // AXI Implementation Type
    // 1 = Common Clock Block RAM FIFO
    // 2 = Common Clock Distributed RAM FIFO
    // 11 = Independent Clock Block RAM FIFO
    // 12 = Independent Clock Distributed RAM FIFO
    parameter C_IMPLEMENTATION_TYPE_WACH     = 0,
    parameter C_IMPLEMENTATION_TYPE_WDCH     = 0,
    parameter C_IMPLEMENTATION_TYPE_WRCH     = 0,
    parameter C_IMPLEMENTATION_TYPE_RACH     = 0,
    parameter C_IMPLEMENTATION_TYPE_RDCH     = 0,
    parameter C_IMPLEMENTATION_TYPE_AXIS     = 0,

    // AXI FIFO Type
    // 0 = Data FIFO
    // 1 = Packet FIFO
    // 2 = Low Latency Sync FIFO
    // 3 = Low Latency Async FIFO
    parameter C_APPLICATION_TYPE_WACH        = 0,
    parameter C_APPLICATION_TYPE_WDCH        = 0,
    parameter C_APPLICATION_TYPE_WRCH        = 0,
    parameter C_APPLICATION_TYPE_RACH        = 0,
    parameter C_APPLICATION_TYPE_RDCH        = 0,
    parameter C_APPLICATION_TYPE_AXIS        = 0,

    // AXI Built-in FIFO Primitive Type
    // 512x36, 1kx18, 2kx9, 4kx4, etc
    parameter C_PRIM_FIFO_TYPE_WACH          = "512x36",
    parameter C_PRIM_FIFO_TYPE_WDCH          = "512x36",
    parameter C_PRIM_FIFO_TYPE_WRCH          = "512x36",
    parameter C_PRIM_FIFO_TYPE_RACH          = "512x36",
    parameter C_PRIM_FIFO_TYPE_RDCH          = "512x36",
    parameter C_PRIM_FIFO_TYPE_AXIS          = "512x36",

    // Enable ECC
    // 0 = ECC disabled
    // 1 = ECC enabled
    parameter C_USE_ECC_WACH                 = 0,
    parameter C_USE_ECC_WDCH                 = 0,
    parameter C_USE_ECC_WRCH                 = 0,
    parameter C_USE_ECC_RACH                 = 0,
    parameter C_USE_ECC_RDCH                 = 0,
    parameter C_USE_ECC_AXIS                 = 0,

    // ECC Error Injection Type
    // 0 = No Error Injection
    // 1 = Single Bit Error Injection
    // 2 = Double Bit Error Injection
    // 3 = Single Bit and Double Bit Error Injection
    parameter C_ERROR_INJECTION_TYPE_WACH    = 0,
    parameter C_ERROR_INJECTION_TYPE_WDCH    = 0,
    parameter C_ERROR_INJECTION_TYPE_WRCH    = 0,
    parameter C_ERROR_INJECTION_TYPE_RACH    = 0,
    parameter C_ERROR_INJECTION_TYPE_RDCH    = 0,
    parameter C_ERROR_INJECTION_TYPE_AXIS    = 0,

    // Input Data Width
    // Accumulation of all AXI input signal's width
    parameter C_DIN_WIDTH_WACH               = 1,
    parameter C_DIN_WIDTH_WDCH               = 1,
    parameter C_DIN_WIDTH_WRCH               = 1,
    parameter C_DIN_WIDTH_RACH               = 1,
    parameter C_DIN_WIDTH_RDCH               = 1,
    parameter C_DIN_WIDTH_AXIS               = 1,

    parameter C_WR_DEPTH_WACH                = 16,
    parameter C_WR_DEPTH_WDCH                = 16,
    parameter C_WR_DEPTH_WRCH                = 16,
    parameter C_WR_DEPTH_RACH                = 16,
    parameter C_WR_DEPTH_RDCH                = 16,
    parameter C_WR_DEPTH_AXIS                = 16,

    parameter C_WR_PNTR_WIDTH_WACH           = 4,
    parameter C_WR_PNTR_WIDTH_WDCH           = 4,
    parameter C_WR_PNTR_WIDTH_WRCH           = 4,
    parameter C_WR_PNTR_WIDTH_RACH           = 4,
    parameter C_WR_PNTR_WIDTH_RDCH           = 4,
    parameter C_WR_PNTR_WIDTH_AXIS           = 4,

    parameter C_HAS_DATA_COUNTS_WACH         = 0,
    parameter C_HAS_DATA_COUNTS_WDCH         = 0,
    parameter C_HAS_DATA_COUNTS_WRCH         = 0,
    parameter C_HAS_DATA_COUNTS_RACH         = 0,
    parameter C_HAS_DATA_COUNTS_RDCH         = 0,
    parameter C_HAS_DATA_COUNTS_AXIS         = 0,

    parameter C_HAS_PROG_FLAGS_WACH          = 0,
    parameter C_HAS_PROG_FLAGS_WDCH          = 0,
    parameter C_HAS_PROG_FLAGS_WRCH          = 0,
    parameter C_HAS_PROG_FLAGS_RACH          = 0,
    parameter C_HAS_PROG_FLAGS_RDCH          = 0,
    parameter C_HAS_PROG_FLAGS_AXIS          = 0,

    parameter C_PROG_FULL_TYPE_WACH          = 0,
    parameter C_PROG_FULL_TYPE_WDCH          = 0,
    parameter C_PROG_FULL_TYPE_WRCH          = 0,
    parameter C_PROG_FULL_TYPE_RACH          = 0,
    parameter C_PROG_FULL_TYPE_RDCH          = 0,
    parameter C_PROG_FULL_TYPE_AXIS          = 0,

    parameter C_PROG_FULL_THRESH_ASSERT_VAL_WACH      = 0,
    parameter C_PROG_FULL_THRESH_ASSERT_VAL_WDCH      = 0,
    parameter C_PROG_FULL_THRESH_ASSERT_VAL_WRCH      = 0,
    parameter C_PROG_FULL_THRESH_ASSERT_VAL_RACH      = 0,
    parameter C_PROG_FULL_THRESH_ASSERT_VAL_RDCH      = 0,
    parameter C_PROG_FULL_THRESH_ASSERT_VAL_AXIS      = 0,

    parameter C_PROG_EMPTY_TYPE_WACH         = 0,
    parameter C_PROG_EMPTY_TYPE_WDCH         = 0,
    parameter C_PROG_EMPTY_TYPE_WRCH         = 0,
    parameter C_PROG_EMPTY_TYPE_RACH         = 0,
    parameter C_PROG_EMPTY_TYPE_RDCH         = 0,
    parameter C_PROG_EMPTY_TYPE_AXIS         = 0,

    parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_WACH     = 0,
    parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_WDCH     = 0,
    parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_WRCH     = 0,
    parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_RACH     = 0,
    parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_RDCH     = 0,
    parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_AXIS     = 0,

    parameter C_REG_SLICE_MODE_WACH          = 0,
    parameter C_REG_SLICE_MODE_WDCH          = 0,
    parameter C_REG_SLICE_MODE_WRCH          = 0,
    parameter C_REG_SLICE_MODE_RACH          = 0,
    parameter C_REG_SLICE_MODE_RDCH          = 0,
    parameter C_REG_SLICE_MODE_AXIS          = 0

    )

   (
    //------------------------------------------------------------------------------
    // Input and Output Declarations
    //------------------------------------------------------------------------------

    // Conventional FIFO Interface Signals
    input                               backup,
    input                               backup_marker,
    input                               clk,
    input                               rst,
    input                               srst,
    input                               wr_clk,
    input                               wr_rst,
    input                               rd_clk,
    input                               rd_rst,
    input [C_DIN_WIDTH-1:0]             din,
    input                               wr_en,
    input                               rd_en,
    // Optional inputs
    input [C_RD_PNTR_WIDTH-1:0]         prog_empty_thresh,
    input [C_RD_PNTR_WIDTH-1:0]         prog_empty_thresh_assert,
    input [C_RD_PNTR_WIDTH-1:0]         prog_empty_thresh_negate,
    input [C_WR_PNTR_WIDTH-1:0]         prog_full_thresh,
    input [C_WR_PNTR_WIDTH-1:0]         prog_full_thresh_assert,
    input [C_WR_PNTR_WIDTH-1:0]         prog_full_thresh_negate,
    input                               int_clk,
    input                               injectdbiterr,
    input                               injectsbiterr,
    input                               sleep,

    output [C_DOUT_WIDTH-1:0]           dout,
    output                              full,
    output                              almost_full,
    output                              wr_ack,
    output                              overflow,
    output                              empty,
    output                              almost_empty,
    output                              valid,
    output                              underflow,
    output [C_DATA_COUNT_WIDTH-1:0]     data_count,
    output [C_RD_DATA_COUNT_WIDTH-1:0]  rd_data_count,
    output [C_WR_DATA_COUNT_WIDTH-1:0]  wr_data_count,
    output                              prog_full,
    output                              prog_empty,
    output                              sbiterr,
    output                              dbiterr,
    output                              wr_rst_busy,
    output                              rd_rst_busy,


    // AXI Global Signal
    input                               m_aclk,
    input                               s_aclk,
    input                               s_aresetn,
    input                               s_aclk_en,
    input                               m_aclk_en,
    
    // AXI Full/Lite Slave Write Channel (write side)
    input [C_AXI_ID_WIDTH-1:0]          s_axi_awid,
    input [C_AXI_ADDR_WIDTH-1:0]        s_axi_awaddr,
    input [C_AXI_LEN_WIDTH-1:0]         s_axi_awlen,
    input [3-1:0]                       s_axi_awsize,
    input [2-1:0]                       s_axi_awburst,
    input [C_AXI_LOCK_WIDTH-1:0]        s_axi_awlock,
    input [4-1:0]                       s_axi_awcache,
    input [3-1:0]                       s_axi_awprot,
    input [4-1:0]                       s_axi_awqos,
    input [4-1:0]                       s_axi_awregion,
    input [C_AXI_AWUSER_WIDTH-1:0]      s_axi_awuser,
    input                               s_axi_awvalid,
    output                              s_axi_awready,
    input [C_AXI_ID_WIDTH-1:0]          s_axi_wid,
    input [C_AXI_DATA_WIDTH-1:0]        s_axi_wdata,
    input [C_AXI_DATA_WIDTH/8-1:0]      s_axi_wstrb,
    input                               s_axi_wlast,
    input [C_AXI_WUSER_WIDTH-1:0]       s_axi_wuser,
    input                               s_axi_wvalid,
    output                              s_axi_wready,
    output [C_AXI_ID_WIDTH-1:0]         s_axi_bid,
    output [2-1:0]                      s_axi_bresp,
    output [C_AXI_BUSER_WIDTH-1:0]      s_axi_buser,
    output                              s_axi_bvalid,
    input                               s_axi_bready,
    
    // AXI Full/Lite Master Write Channel (read side)
    output [C_AXI_ID_WIDTH-1:0]         m_axi_awid,
    output [C_AXI_ADDR_WIDTH-1:0]       m_axi_awaddr,
    output [C_AXI_LEN_WIDTH-1:0]        m_axi_awlen,
    output [3-1:0]                      m_axi_awsize,
    output [2-1:0]                      m_axi_awburst,
    output [C_AXI_LOCK_WIDTH-1:0]       m_axi_awlock,
    output [4-1:0]                      m_axi_awcache,
    output [3-1:0]                      m_axi_awprot,
    output [4-1:0]                      m_axi_awqos,
    output [4-1:0]                      m_axi_awregion,
    output [C_AXI_AWUSER_WIDTH-1:0]     m_axi_awuser,
    output                              m_axi_awvalid,
    input                               m_axi_awready,
    output [C_AXI_ID_WIDTH-1:0]         m_axi_wid,
    output [C_AXI_DATA_WIDTH-1:0]       m_axi_wdata,
    output [C_AXI_DATA_WIDTH/8-1:0]     m_axi_wstrb,
    output                              m_axi_wlast,
    output [C_AXI_WUSER_WIDTH-1:0]      m_axi_wuser,
    output                              m_axi_wvalid,
    input                               m_axi_wready,
    input [C_AXI_ID_WIDTH-1:0]          m_axi_bid,
    input [2-1:0]                       m_axi_bresp,
    input [C_AXI_BUSER_WIDTH-1:0]       m_axi_buser,
    input                               m_axi_bvalid,
    output                              m_axi_bready,
    
    
    // AXI Full/Lite Slave Read Channel (write side)
    input [C_AXI_ID_WIDTH-1:0]          s_axi_arid,
    input [C_AXI_ADDR_WIDTH-1:0]        s_axi_araddr, 
    input [C_AXI_LEN_WIDTH-1:0]         s_axi_arlen,
    input [3-1:0]                       s_axi_arsize,
    input [2-1:0]                       s_axi_arburst,
    input [C_AXI_LOCK_WIDTH-1:0]        s_axi_arlock,
    input [4-1:0]                       s_axi_arcache,
    input [3-1:0]                       s_axi_arprot,
    input [4-1:0]                       s_axi_arqos,
    input [4-1:0]                       s_axi_arregion,
    input [C_AXI_ARUSER_WIDTH-1:0]      s_axi_aruser,
    input                               s_axi_arvalid,
    output                              s_axi_arready,
    output [C_AXI_ID_WIDTH-1:0]         s_axi_rid,       
    output [C_AXI_DATA_WIDTH-1:0]       s_axi_rdata, 
    output [2-1:0]                      s_axi_rresp,
    output                              s_axi_rlast,
    output [C_AXI_RUSER_WIDTH-1:0]      s_axi_ruser,
    output                              s_axi_rvalid,
    input                               s_axi_rready,
    
    
    
    // AXI Full/Lite Master Read Channel (read side)
    output [C_AXI_ID_WIDTH-1:0]         m_axi_arid,        
    output [C_AXI_ADDR_WIDTH-1:0]       m_axi_araddr,  
    output [C_AXI_LEN_WIDTH-1:0]        m_axi_arlen,
    output [3-1:0]                      m_axi_arsize,
    output [2-1:0]                      m_axi_arburst,
    output [C_AXI_LOCK_WIDTH-1:0]       m_axi_arlock,
    output [4-1:0]                      m_axi_arcache,
    output [3-1:0]                      m_axi_arprot,
    output [4-1:0]                      m_axi_arqos,
    output [4-1:0]                      m_axi_arregion,
    output [C_AXI_ARUSER_WIDTH-1:0]     m_axi_aruser,
    output                              m_axi_arvalid,
    input                               m_axi_arready,
    input [C_AXI_ID_WIDTH-1:0]          m_axi_rid,        
    input [C_AXI_DATA_WIDTH-1:0]        m_axi_rdata,  
    input [2-1:0]                       m_axi_rresp,
    input                               m_axi_rlast,
    input [C_AXI_RUSER_WIDTH-1:0]       m_axi_ruser,
    input                               m_axi_rvalid,
    output                              m_axi_rready,
    
    
    // AXI Streaming Slave Signals (Write side)
    input                               s_axis_tvalid,
    output                              s_axis_tready,
    input [C_AXIS_TDATA_WIDTH-1:0]      s_axis_tdata,
    input [C_AXIS_TSTRB_WIDTH-1:0]      s_axis_tstrb,
    input [C_AXIS_TKEEP_WIDTH-1:0]      s_axis_tkeep,
    input                               s_axis_tlast,
    input [C_AXIS_TID_WIDTH-1:0]        s_axis_tid,
    input [C_AXIS_TDEST_WIDTH-1:0]      s_axis_tdest,
    input [C_AXIS_TUSER_WIDTH-1:0]      s_axis_tuser,
    
    // AXI Streaming Master Signals (Read side)
    output                              m_axis_tvalid,
    input                               m_axis_tready,
    output [C_AXIS_TDATA_WIDTH-1:0]     m_axis_tdata,
    output [C_AXIS_TSTRB_WIDTH-1:0]     m_axis_tstrb,
    output [C_AXIS_TKEEP_WIDTH-1:0]     m_axis_tkeep,
    output                              m_axis_tlast,
    output [C_AXIS_TID_WIDTH-1:0]       m_axis_tid,
    output [C_AXIS_TDEST_WIDTH-1:0]     m_axis_tdest,
    output [C_AXIS_TUSER_WIDTH-1:0]     m_axis_tuser,
    
           
    
    
    // AXI Full/Lite Write Address Channel signals
    input                               axi_aw_injectsbiterr,
    input                               axi_aw_injectdbiterr,
    input  [C_WR_PNTR_WIDTH_WACH-1:0]   axi_aw_prog_full_thresh,
    input  [C_WR_PNTR_WIDTH_WACH-1:0]   axi_aw_prog_empty_thresh,
    output [C_WR_PNTR_WIDTH_WACH:0]     axi_aw_data_count,
    output [C_WR_PNTR_WIDTH_WACH:0]     axi_aw_wr_data_count,
    output [C_WR_PNTR_WIDTH_WACH:0]     axi_aw_rd_data_count,
    output                              axi_aw_sbiterr,
    output                              axi_aw_dbiterr,
    output                              axi_aw_overflow,
    output                              axi_aw_underflow,
    output                              axi_aw_prog_full,
    output                              axi_aw_prog_empty,
    
    
    // AXI Full/Lite Write Data Channel signals
    input                               axi_w_injectsbiterr,
    input                               axi_w_injectdbiterr,
    input  [C_WR_PNTR_WIDTH_WDCH-1:0]   axi_w_prog_full_thresh,
    input  [C_WR_PNTR_WIDTH_WDCH-1:0]   axi_w_prog_empty_thresh,
    output [C_WR_PNTR_WIDTH_WDCH:0]     axi_w_data_count,
    output [C_WR_PNTR_WIDTH_WDCH:0]     axi_w_wr_data_count,
    output [C_WR_PNTR_WIDTH_WDCH:0]     axi_w_rd_data_count,
    output                              axi_w_sbiterr,
    output                              axi_w_dbiterr,
    output                              axi_w_overflow,
    output                              axi_w_underflow,
    output                              axi_w_prog_full,
    output                              axi_w_prog_empty,
    
    
    // AXI Full/Lite Write Response Channel signals
    input                               axi_b_injectsbiterr,
    input                               axi_b_injectdbiterr,
    input  [C_WR_PNTR_WIDTH_WRCH-1:0]   axi_b_prog_full_thresh,
    input  [C_WR_PNTR_WIDTH_WRCH-1:0]   axi_b_prog_empty_thresh,
    output [C_WR_PNTR_WIDTH_WRCH:0]     axi_b_data_count,
    output [C_WR_PNTR_WIDTH_WRCH:0]     axi_b_wr_data_count,
    output [C_WR_PNTR_WIDTH_WRCH:0]     axi_b_rd_data_count,
    output                              axi_b_sbiterr,
    output                              axi_b_dbiterr,
    output                              axi_b_overflow,
    output                              axi_b_underflow,
    output                              axi_b_prog_full,
    output                              axi_b_prog_empty,
    
    
    
    // AXI Full/Lite Read Address Channel signals
    input                               axi_ar_injectsbiterr,
    input                               axi_ar_injectdbiterr,
    input  [C_WR_PNTR_WIDTH_RACH-1:0]   axi_ar_prog_full_thresh,
    input  [C_WR_PNTR_WIDTH_RACH-1:0]   axi_ar_prog_empty_thresh,
    output [C_WR_PNTR_WIDTH_RACH:0]     axi_ar_data_count,
    output [C_WR_PNTR_WIDTH_RACH:0]     axi_ar_wr_data_count,
    output [C_WR_PNTR_WIDTH_RACH:0]     axi_ar_rd_data_count,
    output                              axi_ar_sbiterr,
    output                              axi_ar_dbiterr,
    output                              axi_ar_overflow,
    output                              axi_ar_underflow,
    output                              axi_ar_prog_full,
    output                              axi_ar_prog_empty,

    
    // AXI Full/Lite Read Data Channel Signals
    input                               axi_r_injectsbiterr,
    input                               axi_r_injectdbiterr,
    input  [C_WR_PNTR_WIDTH_RDCH-1:0]   axi_r_prog_full_thresh,
    input  [C_WR_PNTR_WIDTH_RDCH-1:0]   axi_r_prog_empty_thresh,
    output [C_WR_PNTR_WIDTH_RDCH:0]     axi_r_data_count,
    output [C_WR_PNTR_WIDTH_RDCH:0]     axi_r_wr_data_count,
    output [C_WR_PNTR_WIDTH_RDCH:0]     axi_r_rd_data_count,
    output                              axi_r_sbiterr,
    output                              axi_r_dbiterr,
    output                              axi_r_overflow,
    output                              axi_r_underflow,
    output                              axi_r_prog_full,
    output                              axi_r_prog_empty,

    
    // AXI Streaming FIFO Related Signals
    input                               axis_injectsbiterr,
    input                               axis_injectdbiterr,
    input  [C_WR_PNTR_WIDTH_AXIS-1:0]   axis_prog_full_thresh,
    input  [C_WR_PNTR_WIDTH_AXIS-1:0]   axis_prog_empty_thresh,
    output [C_WR_PNTR_WIDTH_AXIS:0]     axis_data_count,
    output [C_WR_PNTR_WIDTH_AXIS:0]     axis_wr_data_count,
    output [C_WR_PNTR_WIDTH_AXIS:0]     axis_rd_data_count,
    output                              axis_sbiterr,
    output                              axis_dbiterr,
    output                              axis_overflow,
    output                              axis_underflow,
    output                              axis_prog_full,
    output                              axis_prog_empty

    );

    wire                              BACKUP;
    wire                              BACKUP_MARKER;
    wire                              CLK;
    wire                              RST;
    wire                              SRST;
    wire                              WR_CLK;
    wire                              WR_RST;
    wire                              RD_CLK;
    wire                              RD_RST;
    wire [C_DIN_WIDTH-1:0]            DIN;
    wire                              WR_EN;
    wire                              RD_EN;
    wire [C_RD_PNTR_WIDTH-1:0]        PROG_EMPTY_THRESH;
    wire [C_RD_PNTR_WIDTH-1:0]        PROG_EMPTY_THRESH_ASSERT;
    wire [C_RD_PNTR_WIDTH-1:0]        PROG_EMPTY_THRESH_NEGATE;
    wire [C_WR_PNTR_WIDTH-1:0]        PROG_FULL_THRESH;
    wire [C_WR_PNTR_WIDTH-1:0]        PROG_FULL_THRESH_ASSERT;
    wire [C_WR_PNTR_WIDTH-1:0]        PROG_FULL_THRESH_NEGATE;
    wire                              INT_CLK;
    wire                              INJECTDBITERR;
    wire                              INJECTSBITERR;
    wire                              SLEEP;
    wire [C_DOUT_WIDTH-1:0]           DOUT;
    wire                              FULL;
    wire                              ALMOST_FULL;
    wire                              WR_ACK;
    wire                              OVERFLOW;
    wire                              EMPTY;
    wire                              ALMOST_EMPTY;
    wire                              VALID;
    wire                              UNDERFLOW;
    wire [C_DATA_COUNT_WIDTH-1:0]     DATA_COUNT;
    wire [C_RD_DATA_COUNT_WIDTH-1:0]  RD_DATA_COUNT;
    wire [C_WR_DATA_COUNT_WIDTH-1:0]  WR_DATA_COUNT;
    wire                              PROG_FULL;
    wire                              PROG_EMPTY;
    wire                              SBITERR;
    wire                              DBITERR;
    wire                              WR_RST_BUSY;
    wire                              RD_RST_BUSY;
    wire                              M_ACLK;
    wire                              S_ACLK;
    wire                              S_ARESETN;
    wire                              S_ACLK_EN;
    wire                              M_ACLK_EN;
    wire [C_AXI_ID_WIDTH-1:0]         S_AXI_AWID;
    wire [C_AXI_ADDR_WIDTH-1:0]       S_AXI_AWADDR;
    wire [C_AXI_LEN_WIDTH-1:0]        S_AXI_AWLEN;
    wire [3-1:0]                      S_AXI_AWSIZE;
    wire [2-1:0]                      S_AXI_AWBURST;
    wire [C_AXI_LOCK_WIDTH-1:0]       S_AXI_AWLOCK;
    wire [4-1:0]                      S_AXI_AWCACHE;
    wire [3-1:0]                      S_AXI_AWPROT;
    wire [4-1:0]                      S_AXI_AWQOS;
    wire [4-1:0]                      S_AXI_AWREGION;
    wire [C_AXI_AWUSER_WIDTH-1:0]     S_AXI_AWUSER;
    wire                              S_AXI_AWVALID;
    wire                              S_AXI_AWREADY;
    wire [C_AXI_ID_WIDTH-1:0]         S_AXI_WID;
    wire [C_AXI_DATA_WIDTH-1:0]       S_AXI_WDATA;
    wire [C_AXI_DATA_WIDTH/8-1:0]     S_AXI_WSTRB;
    wire                              S_AXI_WLAST;
    wire [C_AXI_WUSER_WIDTH-1:0]      S_AXI_WUSER;
    wire                              S_AXI_WVALID;
    wire                              S_AXI_WREADY;
    wire [C_AXI_ID_WIDTH-1:0]         S_AXI_BID;
    wire [2-1:0]                      S_AXI_BRESP;
    wire [C_AXI_BUSER_WIDTH-1:0]      S_AXI_BUSER;
    wire                              S_AXI_BVALID;
    wire                              S_AXI_BREADY;
    wire [C_AXI_ID_WIDTH-1:0]         M_AXI_AWID;
    wire [C_AXI_ADDR_WIDTH-1:0]       M_AXI_AWADDR;
    wire [C_AXI_LEN_WIDTH-1:0]        M_AXI_AWLEN;
    wire [3-1:0]                      M_AXI_AWSIZE;
    wire [2-1:0]                      M_AXI_AWBURST;
    wire [C_AXI_LOCK_WIDTH-1:0]       M_AXI_AWLOCK;
    wire [4-1:0]                      M_AXI_AWCACHE;
    wire [3-1:0]                      M_AXI_AWPROT;
    wire [4-1:0]                      M_AXI_AWQOS;
    wire [4-1:0]                      M_AXI_AWREGION;
    wire [C_AXI_AWUSER_WIDTH-1:0]     M_AXI_AWUSER;
    wire                              M_AXI_AWVALID;
    wire                              M_AXI_AWREADY;
    wire [C_AXI_ID_WIDTH-1:0]         M_AXI_WID;
    wire [C_AXI_DATA_WIDTH-1:0]       M_AXI_WDATA;
    wire [C_AXI_DATA_WIDTH/8-1:0]     M_AXI_WSTRB;
    wire                              M_AXI_WLAST;
    wire [C_AXI_WUSER_WIDTH-1:0]      M_AXI_WUSER;
    wire                              M_AXI_WVALID;
    wire                              M_AXI_WREADY;
    wire [C_AXI_ID_WIDTH-1:0]         M_AXI_BID;
    wire [2-1:0]                      M_AXI_BRESP;
    wire [C_AXI_BUSER_WIDTH-1:0]      M_AXI_BUSER;
    wire                              M_AXI_BVALID;
    wire                              M_AXI_BREADY;
    wire [C_AXI_ID_WIDTH-1:0]         S_AXI_ARID;
    wire [C_AXI_ADDR_WIDTH-1:0]       S_AXI_ARADDR; 
    wire [C_AXI_LEN_WIDTH-1:0]        S_AXI_ARLEN;
    wire [3-1:0]                      S_AXI_ARSIZE;
    wire [2-1:0]                      S_AXI_ARBURST;
    wire [C_AXI_LOCK_WIDTH-1:0]       S_AXI_ARLOCK;
    wire [4-1:0]                      S_AXI_ARCACHE;
    wire [3-1:0]                      S_AXI_ARPROT;
    wire [4-1:0]                      S_AXI_ARQOS;
    wire [4-1:0]                      S_AXI_ARREGION;
    wire [C_AXI_ARUSER_WIDTH-1:0]     S_AXI_ARUSER;
    wire                              S_AXI_ARVALID;
    wire                              S_AXI_ARREADY;
    wire [C_AXI_ID_WIDTH-1:0]         S_AXI_RID;       
    wire [C_AXI_DATA_WIDTH-1:0]       S_AXI_RDATA; 
    wire [2-1:0]                      S_AXI_RRESP;
    wire                              S_AXI_RLAST;
    wire [C_AXI_RUSER_WIDTH-1:0]      S_AXI_RUSER;
    wire                              S_AXI_RVALID;
    wire                              S_AXI_RREADY;
    wire [C_AXI_ID_WIDTH-1:0]         M_AXI_ARID;        
    wire [C_AXI_ADDR_WIDTH-1:0]       M_AXI_ARADDR;  
    wire [C_AXI_LEN_WIDTH-1:0]        M_AXI_ARLEN;
    wire [3-1:0]                      M_AXI_ARSIZE;
    wire [2-1:0]                      M_AXI_ARBURST;
    wire [C_AXI_LOCK_WIDTH-1:0]       M_AXI_ARLOCK;
    wire [4-1:0]                      M_AXI_ARCACHE;
    wire [3-1:0]                      M_AXI_ARPROT;
    wire [4-1:0]                      M_AXI_ARQOS;
    wire [4-1:0]                      M_AXI_ARREGION;
    wire [C_AXI_ARUSER_WIDTH-1:0]     M_AXI_ARUSER;
    wire                              M_AXI_ARVALID;
    wire                              M_AXI_ARREADY;
    wire [C_AXI_ID_WIDTH-1:0]         M_AXI_RID;        
    wire [C_AXI_DATA_WIDTH-1:0]       M_AXI_RDATA;  
    wire [2-1:0]                      M_AXI_RRESP;
    wire                              M_AXI_RLAST;
    wire [C_AXI_RUSER_WIDTH-1:0]      M_AXI_RUSER;
    wire                              M_AXI_RVALID;
    wire                              M_AXI_RREADY;
    wire                              S_AXIS_TVALID;
    wire                              S_AXIS_TREADY;
    wire [C_AXIS_TDATA_WIDTH-1:0]     S_AXIS_TDATA;
    wire [C_AXIS_TSTRB_WIDTH-1:0]     S_AXIS_TSTRB;
    wire [C_AXIS_TKEEP_WIDTH-1:0]     S_AXIS_TKEEP;
    wire                              S_AXIS_TLAST;
    wire [C_AXIS_TID_WIDTH-1:0]       S_AXIS_TID;
    wire [C_AXIS_TDEST_WIDTH-1:0]     S_AXIS_TDEST;
    wire [C_AXIS_TUSER_WIDTH-1:0]     S_AXIS_TUSER;
    wire                              M_AXIS_TVALID;
    wire                              M_AXIS_TREADY;
    wire [C_AXIS_TDATA_WIDTH-1:0]     M_AXIS_TDATA;
    wire [C_AXIS_TSTRB_WIDTH-1:0]     M_AXIS_TSTRB;
    wire [C_AXIS_TKEEP_WIDTH-1:0]     M_AXIS_TKEEP;
    wire                              M_AXIS_TLAST;
    wire [C_AXIS_TID_WIDTH-1:0]       M_AXIS_TID;
    wire [C_AXIS_TDEST_WIDTH-1:0]     M_AXIS_TDEST;
    wire [C_AXIS_TUSER_WIDTH-1:0]     M_AXIS_TUSER;
    wire                              AXI_AW_INJECTSBITERR;
    wire                              AXI_AW_INJECTDBITERR;
    wire [C_WR_PNTR_WIDTH_WACH-1:0]   AXI_AW_PROG_FULL_THRESH;
    wire [C_WR_PNTR_WIDTH_WACH-1:0]   AXI_AW_PROG_EMPTY_THRESH;
    wire [C_WR_PNTR_WIDTH_WACH:0]     AXI_AW_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_WACH:0]     AXI_AW_WR_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_WACH:0]     AXI_AW_RD_DATA_COUNT;
    wire                              AXI_AW_SBITERR;
    wire                              AXI_AW_DBITERR;
    wire                              AXI_AW_OVERFLOW;
    wire                              AXI_AW_UNDERFLOW;
    wire                              AXI_AW_PROG_FULL;
    wire                              AXI_AW_PROG_EMPTY;
    wire                              AXI_W_INJECTSBITERR;
    wire                              AXI_W_INJECTDBITERR;
    wire [C_WR_PNTR_WIDTH_WDCH-1:0]   AXI_W_PROG_FULL_THRESH;
    wire [C_WR_PNTR_WIDTH_WDCH-1:0]   AXI_W_PROG_EMPTY_THRESH;
    wire [C_WR_PNTR_WIDTH_WDCH:0]     AXI_W_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_WDCH:0]     AXI_W_WR_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_WDCH:0]     AXI_W_RD_DATA_COUNT;
    wire                              AXI_W_SBITERR;
    wire                              AXI_W_DBITERR;
    wire                              AXI_W_OVERFLOW;
    wire                              AXI_W_UNDERFLOW;
    wire                              AXI_W_PROG_FULL;
    wire                              AXI_W_PROG_EMPTY;
    wire                              AXI_B_INJECTSBITERR;
    wire                              AXI_B_INJECTDBITERR;
    wire [C_WR_PNTR_WIDTH_WRCH-1:0]   AXI_B_PROG_FULL_THRESH;
    wire [C_WR_PNTR_WIDTH_WRCH-1:0]   AXI_B_PROG_EMPTY_THRESH;
    wire [C_WR_PNTR_WIDTH_WRCH:0]     AXI_B_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_WRCH:0]     AXI_B_WR_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_WRCH:0]     AXI_B_RD_DATA_COUNT;
    wire                              AXI_B_SBITERR;
    wire                              AXI_B_DBITERR;
    wire                              AXI_B_OVERFLOW;
    wire                              AXI_B_UNDERFLOW;
    wire                              AXI_B_PROG_FULL;
    wire                              AXI_B_PROG_EMPTY;
    wire                              AXI_AR_INJECTSBITERR;
    wire                              AXI_AR_INJECTDBITERR;
    wire [C_WR_PNTR_WIDTH_RACH-1:0]   AXI_AR_PROG_FULL_THRESH;
    wire [C_WR_PNTR_WIDTH_RACH-1:0]   AXI_AR_PROG_EMPTY_THRESH;
    wire [C_WR_PNTR_WIDTH_RACH:0]     AXI_AR_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_RACH:0]     AXI_AR_WR_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_RACH:0]     AXI_AR_RD_DATA_COUNT;
    wire                              AXI_AR_SBITERR;
    wire                              AXI_AR_DBITERR;
    wire                              AXI_AR_OVERFLOW;
    wire                              AXI_AR_UNDERFLOW;
    wire                              AXI_AR_PROG_FULL;
    wire                              AXI_AR_PROG_EMPTY;
    wire                              AXI_R_INJECTSBITERR;
    wire                              AXI_R_INJECTDBITERR;
    wire [C_WR_PNTR_WIDTH_RDCH-1:0]   AXI_R_PROG_FULL_THRESH;
    wire [C_WR_PNTR_WIDTH_RDCH-1:0]   AXI_R_PROG_EMPTY_THRESH;
    wire [C_WR_PNTR_WIDTH_RDCH:0]     AXI_R_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_RDCH:0]     AXI_R_WR_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_RDCH:0]     AXI_R_RD_DATA_COUNT;
    wire                              AXI_R_SBITERR;
    wire                              AXI_R_DBITERR;
    wire                              AXI_R_OVERFLOW;
    wire                              AXI_R_UNDERFLOW;
    wire                              AXI_R_PROG_FULL;
    wire                              AXI_R_PROG_EMPTY;
    wire                              AXIS_INJECTSBITERR;
    wire                              AXIS_INJECTDBITERR;
    wire [C_WR_PNTR_WIDTH_AXIS-1:0]   AXIS_PROG_FULL_THRESH;
    wire [C_WR_PNTR_WIDTH_AXIS-1:0]   AXIS_PROG_EMPTY_THRESH;
    wire [C_WR_PNTR_WIDTH_AXIS:0]     AXIS_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_AXIS:0]     AXIS_WR_DATA_COUNT;
    wire [C_WR_PNTR_WIDTH_AXIS:0]     AXIS_RD_DATA_COUNT;
    wire                              AXIS_SBITERR;
    wire                              AXIS_DBITERR;
    wire                              AXIS_OVERFLOW;
    wire                              AXIS_UNDERFLOW;
    wire                              AXIS_PROG_FULL;
    wire                              AXIS_PROG_EMPTY;
    wire [C_WR_DATA_COUNT_WIDTH-1:0]  wr_data_count_in;
    wire                              wr_rst_int;
    wire                              rd_rst_int;



  function integer find_log2;
    input integer int_val;
    integer i,j;
    begin
      i = 1;
      j = 0;
      for (i = 1; i < int_val; i = i*2) begin
        j = j + 1;
      end
      find_log2 = j;
    end
  endfunction




    // Conventional FIFO Interface Signals
    assign BACKUP                 = backup;
    assign BACKUP_MARKER          = backup_marker;
    assign CLK                    = clk;
    assign RST                    = rst;
    assign SRST                   = srst;
    assign WR_CLK                 = wr_clk;
    assign WR_RST                 = wr_rst;
    assign RD_CLK                 = rd_clk;
    assign RD_RST                 = rd_rst;
    assign WR_EN                  = wr_en;
    assign RD_EN                  = rd_en;
    assign INT_CLK                = int_clk;
    assign INJECTDBITERR          = injectdbiterr;
    assign INJECTSBITERR          = injectsbiterr;
    assign SLEEP                  = sleep;
    assign full                   = FULL;
    assign almost_full            = ALMOST_FULL;
    assign wr_ack                 = WR_ACK;
    assign overflow               = OVERFLOW;
    assign empty                  = EMPTY;
    assign almost_empty           = ALMOST_EMPTY;
    assign valid                  = VALID;
    assign underflow              = UNDERFLOW;
    assign prog_full              = PROG_FULL;
    assign prog_empty             = PROG_EMPTY;
    assign sbiterr                = SBITERR;
    assign dbiterr                = DBITERR;
    assign wr_rst_busy            = WR_RST_BUSY;
    assign rd_rst_busy            = RD_RST_BUSY;
    assign M_ACLK                 = m_aclk;
    assign S_ACLK                 = s_aclk;
    assign S_ARESETN              = s_aresetn;
    assign S_ACLK_EN              = s_aclk_en;
    assign M_ACLK_EN              = m_aclk_en;
    assign S_AXI_AWVALID          = s_axi_awvalid;
    assign s_axi_awready          = S_AXI_AWREADY;
    assign S_AXI_WLAST            = s_axi_wlast;
    assign S_AXI_WVALID           = s_axi_wvalid;
    assign s_axi_wready           = S_AXI_WREADY;
    assign s_axi_bvalid           = S_AXI_BVALID;
    assign S_AXI_BREADY           = s_axi_bready;
    assign m_axi_awvalid          = M_AXI_AWVALID;
    assign M_AXI_AWREADY          = m_axi_awready;
    assign m_axi_wlast            = M_AXI_WLAST;
    assign m_axi_wvalid           = M_AXI_WVALID;
    assign M_AXI_WREADY           = m_axi_wready;
    assign M_AXI_BVALID           = m_axi_bvalid;
    assign m_axi_bready           = M_AXI_BREADY;
    assign S_AXI_ARVALID          = s_axi_arvalid;
    assign s_axi_arready          = S_AXI_ARREADY;
    assign s_axi_rlast            = S_AXI_RLAST;
    assign s_axi_rvalid           = S_AXI_RVALID;
    assign S_AXI_RREADY           = s_axi_rready;
    assign m_axi_arvalid          = M_AXI_ARVALID;
    assign M_AXI_ARREADY          = m_axi_arready;
    assign M_AXI_RLAST            = m_axi_rlast;
    assign M_AXI_RVALID           = m_axi_rvalid;
    assign m_axi_rready           = M_AXI_RREADY;
    assign S_AXIS_TVALID          = s_axis_tvalid;
    assign s_axis_tready          = S_AXIS_TREADY;
    assign S_AXIS_TLAST           = s_axis_tlast;
    assign m_axis_tvalid          = M_AXIS_TVALID;
    assign M_AXIS_TREADY          = m_axis_tready;
    assign m_axis_tlast           = M_AXIS_TLAST;
    assign AXI_AW_INJECTSBITERR   = axi_aw_injectsbiterr;
    assign AXI_AW_INJECTDBITERR   = axi_aw_injectdbiterr;
    assign axi_aw_sbiterr         = AXI_AW_SBITERR;
    assign axi_aw_dbiterr         = AXI_AW_DBITERR;
    assign axi_aw_overflow        = AXI_AW_OVERFLOW;
    assign axi_aw_underflow       = AXI_AW_UNDERFLOW;
    assign axi_aw_prog_full       = AXI_AW_PROG_FULL;
    assign axi_aw_prog_empty      = AXI_AW_PROG_EMPTY;
    assign AXI_W_INJECTSBITERR    = axi_w_injectsbiterr;
    assign AXI_W_INJECTDBITERR    = axi_w_injectdbiterr;
    assign axi_w_sbiterr          = AXI_W_SBITERR;
    assign axi_w_dbiterr          = AXI_W_DBITERR;
    assign axi_w_overflow         = AXI_W_OVERFLOW;
    assign axi_w_underflow        = AXI_W_UNDERFLOW;
    assign axi_w_prog_full        = AXI_W_PROG_FULL;
    assign axi_w_prog_empty       = AXI_W_PROG_EMPTY;
    assign AXI_B_INJECTSBITERR    = axi_b_injectsbiterr;
    assign AXI_B_INJECTDBITERR    = axi_b_injectdbiterr;
    assign axi_b_sbiterr          = AXI_B_SBITERR;
    assign axi_b_dbiterr          = AXI_B_DBITERR;
    assign axi_b_overflow         = AXI_B_OVERFLOW;
    assign axi_b_underflow        = AXI_B_UNDERFLOW;
    assign axi_b_prog_full        = AXI_B_PROG_FULL;
    assign axi_b_prog_empty       = AXI_B_PROG_EMPTY;
    assign AXI_AR_INJECTSBITERR   = axi_ar_injectsbiterr;
    assign AXI_AR_INJECTDBITERR   = axi_ar_injectdbiterr;
    assign axi_ar_sbiterr         = AXI_AR_SBITERR;
    assign axi_ar_dbiterr         = AXI_AR_DBITERR;
    assign axi_ar_overflow        = AXI_AR_OVERFLOW;
    assign axi_ar_underflow       = AXI_AR_UNDERFLOW;
    assign axi_ar_prog_full       = AXI_AR_PROG_FULL;
    assign axi_ar_prog_empty      = AXI_AR_PROG_EMPTY;
    assign AXI_R_INJECTSBITERR    = axi_r_injectsbiterr;
    assign AXI_R_INJECTDBITERR    = axi_r_injectdbiterr;
    assign axi_r_sbiterr          = AXI_R_SBITERR;
    assign axi_r_dbiterr          = AXI_R_DBITERR;
    assign axi_r_overflow         = AXI_R_OVERFLOW;
    assign axi_r_underflow        = AXI_R_UNDERFLOW;
    assign axi_r_prog_full        = AXI_R_PROG_FULL;
    assign axi_r_prog_empty       = AXI_R_PROG_EMPTY;
    assign AXIS_INJECTSBITERR     = axis_injectsbiterr;
    assign AXIS_INJECTDBITERR     = axis_injectdbiterr;
    assign axis_sbiterr           = AXIS_SBITERR;
    assign axis_dbiterr           = AXIS_DBITERR;
    assign axis_overflow          = AXIS_OVERFLOW;
    assign axis_underflow         = AXIS_UNDERFLOW;
    assign axis_prog_full         = AXIS_PROG_FULL;
    assign axis_prog_empty        = AXIS_PROG_EMPTY;


    assign DIN                       = din;
    assign PROG_EMPTY_THRESH         = prog_empty_thresh;
    assign PROG_EMPTY_THRESH_ASSERT  = prog_empty_thresh_assert;
    assign PROG_EMPTY_THRESH_NEGATE  = prog_empty_thresh_negate;
    assign PROG_FULL_THRESH          = prog_full_thresh;
    assign PROG_FULL_THRESH_ASSERT   = prog_full_thresh_assert;
    assign PROG_FULL_THRESH_NEGATE   = prog_full_thresh_negate;
    assign dout                      = DOUT;
    assign data_count                = DATA_COUNT;
    assign rd_data_count             = RD_DATA_COUNT;
    assign wr_data_count             = WR_DATA_COUNT;
    assign S_AXI_AWID                = s_axi_awid;
    assign S_AXI_AWADDR              = s_axi_awaddr;
    assign S_AXI_AWLEN               = s_axi_awlen;
    assign S_AXI_AWSIZE              = s_axi_awsize;
    assign S_AXI_AWBURST             = s_axi_awburst;
    assign S_AXI_AWLOCK              = s_axi_awlock;
    assign S_AXI_AWCACHE             = s_axi_awcache;
    assign S_AXI_AWPROT              = s_axi_awprot;
    assign S_AXI_AWQOS               = s_axi_awqos;
    assign S_AXI_AWREGION            = s_axi_awregion;
    assign S_AXI_AWUSER              = s_axi_awuser;
    assign S_AXI_WID                 = s_axi_wid;
    assign S_AXI_WDATA               = s_axi_wdata;
    assign S_AXI_WSTRB               = s_axi_wstrb;
    assign S_AXI_WUSER               = s_axi_wuser;
    assign s_axi_bid                 = S_AXI_BID;
    assign s_axi_bresp               = S_AXI_BRESP;
    assign s_axi_buser               = S_AXI_BUSER;
    assign m_axi_awid                = M_AXI_AWID;
    assign m_axi_awaddr              = M_AXI_AWADDR;
    assign m_axi_awlen               = M_AXI_AWLEN;
    assign m_axi_awsize              = M_AXI_AWSIZE;
    assign m_axi_awburst             = M_AXI_AWBURST;
    assign m_axi_awlock              = M_AXI_AWLOCK;
    assign m_axi_awcache             = M_AXI_AWCACHE;
    assign m_axi_awprot              = M_AXI_AWPROT;
    assign m_axi_awqos               = M_AXI_AWQOS;
    assign m_axi_awregion            = M_AXI_AWREGION;
    assign m_axi_awuser              = M_AXI_AWUSER;
    assign m_axi_wid                 = M_AXI_WID;
    assign m_axi_wdata               = M_AXI_WDATA;
    assign m_axi_wstrb               = M_AXI_WSTRB;
    assign m_axi_wuser               = M_AXI_WUSER;
    assign M_AXI_BID                 = m_axi_bid;
    assign M_AXI_BRESP               = m_axi_bresp;
    assign M_AXI_BUSER               = m_axi_buser;
    assign S_AXI_ARID                = s_axi_arid;
    assign S_AXI_ARADDR              = s_axi_araddr; 
    assign S_AXI_ARLEN               = s_axi_arlen;
    assign S_AXI_ARSIZE              = s_axi_arsize;
    assign S_AXI_ARBURST             = s_axi_arburst;
    assign S_AXI_ARLOCK              = s_axi_arlock;
    assign S_AXI_ARCACHE             = s_axi_arcache;
    assign S_AXI_ARPROT              = s_axi_arprot;
    assign S_AXI_ARQOS               = s_axi_arqos;
    assign S_AXI_ARREGION            = s_axi_arregion;
    assign S_AXI_ARUSER              = s_axi_aruser;
    assign s_axi_rid                 = S_AXI_RID;
    assign s_axi_rdata               = S_AXI_RDATA;
    assign s_axi_rresp               = S_AXI_RRESP;
    assign s_axi_ruser               = S_AXI_RUSER;
    assign m_axi_arid                = M_AXI_ARID;        
    assign m_axi_araddr              = M_AXI_ARADDR;  
    assign m_axi_arlen               = M_AXI_ARLEN;
    assign m_axi_arsize              = M_AXI_ARSIZE;
    assign m_axi_arburst             = M_AXI_ARBURST;
    assign m_axi_arlock              = M_AXI_ARLOCK;
    assign m_axi_arcache             = M_AXI_ARCACHE;
    assign m_axi_arprot              = M_AXI_ARPROT;
    assign m_axi_arqos               = M_AXI_ARQOS;
    assign m_axi_arregion            = M_AXI_ARREGION;
    assign m_axi_aruser              = M_AXI_ARUSER;
    assign M_AXI_RID                 = m_axi_rid;        
    assign M_AXI_RDATA               = m_axi_rdata;  
    assign M_AXI_RRESP               = m_axi_rresp;
    assign M_AXI_RUSER               = m_axi_ruser;
    assign S_AXIS_TDATA              = s_axis_tdata;
    assign S_AXIS_TSTRB              = s_axis_tstrb;
    assign S_AXIS_TKEEP              = s_axis_tkeep;
    assign S_AXIS_TID                = s_axis_tid;
    assign S_AXIS_TDEST              = s_axis_tdest;
    assign S_AXIS_TUSER              = s_axis_tuser;
    assign m_axis_tdata              = M_AXIS_TDATA;
    assign m_axis_tstrb              = M_AXIS_TSTRB;
    assign m_axis_tkeep              = M_AXIS_TKEEP;
    assign m_axis_tid                = M_AXIS_TID;
    assign m_axis_tdest              = M_AXIS_TDEST;
    assign m_axis_tuser              = M_AXIS_TUSER;
    assign AXI_AW_PROG_FULL_THRESH   = axi_aw_prog_full_thresh;
    assign AXI_AW_PROG_EMPTY_THRESH  = axi_aw_prog_empty_thresh;
    assign axi_aw_data_count         = AXI_AW_DATA_COUNT;
    assign axi_aw_wr_data_count      = AXI_AW_WR_DATA_COUNT;
    assign axi_aw_rd_data_count      = AXI_AW_RD_DATA_COUNT;
    assign AXI_W_PROG_FULL_THRESH    = axi_w_prog_full_thresh;
    assign AXI_W_PROG_EMPTY_THRESH   = axi_w_prog_empty_thresh;
    assign axi_w_data_count          = AXI_W_DATA_COUNT;
    assign axi_w_wr_data_count       = AXI_W_WR_DATA_COUNT;
    assign axi_w_rd_data_count       = AXI_W_RD_DATA_COUNT;
    assign AXI_B_PROG_FULL_THRESH    = axi_b_prog_full_thresh;
    assign AXI_B_PROG_EMPTY_THRESH   = axi_b_prog_empty_thresh;
    assign axi_b_data_count          = AXI_B_DATA_COUNT;
    assign axi_b_wr_data_count       = AXI_B_WR_DATA_COUNT;
    assign axi_b_rd_data_count       = AXI_B_RD_DATA_COUNT;
    assign AXI_AR_PROG_FULL_THRESH   = axi_ar_prog_full_thresh;
    assign AXI_AR_PROG_EMPTY_THRESH  = axi_ar_prog_empty_thresh;
    assign axi_ar_data_count         = AXI_AR_DATA_COUNT;
    assign axi_ar_wr_data_count      = AXI_AR_WR_DATA_COUNT;
    assign axi_ar_rd_data_count      = AXI_AR_RD_DATA_COUNT;
    assign AXI_R_PROG_FULL_THRESH    = axi_r_prog_full_thresh;
    assign AXI_R_PROG_EMPTY_THRESH   = axi_r_prog_empty_thresh;
    assign axi_r_data_count          = AXI_R_DATA_COUNT;
    assign axi_r_wr_data_count       = AXI_R_WR_DATA_COUNT;
    assign axi_r_rd_data_count       = AXI_R_RD_DATA_COUNT;
    assign AXIS_PROG_FULL_THRESH     = axis_prog_full_thresh;
    assign AXIS_PROG_EMPTY_THRESH    = axis_prog_empty_thresh;
    assign axis_data_count           = AXIS_DATA_COUNT;
    assign axis_wr_data_count        = AXIS_WR_DATA_COUNT;
    assign axis_rd_data_count        = AXIS_RD_DATA_COUNT;


  generate if (C_INTERFACE_TYPE == 0) begin : conv_fifo

    FIFO_GENERATOR_v12_0_CONV_VER
      #(
        .C_COMMON_CLOCK 		(C_COMMON_CLOCK),
        .C_COUNT_TYPE			(C_COUNT_TYPE),
        .C_DATA_COUNT_WIDTH		(C_DATA_COUNT_WIDTH),
        .C_DEFAULT_VALUE		(C_DEFAULT_VALUE),
        .C_DIN_WIDTH			(C_DIN_WIDTH),
        .C_DOUT_RST_VAL			(C_USE_DOUT_RST == 1 ? C_DOUT_RST_VAL : 0),
        .C_DOUT_WIDTH			(C_DOUT_WIDTH),
        .C_ENABLE_RLOCS			(C_ENABLE_RLOCS),
        .C_FAMILY			(C_FAMILY),
        .C_FULL_FLAGS_RST_VAL           (C_FULL_FLAGS_RST_VAL),
        .C_HAS_ALMOST_EMPTY		(C_HAS_ALMOST_EMPTY),
        .C_HAS_ALMOST_FULL		(C_HAS_ALMOST_FULL),
        .C_HAS_BACKUP			(C_HAS_BACKUP),
        .C_HAS_DATA_COUNT		(C_HAS_DATA_COUNT),
        .C_HAS_INT_CLK                  (C_HAS_INT_CLK),
        .C_HAS_MEMINIT_FILE		(C_HAS_MEMINIT_FILE),
        .C_HAS_OVERFLOW			(C_HAS_OVERFLOW),
        .C_HAS_RD_DATA_COUNT		(C_HAS_RD_DATA_COUNT),
        .C_HAS_RD_RST			(C_HAS_RD_RST),
        .C_HAS_RST			(C_HAS_RST),
        .C_HAS_SRST			(C_HAS_SRST),
        .C_HAS_UNDERFLOW		(C_HAS_UNDERFLOW),
        .C_HAS_VALID			(C_HAS_VALID),
        .C_HAS_WR_ACK			(C_HAS_WR_ACK),
        .C_HAS_WR_DATA_COUNT		(C_HAS_WR_DATA_COUNT),
        .C_HAS_WR_RST			(C_HAS_WR_RST),
        .C_IMPLEMENTATION_TYPE		(C_IMPLEMENTATION_TYPE),
        .C_INIT_WR_PNTR_VAL		(C_INIT_WR_PNTR_VAL),
        .C_MEMORY_TYPE			(C_MEMORY_TYPE),
        .C_MIF_FILE_NAME		(C_MIF_FILE_NAME),
        .C_OPTIMIZATION_MODE		(C_OPTIMIZATION_MODE),
        .C_OVERFLOW_LOW			(C_OVERFLOW_LOW),
        .C_PRELOAD_LATENCY		(C_PRELOAD_LATENCY),
        .C_PRELOAD_REGS			(C_PRELOAD_REGS),
        .C_PRIM_FIFO_TYPE		(C_PRIM_FIFO_TYPE),
        .C_PROG_EMPTY_THRESH_ASSERT_VAL	(C_PROG_EMPTY_THRESH_ASSERT_VAL),
        .C_PROG_EMPTY_THRESH_NEGATE_VAL	(C_PROG_EMPTY_THRESH_NEGATE_VAL),
        .C_PROG_EMPTY_TYPE		(C_PROG_EMPTY_TYPE),
        .C_PROG_FULL_THRESH_ASSERT_VAL	(C_PROG_FULL_THRESH_ASSERT_VAL),
        .C_PROG_FULL_THRESH_NEGATE_VAL	(C_PROG_FULL_THRESH_NEGATE_VAL),
        .C_PROG_FULL_TYPE		(C_PROG_FULL_TYPE),
        .C_RD_DATA_COUNT_WIDTH		(C_RD_DATA_COUNT_WIDTH),
        .C_RD_DEPTH			(C_RD_DEPTH),
        .C_RD_FREQ			(C_RD_FREQ),
        .C_RD_PNTR_WIDTH		(C_RD_PNTR_WIDTH),
        .C_UNDERFLOW_LOW		(C_UNDERFLOW_LOW),
        .C_USE_DOUT_RST                 (C_USE_DOUT_RST),
        .C_USE_ECC                      (C_USE_ECC),
        .C_USE_EMBEDDED_REG		(C_USE_EMBEDDED_REG),
        .C_USE_FIFO16_FLAGS		(C_USE_FIFO16_FLAGS),
        .C_USE_FWFT_DATA_COUNT		(C_USE_FWFT_DATA_COUNT),
        .C_VALID_LOW			(C_VALID_LOW),
        .C_WR_ACK_LOW			(C_WR_ACK_LOW),
        .C_WR_DATA_COUNT_WIDTH		(C_WR_DATA_COUNT_WIDTH),
        .C_WR_DEPTH			(C_WR_DEPTH),
        .C_WR_FREQ			(C_WR_FREQ),
        .C_WR_PNTR_WIDTH		(C_WR_PNTR_WIDTH),
        .C_WR_RESPONSE_LATENCY		(C_WR_RESPONSE_LATENCY),
        .C_MSGON_VAL                    (C_MSGON_VAL),
        .C_ENABLE_RST_SYNC              (C_ENABLE_RST_SYNC),
        .C_ERROR_INJECTION_TYPE         (C_ERROR_INJECTION_TYPE),
        .C_AXI_TYPE                     (C_AXI_TYPE),
        .C_SYNCHRONIZER_STAGE           (C_SYNCHRONIZER_STAGE)
      )
    fifo_generator_v12_0_conv_dut
      (
        .BACKUP                   (BACKUP),
        .BACKUP_MARKER            (BACKUP_MARKER),
        .CLK                      (CLK),
        .RST                      (RST),
        .SRST                     (SRST),
        .WR_CLK                   (WR_CLK),
        .WR_RST                   (WR_RST),
        .RD_CLK                   (RD_CLK),
        .RD_RST                   (RD_RST),
        .DIN                      (DIN),
        .WR_EN                    (WR_EN),
        .RD_EN                    (RD_EN),
        .PROG_EMPTY_THRESH        (PROG_EMPTY_THRESH),
        .PROG_EMPTY_THRESH_ASSERT (PROG_EMPTY_THRESH_ASSERT),
        .PROG_EMPTY_THRESH_NEGATE (PROG_EMPTY_THRESH_NEGATE),
        .PROG_FULL_THRESH         (PROG_FULL_THRESH),
        .PROG_FULL_THRESH_ASSERT  (PROG_FULL_THRESH_ASSERT),
        .PROG_FULL_THRESH_NEGATE  (PROG_FULL_THRESH_NEGATE),
        .INT_CLK                  (INT_CLK),
        .INJECTDBITERR            (INJECTDBITERR), 
        .INJECTSBITERR            (INJECTSBITERR),
  
        .DOUT                     (DOUT),
        .FULL                     (FULL),
        .ALMOST_FULL              (ALMOST_FULL),
        .WR_ACK                   (WR_ACK),
        .OVERFLOW                 (OVERFLOW),
        .EMPTY                    (EMPTY),
        .ALMOST_EMPTY             (ALMOST_EMPTY),
        .VALID                    (VALID),
        .UNDERFLOW                (UNDERFLOW),
        .DATA_COUNT               (DATA_COUNT),
        .RD_DATA_COUNT            (RD_DATA_COUNT),
        .WR_DATA_COUNT            (wr_data_count_in),
        .PROG_FULL                (PROG_FULL),
        .PROG_EMPTY               (PROG_EMPTY),
        .SBITERR                  (SBITERR),
        .DBITERR                  (DBITERR),
        .wr_rst_busy              (wr_rst_busy),
        .rd_rst_busy              (rd_rst_busy),
        .wr_rst_i_out             (wr_rst_int),
        .rd_rst_i_out             (rd_rst_int)
       );
  end endgenerate



  localparam IS_8SERIES         = (C_FAMILY == "virtexu" || C_FAMILY == "kintexu" || C_FAMILY == "artixu" || C_FAMILY == "virtexum" || C_FAMILY == "zynque") ? 1 : 0;
  localparam C_AXI_SIZE_WIDTH   = 3;
  localparam C_AXI_BURST_WIDTH  = 2;
  localparam C_AXI_CACHE_WIDTH  = 4;
  localparam C_AXI_PROT_WIDTH   = 3;
  localparam C_AXI_QOS_WIDTH    = 4;
  localparam C_AXI_REGION_WIDTH = 4;
  localparam C_AXI_BRESP_WIDTH  = 2;
  localparam C_AXI_RRESP_WIDTH  = 2;

  localparam IS_AXI_STREAMING  = C_INTERFACE_TYPE == 1 ? 1 : 0;
  localparam TDATA_OFFSET      = C_HAS_AXIS_TDATA == 1 ? C_DIN_WIDTH_AXIS-C_AXIS_TDATA_WIDTH : C_DIN_WIDTH_AXIS;
  localparam TSTRB_OFFSET      = C_HAS_AXIS_TSTRB == 1 ? TDATA_OFFSET-C_AXIS_TSTRB_WIDTH : TDATA_OFFSET;
  localparam TKEEP_OFFSET      = C_HAS_AXIS_TKEEP == 1 ? TSTRB_OFFSET-C_AXIS_TKEEP_WIDTH : TSTRB_OFFSET;
  localparam TID_OFFSET        = C_HAS_AXIS_TID   == 1 ? TKEEP_OFFSET-C_AXIS_TID_WIDTH : TKEEP_OFFSET;
  localparam TDEST_OFFSET      = C_HAS_AXIS_TDEST == 1 ? TID_OFFSET-C_AXIS_TDEST_WIDTH : TID_OFFSET;
  localparam TUSER_OFFSET      = C_HAS_AXIS_TUSER == 1 ? TDEST_OFFSET-C_AXIS_TUSER_WIDTH : TDEST_OFFSET;
  localparam LOG_DEPTH_AXIS    = find_log2(C_WR_DEPTH_AXIS); 
  localparam LOG_WR_DEPTH      = find_log2(C_WR_DEPTH); 


  function [LOG_DEPTH_AXIS-1:0] bin2gray;
      input [LOG_DEPTH_AXIS-1:0] x;
      begin
         bin2gray = x ^ (x>>1);
      end
   endfunction

  function [LOG_DEPTH_AXIS-1:0] gray2bin;
      input [LOG_DEPTH_AXIS-1:0] x;
      integer                i;
      begin
         gray2bin[LOG_DEPTH_AXIS-1] = x[LOG_DEPTH_AXIS-1];
         for(i=LOG_DEPTH_AXIS-2; i>=0; i=i-1) begin
            gray2bin[i] =  gray2bin[i+1] ^ x[i];
         end
      end
   endfunction

wire [(LOG_WR_DEPTH)-1 : 0] w_cnt_gc_asreg_last;
wire  [LOG_WR_DEPTH-1 : 0]  w_q [0:C_SYNCHRONIZER_STAGE] ;
wire [LOG_WR_DEPTH-1 : 0] w_q_temp [1:C_SYNCHRONIZER_STAGE]  ;
reg [LOG_WR_DEPTH-1 : 0] w_cnt_rd = 0;
reg [LOG_WR_DEPTH-1 : 0] w_cnt = 0;
reg [LOG_WR_DEPTH-1 : 0] w_cnt_gc = 0;
reg [LOG_WR_DEPTH-1 : 0] r_cnt = 0;
wire [LOG_WR_DEPTH : 0] adj_w_cnt_rd_pad;
wire [LOG_WR_DEPTH : 0] r_inv_pad;
wire [LOG_WR_DEPTH-1 : 0] d_cnt;
reg [LOG_WR_DEPTH : 0] d_cnt_pad = 0;
reg adj_w_cnt_rd_pad_0 = 0;
reg r_inv_pad_0 = 0;


   genvar l;

   generate for (l = 1; ((l <= C_SYNCHRONIZER_STAGE) && (C_HAS_DATA_COUNTS_AXIS == 3 && C_INTERFACE_TYPE == 0) ); l = l + 1) begin : g_cnt_sync_stage
     fifo_generator_v12_0_sync_stage
       #(
         .C_WIDTH  (LOG_WR_DEPTH)
        )
     rd_stg_inst
        (
         .RST      (rd_rst_int), 
         .CLK      (RD_CLK), 
         .DIN      (w_q[l-1]), 
         .DOUT     (w_q[l])
        );
   end endgenerate // gpkt_cnt_sync_stage



   generate if (C_INTERFACE_TYPE == 0 && C_HAS_DATA_COUNTS_AXIS == 3) begin : fifo_ic_adapter
    assign wr_eop_ad = WR_EN & !(FULL);
    assign rd_eop_ad = RD_EN & !(EMPTY);


  always @ (posedge wr_rst_int or posedge WR_CLK)
    begin
      if (wr_rst_int)
        w_cnt    <= 1'b0;
      else if (wr_eop_ad)
        w_cnt    <= w_cnt + 1;
    end

  always @ (posedge wr_rst_int or posedge WR_CLK)
    begin
      if (wr_rst_int)
        w_cnt_gc    <= 1'b0;
      else 
        w_cnt_gc    <= bin2gray(w_cnt);
    end


    assign  w_q[0]  = w_cnt_gc;
    assign  w_cnt_gc_asreg_last       = w_q[C_SYNCHRONIZER_STAGE];



  always @ (posedge rd_rst_int or posedge RD_CLK)
    begin
      if (rd_rst_int)
        w_cnt_rd    <= 1'b0;
      else 
        w_cnt_rd    <= gray2bin(w_cnt_gc_asreg_last);
    end

  always @ (posedge rd_rst_int or posedge RD_CLK)
    begin
      if (rd_rst_int)
        r_cnt    <= 1'b0;
      else if (rd_eop_ad)
        r_cnt    <= r_cnt + 1;
    end


  // Take the difference of write and read packet count
  // Logic is similar to rd_pe_as
   assign adj_w_cnt_rd_pad[LOG_WR_DEPTH : 1] = w_cnt_rd;
   assign r_inv_pad[LOG_WR_DEPTH : 1]        = ~r_cnt;
   assign adj_w_cnt_rd_pad[0]                = adj_w_cnt_rd_pad_0;
   assign r_inv_pad[0]                       = r_inv_pad_0;


  always @ ( rd_eop_ad )
    begin
      if (!rd_eop_ad) begin
        adj_w_cnt_rd_pad_0    <= 1'b1;
        r_inv_pad_0           <= 1'b1;
      end else begin 
        adj_w_cnt_rd_pad_0    <= 1'b0;
        r_inv_pad_0           <= 1'b0;
      end	
    end

  always @ (posedge rd_rst_int or posedge RD_CLK)
    begin
      if (rd_rst_int)
        d_cnt_pad    <= 1'b0;
      else 
        d_cnt_pad    <= adj_w_cnt_rd_pad + r_inv_pad ;
    end

   assign  d_cnt = d_cnt_pad [LOG_WR_DEPTH : 1] ;
   assign  WR_DATA_COUNT = d_cnt;

  end endgenerate // fifo_ic_adapter

      generate if (C_INTERFACE_TYPE == 0 && C_HAS_DATA_COUNTS_AXIS != 3) begin : fifo_icn_adapter
   assign  WR_DATA_COUNT = wr_data_count_in;

  end endgenerate // fifo_icn_adapter



  wire                          inverted_reset = ~S_ARESETN;
  wire                          axi_rs_rst;
  reg                           rst_d1 = 0        ;
  reg                           rst_d2 = 0        ;
  wire  [C_DIN_WIDTH_AXIS-1:0]  axis_din          ;
  wire  [C_DIN_WIDTH_AXIS-1:0]  axis_dout         ;
  wire                          axis_full         ;
  wire                          axis_almost_full  ;
  wire                          axis_empty        ;
  wire                          axis_s_axis_tready;
  wire                          axis_m_axis_tvalid;
  wire                          axis_wr_en        ;
  wire                          axis_rd_en        ;
  wire                          axis_we           ;
  wire                          axis_re           ;
  wire [C_WR_PNTR_WIDTH_AXIS:0] axis_dc;
  reg                           axis_pkt_read = 1'b0;
  wire                          axis_rd_rst;
  wire                          axis_wr_rst;

  generate if (C_INTERFACE_TYPE > 0 && (C_AXIS_TYPE == 1 || C_WACH_TYPE == 1 ||
               C_WDCH_TYPE == 1 || C_WRCH_TYPE == 1 || C_RACH_TYPE == 1 || C_RDCH_TYPE == 1)) begin : gaxi_rs_rst
      always @ (posedge inverted_reset or posedge S_ACLK) begin
        if (inverted_reset) begin
          rst_d1         <= 1'b1;
          rst_d2         <= 1'b1;
        end else begin
          rst_d1         <= #`TCQ 1'b0;
          rst_d2         <= #`TCQ rst_d1;
        end
      end

      assign axi_rs_rst = rst_d2;
  end endgenerate // gaxi_rs_rst

  generate if (IS_AXI_STREAMING == 1 && C_AXIS_TYPE == 0) begin : axi_streaming

    // Write protection when almost full or prog_full is high
    assign axis_we    = (C_PROG_FULL_TYPE_AXIS != 0) ? axis_s_axis_tready & S_AXIS_TVALID : 
                        (C_APPLICATION_TYPE_AXIS == 1) ? axis_s_axis_tready & S_AXIS_TVALID : S_AXIS_TVALID;

    // Read protection when almost empty or prog_empty is high
    assign axis_re    = (C_PROG_EMPTY_TYPE_AXIS != 0) ? axis_m_axis_tvalid & M_AXIS_TREADY :
                        (C_APPLICATION_TYPE_AXIS == 1) ? axis_m_axis_tvalid & M_AXIS_TREADY : M_AXIS_TREADY;
    assign axis_wr_en = (C_HAS_SLAVE_CE == 1)  ? axis_we & S_ACLK_EN : axis_we;
    assign axis_rd_en = (C_HAS_MASTER_CE == 1) ? axis_re & M_ACLK_EN : axis_re;

    FIFO_GENERATOR_v12_0_CONV_VER
      #(
        .C_FAMILY			(C_FAMILY),
        .C_COMMON_CLOCK                 (C_COMMON_CLOCK),
        .C_MEMORY_TYPE			((C_IMPLEMENTATION_TYPE_AXIS == 1  || C_IMPLEMENTATION_TYPE_AXIS == 11) ? 1 :
                                         (C_IMPLEMENTATION_TYPE_AXIS == 2  || C_IMPLEMENTATION_TYPE_AXIS == 12) ? 2 : 4),
        .C_IMPLEMENTATION_TYPE		((C_IMPLEMENTATION_TYPE_AXIS == 1  || C_IMPLEMENTATION_TYPE_AXIS == 2) ? 0 :
                                         (C_IMPLEMENTATION_TYPE_AXIS == 11 || C_IMPLEMENTATION_TYPE_AXIS == 12) ? 2 : 6),
        .C_PRELOAD_REGS			(1), // always FWFT for AXI
        .C_PRELOAD_LATENCY		(0), // always FWFT for AXI
        .C_DIN_WIDTH			(C_DIN_WIDTH_AXIS),
        .C_WR_DEPTH			(C_WR_DEPTH_AXIS),
        .C_WR_PNTR_WIDTH		(C_WR_PNTR_WIDTH_AXIS),
        .C_DOUT_WIDTH			(C_DIN_WIDTH_AXIS),
        .C_RD_DEPTH			(C_WR_DEPTH_AXIS),
        .C_RD_PNTR_WIDTH		(C_WR_PNTR_WIDTH_AXIS),
        .C_PROG_FULL_TYPE		(C_PROG_FULL_TYPE_AXIS),
        .C_PROG_FULL_THRESH_ASSERT_VAL	(C_PROG_FULL_THRESH_ASSERT_VAL_AXIS),
        .C_PROG_EMPTY_TYPE		(C_PROG_EMPTY_TYPE_AXIS),
        .C_PROG_EMPTY_THRESH_ASSERT_VAL	(C_PROG_EMPTY_THRESH_ASSERT_VAL_AXIS),
        .C_USE_ECC                      (C_USE_ECC_AXIS),
        .C_ERROR_INJECTION_TYPE         (C_ERROR_INJECTION_TYPE_AXIS),
        .C_HAS_ALMOST_EMPTY		(0),
        .C_HAS_ALMOST_FULL		(C_APPLICATION_TYPE_AXIS == 1 ? 1: 0),
        .C_AXI_TYPE                     (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE),
        .C_USE_EMBEDDED_REG		(C_USE_EMBEDDED_REG),

        .C_FIFO_TYPE                    (C_APPLICATION_TYPE_AXIS == 1 ? 0: C_APPLICATION_TYPE_AXIS),
        .C_SYNCHRONIZER_STAGE           (C_SYNCHRONIZER_STAGE),

        .C_HAS_WR_RST			(0),
        .C_HAS_RD_RST			(0),
        .C_HAS_RST			(1),
        .C_HAS_SRST			(0),
        .C_DOUT_RST_VAL			(0),

        .C_HAS_VALID			(0),
        .C_VALID_LOW			(C_VALID_LOW),
        .C_HAS_UNDERFLOW		(C_HAS_UNDERFLOW),
        .C_UNDERFLOW_LOW		(C_UNDERFLOW_LOW),
        .C_HAS_WR_ACK			(0),
        .C_WR_ACK_LOW			(C_WR_ACK_LOW),
        .C_HAS_OVERFLOW			(C_HAS_OVERFLOW),
        .C_OVERFLOW_LOW			(C_OVERFLOW_LOW),

        .C_HAS_DATA_COUNT		((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_AXIS == 1) ? 1 : 0),
        .C_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_AXIS + 1),
        .C_HAS_RD_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_AXIS == 1) ? 1 : 0),
        .C_RD_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_AXIS + 1),
        .C_USE_FWFT_DATA_COUNT		(1), // use extra logic is always true
        .C_HAS_WR_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_AXIS == 1) ? 1 : 0),
        .C_WR_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_AXIS + 1),
        .C_FULL_FLAGS_RST_VAL           (1),
        .C_USE_DOUT_RST                 (0),
        .C_MSGON_VAL                    (C_MSGON_VAL),
        .C_ENABLE_RST_SYNC              (1),

        .C_COUNT_TYPE			(C_COUNT_TYPE),
        .C_DEFAULT_VALUE		(C_DEFAULT_VALUE),
        .C_ENABLE_RLOCS			(C_ENABLE_RLOCS),
        .C_HAS_BACKUP			(C_HAS_BACKUP),
        .C_HAS_INT_CLK                  (C_HAS_INT_CLK),
        .C_MIF_FILE_NAME		(C_MIF_FILE_NAME),
        .C_HAS_MEMINIT_FILE		(C_HAS_MEMINIT_FILE),
        .C_INIT_WR_PNTR_VAL		(C_INIT_WR_PNTR_VAL),
        .C_OPTIMIZATION_MODE		(C_OPTIMIZATION_MODE),
        .C_PRIM_FIFO_TYPE		(C_PRIM_FIFO_TYPE),
        .C_RD_FREQ			(C_RD_FREQ),
        .C_USE_FIFO16_FLAGS		(C_USE_FIFO16_FLAGS),
        .C_WR_FREQ			(C_WR_FREQ),
        .C_WR_RESPONSE_LATENCY		(C_WR_RESPONSE_LATENCY)
      )
    fifo_generator_v12_0_axis_dut
      (
        .CLK                      (S_ACLK),
        .WR_CLK                   (S_ACLK),
        .RD_CLK                   (M_ACLK),
        .RST                      (inverted_reset),
        .SRST                     (1'b0),
        .WR_RST                   (inverted_reset),
        .RD_RST                   (inverted_reset),
        .WR_EN                    (axis_wr_en),
        .RD_EN                    (axis_rd_en),
        .PROG_FULL_THRESH         (AXIS_PROG_FULL_THRESH),
        .PROG_FULL_THRESH_ASSERT  ({C_WR_PNTR_WIDTH_AXIS{1'b0}}),
        .PROG_FULL_THRESH_NEGATE  ({C_WR_PNTR_WIDTH_AXIS{1'b0}}),
        .PROG_EMPTY_THRESH        (AXIS_PROG_EMPTY_THRESH),
        .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_AXIS{1'b0}}),
        .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_AXIS{1'b0}}),
        .INJECTDBITERR            (AXIS_INJECTDBITERR), 
        .INJECTSBITERR            (AXIS_INJECTSBITERR),
  
        .DIN                      (axis_din),
        .DOUT                     (axis_dout),
        .FULL                     (axis_full),
        .EMPTY                    (axis_empty),
        .ALMOST_FULL              (axis_almost_full),
        .PROG_FULL                (AXIS_PROG_FULL),
        .ALMOST_EMPTY             (),
        .PROG_EMPTY               (AXIS_PROG_EMPTY),
  
        .WR_ACK                   (),
        .OVERFLOW                 (AXIS_OVERFLOW),
        .VALID                    (),
        .UNDERFLOW                (AXIS_UNDERFLOW),
        .DATA_COUNT               (axis_dc),
        .RD_DATA_COUNT            (AXIS_RD_DATA_COUNT),
        .WR_DATA_COUNT            (AXIS_WR_DATA_COUNT),
        .SBITERR                  (AXIS_SBITERR),
        .DBITERR                  (AXIS_DBITERR),
        .wr_rst_busy              (wr_rst_busy_axis),
        .rd_rst_busy              (rd_rst_busy_axis),
        .wr_rst_i_out             (axis_wr_rst),
        .rd_rst_i_out             (axis_rd_rst),
  
        .BACKUP                   (BACKUP),
        .BACKUP_MARKER            (BACKUP_MARKER),
        .INT_CLK                  (INT_CLK)
       );

    assign axis_s_axis_tready    = (IS_8SERIES == 0) ? ~axis_full : (C_IMPLEMENTATION_TYPE_AXIS == 5 || C_IMPLEMENTATION_TYPE_AXIS == 13) ? ~(axis_full | wr_rst_busy_axis) : ~axis_full;
    assign axis_m_axis_tvalid    = (C_APPLICATION_TYPE_AXIS != 1) ? ~axis_empty : ~axis_empty & axis_pkt_read;
    assign S_AXIS_TREADY         = axis_s_axis_tready;
    assign M_AXIS_TVALID         = axis_m_axis_tvalid;

  end endgenerate // axi_streaming

  wire axis_wr_eop;
  reg  axis_wr_eop_d1 = 1'b0;
  wire axis_rd_eop;
  integer  axis_pkt_cnt;

  generate if (C_APPLICATION_TYPE_AXIS == 1 && C_COMMON_CLOCK == 1) begin : gaxis_pkt_fifo_cc
    assign axis_wr_eop = axis_wr_en & S_AXIS_TLAST;
    assign axis_rd_eop = axis_rd_en & axis_dout[0];

    always @ (posedge inverted_reset or posedge S_ACLK)
    begin
      if (inverted_reset)
        axis_pkt_read    <= 1'b0;
      else if (axis_rd_eop && (axis_pkt_cnt == 1) && ~axis_wr_eop_d1)
        axis_pkt_read    <= 1'b0;
      else if ((axis_pkt_cnt > 0) || (axis_almost_full && ~axis_empty))
        axis_pkt_read    <= 1'b1;
    end

    always @ (posedge inverted_reset or posedge S_ACLK)
    begin
      if (inverted_reset)
        axis_wr_eop_d1    <= 1'b0;
      else
        axis_wr_eop_d1   <= axis_wr_eop;
    end

    always @ (posedge inverted_reset or posedge S_ACLK)
    begin
      if (inverted_reset)
        axis_pkt_cnt    <= 0;
      else if (axis_wr_eop_d1 && ~axis_rd_eop)
        axis_pkt_cnt    <= axis_pkt_cnt + 1;
      else if (axis_rd_eop && ~axis_wr_eop_d1)
        axis_pkt_cnt    <= axis_pkt_cnt - 1;
    end
  end endgenerate // gaxis_pkt_fifo_cc


reg [LOG_DEPTH_AXIS-1 : 0] axis_wpkt_cnt_gc = 0;
wire [(LOG_DEPTH_AXIS)-1 : 0] axis_wpkt_cnt_gc_asreg_last;
wire axis_rd_has_rst;
wire [0:C_SYNCHRONIZER_STAGE] axis_af_q ;
wire  [LOG_DEPTH_AXIS-1 : 0]  wpkt_q [0:C_SYNCHRONIZER_STAGE] ;
wire [1:C_SYNCHRONIZER_STAGE] axis_af_q_temp = 0;
wire [LOG_DEPTH_AXIS-1 : 0] wpkt_q_temp [1:C_SYNCHRONIZER_STAGE]  ;
reg [LOG_DEPTH_AXIS-1 : 0] axis_wpkt_cnt_rd = 0;
reg [LOG_DEPTH_AXIS-1 : 0] axis_wpkt_cnt = 0;
reg [LOG_DEPTH_AXIS-1 : 0] axis_rpkt_cnt = 0;
wire [LOG_DEPTH_AXIS : 0] adj_axis_wpkt_cnt_rd_pad;
wire [LOG_DEPTH_AXIS : 0] rpkt_inv_pad;
wire [LOG_DEPTH_AXIS-1 : 0] diff_pkt_cnt;
reg [LOG_DEPTH_AXIS : 0] diff_pkt_cnt_pad = 0;
reg adj_axis_wpkt_cnt_rd_pad_0 = 0;
reg rpkt_inv_pad_0 = 0;
wire axis_af_rd ;

generate if (C_HAS_RST == 1) begin : rst_blk_has
  assign axis_rd_has_rst = axis_rd_rst;
end endgenerate //rst_blk_has

generate if (C_HAS_RST == 0) begin :rst_blk_no
  assign axis_rd_has_rst = 1'b0;
end endgenerate //rst_blk_no

   genvar i;

   generate for (i = 1; ((i <= C_SYNCHRONIZER_STAGE) && (C_APPLICATION_TYPE_AXIS == 1 && C_COMMON_CLOCK == 0) ); i = i + 1) begin : gpkt_cnt_sync_stage
     fifo_generator_v12_0_sync_stage
       #(
         .C_WIDTH  (LOG_DEPTH_AXIS)
        )
     rd_stg_inst
        (
         .RST      (axis_rd_has_rst), 
         .CLK      (M_ACLK), 
         .DIN      (wpkt_q[i-1]), 
         .DOUT     (wpkt_q[i])
        );
 
     fifo_generator_v12_0_sync_stage
       #(
         .C_WIDTH  (1)
        )
     wr_stg_inst
        (
         .RST      (axis_rd_has_rst), 
         .CLK      (M_ACLK), 
         .DIN      (axis_af_q[i-1]), 
         .DOUT     (axis_af_q[i])
        );
   end endgenerate // gpkt_cnt_sync_stage


  generate if (C_APPLICATION_TYPE_AXIS == 1 && C_COMMON_CLOCK == 0) begin : gaxis_pkt_fifo_ic
    assign axis_wr_eop = axis_wr_en & S_AXIS_TLAST;
    assign axis_rd_eop = axis_rd_en & axis_dout[0];

    always @ (posedge axis_rd_has_rst or posedge M_ACLK)
    begin
      if (axis_rd_has_rst)
        axis_pkt_read    <= 1'b0;
      else if (axis_rd_eop && (diff_pkt_cnt == 1))
        axis_pkt_read    <= 1'b0;
      else if ((diff_pkt_cnt > 0) || (axis_af_rd && ~axis_empty))
        axis_pkt_read    <= 1'b1;
    end

  always @ (posedge axis_wr_rst or posedge S_ACLK)
    begin
      if (axis_wr_rst)
        axis_wpkt_cnt    <= 1'b0;
      else if (axis_wr_eop)
        axis_wpkt_cnt    <= axis_wpkt_cnt + 1;
    end

  always @ (posedge axis_wr_rst or posedge S_ACLK)
    begin
      if (axis_wr_rst)
        axis_wpkt_cnt_gc    <= 1'b0;
      else 
        axis_wpkt_cnt_gc    <= bin2gray(axis_wpkt_cnt);
    end


    assign  wpkt_q[0]  = axis_wpkt_cnt_gc;
    assign  axis_wpkt_cnt_gc_asreg_last       = wpkt_q[C_SYNCHRONIZER_STAGE];
    assign  axis_af_q[0]                      = axis_almost_full;
    //assign  axis_af_q[1:C_SYNCHRONIZER_STAGE] = axis_af_q_temp[1:C_SYNCHRONIZER_STAGE];
    assign  axis_af_rd                        = axis_af_q[C_SYNCHRONIZER_STAGE];



  always @ (posedge axis_rd_has_rst or posedge M_ACLK)
    begin
      if (axis_rd_has_rst)
        axis_wpkt_cnt_rd    <= 1'b0;
      else 
        axis_wpkt_cnt_rd    <= gray2bin(axis_wpkt_cnt_gc_asreg_last);
    end

  always @ (posedge axis_rd_rst or posedge M_ACLK)
    begin
      if (axis_rd_has_rst)
        axis_rpkt_cnt    <= 1'b0;
      else if (axis_rd_eop)
        axis_rpkt_cnt    <= axis_rpkt_cnt + 1;
    end


  // Take the difference of write and read packet count
  // Logic is similar to rd_pe_as
   assign adj_axis_wpkt_cnt_rd_pad[LOG_DEPTH_AXIS : 1] = axis_wpkt_cnt_rd;
   assign rpkt_inv_pad[LOG_DEPTH_AXIS : 1]             = ~axis_rpkt_cnt;
   assign adj_axis_wpkt_cnt_rd_pad[0]                                = adj_axis_wpkt_cnt_rd_pad_0;
   assign rpkt_inv_pad[0]                                            = rpkt_inv_pad_0;


  always @ ( axis_rd_eop )
    begin
      if (!axis_rd_eop) begin
        adj_axis_wpkt_cnt_rd_pad_0    <= 1'b1;
        rpkt_inv_pad_0                <= 1'b1;
      end else begin 
        adj_axis_wpkt_cnt_rd_pad_0    <= 1'b0;
        rpkt_inv_pad_0                <= 1'b0;
      end	
    end

  always @ (posedge axis_rd_rst or posedge M_ACLK)
    begin
      if (axis_rd_has_rst)
        diff_pkt_cnt_pad    <= 1'b0;
      else 
        diff_pkt_cnt_pad    <= adj_axis_wpkt_cnt_rd_pad + rpkt_inv_pad ;
    end

   assign  diff_pkt_cnt = diff_pkt_cnt_pad [LOG_DEPTH_AXIS : 1] ;





   end endgenerate // gaxis_pkt_fifo_ic




  // Generate the accurate data count for axi stream packet fifo configuration
  reg [C_WR_PNTR_WIDTH_AXIS:0] axis_dc_pkt_fifo = 0;
  generate if (IS_AXI_STREAMING == 1 && C_HAS_DATA_COUNTS_AXIS == 1 && C_APPLICATION_TYPE_AXIS == 1) begin : gdc_pkt
    always @ (posedge inverted_reset or posedge S_ACLK)
    begin
      if (inverted_reset)
        axis_dc_pkt_fifo <= 0;
      else if (axis_wr_en && (~axis_rd_en))
        axis_dc_pkt_fifo <= #`TCQ axis_dc_pkt_fifo + 1;
      else if (~axis_wr_en && axis_rd_en)
        axis_dc_pkt_fifo <= #`TCQ axis_dc_pkt_fifo - 1;
    end
    assign AXIS_DATA_COUNT = axis_dc_pkt_fifo;
  end endgenerate // gdc_pkt

  generate if (IS_AXI_STREAMING == 1 && C_HAS_DATA_COUNTS_AXIS == 0 && C_APPLICATION_TYPE_AXIS == 1) begin : gndc_pkt
    assign AXIS_DATA_COUNT = 0;
  end endgenerate // gndc_pkt

  generate if (IS_AXI_STREAMING == 1 && C_APPLICATION_TYPE_AXIS != 1) begin : gdc
    assign AXIS_DATA_COUNT = axis_dc;
  end endgenerate // gdc

  // Register Slice for Write Address Channel
  generate if (C_AXIS_TYPE == 1) begin : gaxis_reg_slice
    assign axis_wr_en = (C_HAS_SLAVE_CE == 1)  ? S_AXIS_TVALID & S_ACLK_EN : S_AXIS_TVALID;
    assign axis_rd_en = (C_HAS_MASTER_CE == 1) ? M_AXIS_TREADY & M_ACLK_EN : M_AXIS_TREADY;

    fifo_generator_v12_0_axic_reg_slice
          #(
            .C_FAMILY                (C_FAMILY),
            .C_DATA_WIDTH            (C_DIN_WIDTH_AXIS),
            .C_REG_CONFIG            (C_REG_SLICE_MODE_AXIS)
            )
    axis_reg_slice_inst
        (
          // System Signals
          .ACLK                      (S_ACLK),
          .ARESET                    (axi_rs_rst),

          // Slave side
          .S_PAYLOAD_DATA            (axis_din),
          .S_VALID                   (axis_wr_en),
          .S_READY                   (S_AXIS_TREADY),

          // Master side
          .M_PAYLOAD_DATA            (axis_dout),
          .M_VALID                   (M_AXIS_TVALID),
          .M_READY                   (axis_rd_en)
          );
  end endgenerate // gaxis_reg_slice



  generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TDATA == 1) begin : tdata
    assign axis_din[C_DIN_WIDTH_AXIS-1:TDATA_OFFSET] = S_AXIS_TDATA;
    assign M_AXIS_TDATA   = axis_dout[C_DIN_WIDTH_AXIS-1:TDATA_OFFSET];
  end endgenerate

  generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TSTRB == 1) begin : tstrb
    assign axis_din[TDATA_OFFSET-1:TSTRB_OFFSET] = S_AXIS_TSTRB;
    assign M_AXIS_TSTRB   = axis_dout[TDATA_OFFSET-1:TSTRB_OFFSET];
  end endgenerate

  generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TKEEP == 1) begin : tkeep
    assign axis_din[TSTRB_OFFSET-1:TKEEP_OFFSET] = S_AXIS_TKEEP;
    assign M_AXIS_TKEEP   = axis_dout[TSTRB_OFFSET-1:TKEEP_OFFSET];
  end endgenerate

  generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TID == 1) begin : tid
    assign axis_din[TKEEP_OFFSET-1:TID_OFFSET] = S_AXIS_TID;
    assign M_AXIS_TID     = axis_dout[TKEEP_OFFSET-1:TID_OFFSET];
  end endgenerate

  generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TDEST == 1) begin : tdest
    assign axis_din[TID_OFFSET-1:TDEST_OFFSET] = S_AXIS_TDEST;
    assign M_AXIS_TDEST   = axis_dout[TID_OFFSET-1:TDEST_OFFSET];
  end endgenerate

  generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TUSER == 1) begin : tuser
    assign axis_din[TDEST_OFFSET-1:TUSER_OFFSET] = S_AXIS_TUSER;
    assign M_AXIS_TUSER   = axis_dout[TDEST_OFFSET-1:TUSER_OFFSET];
  end endgenerate

  generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TLAST == 1) begin : tlast
    assign axis_din[0] = S_AXIS_TLAST;
    assign M_AXIS_TLAST   = axis_dout[0];
  end endgenerate

  //###########################################################################
  //  AXI FULL Write Channel (axi_write_channel)
  //###########################################################################

  localparam IS_AXI_FULL       = ((C_INTERFACE_TYPE == 2) && (C_AXI_TYPE != 2)) ? 1 : 0;
  localparam IS_AXI_LITE       = ((C_INTERFACE_TYPE == 2) && (C_AXI_TYPE == 2)) ? 1 : 0;

  localparam IS_AXI_FULL_WACH  = ((IS_AXI_FULL == 1) && (C_WACH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0;
  localparam IS_AXI_FULL_WDCH  = ((IS_AXI_FULL == 1) && (C_WDCH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0;
  localparam IS_AXI_FULL_WRCH  = ((IS_AXI_FULL == 1) && (C_WRCH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0;
  localparam IS_AXI_FULL_RACH  = ((IS_AXI_FULL == 1) && (C_RACH_TYPE == 0) && C_HAS_AXI_RD_CHANNEL == 1) ? 1 : 0;
  localparam IS_AXI_FULL_RDCH  = ((IS_AXI_FULL == 1) && (C_RDCH_TYPE == 0) && C_HAS_AXI_RD_CHANNEL == 1) ? 1 : 0;

  localparam IS_AXI_LITE_WACH  = ((IS_AXI_LITE == 1) && (C_WACH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0;
  localparam IS_AXI_LITE_WDCH  = ((IS_AXI_LITE == 1) && (C_WDCH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0;
  localparam IS_AXI_LITE_WRCH  = ((IS_AXI_LITE == 1) && (C_WRCH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0;
  localparam IS_AXI_LITE_RACH  = ((IS_AXI_LITE == 1) && (C_RACH_TYPE == 0) && C_HAS_AXI_RD_CHANNEL == 1) ? 1 : 0;
  localparam IS_AXI_LITE_RDCH  = ((IS_AXI_LITE == 1) && (C_RDCH_TYPE == 0) && C_HAS_AXI_RD_CHANNEL == 1) ? 1 : 0;

  localparam IS_WR_ADDR_CH     = ((IS_AXI_FULL_WACH == 1) || (IS_AXI_LITE_WACH == 1)) ? 1 : 0;
  localparam IS_WR_DATA_CH     = ((IS_AXI_FULL_WDCH == 1) || (IS_AXI_LITE_WDCH == 1)) ? 1 : 0;
  localparam IS_WR_RESP_CH     = ((IS_AXI_FULL_WRCH == 1) || (IS_AXI_LITE_WRCH == 1)) ? 1 : 0;
  localparam IS_RD_ADDR_CH     = ((IS_AXI_FULL_RACH == 1) || (IS_AXI_LITE_RACH == 1)) ? 1 : 0;
  localparam IS_RD_DATA_CH     = ((IS_AXI_FULL_RDCH == 1) || (IS_AXI_LITE_RDCH == 1)) ? 1 : 0;

  localparam AWID_OFFSET       = (C_AXI_TYPE != 2 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_WACH - C_AXI_ID_WIDTH : C_DIN_WIDTH_WACH;
  localparam AWADDR_OFFSET     = AWID_OFFSET - C_AXI_ADDR_WIDTH;
  localparam AWLEN_OFFSET      = C_AXI_TYPE != 2 ? AWADDR_OFFSET - C_AXI_LEN_WIDTH : AWADDR_OFFSET;
  localparam AWSIZE_OFFSET     = C_AXI_TYPE != 2 ? AWLEN_OFFSET - C_AXI_SIZE_WIDTH : AWLEN_OFFSET;
  localparam AWBURST_OFFSET    = C_AXI_TYPE != 2 ? AWSIZE_OFFSET - C_AXI_BURST_WIDTH : AWSIZE_OFFSET;
  localparam AWLOCK_OFFSET     = C_AXI_TYPE != 2 ? AWBURST_OFFSET - C_AXI_LOCK_WIDTH : AWBURST_OFFSET;
  localparam AWCACHE_OFFSET    = C_AXI_TYPE != 2 ? AWLOCK_OFFSET - C_AXI_CACHE_WIDTH : AWLOCK_OFFSET;
  localparam AWPROT_OFFSET     = AWCACHE_OFFSET - C_AXI_PROT_WIDTH;
  localparam AWQOS_OFFSET      = AWPROT_OFFSET - C_AXI_QOS_WIDTH;
  localparam AWREGION_OFFSET   = C_AXI_TYPE == 1 ? AWQOS_OFFSET - C_AXI_REGION_WIDTH : AWQOS_OFFSET;
  localparam AWUSER_OFFSET     = C_HAS_AXI_AWUSER == 1 ? AWREGION_OFFSET-C_AXI_AWUSER_WIDTH : AWREGION_OFFSET;

  localparam WID_OFFSET        = (C_AXI_TYPE == 3 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_WDCH - C_AXI_ID_WIDTH : C_DIN_WIDTH_WDCH;
  localparam WDATA_OFFSET      = WID_OFFSET - C_AXI_DATA_WIDTH;
  localparam WSTRB_OFFSET      = WDATA_OFFSET - C_AXI_DATA_WIDTH/8;
  localparam WUSER_OFFSET      = C_HAS_AXI_WUSER == 1 ? WSTRB_OFFSET-C_AXI_WUSER_WIDTH : WSTRB_OFFSET;

  localparam BID_OFFSET        = (C_AXI_TYPE != 2 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_WRCH - C_AXI_ID_WIDTH : C_DIN_WIDTH_WRCH;
  localparam BRESP_OFFSET      = BID_OFFSET - C_AXI_BRESP_WIDTH;
  localparam BUSER_OFFSET      = C_HAS_AXI_BUSER == 1 ? BRESP_OFFSET-C_AXI_BUSER_WIDTH : BRESP_OFFSET;


  wire  [C_DIN_WIDTH_WACH-1:0]  wach_din          ;
  wire  [C_DIN_WIDTH_WACH-1:0]  wach_dout         ;
  wire  [C_DIN_WIDTH_WACH-1:0]  wach_dout_pkt     ;
  wire                          wach_full         ;
  wire                          wach_almost_full  ;
  wire                          wach_prog_full    ;
  wire                          wach_empty        ;
  wire                          wach_almost_empty ;
  wire                          wach_prog_empty   ;
  wire  [C_DIN_WIDTH_WDCH-1:0]  wdch_din          ;
  wire  [C_DIN_WIDTH_WDCH-1:0]  wdch_dout         ;
  wire                          wdch_full         ;
  wire                          wdch_almost_full  ;
  wire                          wdch_prog_full    ;
  wire                          wdch_empty        ;
  wire                          wdch_almost_empty ;
  wire                          wdch_prog_empty   ;
  wire  [C_DIN_WIDTH_WRCH-1:0]  wrch_din          ;
  wire  [C_DIN_WIDTH_WRCH-1:0]  wrch_dout         ;
  wire                          wrch_full         ;
  wire                          wrch_almost_full  ;
  wire                          wrch_prog_full    ;
  wire                          wrch_empty        ;
  wire                          wrch_almost_empty ;
  wire                          wrch_prog_empty   ;
  wire                          axi_aw_underflow_i;
  wire                          axi_w_underflow_i ;
  wire                          axi_b_underflow_i ;
  wire                          axi_aw_overflow_i ;
  wire                          axi_w_overflow_i  ;
  wire                          axi_b_overflow_i  ;
  wire                          axi_wr_underflow_i;
  wire                          axi_wr_overflow_i ;
  wire                          wach_s_axi_awready;
  wire                          wach_m_axi_awvalid;
  wire                          wach_wr_en        ;
  wire                          wach_rd_en        ;
  wire                          wdch_s_axi_wready ;
  wire                          wdch_m_axi_wvalid ;
  wire                          wdch_wr_en        ;
  wire                          wdch_rd_en        ;
  wire                          wrch_s_axi_bvalid ;
  wire                          wrch_m_axi_bready ;
  wire                          wrch_wr_en        ;
  wire                          wrch_rd_en        ;
  wire                          txn_count_up      ;
  wire                          txn_count_down    ;
  wire                          awvalid_en        ;
  wire                          awvalid_pkt       ;
  wire                          awready_pkt       ;
  integer                       wr_pkt_count      ;
  wire                          wach_we           ;
  wire                          wach_re           ;
  wire                          wdch_we           ;
  wire                          wdch_re           ;
  wire                          wrch_we           ;
  wire                          wrch_re           ;

  generate if (IS_WR_ADDR_CH == 1) begin : axi_write_address_channel
    // Write protection when almost full or prog_full is high
    assign wach_we    = (C_PROG_FULL_TYPE_WACH != 0) ? wach_s_axi_awready & S_AXI_AWVALID : S_AXI_AWVALID;

    // Read protection when almost empty or prog_empty is high
    assign wach_re    = (C_PROG_EMPTY_TYPE_WACH != 0 && C_APPLICATION_TYPE_WACH == 1) ? 
                        wach_m_axi_awvalid & awready_pkt & awvalid_en : 
                        (C_PROG_EMPTY_TYPE_WACH != 0 && C_APPLICATION_TYPE_WACH != 1) ? 
                        M_AXI_AWREADY && wach_m_axi_awvalid :
                        (C_PROG_EMPTY_TYPE_WACH == 0 && C_APPLICATION_TYPE_WACH == 1) ? 
                        awready_pkt & awvalid_en : 
                        (C_PROG_EMPTY_TYPE_WACH == 0 && C_APPLICATION_TYPE_WACH != 1) ? 
                        M_AXI_AWREADY : 1'b0;
    assign wach_wr_en = (C_HAS_SLAVE_CE == 1)  ? wach_we & S_ACLK_EN : wach_we;
    assign wach_rd_en = (C_HAS_MASTER_CE == 1) ? wach_re & M_ACLK_EN : wach_re;

    FIFO_GENERATOR_v12_0_CONV_VER
      #(
        .C_FAMILY			(C_FAMILY),
        .C_COMMON_CLOCK                 (C_COMMON_CLOCK),
        .C_MEMORY_TYPE			((C_IMPLEMENTATION_TYPE_WACH == 1  || C_IMPLEMENTATION_TYPE_WACH == 11) ? 1 :
                                         (C_IMPLEMENTATION_TYPE_WACH == 2  || C_IMPLEMENTATION_TYPE_WACH == 12) ? 2 : 4),
        .C_IMPLEMENTATION_TYPE		((C_IMPLEMENTATION_TYPE_WACH == 1  || C_IMPLEMENTATION_TYPE_WACH == 2) ? 0 :
                                         (C_IMPLEMENTATION_TYPE_WACH == 11 || C_IMPLEMENTATION_TYPE_WACH == 12) ? 2 : 6),
        .C_PRELOAD_REGS			(1), // always FWFT for AXI
        .C_PRELOAD_LATENCY		(0), // always FWFT for AXI
        .C_DIN_WIDTH			(C_DIN_WIDTH_WACH),
        .C_WR_DEPTH			(C_WR_DEPTH_WACH),
        .C_WR_PNTR_WIDTH		(C_WR_PNTR_WIDTH_WACH),
        .C_DOUT_WIDTH			(C_DIN_WIDTH_WACH),
        .C_RD_DEPTH			(C_WR_DEPTH_WACH),
        .C_RD_PNTR_WIDTH		(C_WR_PNTR_WIDTH_WACH),
        .C_PROG_FULL_TYPE		(C_PROG_FULL_TYPE_WACH),
        .C_PROG_FULL_THRESH_ASSERT_VAL	(C_PROG_FULL_THRESH_ASSERT_VAL_WACH),
        .C_PROG_EMPTY_TYPE		(C_PROG_EMPTY_TYPE_WACH),
        .C_PROG_EMPTY_THRESH_ASSERT_VAL	(C_PROG_EMPTY_THRESH_ASSERT_VAL_WACH),
        .C_USE_ECC                      (C_USE_ECC_WACH),
        .C_ERROR_INJECTION_TYPE         (C_ERROR_INJECTION_TYPE_WACH),
        .C_HAS_ALMOST_EMPTY		(0),
        .C_HAS_ALMOST_FULL		(0),
        .C_AXI_TYPE                     (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE),

        .C_FIFO_TYPE                    ((C_APPLICATION_TYPE_WACH == 1)?0:C_APPLICATION_TYPE_WACH),
        .C_SYNCHRONIZER_STAGE           (C_SYNCHRONIZER_STAGE),

        .C_HAS_WR_RST			(0),
        .C_HAS_RD_RST			(0),
        .C_HAS_RST			(1),
        .C_HAS_SRST			(0),
        .C_DOUT_RST_VAL			(0),

        .C_HAS_VALID			(0),
        .C_VALID_LOW			(C_VALID_LOW),
        .C_HAS_UNDERFLOW		(C_HAS_UNDERFLOW),
        .C_UNDERFLOW_LOW		(C_UNDERFLOW_LOW),
        .C_HAS_WR_ACK			(0),
        .C_WR_ACK_LOW			(C_WR_ACK_LOW),
        .C_HAS_OVERFLOW			(C_HAS_OVERFLOW),
        .C_OVERFLOW_LOW			(C_OVERFLOW_LOW),

        .C_HAS_DATA_COUNT		((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_WACH == 1) ? 1 : 0),
        .C_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_WACH + 1),
        .C_HAS_RD_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WACH == 1) ? 1 : 0),
        .C_RD_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_WACH + 1),
        .C_USE_FWFT_DATA_COUNT		(1), // use extra logic is always true
        .C_HAS_WR_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WACH == 1) ? 1 : 0),
        .C_WR_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_WACH + 1),
        .C_FULL_FLAGS_RST_VAL           (1),
        .C_USE_EMBEDDED_REG		(0),
        .C_USE_DOUT_RST                 (0),
        .C_MSGON_VAL                    (C_MSGON_VAL),
        .C_ENABLE_RST_SYNC              (1),

        .C_COUNT_TYPE			(C_COUNT_TYPE),
        .C_DEFAULT_VALUE		(C_DEFAULT_VALUE),
        .C_ENABLE_RLOCS			(C_ENABLE_RLOCS),
        .C_HAS_BACKUP			(C_HAS_BACKUP),
        .C_HAS_INT_CLK                  (C_HAS_INT_CLK),
        .C_MIF_FILE_NAME		(C_MIF_FILE_NAME),
        .C_HAS_MEMINIT_FILE		(C_HAS_MEMINIT_FILE),
        .C_INIT_WR_PNTR_VAL		(C_INIT_WR_PNTR_VAL),
        .C_OPTIMIZATION_MODE		(C_OPTIMIZATION_MODE),
        .C_PRIM_FIFO_TYPE		(C_PRIM_FIFO_TYPE),
        .C_RD_FREQ			(C_RD_FREQ),
        .C_USE_FIFO16_FLAGS		(C_USE_FIFO16_FLAGS),
        .C_WR_FREQ			(C_WR_FREQ),
        .C_WR_RESPONSE_LATENCY		(C_WR_RESPONSE_LATENCY)
      )
    fifo_generator_v12_0_wach_dut
      (
        .CLK                      (S_ACLK),
        .WR_CLK                   (S_ACLK),
        .RD_CLK                   (M_ACLK),
        .RST                      (inverted_reset),
        .SRST                     (1'b0),
        .WR_RST                   (inverted_reset),
        .RD_RST                   (inverted_reset),
        .WR_EN                    (wach_wr_en),
        .RD_EN                    (wach_rd_en),
        .PROG_FULL_THRESH         (AXI_AW_PROG_FULL_THRESH),
        .PROG_FULL_THRESH_ASSERT  ({C_WR_PNTR_WIDTH_WACH{1'b0}}),
        .PROG_FULL_THRESH_NEGATE  ({C_WR_PNTR_WIDTH_WACH{1'b0}}),
        .PROG_EMPTY_THRESH        (AXI_AW_PROG_EMPTY_THRESH),
        .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_WACH{1'b0}}),
        .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_WACH{1'b0}}),
        .INJECTDBITERR            (AXI_AW_INJECTDBITERR), 
        .INJECTSBITERR            (AXI_AW_INJECTSBITERR),
  
        .DIN                      (wach_din),
        .DOUT                     (wach_dout_pkt),
        .FULL                     (wach_full),
        .EMPTY                    (wach_empty),
        .ALMOST_FULL              (),
        .PROG_FULL                (AXI_AW_PROG_FULL),
        .ALMOST_EMPTY             (),
        .PROG_EMPTY               (AXI_AW_PROG_EMPTY),
  
        .WR_ACK                   (),
        .OVERFLOW                 (axi_aw_overflow_i),
        .VALID                    (),
        .UNDERFLOW                (axi_aw_underflow_i),
        .DATA_COUNT               (AXI_AW_DATA_COUNT),
        .RD_DATA_COUNT            (AXI_AW_RD_DATA_COUNT),
        .WR_DATA_COUNT            (AXI_AW_WR_DATA_COUNT),
        .SBITERR                  (AXI_AW_SBITERR),
        .DBITERR                  (AXI_AW_DBITERR),
        .wr_rst_busy              (wr_rst_busy_wach),
        .rd_rst_busy              (rd_rst_busy_wach),
        .wr_rst_i_out             (),
        .rd_rst_i_out             (),
  
        .BACKUP                   (BACKUP),
        .BACKUP_MARKER            (BACKUP_MARKER),
        .INT_CLK                  (INT_CLK)
       );

    assign wach_s_axi_awready    = (IS_8SERIES == 0) ? ~wach_full : (C_IMPLEMENTATION_TYPE_WACH == 5 || C_IMPLEMENTATION_TYPE_WACH == 13) ? ~(wach_full | wr_rst_busy_wach) : ~wach_full;
    assign wach_m_axi_awvalid   = ~wach_empty;
    assign S_AXI_AWREADY        = wach_s_axi_awready;

    assign AXI_AW_UNDERFLOW  = C_USE_COMMON_UNDERFLOW == 0 ? axi_aw_underflow_i : 0;
    assign AXI_AW_OVERFLOW   = C_USE_COMMON_OVERFLOW  == 0 ? axi_aw_overflow_i  : 0;

  end endgenerate // axi_write_address_channel

  // Register Slice for Write Address Channel
  generate if (C_WACH_TYPE == 1) begin : gwach_reg_slice

    fifo_generator_v12_0_axic_reg_slice
          #(
            .C_FAMILY                (C_FAMILY),
            .C_DATA_WIDTH            (C_DIN_WIDTH_WACH),
            .C_REG_CONFIG            (C_REG_SLICE_MODE_WACH)
            )
    wach_reg_slice_inst
        (
          // System Signals
          .ACLK                      (S_ACLK),
          .ARESET                    (axi_rs_rst),

          // Slave side
          .S_PAYLOAD_DATA            (wach_din),
          .S_VALID                   (S_AXI_AWVALID),
          .S_READY                   (S_AXI_AWREADY),

          // Master side
          .M_PAYLOAD_DATA            (wach_dout),
          .M_VALID                   (M_AXI_AWVALID),
          .M_READY                   (M_AXI_AWREADY)
          );
  end endgenerate // gwach_reg_slice
  
  generate if (C_APPLICATION_TYPE_WACH == 1 && C_HAS_AXI_WR_CHANNEL == 1) begin : axi_mm_pkt_fifo_wr

    fifo_generator_v12_0_axic_reg_slice
          #(
            .C_FAMILY                (C_FAMILY),
            .C_DATA_WIDTH            (C_DIN_WIDTH_WACH),
            .C_REG_CONFIG            (1)
            )
    wach_pkt_reg_slice_inst
        (
          // System Signals
          .ACLK                      (S_ACLK),
          .ARESET                    (inverted_reset),

          // Slave side
          .S_PAYLOAD_DATA            (wach_dout_pkt),
          .S_VALID                   (awvalid_pkt),
          .S_READY                   (awready_pkt),

          // Master side
          .M_PAYLOAD_DATA            (wach_dout),
          .M_VALID                   (M_AXI_AWVALID),
          .M_READY                   (M_AXI_AWREADY)
          );

    assign awvalid_pkt = wach_m_axi_awvalid && awvalid_en;

    assign txn_count_up = wdch_s_axi_wready && wdch_wr_en && wdch_din[0]; 
    assign txn_count_down = wach_m_axi_awvalid && awready_pkt && awvalid_en;

    always@(posedge S_ACLK or posedge inverted_reset) begin
      if(inverted_reset == 1) begin
	wr_pkt_count <= 0;
      end else begin
	if(txn_count_up == 1 && txn_count_down == 0) begin
	  wr_pkt_count <= wr_pkt_count + 1;
	end else if(txn_count_up == 0 && txn_count_down == 1) begin
	  wr_pkt_count <= wr_pkt_count - 1;
	end
      end
    end //Always end
    assign awvalid_en = (wr_pkt_count > 0)?1:0;
  end endgenerate
  
  generate if (C_APPLICATION_TYPE_WACH != 1) begin : axi_mm_fifo_wr
    assign awvalid_en    = 1;    
    assign wach_dout     = wach_dout_pkt;
    assign M_AXI_AWVALID = wach_m_axi_awvalid;
  end
  endgenerate



  generate if (IS_WR_DATA_CH == 1) begin : axi_write_data_channel
    // Write protection when almost full or prog_full is high
    assign wdch_we    = (C_PROG_FULL_TYPE_WDCH != 0) ? wdch_s_axi_wready & S_AXI_WVALID : S_AXI_WVALID;

    // Read protection when almost empty or prog_empty is high
    assign wdch_re    = (C_PROG_EMPTY_TYPE_WDCH != 0) ? wdch_m_axi_wvalid & M_AXI_WREADY : M_AXI_WREADY;
    assign wdch_wr_en = (C_HAS_SLAVE_CE == 1)  ? wdch_we & S_ACLK_EN : wdch_we;
    assign wdch_rd_en = (C_HAS_MASTER_CE == 1) ? wdch_re & M_ACLK_EN : wdch_re;


    FIFO_GENERATOR_v12_0_CONV_VER
      #(
        .C_FAMILY			(C_FAMILY),
        .C_COMMON_CLOCK                 (C_COMMON_CLOCK),
        .C_MEMORY_TYPE			((C_IMPLEMENTATION_TYPE_WDCH == 1  || C_IMPLEMENTATION_TYPE_WDCH == 11) ? 1 :
                                         (C_IMPLEMENTATION_TYPE_WDCH == 2  || C_IMPLEMENTATION_TYPE_WDCH == 12) ? 2 : 4),
        .C_IMPLEMENTATION_TYPE		((C_IMPLEMENTATION_TYPE_WDCH == 1  || C_IMPLEMENTATION_TYPE_WDCH == 2) ? 0 :
                                         (C_IMPLEMENTATION_TYPE_WDCH == 11 || C_IMPLEMENTATION_TYPE_WDCH == 12) ? 2 : 6),
        .C_PRELOAD_REGS			(1), // always FWFT for AXI
        .C_PRELOAD_LATENCY		(0), // always FWFT for AXI
        .C_DIN_WIDTH			(C_DIN_WIDTH_WDCH),
        .C_WR_DEPTH			(C_WR_DEPTH_WDCH),
        .C_WR_PNTR_WIDTH		(C_WR_PNTR_WIDTH_WDCH),
        .C_DOUT_WIDTH			(C_DIN_WIDTH_WDCH),
        .C_RD_DEPTH			(C_WR_DEPTH_WDCH),
        .C_RD_PNTR_WIDTH		(C_WR_PNTR_WIDTH_WDCH),
        .C_PROG_FULL_TYPE		(C_PROG_FULL_TYPE_WDCH),
        .C_PROG_FULL_THRESH_ASSERT_VAL	(C_PROG_FULL_THRESH_ASSERT_VAL_WDCH),
        .C_PROG_EMPTY_TYPE		(C_PROG_EMPTY_TYPE_WDCH),
        .C_PROG_EMPTY_THRESH_ASSERT_VAL	(C_PROG_EMPTY_THRESH_ASSERT_VAL_WDCH),
        .C_USE_ECC                      (C_USE_ECC_WDCH),
        .C_ERROR_INJECTION_TYPE         (C_ERROR_INJECTION_TYPE_WDCH),
        .C_HAS_ALMOST_EMPTY		(0),
        .C_HAS_ALMOST_FULL		(0),
        .C_AXI_TYPE                     (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE),

        .C_FIFO_TYPE                    (C_APPLICATION_TYPE_WDCH),
        .C_SYNCHRONIZER_STAGE           (C_SYNCHRONIZER_STAGE),

        .C_HAS_WR_RST			(0),
        .C_HAS_RD_RST			(0),
        .C_HAS_RST			(1),
        .C_HAS_SRST			(0),
        .C_DOUT_RST_VAL			(0),

        .C_HAS_VALID			(0),
        .C_VALID_LOW			(C_VALID_LOW),
        .C_HAS_UNDERFLOW		(C_HAS_UNDERFLOW),
        .C_UNDERFLOW_LOW		(C_UNDERFLOW_LOW),
        .C_HAS_WR_ACK			(0),
        .C_WR_ACK_LOW			(C_WR_ACK_LOW),
        .C_HAS_OVERFLOW			(C_HAS_OVERFLOW),
        .C_OVERFLOW_LOW			(C_OVERFLOW_LOW),

        .C_HAS_DATA_COUNT		((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_WDCH == 1) ? 1 : 0),
        .C_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_WDCH + 1),
        .C_HAS_RD_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WDCH == 1) ? 1 : 0),
        .C_RD_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_WDCH + 1),
        .C_USE_FWFT_DATA_COUNT		(1), // use extra logic is always true
        .C_HAS_WR_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WDCH == 1) ? 1 : 0),
        .C_WR_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_WDCH + 1),
        .C_FULL_FLAGS_RST_VAL           (1),
        .C_USE_EMBEDDED_REG		(0),
        .C_USE_DOUT_RST                 (0),
        .C_MSGON_VAL                    (C_MSGON_VAL),
        .C_ENABLE_RST_SYNC              (1),

        .C_COUNT_TYPE			(C_COUNT_TYPE),
        .C_DEFAULT_VALUE		(C_DEFAULT_VALUE),
        .C_ENABLE_RLOCS			(C_ENABLE_RLOCS),
        .C_HAS_BACKUP			(C_HAS_BACKUP),
        .C_HAS_INT_CLK                  (C_HAS_INT_CLK),
        .C_MIF_FILE_NAME		(C_MIF_FILE_NAME),
        .C_HAS_MEMINIT_FILE		(C_HAS_MEMINIT_FILE),
        .C_INIT_WR_PNTR_VAL		(C_INIT_WR_PNTR_VAL),
        .C_OPTIMIZATION_MODE		(C_OPTIMIZATION_MODE),
        .C_PRIM_FIFO_TYPE		(C_PRIM_FIFO_TYPE),
        .C_RD_FREQ			(C_RD_FREQ),
        .C_USE_FIFO16_FLAGS		(C_USE_FIFO16_FLAGS),
        .C_WR_FREQ			(C_WR_FREQ),
        .C_WR_RESPONSE_LATENCY		(C_WR_RESPONSE_LATENCY)
      )
    fifo_generator_v12_0_wdch_dut
      (
        .CLK                      (S_ACLK),
        .WR_CLK                   (S_ACLK),
        .RD_CLK                   (M_ACLK),
        .RST                      (inverted_reset),
        .SRST                     (1'b0),
        .WR_RST                   (inverted_reset),
        .RD_RST                   (inverted_reset),
        .WR_EN                    (wdch_wr_en),
        .RD_EN                    (wdch_rd_en),
        .PROG_FULL_THRESH         (AXI_W_PROG_FULL_THRESH),
        .PROG_FULL_THRESH_ASSERT  ({C_WR_PNTR_WIDTH_WDCH{1'b0}}),
        .PROG_FULL_THRESH_NEGATE  ({C_WR_PNTR_WIDTH_WDCH{1'b0}}),
        .PROG_EMPTY_THRESH        (AXI_W_PROG_EMPTY_THRESH),
        .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_WDCH{1'b0}}),
        .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_WDCH{1'b0}}),
        .INJECTDBITERR            (AXI_W_INJECTDBITERR), 
        .INJECTSBITERR            (AXI_W_INJECTSBITERR),
  
        .DIN                      (wdch_din),
        .DOUT                     (wdch_dout),
        .FULL                     (wdch_full),
        .EMPTY                    (wdch_empty),
        .ALMOST_FULL              (),
        .PROG_FULL                (AXI_W_PROG_FULL),
        .ALMOST_EMPTY             (),
        .PROG_EMPTY               (AXI_W_PROG_EMPTY),
  
        .WR_ACK                   (),
        .OVERFLOW                 (axi_w_overflow_i),
        .VALID                    (),
        .UNDERFLOW                (axi_w_underflow_i),
        .DATA_COUNT               (AXI_W_DATA_COUNT),
        .RD_DATA_COUNT            (AXI_W_RD_DATA_COUNT),
        .WR_DATA_COUNT            (AXI_W_WR_DATA_COUNT),
        .SBITERR                  (AXI_W_SBITERR),
        .DBITERR                  (AXI_W_DBITERR),
        .wr_rst_busy              (wr_rst_busy_wdch),
        .rd_rst_busy              (rd_rst_busy_wdch),
        .wr_rst_i_out             (),
        .rd_rst_i_out             (),
  
        .BACKUP                   (BACKUP),
        .BACKUP_MARKER            (BACKUP_MARKER),
        .INT_CLK                  (INT_CLK)
       );

    assign wdch_s_axi_wready     = (IS_8SERIES == 0) ? ~wdch_full : (C_IMPLEMENTATION_TYPE_WDCH == 5 || C_IMPLEMENTATION_TYPE_WDCH == 13) ? ~(wdch_full | wr_rst_busy_wdch) : ~wdch_full;
    assign wdch_m_axi_wvalid = ~wdch_empty;
    assign S_AXI_WREADY      = wdch_s_axi_wready;
    assign M_AXI_WVALID      = wdch_m_axi_wvalid;

    assign AXI_W_UNDERFLOW   = C_USE_COMMON_UNDERFLOW == 0 ? axi_w_underflow_i  : 0;
    assign AXI_W_OVERFLOW    = C_USE_COMMON_OVERFLOW  == 0 ? axi_w_overflow_i   : 0;

  end endgenerate // axi_write_data_channel

  // Register Slice for Write Data Channel
  generate if (C_WDCH_TYPE == 1) begin : gwdch_reg_slice

    fifo_generator_v12_0_axic_reg_slice
          #(
            .C_FAMILY                (C_FAMILY),
            .C_DATA_WIDTH            (C_DIN_WIDTH_WDCH),
            .C_REG_CONFIG            (C_REG_SLICE_MODE_WDCH)
            )
    wdch_reg_slice_inst
        (
          // System Signals
          .ACLK                      (S_ACLK),
          .ARESET                    (axi_rs_rst),

          // Slave side
          .S_PAYLOAD_DATA            (wdch_din),
          .S_VALID                   (S_AXI_WVALID),
          .S_READY                   (S_AXI_WREADY),

          // Master side
          .M_PAYLOAD_DATA            (wdch_dout),
          .M_VALID                   (M_AXI_WVALID),
          .M_READY                   (M_AXI_WREADY)
          );
  end endgenerate // gwdch_reg_slice

  generate if (IS_WR_RESP_CH == 1) begin : axi_write_resp_channel
    // Write protection when almost full or prog_full is high
    assign wrch_we    = (C_PROG_FULL_TYPE_WRCH != 0) ? wrch_m_axi_bready & M_AXI_BVALID : M_AXI_BVALID;

    // Read protection when almost empty or prog_empty is high
    assign wrch_re    = (C_PROG_EMPTY_TYPE_WRCH != 0) ? wrch_s_axi_bvalid & S_AXI_BREADY : S_AXI_BREADY;
    assign wrch_wr_en = (C_HAS_SLAVE_CE == 1)  ? wrch_we & S_ACLK_EN : wrch_we;
    assign wrch_rd_en = (C_HAS_MASTER_CE == 1) ? wrch_re & M_ACLK_EN : wrch_re;

    FIFO_GENERATOR_v12_0_CONV_VER
      #(
        .C_FAMILY			(C_FAMILY),
        .C_COMMON_CLOCK                 (C_COMMON_CLOCK),
        .C_MEMORY_TYPE			((C_IMPLEMENTATION_TYPE_WRCH == 1  || C_IMPLEMENTATION_TYPE_WRCH == 11) ? 1 :
                                         (C_IMPLEMENTATION_TYPE_WRCH == 2  || C_IMPLEMENTATION_TYPE_WRCH == 12) ? 2 : 4),
        .C_IMPLEMENTATION_TYPE		((C_IMPLEMENTATION_TYPE_WRCH == 1  || C_IMPLEMENTATION_TYPE_WRCH == 2) ? 0 :
                                         (C_IMPLEMENTATION_TYPE_WRCH == 11 || C_IMPLEMENTATION_TYPE_WRCH == 12) ? 2 : 6),
        .C_PRELOAD_REGS			(1), // always FWFT for AXI
        .C_PRELOAD_LATENCY		(0), // always FWFT for AXI
        .C_DIN_WIDTH			(C_DIN_WIDTH_WRCH),
        .C_WR_DEPTH			(C_WR_DEPTH_WRCH),
        .C_WR_PNTR_WIDTH		(C_WR_PNTR_WIDTH_WRCH),
        .C_DOUT_WIDTH			(C_DIN_WIDTH_WRCH),
        .C_RD_DEPTH			(C_WR_DEPTH_WRCH),
        .C_RD_PNTR_WIDTH		(C_WR_PNTR_WIDTH_WRCH),
        .C_PROG_FULL_TYPE		(C_PROG_FULL_TYPE_WRCH),
        .C_PROG_FULL_THRESH_ASSERT_VAL	(C_PROG_FULL_THRESH_ASSERT_VAL_WRCH),
        .C_PROG_EMPTY_TYPE		(C_PROG_EMPTY_TYPE_WRCH),
        .C_PROG_EMPTY_THRESH_ASSERT_VAL	(C_PROG_EMPTY_THRESH_ASSERT_VAL_WRCH),
        .C_USE_ECC                      (C_USE_ECC_WRCH),
        .C_ERROR_INJECTION_TYPE         (C_ERROR_INJECTION_TYPE_WRCH),
        .C_HAS_ALMOST_EMPTY		(0),
        .C_HAS_ALMOST_FULL		(0),
        .C_AXI_TYPE                     (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE),

        .C_FIFO_TYPE                    (C_APPLICATION_TYPE_WRCH),
        .C_SYNCHRONIZER_STAGE           (C_SYNCHRONIZER_STAGE),

        .C_HAS_WR_RST			(0),
        .C_HAS_RD_RST			(0),
        .C_HAS_RST			(1),
        .C_HAS_SRST			(0),
        .C_DOUT_RST_VAL			(0),

        .C_HAS_VALID			(0),
        .C_VALID_LOW			(C_VALID_LOW),
        .C_HAS_UNDERFLOW		(C_HAS_UNDERFLOW),
        .C_UNDERFLOW_LOW		(C_UNDERFLOW_LOW),
        .C_HAS_WR_ACK			(0),
        .C_WR_ACK_LOW			(C_WR_ACK_LOW),
        .C_HAS_OVERFLOW			(C_HAS_OVERFLOW),
        .C_OVERFLOW_LOW			(C_OVERFLOW_LOW),

        .C_HAS_DATA_COUNT		((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_WRCH == 1) ? 1 : 0),
        .C_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_WRCH + 1),
        .C_HAS_RD_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WRCH == 1) ? 1 : 0),
        .C_RD_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_WRCH + 1),
        .C_USE_FWFT_DATA_COUNT		(1), // use extra logic is always true
        .C_HAS_WR_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WRCH == 1) ? 1 : 0),
        .C_WR_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_WRCH + 1),
        .C_FULL_FLAGS_RST_VAL           (1),
        .C_USE_EMBEDDED_REG		(0),
        .C_USE_DOUT_RST                 (0),
        .C_MSGON_VAL                    (C_MSGON_VAL),
        .C_ENABLE_RST_SYNC              (1),

        .C_COUNT_TYPE			(C_COUNT_TYPE),
        .C_DEFAULT_VALUE		(C_DEFAULT_VALUE),
        .C_ENABLE_RLOCS			(C_ENABLE_RLOCS),
        .C_HAS_BACKUP			(C_HAS_BACKUP),
        .C_HAS_INT_CLK                  (C_HAS_INT_CLK),
        .C_MIF_FILE_NAME		(C_MIF_FILE_NAME),
        .C_HAS_MEMINIT_FILE		(C_HAS_MEMINIT_FILE),
        .C_INIT_WR_PNTR_VAL		(C_INIT_WR_PNTR_VAL),
        .C_OPTIMIZATION_MODE		(C_OPTIMIZATION_MODE),
        .C_PRIM_FIFO_TYPE		(C_PRIM_FIFO_TYPE),
        .C_RD_FREQ			(C_RD_FREQ),
        .C_USE_FIFO16_FLAGS		(C_USE_FIFO16_FLAGS),
        .C_WR_FREQ			(C_WR_FREQ),
        .C_WR_RESPONSE_LATENCY		(C_WR_RESPONSE_LATENCY)
      )
    fifo_generator_v12_0_wrch_dut
      (
        .CLK                      (S_ACLK),
        .WR_CLK                   (M_ACLK),
        .RD_CLK                   (S_ACLK),
        .RST                      (inverted_reset),
        .SRST                     (1'b0),
        .WR_RST                   (inverted_reset),
        .RD_RST                   (inverted_reset),
        .WR_EN                    (wrch_wr_en),
        .RD_EN                    (wrch_rd_en),
        .PROG_FULL_THRESH         (AXI_B_PROG_FULL_THRESH),
        .PROG_FULL_THRESH_ASSERT  ({C_WR_PNTR_WIDTH_WRCH{1'b0}}),
        .PROG_FULL_THRESH_NEGATE  ({C_WR_PNTR_WIDTH_WRCH{1'b0}}),
        .PROG_EMPTY_THRESH        (AXI_B_PROG_EMPTY_THRESH),
        .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_WRCH{1'b0}}),
        .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_WRCH{1'b0}}),
        .INJECTDBITERR            (AXI_B_INJECTDBITERR), 
        .INJECTSBITERR            (AXI_B_INJECTSBITERR),
  
        .DIN                      (wrch_din),
        .DOUT                     (wrch_dout),
        .FULL                     (wrch_full),
        .EMPTY                    (wrch_empty),
        .ALMOST_FULL              (),
        .ALMOST_EMPTY             (),
        .PROG_FULL                (AXI_B_PROG_FULL),
        .PROG_EMPTY               (AXI_B_PROG_EMPTY),
  
        .WR_ACK                   (),
        .OVERFLOW                 (axi_b_overflow_i),
        .VALID                    (),
        .UNDERFLOW                (axi_b_underflow_i),
        .DATA_COUNT               (AXI_B_DATA_COUNT),
        .RD_DATA_COUNT            (AXI_B_RD_DATA_COUNT),
        .WR_DATA_COUNT            (AXI_B_WR_DATA_COUNT),
        .SBITERR                  (AXI_B_SBITERR),
        .DBITERR                  (AXI_B_DBITERR),
        .wr_rst_busy              (wr_rst_busy_wrch),
        .rd_rst_busy              (rd_rst_busy_wrch),
        .wr_rst_i_out             (),
        .rd_rst_i_out             (),
  
        .BACKUP                   (BACKUP),
        .BACKUP_MARKER            (BACKUP_MARKER),
        .INT_CLK                  (INT_CLK)
       );

    assign wrch_s_axi_bvalid = ~wrch_empty;
    assign wrch_m_axi_bready     = (IS_8SERIES == 0) ? ~wrch_full : (C_IMPLEMENTATION_TYPE_WRCH == 5 || C_IMPLEMENTATION_TYPE_WRCH == 13) ? ~(wrch_full | wr_rst_busy_wrch) : ~wrch_full;
    assign S_AXI_BVALID      = wrch_s_axi_bvalid;
    assign M_AXI_BREADY      = wrch_m_axi_bready;

    assign AXI_B_UNDERFLOW   = C_USE_COMMON_UNDERFLOW == 0 ? axi_b_underflow_i  : 0;
    assign AXI_B_OVERFLOW    = C_USE_COMMON_OVERFLOW  == 0 ? axi_b_overflow_i   : 0;
  end endgenerate // axi_write_resp_channel

  // Register Slice for Write Response Channel
  generate if (C_WRCH_TYPE == 1) begin : gwrch_reg_slice

    fifo_generator_v12_0_axic_reg_slice
          #(
            .C_FAMILY                (C_FAMILY),
            .C_DATA_WIDTH            (C_DIN_WIDTH_WRCH),
            .C_REG_CONFIG            (C_REG_SLICE_MODE_WRCH)
            )
    wrch_reg_slice_inst
        (
          // System Signals
          .ACLK                      (S_ACLK),
          .ARESET                    (axi_rs_rst),

          // Slave side
          .S_PAYLOAD_DATA            (wrch_din),
          .S_VALID                   (M_AXI_BVALID),
          .S_READY                   (M_AXI_BREADY),

          // Master side
          .M_PAYLOAD_DATA            (wrch_dout),
          .M_VALID                   (S_AXI_BVALID),
          .M_READY                   (S_AXI_BREADY)
          );
  end endgenerate // gwrch_reg_slice


    assign axi_wr_underflow_i = C_USE_COMMON_UNDERFLOW  == 1 ? (axi_aw_underflow_i || axi_w_underflow_i || axi_b_underflow_i) : 0;
    assign axi_wr_overflow_i  = C_USE_COMMON_OVERFLOW   == 1 ? (axi_aw_overflow_i  || axi_w_overflow_i  || axi_b_overflow_i)  : 0;

  generate if (IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) begin : axi_wach_output
    assign M_AXI_AWADDR    = wach_dout[AWID_OFFSET-1:AWADDR_OFFSET];    
    assign M_AXI_AWLEN     = wach_dout[AWADDR_OFFSET-1:AWLEN_OFFSET];    
    assign M_AXI_AWSIZE    = wach_dout[AWLEN_OFFSET-1:AWSIZE_OFFSET];    
    assign M_AXI_AWBURST   = wach_dout[AWSIZE_OFFSET-1:AWBURST_OFFSET];    
    assign M_AXI_AWLOCK    = wach_dout[AWBURST_OFFSET-1:AWLOCK_OFFSET];    
    assign M_AXI_AWCACHE   = wach_dout[AWLOCK_OFFSET-1:AWCACHE_OFFSET];    
    assign M_AXI_AWPROT    = wach_dout[AWCACHE_OFFSET-1:AWPROT_OFFSET];    
    assign M_AXI_AWQOS     = wach_dout[AWPROT_OFFSET-1:AWQOS_OFFSET];    
    assign wach_din[AWID_OFFSET-1:AWADDR_OFFSET]    = S_AXI_AWADDR;
    assign wach_din[AWADDR_OFFSET-1:AWLEN_OFFSET]   = S_AXI_AWLEN;
    assign wach_din[AWLEN_OFFSET-1:AWSIZE_OFFSET]   = S_AXI_AWSIZE;
    assign wach_din[AWSIZE_OFFSET-1:AWBURST_OFFSET] = S_AXI_AWBURST;
    assign wach_din[AWBURST_OFFSET-1:AWLOCK_OFFSET] = S_AXI_AWLOCK;
    assign wach_din[AWLOCK_OFFSET-1:AWCACHE_OFFSET] = S_AXI_AWCACHE;
    assign wach_din[AWCACHE_OFFSET-1:AWPROT_OFFSET] = S_AXI_AWPROT;
    assign wach_din[AWPROT_OFFSET-1:AWQOS_OFFSET]   = S_AXI_AWQOS;
  end endgenerate // axi_wach_output

  generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_AXI_TYPE == 1) begin : axi_awregion
    assign M_AXI_AWREGION  = wach_dout[AWQOS_OFFSET-1:AWREGION_OFFSET];    
  end endgenerate // axi_awregion

  generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_AXI_TYPE != 1) begin : naxi_awregion
    assign M_AXI_AWREGION  = 0;    
  end endgenerate // naxi_awregion

  generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_AWUSER == 1) begin : axi_awuser
    assign M_AXI_AWUSER  = wach_dout[AWREGION_OFFSET-1:AWUSER_OFFSET];    
  end endgenerate // axi_awuser

  generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_AWUSER == 0) begin : naxi_awuser
    assign M_AXI_AWUSER  = 0;    
  end endgenerate // naxi_awuser


  generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : axi_awid
    assign M_AXI_AWID      = wach_dout[C_DIN_WIDTH_WACH-1:AWID_OFFSET];
  end endgenerate //axi_awid

  generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_ID == 0) begin : naxi_awid
    assign M_AXI_AWID      = 0;
  end endgenerate //naxi_awid

  generate if (IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) begin : axi_wdch_output
    assign M_AXI_WDATA     = wdch_dout[WID_OFFSET-1:WDATA_OFFSET];
    assign M_AXI_WSTRB     = wdch_dout[WDATA_OFFSET-1:WSTRB_OFFSET];
    assign M_AXI_WLAST     = wdch_dout[0];
    assign wdch_din[WID_OFFSET-1:WDATA_OFFSET]   = S_AXI_WDATA;
    assign wdch_din[WDATA_OFFSET-1:WSTRB_OFFSET] = S_AXI_WSTRB;
    assign wdch_din[0]   = S_AXI_WLAST;
  end endgenerate // axi_wdch_output

  generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && C_HAS_AXI_ID == 1 && C_AXI_TYPE == 3) begin
    assign M_AXI_WID       = wdch_dout[C_DIN_WIDTH_WDCH-1:WID_OFFSET];
  end endgenerate
  generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && (C_HAS_AXI_ID == 0 || C_AXI_TYPE != 3)) begin
    assign M_AXI_WID       = 0;
  end endgenerate

  generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && C_HAS_AXI_WUSER == 1 ) begin
    assign M_AXI_WUSER     = wdch_dout[WSTRB_OFFSET-1:WUSER_OFFSET];    
  end endgenerate
  generate if (C_HAS_AXI_WUSER == 0) begin
    assign M_AXI_WUSER       = 0;
  end endgenerate

  generate if (IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) begin : axi_wrch_output
    assign S_AXI_BRESP = wrch_dout[BID_OFFSET-1:BRESP_OFFSET]; 
    assign wrch_din[BID_OFFSET-1:BRESP_OFFSET]   = M_AXI_BRESP;
  end endgenerate // axi_wrch_output

  generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_BUSER == 1) begin : axi_buser
    assign S_AXI_BUSER = wrch_dout[BRESP_OFFSET-1:BUSER_OFFSET];
  end endgenerate // axi_buser

  generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_BUSER == 0) begin : naxi_buser
    assign S_AXI_BUSER = 0;
  end endgenerate // naxi_buser

  generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : axi_bid
    assign S_AXI_BID   =  wrch_dout[C_DIN_WIDTH_WRCH-1:BID_OFFSET];
  end endgenerate // axi_bid
  
  generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_ID == 0) begin : naxi_bid
    assign S_AXI_BID   =  0 ;
  end endgenerate // naxi_bid  


  generate if (IS_AXI_LITE_WACH == 1 || (IS_AXI_LITE == 1 && C_WACH_TYPE == 1)) begin : axi_wach_output1
    assign wach_din        = {S_AXI_AWADDR, S_AXI_AWPROT};
    assign M_AXI_AWADDR    = wach_dout[C_DIN_WIDTH_WACH-1:AWADDR_OFFSET];    
    assign M_AXI_AWPROT    = wach_dout[AWADDR_OFFSET-1:AWPROT_OFFSET];    
  end endgenerate // axi_wach_output1

  generate if (IS_AXI_LITE_WDCH == 1 || (IS_AXI_LITE == 1 && C_WDCH_TYPE == 1)) begin : axi_wdch_output1
    assign wdch_din        = {S_AXI_WDATA, S_AXI_WSTRB};
    assign M_AXI_WDATA     = wdch_dout[C_DIN_WIDTH_WDCH-1:WDATA_OFFSET];
    assign M_AXI_WSTRB     = wdch_dout[WDATA_OFFSET-1:WSTRB_OFFSET];
  end endgenerate // axi_wdch_output1

  generate if (IS_AXI_LITE_WRCH == 1 || (IS_AXI_LITE == 1 && C_WRCH_TYPE == 1)) begin : axi_wrch_output1
    assign wrch_din        = M_AXI_BRESP;
    assign S_AXI_BRESP     = wrch_dout[C_DIN_WIDTH_WRCH-1:BRESP_OFFSET]; 
  end endgenerate // axi_wrch_output1

  generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_AWUSER == 1) begin : gwach_din1
    assign wach_din[AWREGION_OFFSET-1:AWUSER_OFFSET]     = S_AXI_AWUSER;
  end endgenerate // gwach_din1

  generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : gwach_din2
    assign wach_din[C_DIN_WIDTH_WACH-1:AWID_OFFSET]     = S_AXI_AWID;
  end endgenerate // gwach_din2

  generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_AXI_TYPE == 1) begin : gwach_din3
    assign wach_din[AWQOS_OFFSET-1:AWREGION_OFFSET]     = S_AXI_AWREGION;
  end endgenerate // gwach_din3

  generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && C_HAS_AXI_WUSER == 1) begin : gwdch_din1
    assign wdch_din[WSTRB_OFFSET-1:WUSER_OFFSET] = S_AXI_WUSER;
  end endgenerate // gwdch_din1

  generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && C_HAS_AXI_ID == 1 && C_AXI_TYPE == 3) begin : gwdch_din2
    assign wdch_din[C_DIN_WIDTH_WDCH-1:WID_OFFSET] = S_AXI_WID;
  end endgenerate // gwdch_din2

  generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_BUSER == 1) begin : gwrch_din1
    assign wrch_din[BRESP_OFFSET-1:BUSER_OFFSET]    = M_AXI_BUSER;
  end endgenerate // gwrch_din1

  generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : gwrch_din2
    assign wrch_din[C_DIN_WIDTH_WRCH-1:BID_OFFSET]    = M_AXI_BID;
  end endgenerate // gwrch_din2

  //end of  axi_write_channel

  //###########################################################################
  //  AXI FULL Read Channel (axi_read_channel)
  //###########################################################################
  wire [C_DIN_WIDTH_RACH-1:0]        rach_din            ;
  wire [C_DIN_WIDTH_RACH-1:0]        rach_dout           ;
  wire [C_DIN_WIDTH_RACH-1:0]        rach_dout_pkt       ;
  wire                               rach_full           ;
  wire                               rach_almost_full    ;
  wire                               rach_prog_full      ;
  wire                               rach_empty          ;
  wire                               rach_almost_empty   ;
  wire                               rach_prog_empty     ;
  wire [C_DIN_WIDTH_RDCH-1:0]        rdch_din            ;
  wire [C_DIN_WIDTH_RDCH-1:0]        rdch_dout           ;
  wire                               rdch_full           ;
  wire                               rdch_almost_full    ;
  wire                               rdch_prog_full      ;
  wire                               rdch_empty          ;
  wire                               rdch_almost_empty   ;
  wire                               rdch_prog_empty     ;
  wire                               axi_ar_underflow_i  ;
  wire                               axi_r_underflow_i   ;
  wire                               axi_ar_overflow_i   ;
  wire                               axi_r_overflow_i    ;
  wire                               axi_rd_underflow_i  ;
  wire                               axi_rd_overflow_i   ;
  wire                               rach_s_axi_arready  ;
  wire                               rach_m_axi_arvalid  ;
  wire                               rach_wr_en          ;
  wire                               rach_rd_en          ;
  wire                               rdch_m_axi_rready   ;
  wire                               rdch_s_axi_rvalid   ;
  wire                               rdch_wr_en          ;
  wire                               rdch_rd_en          ;
  wire                               arvalid_pkt         ;
  wire                               arready_pkt         ;
  wire                               arvalid_en          ;
  wire                               rdch_rd_ok          ;
  wire                               accept_next_pkt     ;
  integer                            rdch_free_space     ;
  integer                            rdch_commited_space ;
  wire                               rach_we             ;
  wire                               rach_re             ;
  wire                               rdch_we             ;
  wire                               rdch_re             ;

  localparam ARID_OFFSET       = (C_AXI_TYPE != 2 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_RACH - C_AXI_ID_WIDTH : C_DIN_WIDTH_RACH;
  localparam ARADDR_OFFSET     = ARID_OFFSET - C_AXI_ADDR_WIDTH;
  localparam ARLEN_OFFSET      = C_AXI_TYPE != 2 ? ARADDR_OFFSET - C_AXI_LEN_WIDTH : ARADDR_OFFSET;
  localparam ARSIZE_OFFSET     = C_AXI_TYPE != 2 ? ARLEN_OFFSET - C_AXI_SIZE_WIDTH : ARLEN_OFFSET;
  localparam ARBURST_OFFSET    = C_AXI_TYPE != 2 ? ARSIZE_OFFSET - C_AXI_BURST_WIDTH : ARSIZE_OFFSET;
  localparam ARLOCK_OFFSET     = C_AXI_TYPE != 2 ? ARBURST_OFFSET - C_AXI_LOCK_WIDTH : ARBURST_OFFSET;
  localparam ARCACHE_OFFSET    = C_AXI_TYPE != 2 ? ARLOCK_OFFSET - C_AXI_CACHE_WIDTH : ARLOCK_OFFSET;
  localparam ARPROT_OFFSET     = ARCACHE_OFFSET - C_AXI_PROT_WIDTH;
  localparam ARQOS_OFFSET      = ARPROT_OFFSET - C_AXI_QOS_WIDTH;
  localparam ARREGION_OFFSET   = C_AXI_TYPE == 1 ? ARQOS_OFFSET - C_AXI_REGION_WIDTH : ARQOS_OFFSET;
  localparam ARUSER_OFFSET     = C_HAS_AXI_ARUSER == 1 ? ARREGION_OFFSET-C_AXI_ARUSER_WIDTH : ARREGION_OFFSET;

  localparam RID_OFFSET        = (C_AXI_TYPE != 2 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_RDCH - C_AXI_ID_WIDTH : C_DIN_WIDTH_RDCH;
  localparam RDATA_OFFSET      = RID_OFFSET - C_AXI_DATA_WIDTH;
  localparam RRESP_OFFSET      = RDATA_OFFSET - C_AXI_RRESP_WIDTH;
  localparam RUSER_OFFSET      = C_HAS_AXI_RUSER == 1 ? RRESP_OFFSET-C_AXI_RUSER_WIDTH : RRESP_OFFSET;


  generate if (IS_RD_ADDR_CH == 1) begin : axi_read_addr_channel

    // Write protection when almost full or prog_full is high
    assign rach_we    = (C_PROG_FULL_TYPE_RACH != 0) ? rach_s_axi_arready & S_AXI_ARVALID : S_AXI_ARVALID;

    // Read protection when almost empty or prog_empty is high
//    assign rach_rd_en = (C_PROG_EMPTY_TYPE_RACH != 5) ? rach_m_axi_arvalid & M_AXI_ARREADY : M_AXI_ARREADY && arvalid_en;
    assign rach_re    = (C_PROG_EMPTY_TYPE_RACH != 0 && C_APPLICATION_TYPE_RACH == 1) ? 
                        rach_m_axi_arvalid & arready_pkt & arvalid_en : 
                        (C_PROG_EMPTY_TYPE_RACH != 0 && C_APPLICATION_TYPE_RACH != 1) ? 
                        M_AXI_ARREADY && rach_m_axi_arvalid :
                        (C_PROG_EMPTY_TYPE_RACH == 0 && C_APPLICATION_TYPE_RACH == 1) ? 
                        arready_pkt & arvalid_en : 
                        (C_PROG_EMPTY_TYPE_RACH == 0 && C_APPLICATION_TYPE_RACH != 1) ? 
                        M_AXI_ARREADY : 1'b0;
    assign rach_wr_en = (C_HAS_SLAVE_CE == 1)  ? rach_we & S_ACLK_EN : rach_we;
    assign rach_rd_en = (C_HAS_MASTER_CE == 1) ? rach_re & M_ACLK_EN : rach_re;


    FIFO_GENERATOR_v12_0_CONV_VER
      #(
        .C_FAMILY			(C_FAMILY),
        .C_COMMON_CLOCK                 (C_COMMON_CLOCK),
        .C_MEMORY_TYPE			((C_IMPLEMENTATION_TYPE_RACH == 1  || C_IMPLEMENTATION_TYPE_RACH == 11) ? 1 :
                                         (C_IMPLEMENTATION_TYPE_RACH == 2  || C_IMPLEMENTATION_TYPE_RACH == 12) ? 2 : 4),
        .C_IMPLEMENTATION_TYPE		((C_IMPLEMENTATION_TYPE_RACH == 1  || C_IMPLEMENTATION_TYPE_RACH == 2) ? 0 :
                                         (C_IMPLEMENTATION_TYPE_RACH == 11 || C_IMPLEMENTATION_TYPE_RACH == 12) ? 2 : 6),
        .C_PRELOAD_REGS			(1), // always FWFT for AXI
        .C_PRELOAD_LATENCY		(0), // always FWFT for AXI
        .C_DIN_WIDTH			(C_DIN_WIDTH_RACH),
        .C_WR_DEPTH			(C_WR_DEPTH_RACH),
        .C_WR_PNTR_WIDTH		(C_WR_PNTR_WIDTH_RACH),
        .C_DOUT_WIDTH			(C_DIN_WIDTH_RACH),
        .C_RD_DEPTH			(C_WR_DEPTH_RACH),
        .C_RD_PNTR_WIDTH		(C_WR_PNTR_WIDTH_RACH),
        .C_PROG_FULL_TYPE		(C_PROG_FULL_TYPE_RACH),
        .C_PROG_FULL_THRESH_ASSERT_VAL	(C_PROG_FULL_THRESH_ASSERT_VAL_RACH),
        .C_PROG_EMPTY_TYPE		(C_PROG_EMPTY_TYPE_RACH),
        .C_PROG_EMPTY_THRESH_ASSERT_VAL	(C_PROG_EMPTY_THRESH_ASSERT_VAL_RACH),
        .C_USE_ECC                      (C_USE_ECC_RACH),
        .C_ERROR_INJECTION_TYPE         (C_ERROR_INJECTION_TYPE_RACH),
        .C_HAS_ALMOST_EMPTY		(0),
        .C_HAS_ALMOST_FULL		(0),
        .C_AXI_TYPE                     (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE),

        .C_FIFO_TYPE                    ((C_APPLICATION_TYPE_RACH == 1)?0:C_APPLICATION_TYPE_RACH),
        .C_SYNCHRONIZER_STAGE           (C_SYNCHRONIZER_STAGE),

        .C_HAS_WR_RST			(0),
        .C_HAS_RD_RST			(0),
        .C_HAS_RST			(1),
        .C_HAS_SRST			(0),
        .C_DOUT_RST_VAL			(0),

        .C_HAS_VALID			(0),
        .C_VALID_LOW			(C_VALID_LOW),
        .C_HAS_UNDERFLOW		(C_HAS_UNDERFLOW),
        .C_UNDERFLOW_LOW		(C_UNDERFLOW_LOW),
        .C_HAS_WR_ACK			(0),
        .C_WR_ACK_LOW			(C_WR_ACK_LOW),
        .C_HAS_OVERFLOW			(C_HAS_OVERFLOW),
        .C_OVERFLOW_LOW			(C_OVERFLOW_LOW),

        .C_HAS_DATA_COUNT		((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_RACH == 1) ? 1 : 0),
        .C_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_RACH + 1),
        .C_HAS_RD_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_RACH == 1) ? 1 : 0),
        .C_RD_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_RACH + 1),
        .C_USE_FWFT_DATA_COUNT		(1), // use extra logic is always true
        .C_HAS_WR_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_RACH == 1) ? 1 : 0),
        .C_WR_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_RACH + 1),
        .C_FULL_FLAGS_RST_VAL           (1),
        .C_USE_EMBEDDED_REG		(0),
        .C_USE_DOUT_RST                 (0),
        .C_MSGON_VAL                    (C_MSGON_VAL),
        .C_ENABLE_RST_SYNC              (1),

        .C_COUNT_TYPE			(C_COUNT_TYPE),
        .C_DEFAULT_VALUE		(C_DEFAULT_VALUE),
        .C_ENABLE_RLOCS			(C_ENABLE_RLOCS),
        .C_HAS_BACKUP			(C_HAS_BACKUP),
        .C_HAS_INT_CLK                  (C_HAS_INT_CLK),
        .C_MIF_FILE_NAME		(C_MIF_FILE_NAME),
        .C_HAS_MEMINIT_FILE		(C_HAS_MEMINIT_FILE),
        .C_INIT_WR_PNTR_VAL		(C_INIT_WR_PNTR_VAL),
        .C_OPTIMIZATION_MODE		(C_OPTIMIZATION_MODE),
        .C_PRIM_FIFO_TYPE		(C_PRIM_FIFO_TYPE),
        .C_RD_FREQ			(C_RD_FREQ),
        .C_USE_FIFO16_FLAGS		(C_USE_FIFO16_FLAGS),
        .C_WR_FREQ			(C_WR_FREQ),
        .C_WR_RESPONSE_LATENCY		(C_WR_RESPONSE_LATENCY)
      )
    fifo_generator_v12_0_rach_dut
      (
        .CLK                      (S_ACLK),
        .WR_CLK                   (S_ACLK),
        .RD_CLK                   (M_ACLK),
        .RST                      (inverted_reset),
        .SRST                     (1'b0),
        .WR_RST                   (inverted_reset),
        .RD_RST                   (inverted_reset),
        .WR_EN                    (rach_wr_en),
        .RD_EN                    (rach_rd_en),
        .PROG_FULL_THRESH         (AXI_AR_PROG_FULL_THRESH),
        .PROG_FULL_THRESH_ASSERT  ({C_WR_PNTR_WIDTH_RACH{1'b0}}),
        .PROG_FULL_THRESH_NEGATE  ({C_WR_PNTR_WIDTH_RACH{1'b0}}),
        .PROG_EMPTY_THRESH        (AXI_AR_PROG_EMPTY_THRESH),
        .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_RACH{1'b0}}),
        .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_RACH{1'b0}}),
        .INJECTDBITERR            (AXI_AR_INJECTDBITERR), 
        .INJECTSBITERR            (AXI_AR_INJECTSBITERR),
  
        .DIN                      (rach_din),
        .DOUT                     (rach_dout_pkt),
        .FULL                     (rach_full),
        .EMPTY                    (rach_empty),
        .ALMOST_FULL              (),
        .ALMOST_EMPTY             (),
        .PROG_FULL                (AXI_AR_PROG_FULL),
        .PROG_EMPTY               (AXI_AR_PROG_EMPTY),
  
        .WR_ACK                   (),
        .OVERFLOW                 (axi_ar_overflow_i),
        .VALID                    (),
        .UNDERFLOW                (axi_ar_underflow_i),
        .DATA_COUNT               (AXI_AR_DATA_COUNT),
        .RD_DATA_COUNT            (AXI_AR_RD_DATA_COUNT),
        .WR_DATA_COUNT            (AXI_AR_WR_DATA_COUNT),
        .SBITERR                  (AXI_AR_SBITERR),
        .DBITERR                  (AXI_AR_DBITERR),
        .wr_rst_busy              (wr_rst_busy_rach),
        .rd_rst_busy              (rd_rst_busy_rach),
        .wr_rst_i_out             (),
        .rd_rst_i_out             (),
  
        .BACKUP                   (BACKUP),
        .BACKUP_MARKER            (BACKUP_MARKER),
        .INT_CLK                  (INT_CLK)
       );

    assign rach_s_axi_arready    = (IS_8SERIES == 0) ? ~rach_full : (C_IMPLEMENTATION_TYPE_RACH == 5 || C_IMPLEMENTATION_TYPE_RACH == 13) ? ~(rach_full | wr_rst_busy_rach) : ~rach_full;
    assign rach_m_axi_arvalid = ~rach_empty;
    assign S_AXI_ARREADY      = rach_s_axi_arready;

    assign AXI_AR_UNDERFLOW  = C_USE_COMMON_UNDERFLOW == 0 ? axi_ar_underflow_i : 0;
    assign AXI_AR_OVERFLOW   = C_USE_COMMON_OVERFLOW  == 0 ? axi_ar_overflow_i  : 0;

  end endgenerate // axi_read_addr_channel

  // Register Slice for Read Address Channel
  generate if (C_RACH_TYPE == 1) begin : grach_reg_slice

    fifo_generator_v12_0_axic_reg_slice
          #(
            .C_FAMILY                (C_FAMILY),
            .C_DATA_WIDTH            (C_DIN_WIDTH_RACH),
            .C_REG_CONFIG            (C_REG_SLICE_MODE_RACH)
            )
    rach_reg_slice_inst
        (
          // System Signals
          .ACLK                      (S_ACLK),
          .ARESET                    (axi_rs_rst),

          // Slave side
          .S_PAYLOAD_DATA            (rach_din),
          .S_VALID                   (S_AXI_ARVALID),
          .S_READY                   (S_AXI_ARREADY),

          // Master side
          .M_PAYLOAD_DATA            (rach_dout),
          .M_VALID                   (M_AXI_ARVALID),
          .M_READY                   (M_AXI_ARREADY)
          );
  end endgenerate // grach_reg_slice

  // Register Slice for Read Address Channel for MM Packet FIFO
  generate if (C_RACH_TYPE == 0 && C_APPLICATION_TYPE_RACH == 1) begin : grach_reg_slice_mm_pkt_fifo

    fifo_generator_v12_0_axic_reg_slice
          #(
            .C_FAMILY                (C_FAMILY),
            .C_DATA_WIDTH            (C_DIN_WIDTH_RACH),
            .C_REG_CONFIG            (1)
            )
    reg_slice_mm_pkt_fifo_inst
        (
          // System Signals
          .ACLK                      (S_ACLK),
          .ARESET                    (inverted_reset),

          // Slave side
          .S_PAYLOAD_DATA            (rach_dout_pkt),
          .S_VALID                   (arvalid_pkt),
          .S_READY                   (arready_pkt),

          // Master side
          .M_PAYLOAD_DATA            (rach_dout),
          .M_VALID                   (M_AXI_ARVALID),
          .M_READY                   (M_AXI_ARREADY)
          );
  end endgenerate // grach_reg_slice_mm_pkt_fifo

  
  generate if (C_RACH_TYPE == 0 && C_APPLICATION_TYPE_RACH != 1) begin : grach_m_axi_arvalid
    assign M_AXI_ARVALID      = rach_m_axi_arvalid;
    assign rach_dout          = rach_dout_pkt;
  end endgenerate // grach_m_axi_arvalid
  
  
  generate if (C_APPLICATION_TYPE_RACH == 1 && C_HAS_AXI_RD_CHANNEL == 1) begin : axi_mm_pkt_fifo_rd
    assign rdch_rd_ok = rdch_s_axi_rvalid && rdch_rd_en;
    assign arvalid_pkt = rach_m_axi_arvalid && arvalid_en;
    assign accept_next_pkt  = rach_m_axi_arvalid && arready_pkt && arvalid_en;

    always@(posedge S_ACLK or posedge inverted_reset) begin
      if(inverted_reset) begin
	rdch_commited_space <= 0;
      end else begin
	if(rdch_rd_ok && !accept_next_pkt) begin
	  rdch_commited_space <= rdch_commited_space-1;
	end else if(!rdch_rd_ok && accept_next_pkt) begin
	  rdch_commited_space <= rdch_commited_space+(rach_dout_pkt[ARADDR_OFFSET-1:ARLEN_OFFSET]+1);
	end else if(rdch_rd_ok && accept_next_pkt) begin
	  rdch_commited_space <= rdch_commited_space+(rach_dout_pkt[ARADDR_OFFSET-1:ARLEN_OFFSET]);
	end
      end
    end //Always end

    always@(*) begin
      rdch_free_space <= (C_WR_DEPTH_RDCH-(rdch_commited_space+rach_dout_pkt[ARADDR_OFFSET-1:ARLEN_OFFSET]+1));
    end

    assign arvalid_en = (rdch_free_space >= 0)?1:0;
  end
  endgenerate
  
  generate if (C_APPLICATION_TYPE_RACH != 1) begin : axi_mm_fifo_rd
    assign arvalid_en = 1;    
  end
  endgenerate

  generate if (IS_RD_DATA_CH == 1) begin : axi_read_data_channel

    // Write protection when almost full or prog_full is high
    assign rdch_we    = (C_PROG_FULL_TYPE_RDCH != 0) ? rdch_m_axi_rready  & M_AXI_RVALID : M_AXI_RVALID;

    // Read protection when almost empty or prog_empty is high
    assign rdch_re    = (C_PROG_EMPTY_TYPE_RDCH != 0) ? rdch_s_axi_rvalid  & S_AXI_RREADY : S_AXI_RREADY;
    assign rdch_wr_en = (C_HAS_SLAVE_CE == 1)  ? rdch_we & S_ACLK_EN : rdch_we;
    assign rdch_rd_en = (C_HAS_MASTER_CE == 1) ? rdch_re & M_ACLK_EN : rdch_re;

    FIFO_GENERATOR_v12_0_CONV_VER
      #(
        .C_FAMILY			(C_FAMILY),
        .C_COMMON_CLOCK                 (C_COMMON_CLOCK),
        .C_MEMORY_TYPE			((C_IMPLEMENTATION_TYPE_RDCH == 1  || C_IMPLEMENTATION_TYPE_RDCH == 11) ? 1 :
                                         (C_IMPLEMENTATION_TYPE_RDCH == 2  || C_IMPLEMENTATION_TYPE_RDCH == 12) ? 2 : 4),
        .C_IMPLEMENTATION_TYPE		((C_IMPLEMENTATION_TYPE_RDCH == 1  || C_IMPLEMENTATION_TYPE_RDCH == 2) ? 0 :
                                         (C_IMPLEMENTATION_TYPE_RDCH == 11 || C_IMPLEMENTATION_TYPE_RDCH == 12) ? 2 : 6),
        .C_PRELOAD_REGS			(1), // always FWFT for AXI
        .C_PRELOAD_LATENCY		(0), // always FWFT for AXI
        .C_DIN_WIDTH			(C_DIN_WIDTH_RDCH),
        .C_WR_DEPTH			(C_WR_DEPTH_RDCH),
        .C_WR_PNTR_WIDTH		(C_WR_PNTR_WIDTH_RDCH),
        .C_DOUT_WIDTH			(C_DIN_WIDTH_RDCH),
        .C_RD_DEPTH			(C_WR_DEPTH_RDCH),
        .C_RD_PNTR_WIDTH		(C_WR_PNTR_WIDTH_RDCH),
        .C_PROG_FULL_TYPE		(C_PROG_FULL_TYPE_RDCH),
        .C_PROG_FULL_THRESH_ASSERT_VAL	(C_PROG_FULL_THRESH_ASSERT_VAL_RDCH),
        .C_PROG_EMPTY_TYPE		(C_PROG_EMPTY_TYPE_RDCH),
        .C_PROG_EMPTY_THRESH_ASSERT_VAL	(C_PROG_EMPTY_THRESH_ASSERT_VAL_RDCH),
        .C_USE_ECC                      (C_USE_ECC_RDCH),
        .C_ERROR_INJECTION_TYPE         (C_ERROR_INJECTION_TYPE_RDCH),
        .C_HAS_ALMOST_EMPTY		(0),
        .C_HAS_ALMOST_FULL		(0),
        .C_AXI_TYPE                     (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE),

        .C_FIFO_TYPE                    (C_APPLICATION_TYPE_RDCH),
        .C_SYNCHRONIZER_STAGE           (C_SYNCHRONIZER_STAGE),

        .C_HAS_WR_RST			(0),
        .C_HAS_RD_RST			(0),
        .C_HAS_RST			(1),
        .C_HAS_SRST			(0),
        .C_DOUT_RST_VAL			(0),

        .C_HAS_VALID			(0),
        .C_VALID_LOW			(C_VALID_LOW),
        .C_HAS_UNDERFLOW		(C_HAS_UNDERFLOW),
        .C_UNDERFLOW_LOW		(C_UNDERFLOW_LOW),
        .C_HAS_WR_ACK			(0),
        .C_WR_ACK_LOW			(C_WR_ACK_LOW),
        .C_HAS_OVERFLOW			(C_HAS_OVERFLOW),
        .C_OVERFLOW_LOW			(C_OVERFLOW_LOW),

        .C_HAS_DATA_COUNT		((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_RDCH == 1) ? 1 : 0),
        .C_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_RDCH + 1),
        .C_HAS_RD_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_RDCH == 1) ? 1 : 0),
        .C_RD_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_RDCH + 1),
        .C_USE_FWFT_DATA_COUNT		(1), // use extra logic is always true
        .C_HAS_WR_DATA_COUNT		((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_RDCH == 1) ? 1 : 0),
        .C_WR_DATA_COUNT_WIDTH		(C_WR_PNTR_WIDTH_RDCH + 1),
        .C_FULL_FLAGS_RST_VAL           (1),
        .C_USE_EMBEDDED_REG		(0),
        .C_USE_DOUT_RST                 (0),
        .C_MSGON_VAL                    (C_MSGON_VAL),
        .C_ENABLE_RST_SYNC              (1),

        .C_COUNT_TYPE			(C_COUNT_TYPE),
        .C_DEFAULT_VALUE		(C_DEFAULT_VALUE),
        .C_ENABLE_RLOCS			(C_ENABLE_RLOCS),
        .C_HAS_BACKUP			(C_HAS_BACKUP),
        .C_HAS_INT_CLK                  (C_HAS_INT_CLK),
        .C_MIF_FILE_NAME		(C_MIF_FILE_NAME),
        .C_HAS_MEMINIT_FILE		(C_HAS_MEMINIT_FILE),
        .C_INIT_WR_PNTR_VAL		(C_INIT_WR_PNTR_VAL),
        .C_OPTIMIZATION_MODE		(C_OPTIMIZATION_MODE),
        .C_PRIM_FIFO_TYPE		(C_PRIM_FIFO_TYPE),
        .C_RD_FREQ			(C_RD_FREQ),
        .C_USE_FIFO16_FLAGS		(C_USE_FIFO16_FLAGS),
        .C_WR_FREQ			(C_WR_FREQ),
        .C_WR_RESPONSE_LATENCY		(C_WR_RESPONSE_LATENCY)
      )
    fifo_generator_v12_0_rdch_dut
      (
        .CLK                      (S_ACLK),
        .WR_CLK                   (M_ACLK),
        .RD_CLK                   (S_ACLK),
        .RST                      (inverted_reset),
        .SRST                     (1'b0),
        .WR_RST                   (inverted_reset),
        .RD_RST                   (inverted_reset),
        .WR_EN                    (rdch_wr_en),
        .RD_EN                    (rdch_rd_en),
        .PROG_FULL_THRESH         (AXI_R_PROG_FULL_THRESH),
        .PROG_FULL_THRESH_ASSERT  ({C_WR_PNTR_WIDTH_RDCH{1'b0}}),
        .PROG_FULL_THRESH_NEGATE  ({C_WR_PNTR_WIDTH_RDCH{1'b0}}),
        .PROG_EMPTY_THRESH        (AXI_R_PROG_EMPTY_THRESH),
        .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_RDCH{1'b0}}),
        .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_RDCH{1'b0}}),
        .INJECTDBITERR            (AXI_R_INJECTDBITERR), 
        .INJECTSBITERR            (AXI_R_INJECTSBITERR),
  
        .DIN                      (rdch_din),
        .DOUT                     (rdch_dout),
        .FULL                     (rdch_full),
        .EMPTY                    (rdch_empty),
        .ALMOST_FULL              (),
        .ALMOST_EMPTY             (),
        .PROG_FULL                (AXI_R_PROG_FULL),
        .PROG_EMPTY               (AXI_R_PROG_EMPTY),
  
        .WR_ACK                   (),
        .OVERFLOW                 (axi_r_overflow_i),
        .VALID                    (),
        .UNDERFLOW                (axi_r_underflow_i),
        .DATA_COUNT               (AXI_R_DATA_COUNT),
        .RD_DATA_COUNT            (AXI_R_RD_DATA_COUNT),
        .WR_DATA_COUNT            (AXI_R_WR_DATA_COUNT),
        .SBITERR                  (AXI_R_SBITERR),
        .DBITERR                  (AXI_R_DBITERR),
        .wr_rst_busy              (wr_rst_busy_rdch),
        .rd_rst_busy              (rd_rst_busy_rdch),
        .wr_rst_i_out             (),
        .rd_rst_i_out             (),
  
        .BACKUP                   (BACKUP),
        .BACKUP_MARKER            (BACKUP_MARKER),
        .INT_CLK                  (INT_CLK)
       );

    assign rdch_s_axi_rvalid = ~rdch_empty;
    assign rdch_m_axi_rready     = (IS_8SERIES == 0) ? ~rdch_full : (C_IMPLEMENTATION_TYPE_RDCH == 5 || C_IMPLEMENTATION_TYPE_RDCH == 13) ? ~(rdch_full | wr_rst_busy_rdch) : ~rdch_full;
    assign S_AXI_RVALID      = rdch_s_axi_rvalid;
    assign M_AXI_RREADY      = rdch_m_axi_rready;

    assign AXI_R_UNDERFLOW   = C_USE_COMMON_UNDERFLOW == 0 ? axi_r_underflow_i  : 0;
    assign AXI_R_OVERFLOW    = C_USE_COMMON_OVERFLOW  == 0 ? axi_r_overflow_i   : 0;

  end endgenerate //axi_read_data_channel

  // Register Slice for read Data Channel
  generate if (C_RDCH_TYPE == 1) begin : grdch_reg_slice

    fifo_generator_v12_0_axic_reg_slice
          #(
            .C_FAMILY                (C_FAMILY),
            .C_DATA_WIDTH            (C_DIN_WIDTH_RDCH),
            .C_REG_CONFIG            (C_REG_SLICE_MODE_RDCH)
            )
    rdch_reg_slice_inst
        (
          // System Signals
          .ACLK                      (S_ACLK),
          .ARESET                    (axi_rs_rst),

          // Slave side
          .S_PAYLOAD_DATA            (rdch_din),
          .S_VALID                   (M_AXI_RVALID),
          .S_READY                   (M_AXI_RREADY),

          // Master side
          .M_PAYLOAD_DATA            (rdch_dout),
          .M_VALID                   (S_AXI_RVALID),
          .M_READY                   (S_AXI_RREADY)
          );
  end endgenerate // grdch_reg_slice


    assign axi_rd_underflow_i = C_USE_COMMON_UNDERFLOW == 1 ? (axi_ar_underflow_i || axi_r_underflow_i) : 0;
    assign axi_rd_overflow_i  = C_USE_COMMON_OVERFLOW  == 1 ? (axi_ar_overflow_i  || axi_r_overflow_i) : 0;


  generate if (IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) begin : axi_full_rach_output
    assign M_AXI_ARADDR    = rach_dout[ARID_OFFSET-1:ARADDR_OFFSET];    
    assign M_AXI_ARLEN     = rach_dout[ARADDR_OFFSET-1:ARLEN_OFFSET];    
    assign M_AXI_ARSIZE    = rach_dout[ARLEN_OFFSET-1:ARSIZE_OFFSET];    
    assign M_AXI_ARBURST   = rach_dout[ARSIZE_OFFSET-1:ARBURST_OFFSET];    
    assign M_AXI_ARLOCK    = rach_dout[ARBURST_OFFSET-1:ARLOCK_OFFSET];    
    assign M_AXI_ARCACHE   = rach_dout[ARLOCK_OFFSET-1:ARCACHE_OFFSET];    
    assign M_AXI_ARPROT    = rach_dout[ARCACHE_OFFSET-1:ARPROT_OFFSET];    
    assign M_AXI_ARQOS     = rach_dout[ARPROT_OFFSET-1:ARQOS_OFFSET];    
    assign rach_din[ARID_OFFSET-1:ARADDR_OFFSET]    = S_AXI_ARADDR;
    assign rach_din[ARADDR_OFFSET-1:ARLEN_OFFSET]   = S_AXI_ARLEN;
    assign rach_din[ARLEN_OFFSET-1:ARSIZE_OFFSET]   = S_AXI_ARSIZE;
    assign rach_din[ARSIZE_OFFSET-1:ARBURST_OFFSET] = S_AXI_ARBURST;
    assign rach_din[ARBURST_OFFSET-1:ARLOCK_OFFSET] = S_AXI_ARLOCK;
    assign rach_din[ARLOCK_OFFSET-1:ARCACHE_OFFSET] = S_AXI_ARCACHE;
    assign rach_din[ARCACHE_OFFSET-1:ARPROT_OFFSET] = S_AXI_ARPROT;
    assign rach_din[ARPROT_OFFSET-1:ARQOS_OFFSET]   = S_AXI_ARQOS;
  end endgenerate // axi_full_rach_output

  generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_AXI_TYPE == 1) begin : axi_arregion
    assign M_AXI_ARREGION  = rach_dout[ARQOS_OFFSET-1:ARREGION_OFFSET];    
  end endgenerate // axi_arregion

  generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_AXI_TYPE != 1) begin : naxi_arregion
    assign M_AXI_ARREGION  = 0;    
  end endgenerate // naxi_arregion

  generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ARUSER == 1) begin : axi_aruser
    assign M_AXI_ARUSER = rach_dout[ARREGION_OFFSET-1:ARUSER_OFFSET];    
  end endgenerate // axi_aruser

  generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ARUSER == 0) begin : naxi_aruser
    assign M_AXI_ARUSER = 0;    
  end endgenerate // naxi_aruser

  generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : axi_arid
    assign M_AXI_ARID      = rach_dout[C_DIN_WIDTH_RACH-1:ARID_OFFSET];
  end endgenerate // axi_arid

  generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ID == 0) begin : naxi_arid
    assign M_AXI_ARID      = 0;
  end endgenerate // naxi_arid

  generate if (IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) begin : axi_full_rdch_output
    assign S_AXI_RDATA     = rdch_dout[RID_OFFSET-1:RDATA_OFFSET];
    assign S_AXI_RRESP     = rdch_dout[RDATA_OFFSET-1:RRESP_OFFSET];
    assign S_AXI_RLAST     = rdch_dout[0];
    assign rdch_din[RID_OFFSET-1:RDATA_OFFSET]   = M_AXI_RDATA;
    assign rdch_din[RDATA_OFFSET-1:RRESP_OFFSET] = M_AXI_RRESP;
    assign rdch_din[0] = M_AXI_RLAST;
  end endgenerate // axi_full_rdch_output
  
  generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_RUSER == 1) begin : axi_full_ruser_output
    assign S_AXI_RUSER     = rdch_dout[RRESP_OFFSET-1:RUSER_OFFSET];
  end endgenerate // axi_full_ruser_output

  generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_RUSER == 0) begin : axi_full_nruser_output
    assign S_AXI_RUSER     =  0;
  end endgenerate // axi_full_nruser_output
  
  generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : axi_rid
    assign S_AXI_RID       = rdch_dout[C_DIN_WIDTH_RDCH-1:RID_OFFSET];
  end endgenerate // axi_rid

  generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_ID == 0) begin : naxi_rid
    assign S_AXI_RID       = 0;
  end endgenerate // naxi_rid

  generate if (IS_AXI_LITE_RACH == 1 || (IS_AXI_LITE == 1 && C_RACH_TYPE == 1)) begin : axi_lite_rach_output1
    assign rach_din      = {S_AXI_ARADDR, S_AXI_ARPROT};
    assign M_AXI_ARADDR  = rach_dout[C_DIN_WIDTH_RACH-1:ARADDR_OFFSET];
    assign M_AXI_ARPROT  = rach_dout[ARADDR_OFFSET-1:ARPROT_OFFSET];
  end endgenerate // axi_lite_rach_output

  generate if (IS_AXI_LITE_RDCH == 1 || (IS_AXI_LITE == 1 && C_RDCH_TYPE == 1)) begin : axi_lite_rdch_output1
    assign rdch_din      = {M_AXI_RDATA, M_AXI_RRESP};
    assign S_AXI_RDATA   = rdch_dout[C_DIN_WIDTH_RDCH-1:RDATA_OFFSET];
    assign S_AXI_RRESP   = rdch_dout[RDATA_OFFSET-1:RRESP_OFFSET];
  end endgenerate // axi_lite_rdch_output

  generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ARUSER == 1) begin : grach_din1
    assign rach_din[ARREGION_OFFSET-1:ARUSER_OFFSET]     = S_AXI_ARUSER;
  end endgenerate // grach_din1

  generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : grach_din2
    assign rach_din[C_DIN_WIDTH_RACH-1:ARID_OFFSET]     = S_AXI_ARID;
  end endgenerate // grach_din2

  generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_AXI_TYPE == 1) begin
    assign rach_din[ARQOS_OFFSET-1:ARREGION_OFFSET] = S_AXI_ARREGION;
  end endgenerate

  generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_RUSER == 1) begin : grdch_din1
    assign rdch_din[RRESP_OFFSET-1:RUSER_OFFSET]     = M_AXI_RUSER;
  end endgenerate // grdch_din1

  generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : grdch_din2
    assign rdch_din[C_DIN_WIDTH_RDCH-1:RID_OFFSET] = M_AXI_RID;
  end endgenerate // grdch_din2

  //end of axi_read_channel

  generate if (C_INTERFACE_TYPE == 1 && C_USE_COMMON_UNDERFLOW == 1) begin : gaxi_comm_uf
    assign UNDERFLOW = (C_HAS_AXI_WR_CHANNEL == 1 && C_HAS_AXI_RD_CHANNEL == 1) ? (axi_wr_underflow_i || axi_rd_underflow_i) :
                       (C_HAS_AXI_WR_CHANNEL == 1 && C_HAS_AXI_RD_CHANNEL == 0) ? axi_wr_underflow_i :
                       (C_HAS_AXI_WR_CHANNEL == 0 && C_HAS_AXI_RD_CHANNEL == 1) ? axi_rd_underflow_i : 0;
  end endgenerate // gaxi_comm_uf

  generate if (C_INTERFACE_TYPE == 1 && C_USE_COMMON_OVERFLOW == 1) begin : gaxi_comm_of
    assign OVERFLOW = (C_HAS_AXI_WR_CHANNEL == 1 && C_HAS_AXI_RD_CHANNEL == 1) ? (axi_wr_overflow_i || axi_rd_overflow_i) :
                      (C_HAS_AXI_WR_CHANNEL == 1 && C_HAS_AXI_RD_CHANNEL == 0) ? axi_wr_overflow_i :
                      (C_HAS_AXI_WR_CHANNEL == 0 && C_HAS_AXI_RD_CHANNEL == 1) ? axi_rd_overflow_i : 0;
  end endgenerate // gaxi_comm_of
  
  //-------------------------------------------------------------------------
  //-------------------------------------------------------------------------
  //-------------------------------------------------------------------------
  // Pass Through Logic or Wiring Logic
  //-------------------------------------------------------------------------
  //-------------------------------------------------------------------------
  //-------------------------------------------------------------------------
  
  //-------------------------------------------------------------------------
  // Pass Through Logic for Read Channel
  //-------------------------------------------------------------------------

  // Wiring logic for Write Address Channel
  generate if (C_WACH_TYPE == 2) begin : gwach_pass_through
    assign M_AXI_AWID      = S_AXI_AWID;
    assign M_AXI_AWADDR    = S_AXI_AWADDR;
    assign M_AXI_AWLEN     = S_AXI_AWLEN;
    assign M_AXI_AWSIZE    = S_AXI_AWSIZE;
    assign M_AXI_AWBURST   = S_AXI_AWBURST;
    assign M_AXI_AWLOCK    = S_AXI_AWLOCK;
    assign M_AXI_AWCACHE   = S_AXI_AWCACHE;
    assign M_AXI_AWPROT    = S_AXI_AWPROT;
    assign M_AXI_AWQOS     = S_AXI_AWQOS;
    assign M_AXI_AWREGION  = S_AXI_AWREGION;
    assign M_AXI_AWUSER    = S_AXI_AWUSER;
    assign S_AXI_AWREADY   = M_AXI_AWREADY;
    assign M_AXI_AWVALID   = S_AXI_AWVALID;
  end endgenerate // gwach_pass_through;

  // Wiring logic for Write Data Channel
  generate if (C_WDCH_TYPE == 2) begin : gwdch_pass_through
    assign M_AXI_WID       = S_AXI_WID;
    assign M_AXI_WDATA     = S_AXI_WDATA;
    assign M_AXI_WSTRB     = S_AXI_WSTRB;
    assign M_AXI_WLAST     = S_AXI_WLAST;
    assign M_AXI_WUSER     = S_AXI_WUSER;
    assign S_AXI_WREADY    = M_AXI_WREADY;
    assign M_AXI_WVALID    = S_AXI_WVALID;
  end endgenerate // gwdch_pass_through;

  // Wiring logic for Write Response Channel
  generate if (C_WRCH_TYPE == 2) begin : gwrch_pass_through
    assign S_AXI_BID       = M_AXI_BID;
    assign S_AXI_BRESP     = M_AXI_BRESP;
    assign S_AXI_BUSER     = M_AXI_BUSER;
    assign M_AXI_BREADY    = S_AXI_BREADY;
    assign S_AXI_BVALID    = M_AXI_BVALID;
  end endgenerate // gwrch_pass_through;

  //-------------------------------------------------------------------------
  // Pass Through Logic for Read Channel
  //-------------------------------------------------------------------------

  // Wiring logic for Read Address Channel
  generate if (C_RACH_TYPE == 2) begin : grach_pass_through
    assign M_AXI_ARID      = S_AXI_ARID;
    assign M_AXI_ARADDR    = S_AXI_ARADDR;
    assign M_AXI_ARLEN     = S_AXI_ARLEN;
    assign M_AXI_ARSIZE    = S_AXI_ARSIZE;
    assign M_AXI_ARBURST   = S_AXI_ARBURST;
    assign M_AXI_ARLOCK    = S_AXI_ARLOCK;
    assign M_AXI_ARCACHE   = S_AXI_ARCACHE;
    assign M_AXI_ARPROT    = S_AXI_ARPROT;
    assign M_AXI_ARQOS     = S_AXI_ARQOS;
    assign M_AXI_ARREGION  = S_AXI_ARREGION;
    assign M_AXI_ARUSER    = S_AXI_ARUSER;
    assign S_AXI_ARREADY   = M_AXI_ARREADY;
    assign M_AXI_ARVALID   = S_AXI_ARVALID;
  end endgenerate // grach_pass_through;

  // Wiring logic for Read Data Channel 
  generate if (C_RDCH_TYPE == 2) begin : grdch_pass_through
    assign S_AXI_RID      = M_AXI_RID;
    assign S_AXI_RLAST    = M_AXI_RLAST;
    assign S_AXI_RUSER    = M_AXI_RUSER;
    assign S_AXI_RDATA    = M_AXI_RDATA;
    assign S_AXI_RRESP    = M_AXI_RRESP;
    assign S_AXI_RVALID   = M_AXI_RVALID;
    assign M_AXI_RREADY   = S_AXI_RREADY;
  end endgenerate // grdch_pass_through;

  // Wiring logic for AXI Streaming
  generate if (C_AXIS_TYPE == 2) begin : gaxis_pass_through
    assign M_AXIS_TDATA   = S_AXIS_TDATA;
    assign M_AXIS_TSTRB   = S_AXIS_TSTRB;
    assign M_AXIS_TKEEP   = S_AXIS_TKEEP;
    assign M_AXIS_TID     = S_AXIS_TID;
    assign M_AXIS_TDEST   = S_AXIS_TDEST;
    assign M_AXIS_TUSER   = S_AXIS_TUSER;
    assign M_AXIS_TLAST   = S_AXIS_TLAST;
    assign S_AXIS_TREADY  = M_AXIS_TREADY;
    assign M_AXIS_TVALID  = S_AXIS_TVALID;
  end endgenerate // gaxis_pass_through;


endmodule //FIFO_GENERATOR_v12_0



/*******************************************************************************
 * Declaration of top-level module for Conventional FIFO
 ******************************************************************************/
module FIFO_GENERATOR_v12_0_CONV_VER
  #(
    parameter  C_COMMON_CLOCK                 = 0,
    parameter  C_COUNT_TYPE                   = 0,
    parameter  C_DATA_COUNT_WIDTH             = 2,
    parameter  C_DEFAULT_VALUE                = "",
    parameter  C_DIN_WIDTH                    = 8,
    parameter  C_DOUT_RST_VAL                 = "",
    parameter  C_DOUT_WIDTH                   = 8,
    parameter  C_ENABLE_RLOCS                 = 0,
    parameter  C_FAMILY                       = "virtex7", //Not allowed in Verilog model
    parameter  C_FULL_FLAGS_RST_VAL           = 1,
    parameter  C_HAS_ALMOST_EMPTY             = 0,
    parameter  C_HAS_ALMOST_FULL              = 0,
    parameter  C_HAS_BACKUP                   = 0,
    parameter  C_HAS_DATA_COUNT               = 0,
    parameter  C_HAS_INT_CLK                  = 0,
    parameter  C_HAS_MEMINIT_FILE             = 0,
    parameter  C_HAS_OVERFLOW                 = 0,
    parameter  C_HAS_RD_DATA_COUNT            = 0,
    parameter  C_HAS_RD_RST                   = 0,
    parameter  C_HAS_RST                      = 0,
    parameter  C_HAS_SRST                     = 0,
    parameter  C_HAS_UNDERFLOW                = 0,
    parameter  C_HAS_VALID                    = 0,
    parameter  C_HAS_WR_ACK                   = 0,
    parameter  C_HAS_WR_DATA_COUNT            = 0,
    parameter  C_HAS_WR_RST                   = 0,
    parameter  C_IMPLEMENTATION_TYPE          = 0,
    parameter  C_INIT_WR_PNTR_VAL             = 0,
    parameter  C_MEMORY_TYPE                  = 1,
    parameter  C_MIF_FILE_NAME                = "",
    parameter  C_OPTIMIZATION_MODE            = 0,
    parameter  C_OVERFLOW_LOW                 = 0,
    parameter  C_PRELOAD_LATENCY              = 1,
    parameter  C_PRELOAD_REGS                 = 0,
    parameter  C_PRIM_FIFO_TYPE               = "",
    parameter  C_PROG_EMPTY_THRESH_ASSERT_VAL = 0,
    parameter  C_PROG_EMPTY_THRESH_NEGATE_VAL = 0,
    parameter  C_PROG_EMPTY_TYPE              = 0,
    parameter  C_PROG_FULL_THRESH_ASSERT_VAL  = 0,
    parameter  C_PROG_FULL_THRESH_NEGATE_VAL  = 0,
    parameter  C_PROG_FULL_TYPE               = 0,
    parameter  C_RD_DATA_COUNT_WIDTH          = 2,
    parameter  C_RD_DEPTH                     = 256,
    parameter  C_RD_FREQ                      = 1,
    parameter  C_RD_PNTR_WIDTH                = 8,
    parameter  C_UNDERFLOW_LOW                = 0,
    parameter  C_USE_DOUT_RST                 = 0,
    parameter  C_USE_ECC                      = 0,
    parameter  C_USE_EMBEDDED_REG             = 0,
    parameter  C_USE_FIFO16_FLAGS             = 0,
    parameter  C_USE_FWFT_DATA_COUNT          = 0,
    parameter  C_VALID_LOW                    = 0,
    parameter  C_WR_ACK_LOW                   = 0,
    parameter  C_WR_DATA_COUNT_WIDTH          = 2,
    parameter  C_WR_DEPTH                     = 256,
    parameter  C_WR_FREQ                      = 1,
    parameter  C_WR_PNTR_WIDTH                = 8,
    parameter  C_WR_RESPONSE_LATENCY          = 1,
    parameter  C_MSGON_VAL                    = 1,
    parameter  C_ENABLE_RST_SYNC              = 1,
    parameter  C_ERROR_INJECTION_TYPE         = 0,
    parameter  C_FIFO_TYPE                    = 0,
    parameter  C_SYNCHRONIZER_STAGE           = 2,
    parameter  C_AXI_TYPE                     = 0
   )

  (
   input                               BACKUP,
   input                               BACKUP_MARKER,
   input                               CLK,
   input                               RST,
   input                               SRST,
   input                               WR_CLK,
   input                               WR_RST,
   input                               RD_CLK,
   input                               RD_RST,
   input [C_DIN_WIDTH-1:0]             DIN,
   input                               WR_EN,
   input                               RD_EN,
   input [C_RD_PNTR_WIDTH-1:0]         PROG_EMPTY_THRESH,
   input [C_RD_PNTR_WIDTH-1:0]         PROG_EMPTY_THRESH_ASSERT,
   input [C_RD_PNTR_WIDTH-1:0]         PROG_EMPTY_THRESH_NEGATE,
   input [C_WR_PNTR_WIDTH-1:0]         PROG_FULL_THRESH,
   input [C_WR_PNTR_WIDTH-1:0]         PROG_FULL_THRESH_ASSERT,
   input [C_WR_PNTR_WIDTH-1:0]         PROG_FULL_THRESH_NEGATE,
   input                               INT_CLK,
   input                               INJECTDBITERR,
   input                               INJECTSBITERR,
  
   output [C_DOUT_WIDTH-1:0]           DOUT,
   output                              FULL,
   output                              ALMOST_FULL,
   output                              WR_ACK,
   output                              OVERFLOW,
   output                              EMPTY,
   output                              ALMOST_EMPTY,
   output                              VALID,
   output                              UNDERFLOW,
   output [C_DATA_COUNT_WIDTH-1:0]     DATA_COUNT,
   output [C_RD_DATA_COUNT_WIDTH-1:0]  RD_DATA_COUNT,
   output [C_WR_DATA_COUNT_WIDTH-1:0]  WR_DATA_COUNT,
   output                              PROG_FULL,
   output                              PROG_EMPTY,
   output                              SBITERR,
   output                              DBITERR,
   output                              wr_rst_busy,
   output                              rd_rst_busy,
   output                              wr_rst_i_out,
   output                              rd_rst_i_out
  );

/*
 ******************************************************************************
 * Definition of Parameters
 ******************************************************************************
 *     C_COMMON_CLOCK                : Common Clock (1), Independent Clocks (0)
 *     C_COUNT_TYPE                  :    *not used
 *     C_DATA_COUNT_WIDTH            : Width of DATA_COUNT bus
 *     C_DEFAULT_VALUE               :    *not used
 *     C_DIN_WIDTH                   : Width of DIN bus
 *     C_DOUT_RST_VAL                : Reset value of DOUT
 *     C_DOUT_WIDTH                  : Width of DOUT bus
 *     C_ENABLE_RLOCS                :    *not used
 *     C_FAMILY                      : not used in bhv model
 *     C_FULL_FLAGS_RST_VAL          : Full flags rst val (0 or 1)
 *     C_HAS_ALMOST_EMPTY            : 1=Core has ALMOST_EMPTY flag
 *     C_HAS_ALMOST_FULL             : 1=Core has ALMOST_FULL flag
 *     C_HAS_BACKUP                  :    *not used
 *     C_HAS_DATA_COUNT              : 1=Core has DATA_COUNT bus
 *     C_HAS_INT_CLK                 : not used in bhv model
 *     C_HAS_MEMINIT_FILE            :    *not used
 *     C_HAS_OVERFLOW                : 1=Core has OVERFLOW flag
 *     C_HAS_RD_DATA_COUNT           : 1=Core has RD_DATA_COUNT bus
 *     C_HAS_RD_RST                  :    *not used
 *     C_HAS_RST                     : 1=Core has Async Rst
 *     C_HAS_SRST                    : 1=Core has Sync Rst
 *     C_HAS_UNDERFLOW               : 1=Core has UNDERFLOW flag
 *     C_HAS_VALID                   : 1=Core has VALID flag
 *     C_HAS_WR_ACK                  : 1=Core has WR_ACK flag
 *     C_HAS_WR_DATA_COUNT           : 1=Core has WR_DATA_COUNT bus
 *     C_HAS_WR_RST                  :    *not used
 *     C_IMPLEMENTATION_TYPE         : 0=Common-Clock Bram/Dram
 *                                     1=Common-Clock ShiftRam
 *                                     2=Indep. Clocks Bram/Dram
 *                                     3=Virtex-4 Built-in
 *                                     4=Virtex-5 Built-in
 *     C_INIT_WR_PNTR_VAL            :   *not used
 *     C_MEMORY_TYPE                 : 1=Block RAM
 *                                     2=Distributed RAM
 *                                     3=Shift RAM
 *                                     4=Built-in FIFO
 *     C_MIF_FILE_NAME               :   *not used
 *     C_OPTIMIZATION_MODE           :   *not used
 *     C_OVERFLOW_LOW                : 1=OVERFLOW active low
 *     C_PRELOAD_LATENCY             : Latency of read: 0, 1, 2
 *     C_PRELOAD_REGS                : 1=Use output registers
 *     C_PRIM_FIFO_TYPE              : not used in bhv model
 *     C_PROG_EMPTY_THRESH_ASSERT_VAL: PROG_EMPTY assert threshold
 *     C_PROG_EMPTY_THRESH_NEGATE_VAL: PROG_EMPTY negate threshold
 *     C_PROG_EMPTY_TYPE             : 0=No programmable empty
 *                                     1=Single prog empty thresh constant
 *                                     2=Multiple prog empty thresh constants
 *                                     3=Single prog empty thresh input
 *                                     4=Multiple prog empty thresh inputs
 *     C_PROG_FULL_THRESH_ASSERT_VAL : PROG_FULL assert threshold
 *     C_PROG_FULL_THRESH_NEGATE_VAL : PROG_FULL negate threshold
 *     C_PROG_FULL_TYPE              : 0=No prog full
 *                                     1=Single prog full thresh constant
 *                                     2=Multiple prog full thresh constants
 *                                     3=Single prog full thresh input
 *                                     4=Multiple prog full thresh inputs
 *     C_RD_DATA_COUNT_WIDTH         : Width of RD_DATA_COUNT bus
 *     C_RD_DEPTH                    : Depth of read interface (2^N)
 *     C_RD_FREQ                     : not used in bhv model
 *     C_RD_PNTR_WIDTH               : always log2(C_RD_DEPTH)
 *     C_UNDERFLOW_LOW               : 1=UNDERFLOW active low
 *     C_USE_DOUT_RST                : 1=Resets DOUT on RST
 *     C_USE_ECC                     : Used for error injection purpose
 *     C_USE_EMBEDDED_REG            : 1=Use BRAM embedded output register
 *     C_USE_FIFO16_FLAGS            : not used in bhv model
 *     C_USE_FWFT_DATA_COUNT         : 1=Use extra logic for FWFT data count
 *     C_VALID_LOW                   : 1=VALID active low
 *     C_WR_ACK_LOW                  : 1=WR_ACK active low
 *     C_WR_DATA_COUNT_WIDTH         : Width of WR_DATA_COUNT bus
 *     C_WR_DEPTH                    : Depth of write interface (2^N)
 *     C_WR_FREQ                     : not used in bhv model
 *     C_WR_PNTR_WIDTH               : always log2(C_WR_DEPTH)
 *     C_WR_RESPONSE_LATENCY         :    *not used
 *     C_MSGON_VAL                   :    *not used by bhv model
 *     C_ENABLE_RST_SYNC             : 0 = Use WR_RST & RD_RST
 *                                     1 = Use RST
 *     C_ERROR_INJECTION_TYPE        : 0 = No error injection
 *                                     1 = Single bit error injection only
 *                                     2 = Double bit error injection only
 *                                     3 = Single and double bit error injection
 ******************************************************************************
 * Definition of Ports
 ******************************************************************************
 *   BACKUP       : Not used
 *   BACKUP_MARKER: Not used
 *   CLK          : Clock
 *   DIN          : Input data bus
 *   PROG_EMPTY_THRESH       : Threshold for Programmable Empty Flag
 *   PROG_EMPTY_THRESH_ASSERT: Threshold for Programmable Empty Flag
 *   PROG_EMPTY_THRESH_NEGATE: Threshold for Programmable Empty Flag
 *   PROG_FULL_THRESH        : Threshold for Programmable Full Flag
 *   PROG_FULL_THRESH_ASSERT : Threshold for Programmable Full Flag
 *   PROG_FULL_THRESH_NEGATE : Threshold for Programmable Full Flag
 *   RD_CLK       : Read Domain Clock
 *   RD_EN        : Read enable
 *   RD_RST       : Read Reset
 *   RST          : Asynchronous Reset
 *   SRST         : Synchronous Reset
 *   WR_CLK       : Write Domain Clock
 *   WR_EN        : Write enable
 *   WR_RST       : Write Reset
 *   INT_CLK      : Internal Clock
 *   INJECTSBITERR: Inject Signle bit error
 *   INJECTDBITERR: Inject Double bit error
 *   ALMOST_EMPTY : One word remaining in FIFO
 *   ALMOST_FULL  : One empty space remaining in FIFO
 *   DATA_COUNT   : Number of data words in fifo( synchronous to CLK)
 *   DOUT         : Output data bus
 *   EMPTY        : Empty flag
 *   FULL         : Full flag
 *   OVERFLOW     : Last write rejected
 *   PROG_EMPTY   : Programmable Empty Flag
 *   PROG_FULL    : Programmable Full Flag
 *   RD_DATA_COUNT: Number of data words in fifo (synchronous to RD_CLK)
 *   UNDERFLOW    : Last read rejected
 *   VALID        : Last read acknowledged, DOUT bus VALID
 *   WR_ACK       : Last write acknowledged
 *   WR_DATA_COUNT: Number of data words in fifo (synchronous to WR_CLK)
 *   SBITERR      : Single Bit ECC Error Detected
 *   DBITERR      : Double Bit ECC Error Detected
 ******************************************************************************
 */

  //----------------------------------------------------------------------------
  //- Internal Signals for delayed input signals
  //- All the input signals except Clock are delayed by 100 ps and then given to
  //- the models.
  //----------------------------------------------------------------------------
 
  reg                         rst_delayed                       ;
  reg                         empty_fb                       ;
  reg                         srst_delayed                      ;
  reg                         wr_rst_delayed                    ;
  reg                         rd_rst_delayed                    ;
  reg                         wr_en_delayed                     ;
  reg                         rd_en_delayed                     ;
  reg  [C_DIN_WIDTH-1:0]      din_delayed                       ;
  reg  [C_RD_PNTR_WIDTH-1:0]  prog_empty_thresh_delayed         ;
  reg  [C_RD_PNTR_WIDTH-1:0]  prog_empty_thresh_assert_delayed  ;
  reg  [C_RD_PNTR_WIDTH-1:0]  prog_empty_thresh_negate_delayed  ;
  reg  [C_WR_PNTR_WIDTH-1:0]  prog_full_thresh_delayed          ;
  reg  [C_WR_PNTR_WIDTH-1:0]  prog_full_thresh_assert_delayed   ;
  reg  [C_WR_PNTR_WIDTH-1:0]  prog_full_thresh_negate_delayed   ;
  reg                         injectdbiterr_delayed             ;
  reg                         injectsbiterr_delayed             ;
   wire                        empty_p0_out;

  always @* rst_delayed                       <= #`TCQ RST                      ;
  always @* empty_fb                       <= #`TCQ empty_p0_out                      ;
  always @* srst_delayed                      <= #`TCQ SRST                     ; 
  always @* wr_rst_delayed                    <= #`TCQ WR_RST                   ; 
  always @* rd_rst_delayed                    <= #`TCQ RD_RST                   ; 
  always @* din_delayed                       <= #`TCQ DIN                      ; 
  always @* wr_en_delayed                     <= #`TCQ WR_EN                    ; 
  always @* rd_en_delayed                     <= #`TCQ RD_EN                    ; 
  always @* prog_empty_thresh_delayed         <= #`TCQ PROG_EMPTY_THRESH        ; 
  always @* prog_empty_thresh_assert_delayed  <= #`TCQ PROG_EMPTY_THRESH_ASSERT ; 
  always @* prog_empty_thresh_negate_delayed  <= #`TCQ PROG_EMPTY_THRESH_NEGATE ; 
  always @* prog_full_thresh_delayed          <= #`TCQ PROG_FULL_THRESH         ; 
  always @* prog_full_thresh_assert_delayed   <= #`TCQ PROG_FULL_THRESH_ASSERT  ; 
  always @* prog_full_thresh_negate_delayed   <= #`TCQ PROG_FULL_THRESH_NEGATE  ; 
  always @* injectdbiterr_delayed             <= #`TCQ INJECTDBITERR            ; 
  always @* injectsbiterr_delayed             <= #`TCQ INJECTSBITERR            ; 

  /*****************************************************************************
   * Derived parameters
   ****************************************************************************/
  //There are 2 Verilog behavioral models
  // 0 = Common-Clock FIFO/ShiftRam FIFO
  // 1 = Independent Clocks FIFO
  // 2 = Low Latency Synchronous FIFO
  // 3 = Low Latency Asynchronous FIFO
  localparam C_VERILOG_IMPL = (C_FIFO_TYPE == 3) ? 2 :
                              (C_IMPLEMENTATION_TYPE == 2) ? 1 : 0;
  localparam IS_8SERIES         = (C_FAMILY == "virtexu" || C_FAMILY == "kintexu" || C_FAMILY == "artixu" || C_FAMILY == "virtexum" || C_FAMILY == "zynque") ? 1 : 0;

  //Internal reset signals
  reg                                rd_rst_asreg    = 0;
  reg                                rd_rst_asreg_d1 = 0;
  reg                                rd_rst_asreg_d2 = 0;
  reg                                rd_rst_asreg_d3 = 0;
  reg                                rd_rst_reg      = 0;
  wire                               rd_rst_comb;
  reg                                wr_rst_d0       = 0;
  reg                                wr_rst_d1       = 0;
  reg                                wr_rst_d2       = 0;
  reg                                rd_rst_d0       = 0;
  reg                                rd_rst_d1       = 0;
  reg                                rd_rst_d2       = 0;
  reg                                rd_rst_d3       = 0;
  reg                                wrrst_done      = 0;
  reg                                rdrst_done      = 0;
  reg                                wr_rst_asreg    = 0;
  reg                                wr_rst_asreg_d1 = 0;
  reg                                wr_rst_asreg_d2 = 0;
  reg                                wr_rst_asreg_d3 = 0;
  reg                                rd_rst_wr_d0    = 0;
  reg                                rd_rst_wr_d1    = 0;
  reg                                rd_rst_wr_d2    = 0;
  reg                                wr_rst_reg      = 0;
  reg                                rst_active_i    = 1'b1;
  reg                                rst_delayed_d1  = 1'b1;
  reg                                rst_delayed_d2  = 1'b1;
  wire                               wr_rst_comb;
  wire                               wr_rst_i;
  wire                               rd_rst_i;
  wire                               rst_i;

  //Internal reset signals
  reg                                rst_asreg    = 0;
  reg                                srst_asreg    = 0;
  reg                                rst_asreg_d1 = 0;
  reg                                rst_asreg_d2 = 0;
  reg                                srst_asreg_d1 = 0;
  reg                                srst_asreg_d2 = 0;
  reg                                rst_reg      = 0;
  reg                                srst_reg      = 0;
  wire                               rst_comb;
  wire                               srst_comb;
  reg                                rst_full_gen_i = 0;
  reg                                rst_full_ff_i = 0;
                                     
  wire                               RD_CLK_P0_IN;
  wire                               RST_P0_IN;
  wire                               RD_EN_FIFO_IN;
  wire                               RD_EN_P0_IN;

  wire                               ALMOST_EMPTY_FIFO_OUT;
  wire                               ALMOST_FULL_FIFO_OUT;
  wire [C_DATA_COUNT_WIDTH-1:0]      DATA_COUNT_FIFO_OUT;
  wire [C_DOUT_WIDTH-1:0]            DOUT_FIFO_OUT;
  wire                               EMPTY_FIFO_OUT;
  wire                               FULL_FIFO_OUT;
  wire                               OVERFLOW_FIFO_OUT;
  wire                               PROG_EMPTY_FIFO_OUT;
  wire                               PROG_FULL_FIFO_OUT;
  wire                               VALID_FIFO_OUT;
  wire [C_RD_DATA_COUNT_WIDTH-1:0]   RD_DATA_COUNT_FIFO_OUT;
  wire                               UNDERFLOW_FIFO_OUT;
  wire                               WR_ACK_FIFO_OUT;
  wire [C_WR_DATA_COUNT_WIDTH-1:0]   WR_DATA_COUNT_FIFO_OUT;


  //***************************************************************************
  // Internal Signals
  //   The core uses either the internal_ wires or the preload0_ wires depending
  //     on whether the core uses Preload0 or not.
  //   When using preload0, the internal signals connect the internal core to
  //     the preload logic, and the external core's interfaces are tied to the
  //     preload0 signals from the preload logic.
  //***************************************************************************
  wire [C_DOUT_WIDTH-1:0]            DATA_P0_OUT;
  wire                               VALID_P0_OUT;
  wire                               EMPTY_P0_OUT;
  wire                               ALMOSTEMPTY_P0_OUT;
  reg                                EMPTY_P0_OUT_Q;
  reg                                ALMOSTEMPTY_P0_OUT_Q;
  wire                               UNDERFLOW_P0_OUT;
  wire                               RDEN_P0_OUT;
  wire [C_DOUT_WIDTH-1:0]            DATA_P0_IN;
  wire                               EMPTY_P0_IN;
  reg  [31:0]                        DATA_COUNT_FWFT;
  reg                                SS_FWFT_WR  ;
  reg                                SS_FWFT_RD ;

  wire                               sbiterr_fifo_out;
  wire                               dbiterr_fifo_out;
  wire                               inject_sbit_err;
  wire                               inject_dbit_err;

  // Assign 0 if not selected to avoid 'X' propogation to S/DBITERR.
  assign inject_sbit_err = ((C_ERROR_INJECTION_TYPE == 1) || (C_ERROR_INJECTION_TYPE == 3)) ?
                           injectsbiterr_delayed : 0;
  assign inject_dbit_err = ((C_ERROR_INJECTION_TYPE == 2) || (C_ERROR_INJECTION_TYPE == 3)) ?
                           injectdbiterr_delayed : 0;
                           
  assign wr_rst_i_out = wr_rst_i;
  assign rd_rst_i_out = rd_rst_i;
   
// Choose the behavioral model to instantiate based on the C_VERILOG_IMPL
// parameter (1=Independent Clocks, 0=Common Clock)

  localparam FULL_FLAGS_RST_VAL = (C_HAS_SRST == 1) ? 0 : C_FULL_FLAGS_RST_VAL;
generate
case (C_VERILOG_IMPL)
0 : begin : block1
  //Common Clock Behavioral Model
  fifo_generator_v12_0_bhv_ver_ss
  #(
    .C_FAMILY                            (C_FAMILY),
    .C_DATA_COUNT_WIDTH                  (C_DATA_COUNT_WIDTH),            
    .C_DIN_WIDTH                         (C_DIN_WIDTH),                   
    .C_DOUT_RST_VAL                      (C_DOUT_RST_VAL),                
    .C_DOUT_WIDTH                        (C_DOUT_WIDTH),                  
    .C_FULL_FLAGS_RST_VAL                (FULL_FLAGS_RST_VAL),            
    .C_HAS_ALMOST_EMPTY                  (C_HAS_ALMOST_EMPTY),            
    .C_HAS_ALMOST_FULL                   ((C_AXI_TYPE == 0 && C_FIFO_TYPE == 1) ? 1 : C_HAS_ALMOST_FULL),             
    .C_HAS_DATA_COUNT                    (C_HAS_DATA_COUNT),              
    .C_HAS_OVERFLOW                      (C_HAS_OVERFLOW),                
    .C_HAS_RD_DATA_COUNT                 (C_HAS_RD_DATA_COUNT),           
    .C_HAS_RST                           (C_HAS_RST),                     
    .C_HAS_SRST                          (C_HAS_SRST),                    
    .C_HAS_UNDERFLOW                     (C_HAS_UNDERFLOW),               
    .C_HAS_VALID                         (C_HAS_VALID),                   
    .C_HAS_WR_ACK                        (C_HAS_WR_ACK),                  
    .C_HAS_WR_DATA_COUNT                 (C_HAS_WR_DATA_COUNT),           
    .C_IMPLEMENTATION_TYPE               (C_IMPLEMENTATION_TYPE),         
    .C_MEMORY_TYPE                       (C_MEMORY_TYPE),                 
    .C_OVERFLOW_LOW                      (C_OVERFLOW_LOW),                
    .C_PRELOAD_LATENCY                   (C_PRELOAD_LATENCY),             
    .C_PRELOAD_REGS                      (C_PRELOAD_REGS),                
    .C_PROG_EMPTY_THRESH_ASSERT_VAL      (C_PROG_EMPTY_THRESH_ASSERT_VAL),
    .C_PROG_EMPTY_THRESH_NEGATE_VAL      (C_PROG_EMPTY_THRESH_NEGATE_VAL),
    .C_PROG_EMPTY_TYPE                   (C_PROG_EMPTY_TYPE),             
    .C_PROG_FULL_THRESH_ASSERT_VAL       (C_PROG_FULL_THRESH_ASSERT_VAL), 
    .C_PROG_FULL_THRESH_NEGATE_VAL       (C_PROG_FULL_THRESH_NEGATE_VAL), 
    .C_PROG_FULL_TYPE                    (C_PROG_FULL_TYPE),              
    .C_RD_DATA_COUNT_WIDTH               (C_RD_DATA_COUNT_WIDTH),         
    .C_RD_DEPTH                          (C_RD_DEPTH),                    
    .C_RD_PNTR_WIDTH                     (C_RD_PNTR_WIDTH),               
    .C_UNDERFLOW_LOW                     (C_UNDERFLOW_LOW),               
    .C_USE_DOUT_RST                      (C_USE_DOUT_RST),                
    .C_USE_EMBEDDED_REG                  (C_USE_EMBEDDED_REG),            
    .C_USE_FWFT_DATA_COUNT               (C_USE_FWFT_DATA_COUNT),         
    .C_VALID_LOW                         (C_VALID_LOW),                   
    .C_WR_ACK_LOW                        (C_WR_ACK_LOW),                  
    .C_WR_DATA_COUNT_WIDTH               (C_WR_DATA_COUNT_WIDTH),         
    .C_WR_DEPTH                          (C_WR_DEPTH),                    
    .C_WR_PNTR_WIDTH                     (C_WR_PNTR_WIDTH),               
    .C_USE_ECC                           (C_USE_ECC),                     
    .C_ENABLE_RST_SYNC                   (C_ENABLE_RST_SYNC),             
    .C_ERROR_INJECTION_TYPE              (C_ERROR_INJECTION_TYPE),
    .C_FIFO_TYPE                         (C_FIFO_TYPE)                     
  )
  gen_ss
  (
    .CLK                      (CLK),
    .RST                      (rst_i),
    .SRST                     (srst_delayed),
    .RST_FULL_GEN             (rst_full_gen_i),
    .RST_FULL_FF              (rst_full_ff_i),
    .DIN                      (din_delayed),
    .WR_EN                    (wr_en_delayed),
    .RD_EN                    (RD_EN_FIFO_IN),
    .RD_EN_USER               (rd_en_delayed),
    .USER_EMPTY_FB            (empty_fb),
    .PROG_EMPTY_THRESH        (prog_empty_thresh_delayed),
    .PROG_EMPTY_THRESH_ASSERT (prog_empty_thresh_assert_delayed),
    .PROG_EMPTY_THRESH_NEGATE (prog_empty_thresh_negate_delayed),
    .PROG_FULL_THRESH         (prog_full_thresh_delayed),
    .PROG_FULL_THRESH_ASSERT  (prog_full_thresh_assert_delayed),
    .PROG_FULL_THRESH_NEGATE  (prog_full_thresh_negate_delayed),
    .INJECTSBITERR            (inject_sbit_err),
    .INJECTDBITERR            (inject_dbit_err),
    .DOUT                     (DOUT_FIFO_OUT),
    .FULL                     (FULL_FIFO_OUT),
    .ALMOST_FULL              (ALMOST_FULL_FIFO_OUT),
    .WR_ACK                   (WR_ACK_FIFO_OUT),
    .OVERFLOW                 (OVERFLOW_FIFO_OUT),
    .EMPTY                    (EMPTY_FIFO_OUT),
    .ALMOST_EMPTY             (ALMOST_EMPTY_FIFO_OUT),
    .VALID                    (VALID_FIFO_OUT),
    .UNDERFLOW                (UNDERFLOW_FIFO_OUT),
    .DATA_COUNT               (DATA_COUNT_FIFO_OUT),
    .RD_DATA_COUNT            (RD_DATA_COUNT_FIFO_OUT),
    .WR_DATA_COUNT            (WR_DATA_COUNT_FIFO_OUT),
    .PROG_FULL                (PROG_FULL_FIFO_OUT),
    .PROG_EMPTY               (PROG_EMPTY_FIFO_OUT),
    .WR_RST_BUSY              (wr_rst_busy),
    .RD_RST_BUSY              (rd_rst_busy),
    .SBITERR                  (sbiterr_fifo_out),
    .DBITERR                  (dbiterr_fifo_out)
   );
end
1 : begin : block1
  //Independent Clocks Behavioral Model
  fifo_generator_v12_0_bhv_ver_as
  #(
    .C_FAMILY                          (C_FAMILY),
    .C_DATA_COUNT_WIDTH                (C_DATA_COUNT_WIDTH),
    .C_DIN_WIDTH                       (C_DIN_WIDTH),
    .C_DOUT_RST_VAL                    (C_DOUT_RST_VAL),
    .C_DOUT_WIDTH                      (C_DOUT_WIDTH),
    .C_FULL_FLAGS_RST_VAL              (C_FULL_FLAGS_RST_VAL),
    .C_HAS_ALMOST_EMPTY                (C_HAS_ALMOST_EMPTY),
    .C_HAS_ALMOST_FULL                 (C_HAS_ALMOST_FULL),
    .C_HAS_DATA_COUNT                  (C_HAS_DATA_COUNT),
    .C_HAS_OVERFLOW                    (C_HAS_OVERFLOW),
    .C_HAS_RD_DATA_COUNT               (C_HAS_RD_DATA_COUNT),
    .C_HAS_RST                         (C_HAS_RST),
    .C_HAS_UNDERFLOW                   (C_HAS_UNDERFLOW),
    .C_HAS_VALID                       (C_HAS_VALID),
    .C_HAS_WR_ACK                      (C_HAS_WR_ACK),
    .C_HAS_WR_DATA_COUNT               (C_HAS_WR_DATA_COUNT),
    .C_IMPLEMENTATION_TYPE             (C_IMPLEMENTATION_TYPE),
    .C_MEMORY_TYPE                     (C_MEMORY_TYPE),
    .C_OVERFLOW_LOW                    (C_OVERFLOW_LOW),
    .C_PRELOAD_LATENCY                 (C_PRELOAD_LATENCY),
    .C_PRELOAD_REGS                    (C_PRELOAD_REGS),
    .C_PROG_EMPTY_THRESH_ASSERT_VAL    (C_PROG_EMPTY_THRESH_ASSERT_VAL),
    .C_PROG_EMPTY_THRESH_NEGATE_VAL    (C_PROG_EMPTY_THRESH_NEGATE_VAL),
    .C_PROG_EMPTY_TYPE                 (C_PROG_EMPTY_TYPE),
    .C_PROG_FULL_THRESH_ASSERT_VAL     (C_PROG_FULL_THRESH_ASSERT_VAL),
    .C_PROG_FULL_THRESH_NEGATE_VAL     (C_PROG_FULL_THRESH_NEGATE_VAL),
    .C_PROG_FULL_TYPE                  (C_PROG_FULL_TYPE),
    .C_RD_DATA_COUNT_WIDTH             (C_RD_DATA_COUNT_WIDTH),
    .C_RD_DEPTH                        (C_RD_DEPTH),
    .C_RD_PNTR_WIDTH                   (C_RD_PNTR_WIDTH),
    .C_UNDERFLOW_LOW                   (C_UNDERFLOW_LOW),
    .C_USE_DOUT_RST                    (C_USE_DOUT_RST),
    .C_USE_EMBEDDED_REG                (C_USE_EMBEDDED_REG),
    .C_USE_FWFT_DATA_COUNT             (C_USE_FWFT_DATA_COUNT),
    .C_VALID_LOW                       (C_VALID_LOW),
    .C_WR_ACK_LOW                      (C_WR_ACK_LOW),
    .C_WR_DATA_COUNT_WIDTH             (C_WR_DATA_COUNT_WIDTH),
    .C_WR_DEPTH                        (C_WR_DEPTH),
    .C_WR_PNTR_WIDTH                   (C_WR_PNTR_WIDTH),
    .C_USE_ECC                         (C_USE_ECC),
    .C_SYNCHRONIZER_STAGE              (C_SYNCHRONIZER_STAGE),
    .C_ENABLE_RST_SYNC                 (C_ENABLE_RST_SYNC),
    .C_ERROR_INJECTION_TYPE            (C_ERROR_INJECTION_TYPE)
  )
  gen_as
  (
    .WR_CLK                   (WR_CLK),
    .RD_CLK                   (RD_CLK),
    .RST                      (rst_i),
    .RST_FULL_GEN             (rst_full_gen_i),
    .RST_FULL_FF              (rst_full_ff_i),
    .WR_RST                   (wr_rst_i),
    .RD_RST                   (rd_rst_i),
    .DIN                      (din_delayed),
    .WR_EN                    (wr_en_delayed),
    .RD_EN                    (RD_EN_FIFO_IN),
    .RD_EN_USER               (rd_en_delayed),
    .PROG_EMPTY_THRESH        (prog_empty_thresh_delayed),
    .PROG_EMPTY_THRESH_ASSERT (prog_empty_thresh_assert_delayed),
    .PROG_EMPTY_THRESH_NEGATE (prog_empty_thresh_negate_delayed),
    .PROG_FULL_THRESH         (prog_full_thresh_delayed),
    .PROG_FULL_THRESH_ASSERT  (prog_full_thresh_assert_delayed),
    .PROG_FULL_THRESH_NEGATE  (prog_full_thresh_negate_delayed),
    .INJECTSBITERR            (inject_sbit_err),
    .INJECTDBITERR            (inject_dbit_err),
    .USER_EMPTY_FB            (EMPTY_P0_OUT),
    .DOUT                     (DOUT_FIFO_OUT),
    .FULL                     (FULL_FIFO_OUT),
    .ALMOST_FULL              (ALMOST_FULL_FIFO_OUT),
    .WR_ACK                   (WR_ACK_FIFO_OUT),
    .OVERFLOW                 (OVERFLOW_FIFO_OUT),
    .EMPTY                    (EMPTY_FIFO_OUT),
    .ALMOST_EMPTY             (ALMOST_EMPTY_FIFO_OUT),
    .VALID                    (VALID_FIFO_OUT),
    .UNDERFLOW                (UNDERFLOW_FIFO_OUT),
    .RD_DATA_COUNT            (RD_DATA_COUNT_FIFO_OUT),
    .WR_DATA_COUNT            (WR_DATA_COUNT_FIFO_OUT),
    .PROG_FULL                (PROG_FULL_FIFO_OUT),
    .PROG_EMPTY               (PROG_EMPTY_FIFO_OUT),
    .SBITERR                  (sbiterr_fifo_out),
    .DBITERR                  (dbiterr_fifo_out)
   );
end

2 : begin : ll_afifo_inst
  fifo_generator_v12_0_beh_ver_ll_afifo
  #(
    .C_DIN_WIDTH                    (C_DIN_WIDTH),
    .C_DOUT_RST_VAL                 (C_DOUT_RST_VAL),
    .C_DOUT_WIDTH                   (C_DOUT_WIDTH),
    .C_FULL_FLAGS_RST_VAL           (C_FULL_FLAGS_RST_VAL),
    .C_HAS_RD_DATA_COUNT            (C_HAS_RD_DATA_COUNT),
    .C_HAS_WR_DATA_COUNT            (C_HAS_WR_DATA_COUNT),
    .C_RD_DEPTH                     (C_RD_DEPTH),
    .C_RD_PNTR_WIDTH                (C_RD_PNTR_WIDTH),
    .C_USE_DOUT_RST                 (C_USE_DOUT_RST),
    .C_WR_DATA_COUNT_WIDTH          (C_WR_DATA_COUNT_WIDTH),
    .C_WR_DEPTH                     (C_WR_DEPTH),
    .C_WR_PNTR_WIDTH                (C_WR_PNTR_WIDTH),
    .C_FIFO_TYPE                    (C_FIFO_TYPE)
   )
  gen_ll_afifo
  (
    .DIN                        (din_delayed),
    .RD_CLK                     (RD_CLK),
    .RD_EN                      (rd_en_delayed),
    .WR_RST                     (wr_rst_i),
    .RD_RST                     (rd_rst_i),
    .WR_CLK                     (WR_CLK),
    .WR_EN                      (wr_en_delayed),
    .DOUT                       (DOUT),
    .EMPTY                      (EMPTY),
    .FULL                       (FULL)
  );
end
default : begin : block1
  //Independent Clocks Behavioral Model
  fifo_generator_v12_0_bhv_ver_as
  #(
    .C_FAMILY                          (C_FAMILY),
    .C_DATA_COUNT_WIDTH                (C_DATA_COUNT_WIDTH),
    .C_DIN_WIDTH                       (C_DIN_WIDTH),
    .C_DOUT_RST_VAL                    (C_DOUT_RST_VAL),
    .C_DOUT_WIDTH                      (C_DOUT_WIDTH),
    .C_FULL_FLAGS_RST_VAL              (C_FULL_FLAGS_RST_VAL),
    .C_HAS_ALMOST_EMPTY                (C_HAS_ALMOST_EMPTY),
    .C_HAS_ALMOST_FULL                 (C_HAS_ALMOST_FULL),
    .C_HAS_DATA_COUNT                  (C_HAS_DATA_COUNT),
    .C_HAS_OVERFLOW                    (C_HAS_OVERFLOW),
    .C_HAS_RD_DATA_COUNT               (C_HAS_RD_DATA_COUNT),
    .C_HAS_RST                         (C_HAS_RST),
    .C_HAS_UNDERFLOW                   (C_HAS_UNDERFLOW),
    .C_HAS_VALID                       (C_HAS_VALID),
    .C_HAS_WR_ACK                      (C_HAS_WR_ACK),
    .C_HAS_WR_DATA_COUNT               (C_HAS_WR_DATA_COUNT),
    .C_IMPLEMENTATION_TYPE             (C_IMPLEMENTATION_TYPE),
    .C_MEMORY_TYPE                     (C_MEMORY_TYPE),
    .C_OVERFLOW_LOW                    (C_OVERFLOW_LOW),
    .C_PRELOAD_LATENCY                 (C_PRELOAD_LATENCY),
    .C_PRELOAD_REGS                    (C_PRELOAD_REGS),
    .C_PROG_EMPTY_THRESH_ASSERT_VAL    (C_PROG_EMPTY_THRESH_ASSERT_VAL),
    .C_PROG_EMPTY_THRESH_NEGATE_VAL    (C_PROG_EMPTY_THRESH_NEGATE_VAL),
    .C_PROG_EMPTY_TYPE                 (C_PROG_EMPTY_TYPE),
    .C_PROG_FULL_THRESH_ASSERT_VAL     (C_PROG_FULL_THRESH_ASSERT_VAL),
    .C_PROG_FULL_THRESH_NEGATE_VAL     (C_PROG_FULL_THRESH_NEGATE_VAL),
    .C_PROG_FULL_TYPE                  (C_PROG_FULL_TYPE),
    .C_RD_DATA_COUNT_WIDTH             (C_RD_DATA_COUNT_WIDTH),
    .C_RD_DEPTH                        (C_RD_DEPTH),
    .C_RD_PNTR_WIDTH                   (C_RD_PNTR_WIDTH),
    .C_UNDERFLOW_LOW                   (C_UNDERFLOW_LOW),
    .C_USE_DOUT_RST                    (C_USE_DOUT_RST),
    .C_USE_EMBEDDED_REG                (C_USE_EMBEDDED_REG),
    .C_USE_FWFT_DATA_COUNT             (C_USE_FWFT_DATA_COUNT),
    .C_VALID_LOW                       (C_VALID_LOW),
    .C_WR_ACK_LOW                      (C_WR_ACK_LOW),
    .C_WR_DATA_COUNT_WIDTH             (C_WR_DATA_COUNT_WIDTH),
    .C_WR_DEPTH                        (C_WR_DEPTH),
    .C_WR_PNTR_WIDTH                   (C_WR_PNTR_WIDTH),
    .C_USE_ECC                         (C_USE_ECC),
    .C_SYNCHRONIZER_STAGE              (C_SYNCHRONIZER_STAGE),
    .C_ENABLE_RST_SYNC                 (C_ENABLE_RST_SYNC),
    .C_ERROR_INJECTION_TYPE            (C_ERROR_INJECTION_TYPE)
  )
  gen_as
  (
    .WR_CLK                   (WR_CLK),
    .RD_CLK                   (RD_CLK),
    .RST                      (rst_i),
    .RST_FULL_GEN             (rst_full_gen_i),
    .RST_FULL_FF              (rst_full_ff_i),
    .WR_RST                   (wr_rst_i),
    .RD_RST                   (rd_rst_i),
    .DIN                      (din_delayed),
    .WR_EN                    (wr_en_delayed),
    .RD_EN                    (RD_EN_FIFO_IN),
    .RD_EN_USER               (rd_en_delayed),
    .PROG_EMPTY_THRESH        (prog_empty_thresh_delayed),
    .PROG_EMPTY_THRESH_ASSERT (prog_empty_thresh_assert_delayed),
    .PROG_EMPTY_THRESH_NEGATE (prog_empty_thresh_negate_delayed),
    .PROG_FULL_THRESH         (prog_full_thresh_delayed),
    .PROG_FULL_THRESH_ASSERT  (prog_full_thresh_assert_delayed),
    .PROG_FULL_THRESH_NEGATE  (prog_full_thresh_negate_delayed),
    .INJECTSBITERR            (inject_sbit_err),
    .INJECTDBITERR            (inject_dbit_err),
    .USER_EMPTY_FB            (EMPTY_P0_OUT),
    .DOUT                     (DOUT_FIFO_OUT),
    .FULL                     (FULL_FIFO_OUT),
    .ALMOST_FULL              (ALMOST_FULL_FIFO_OUT),
    .WR_ACK                   (WR_ACK_FIFO_OUT),
    .OVERFLOW                 (OVERFLOW_FIFO_OUT),
    .EMPTY                    (EMPTY_FIFO_OUT),
    .ALMOST_EMPTY             (ALMOST_EMPTY_FIFO_OUT),
    .VALID                    (VALID_FIFO_OUT),
    .UNDERFLOW                (UNDERFLOW_FIFO_OUT),
    .RD_DATA_COUNT            (RD_DATA_COUNT_FIFO_OUT),
    .WR_DATA_COUNT            (WR_DATA_COUNT_FIFO_OUT),
    .PROG_FULL                (PROG_FULL_FIFO_OUT),
    .PROG_EMPTY               (PROG_EMPTY_FIFO_OUT),
    .SBITERR                  (sbiterr_fifo_out),
    .DBITERR                  (dbiterr_fifo_out)
   );
end

endcase
endgenerate


   //**************************************************************************
   // Connect Internal Signals
   //   (Signals labeled internal_*)
   //  In the normal case, these signals tie directly to the FIFO's inputs and
   //    outputs.
   //  In the case of Preload Latency 0 or 1, there are intermediate
   //    signals between the internal FIFO and the preload logic.
   //**************************************************************************
   
   
   //***********************************************
   // If First-Word Fall-Through, instantiate
   // the preload0 (FWFT) module
   //***********************************************
   wire                        rd_en_to_fwft_fifo;
   wire                        sbiterr_fwft;
   wire                        dbiterr_fwft;
   wire [C_DOUT_WIDTH-1:0]     dout_fwft;
   wire                        empty_fwft;
   wire                        rd_en_fifo_in;
   wire                        stage2_reg_en_i;
   wire [1:0]                  valid_stages_i;
   wire                        rst_fwft;
   //wire                        empty_p0_out;
   reg  [C_SYNCHRONIZER_STAGE-1:0] pkt_empty_sync = 'b1;

   localparam IS_FWFT          = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ? 1 : 0;
   localparam IS_PKT_FIFO      = (C_FIFO_TYPE == 1) ? 1 : 0;
   localparam IS_AXIS_PKT_FIFO = (C_FIFO_TYPE == 1 && C_AXI_TYPE == 0) ? 1 : 0;
   assign rst_fwft = (C_COMMON_CLOCK == 0) ? rd_rst_i : (C_HAS_RST == 1) ? rst_i : 1'b0;

   generate if (IS_FWFT == 1 && C_FIFO_TYPE != 3) begin : block2


         fifo_generator_v12_0_bhv_ver_preload0
           #(
             .C_DOUT_RST_VAL      (C_DOUT_RST_VAL),
             .C_DOUT_WIDTH        (C_DOUT_WIDTH),
             .C_HAS_RST           (C_HAS_RST),
             .C_ENABLE_RST_SYNC   (C_ENABLE_RST_SYNC),
             .C_HAS_SRST          (C_HAS_SRST),
             .C_USE_DOUT_RST      (C_USE_DOUT_RST),
             .C_USE_ECC           (C_USE_ECC),
             .C_USERVALID_LOW     (C_VALID_LOW),
             .C_USERUNDERFLOW_LOW (C_UNDERFLOW_LOW),
             .C_MEMORY_TYPE       (C_MEMORY_TYPE),
             .C_FIFO_TYPE         (C_FIFO_TYPE)
             )
             fgpl0
               (
                .RD_CLK           (RD_CLK_P0_IN),
                .RD_RST           (RST_P0_IN),
                .SRST             (srst_delayed),
                .WR_RST_BUSY      (wr_rst_busy),
                .RD_RST_BUSY      (rd_rst_busy),
                .RD_EN            (RD_EN_P0_IN),
                .FIFOEMPTY        (EMPTY_P0_IN),
                .FIFODATA         (DATA_P0_IN),
                .FIFOSBITERR      (sbiterr_fifo_out),
                .FIFODBITERR      (dbiterr_fifo_out),
                // Output
                .USERDATA         (dout_fwft),
                .USERVALID        (VALID_P0_OUT),
                .USEREMPTY        (empty_fwft),
                .USERALMOSTEMPTY  (ALMOSTEMPTY_P0_OUT),
                .USERUNDERFLOW    (UNDERFLOW_P0_OUT),
                .RAMVALID         (),
                .FIFORDEN         (rd_en_fifo_in),
                .USERSBITERR      (sbiterr_fwft),
                .USERDBITERR      (dbiterr_fwft),
                .STAGE2_REG_EN    (stage2_reg_en_i),
                .VALID_STAGES     (valid_stages_i)
                );

         
         //***********************************************
         // Connect inputs to preload (FWFT) module
         //***********************************************
         //Connect the RD_CLK of the Preload (FWFT) module to CLK if we 
         // have a common-clock FIFO, or RD_CLK if we have an 
         // independent clock FIFO
         assign RD_CLK_P0_IN       = ((C_VERILOG_IMPL == 0) ? CLK : RD_CLK);
         assign RST_P0_IN          = (C_COMMON_CLOCK == 0) ? rd_rst_i : (C_HAS_RST == 1) ? rst_i : 0;
         assign RD_EN_P0_IN        = (C_FIFO_TYPE != 1) ? rd_en_delayed : rd_en_to_fwft_fifo;
         assign EMPTY_P0_IN        = EMPTY_FIFO_OUT;
         assign DATA_P0_IN         = DOUT_FIFO_OUT;
         
         //***********************************************
         // Connect outputs from preload (FWFT) module
         //***********************************************
         assign VALID              = VALID_P0_OUT ;
         assign ALMOST_EMPTY       = ALMOSTEMPTY_P0_OUT;
         assign UNDERFLOW          = UNDERFLOW_P0_OUT ;
         
         assign RD_EN_FIFO_IN      = rd_en_fifo_in;
         
         
         //***********************************************
         // Create DATA_COUNT from First-Word Fall-Through
         // data count
         //***********************************************
         assign DATA_COUNT = (C_USE_FWFT_DATA_COUNT == 0)? DATA_COUNT_FIFO_OUT:
           (C_DATA_COUNT_WIDTH>C_RD_PNTR_WIDTH) ? DATA_COUNT_FWFT[C_RD_PNTR_WIDTH:0] : 
           DATA_COUNT_FWFT[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH-C_DATA_COUNT_WIDTH+1];  
         
         //***********************************************
         // Create DATA_COUNT from First-Word Fall-Through
         // data count
         //***********************************************
         always @ (posedge RD_CLK_P0_IN or posedge RST_P0_IN) begin
            if (RST_P0_IN) begin
               EMPTY_P0_OUT_Q       <= #`TCQ 1;
               ALMOSTEMPTY_P0_OUT_Q <= #`TCQ 1;
            end else begin
               EMPTY_P0_OUT_Q       <= #`TCQ empty_p0_out;
//               EMPTY_P0_OUT_Q       <= #`TCQ EMPTY_FIFO_OUT;
               ALMOSTEMPTY_P0_OUT_Q <= #`TCQ ALMOSTEMPTY_P0_OUT;
            end
         end //always
         
         
         //***********************************************
         // logic for common-clock data count when FWFT is selected
         //***********************************************
         initial begin
            SS_FWFT_RD = 1'b0;
            DATA_COUNT_FWFT = 0 ;
            SS_FWFT_WR   = 1'b0 ;
         end //initial
         
         
         //***********************************************
         // common-clock data count is implemented as an
         // up-down counter. SS_FWFT_WR and SS_FWFT_RD
         // are the up/down enables for the counter.
         //***********************************************
         always @ (RD_EN or VALID_P0_OUT or WR_EN or FULL_FIFO_OUT or empty_p0_out) begin
            if (C_VALID_LOW == 1) begin
              SS_FWFT_RD = (C_FIFO_TYPE != 1) ? (RD_EN && ~VALID_P0_OUT) : (~empty_p0_out && RD_EN && ~VALID_P0_OUT) ;
            end else begin
              SS_FWFT_RD = (C_FIFO_TYPE != 1) ? (RD_EN && VALID_P0_OUT) : (~empty_p0_out && RD_EN && VALID_P0_OUT) ;
            end
            SS_FWFT_WR = (WR_EN && (~FULL_FIFO_OUT))  ;
         end 

         //***********************************************
         // common-clock data count is implemented as an
         // up-down counter for FWFT. This always block 
         // calculates the counter.
         //***********************************************
         always @ (posedge RD_CLK_P0_IN or posedge RST_P0_IN) begin
            if (RST_P0_IN) begin
               DATA_COUNT_FWFT      <= #`TCQ 0;
            end else begin
               //if (srst_delayed && (C_HAS_SRST == 1) ) begin
               if ((srst_delayed | wr_rst_busy | rd_rst_busy) && (C_HAS_SRST == 1) ) begin
                  DATA_COUNT_FWFT      <= #`TCQ 0;
               end else begin
                  case ( {SS_FWFT_WR, SS_FWFT_RD})
                    2'b00: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT ;
                    2'b01: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT - 1 ;
                    2'b10: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT + 1 ;
                    2'b11: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT ;
                  endcase  
               end //if SRST
            end //IF RST
         end //always

      end endgenerate // : block2

    // AXI Streaming Packet FIFO
    reg  [C_WR_PNTR_WIDTH-1:0]  wr_pkt_count       = 0;
    reg  [C_RD_PNTR_WIDTH-1:0]  rd_pkt_count       = 0;
    reg  [C_RD_PNTR_WIDTH-1:0]  rd_pkt_count_plus1 = 0;
    reg  [C_RD_PNTR_WIDTH-1:0]  rd_pkt_count_reg   = 0;
    reg                         partial_packet     = 0;
    reg                         stage1_eop_d1      = 0;
    reg                         rd_en_fifo_in_d1   = 0;
    reg                         eop_at_stage2      = 0;
    reg                         ram_pkt_empty      = 0;
    reg                         ram_pkt_empty_d1   = 0;

    wire [C_DOUT_WIDTH-1:0]     dout_p0_out;
    wire                        packet_empty_wr;
    wire                        wr_rst_fwft_pkt_fifo;
    wire                        dummy_wr_eop;
    wire                        ram_wr_en_pkt_fifo;
    wire                        wr_eop;
    wire                        ram_rd_en_compare;
    wire                        stage1_eop;
    wire                        pkt_ready_to_read;
    wire                        rd_en_2_stage2;

    // Generate Dummy WR_EOP for partial packet (Only for AXI Streaming)
    // When Packet EMPTY is high, and FIFO is full, then generate the dummy WR_EOP
    // When dummy WR_EOP is high, mask the actual EOP to avoid double increment of
    // write packet count
    generate if (IS_FWFT == 1 && IS_AXIS_PKT_FIFO == 1) begin // gdummy_wr_eop
       always @ (posedge wr_rst_fwft_pkt_fifo or posedge WR_CLK) begin 
          if (wr_rst_fwft_pkt_fifo)
             partial_packet   <= 1'b0;
          else begin
             if (srst_delayed | wr_rst_busy | rd_rst_busy)
                partial_packet <= #`TCQ 1'b0;
             else if (ALMOST_FULL_FIFO_OUT && ram_wr_en_pkt_fifo && packet_empty_wr && (~din_delayed[0]))
                partial_packet <= #`TCQ 1'b1;
             else if (partial_packet && din_delayed[0] && ram_wr_en_pkt_fifo)
                partial_packet <= #`TCQ 1'b0;
          end
        end
    end endgenerate // gdummy_wr_eop

    generate if (IS_FWFT == 1 && IS_PKT_FIFO == 1) begin // gpkt_fifo_fwft
      assign wr_rst_fwft_pkt_fifo = (C_COMMON_CLOCK == 0) ? wr_rst_i : (C_HAS_RST == 1) ? rst_i:1'b0;
      assign dummy_wr_eop = ALMOST_FULL_FIFO_OUT && ram_wr_en_pkt_fifo && packet_empty_wr && (~din_delayed[0]) && (~partial_packet);
      assign packet_empty_wr = (C_COMMON_CLOCK == 1) ? empty_p0_out : pkt_empty_sync[C_SYNCHRONIZER_STAGE-1];
  
      always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin 
        if (rst_fwft) begin
          stage1_eop_d1    <= 1'b0;
          rd_en_fifo_in_d1 <= 1'b0;
        end else begin
          if (srst_delayed | wr_rst_busy | rd_rst_busy) begin
            stage1_eop_d1    <= #`TCQ 1'b0;
            rd_en_fifo_in_d1 <= #`TCQ 1'b0;
          end else begin
            stage1_eop_d1    <= #`TCQ stage1_eop;
            rd_en_fifo_in_d1 <= #`TCQ rd_en_fifo_in;
          end
        end
      end
      assign stage1_eop = (rd_en_fifo_in_d1) ? DOUT_FIFO_OUT[0] : stage1_eop_d1;
      assign ram_wr_en_pkt_fifo = wr_en_delayed && (~FULL_FIFO_OUT);
      assign wr_eop = ram_wr_en_pkt_fifo && ((din_delayed[0] && (~partial_packet)) || dummy_wr_eop);
      assign ram_rd_en_compare = stage2_reg_en_i && stage1_eop;


         fifo_generator_v12_0_bhv_ver_preload0
           #(
             .C_DOUT_RST_VAL      (C_DOUT_RST_VAL),
             .C_DOUT_WIDTH        (C_DOUT_WIDTH),
             .C_HAS_RST           (C_HAS_RST),
             .C_HAS_SRST          (C_HAS_SRST),
             .C_USE_DOUT_RST      (C_USE_DOUT_RST),
             .C_USE_ECC           (C_USE_ECC),
             .C_USERVALID_LOW     (C_VALID_LOW),
             .C_USERUNDERFLOW_LOW (C_UNDERFLOW_LOW),
             .C_ENABLE_RST_SYNC   (C_ENABLE_RST_SYNC),
             .C_MEMORY_TYPE       (C_MEMORY_TYPE),
             .C_FIFO_TYPE         (2) // Enable low latency fwft logic
             )
         pkt_fifo_fwft
               (
                .RD_CLK           (RD_CLK_P0_IN),
                .RD_RST           (rst_fwft),
                .SRST             (srst_delayed),
                .WR_RST_BUSY      (wr_rst_busy),
                .RD_RST_BUSY      (rd_rst_busy),
                .RD_EN            (rd_en_delayed),
                .FIFOEMPTY        (pkt_ready_to_read),
                .FIFODATA         (dout_fwft),
                .FIFOSBITERR      (sbiterr_fwft),
                .FIFODBITERR      (dbiterr_fwft),
                // Output
                .USERDATA         (dout_p0_out),
                .USERVALID        (),
                .USEREMPTY        (empty_p0_out),
                .USERALMOSTEMPTY  (),
                .USERUNDERFLOW    (),
                .RAMVALID         (),
                .FIFORDEN         (rd_en_2_stage2),
                .USERSBITERR      (SBITERR),
                .USERDBITERR      (DBITERR),
                .STAGE2_REG_EN    (),
                .VALID_STAGES     ()
                );

      assign pkt_ready_to_read  = ~(!(ram_pkt_empty || empty_fwft) && ((valid_stages_i[0] && valid_stages_i[1]) || eop_at_stage2));
      assign rd_en_to_fwft_fifo = ~empty_fwft && rd_en_2_stage2;

      always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin 
        if (rst_fwft)
          eop_at_stage2 <= 1'b0;
        else if (stage2_reg_en_i)
          eop_at_stage2 <= #`TCQ stage1_eop;
      end

      //---------------------------------------------------------------------------
      // Write and Read Packet Count
      //---------------------------------------------------------------------------
      always @ (posedge wr_rst_fwft_pkt_fifo or posedge WR_CLK) begin 
         if (wr_rst_fwft_pkt_fifo)
            wr_pkt_count  <= 0;
         else if (srst_delayed  | wr_rst_busy | rd_rst_busy)
            wr_pkt_count  <= #`TCQ 0;
         else if (wr_eop)
            wr_pkt_count  <= #`TCQ wr_pkt_count + 1;
      end
    
    end endgenerate // gpkt_fifo_fwft

    assign DOUT               = (C_FIFO_TYPE != 1) ? dout_fwft : dout_p0_out;
    assign EMPTY              = (C_FIFO_TYPE != 1) ? empty_fwft : empty_p0_out;

    generate if (IS_FWFT == 1 && IS_PKT_FIFO == 1 && C_COMMON_CLOCK == 1) begin // grss_pkt_cnt
      always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin 
         if (rst_fwft) begin
            rd_pkt_count       <= 0;
            rd_pkt_count_plus1 <= 1;
         end else if (srst_delayed | wr_rst_busy | rd_rst_busy) begin
            rd_pkt_count       <= #`TCQ 0;
            rd_pkt_count_plus1 <= #`TCQ 1;
         end else if (stage2_reg_en_i && stage1_eop) begin
            rd_pkt_count       <= #`TCQ rd_pkt_count + 1;
            rd_pkt_count_plus1 <= #`TCQ rd_pkt_count_plus1 + 1;
         end
      end

      always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin 
         if (rst_fwft) begin
            ram_pkt_empty    <= 1'b1;
            ram_pkt_empty_d1 <= 1'b1;
         end else if (SRST | wr_rst_busy | rd_rst_busy) begin
            ram_pkt_empty    <= #`TCQ 1'b1;
            ram_pkt_empty_d1 <= #`TCQ 1'b1;
         end else if ((rd_pkt_count == wr_pkt_count) && wr_eop) begin
            ram_pkt_empty    <= #`TCQ 1'b0;
            ram_pkt_empty_d1 <= #`TCQ 1'b0;
         end else if (ram_pkt_empty_d1 && rd_en_to_fwft_fifo) begin
            ram_pkt_empty    <= #`TCQ 1'b1;
         end else if ((rd_pkt_count_plus1 == wr_pkt_count) && ~wr_eop && ~ALMOST_FULL_FIFO_OUT && ram_rd_en_compare) begin
            ram_pkt_empty_d1 <= #`TCQ 1'b1;
         end
      end
    end endgenerate //grss_pkt_cnt
    
    localparam SYNC_STAGE_WIDTH = (C_SYNCHRONIZER_STAGE+1)*C_WR_PNTR_WIDTH;
    reg  [SYNC_STAGE_WIDTH-1:0] wr_pkt_count_q = 0;
    reg  [C_WR_PNTR_WIDTH-1:0]  wr_pkt_count_b2g = 0;
    wire [C_WR_PNTR_WIDTH-1:0]  wr_pkt_count_rd;
    generate if (IS_FWFT == 1 && IS_PKT_FIFO == 1 && C_COMMON_CLOCK == 0) begin // gras_pkt_cnt
      // Delay the write packet count in write clock domain to accomodate the binary to gray conversion delay
      always @ (posedge wr_rst_fwft_pkt_fifo or posedge WR_CLK) begin
         if (wr_rst_fwft_pkt_fifo)
            wr_pkt_count_b2g  <= 0;
         else
            wr_pkt_count_b2g  <= #`TCQ wr_pkt_count;
      end

      // Synchronize the delayed write packet count in read domain, and also compensate the gray to binay conversion delay
      always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin 
         if (rst_fwft)
            wr_pkt_count_q       <= 0;
         else
            wr_pkt_count_q       <= #`TCQ {wr_pkt_count_q[SYNC_STAGE_WIDTH-C_WR_PNTR_WIDTH-1:0],wr_pkt_count_b2g};
      end

      always @* begin
        if (stage1_eop)
           rd_pkt_count    <= rd_pkt_count_reg + 1;
        else
           rd_pkt_count    <= rd_pkt_count_reg;
      end

      assign wr_pkt_count_rd    = wr_pkt_count_q[SYNC_STAGE_WIDTH-1:SYNC_STAGE_WIDTH-C_WR_PNTR_WIDTH];

      always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin 
         if (rst_fwft)
            rd_pkt_count_reg       <= 0;
         else if (rd_en_fifo_in)
            rd_pkt_count_reg       <= #`TCQ rd_pkt_count;
      end

      always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin 
         if (rst_fwft) begin
            ram_pkt_empty    <= 1'b1;
            ram_pkt_empty_d1 <= 1'b1;
         end else if (rd_pkt_count != wr_pkt_count_rd) begin
            ram_pkt_empty    <= #`TCQ 1'b0;
            ram_pkt_empty_d1 <= #`TCQ 1'b0;
         end else if (ram_pkt_empty_d1 && rd_en_to_fwft_fifo) begin
            ram_pkt_empty    <= #`TCQ 1'b1;
         end else if ((rd_pkt_count == wr_pkt_count_rd) && stage2_reg_en_i) begin
            ram_pkt_empty_d1 <= #`TCQ 1'b1;
         end
      end

      // Synchronize the empty in write domain
      always @ (posedge wr_rst_fwft_pkt_fifo or posedge WR_CLK) begin
         if (wr_rst_fwft_pkt_fifo)
            pkt_empty_sync  <= 'b1;
         else
            pkt_empty_sync  <= #`TCQ {pkt_empty_sync[C_SYNCHRONIZER_STAGE-2:0], empty_p0_out};
      end

    end endgenerate //gras_pkt_cnt

   generate if (IS_FWFT == 0 || C_FIFO_TYPE == 3) begin : STD_FIFO

     //***********************************************
     // If NOT First-Word Fall-Through, wire the outputs
     // of the internal _ss or _as FIFO directly to the
     // output, and do not instantiate the preload0
     // module.
     //***********************************************

     assign RD_CLK_P0_IN       = 0;
     assign RST_P0_IN          = 0;
     assign RD_EN_P0_IN        = 0;

     assign RD_EN_FIFO_IN      = rd_en_delayed;

     assign DOUT               = DOUT_FIFO_OUT;
     assign DATA_P0_IN         = 0;
     assign VALID              = VALID_FIFO_OUT;
     assign EMPTY              = EMPTY_FIFO_OUT;
     assign ALMOST_EMPTY       = ALMOST_EMPTY_FIFO_OUT;
     assign EMPTY_P0_IN        = 0;
     assign UNDERFLOW          = UNDERFLOW_FIFO_OUT;
     assign DATA_COUNT         = DATA_COUNT_FIFO_OUT;
     assign SBITERR            = sbiterr_fifo_out;
     assign DBITERR            = dbiterr_fifo_out;

   end endgenerate // STD_FIFO

   generate if (IS_FWFT == 1 && C_FIFO_TYPE != 1) begin : NO_PKT_FIFO
     assign empty_p0_out       = empty_fwft;
     assign SBITERR            = sbiterr_fwft;
     assign DBITERR            = dbiterr_fwft;
     assign DOUT               = dout_fwft;
     assign RD_EN_P0_IN        = (C_FIFO_TYPE != 1) ? rd_en_delayed : rd_en_to_fwft_fifo;

   end endgenerate // NO_PKT_FIFO

   //***********************************************
   // Connect user flags to internal signals
   //***********************************************
   
   //If we are using extra logic for the FWFT data count, then override the
   //RD_DATA_COUNT output when we are EMPTY or ALMOST_EMPTY.
   //RD_DATA_COUNT is 0 when EMPTY and 1 when ALMOST_EMPTY.
   generate
      if (C_USE_FWFT_DATA_COUNT==1 && (C_RD_DATA_COUNT_WIDTH>C_RD_PNTR_WIDTH) ) begin : block3
      if (C_COMMON_CLOCK == 0) begin : block_ic
         assign RD_DATA_COUNT = (EMPTY_P0_OUT_Q | RST_P0_IN) ? 0 : (ALMOSTEMPTY_P0_OUT_Q ? 1 : RD_DATA_COUNT_FIFO_OUT);
      end //block_ic
      else begin
         assign RD_DATA_COUNT = RD_DATA_COUNT_FIFO_OUT;
      end 
      end //block3
   endgenerate
   
   //If we are using extra logic for the FWFT data count, then override the
   //RD_DATA_COUNT output when we are EMPTY or ALMOST_EMPTY.
   //Due to asymmetric ports, RD_DATA_COUNT is 0 when EMPTY or ALMOST_EMPTY.
   generate
      if (C_USE_FWFT_DATA_COUNT==1 && (C_RD_DATA_COUNT_WIDTH <=C_RD_PNTR_WIDTH) ) begin : block30
       if (C_COMMON_CLOCK == 0) begin : block_ic
         assign RD_DATA_COUNT = (EMPTY_P0_OUT_Q | RST_P0_IN) ? 0 : (ALMOSTEMPTY_P0_OUT_Q ? 0 : RD_DATA_COUNT_FIFO_OUT);
       end 
       else begin
         assign RD_DATA_COUNT = RD_DATA_COUNT_FIFO_OUT;
        end 
      end //block30
   endgenerate

   //If we are not using extra logic for the FWFT data count,
   //then connect RD_DATA_COUNT to the RD_DATA_COUNT from the
   //internal FIFO instance  
   generate
      if (C_USE_FWFT_DATA_COUNT==0 ) begin : block31
         assign RD_DATA_COUNT = RD_DATA_COUNT_FIFO_OUT;
      end
   endgenerate

   //Always connect WR_DATA_COUNT to the WR_DATA_COUNT from the internal
   //FIFO instance
   generate
      if (C_USE_FWFT_DATA_COUNT==1) begin : block4
         assign WR_DATA_COUNT = WR_DATA_COUNT_FIFO_OUT;
      end
      else begin : block4
         assign WR_DATA_COUNT = WR_DATA_COUNT_FIFO_OUT;
      end
   endgenerate


   //Connect other flags to the internal FIFO instance
   assign       FULL        = FULL_FIFO_OUT;
   assign       ALMOST_FULL = ALMOST_FULL_FIFO_OUT;
   assign       WR_ACK      = WR_ACK_FIFO_OUT;
   assign       OVERFLOW    = OVERFLOW_FIFO_OUT;
   assign       PROG_FULL   = PROG_FULL_FIFO_OUT;
   assign       PROG_EMPTY  = PROG_EMPTY_FIFO_OUT;


  /**************************************************************************
  * find_log2
  *   Returns the 'log2' value for the input value for the supported ratios
  ***************************************************************************/
  function integer find_log2;
    input integer int_val;
    integer i,j;
    begin
      i = 1;
      j = 0;
      for (i = 1; i < int_val; i = i*2) begin
        j = j + 1;
      end
      find_log2 = j;
    end
  endfunction

  
  /**************************************************************************
  * Internal reset logic
  **************************************************************************/
  assign wr_rst_i         = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? wr_rst_reg : 0;
  assign rd_rst_i         = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? rd_rst_reg : 0;
  assign rst_i            = C_HAS_RST ? rst_reg : 0;

  wire rst_2_sync;
  wire clk_2_sync = (C_COMMON_CLOCK == 1) ? CLK : WR_CLK;
  generate
      if (C_ENABLE_RST_SYNC == 0) begin : gnrst_sync
        always @* begin
          wr_rst_reg <= wr_rst_delayed;
          rd_rst_reg <= rd_rst_delayed;
          rst_reg    <= 1'b0;
          srst_reg    <= 1'b0;
        end
        assign rst_2_sync = wr_rst_delayed;
        assign wr_rst_busy = 1'b0;
        assign rd_rst_busy = 1'b0;
      end else if (C_HAS_RST == 1 && C_COMMON_CLOCK == 0) begin : g7s_ic_rst
        assign wr_rst_comb      = !wr_rst_asreg_d2 && wr_rst_asreg;
        assign rd_rst_comb      = !rd_rst_asreg_d2 && rd_rst_asreg;
        assign rst_2_sync = rst_delayed;
        assign wr_rst_busy = 1'b0;
        assign rd_rst_busy = 1'b0;

        always @(posedge WR_CLK or posedge rst_delayed) begin
          if (rst_delayed == 1'b1) begin
            wr_rst_asreg <= #`TCQ 1'b1;
          end else begin
            if (wr_rst_asreg_d1 == 1'b1) begin
              wr_rst_asreg <= #`TCQ 1'b0;
            end else begin
              wr_rst_asreg <= #`TCQ wr_rst_asreg;
            end
          end    
        end   
      
        always @(posedge WR_CLK) begin
          wr_rst_asreg_d1 <= #`TCQ wr_rst_asreg;
          wr_rst_asreg_d2 <= #`TCQ wr_rst_asreg_d1;
        end
        
        always @(posedge WR_CLK or posedge wr_rst_comb) begin
          if (wr_rst_comb == 1'b1) begin
            wr_rst_reg <= #`TCQ 1'b1;
          end else begin
            wr_rst_reg <= #`TCQ 1'b0;
          end    
        end   
        
        always @(posedge RD_CLK or posedge rst_delayed) begin
          if (rst_delayed == 1'b1) begin
            rd_rst_asreg <= #`TCQ 1'b1;
          end else begin
            if (rd_rst_asreg_d1 == 1'b1) begin
              rd_rst_asreg <= #`TCQ 1'b0;
            end else begin
              rd_rst_asreg <= #`TCQ rd_rst_asreg;
            end
          end    
        end   

        always @(posedge RD_CLK) begin
          rd_rst_asreg_d1 <= #`TCQ rd_rst_asreg;
          rd_rst_asreg_d2 <= #`TCQ rd_rst_asreg_d1;
        end
        
        always @(posedge RD_CLK or posedge rd_rst_comb) begin
          if (rd_rst_comb == 1'b1) begin
            rd_rst_reg <= #`TCQ 1'b1;
          end else begin
            rd_rst_reg <= #`TCQ 1'b0;
          end    
        end   
      end else if (C_HAS_RST == 1 && C_COMMON_CLOCK == 1) begin : g7s_cc_rst
        assign rst_comb      = !rst_asreg_d2 && rst_asreg;     
        assign rst_2_sync = rst_delayed;
        assign wr_rst_busy = 1'b0;
        assign rd_rst_busy = 1'b0;
 
        always @(posedge CLK or posedge rst_delayed) begin
          if (rst_delayed == 1'b1) begin
            rst_asreg <= #`TCQ 1'b1;
          end else begin
            if (rst_asreg_d1 == 1'b1) begin
              rst_asreg <= #`TCQ 1'b0;
            end else begin
              rst_asreg <= #`TCQ rst_asreg;
            end
          end    
        end   
        
        always @(posedge CLK) begin
          rst_asreg_d1 <= #`TCQ rst_asreg;
          rst_asreg_d2 <= #`TCQ rst_asreg_d1;
        end

        always @(posedge CLK or posedge rst_comb) begin
          if (rst_comb == 1'b1) begin
            rst_reg <= #`TCQ 1'b1;
          end else begin
            rst_reg <= #`TCQ 1'b0;
          end    
        end   
      end else if (IS_8SERIES == 1 && C_HAS_SRST == 1 && C_COMMON_CLOCK == 1) begin : g8s_cc_rst
        assign wr_rst_busy = (C_MEMORY_TYPE != 4) ? rst_reg : rst_active_i;
        assign rd_rst_busy = rst_reg;
        assign rst_2_sync = srst_delayed;
        always @* rst_full_ff_i  <= rst_reg;
        always @* rst_full_gen_i <= C_FULL_FLAGS_RST_VAL == 1 ? rst_active_i : 0;

        always @(posedge CLK) begin
          rst_delayed_d1 <= #`TCQ srst_delayed;
          rst_delayed_d2 <= #`TCQ rst_delayed_d1;
          if (rst_reg || rst_delayed_d2) begin
            rst_active_i <= #`TCQ 1'b1;
          end else begin
            rst_active_i <= #`TCQ rst_reg;
          end    
        end   
        always @(posedge CLK) begin
          if (~rst_reg && srst_delayed) begin
             rst_reg <= #`TCQ 1'b1;
           end else if (rst_reg) begin
             rst_reg <= #`TCQ 1'b0;
           end else begin
             rst_reg <= #`TCQ rst_reg;
           end    
        end   
      end else begin 
        assign wr_rst_busy = 1'b0;
        assign rd_rst_busy = 1'b0;
      end
      // end g8s_cc_rst
  endgenerate 

  reg rst_d1 = 1'b0;
  reg rst_d2 = 1'b0;
  reg rst_d3 = 1'b0;
  reg rst_d4 = 1'b0;
  generate
    if ((C_HAS_RST == 1 || C_HAS_SRST == 1 || C_ENABLE_RST_SYNC == 0) && C_FULL_FLAGS_RST_VAL == 1) begin : grstd1
    // RST_FULL_GEN replaces the reset falling edge detection used to de-assert
    // FULL, ALMOST_FULL & PROG_FULL flags if C_FULL_FLAGS_RST_VAL = 1.

    // RST_FULL_FF goes to the reset pin of the final flop of FULL, ALMOST_FULL &
    // PROG_FULL

      always @ (posedge rst_2_sync or posedge clk_2_sync) begin
        if (rst_2_sync) begin
          rst_d1         <= 1'b1;
          rst_d2         <= 1'b1;
          rst_d3         <= 1'b1;
          rst_d4         <= 1'b0;
        end else begin
          if (srst_delayed) begin
            rst_d1         <= #`TCQ 1'b1;
            rst_d2         <= #`TCQ 1'b1;
            rst_d3         <= #`TCQ 1'b1;
            rst_d4         <= #`TCQ 1'b0;
          end else begin
            rst_d1         <= #`TCQ 1'b0;
            rst_d2         <= #`TCQ rst_d1;
            rst_d3         <= #`TCQ rst_d2;
            rst_d4         <= #`TCQ rst_d3;
          end
        end
      end

      always @* rst_full_ff_i  <= (C_HAS_SRST == 0) ? rst_d2 : 1'b0 ;
      always @* rst_full_gen_i <= rst_d4;

    end else if ((C_HAS_RST == 1 || C_HAS_SRST == 1 || C_ENABLE_RST_SYNC == 0) && C_FULL_FLAGS_RST_VAL == 0) begin : gnrst_full
      always @* rst_full_ff_i  <= (C_COMMON_CLOCK == 0) ? wr_rst_i : rst_i;
    end
  endgenerate // grstd1

endmodule //FIFO_GENERATOR_v12_0_CONV_VER


module fifo_generator_v12_0_sync_stage
  #(
    parameter  C_WIDTH          = 10
   )
   (
    input                     RST,
    input                     CLK,
    input       [C_WIDTH-1:0] DIN,
    output reg  [C_WIDTH-1:0] DOUT = 0
   );
   always @ (posedge RST or posedge CLK) begin
     if (RST)
       DOUT <= 0;
     else
       DOUT <= #`TCQ DIN;
   end
endmodule // fifo_generator_v12_0_sync_stage

/*******************************************************************************
 * Declaration of Independent-Clocks FIFO Module
 ******************************************************************************/
module fifo_generator_v12_0_bhv_ver_as
   
  /***************************************************************************
   * Declare user parameters and their defaults
   ***************************************************************************/
  #(
    parameter  C_FAMILY                       = "virtex7",
    parameter  C_DATA_COUNT_WIDTH             = 2,
    parameter  C_DIN_WIDTH                    = 8,
    parameter  C_DOUT_RST_VAL                 = "",
    parameter  C_DOUT_WIDTH                   = 8,
    parameter  C_FULL_FLAGS_RST_VAL           = 1,
    parameter  C_HAS_ALMOST_EMPTY             = 0,
    parameter  C_HAS_ALMOST_FULL              = 0,
    parameter  C_HAS_DATA_COUNT               = 0,
    parameter  C_HAS_OVERFLOW                 = 0,
    parameter  C_HAS_RD_DATA_COUNT            = 0,
    parameter  C_HAS_RST                      = 0,
    parameter  C_HAS_UNDERFLOW                = 0,
    parameter  C_HAS_VALID                    = 0,
    parameter  C_HAS_WR_ACK                   = 0,
    parameter  C_HAS_WR_DATA_COUNT            = 0,
    parameter  C_IMPLEMENTATION_TYPE          = 0,
    parameter  C_MEMORY_TYPE                  = 1,
    parameter  C_OVERFLOW_LOW                 = 0,
    parameter  C_PRELOAD_LATENCY              = 1,
    parameter  C_PRELOAD_REGS                 = 0,
    parameter  C_PROG_EMPTY_THRESH_ASSERT_VAL = 0,
    parameter  C_PROG_EMPTY_THRESH_NEGATE_VAL = 0,
    parameter  C_PROG_EMPTY_TYPE              = 0,
    parameter  C_PROG_FULL_THRESH_ASSERT_VAL  = 0,
    parameter  C_PROG_FULL_THRESH_NEGATE_VAL  = 0,
    parameter  C_PROG_FULL_TYPE               = 0,
    parameter  C_RD_DATA_COUNT_WIDTH          = 2,
    parameter  C_RD_DEPTH                     = 256,
    parameter  C_RD_PNTR_WIDTH                = 8,
    parameter  C_UNDERFLOW_LOW                = 0,
    parameter  C_USE_DOUT_RST                 = 0,
    parameter  C_USE_EMBEDDED_REG             = 0,
    parameter  C_USE_FWFT_DATA_COUNT          = 0,
    parameter  C_VALID_LOW                    = 0,
    parameter  C_WR_ACK_LOW                   = 0,
    parameter  C_WR_DATA_COUNT_WIDTH          = 2,
    parameter  C_WR_DEPTH                     = 256,
    parameter  C_WR_PNTR_WIDTH                = 8,
    parameter  C_USE_ECC                      = 0, 
    parameter  C_ENABLE_RST_SYNC              = 1,
    parameter  C_ERROR_INJECTION_TYPE         = 0,
    parameter  C_SYNCHRONIZER_STAGE           = 2 
   )

  /***************************************************************************
   * Declare Input and Output Ports
   ***************************************************************************/
  (
   input       [C_DIN_WIDTH-1:0]                 DIN,
   input       [C_RD_PNTR_WIDTH-1:0]             PROG_EMPTY_THRESH,
   input       [C_RD_PNTR_WIDTH-1:0]             PROG_EMPTY_THRESH_ASSERT,
   input       [C_RD_PNTR_WIDTH-1:0]             PROG_EMPTY_THRESH_NEGATE,
   input       [C_WR_PNTR_WIDTH-1:0]             PROG_FULL_THRESH,
   input       [C_WR_PNTR_WIDTH-1:0]             PROG_FULL_THRESH_ASSERT,
   input       [C_WR_PNTR_WIDTH-1:0]             PROG_FULL_THRESH_NEGATE,
   input                                         RD_CLK,
   input                                         RD_EN,
   input                                         RD_EN_USER,
   input                                         RST,
   input                                         RST_FULL_GEN,
   input                                         RST_FULL_FF,
   input                                         WR_RST,
   input                                         RD_RST,
   input                                         WR_CLK,
   input                                         WR_EN,
   input                                         INJECTDBITERR,
   input                                         INJECTSBITERR,
   input                                         USER_EMPTY_FB,
   output reg                                    ALMOST_EMPTY = 1'b1,
   output reg                                    ALMOST_FULL = C_FULL_FLAGS_RST_VAL,
   output      [C_DOUT_WIDTH-1:0]                DOUT,
   output reg                                    EMPTY = 1'b1,
   output reg                                    FULL = C_FULL_FLAGS_RST_VAL,
   output                                        OVERFLOW,
   output                                        PROG_EMPTY,
   output                                        PROG_FULL,
   output                                        VALID,
   output      [C_RD_DATA_COUNT_WIDTH-1:0]       RD_DATA_COUNT,
   output                                        UNDERFLOW,
   output                                        WR_ACK,
   output      [C_WR_DATA_COUNT_WIDTH-1:0]       WR_DATA_COUNT,
   output                                        SBITERR,
   output                                        DBITERR
  );


   reg  [C_RD_PNTR_WIDTH:0] rd_data_count_int = 0;
   reg  [C_WR_PNTR_WIDTH:0] wr_data_count_int = 0;
   reg  [C_WR_PNTR_WIDTH:0] wdc_fwft_ext_as = 0;
   
  
   /***************************************************************************
    * Parameters used as constants
    **************************************************************************/
  localparam IS_8SERIES         = (C_FAMILY == "virtexu" || C_FAMILY == "kintexu" || C_FAMILY == "artixu" || C_FAMILY == "virtexum" || C_FAMILY == "zynque") ? 1 : 0;
   //When RST is present, set FULL reset value to '1'.
   //If core has no RST, make sure FULL powers-on as '0'.
   localparam C_DEPTH_RATIO_WR =  
      (C_WR_DEPTH>C_RD_DEPTH) ? (C_WR_DEPTH/C_RD_DEPTH) : 1;
   localparam C_DEPTH_RATIO_RD =  
      (C_RD_DEPTH>C_WR_DEPTH) ? (C_RD_DEPTH/C_WR_DEPTH) : 1;
   localparam C_FIFO_WR_DEPTH = C_WR_DEPTH - 1;
   localparam C_FIFO_RD_DEPTH = C_RD_DEPTH - 1;

   //  C_DEPTH_RATIO_WR | C_DEPTH_RATIO_RD | C_PNTR_WIDTH    | EXTRA_WORDS_DC
   //  -----------------|------------------|-----------------|---------------
   //  1                | 8                | C_RD_PNTR_WIDTH | 2
   //  1                | 4                | C_RD_PNTR_WIDTH | 2
   //  1                | 2                | C_RD_PNTR_WIDTH | 2
   //  1                | 1                | C_WR_PNTR_WIDTH | 2
   //  2                | 1                | C_WR_PNTR_WIDTH | 4
   //  4                | 1                | C_WR_PNTR_WIDTH | 8
   //  8                | 1                | C_WR_PNTR_WIDTH | 16
   
   localparam C_PNTR_WIDTH  = (C_WR_PNTR_WIDTH>=C_RD_PNTR_WIDTH) ? C_WR_PNTR_WIDTH : C_RD_PNTR_WIDTH;
   wire [C_PNTR_WIDTH:0] EXTRA_WORDS_DC = (C_DEPTH_RATIO_WR == 1) ? 2 : (2 * C_DEPTH_RATIO_WR/C_DEPTH_RATIO_RD);

   localparam [31:0] reads_per_write = C_DIN_WIDTH/C_DOUT_WIDTH;
   
   localparam [31:0] log2_reads_per_write = log2_val(reads_per_write);
   
   localparam [31:0] writes_per_read = C_DOUT_WIDTH/C_DIN_WIDTH;
   
   localparam [31:0] log2_writes_per_read = log2_val(writes_per_read);



   /**************************************************************************
    * FIFO Contents Tracking and Data Count Calculations
    *************************************************************************/
   
   // Memory which will be used to simulate a FIFO
   reg [C_DIN_WIDTH-1:0] memory[C_WR_DEPTH-1:0];
   // Local parameters used to determine whether to inject ECC error or not
   localparam SYMMETRIC_PORT = (C_DIN_WIDTH == C_DOUT_WIDTH) ? 1 : 0;
   localparam ERR_INJECTION = (C_ERROR_INJECTION_TYPE != 0) ? 1 : 0;
   localparam ENABLE_ERR_INJECTION = C_USE_ECC && SYMMETRIC_PORT && ERR_INJECTION;
   // Array that holds the error injection type (single/double bit error) on 
   // a specific write operation, which is returned on read to corrupt the
   // output data.
   reg [1:0] ecc_err[C_WR_DEPTH-1:0];

   //The amount of data stored in the FIFO at any time is given
   // by num_wr_bits (in the WR_CLK domain) and num_rd_bits (in the RD_CLK
   // domain.
   //num_wr_bits is calculated by considering the total words in the FIFO,
   // and the state of the read pointer (which may not have yet crossed clock
   // domains.)
   //num_rd_bits is calculated by considering the total words in the FIFO,
   // and the state of the write pointer (which may not have yet crossed clock
   // domains.)
   reg [31:0]  num_wr_bits;
   reg [31:0]  num_rd_bits;
   reg [31:0]  next_num_wr_bits;
   reg [31:0]  next_num_rd_bits;

   //The write pointer - tracks write operations
   // (Works opposite to core: wr_ptr is a DOWN counter)
   reg  [31:0]                 wr_ptr;
   reg  [C_WR_PNTR_WIDTH-1:0]  wr_pntr = 0; // UP counter: Rolls back to 0 when reaches to max value.
   reg  [C_WR_PNTR_WIDTH-1:0]  wr_pntr_rd1    = 0;
   reg  [C_WR_PNTR_WIDTH-1:0]  wr_pntr_rd2    = 0;
   reg  [C_WR_PNTR_WIDTH-1:0]  wr_pntr_rd3    = 0;
   wire [C_RD_PNTR_WIDTH-1:0]  adj_wr_pntr_rd;
   reg  [C_WR_PNTR_WIDTH-1:0]  wr_pntr_rd     = 0;
   wire                        wr_rst_i = WR_RST;   
   reg                         wr_rst_d1      =0;

   //The read pointer - tracks read operations
   // (rd_ptr Works opposite to core: rd_ptr is a DOWN counter)
   reg  [31:0]                 rd_ptr;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr = 0; // UP counter: Rolls back to 0 when reaches to max value.
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr1 = 0;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr2 = 0;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr3 = 0;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr4 = 0;
   wire [C_WR_PNTR_WIDTH-1:0]  adj_rd_pntr_wr;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr  = 0;
   wire                        rd_rst_i = RD_RST;
   wire                        ram_rd_en;
   wire                        empty_int;
   wire                        almost_empty_int;
   wire                        ram_wr_en;
   wire                        full_int;
   wire                        almost_full_int;
   reg                         ram_rd_en_d1 = 1'b0;


   // Delayed ram_rd_en is needed only for STD Embedded register option
   generate
     if (C_PRELOAD_LATENCY == 2) begin : grd_d
       always @ (posedge RD_CLK or posedge rd_rst_i) begin
         if (rd_rst_i)
           ram_rd_en_d1 <= #`TCQ 1'b0;
         else
           ram_rd_en_d1 <= #`TCQ ram_rd_en;
       end
     end
   endgenerate

   // Write pointer adjustment based on pointers width for EMPTY/ALMOST_EMPTY generation
   //ANDREAS: NOP
   generate
     if (C_RD_PNTR_WIDTH > C_WR_PNTR_WIDTH) begin : rdg // Read depth greater than write depth
       assign adj_wr_pntr_rd[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr_rd;
       assign adj_wr_pntr_rd[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1:0] = 0;
     end else begin : rdl // Read depth lesser than or equal to write depth
       assign adj_wr_pntr_rd = wr_pntr_rd[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH];
     end
   endgenerate

   // Generate Empty and Almost Empty
  // ram_rd_en used to determine EMPTY should depend on the EMPTY.
   assign ram_rd_en        = RD_EN & !EMPTY;
   assign empty_int        = ((adj_wr_pntr_rd == rd_pntr) || (ram_rd_en && (adj_wr_pntr_rd == (rd_pntr+1'h1))));
   assign almost_empty_int = ((adj_wr_pntr_rd == (rd_pntr+1'h1)) || (ram_rd_en && (adj_wr_pntr_rd == (rd_pntr+2'h2))));

   // Register Empty and Almost Empty
   always @ (posedge RD_CLK or posedge rd_rst_i)
     begin
       if (rd_rst_i) begin
         EMPTY             <= #`TCQ 1'b1;
         ALMOST_EMPTY      <= #`TCQ 1'b1;
         rd_data_count_int <= #`TCQ {C_RD_PNTR_WIDTH{1'b0}};
       end else begin
         rd_data_count_int <= #`TCQ {(adj_wr_pntr_rd[C_RD_PNTR_WIDTH-1:0] - rd_pntr[C_RD_PNTR_WIDTH-1:0]), 1'b0};

         if (empty_int)
           EMPTY           <= #`TCQ 1'b1;
         else
           EMPTY           <= #`TCQ 1'b0;

         if (!EMPTY) begin
           if (almost_empty_int)
             ALMOST_EMPTY  <= #`TCQ 1'b1;
           else
             ALMOST_EMPTY  <= #`TCQ 1'b0;
         end
       end // rd_rst_i
     end // always

   // Read pointer adjustment based on pointers width for EMPTY/ALMOST_EMPTY generation
   generate
     if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin : wdg // Write depth greater than read depth
       assign adj_rd_pntr_wr[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH] = rd_pntr_wr;
       assign adj_rd_pntr_wr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1:0] = 0;
     end else begin : wdl // Write depth lesser than or equal to read depth
       assign adj_rd_pntr_wr = rd_pntr_wr[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH];
     end
   endgenerate

  // Generate FULL and ALMOST_FULL
  // ram_wr_en used to determine FULL should depend on the FULL.
  assign ram_wr_en       = WR_EN & !FULL;
  assign full_int        = ((adj_rd_pntr_wr == (wr_pntr+1'h1)) || (ram_wr_en && (adj_rd_pntr_wr == (wr_pntr+2'h2))));
  assign almost_full_int = ((adj_rd_pntr_wr == (wr_pntr+2'h2)) || (ram_wr_en && (adj_rd_pntr_wr == (wr_pntr+3'h3))));

   // Register FULL and ALMOST_FULL Empty
   always @ (posedge WR_CLK or posedge RST_FULL_FF)
     begin
       if (RST_FULL_FF) begin
         FULL             <= #`TCQ C_FULL_FLAGS_RST_VAL;
         ALMOST_FULL      <= #`TCQ C_FULL_FLAGS_RST_VAL;
       end else begin
         if (full_int) begin
           FULL           <= #`TCQ 1'b1;
         end else begin
           FULL           <= #`TCQ 1'b0;
         end

         if (RST_FULL_GEN) begin
           ALMOST_FULL    <= #`TCQ 1'b0;
         end else if (!FULL) begin
           if (almost_full_int)
             ALMOST_FULL  <= #`TCQ 1'b1;
           else
             ALMOST_FULL  <= #`TCQ 1'b0;
         end
       end // wr_rst_i
     end // always
   always @ (posedge WR_CLK or posedge wr_rst_i)
     begin
       if (wr_rst_i) begin
         wr_data_count_int <= #`TCQ {C_WR_DATA_COUNT_WIDTH{1'b0}};
       end else begin
         wr_data_count_int <= #`TCQ {(wr_pntr[C_WR_PNTR_WIDTH-1:0] - adj_rd_pntr_wr[C_WR_PNTR_WIDTH-1:0]), 1'b0};
       end // wr_rst_i
     end // always

   // Determine which stage in FWFT registers are valid
   reg stage1_valid = 0;
   reg stage2_valid = 0;
   generate
     if (C_PRELOAD_LATENCY == 0) begin : grd_fwft_proc
       always @ (posedge RD_CLK or posedge rd_rst_i) begin
         if (rd_rst_i) begin
           stage1_valid     <= #`TCQ 0;
           stage2_valid     <= #`TCQ 0;
         end else begin

           if (!stage1_valid && !stage2_valid) begin
             if (!EMPTY)
               stage1_valid    <= #`TCQ 1'b1;
             else
               stage1_valid    <= #`TCQ 1'b0;
           end else if (stage1_valid && !stage2_valid) begin
             if (EMPTY) begin
               stage1_valid    <= #`TCQ 1'b0;
               stage2_valid    <= #`TCQ 1'b1;
             end else begin
               stage1_valid    <= #`TCQ 1'b1;
               stage2_valid    <= #`TCQ 1'b1;
             end
           end else if (!stage1_valid && stage2_valid) begin
             if (EMPTY && RD_EN_USER) begin
               stage1_valid    <= #`TCQ 1'b0;
               stage2_valid    <= #`TCQ 1'b0;
             end else if (!EMPTY && RD_EN_USER) begin
               stage1_valid    <= #`TCQ 1'b1;
               stage2_valid    <= #`TCQ 1'b0;
             end else if (!EMPTY && !RD_EN_USER) begin
               stage1_valid    <= #`TCQ 1'b1;
               stage2_valid    <= #`TCQ 1'b1;
             end else begin
               stage1_valid    <= #`TCQ 1'b0;
               stage2_valid    <= #`TCQ 1'b1;
             end
           end else if (stage1_valid && stage2_valid) begin
             if (EMPTY && RD_EN_USER) begin
               stage1_valid    <= #`TCQ 1'b0;
               stage2_valid    <= #`TCQ 1'b1;
             end else begin
               stage1_valid    <= #`TCQ 1'b1;
               stage2_valid    <= #`TCQ 1'b1;
             end
           end else begin
             stage1_valid    <= #`TCQ 1'b0;
             stage2_valid    <= #`TCQ 1'b0;
           end
         end // rd_rst_i
       end // always
     end
   endgenerate

   //Pointers passed into opposite clock domain
   reg [31:0]  wr_ptr_rdclk;
   reg [31:0]  wr_ptr_rdclk_next;
   reg [31:0]  rd_ptr_wrclk;
   reg [31:0]  rd_ptr_wrclk_next;

   //Amount of data stored in the FIFO scaled to the narrowest (deepest) port
   // (Do not include data in FWFT stages)
   //Used to calculate PROG_EMPTY.
   wire [31:0] num_read_words_pe = 
     num_rd_bits/(C_DOUT_WIDTH/C_DEPTH_RATIO_WR);

   //Amount of data stored in the FIFO scaled to the narrowest (deepest) port
   // (Do not include data in FWFT stages)
   //Used to calculate PROG_FULL.
   wire [31:0] num_write_words_pf =
     num_wr_bits/(C_DIN_WIDTH/C_DEPTH_RATIO_RD);

   /**************************
    * Read Data Count
    *************************/

   reg [31:0] num_read_words_dc;
   reg [C_RD_DATA_COUNT_WIDTH-1:0] num_read_words_sized_i;
   
   always @(num_rd_bits) begin
     if (C_USE_FWFT_DATA_COUNT) begin
        
        //If using extra logic for FWFT Data Counts, 
        // then scale FIFO contents to read domain, 
        // and add two read words for FWFT stages
        //This value is only a temporary value and not used in the code.
        num_read_words_dc = (num_rd_bits/C_DOUT_WIDTH+2);
        
        //Trim the read words for use with RD_DATA_COUNT
        num_read_words_sized_i = 
          num_read_words_dc[C_RD_PNTR_WIDTH : C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH+1];
        
     end else begin
        
        //If not using extra logic for FWFT Data Counts, 
        // then scale FIFO contents to read domain.
        //This value is only a temporary value and not used in the code.
        num_read_words_dc = num_rd_bits/C_DOUT_WIDTH;
        
        //Trim the read words for use with RD_DATA_COUNT
        num_read_words_sized_i = 
          num_read_words_dc[C_RD_PNTR_WIDTH-1 : C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH];
        
     end //if (C_USE_FWFT_DATA_COUNT)
   end //always

   
   /**************************
    * Write Data Count
    *************************/

   reg [31:0] num_write_words_dc;
   reg [C_WR_DATA_COUNT_WIDTH-1:0] num_write_words_sized_i;
   
   always @(num_wr_bits) begin
     if (C_USE_FWFT_DATA_COUNT) begin
        
        //Calculate the Data Count value for the number of write words, 
        // when using First-Word Fall-Through with extra logic for Data 
        // Counts. This takes into consideration the number of words that 
        // are expected to be stored in the FWFT register stages (it always 
        // assumes they are filled).
        //This value is scaled to the Write Domain.
        //The expression (((A-1)/B))+1 divides A/B, but takes the 
        // ceiling of the result.
        //When num_wr_bits==0, set the result manually to prevent 
        // division errors.
        //EXTRA_WORDS_DC is the number of words added to write_words 
        // due to FWFT.
        //This value is only a temporary value and not used in the code.
        num_write_words_dc = (num_wr_bits==0) ? EXTRA_WORDS_DC :  (((num_wr_bits-1)/C_DIN_WIDTH)+1) + EXTRA_WORDS_DC ;
        
        //Trim the write words for use with WR_DATA_COUNT
        num_write_words_sized_i = 
          num_write_words_dc[C_WR_PNTR_WIDTH : C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH+1];
        
     end else begin
        
        //Calculate the Data Count value for the number of write words, when NOT
        // using First-Word Fall-Through with extra logic for Data Counts. This 
        // calculates only the number of words in the internal FIFO.
        //The expression (((A-1)/B))+1 divides A/B, but takes the 
        // ceiling of the result.
        //This value is scaled to the Write Domain.
        //When num_wr_bits==0, set the result manually to prevent 
        // division errors.
        //This value is only a temporary value and not used in the code.
        num_write_words_dc = (num_wr_bits==0) ? 0 : ((num_wr_bits-1)/C_DIN_WIDTH)+1;
        
        //Trim the read words for use with RD_DATA_COUNT
        num_write_words_sized_i = 
          num_write_words_dc[C_WR_PNTR_WIDTH-1 : C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH];
        
     end //if (C_USE_FWFT_DATA_COUNT)
   end //always

    
    
   /***************************************************************************
    * Internal registers and wires
    **************************************************************************/

   //Temporary signals used for calculating the model's outputs. These
   //are only used in the assign statements immediately following wire,
   //parameter, and function declarations.
   wire [C_DOUT_WIDTH-1:0] ideal_dout_out;      
   wire valid_i;
   wire valid_out;  
   wire underflow_i;

   //Ideal FIFO signals. These are the raw output of the behavioral model,
   //which behaves like an ideal FIFO.
   reg [1:0]               err_type                 = 0;
   reg [1:0]               err_type_d1              = 0;
   reg [C_DOUT_WIDTH-1:0]  ideal_dout               = 0;
   reg [C_DOUT_WIDTH-1:0]  ideal_dout_d1            = 0;
   reg                     ideal_wr_ack             = 0;
   reg                     ideal_valid              = 0;
   reg                     ideal_overflow           = C_OVERFLOW_LOW;
   reg                     ideal_underflow          = C_UNDERFLOW_LOW;
   reg                     ideal_prog_full          = 0;
   reg                     ideal_prog_empty         = 1;
   reg [C_WR_DATA_COUNT_WIDTH-1 : 0] ideal_wr_count = 0;
   reg [C_RD_DATA_COUNT_WIDTH-1 : 0] ideal_rd_count = 0;

   //Assorted reg values for delayed versions of signals   
   reg         valid_d1     = 0;
   
   
   //user specified value for reseting the size of the fifo
   reg [C_DOUT_WIDTH-1:0]            dout_reset_val = 0;
   
   //temporary registers for WR_RESPONSE_LATENCY feature
   
   integer                           tmp_wr_listsize;
   integer                           tmp_rd_listsize;
   
   //Signal for registered version of prog full and empty
   
   //Threshold values for Programmable Flags
   integer                           prog_empty_actual_thresh_assert;
   integer                           prog_empty_actual_thresh_negate;
   integer                           prog_full_actual_thresh_assert;
   integer                           prog_full_actual_thresh_negate;
   

  /****************************************************************************
   * Function Declarations
   ***************************************************************************/

  /**************************************************************************
   * write_fifo
   *   This task writes a word to the FIFO memory and updates the 
   * write pointer.
   *   FIFO size is relative to write domain.
  ***************************************************************************/
  task write_fifo;
    begin
       //ANDREAS:$display("writing %x %d %m", DIN,wr_pntr);       
      memory[wr_ptr]     <= DIN;
      wr_pntr           <= #`TCQ wr_pntr + 1;
      // Store the type of error injection (double/single) on write
      case (C_ERROR_INJECTION_TYPE)
        3:       ecc_err[wr_ptr]    <= {INJECTDBITERR,INJECTSBITERR};
        2:       ecc_err[wr_ptr]    <= {INJECTDBITERR,1'b0};
        1:       ecc_err[wr_ptr]    <= {1'b0,INJECTSBITERR};
        default: ecc_err[wr_ptr]    <= 0;
      endcase
      // (Works opposite to core: wr_ptr is a DOWN counter)
      if (wr_ptr == 0) begin
        wr_ptr          <= C_WR_DEPTH - 1;
      end else begin
        wr_ptr          <= wr_ptr - 1;
      end
    end
  endtask // write_fifo

  /**************************************************************************
   * read_fifo
   *   This task reads a word from the FIFO memory and updates the read 
   * pointer. It's output is the ideal_dout bus.
   *   FIFO size is relative to write domain.
   ***************************************************************************/
  task read_fifo;
    integer i;
    reg [C_DOUT_WIDTH-1:0]      tmp_dout;
    reg [C_DIN_WIDTH-1:0]       memory_read;
    reg [31:0]                  tmp_rd_ptr;
    reg [31:0]                  rd_ptr_high;
    reg [31:0]                  rd_ptr_low;
    reg [1:0]                   tmp_ecc_err;
    begin
      rd_pntr <= #`TCQ rd_pntr + 1;
      // output is wider than input
      if (reads_per_write == 0) begin
        tmp_dout = 0;
        tmp_rd_ptr = (rd_ptr << log2_writes_per_read)+(writes_per_read-1);
        for (i = writes_per_read - 1; i >= 0; i = i - 1) begin
          tmp_dout = tmp_dout << C_DIN_WIDTH;
          tmp_dout = tmp_dout | memory[tmp_rd_ptr];
           
          // (Works opposite to core: rd_ptr is a DOWN counter)
          if (tmp_rd_ptr == 0) begin
            tmp_rd_ptr = C_WR_DEPTH - 1;
          end else begin
            tmp_rd_ptr = tmp_rd_ptr - 1;
          end
        end

      // output is symmetric
      end else if (reads_per_write == 1) begin
        tmp_dout = memory[rd_ptr][C_DIN_WIDTH-1:0];
        // Retreive the error injection type. Based on the error injection type
        // corrupt the output data.
        tmp_ecc_err = ecc_err[rd_ptr];
        if (ENABLE_ERR_INJECTION && C_DIN_WIDTH == C_DOUT_WIDTH) begin
          if (tmp_ecc_err[1]) begin // Corrupt the output data only for double bit error
            if (C_DOUT_WIDTH == 1) begin
               $display("FAILURE : Data width must be >= 2 for double bit error injection.");
              $finish;
            end else if (C_DOUT_WIDTH == 2)
              tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2]};
            else
              tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2],(tmp_dout << 2)};
          end else begin
            tmp_dout = tmp_dout[C_DOUT_WIDTH-1:0];
          end
          err_type <= {tmp_ecc_err[1], tmp_ecc_err[0] & !tmp_ecc_err[1]};
        end else begin
          err_type <= 0;
        end

      // input is wider than output
      end else begin
        rd_ptr_high = rd_ptr >> log2_reads_per_write;
        rd_ptr_low  = rd_ptr & (reads_per_write - 1);
        memory_read = memory[rd_ptr_high];
        tmp_dout    = memory_read >> (rd_ptr_low*C_DOUT_WIDTH);
      end
      ideal_dout <= tmp_dout;
       
      // (Works opposite to core: rd_ptr is a DOWN counter)
      if (rd_ptr == 0) begin
        rd_ptr <= C_RD_DEPTH - 1;
      end else begin
        rd_ptr <= rd_ptr - 1;
      end
    end
  endtask

  /**************************************************************************
  * log2_val
  *   Returns the 'log2' value for the input value for the supported ratios
  ***************************************************************************/
  function [31:0] log2_val;
    input [31:0] binary_val;

    begin
      if (binary_val == 8) begin
        log2_val = 3;
      end else if (binary_val == 4) begin
        log2_val = 2;
      end else begin
        log2_val = 1;
      end
    end
  endfunction

  /***********************************************************************
  * hexstr_conv
  *   Converts a string of type hex to a binary value (for C_DOUT_RST_VAL)
  ***********************************************************************/
  function [C_DOUT_WIDTH-1:0] hexstr_conv;
    input [(C_DOUT_WIDTH*8)-1:0] def_data;

    integer index,i,j;
    reg [3:0] bin;

    begin
      index = 0;
      hexstr_conv = 'b0;
      for( i=C_DOUT_WIDTH-1; i>=0; i=i-1 )
      begin
        case (def_data[7:0])
          8'b00000000 :
          begin
            bin = 4'b0000;
            i = -1;
          end
          8'b00110000 : bin = 4'b0000;
          8'b00110001 : bin = 4'b0001;
          8'b00110010 : bin = 4'b0010;
          8'b00110011 : bin = 4'b0011;
          8'b00110100 : bin = 4'b0100;
          8'b00110101 : bin = 4'b0101;
          8'b00110110 : bin = 4'b0110;
          8'b00110111 : bin = 4'b0111;
          8'b00111000 : bin = 4'b1000;
          8'b00111001 : bin = 4'b1001;
          8'b01000001 : bin = 4'b1010;
          8'b01000010 : bin = 4'b1011;
          8'b01000011 : bin = 4'b1100;
          8'b01000100 : bin = 4'b1101;
          8'b01000101 : bin = 4'b1110;
          8'b01000110 : bin = 4'b1111;
          8'b01100001 : bin = 4'b1010;
          8'b01100010 : bin = 4'b1011;
          8'b01100011 : bin = 4'b1100;
          8'b01100100 : bin = 4'b1101;
          8'b01100101 : bin = 4'b1110;
          8'b01100110 : bin = 4'b1111;
          default :
          begin
            bin = 4'bx;
          end
        endcase
        for( j=0; j<4; j=j+1)
        begin
          if ((index*4)+j < C_DOUT_WIDTH)
          begin
            hexstr_conv[(index*4)+j] = bin[j];
          end
        end
        index = index + 1;
        def_data = def_data >> 8;
      end
    end
  endfunction

  /*************************************************************************
  * Initialize Signals for clean power-on simulation
  *************************************************************************/
   initial begin
      num_wr_bits        = 0;
      num_rd_bits        = 0;
      next_num_wr_bits   = 0;
      next_num_rd_bits   = 0;
      rd_ptr             = C_RD_DEPTH - 1;
      wr_ptr             = C_WR_DEPTH - 1;
      wr_pntr            = 0;
      rd_pntr            = 0;
      rd_ptr_wrclk       = rd_ptr;
      wr_ptr_rdclk       = wr_ptr;
      dout_reset_val     = hexstr_conv(C_DOUT_RST_VAL);
      ideal_dout         = dout_reset_val;
      err_type           = 0;
      ideal_dout_d1      = dout_reset_val;
      ideal_wr_ack       = 1'b0;
      ideal_valid        = 1'b0;
      valid_d1           = 1'b0;
      ideal_overflow     = C_OVERFLOW_LOW;
      ideal_underflow    = C_UNDERFLOW_LOW;
      ideal_wr_count     = 0;
      ideal_rd_count     = 0;
      ideal_prog_full    = 1'b0;
      ideal_prog_empty   = 1'b1;
    end


  /*************************************************************************
   * Connect the module inputs and outputs to the internal signals of the 
   * behavioral model.
   *************************************************************************/
   //Inputs
   /*
    wire [C_DIN_WIDTH-1:0] DIN;
   wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH;
   wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT;
   wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE;
   wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH;
   wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT;
   wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE;   
   wire RD_CLK;
   wire RD_EN;
   wire RST;
   wire WR_CLK;
   wire WR_EN;
    */

   //***************************************************************************
   // Dout may change behavior based on latency
   //***************************************************************************
   assign ideal_dout_out[C_DOUT_WIDTH-1:0] = (C_PRELOAD_LATENCY==2 &&
                          (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1))?
                         ideal_dout_d1: ideal_dout;   
   assign DOUT[C_DOUT_WIDTH-1:0] = ideal_dout_out; 

   //***************************************************************************
   // Assign SBITERR and DBITERR based on latency 
   //***************************************************************************
   assign SBITERR = (C_ERROR_INJECTION_TYPE == 1 || C_ERROR_INJECTION_TYPE == 3) && 
                    (C_PRELOAD_LATENCY == 2 &&
                    (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ?
                    err_type_d1[0]: err_type[0]; 
   assign DBITERR = (C_ERROR_INJECTION_TYPE == 2 || C_ERROR_INJECTION_TYPE == 3) &&
                    (C_PRELOAD_LATENCY==2 && (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ?
                    err_type_d1[1]: err_type[1]; 
  

   //***************************************************************************
   // Overflow may be active-low
   //***************************************************************************
   generate
      if (C_HAS_OVERFLOW==1) begin : blockOF1
   assign OVERFLOW = ideal_overflow ? !C_OVERFLOW_LOW : C_OVERFLOW_LOW;
      end
   endgenerate

   assign PROG_EMPTY = ideal_prog_empty;
   assign PROG_FULL  = ideal_prog_full;

   //***************************************************************************
   // Valid may change behavior based on latency or active-low
   //***************************************************************************
   generate
      if (C_HAS_VALID==1) begin : blockVL1
   assign valid_i   = (C_PRELOAD_LATENCY==0) ? (RD_EN & ~EMPTY) : ideal_valid;
   assign valid_out = (C_PRELOAD_LATENCY==2 &&
                       (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1))?
                       valid_d1: valid_i;  
   assign VALID     = valid_out ? !C_VALID_LOW : C_VALID_LOW;
     end
   endgenerate


   //***************************************************************************
   // Underflow may change behavior based on latency or active-low   
   //***************************************************************************
   generate
      if (C_HAS_UNDERFLOW==1) begin : blockUF1
   assign underflow_i = (C_PRELOAD_LATENCY==0) ? (RD_EN & EMPTY) : ideal_underflow;
   assign UNDERFLOW   = underflow_i ? !C_UNDERFLOW_LOW : C_UNDERFLOW_LOW;
    end
   endgenerate

   //***************************************************************************
   // Write acknowledge may be active low
   //***************************************************************************
   generate
      if (C_HAS_WR_ACK==1) begin : blockWK1
   assign WR_ACK = ideal_wr_ack ? !C_WR_ACK_LOW : C_WR_ACK_LOW;
     end
   endgenerate


   //***************************************************************************
   // Generate RD_DATA_COUNT if Use Extra Logic option is selected
   //***************************************************************************
   generate
      if (C_HAS_WR_DATA_COUNT == 1 && C_USE_FWFT_DATA_COUNT == 1) begin : wdc_fwft_ext

      reg  [C_PNTR_WIDTH-1:0]  adjusted_wr_pntr = 0;
      reg  [C_PNTR_WIDTH-1:0]  adjusted_rd_pntr = 0;
      wire [C_PNTR_WIDTH-1:0]  diff_wr_rd_tmp;
      wire [C_PNTR_WIDTH:0]    diff_wr_rd;
      reg  [C_PNTR_WIDTH:0]    wr_data_count_i  = 0;
        always @* begin
          if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin
            adjusted_wr_pntr = wr_pntr;
            adjusted_rd_pntr = 0;
            adjusted_rd_pntr[C_PNTR_WIDTH-1:C_PNTR_WIDTH-C_RD_PNTR_WIDTH] = rd_pntr_wr;
          end else if (C_WR_PNTR_WIDTH < C_RD_PNTR_WIDTH) begin
            adjusted_rd_pntr = rd_pntr_wr;
            adjusted_wr_pntr = 0;
            adjusted_wr_pntr[C_PNTR_WIDTH-1:C_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr;
          end else begin
            adjusted_wr_pntr = wr_pntr;
            adjusted_rd_pntr = rd_pntr_wr;
          end
        end // always @*

        assign diff_wr_rd_tmp = adjusted_wr_pntr - adjusted_rd_pntr;
        assign diff_wr_rd     = {1'b0,diff_wr_rd_tmp};

        always @ (posedge wr_rst_i or posedge WR_CLK)
        begin
            if (wr_rst_i)
              wr_data_count_i <= #`TCQ 0;
            else
              wr_data_count_i <= #`TCQ diff_wr_rd + EXTRA_WORDS_DC;
        end // always @ (posedge WR_CLK or posedge WR_CLK)

        always @* begin
          if (C_WR_PNTR_WIDTH >= C_RD_PNTR_WIDTH)
            wdc_fwft_ext_as = wr_data_count_i[C_PNTR_WIDTH:0];
          else
            wdc_fwft_ext_as = wr_data_count_i[C_PNTR_WIDTH:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH];
        end // always @*
      end // wdc_fwft_ext
   endgenerate

   //***************************************************************************
   // Generate RD_DATA_COUNT if Use Extra Logic option is selected
   //***************************************************************************
   reg  [C_RD_PNTR_WIDTH:0]    rdc_fwft_ext_as  = 0;

   generate
      if (C_HAS_RD_DATA_COUNT == 1 && C_USE_FWFT_DATA_COUNT == 1) begin : rdc_fwft_ext
      reg  [C_RD_PNTR_WIDTH-1:0]  adjusted_wr_pntr_rd = 0;
      wire [C_RD_PNTR_WIDTH-1:0]  diff_rd_wr_tmp;
      wire [C_RD_PNTR_WIDTH:0]    diff_rd_wr;
        always @* begin
          if (C_RD_PNTR_WIDTH > C_WR_PNTR_WIDTH) begin
            adjusted_wr_pntr_rd = 0;
            adjusted_wr_pntr_rd[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr_rd;
          end else begin
            adjusted_wr_pntr_rd = wr_pntr_rd[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH];
          end
        end // always @*

        assign diff_rd_wr_tmp = adjusted_wr_pntr_rd - rd_pntr;
        assign diff_rd_wr     = {1'b0,diff_rd_wr_tmp};

        always @ (posedge rd_rst_i or posedge RD_CLK)
        begin
            if (rd_rst_i) begin
              rdc_fwft_ext_as   <= #`TCQ 0;
            end else begin
              if (!stage2_valid)
                rdc_fwft_ext_as <= #`TCQ 0;
              else if (!stage1_valid && stage2_valid)
                rdc_fwft_ext_as <= #`TCQ 1;
              else
                rdc_fwft_ext_as <= #`TCQ diff_rd_wr + 2'h2;
            end 
        end // always @ (posedge WR_CLK or posedge WR_CLK)
      end // rdc_fwft_ext
   endgenerate

   //***************************************************************************
   // Assign the read data count value only if it is selected, 
   // otherwise output zeros.
   //***************************************************************************
   generate
      if (C_HAS_RD_DATA_COUNT == 1) begin : grdc
   assign RD_DATA_COUNT[C_RD_DATA_COUNT_WIDTH-1:0] = C_USE_FWFT_DATA_COUNT ?
          rdc_fwft_ext_as[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH+1-C_RD_DATA_COUNT_WIDTH] :
          rd_data_count_int[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH+1-C_RD_DATA_COUNT_WIDTH];
      end
   endgenerate

   generate
      if (C_HAS_RD_DATA_COUNT == 0) begin : gnrdc
   assign RD_DATA_COUNT[C_RD_DATA_COUNT_WIDTH-1:0] = {C_RD_DATA_COUNT_WIDTH{1'b0}};
      end
   endgenerate

   //***************************************************************************
   // Assign the write data count value only if it is selected, 
   // otherwise output zeros
   //***************************************************************************
   generate
      if (C_HAS_WR_DATA_COUNT == 1) begin : gwdc
   assign WR_DATA_COUNT[C_WR_DATA_COUNT_WIDTH-1:0] = (C_USE_FWFT_DATA_COUNT == 1) ?
          wdc_fwft_ext_as[C_WR_PNTR_WIDTH:C_WR_PNTR_WIDTH+1-C_WR_DATA_COUNT_WIDTH] :
          wr_data_count_int[C_WR_PNTR_WIDTH:C_WR_PNTR_WIDTH+1-C_WR_DATA_COUNT_WIDTH];
      end
   endgenerate
   
   generate
      if (C_HAS_WR_DATA_COUNT == 0) begin : gnwdc
   assign WR_DATA_COUNT[C_WR_DATA_COUNT_WIDTH-1:0] = {C_WR_DATA_COUNT_WIDTH{1'b0}};
      end
   endgenerate


  /**************************************************************************
  * Assorted registers for delayed versions of signals
  **************************************************************************/
  //Capture delayed version of valid
  generate
      if (C_HAS_VALID==1) begin : blockVL2
  always @(posedge RD_CLK or posedge rd_rst_i) begin
    if (rd_rst_i == 1'b1) begin
      valid_d1 <= #`TCQ 1'b0;
    end else begin
      valid_d1 <= #`TCQ valid_i;
    end    
  end 
      end
 endgenerate  
   
  //Capture delayed version of dout
  always @(posedge RD_CLK or posedge rd_rst_i) begin
    if (rd_rst_i == 1'b1) begin
      // Reset err_type only if ECC is not selected
      if (C_USE_ECC == 0)
        err_type_d1     <= #`TCQ 0;
    end else if (ram_rd_en_d1) begin
      ideal_dout_d1   <= #`TCQ ideal_dout;
      err_type_d1     <= #`TCQ err_type;
    end    
  end   
  
   /**************************************************************************
    * Overflow and Underflow Flag calculation
    *  (handled separately because they don't support rst)
    **************************************************************************/
   generate
     if (C_HAS_OVERFLOW == 1 && IS_8SERIES == 0) begin : g7s_ovflw
       always @(posedge WR_CLK) begin
         ideal_overflow    <= #`TCQ WR_EN & FULL;
       end
     end else if (C_HAS_OVERFLOW == 1 && IS_8SERIES == 1) begin : g8s_ovflw
       always @(posedge WR_CLK) begin
         //ideal_overflow    <= #`TCQ WR_EN & (FULL | wr_rst_i);
         ideal_overflow    <= #`TCQ WR_EN & (FULL );
       end
     end
   endgenerate

   generate
     if (C_HAS_UNDERFLOW == 1 && IS_8SERIES == 0) begin : g7s_unflw
       always @(posedge RD_CLK) begin
         ideal_underflow    <= #`TCQ EMPTY & RD_EN;
       end
     end else if (C_HAS_UNDERFLOW == 1 && IS_8SERIES == 1) begin : g8s_unflw
       always @(posedge RD_CLK) begin
         ideal_underflow    <= #`TCQ (EMPTY) & RD_EN;
         //ideal_underflow    <= #`TCQ (rd_rst_i | EMPTY) & RD_EN;
       end
     end
   endgenerate

   /**************************************************************************
   * Write/Read Pointer Synchronization
   **************************************************************************/
   localparam NO_OF_SYNC_STAGE_INC_G2B = C_SYNCHRONIZER_STAGE + 1;
   wire [C_WR_PNTR_WIDTH-1:0] wr_pntr_sync_stgs [0:NO_OF_SYNC_STAGE_INC_G2B];
   wire [C_RD_PNTR_WIDTH-1:0] rd_pntr_sync_stgs [0:NO_OF_SYNC_STAGE_INC_G2B];
   genvar gss;

   generate for (gss = 1; gss <= NO_OF_SYNC_STAGE_INC_G2B; gss = gss + 1) begin : Sync_stage_inst
     fifo_generator_v12_0_sync_stage
       #(
         .C_WIDTH  (C_WR_PNTR_WIDTH)
        )
     rd_stg_inst
        (
         .RST      (rd_rst_i), 
         .CLK      (RD_CLK), 
         .DIN      (wr_pntr_sync_stgs[gss-1]), 
         .DOUT     (wr_pntr_sync_stgs[gss])
        );
 
     fifo_generator_v12_0_sync_stage
       #(
         .C_WIDTH  (C_RD_PNTR_WIDTH)
        )
     wr_stg_inst
        (
         .RST      (wr_rst_i), 
         .CLK      (WR_CLK), 
         .DIN      (rd_pntr_sync_stgs[gss-1]), 
         .DOUT     (rd_pntr_sync_stgs[gss])
        );
   end endgenerate // Sync_stage_inst

   assign wr_pntr_sync_stgs[0] = wr_pntr_rd1;
   assign rd_pntr_sync_stgs[0] = rd_pntr_wr1;
   always@* begin
     wr_pntr_rd           <= wr_pntr_sync_stgs[NO_OF_SYNC_STAGE_INC_G2B];
     rd_pntr_wr           <= rd_pntr_sync_stgs[NO_OF_SYNC_STAGE_INC_G2B];
   end

   /**************************************************************************
   * Write Domain Logic
   **************************************************************************/
   reg [C_WR_PNTR_WIDTH-1:0] diff_pntr = 0;
   always @(posedge WR_CLK or posedge wr_rst_i) begin : gen_fifo_w

     /****** Reset fifo (case 1)***************************************/
     if (wr_rst_i == 1'b1) begin
       num_wr_bits       <= #`TCQ 0;
       next_num_wr_bits   = #`TCQ 0;
       wr_ptr            <= #`TCQ C_WR_DEPTH - 1;
       rd_ptr_wrclk      <= #`TCQ C_RD_DEPTH - 1;
       ideal_wr_ack      <= #`TCQ 0;
       ideal_wr_count    <= #`TCQ 0;
       tmp_wr_listsize    = #`TCQ 0;
       rd_ptr_wrclk_next <= #`TCQ 0;
       wr_pntr           <= #`TCQ 0;
       wr_pntr_rd1       <= #`TCQ 0;

     end else begin //wr_rst_i==0
       wr_pntr_rd1   <= #`TCQ wr_pntr;

       //Determine the current number of words in the FIFO
       tmp_wr_listsize = (C_DEPTH_RATIO_RD > 1) ? num_wr_bits/C_DOUT_WIDTH :
                         num_wr_bits/C_DIN_WIDTH;
       rd_ptr_wrclk_next = rd_ptr;
       if (rd_ptr_wrclk < rd_ptr_wrclk_next) begin
         next_num_wr_bits = num_wr_bits -
                            C_DOUT_WIDTH*(rd_ptr_wrclk + C_RD_DEPTH
                                          - rd_ptr_wrclk_next);
       end else begin
         next_num_wr_bits = num_wr_bits -
                            C_DOUT_WIDTH*(rd_ptr_wrclk - rd_ptr_wrclk_next);
       end

       //If this is a write, handle the write by adding the value
       // to the linked list, and updating all outputs appropriately
       if (WR_EN == 1'b1) begin
         if (FULL == 1'b1) begin

           //If the FIFO is full, do NOT perform the write,
           // update flags accordingly
           if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD 
             >= C_FIFO_WR_DEPTH) begin
             //write unsuccessful - do not change contents

             //Do not acknowledge the write
             ideal_wr_ack      <= #`TCQ 0;
             //Reminder that FIFO is still full

             ideal_wr_count    <= #`TCQ num_write_words_sized_i;

           //If the FIFO is one from full, but reporting full
           end else 
             if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD ==
                C_FIFO_WR_DEPTH-1) begin
             //No change to FIFO

             //Write not successful
             ideal_wr_ack      <= #`TCQ 0;
             //With DEPTH-1 words in the FIFO, it is almost_full

             ideal_wr_count    <= #`TCQ num_write_words_sized_i;


           //If the FIFO is completely empty, but it is
           // reporting FULL for some reason (like reset)
           end else 
             if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD <=
                C_FIFO_WR_DEPTH-2) begin
             //No change to FIFO

             //Write not successful
             ideal_wr_ack      <= #`TCQ 0;
             //FIFO is really not close to full, so change flag status.

             ideal_wr_count    <= #`TCQ num_write_words_sized_i;
           end //(tmp_wr_listsize == 0)

         end else begin

           //If the FIFO is full, do NOT perform the write,
           // update flags accordingly
           if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD >=
              C_FIFO_WR_DEPTH) begin
             //write unsuccessful - do not change contents

             //Do not acknowledge the write
             ideal_wr_ack       <= #`TCQ 0;
             //Reminder that FIFO is still full

             ideal_wr_count     <= #`TCQ num_write_words_sized_i;

           //If the FIFO is one from full
           end else 
             if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD ==
                C_FIFO_WR_DEPTH-1) begin
		
             //Add value on DIN port to FIFO
             write_fifo;
             next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH;

             //Write successful, so issue acknowledge
             // and no error
             ideal_wr_ack      <= #`TCQ 1;
             //This write is CAUSING the FIFO to go full

             ideal_wr_count    <= #`TCQ num_write_words_sized_i;

           //If the FIFO is 2 from full
           end else 
             if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD == 
                C_FIFO_WR_DEPTH-2) begin
             //Add value on DIN port to FIFO
   	    $display("two from full");
             write_fifo;
             next_num_wr_bits =  next_num_wr_bits + C_DIN_WIDTH;
             //Write successful, so issue acknowledge
             // and no error
             ideal_wr_ack      <= #`TCQ 1;
             //Still 2 from full

             ideal_wr_count    <= #`TCQ num_write_words_sized_i;

           //If the FIFO is not close to being full
           end else 
             if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD <
                C_FIFO_WR_DEPTH-2) begin
             //Add value on DIN port to FIFO
             write_fifo;
             next_num_wr_bits  = next_num_wr_bits + C_DIN_WIDTH;
             //Write successful, so issue acknowledge
             // and no error
             ideal_wr_ack      <= #`TCQ 1;
             //Not even close to full.

             ideal_wr_count    <= num_write_words_sized_i;

           end

         end

       end else begin //(WR_EN == 1'b1)

         //If user did not attempt a write, then do not
         // give ack or err
         ideal_wr_ack   <= #`TCQ 0;
         ideal_wr_count <= #`TCQ num_write_words_sized_i;
       end
       num_wr_bits       <= #`TCQ next_num_wr_bits;
       rd_ptr_wrclk      <= #`TCQ rd_ptr;

     end //wr_rst_i==0
   end // gen_fifo_w


  /***************************************************************************
   * Programmable FULL flags
   ***************************************************************************/

   wire [C_WR_PNTR_WIDTH-1:0] pf_thr_assert_val;
   wire [C_WR_PNTR_WIDTH-1:0] pf_thr_negate_val;

   generate if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) begin : FWFT
     assign pf_thr_assert_val = C_PROG_FULL_THRESH_ASSERT_VAL - EXTRA_WORDS_DC;
     assign pf_thr_negate_val = C_PROG_FULL_THRESH_NEGATE_VAL - EXTRA_WORDS_DC;
   end else begin // STD
     assign pf_thr_assert_val = C_PROG_FULL_THRESH_ASSERT_VAL;
     assign pf_thr_negate_val = C_PROG_FULL_THRESH_NEGATE_VAL;
   end endgenerate

   always @(posedge WR_CLK or posedge wr_rst_i) begin

     if (wr_rst_i == 1'b1) begin
       diff_pntr         <= 0;
     end else begin
       if (ram_wr_en)
         diff_pntr <= #`TCQ (wr_pntr - adj_rd_pntr_wr + 2'h1);
       else if (!ram_wr_en)
         diff_pntr <= #`TCQ (wr_pntr - adj_rd_pntr_wr);
    end
  end


   always @(posedge WR_CLK or posedge RST_FULL_FF) begin : gen_pf

     if (RST_FULL_FF == 1'b1) begin
       ideal_prog_full   <= #`TCQ C_FULL_FLAGS_RST_VAL;
     end else begin

       if (RST_FULL_GEN)
         ideal_prog_full   <= #`TCQ 0;
       //Single Programmable Full Constant Threshold
       else if (C_PROG_FULL_TYPE == 1) begin
         if (FULL == 0) begin
           if (diff_pntr >= pf_thr_assert_val)
             ideal_prog_full <= #`TCQ 1;
           else
             ideal_prog_full <= #`TCQ 0;
         end else
           ideal_prog_full   <= #`TCQ ideal_prog_full;
       //Two Programmable Full Constant Thresholds
       end else if (C_PROG_FULL_TYPE == 2) begin
         if (FULL == 0) begin
           if (diff_pntr >= pf_thr_assert_val)
             ideal_prog_full <= #`TCQ 1;
           else if (diff_pntr < pf_thr_negate_val)
             ideal_prog_full <= #`TCQ 0;
           else
             ideal_prog_full <= #`TCQ ideal_prog_full;
         end else
           ideal_prog_full   <= #`TCQ ideal_prog_full;
       //Single Programmable Full Threshold Input
       end else if (C_PROG_FULL_TYPE == 3) begin
         if (FULL == 0) begin
           if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) begin // FWFT
             if (diff_pntr >= (PROG_FULL_THRESH - EXTRA_WORDS_DC))
               ideal_prog_full <= #`TCQ 1;
             else
               ideal_prog_full <= #`TCQ 0;
           end else begin // STD
             if (diff_pntr >= PROG_FULL_THRESH)
               ideal_prog_full <= #`TCQ 1;
             else
               ideal_prog_full <= #`TCQ 0;
           end
         end else
           ideal_prog_full   <= #`TCQ ideal_prog_full;
       //Two Programmable Full Threshold Inputs
       end else if (C_PROG_FULL_TYPE == 4) begin
         if (FULL == 0) begin
           if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) begin // FWFT
             if (diff_pntr >= (PROG_FULL_THRESH_ASSERT - EXTRA_WORDS_DC))
               ideal_prog_full <= #`TCQ 1;
             else if (diff_pntr < (PROG_FULL_THRESH_NEGATE - EXTRA_WORDS_DC))
               ideal_prog_full <= #`TCQ 0;
             else
               ideal_prog_full <= #`TCQ ideal_prog_full;
           end else begin // STD
             if (diff_pntr >= PROG_FULL_THRESH_ASSERT)
               ideal_prog_full <= #`TCQ 1;
             else if (diff_pntr < PROG_FULL_THRESH_NEGATE)
               ideal_prog_full <= #`TCQ 0;
             else
               ideal_prog_full <= #`TCQ ideal_prog_full;
           end
         end else
           ideal_prog_full   <= #`TCQ ideal_prog_full;
       end // C_PROG_FULL_TYPE

     end //wr_rst_i==0
   end //

   
   /**************************************************************************
   * Read Domain Logic
   **************************************************************************/


   /*********************************************************
    * Programmable EMPTY flags
    *********************************************************/
   //Determine the Assert and Negate thresholds for Programmable Empty

   wire [C_RD_PNTR_WIDTH-1:0] pe_thr_assert_val;
   wire [C_RD_PNTR_WIDTH-1:0] pe_thr_negate_val;
   reg [C_RD_PNTR_WIDTH-1:0] diff_pntr_rd      = 0;

   always @(posedge RD_CLK or posedge rd_rst_i) begin : gen_pe

     if (rd_rst_i) begin
       diff_pntr_rd       <= #`TCQ 0;
       ideal_prog_empty   <= #`TCQ 1'b1;
     end else begin
       if (ram_rd_en)
         diff_pntr_rd       <=  #`TCQ (adj_wr_pntr_rd - rd_pntr) - 1'h1;
       else if (!ram_rd_en)
         diff_pntr_rd       <=  #`TCQ (adj_wr_pntr_rd - rd_pntr);
       else
         diff_pntr_rd       <=  #`TCQ diff_pntr_rd;
  
       if (C_PROG_EMPTY_TYPE == 1) begin
         if (EMPTY == 0) begin
           if (diff_pntr_rd <= pe_thr_assert_val)
             ideal_prog_empty <= #`TCQ 1;
           else
             ideal_prog_empty <= #`TCQ 0;
         end else
           ideal_prog_empty   <= #`TCQ ideal_prog_empty;
       end else if (C_PROG_EMPTY_TYPE == 2) begin
         if (EMPTY == 0) begin
           if (diff_pntr_rd <= pe_thr_assert_val)
             ideal_prog_empty <= #`TCQ 1;
           else if (diff_pntr_rd > pe_thr_negate_val)
             ideal_prog_empty <= #`TCQ 0;
           else
             ideal_prog_empty <= #`TCQ ideal_prog_empty;
         end else
           ideal_prog_empty   <= #`TCQ ideal_prog_empty;
       end else if (C_PROG_EMPTY_TYPE == 3) begin
         if (EMPTY == 0) begin
           if (diff_pntr_rd <= pe_thr_assert_val)
             ideal_prog_empty <= #`TCQ 1;
           else
             ideal_prog_empty <= #`TCQ 0;
         end else
           ideal_prog_empty   <= #`TCQ ideal_prog_empty;
       end else if (C_PROG_EMPTY_TYPE == 4) begin
         if (EMPTY == 0) begin
           if (diff_pntr_rd <= pe_thr_assert_val)
             ideal_prog_empty <= #`TCQ 1;
           else if (diff_pntr_rd > pe_thr_negate_val)
             ideal_prog_empty <= #`TCQ 0;
           else
             ideal_prog_empty <= #`TCQ ideal_prog_empty;
         end else
           ideal_prog_empty   <= #`TCQ ideal_prog_empty;
       end  //C_PROG_EMPTY_TYPE
     end
   end // gen_pe

   generate if (C_PROG_EMPTY_TYPE == 3) begin : single_pe_thr_input
     assign pe_thr_assert_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ?
                                PROG_EMPTY_THRESH - 2'h2 : PROG_EMPTY_THRESH;
   end endgenerate // single_pe_thr_input

   generate if (C_PROG_EMPTY_TYPE == 4) begin : multiple_pe_thr_input
     assign pe_thr_assert_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ?
                                PROG_EMPTY_THRESH_ASSERT - 2'h2 : PROG_EMPTY_THRESH_ASSERT;
     assign pe_thr_negate_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ?
                                PROG_EMPTY_THRESH_NEGATE - 2'h2 : PROG_EMPTY_THRESH_NEGATE;
   end endgenerate // multiple_pe_thr_input

   generate if (C_PROG_EMPTY_TYPE < 3) begin : single_multiple_pe_thr_const
     assign pe_thr_assert_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ?
                                C_PROG_EMPTY_THRESH_ASSERT_VAL - 2'h2 : C_PROG_EMPTY_THRESH_ASSERT_VAL;
     assign pe_thr_negate_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ?
                                C_PROG_EMPTY_THRESH_NEGATE_VAL - 2'h2 : C_PROG_EMPTY_THRESH_NEGATE_VAL;
   end endgenerate // single_multiple_pe_thr_const

   // block memory has a synchronous reset
   always @(posedge RD_CLK) begin : gen_fifo_blkmemdout
      // make it consistent with the core.
      if (rd_rst_i) begin
         // Reset err_type only if ECC is not selected
         if (C_USE_ECC == 0 && C_MEMORY_TYPE < 2)
            err_type <= #`TCQ 0;
   
         // BRAM resets synchronously
         if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2) begin
            ideal_dout    <= #`TCQ dout_reset_val;
            ideal_dout_d1 <= #`TCQ dout_reset_val;
         end
      end
   end //always

   always @(posedge RD_CLK or posedge rd_rst_i) begin : gen_fifo_r

     /****** Reset fifo (case 1)***************************************/
     if (rd_rst_i) begin
       num_rd_bits        <= #`TCQ 0;
       next_num_rd_bits    = #`TCQ 0;
       rd_ptr             <= #`TCQ C_RD_DEPTH -1;
       rd_pntr            <= #`TCQ 0;
       rd_pntr_wr1       <= #`TCQ 0;
       wr_ptr_rdclk       <= #`TCQ C_WR_DEPTH -1;
  
       // DRAM resets asynchronously
       if (C_MEMORY_TYPE == 2 && C_USE_DOUT_RST == 1)
          ideal_dout    <= #`TCQ dout_reset_val;
  
       // Reset err_type only if ECC is not selected
       if (C_USE_ECC == 0)
         err_type         <= #`TCQ 0;
       ideal_valid        <= #`TCQ 1'b0;
       ideal_rd_count     <= #`TCQ 0;

     end else begin //rd_rst_i==0

       rd_pntr_wr1   <= #`TCQ rd_pntr;

       //Determine the current number of words in the FIFO
       tmp_rd_listsize = (C_DEPTH_RATIO_WR > 1) ? num_rd_bits/C_DIN_WIDTH :
                         num_rd_bits/C_DOUT_WIDTH;
       wr_ptr_rdclk_next = wr_ptr;

       if (wr_ptr_rdclk < wr_ptr_rdclk_next) begin
         next_num_rd_bits = num_rd_bits +
                            C_DIN_WIDTH*(wr_ptr_rdclk +C_WR_DEPTH
                                         - wr_ptr_rdclk_next);
       end else begin
         next_num_rd_bits = num_rd_bits +
                             C_DIN_WIDTH*(wr_ptr_rdclk - wr_ptr_rdclk_next);
       end

       /*****************************************************************/
       // Read Operation - Read Latency 1
       /*****************************************************************/
       if (C_PRELOAD_LATENCY==1 || C_PRELOAD_LATENCY==2) begin
                 ideal_valid        <= #`TCQ 1'b0;

         if (ram_rd_en == 1'b1) begin

           if (EMPTY == 1'b1) begin

             //If the FIFO is completely empty, and is reporting empty
             if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0)
               begin
                 //Do not change the contents of the FIFO

                 //Do not acknowledge the read from empty FIFO
                 ideal_valid        <= #`TCQ 1'b0;
                 //Reminder that FIFO is still empty

                 ideal_rd_count     <= #`TCQ num_read_words_sized_i;
               end // if (tmp_rd_listsize <= 0)

             //If the FIFO is one from empty, but it is reporting empty
             else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1)
               begin
                 //Do not change the contents of the FIFO

                 //Do not acknowledge the read from empty FIFO
                 ideal_valid        <= #`TCQ 1'b0;
                 //Note that FIFO is no longer empty, but is almost empty (has one word left)

                 ideal_rd_count     <= #`TCQ num_read_words_sized_i;

               end // if (tmp_rd_listsize == 1)

             //If the FIFO is two from empty, and is reporting empty
             else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2)
               begin
                 //Do not change the contents of the FIFO

                 //Do not acknowledge the read from empty FIFO
                 ideal_valid        <= #`TCQ 1'b0;
                 //Fifo has two words, so is neither empty or almost empty

                 ideal_rd_count     <= #`TCQ num_read_words_sized_i;

               end // if (tmp_rd_listsize == 2)

             //If the FIFO is not close to empty, but is reporting that it is
             // Treat the FIFO as empty this time, but unset EMPTY flags.
             if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) && (tmp_rd_listsize/C_DEPTH_RATIO_WR<C_FIFO_RD_DEPTH))
               begin
                 //Do not change the contents of the FIFO

                 //Do not acknowledge the read from empty FIFO
                 ideal_valid <= #`TCQ 1'b0;
                 //Note that the FIFO is No Longer Empty or Almost Empty

                 ideal_rd_count <= #`TCQ num_read_words_sized_i;

               end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1))
             end // else: if(ideal_empty == 1'b1)

           else //if (ideal_empty == 1'b0)
             begin

               //If the FIFO is completely full, and we are successfully reading from it
               if (tmp_rd_listsize/C_DEPTH_RATIO_WR >= C_FIFO_RD_DEPTH)
                 begin
                   //Read the value from the FIFO
                   read_fifo;
                   next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;

                   //Acknowledge the read from the FIFO, no error
                   ideal_valid        <= #`TCQ 1'b1;
                   //Not close to empty

                   ideal_rd_count     <= #`TCQ num_read_words_sized_i;

                 end // if (tmp_rd_listsize == C_FIFO_RD_DEPTH)

               //If the FIFO is not close to being empty
               else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) && (tmp_rd_listsize/C_DEPTH_RATIO_WR<=C_FIFO_RD_DEPTH))
                 begin
                   //Read the value from the FIFO
                   read_fifo;
                   next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;

                   //Acknowledge the read from the FIFO, no error
                   ideal_valid        <= #`TCQ 1'b1;
                   //Not close to empty

                   ideal_rd_count     <= #`TCQ num_read_words_sized_i;

                 end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1))

               //If the FIFO is two from empty
               else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2)
                 begin
                   //Read the value from the FIFO
                   read_fifo;
                   next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;

                   //Acknowledge the read from the FIFO, no error
                   ideal_valid        <= #`TCQ 1'b1;
                   //Fifo is not yet empty. It is going almost_empty

                   ideal_rd_count     <= #`TCQ num_read_words_sized_i;

                 end // if (tmp_rd_listsize == 2)

               //If the FIFO is one from empty
               else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR == 1))
                 begin
                   //Read the value from the FIFO
                   read_fifo;
                   next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;

                   //Acknowledge the read from the FIFO, no error
                   ideal_valid        <= #`TCQ 1'b1;
                   //Note that FIFO is GOING empty

                   ideal_rd_count     <= #`TCQ num_read_words_sized_i;

                 end // if (tmp_rd_listsize == 1)


               //If the FIFO is completely empty
               else if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0)
                 begin
                   //Do not change the contents of the FIFO

                   //Do not acknowledge the read from empty FIFO
                   ideal_valid        <= #`TCQ 1'b0;

                   ideal_rd_count     <= #`TCQ num_read_words_sized_i;

                 end // if (tmp_rd_listsize <= 0)

             end // if (ideal_empty == 1'b0)

           end //(RD_EN == 1'b1)

         else //if (RD_EN == 1'b0)
           begin
             //If user did not attempt a read, do not give an ack or err
             ideal_valid          <= #`TCQ 1'b0;

             ideal_rd_count       <= #`TCQ num_read_words_sized_i;

           end // else: !if(RD_EN == 1'b1)

       /*****************************************************************/
       // Read Operation - Read Latency 0
       /*****************************************************************/
       end else if (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) begin
                 ideal_valid        <= #`TCQ 1'b0;
         if (ram_rd_en == 1'b1) begin

           if (EMPTY == 1'b1) begin

             //If the FIFO is completely empty, and is reporting empty
             if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0) begin
               //Do not change the contents of the FIFO

               //Do not acknowledge the read from empty FIFO
               ideal_valid        <= #`TCQ 1'b0;
               //Reminder that FIFO is still empty

               ideal_rd_count     <= #`TCQ num_read_words_sized_i;

             //If the FIFO is one from empty, but it is reporting empty
             end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1) begin
               //Do not change the contents of the FIFO

               //Do not acknowledge the read from empty FIFO
               ideal_valid        <= #`TCQ 1'b0;
               //Note that FIFO is no longer empty, but is almost empty (has one word left)

               ideal_rd_count     <= #`TCQ num_read_words_sized_i;

             //If the FIFO is two from empty, and is reporting empty
             end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2) begin
               //Do not change the contents of the FIFO

               //Do not acknowledge the read from empty FIFO
               ideal_valid        <= #`TCQ 1'b0;
               //Fifo has two words, so is neither empty or almost empty

               ideal_rd_count     <= #`TCQ num_read_words_sized_i;

               //If the FIFO is not close to empty, but is reporting that it is
             // Treat the FIFO as empty this time, but unset EMPTY flags.
             end else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) &&
                         (tmp_rd_listsize/C_DEPTH_RATIO_WR<C_FIFO_RD_DEPTH)) begin
               //Do not change the contents of the FIFO

               //Do not acknowledge the read from empty FIFO
               ideal_valid        <= #`TCQ 1'b0;
               //Note that the FIFO is No Longer Empty or Almost Empty

               ideal_rd_count     <= #`TCQ num_read_words_sized_i;

             end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1))

           end else begin

             //If the FIFO is completely full, and we are successfully reading from it
             if (tmp_rd_listsize/C_DEPTH_RATIO_WR >= C_FIFO_RD_DEPTH) begin
               //Read the value from the FIFO
               read_fifo;
               next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;

               //Acknowledge the read from the FIFO, no error
               ideal_valid        <= #`TCQ 1'b1;
               //Not close to empty

               ideal_rd_count     <= #`TCQ num_read_words_sized_i;

             //If the FIFO is not close to being empty
             end else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) &&
                          (tmp_rd_listsize/C_DEPTH_RATIO_WR<=C_FIFO_RD_DEPTH)) begin
               //Read the value from the FIFO
               read_fifo;
               next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;

               //Acknowledge the read from the FIFO, no error
               ideal_valid        <= #`TCQ 1'b1;
               //Not close to empty

               ideal_rd_count     <= #`TCQ num_read_words_sized_i;

             //If the FIFO is two from empty
             end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2) begin
               //Read the value from the FIFO
               read_fifo;
               next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;

               //Acknowledge the read from the FIFO, no error
               ideal_valid        <= #`TCQ 1'b1;
               //Fifo is not yet empty. It is going almost_empty

               ideal_rd_count     <= #`TCQ num_read_words_sized_i;

             //If the FIFO is one from empty
             end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1) begin
               //Read the value from the FIFO
               read_fifo;
               next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;

               //Acknowledge the read from the FIFO, no error
               ideal_valid        <= #`TCQ 1'b1;
               //Note that FIFO is GOING empty

               ideal_rd_count     <= #`TCQ num_read_words_sized_i;

             //If the FIFO is completely empty
             end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0) begin
               //Do not change the contents of the FIFO

               //Do not acknowledge the read from empty FIFO
               ideal_valid        <= #`TCQ 1'b0;
               //Reminder that FIFO is still empty

               ideal_rd_count     <= #`TCQ num_read_words_sized_i;

             end // if (tmp_rd_listsize <= 0)

           end // if (ideal_empty == 1'b0)

         end else begin//(RD_EN == 1'b0)

         
           //If user did not attempt a read, do not give an ack or err
           ideal_valid           <= #`TCQ 1'b0;
           ideal_rd_count        <= #`TCQ num_read_words_sized_i;

         end // else: !if(RD_EN == 1'b1)
       end //if (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0)

       num_rd_bits      <= #`TCQ next_num_rd_bits;
       wr_ptr_rdclk     <= #`TCQ wr_ptr;
     end //rd_rst_i==0
   end //always

endmodule // fifo_generator_v12_0_bhv_ver_as


/*******************************************************************************
 * Declaration of Low Latency Asynchronous FIFO
 ******************************************************************************/
module fifo_generator_v12_0_beh_ver_ll_afifo
   
  /***************************************************************************
   * Declare user parameters and their defaults
   ***************************************************************************/
  #(
    parameter  C_DIN_WIDTH                    = 8,
    parameter  C_DOUT_RST_VAL                 = "",
    parameter  C_DOUT_WIDTH                   = 8,
    parameter  C_FULL_FLAGS_RST_VAL           = 1,
    parameter  C_HAS_RD_DATA_COUNT            = 0,
    parameter  C_HAS_WR_DATA_COUNT            = 0,
    parameter  C_RD_DEPTH                     = 256,
    parameter  C_RD_PNTR_WIDTH                = 8,
    parameter  C_USE_DOUT_RST                 = 0,
    parameter  C_WR_DATA_COUNT_WIDTH          = 2,
    parameter  C_WR_DEPTH                     = 256,
    parameter  C_WR_PNTR_WIDTH                = 8,
    parameter  C_FIFO_TYPE                    = 0
   )

  /***************************************************************************
   * Declare Input and Output Ports
   ***************************************************************************/
  (
   input       [C_DIN_WIDTH-1:0]                 DIN,
   input                                         RD_CLK,
   input                                         RD_EN,
   input                                         WR_RST,
   input                                         RD_RST,
   input                                         WR_CLK,
   input                                         WR_EN,
   output reg  [C_DOUT_WIDTH-1:0]                DOUT = 0,
   output reg                                    EMPTY = 1'b1,
   output reg                                    FULL = C_FULL_FLAGS_RST_VAL
  );

  //-----------------------------------------------------------------------------
  // Low Latency Asynchronous FIFO
  //-----------------------------------------------------------------------------

  // Memory which will be used to simulate a FIFO
  reg [C_DIN_WIDTH-1:0] memory[C_WR_DEPTH-1:0];
  integer i;
  initial begin
    for (i = 0; i < C_WR_DEPTH; i = i + 1)
      memory[i] = 0;
  end

  reg  [C_WR_PNTR_WIDTH-1:0] wr_pntr_ll_afifo = 0;
  wire [C_RD_PNTR_WIDTH-1:0] rd_pntr_ll_afifo;
  reg  [C_RD_PNTR_WIDTH-1:0] rd_pntr_ll_afifo_q = 0;
  reg                        ll_afifo_full    = 1'b0;
  reg                        ll_afifo_empty   = 1'b1;
  wire                       write_allow;
  wire                       read_allow;

  assign write_allow = WR_EN & ~ll_afifo_full;
  assign read_allow  = RD_EN & ~ll_afifo_empty;

  //-----------------------------------------------------------------------------
  // Write Pointer Generation
  //-----------------------------------------------------------------------------
  always @(posedge WR_CLK or posedge WR_RST) begin
    if (WR_RST)
      wr_pntr_ll_afifo   <= 0;
    else if (write_allow)
      wr_pntr_ll_afifo <= #`TCQ wr_pntr_ll_afifo + 1;
  end

  //-----------------------------------------------------------------------------
  // Read Pointer Generation
  //-----------------------------------------------------------------------------
  always @(posedge RD_CLK or posedge RD_RST) begin
    if (RD_RST)
      rd_pntr_ll_afifo_q   <= 0;
    else
      rd_pntr_ll_afifo_q <= #`TCQ rd_pntr_ll_afifo;
  end
  assign rd_pntr_ll_afifo = read_allow ? rd_pntr_ll_afifo_q + 1 : rd_pntr_ll_afifo_q;
  
  //-----------------------------------------------------------------------------
  // Fill the Memory
  //-----------------------------------------------------------------------------
  always @(posedge WR_CLK) begin
    if (write_allow)
      memory[wr_pntr_ll_afifo] <= #`TCQ DIN;
  end

  //-----------------------------------------------------------------------------
  // Generate DOUT
  //-----------------------------------------------------------------------------
  always @(posedge RD_CLK) begin
      DOUT <= #`TCQ memory[rd_pntr_ll_afifo];
  end

  //-----------------------------------------------------------------------------
  // Generate EMPTY
  //-----------------------------------------------------------------------------
  always @(posedge RD_CLK or posedge RD_RST) begin
    if (RD_RST)
      ll_afifo_empty   <= 1'b1;
    else
      ll_afifo_empty   <= ((wr_pntr_ll_afifo == rd_pntr_ll_afifo_q) | 
                           (read_allow & (wr_pntr_ll_afifo == (rd_pntr_ll_afifo_q + 2'h1))));
  end

  //-----------------------------------------------------------------------------
  // Generate FULL
  //-----------------------------------------------------------------------------
  always @(posedge WR_CLK or posedge WR_RST) begin
    if (WR_RST)
      ll_afifo_full   <= 1'b1;
    else
      ll_afifo_full   <= ((rd_pntr_ll_afifo_q == (wr_pntr_ll_afifo + 2'h1)) | 
                           (write_allow & (rd_pntr_ll_afifo_q == (wr_pntr_ll_afifo + 2'h2))));
  end

  always @* begin
    FULL  <= ll_afifo_full;
    EMPTY <= ll_afifo_empty;
  end

endmodule // fifo_generator_v12_0_beh_ver_ll_afifo

/*******************************************************************************
 * Declaration of top-level module
 ******************************************************************************/
module fifo_generator_v12_0_bhv_ver_ss
   
  /**************************************************************************
   * Declare user parameters and their defaults
   *************************************************************************/
  #(
    parameter  C_FAMILY                       = "virtex7",
    parameter  C_DATA_COUNT_WIDTH             = 2,
    parameter  C_DIN_WIDTH                    = 8,
    parameter  C_DOUT_RST_VAL                 = "",
    parameter  C_DOUT_WIDTH                   = 8,
    parameter  C_FULL_FLAGS_RST_VAL           = 1,
    parameter  C_HAS_ALMOST_EMPTY             = 0,
    parameter  C_HAS_ALMOST_FULL              = 0,
    parameter  C_HAS_DATA_COUNT               = 0,
    parameter  C_HAS_OVERFLOW                 = 0,
    parameter  C_HAS_RD_DATA_COUNT            = 0,
    parameter  C_HAS_RST                      = 0,
    parameter  C_HAS_SRST                     = 0,
    parameter  C_HAS_UNDERFLOW                = 0,
    parameter  C_HAS_VALID                    = 0,
    parameter  C_HAS_WR_ACK                   = 0,
    parameter  C_HAS_WR_DATA_COUNT            = 0,
    parameter  C_IMPLEMENTATION_TYPE          = 0,
    parameter  C_MEMORY_TYPE                  = 1,
    parameter  C_OVERFLOW_LOW                 = 0,
    parameter  C_PRELOAD_LATENCY              = 1,
    parameter  C_PRELOAD_REGS                 = 0,
    parameter  C_PROG_EMPTY_THRESH_ASSERT_VAL = 0,
    parameter  C_PROG_EMPTY_THRESH_NEGATE_VAL = 0,
    parameter  C_PROG_EMPTY_TYPE              = 0,
    parameter  C_PROG_FULL_THRESH_ASSERT_VAL  = 0,
    parameter  C_PROG_FULL_THRESH_NEGATE_VAL  = 0,
    parameter  C_PROG_FULL_TYPE               = 0,
    parameter  C_RD_DATA_COUNT_WIDTH          = 2,
    parameter  C_RD_DEPTH                     = 256,
    parameter  C_RD_PNTR_WIDTH                = 8,
    parameter  C_UNDERFLOW_LOW                = 0,
    parameter  C_USE_DOUT_RST                 = 0,
    parameter  C_USE_EMBEDDED_REG             = 0,
    parameter  C_USE_FWFT_DATA_COUNT          = 0,
    parameter  C_VALID_LOW                    = 0,
    parameter  C_WR_ACK_LOW                   = 0,
    parameter  C_WR_DATA_COUNT_WIDTH          = 2,
    parameter  C_WR_DEPTH                     = 256,
    parameter  C_WR_PNTR_WIDTH                = 8,
    parameter  C_USE_ECC                      = 0, 
    parameter  C_ENABLE_RST_SYNC              = 1,
    parameter  C_ERROR_INJECTION_TYPE         = 0,
    parameter  C_FIFO_TYPE                    = 0 
   )
   
  /**************************************************************************
   * Declare Input and Output Ports
   *************************************************************************/
   (
    //Inputs
    input                                 CLK,
    input       [C_DIN_WIDTH-1:0]         DIN,
    input       [C_RD_PNTR_WIDTH-1:0]     PROG_EMPTY_THRESH,
    input       [C_RD_PNTR_WIDTH-1:0]     PROG_EMPTY_THRESH_ASSERT,
    input       [C_RD_PNTR_WIDTH-1:0]     PROG_EMPTY_THRESH_NEGATE,
    input       [C_WR_PNTR_WIDTH-1:0]     PROG_FULL_THRESH,
    input       [C_WR_PNTR_WIDTH-1:0]     PROG_FULL_THRESH_ASSERT,
    input       [C_WR_PNTR_WIDTH-1:0]     PROG_FULL_THRESH_NEGATE,
    input                                 RD_EN,
    input                                 RD_EN_USER,
    input                                 USER_EMPTY_FB,
    input                                 RST,
    input                                 RST_FULL_GEN,
    input                                 RST_FULL_FF,
    input                                 SRST,
    input                                 WR_EN,
    input                                 INJECTDBITERR,
    input                                 INJECTSBITERR,
    input                                 WR_RST_BUSY,
    input                                 RD_RST_BUSY,
                                    
    //Outputs                       
    output                                ALMOST_EMPTY,
    output                                ALMOST_FULL,
    output reg   [C_DATA_COUNT_WIDTH-1:0] DATA_COUNT = 0,
    output       [C_DOUT_WIDTH-1:0]       DOUT,
    output                                EMPTY,
    output                                FULL,
    output                                OVERFLOW,
    output [C_RD_DATA_COUNT_WIDTH-1:0]    RD_DATA_COUNT,
    output [C_WR_DATA_COUNT_WIDTH-1:0]    WR_DATA_COUNT,
    output                                PROG_EMPTY,
    output                                PROG_FULL,
    output                                VALID,
    output                                UNDERFLOW,
    output                                WR_ACK,
    output                                SBITERR,
    output                                DBITERR
   );


   reg  [C_RD_PNTR_WIDTH:0] rd_data_count_int = 0;
   reg  [C_WR_PNTR_WIDTH:0] wr_data_count_int = 0;
   wire [C_RD_PNTR_WIDTH:0] rd_data_count_i_ss;
   wire [C_WR_PNTR_WIDTH:0] wr_data_count_i_ss;
   reg  [C_WR_PNTR_WIDTH:0] wdc_fwft_ext_as = 0;
   /***************************************************************************
    * Parameters used as constants
    **************************************************************************/
  localparam IS_8SERIES         = (C_FAMILY == "virtexu" || C_FAMILY == "kintexu" || C_FAMILY == "artixu" || C_FAMILY == "virtexum" || C_FAMILY == "zynque") ? 1 : 0;
   localparam C_DEPTH_RATIO_WR =  
      (C_WR_DEPTH>C_RD_DEPTH) ? (C_WR_DEPTH/C_RD_DEPTH) : 1;
   localparam C_DEPTH_RATIO_RD =  
      (C_RD_DEPTH>C_WR_DEPTH) ? (C_RD_DEPTH/C_WR_DEPTH) : 1;
   //localparam C_FIFO_WR_DEPTH = C_WR_DEPTH - 1;
   //localparam C_FIFO_RD_DEPTH = C_RD_DEPTH - 1;
   localparam C_GRTR_PNTR_WIDTH = (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) ? C_WR_PNTR_WIDTH : C_RD_PNTR_WIDTH ; 


   //  C_DEPTH_RATIO_WR | C_DEPTH_RATIO_RD | C_PNTR_WIDTH    | EXTRA_WORDS_DC
   //  -----------------|------------------|-----------------|---------------
   //  1                | 8                | C_RD_PNTR_WIDTH | 2
   //  1                | 4                | C_RD_PNTR_WIDTH | 2
   //  1                | 2                | C_RD_PNTR_WIDTH | 2
   //  1                | 1                | C_WR_PNTR_WIDTH | 2
   //  2                | 1                | C_WR_PNTR_WIDTH | 4
   //  4                | 1                | C_WR_PNTR_WIDTH | 8
   //  8                | 1                | C_WR_PNTR_WIDTH | 16
   
   localparam C_PNTR_WIDTH  = (C_WR_PNTR_WIDTH>=C_RD_PNTR_WIDTH) ? C_WR_PNTR_WIDTH : C_RD_PNTR_WIDTH;
   wire [C_PNTR_WIDTH:0] EXTRA_WORDS_DC = (C_DEPTH_RATIO_WR == 1) ? 2 : (2 * C_DEPTH_RATIO_WR/C_DEPTH_RATIO_RD);
   wire [C_WR_PNTR_WIDTH:0] EXTRA_WORDS_PF = (C_DEPTH_RATIO_WR == 1) ? 2 : (2 * C_DEPTH_RATIO_WR/C_DEPTH_RATIO_RD);
   //wire [C_RD_PNTR_WIDTH:0] EXTRA_WORDS_PE = (C_DEPTH_RATIO_RD == 1) ? 2 : (2 * C_DEPTH_RATIO_RD/C_DEPTH_RATIO_WR);
   localparam  EXTRA_WORDS_PF_PARAM = (C_DEPTH_RATIO_WR == 1) ? 2 : (2 * C_DEPTH_RATIO_WR/C_DEPTH_RATIO_RD);
   //localparam  EXTRA_WORDS_PE_PARAM  = (C_DEPTH_RATIO_RD == 1) ? 2 : (2 * C_DEPTH_RATIO_RD/C_DEPTH_RATIO_WR);

   localparam [31:0] reads_per_write = C_DIN_WIDTH/C_DOUT_WIDTH;
   
   localparam [31:0] log2_reads_per_write = log2_val(reads_per_write);
   
   localparam [31:0] writes_per_read = C_DOUT_WIDTH/C_DIN_WIDTH;
   
   localparam [31:0] log2_writes_per_read = log2_val(writes_per_read);


   //When RST is present, set FULL reset value to '1'.
   //If core has no RST, make sure FULL powers-on as '0'.
   //The reset value assignments for FULL, ALMOST_FULL, and PROG_FULL are not 
   //changed for v3.2(IP2_Im). When the core has Sync Reset, C_HAS_SRST=1 and C_HAS_RST=0.
   // Therefore, during SRST, all the FULL flags reset to 0.
   localparam                      C_HAS_FAST_FIFO = 0;
   localparam                      C_FIFO_WR_DEPTH = C_WR_DEPTH;
   localparam                      C_FIFO_RD_DEPTH = C_RD_DEPTH;
   // Local parameters used to determine whether to inject ECC error or not
   localparam SYMMETRIC_PORT = (C_DIN_WIDTH == C_DOUT_WIDTH) ? 1 : 0;
   localparam ERR_INJECTION = (C_ERROR_INJECTION_TYPE != 0) ? 1 : 0;
   localparam ENABLE_ERR_INJECTION = C_USE_ECC && SYMMETRIC_PORT && ERR_INJECTION;
   localparam C_DATA_WIDTH = (ENABLE_ERR_INJECTION == 1) ? (C_DIN_WIDTH+2) : C_DIN_WIDTH;
   localparam IS_ASYMMETRY = (C_DIN_WIDTH == C_DOUT_WIDTH) ? 0 : 1;
   localparam LESSER_WIDTH = (C_RD_PNTR_WIDTH > C_WR_PNTR_WIDTH) ? C_WR_PNTR_WIDTH : C_RD_PNTR_WIDTH;
  localparam [C_RD_PNTR_WIDTH-1 : 0] DIFF_MAX_RD = {C_RD_PNTR_WIDTH{1'b1}}; 
  localparam [C_WR_PNTR_WIDTH-1 : 0] DIFF_MAX_WR = {C_WR_PNTR_WIDTH{1'b1}}; 


   /**************************************************************************
    * FIFO Contents Tracking and Data Count Calculations
    *************************************************************************/
   // Memory which will be used to simulate a FIFO
   reg [C_DIN_WIDTH-1:0] memory[C_WR_DEPTH-1:0];
   reg [1:0] ecc_err[C_WR_DEPTH-1:0];

   
   /**************************************************************************
    * Internal Registers and wires
    *************************************************************************/

   //Temporary signals used for calculating the model's outputs. These
   //are only used in the assign statements immediately following wire,
   //parameter, and function declarations.
   wire                           underflow_i;
   wire                           valid_i;
   wire                           valid_out;
   reg [31:0]  num_wr_bits;
   reg [31:0]  num_rd_bits;
   reg [31:0]  next_num_wr_bits;
   reg [31:0]  next_num_rd_bits;

   //The write pointer - tracks write operations
   // (Works opposite to core: wr_ptr is a DOWN counter)
   reg  [31:0]                 wr_ptr;
   reg  [C_WR_PNTR_WIDTH-1:0]  wr_pntr_rd1    = 0;
   reg  [C_WR_PNTR_WIDTH-1:0]  wr_pntr_rd2    = 0;
   reg  [C_WR_PNTR_WIDTH-1:0]  wr_pntr_rd3    = 0;
   reg  [C_WR_PNTR_WIDTH-1:0]  wr_pntr_rd     = 0;
   reg                         wr_rst_d1      =0;

   //The read pointer - tracks read operations
   // (rd_ptr Works opposite to core: rd_ptr is a DOWN counter)
   reg  [31:0]                 rd_ptr;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr1 = 0;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr2 = 0;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr3 = 0;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr4 = 0;
   reg  [C_RD_PNTR_WIDTH-1:0]  rd_pntr_wr  = 0;

   wire                        ram_rd_en;
   wire                        empty_int;
   wire                        almost_empty_int;
   wire                        ram_wr_en;
   wire                        full_int;
   wire                        almost_full_int;
   reg                         ram_rd_en_reg = 1'b0;



   //Ideal FIFO signals. These are the raw output of the behavioral model,
   //which behaves like an ideal FIFO.
   reg [1:0]                      err_type           = 0;
   reg [1:0]                      err_type_d1        = 0;
   reg  [C_DOUT_WIDTH-1:0]        ideal_dout         = 0;
   reg  [C_DOUT_WIDTH-1:0]        ideal_dout_d1      = 0;
   wire [C_DOUT_WIDTH-1:0]        ideal_dout_out;
   wire                           fwft_enabled;
   reg                            ideal_wr_ack       = 0;
   reg                            ideal_valid        = 0;
   reg                            ideal_overflow     = C_OVERFLOW_LOW;
   reg                            ideal_underflow    = C_UNDERFLOW_LOW;

   reg                            full_i             = C_FULL_FLAGS_RST_VAL;
   reg                            full_i_temp        = 0;
   reg                            empty_i            = 1;
   reg                            almost_full_i      = 0;
   reg                            almost_empty_i     = 1;
   reg                            prog_full_i        = 0;
   reg                            prog_empty_i       = 1;
   reg [C_WR_PNTR_WIDTH-1:0]      wr_pntr            = 0;
   reg [C_RD_PNTR_WIDTH-1:0]      rd_pntr            = 0;
   wire [C_RD_PNTR_WIDTH-1:0]  adj_wr_pntr_rd;
   wire [C_WR_PNTR_WIDTH-1:0]  adj_rd_pntr_wr;
   reg [C_RD_PNTR_WIDTH-1:0]      diff_count         = 0;

   reg                            write_allow_q      = 0;
   reg                            read_allow_q       = 0;
   reg                            valid_d1           = 0;
   wire                           rst_i;
   wire                           srst_i;

   //user specified value for reseting the size of the fifo
   reg [C_DOUT_WIDTH-1:0]         dout_reset_val = 0;

   reg [31:0]  wr_ptr_rdclk;
   reg [31:0]  wr_ptr_rdclk_next;
   reg [31:0]  rd_ptr_wrclk;
   reg [31:0]  rd_ptr_wrclk_next;




   /****************************************************************************
    * Function Declarations
    ***************************************************************************/

   /****************************************************************************
    * hexstr_conv
    *   Converts a string of type hex to a binary value (for C_DOUT_RST_VAL)
    ***************************************************************************/
    function [C_DOUT_WIDTH-1:0] hexstr_conv;
    input [(C_DOUT_WIDTH*8)-1:0] def_data;

    integer index,i,j;
    reg [3:0] bin;

    begin
      index = 0;
      hexstr_conv = 'b0;
      for( i=C_DOUT_WIDTH-1; i>=0; i=i-1 ) begin
        case (def_data[7:0])
          8'b00000000 : begin
            bin = 4'b0000;
            i = -1;
          end
          8'b00110000 : bin = 4'b0000;
          8'b00110001 : bin = 4'b0001;
          8'b00110010 : bin = 4'b0010;
          8'b00110011 : bin = 4'b0011;
          8'b00110100 : bin = 4'b0100;
          8'b00110101 : bin = 4'b0101;
          8'b00110110 : bin = 4'b0110;
          8'b00110111 : bin = 4'b0111;
          8'b00111000 : bin = 4'b1000;
          8'b00111001 : bin = 4'b1001;
          8'b01000001 : bin = 4'b1010;
          8'b01000010 : bin = 4'b1011;
          8'b01000011 : bin = 4'b1100;
          8'b01000100 : bin = 4'b1101;
          8'b01000101 : bin = 4'b1110;
          8'b01000110 : bin = 4'b1111;
          8'b01100001 : bin = 4'b1010;
          8'b01100010 : bin = 4'b1011;
          8'b01100011 : bin = 4'b1100;
          8'b01100100 : bin = 4'b1101;
          8'b01100101 : bin = 4'b1110;
          8'b01100110 : bin = 4'b1111;
          default : begin
            bin = 4'bx;
          end
        endcase
        for( j=0; j<4; j=j+1) begin
          if ((index*4)+j < C_DOUT_WIDTH) begin
            hexstr_conv[(index*4)+j] = bin[j];
          end
        end
        index = index + 1;
        def_data = def_data >> 8;
      end
    end
  endfunction
 /**************************************************************************
  * log2_val
  *   Returns the 'log2' value for the input value for the supported ratios
  ***************************************************************************/
  function [31:0] log2_val;
    input [31:0] binary_val;

    begin
      if (binary_val == 8) begin
        log2_val = 3;
      end else if (binary_val == 4) begin
        log2_val = 2;
      end else begin
        log2_val = 1;
      end
    end
  endfunction

   reg                     ideal_prog_full          = 0;
   reg                     ideal_prog_empty         = 1;
   reg [C_WR_DATA_COUNT_WIDTH-1 : 0] ideal_wr_count = 0;
   reg [C_RD_DATA_COUNT_WIDTH-1 : 0] ideal_rd_count = 0;

   //Assorted reg values for delayed versions of signals   
   //reg         valid_d1     = 0;
   
   
   //user specified value for reseting the size of the fifo
   //reg [C_DOUT_WIDTH-1:0]            dout_reset_val = 0;
   
   //temporary registers for WR_RESPONSE_LATENCY feature
   
   integer                           tmp_wr_listsize;
   integer                           tmp_rd_listsize;
   
   //Signal for registered version of prog full and empty
   
   //Threshold values for Programmable Flags
   integer                           prog_empty_actual_thresh_assert;
   integer                           prog_empty_actual_thresh_negate;
   integer                           prog_full_actual_thresh_assert;
   integer                           prog_full_actual_thresh_negate;


 /**************************************************************************
   * write_fifo
   *   This task writes a word to the FIFO memory and updates the 
   * write pointer.
   *   FIFO size is relative to write domain.
  ***************************************************************************/
  task write_fifo;
    begin
      memory[wr_ptr]     <= DIN;
      wr_pntr <= #`TCQ wr_pntr + 1;
      // Store the type of error injection (double/single) on write
      case (C_ERROR_INJECTION_TYPE)
        3:       ecc_err[wr_ptr]    <= {INJECTDBITERR,INJECTSBITERR};
        2:       ecc_err[wr_ptr]    <= {INJECTDBITERR,1'b0};
        1:       ecc_err[wr_ptr]    <= {1'b0,INJECTSBITERR};
        default: ecc_err[wr_ptr]    <= 0;
      endcase
      // (Works opposite to core: wr_ptr is a DOWN counter)
      if (wr_ptr == 0) begin
        wr_ptr          <= C_WR_DEPTH - 1;
      end else begin
        wr_ptr          <= wr_ptr - 1;
      end
    end
  endtask // write_fifo

  /**************************************************************************
   * read_fifo
   *   This task reads a word from the FIFO memory and updates the read 
   * pointer. It's output is the ideal_dout bus.
   *   FIFO size is relative to write domain.
   ***************************************************************************/
  task read_fifo;
    integer i;
    reg [C_DOUT_WIDTH-1:0]      tmp_dout;
    reg [C_DIN_WIDTH-1:0]       memory_read;
    reg [31:0]                  tmp_rd_ptr;
    reg [31:0]                  rd_ptr_high;
    reg [31:0]                  rd_ptr_low;
    reg [1:0]                   tmp_ecc_err;
    begin
      rd_pntr <= #`TCQ rd_pntr + 1;

      // output is wider than input
      if (reads_per_write == 0) begin
        tmp_dout = 0;
        tmp_rd_ptr = (rd_ptr << log2_writes_per_read)+(writes_per_read-1);
        for (i = writes_per_read - 1; i >= 0; i = i - 1) begin
          tmp_dout = tmp_dout << C_DIN_WIDTH;
          tmp_dout = tmp_dout | memory[tmp_rd_ptr];
           
          // (Works opposite to core: rd_ptr is a DOWN counter)
          if (tmp_rd_ptr == 0) begin
            tmp_rd_ptr = C_WR_DEPTH - 1;
          end else begin
            tmp_rd_ptr = tmp_rd_ptr - 1;
          end
        end

      // output is symmetric
      end else if (reads_per_write == 1) begin
        tmp_dout = memory[rd_ptr][C_DIN_WIDTH-1:0];
        // Retreive the error injection type. Based on the error injection type
        // corrupt the output data.
        tmp_ecc_err = ecc_err[rd_ptr];
        if (ENABLE_ERR_INJECTION && C_DIN_WIDTH == C_DOUT_WIDTH) begin
          if (tmp_ecc_err[1]) begin // Corrupt the output data only for double bit error
            if (C_DOUT_WIDTH == 1) begin
              $display("FAILURE : Data width must be >= 2 for double bit error injection.");
              $finish;
            end else if (C_DOUT_WIDTH == 2)
              tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2]};
            else
              tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2],(tmp_dout << 2)};
          end else begin
            tmp_dout = tmp_dout[C_DOUT_WIDTH-1:0];
          end
          err_type <= {tmp_ecc_err[1], tmp_ecc_err[0] & !tmp_ecc_err[1]};
        end else begin
          err_type <= 0;
        end

      // input is wider than output
      end else begin
        rd_ptr_high = rd_ptr >> log2_reads_per_write;
        rd_ptr_low  = rd_ptr & (reads_per_write - 1);
        memory_read = memory[rd_ptr_high];
        tmp_dout    = memory_read >> (rd_ptr_low*C_DOUT_WIDTH);
      end
      ideal_dout <= tmp_dout;
       
      // (Works opposite to core: rd_ptr is a DOWN counter)
     if (rd_ptr == 0) begin
        rd_ptr <= C_RD_DEPTH - 1;
      end else begin
        rd_ptr <= rd_ptr - 1;
      end

     end
  endtask


   
  /*************************************************************************
  * Initialize Signals for clean power-on simulation
  *************************************************************************/
   initial begin
      num_wr_bits        = 0;
      num_rd_bits        = 0;
      next_num_wr_bits   = 0;
      next_num_rd_bits   = 0;
      rd_ptr             = C_RD_DEPTH - 1;
      wr_ptr             = C_WR_DEPTH - 1;
      wr_pntr            = 0;
      rd_pntr            = 0;
      rd_ptr_wrclk       = rd_ptr;
      wr_ptr_rdclk       = wr_ptr;
      dout_reset_val     = hexstr_conv(C_DOUT_RST_VAL);
      ideal_dout         = dout_reset_val;
      err_type           = 0;
      ideal_dout_d1      = dout_reset_val;
      ideal_wr_ack       = 1'b0;
      ideal_valid        = 1'b0;
      valid_d1           = 1'b0;
      ideal_overflow     = C_OVERFLOW_LOW;
      ideal_underflow    = C_UNDERFLOW_LOW;
      ideal_wr_count     = 0;
      ideal_rd_count     = 0;
      ideal_prog_full    = 1'b0;
      ideal_prog_empty   = 1'b1;

   end


  /*************************************************************************
   * Connect the module inputs and outputs to the internal signals of the
   * behavioral model.
   *************************************************************************/
   //Inputs
   /*
   wire CLK;
   wire [C_DIN_WIDTH-1:0] DIN;
   wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH;
   wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT;
   wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE;
   wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH;
   wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT;
   wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE;
   wire RD_EN;
   wire RST;
   wire WR_EN;
    */

  // Assign ALMOST_EPMTY
  generate if (C_HAS_ALMOST_EMPTY == 1) begin : gae
    assign ALMOST_EMPTY = almost_empty_i;
  end else begin : gnae
    assign ALMOST_EMPTY = 0;
  end endgenerate // gae

  // Assign ALMOST_FULL
  generate if (C_HAS_ALMOST_FULL==1) begin : gaf
    assign ALMOST_FULL  = almost_full_i;
  end else begin : gnaf
    assign ALMOST_FULL  = 0;
  end endgenerate // gaf

   // Dout may change behavior based on latency
  assign fwft_enabled = (C_PRELOAD_LATENCY == 0 && C_PRELOAD_REGS == 1)?
                         1: 0;
  assign ideal_dout_out= ((C_USE_EMBEDDED_REG==1 && (fwft_enabled == 0)) &&
                          (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1))?
                         ideal_dout_d1: ideal_dout; 
  assign DOUT = ideal_dout_out;

  // Assign SBITERR and DBITERR based on latency 
  assign SBITERR = (C_ERROR_INJECTION_TYPE == 1 || C_ERROR_INJECTION_TYPE == 3) && 
                   ((C_USE_EMBEDDED_REG==1 && (fwft_enabled == 0)) &&
                    (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ?
                   err_type_d1[0]: err_type[0]; 
  assign DBITERR = (C_ERROR_INJECTION_TYPE == 2 || C_ERROR_INJECTION_TYPE == 3) &&
                   ((C_USE_EMBEDDED_REG==1 && (fwft_enabled == 0)) &&
                    (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ?
                   err_type_d1[1]: err_type[1]; 

  assign EMPTY         = empty_i;
  assign FULL          = full_i;

  //Overflow may be active-low
  generate if (C_HAS_OVERFLOW==1) begin : gof
    assign OVERFLOW = ideal_overflow ? !C_OVERFLOW_LOW : C_OVERFLOW_LOW;
  end else begin : gnof
    assign OVERFLOW = 0;
  end endgenerate // gof

  assign PROG_EMPTY    = prog_empty_i;
  assign PROG_FULL     = prog_full_i;

   //Valid may change behavior based on latency or active-low
  generate if (C_HAS_VALID==1) begin : gvalid
    assign valid_i       = (C_PRELOAD_LATENCY == 0) ? (RD_EN & ~EMPTY) : ideal_valid;
    assign valid_out     = (C_PRELOAD_LATENCY == 2 && C_MEMORY_TYPE < 2) ?
                            valid_d1 : valid_i; 
    assign VALID         = valid_out ? !C_VALID_LOW : C_VALID_LOW;
  end else begin : gnvalid
    assign VALID         = 0;
  end endgenerate // gvalid

  //Trim data count differently depending on set widths
  generate if (C_HAS_DATA_COUNT == 1) begin : gdc
    always @* begin
      diff_count <= wr_pntr - rd_pntr;
      if (C_DATA_COUNT_WIDTH > C_RD_PNTR_WIDTH) begin
        DATA_COUNT[C_RD_PNTR_WIDTH-1:0]  <= diff_count;
        DATA_COUNT[C_DATA_COUNT_WIDTH-1] <= 1'b0 ; 
      end else begin
        DATA_COUNT <= diff_count[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_DATA_COUNT_WIDTH];
      end
    end
//  end else begin : gndc
//    always @* DATA_COUNT <= 0;
  end endgenerate // gdc

  //Underflow may change behavior based on latency or active-low
  generate if (C_HAS_UNDERFLOW==1) begin : guf
    assign underflow_i   = ideal_underflow;
    assign UNDERFLOW     = underflow_i ? !C_UNDERFLOW_LOW : C_UNDERFLOW_LOW;
  end else begin : gnuf
    assign UNDERFLOW     = 0;
  end endgenerate // guf
 

  //Write acknowledge may be active low 
  generate if (C_HAS_WR_ACK==1) begin : gwr_ack
    assign WR_ACK        = ideal_wr_ack ? !C_WR_ACK_LOW : C_WR_ACK_LOW;
  end else begin : gnwr_ack
    assign WR_ACK        = 0;
  end endgenerate // gwr_ack


  /*****************************************************************************
   * Internal reset logic 
   ****************************************************************************/
  assign srst_i           = C_HAS_SRST ? SRST : 0;
  assign srst_wrst_busy   = C_HAS_SRST ? (SRST || WR_RST_BUSY)  : 0;
  assign srst_rrst_busy   = C_HAS_SRST ? (SRST || RD_RST_BUSY)  : 0;
  assign rst_i            = C_HAS_RST ? RST : 0;

   /**************************************************************************
    * Assorted registers for delayed versions of signals
    **************************************************************************/
   //Capture delayed version of valid
   generate if (C_HAS_VALID == 1) begin : blockVL20
     always @(posedge CLK or posedge rst_i) begin
        if (rst_i == 1'b1) begin
           valid_d1 <= #`TCQ 1'b0;
        end else begin
           if (srst_rrst_busy) begin
              valid_d1 <= #`TCQ 1'b0;
           end else begin
              valid_d1 <= #`TCQ valid_i;
           end
        end    
     end // always @ (posedge CLK or posedge rst_i)
   end endgenerate // blockVL20

   // Determine which stage in FWFT registers are valid
   reg stage1_valid = 0;
   reg stage2_valid = 0;
   generate
     if (C_PRELOAD_LATENCY == 0) begin : grd_fwft_proc
       always @ (posedge CLK or posedge rst_i) begin
         if (rst_i) begin
           stage1_valid     <= #`TCQ 0;
           stage2_valid     <= #`TCQ 0;
         end else begin

           if (!stage1_valid && !stage2_valid) begin
             if (!EMPTY)
               stage1_valid    <= #`TCQ 1'b1;
             else
               stage1_valid    <= #`TCQ 1'b0;
           end else if (stage1_valid && !stage2_valid) begin
             if (EMPTY) begin
               stage1_valid    <= #`TCQ 1'b0;
               stage2_valid    <= #`TCQ 1'b1;
             end else begin
               stage1_valid    <= #`TCQ 1'b1;
               stage2_valid    <= #`TCQ 1'b1;
             end
           end else if (!stage1_valid && stage2_valid) begin
             if (EMPTY && RD_EN) begin
               stage1_valid    <= #`TCQ 1'b0;
               stage2_valid    <= #`TCQ 1'b0;
             end else if (!EMPTY && RD_EN) begin
               stage1_valid    <= #`TCQ 1'b1;
               stage2_valid    <= #`TCQ 1'b0;
             end else if (!EMPTY && !RD_EN) begin
               stage1_valid    <= #`TCQ 1'b1;
               stage2_valid    <= #`TCQ 1'b1;
             end else begin
               stage1_valid    <= #`TCQ 1'b0;
               stage2_valid    <= #`TCQ 1'b1;
             end
           end else if (stage1_valid && stage2_valid) begin
             if (EMPTY && RD_EN) begin
               stage1_valid    <= #`TCQ 1'b0;
               stage2_valid    <= #`TCQ 1'b1;
             end else begin
               stage1_valid    <= #`TCQ 1'b1;
               stage2_valid    <= #`TCQ 1'b1;
             end
           end else begin
             stage1_valid    <= #`TCQ 1'b0;
             stage2_valid    <= #`TCQ 1'b0;
           end
         end // rd_rst_i
       end // always
     end
   endgenerate



   //***************************************************************************
   // Assign the read data count value only if it is selected, 
   // otherwise output zeros.
   //***************************************************************************
   generate
      if (C_HAS_RD_DATA_COUNT == 1 && C_USE_FWFT_DATA_COUNT ==1) begin : grdc
       assign RD_DATA_COUNT[C_RD_DATA_COUNT_WIDTH-1:0] = rd_data_count_i_ss[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH+1-C_RD_DATA_COUNT_WIDTH];
      end
   endgenerate

   generate
      if (C_HAS_RD_DATA_COUNT == 0) begin : gnrdc
   assign RD_DATA_COUNT[C_RD_DATA_COUNT_WIDTH-1:0] = {C_RD_DATA_COUNT_WIDTH{1'b0}};
      end
   endgenerate

   //***************************************************************************
   // Assign the write data count value only if it is selected, 
   // otherwise output zeros
   //***************************************************************************
   generate
      if (C_HAS_WR_DATA_COUNT == 1 && C_USE_FWFT_DATA_COUNT == 1) begin : gwdc
       assign WR_DATA_COUNT[C_WR_DATA_COUNT_WIDTH-1:0] = wr_data_count_i_ss[C_WR_PNTR_WIDTH:C_WR_PNTR_WIDTH+1-C_WR_DATA_COUNT_WIDTH] ;
      end
   endgenerate
   
   generate
      if (C_HAS_WR_DATA_COUNT == 0) begin : gnwdc
   assign WR_DATA_COUNT[C_WR_DATA_COUNT_WIDTH-1:0] = {C_WR_DATA_COUNT_WIDTH{1'b0}};
      end
   endgenerate


  
   
   // block memory has a synchronous reset
   generate if (C_MEMORY_TYPE < 2) begin : gen_fifo_blkmemdout_emb
     always @(posedge CLK) begin
       // BRAM resets synchronously
       // make it consistent with the core.
       if ((rst_i || srst_rrst_busy) && (C_USE_DOUT_RST == 1))
         ideal_dout_d1 <= #`TCQ dout_reset_val;
     end //always
   end endgenerate // gen_fifo_blkmemdout_emb
   
   reg ram_rd_en_d1 = 1'b0;
   //Capture delayed version of dout
   always @(posedge CLK or posedge rst_i) begin
      if (rst_i == 1'b1) begin
         // Reset err_type only if ECC is not selected
         if (C_USE_ECC == 0)
            err_type_d1      <= #`TCQ 0;
  
         // DRAM and SRAM reset asynchronously
         if ((C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3) && C_USE_DOUT_RST == 1)
            ideal_dout_d1 <= #`TCQ dout_reset_val;
  
         ram_rd_en_d1 <= #`TCQ 1'b0;
      end else begin
         ram_rd_en_d1 <= #`TCQ RD_EN & ~EMPTY;
         if (srst_rrst_busy) begin
            ram_rd_en_d1 <= #`TCQ 1'b0;
            // Reset err_type only if ECC is not selected
            if (C_USE_ECC == 0)
               err_type_d1   <= #`TCQ 0;
            // Reset DRAM and SRAM based FIFO, BRAM based FIFO is reset above
            if ((C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3) && C_USE_DOUT_RST == 1)
               ideal_dout_d1 <= #`TCQ dout_reset_val;
         end else if (ram_rd_en_d1) begin
            ideal_dout_d1 <= #`TCQ ideal_dout;
            err_type_d1   <= #`TCQ err_type;
         end
      end    
   end   

   /**************************************************************************
    * Overflow and Underflow Flag calculation
    *  (handled separately because they don't support rst)
    **************************************************************************/
   generate if (C_HAS_OVERFLOW == 1 && IS_8SERIES == 0) begin : g7s_ovflw
     always @(posedge CLK) begin
       ideal_overflow    <= #`TCQ WR_EN & full_i;
     end
   end else if (C_HAS_OVERFLOW == 1 && IS_8SERIES == 1) begin : g8s_ovflw
     always @(posedge CLK) begin
       //ideal_overflow    <= #`TCQ WR_EN & (rst_i | full_i);
       ideal_overflow    <= #`TCQ WR_EN & (WR_RST_BUSY | full_i);
     end
   end endgenerate // blockOF20
 
   generate if (C_HAS_UNDERFLOW == 1 && IS_8SERIES == 0) begin : g7s_unflw
     always @(posedge CLK) begin
       ideal_underflow   <= #`TCQ empty_i & RD_EN;
     end
   end else if (C_HAS_UNDERFLOW == 1 && IS_8SERIES == 1) begin : g8s_unflw
     always @(posedge CLK) begin
       //ideal_underflow   <= #`TCQ (rst_i | empty_i) & RD_EN;
       ideal_underflow   <= #`TCQ (RD_RST_BUSY | empty_i) & RD_EN;
     end
   end endgenerate // blockUF20


   /**************************
    * Read Data Count
    *************************/

   reg [31:0] num_read_words_dc;
   reg [C_RD_DATA_COUNT_WIDTH-1:0] num_read_words_sized_i;
   
   always @(num_rd_bits) begin
     if (C_USE_FWFT_DATA_COUNT) begin
        
        //If using extra logic for FWFT Data Counts, 
        // then scale FIFO contents to read domain, 
        // and add two read words for FWFT stages
        //This value is only a temporary value and not used in the code.
        num_read_words_dc = (num_rd_bits/C_DOUT_WIDTH+2);
        
        //Trim the read words for use with RD_DATA_COUNT
        num_read_words_sized_i = 
          num_read_words_dc[C_RD_PNTR_WIDTH : C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH+1];
        
     end else begin
        
        //If not using extra logic for FWFT Data Counts, 
        // then scale FIFO contents to read domain.
        //This value is only a temporary value and not used in the code.
        num_read_words_dc = num_rd_bits/C_DOUT_WIDTH;
        
        //Trim the read words for use with RD_DATA_COUNT
        num_read_words_sized_i = 
          num_read_words_dc[C_RD_PNTR_WIDTH-1 : C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH];
        
     end //if (C_USE_FWFT_DATA_COUNT)
   end //always

   
   /**************************
    * Write Data Count
    *************************/

   reg [31:0] num_write_words_dc;
   reg [C_WR_DATA_COUNT_WIDTH-1:0] num_write_words_sized_i;
   
   always @(num_wr_bits) begin
     if (C_USE_FWFT_DATA_COUNT) begin
        
        //Calculate the Data Count value for the number of write words, 
        // when using First-Word Fall-Through with extra logic for Data 
        // Counts. This takes into consideration the number of words that 
        // are expected to be stored in the FWFT register stages (it always 
        // assumes they are filled).
        //This value is scaled to the Write Domain.
        //The expression (((A-1)/B))+1 divides A/B, but takes the 
        // ceiling of the result.
        //When num_wr_bits==0, set the result manually to prevent 
        // division errors.
        //EXTRA_WORDS_DC is the number of words added to write_words 
        // due to FWFT.
        //This value is only a temporary value and not used in the code.
        num_write_words_dc = (num_wr_bits==0) ? EXTRA_WORDS_DC :  (((num_wr_bits-1)/C_DIN_WIDTH)+1) + EXTRA_WORDS_DC ;
        
        //Trim the write words for use with WR_DATA_COUNT
        num_write_words_sized_i = 
          num_write_words_dc[C_WR_PNTR_WIDTH : C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH+1];
        
     end else begin
        
        //Calculate the Data Count value for the number of write words, when NOT
        // using First-Word Fall-Through with extra logic for Data Counts. This 
        // calculates only the number of words in the internal FIFO.
        //The expression (((A-1)/B))+1 divides A/B, but takes the 
        // ceiling of the result.
        //This value is scaled to the Write Domain.
        //When num_wr_bits==0, set the result manually to prevent 
        // division errors.
        //This value is only a temporary value and not used in the code.
        num_write_words_dc = (num_wr_bits==0) ? 0 : ((num_wr_bits-1)/C_DIN_WIDTH)+1;
        
        //Trim the read words for use with RD_DATA_COUNT
        num_write_words_sized_i = 
          num_write_words_dc[C_WR_PNTR_WIDTH-1 : C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH];
        
     end //if (C_USE_FWFT_DATA_COUNT)
   end //always


  /*************************************************************************
   * Write and Read Logic  
   ************************************************************************/
   wire              write_allow;
   wire              read_allow;
   wire              read_allow_dc;
   wire              write_only;
   wire              read_only;
   //wire              write_only_q;
   reg              write_only_q;
   //wire              read_only_q;
   reg              read_only_q;
   reg              full_reg;
   reg              rst_full_ff_reg1;
   reg              rst_full_ff_reg2;
   wire              ram_full_comb;
   wire              carry;
   
   assign write_allow  = WR_EN & ~full_i;
   assign read_allow   = RD_EN & ~empty_i;
   assign read_allow_dc = RD_EN_USER & ~USER_EMPTY_FB;
   //assign write_only   = write_allow & ~read_allow;
   //assign write_only_q = write_allow_q;
   //assign read_only    = read_allow    & ~write_allow;
   //assign read_only_q  = read_allow_q ;
   wire [C_WR_PNTR_WIDTH-1:0] diff_pntr;
   wire [C_RD_PNTR_WIDTH-1:0] diff_pntr_pe;
   reg [C_WR_PNTR_WIDTH-1:0] diff_pntr_reg1 = 0;
   reg [C_RD_PNTR_WIDTH-1:0] diff_pntr_pe_reg1 = 0;
   reg [C_RD_PNTR_WIDTH:0] diff_pntr_pe_asym = 0;
   wire [C_RD_PNTR_WIDTH:0] adj_wr_pntr_rd_asym ;
   wire [C_RD_PNTR_WIDTH:0] rd_pntr_asym;
   reg [C_WR_PNTR_WIDTH-1:0] diff_pntr_reg2 = 0;
   reg [C_WR_PNTR_WIDTH-1:0] diff_pntr_pe_reg2 = 0;
   wire [C_RD_PNTR_WIDTH-1:0] diff_pntr_pe_max;
   wire [C_RD_PNTR_WIDTH-1:0] diff_pntr_max;

   assign diff_pntr_pe_max = DIFF_MAX_RD;
   assign diff_pntr_max = DIFF_MAX_WR;



   generate if (IS_ASYMMETRY == 0) begin : diff_pntr_sym
    assign write_only   = write_allow & ~read_allow;
    assign read_only    = read_allow    & ~write_allow;
    end endgenerate
    generate if ( IS_ASYMMETRY == 1 && C_WR_PNTR_WIDTH < C_RD_PNTR_WIDTH) begin : wr_grt_rd
     assign read_only   = read_allow & &(rd_pntr[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1 : 0]) & ~write_allow;
     assign write_only    = write_allow    & ~(read_allow & &(rd_pntr[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1 : 0]));
    end endgenerate
    generate if (IS_ASYMMETRY ==1 && C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin : rd_grt_wr
     assign read_only   = read_allow & ~(write_allow  & &(wr_pntr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1 : 0]));
     assign write_only    = write_allow &  &(wr_pntr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1 : 0]) & ~read_allow;
    end endgenerate


   //-----------------------------------------------------------------------------
   // Write and Read pointer generation
   //-----------------------------------------------------------------------------
   always @(posedge CLK or posedge rst_i) begin
     if (rst_i) begin
       wr_pntr         <= 0;
       rd_pntr         <= 0;
     end else begin
       if (srst_i || srst_wrst_busy || srst_rrst_busy ) begin
        if (srst_wrst_busy) 
         wr_pntr       <= #`TCQ 0;
        if (srst_rrst_busy) 
         rd_pntr       <= #`TCQ 0;
       end else begin
         if (write_allow) wr_pntr <= #`TCQ wr_pntr + 1;
         if (read_allow)  rd_pntr <= #`TCQ rd_pntr + 1;
       end
     end
   end

   generate if (C_FIFO_TYPE == 2) begin : gll_dm_dout
   always @(posedge CLK) begin
     if (write_allow) begin
       if (ENABLE_ERR_INJECTION == 1)
         memory[wr_pntr] <= #`TCQ {INJECTDBITERR,INJECTSBITERR,DIN};
       else
         memory[wr_pntr] <= #`TCQ DIN;
     end
   end

   reg  [C_DATA_WIDTH-1:0] dout_tmp_q;
   reg [C_DATA_WIDTH-1:0] dout_tmp = 0;
   reg  [C_DATA_WIDTH-1:0] dout_tmp1 = 0;
   always @(posedge CLK) begin
     dout_tmp_q <= #`TCQ ideal_dout;
   end



     always @* begin
       if (read_allow)
         ideal_dout <= memory[rd_pntr];
       else
         ideal_dout <= dout_tmp_q;
     end
   end endgenerate // gll_dm_dout


   /**************************************************************************
   * Write Domain Logic
   **************************************************************************/
   assign ram_rd_en        = RD_EN & !EMPTY;

   //reg [C_WR_PNTR_WIDTH-1:0] diff_pntr = 0;
   generate if (C_FIFO_TYPE != 2) begin : gnll_din
   always @(posedge CLK or posedge rst_i) begin : gen_fifo_w

     /****** Reset fifo (case 1)***************************************/
     if (rst_i == 1'b1) begin
       num_wr_bits       <= #`TCQ 0;
       next_num_wr_bits   = #`TCQ 0;
       wr_ptr            <= #`TCQ C_WR_DEPTH - 1;
       rd_ptr_wrclk      <= #`TCQ C_RD_DEPTH - 1;
       ideal_wr_ack      <= #`TCQ 0;
       ideal_wr_count    <= #`TCQ 0;
       tmp_wr_listsize    = #`TCQ 0;
       rd_ptr_wrclk_next <= #`TCQ 0;
       wr_pntr           <= #`TCQ 0;
       wr_pntr_rd1       <= #`TCQ 0;

     end else begin //rst_i==0
     if (srst_wrst_busy) begin
       num_wr_bits       <= #`TCQ 0;
       next_num_wr_bits   = #`TCQ 0;
       wr_ptr            <= #`TCQ C_WR_DEPTH - 1;
       rd_ptr_wrclk      <= #`TCQ C_RD_DEPTH - 1;
       ideal_wr_ack      <= #`TCQ 0;
       ideal_wr_count    <= #`TCQ 0;
       tmp_wr_listsize    = #`TCQ 0;
       rd_ptr_wrclk_next <= #`TCQ 0;
       wr_pntr           <= #`TCQ 0;
       wr_pntr_rd1       <= #`TCQ 0;
     end else begin//srst_i=0

       wr_pntr_rd1   <= #`TCQ wr_pntr;

       //Determine the current number of words in the FIFO
       tmp_wr_listsize = (C_DEPTH_RATIO_RD > 1) ? num_wr_bits/C_DOUT_WIDTH :
                         num_wr_bits/C_DIN_WIDTH;
       rd_ptr_wrclk_next = rd_ptr;
       if (rd_ptr_wrclk < rd_ptr_wrclk_next) begin
         next_num_wr_bits = num_wr_bits -
                            C_DOUT_WIDTH*(rd_ptr_wrclk + C_RD_DEPTH
                                          - rd_ptr_wrclk_next);
       end else begin
         next_num_wr_bits = num_wr_bits -
                            C_DOUT_WIDTH*(rd_ptr_wrclk - rd_ptr_wrclk_next);
       end

       if (WR_EN == 1'b1) begin
         if (FULL == 1'b1) begin

             ideal_wr_ack      <= #`TCQ 0;
             //Reminder that FIFO is still full
             ideal_wr_count    <= #`TCQ num_write_words_sized_i;

         end else begin
             write_fifo;
             next_num_wr_bits  = next_num_wr_bits + C_DIN_WIDTH;
             //Write successful, so issue acknowledge
             // and no error  
             ideal_wr_ack      <= #`TCQ 1;
             //Not even close to full.
             ideal_wr_count    <= num_write_words_sized_i;

           //end

         end

       end else begin //(WR_EN == 1'b1)

         //If user did not attempt a write, then do not
         // give ack or err
         ideal_wr_ack   <= #`TCQ 0;
         ideal_wr_count <= #`TCQ num_write_words_sized_i;
       end
       num_wr_bits       <= #`TCQ next_num_wr_bits;
       rd_ptr_wrclk      <= #`TCQ rd_ptr;

     end //srst_i==0
     end //wr_rst_i==0
   end // gen_fifo_w
    end endgenerate

   generate if (C_FIFO_TYPE < 2 && C_MEMORY_TYPE < 2) begin : gnll_dm_dout
     always @(posedge CLK) begin
       if (rst_i || srst_rrst_busy) begin
         if (C_USE_DOUT_RST == 1)
           ideal_dout <= #`TCQ dout_reset_val;
         end
       end
    end endgenerate




   generate if (C_FIFO_TYPE != 2) begin : gnll_dout
   always @(posedge CLK or posedge rst_i) begin : gen_fifo_r

     /****** Reset fifo (case 1)***************************************/
     if (rst_i) begin
       num_rd_bits        <= #`TCQ 0;
       next_num_rd_bits    = #`TCQ 0;
       rd_ptr             <= #`TCQ C_RD_DEPTH -1;
       rd_pntr            <= #`TCQ 0;
       //rd_pntr_wr1       <= #`TCQ 0;
       wr_ptr_rdclk       <= #`TCQ C_WR_DEPTH -1;
  
       // DRAM resets asynchronously
       if (C_FIFO_TYPE < 2 && (C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3 )&& C_USE_DOUT_RST == 1)
          ideal_dout    <= #`TCQ dout_reset_val;
  
       // Reset err_type only if ECC is not selected
       if (C_USE_ECC == 0)
         err_type         <= #`TCQ 0;
       ideal_valid        <= #`TCQ 1'b0;
       ideal_rd_count     <= #`TCQ 0;

     end else begin //rd_rst_i==0
     if (srst_rrst_busy) begin
       num_rd_bits        <= #`TCQ 0;
       next_num_rd_bits    = #`TCQ 0;
       rd_ptr             <= #`TCQ C_RD_DEPTH -1;
       rd_pntr            <= #`TCQ 0;
       //rd_pntr_wr1       <= #`TCQ 0;
       wr_ptr_rdclk       <= #`TCQ C_WR_DEPTH -1;
  
       // DRAM resets synchronously
       if (C_FIFO_TYPE < 2 && (C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3 )&& C_USE_DOUT_RST == 1)
          ideal_dout    <= #`TCQ dout_reset_val;
  
       // Reset err_type only if ECC is not selected
       if (C_USE_ECC == 0)
         err_type         <= #`TCQ 0;
       ideal_valid        <= #`TCQ 1'b0;
       ideal_rd_count     <= #`TCQ 0;
      end //srst_i
      else begin

       //rd_pntr_wr1   <= #`TCQ rd_pntr;

       //Determine the current number of words in the FIFO
       tmp_rd_listsize = (C_DEPTH_RATIO_WR > 1) ? num_rd_bits/C_DIN_WIDTH :
                         num_rd_bits/C_DOUT_WIDTH;
       wr_ptr_rdclk_next = wr_ptr;

       if (wr_ptr_rdclk < wr_ptr_rdclk_next) begin
         next_num_rd_bits = num_rd_bits +
                            C_DIN_WIDTH*(wr_ptr_rdclk +C_WR_DEPTH
                                         - wr_ptr_rdclk_next);
       end else begin
         next_num_rd_bits = num_rd_bits +
                             C_DIN_WIDTH*(wr_ptr_rdclk - wr_ptr_rdclk_next);
       end

         if (RD_EN == 1'b1) begin

           if (EMPTY == 1'b1) begin
                 ideal_valid        <= #`TCQ 1'b0;
                 ideal_rd_count     <= #`TCQ num_read_words_sized_i;
               end 
           else 
             begin
                   read_fifo;
                   next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH;

                   //Acknowledge the read from the FIFO, no error
                   ideal_valid        <= #`TCQ 1'b1;
                   ideal_rd_count     <= #`TCQ num_read_words_sized_i;

                 end // if (tmp_rd_listsize == 2)
         end

       num_rd_bits      <= #`TCQ next_num_rd_bits;
       wr_ptr_rdclk     <= #`TCQ wr_ptr;
     end //s_rst_i==0
     end //rd_rst_i==0
   end //always
  end endgenerate

   //-----------------------------------------------------------------------------
   // Generate diff_pntr for PROG_FULL generation
   // Generate diff_pntr_pe for PROG_EMPTY generation
   //-----------------------------------------------------------------------------
   generate if ((C_PROG_FULL_TYPE != 0 || C_PROG_EMPTY_TYPE != 0) && IS_ASYMMETRY == 0) begin : reg_write_allow
     always @(posedge CLK ) begin
       if (rst_i) begin
         write_only_q   <= 1'b0;
         read_only_q    <= 1'b0;
         diff_pntr_reg1       <= 0;
         diff_pntr_pe_reg1    <= 0;
         diff_pntr_reg2       <= 0;
         diff_pntr_pe_reg2    <= 0;
       end else begin
         if (srst_i || srst_wrst_busy || srst_rrst_busy) begin
          if (srst_rrst_busy) begin
           read_only_q  <= #`TCQ 1'b0;
           diff_pntr_pe_reg1  <= #`TCQ 0;
           diff_pntr_pe_reg2  <= #`TCQ 0;
          end
          if (srst_wrst_busy) begin
           write_only_q <= #`TCQ 1'b0;
           diff_pntr_reg1     <= #`TCQ 0;
           diff_pntr_reg2     <= #`TCQ 0;
          end
         end else begin
           write_only_q <= #`TCQ write_only;
           read_only_q  <= #`TCQ read_only;
           diff_pntr_reg2  <= #`TCQ diff_pntr_reg1;
           diff_pntr_pe_reg2  <= #`TCQ diff_pntr_pe_reg1;

           // Add 1 to the difference pointer value when only write happens.
           if (write_only)  
             diff_pntr_reg1 <= #`TCQ wr_pntr - adj_rd_pntr_wr + 1;
           else
             diff_pntr_reg1 <= #`TCQ wr_pntr - adj_rd_pntr_wr;

           // Add 1 to the difference pointer value when write or both write & read or no write & read happen.
           if (read_only)  
             diff_pntr_pe_reg1 <= #`TCQ adj_wr_pntr_rd - rd_pntr - 1;
           else
             diff_pntr_pe_reg1 <= #`TCQ adj_wr_pntr_rd - rd_pntr;
         end
       end
     end
   assign diff_pntr_pe = diff_pntr_pe_reg1;
   assign diff_pntr = diff_pntr_reg1;
   end endgenerate // reg_write_allow

   generate if ((C_PROG_FULL_TYPE != 0 || C_PROG_EMPTY_TYPE != 0) && IS_ASYMMETRY == 1) begin : reg_write_allow_asym
    assign adj_wr_pntr_rd_asym[C_RD_PNTR_WIDTH:0] = {adj_wr_pntr_rd,1'b1};
    assign rd_pntr_asym[C_RD_PNTR_WIDTH:0] = {~rd_pntr,1'b1};
     always @(posedge CLK ) begin
       if (rst_i) begin
         diff_pntr_pe_asym    <= 0;
         diff_pntr_reg1       <= 0;
         full_reg             <= 0;
         rst_full_ff_reg1     <= 1;
         rst_full_ff_reg2     <= 1;
         diff_pntr_pe_reg1    <= 0;
       end else begin
         if (srst_i || srst_wrst_busy || srst_rrst_busy) begin
          if (srst_wrst_busy)
           diff_pntr_reg1     <= #`TCQ 0;
          if (srst_rrst_busy)
           full_reg             <=  #`TCQ 0;
           rst_full_ff_reg1     <=  #`TCQ 1;
           rst_full_ff_reg2     <=  #`TCQ 1;
           diff_pntr_pe_asym    <=  #`TCQ 0;
           diff_pntr_pe_reg1  <= #`TCQ 0;
         end else begin
             diff_pntr_pe_asym <= #`TCQ adj_wr_pntr_rd_asym + rd_pntr_asym;
             full_reg          <= #`TCQ full_i;
             rst_full_ff_reg1  <=  #`TCQ RST_FULL_FF;
             rst_full_ff_reg2  <=  #`TCQ rst_full_ff_reg1;
           if (~full_i) begin  
             diff_pntr_reg1 <=  #`TCQ wr_pntr - adj_rd_pntr_wr;
          end
         end
       end
     end
   assign carry = (~(|(diff_pntr_pe_asym [C_RD_PNTR_WIDTH : 1])));
   assign diff_pntr_pe = (full_reg && ~rst_full_ff_reg2 && carry ) ? diff_pntr_pe_max : diff_pntr_pe_asym[C_RD_PNTR_WIDTH:1];
   assign diff_pntr = diff_pntr_reg1;
   end endgenerate // reg_write_allow_asym


   //-----------------------------------------------------------------------------
   // Generate FULL flag
   //-----------------------------------------------------------------------------
   wire                 comp0;
   wire                 comp1;
   wire                 going_full;
   wire                 leaving_full;
 
 generate if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin :  gpad 	
    assign adj_rd_pntr_wr [C_WR_PNTR_WIDTH-1 : C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH] = rd_pntr;
    assign adj_rd_pntr_wr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1 : 0] = 0;
  end endgenerate

  generate if (C_WR_PNTR_WIDTH <= C_RD_PNTR_WIDTH) begin :  gtrim 
    assign adj_rd_pntr_wr = rd_pntr[C_RD_PNTR_WIDTH-1 : C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH];
  end endgenerate

   assign comp1         = (adj_rd_pntr_wr == (wr_pntr + 1'b1));
   assign comp0         = (adj_rd_pntr_wr == wr_pntr);

    generate if (C_WR_PNTR_WIDTH == C_RD_PNTR_WIDTH) begin : gf_wp_eq_rp
     assign going_full    = (comp1 & write_allow & ~read_allow);
     assign leaving_full  = (comp0 & read_allow) | RST_FULL_GEN;
    end endgenerate

    // Write data width is bigger than read data width
    // Write depth is smaller than read depth
    // One write could be equal to 2 or 4 or 8 reads
    generate if (C_WR_PNTR_WIDTH < C_RD_PNTR_WIDTH) begin : gf_asym
      assign going_full = (comp1 & write_allow & (~ (read_allow & &(rd_pntr[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1 : 0]))));
      assign leaving_full = (comp0 & read_allow & &(rd_pntr[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1 : 0])) | RST_FULL_GEN;
    end endgenerate

    generate if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin : gf_wp_gt_rp 
      assign going_full = (comp1 & write_allow & ~read_allow);
      assign leaving_full =(comp0 & read_allow) | RST_FULL_GEN;
    end endgenerate


   assign ram_full_comb = going_full | (~leaving_full & full_i);

   always @(posedge CLK or posedge RST_FULL_FF) begin
     if (RST_FULL_FF)
       full_i   <= C_FULL_FLAGS_RST_VAL;
     else if (srst_wrst_busy)
       full_i   <= #`TCQ C_FULL_FLAGS_RST_VAL;
     else
       full_i   <= #`TCQ ram_full_comb;
    end

   //-----------------------------------------------------------------------------
   // Generate EMPTY flag
   //-----------------------------------------------------------------------------
   wire                 ecomp0;
   wire                 ecomp1;
   wire                 going_empty;
   wire                 leaving_empty;
   wire                 ram_empty_comb;

  
 generate if (C_RD_PNTR_WIDTH > C_WR_PNTR_WIDTH) begin :  pad 	
    assign adj_wr_pntr_rd [C_RD_PNTR_WIDTH-1 : C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr;
    assign adj_wr_pntr_rd[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1 : 0] = 0;
  end endgenerate

  generate if (C_RD_PNTR_WIDTH <= C_WR_PNTR_WIDTH) begin :  trim 
    assign adj_wr_pntr_rd = wr_pntr[C_WR_PNTR_WIDTH-1 : C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH];
  end endgenerate

   assign ecomp1         = (adj_wr_pntr_rd == (rd_pntr + 1'b1));
   assign ecomp0         = (adj_wr_pntr_rd == rd_pntr);


    generate if (C_WR_PNTR_WIDTH == C_RD_PNTR_WIDTH) begin : ge_wp_eq_rp
     assign going_empty    = (ecomp1 & ~write_allow & read_allow);
     assign leaving_empty  = (ecomp0 & write_allow);
    end endgenerate

    generate if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin : ge_wp_gt_rp
      assign going_empty = (ecomp1 & read_allow & (~(write_allow & &(wr_pntr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1 : 0]))));
      assign leaving_empty = (ecomp0 & write_allow & &(wr_pntr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1 : 0]));
    end endgenerate
  
   generate if (C_WR_PNTR_WIDTH < C_RD_PNTR_WIDTH) begin : ge_wp_lt_rp 
      assign going_empty = (ecomp1 & ~write_allow & read_allow);
      assign leaving_empty =(ecomp0 & write_allow);
    end endgenerate



    assign ram_empty_comb = going_empty | (~leaving_empty & empty_i);

   always @(posedge CLK or posedge rst_i) begin
     if (rst_i)
       empty_i  <= 1'b1;
     else if (srst_rrst_busy)
       empty_i  <= #`TCQ 1'b1;
     else
       empty_i  <= #`TCQ ram_empty_comb;
    end

   //-----------------------------------------------------------------------------
   // Generate Read and write data counts for asymmetic common clock
   //-----------------------------------------------------------------------------

    reg [C_GRTR_PNTR_WIDTH :0] count_dc = 0; 
    wire [C_GRTR_PNTR_WIDTH :0] ratio; 
    wire decr_by_one;
    wire incr_by_ratio;
    wire incr_by_one;
    wire decr_by_ratio;

   localparam IS_FWFT          = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ? 1 : 0;

   generate if (C_WR_PNTR_WIDTH < C_RD_PNTR_WIDTH) begin : rd_depth_gt_wr 
      assign ratio         = C_DEPTH_RATIO_RD;
      assign decr_by_one   = (IS_FWFT == 1)? read_allow_dc : read_allow;
      assign incr_by_ratio = write_allow;

      always @(posedge CLK or posedge rst_i) begin
       if (rst_i)
         count_dc  <= #`TCQ 0;
       else if (srst_wrst_busy)
         count_dc  <= #`TCQ 0;
       else begin
	 if (decr_by_one) begin
	   if (!incr_by_ratio) 
            count_dc <= #`TCQ count_dc - 1;
           else
	    count_dc <= #`TCQ count_dc - 1  + ratio ;
	 end
	 else begin
	   if (!incr_by_ratio) 
            count_dc <= #`TCQ count_dc ;
           else
	    count_dc <= #`TCQ count_dc + ratio ;
	end
       end
       end

       assign rd_data_count_i_ss[C_RD_PNTR_WIDTH : 0] = count_dc;
       assign wr_data_count_i_ss[C_WR_PNTR_WIDTH : 0] = count_dc[C_RD_PNTR_WIDTH : C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH];

    end endgenerate


    generate if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin : wr_depth_gt_rd 
      assign ratio         = C_DEPTH_RATIO_WR;
      assign incr_by_one   = write_allow;
      assign decr_by_ratio = (IS_FWFT == 1)? read_allow_dc : read_allow;

      always @(posedge CLK or posedge rst_i) begin
       if (rst_i)
         count_dc  <= #`TCQ 0;
       else if (srst_wrst_busy)
         count_dc  <= #`TCQ 0;
       else begin
	 if (incr_by_one) begin
	   if (!decr_by_ratio) 
            count_dc <= #`TCQ count_dc + 1;
           else
	    count_dc <= #`TCQ count_dc + 1  - ratio ;
	 end
	 else begin
	   if (!decr_by_ratio) 
            count_dc <= #`TCQ count_dc ;
           else
	    count_dc <= #`TCQ count_dc - ratio ;
	end
       end
       end

       assign wr_data_count_i_ss[C_WR_PNTR_WIDTH : 0] = count_dc;
       assign rd_data_count_i_ss[C_RD_PNTR_WIDTH : 0] = count_dc[C_WR_PNTR_WIDTH : C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH];

    end endgenerate






   //-----------------------------------------------------------------------------
   // Generate WR_ACK flag
   //-----------------------------------------------------------------------------
   always @(posedge CLK or posedge rst_i) begin
     if (rst_i)
       ideal_wr_ack  <= 1'b0;
     else if (srst_wrst_busy)
       ideal_wr_ack  <= #`TCQ 1'b0;
     else if (WR_EN & ~full_i)
       ideal_wr_ack  <= #`TCQ 1'b1;
     else
       ideal_wr_ack  <= #`TCQ 1'b0;
    end

   //-----------------------------------------------------------------------------
   // Generate VALID flag
   //-----------------------------------------------------------------------------
   always @(posedge CLK or posedge rst_i) begin
     if (rst_i)
       ideal_valid  <= 1'b0;
     else if (srst_rrst_busy)
       ideal_valid  <= #`TCQ 1'b0;
     else if (RD_EN & ~empty_i)
       ideal_valid  <= #`TCQ 1'b1;
     else
       ideal_valid  <= #`TCQ 1'b0;
    end


   //-----------------------------------------------------------------------------
   // Generate ALMOST_FULL flag
   //-----------------------------------------------------------------------------
   //generate if (C_HAS_ALMOST_FULL == 1 || C_PROG_FULL_TYPE > 2 || C_PROG_EMPTY_TYPE > 2) begin : gaf_ss

     wire                 fcomp2;
     wire                 going_afull;
     wire                 leaving_afull;
     wire                 ram_afull_comb;


   assign fcomp2         = (adj_rd_pntr_wr == (wr_pntr + 2'h2));

    generate if (C_WR_PNTR_WIDTH == C_RD_PNTR_WIDTH) begin : gaf_wp_eq_rp
     assign going_afull    = (fcomp2 & write_allow & ~read_allow);
     assign leaving_afull  = (comp1 & read_allow & ~write_allow) | RST_FULL_GEN;
    end endgenerate

    // Write data width is bigger than read data width
    // Write depth is smaller than read depth
    // One write could be equal to 2 or 4 or 8 reads
    generate if (C_WR_PNTR_WIDTH < C_RD_PNTR_WIDTH) begin : gaf_asym
      assign going_afull = (fcomp2 & write_allow & (~ (read_allow & &(rd_pntr[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1 : 0]))));
      assign leaving_afull = (comp1 & (~write_allow) & read_allow & &(rd_pntr[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1 : 0])) | RST_FULL_GEN;
    end endgenerate

    generate if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin : gaf_wp_gt_rp 
      assign going_afull = (fcomp2 & write_allow & ~read_allow);
      assign leaving_afull =((comp0 | comp1 | fcomp2) & read_allow) | RST_FULL_GEN;
    end endgenerate

     assign ram_afull_comb  = going_afull | (~leaving_afull & almost_full_i);


     always @(posedge CLK or posedge RST_FULL_FF) begin
       if (RST_FULL_FF)
         almost_full_i   <= C_FULL_FLAGS_RST_VAL;
       else if (srst_wrst_busy)
         almost_full_i   <= #`TCQ C_FULL_FLAGS_RST_VAL;
       else
         almost_full_i   <= #`TCQ ram_afull_comb;
      end
  // end endgenerate // gaf_ss

   //-----------------------------------------------------------------------------
   // Generate ALMOST_EMPTY flag
   //-----------------------------------------------------------------------------
   //generate if (C_HAS_ALMOST_EMPTY == 1) begin : gae_ss

     wire                 ecomp2;
     wire                 going_aempty;
     wire                 leaving_aempty;
     wire                 ram_aempty_comb;
      
     assign ecomp2          = (adj_wr_pntr_rd == (rd_pntr + 2'h2));
   
    generate if (C_WR_PNTR_WIDTH == C_RD_PNTR_WIDTH) begin : gae_wp_eq_rp
     assign going_aempty    = (ecomp2 & ~write_allow & read_allow);
     assign leaving_aempty  = (ecomp1 & write_allow & ~read_allow);
    end endgenerate

    generate if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin : gae_wp_gt_rp
      assign going_aempty = (ecomp2 & read_allow & (~(write_allow & &(wr_pntr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1 : 0]))));
      assign leaving_aempty = (ecomp1 & ~read_allow & write_allow & &(wr_pntr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1 : 0]));
    end endgenerate
  
   generate if (C_WR_PNTR_WIDTH < C_RD_PNTR_WIDTH) begin : gae_wp_lt_rp 
      assign going_aempty = (ecomp2 & ~write_allow & read_allow);
      assign leaving_aempty =((ecomp2 | ecomp1 |ecomp0) & write_allow);
    end endgenerate


     assign ram_aempty_comb = going_aempty | (~leaving_aempty & almost_empty_i);

     always @(posedge CLK or posedge rst_i) begin
       if (rst_i)
         almost_empty_i  <= 1'b1;
       else if (srst_rrst_busy)
         almost_empty_i  <= #`TCQ 1'b1;
       else
         almost_empty_i  <= #`TCQ ram_aempty_comb;
      end
  // end endgenerate // gae_ss

   //-----------------------------------------------------------------------------
   // Generate PROG_FULL
   //-----------------------------------------------------------------------------

   localparam  C_PF_ASSERT_VAL = (C_PRELOAD_LATENCY == 0) ? 
                                  C_PROG_FULL_THRESH_ASSERT_VAL - EXTRA_WORDS_PF_PARAM : // FWFT 
                                  C_PROG_FULL_THRESH_ASSERT_VAL; // STD
   localparam  C_PF_NEGATE_VAL = (C_PRELOAD_LATENCY == 0) ? 
                                  C_PROG_FULL_THRESH_NEGATE_VAL - EXTRA_WORDS_PF_PARAM: // FWFT
                                  C_PROG_FULL_THRESH_NEGATE_VAL; // STD

   //-----------------------------------------------------------------------------
   // Generate PROG_FULL for single programmable threshold constant
   //-----------------------------------------------------------------------------
   wire [C_WR_PNTR_WIDTH-1:0] temp = C_PF_ASSERT_VAL;   
   generate if (C_PROG_FULL_TYPE == 1) begin : single_pf_const
     always @(posedge CLK or posedge RST_FULL_FF) begin
       if (RST_FULL_FF && C_HAS_RST)
         prog_full_i   <= C_FULL_FLAGS_RST_VAL;
       else begin 
         if (srst_wrst_busy)
           prog_full_i <= #`TCQ C_FULL_FLAGS_RST_VAL;
       else if (IS_ASYMMETRY == 0) begin 
         if (RST_FULL_GEN)
          prog_full_i <= #`TCQ 1'b0;
         else if (diff_pntr == C_PF_ASSERT_VAL && write_only_q)
           prog_full_i <= #`TCQ 1'b1;
         else if (diff_pntr == C_PF_ASSERT_VAL && read_only_q)
           prog_full_i <= #`TCQ 1'b0;
         else
           prog_full_i <= #`TCQ prog_full_i;
       end
       else begin
       if (RST_FULL_GEN)
        prog_full_i <= #`TCQ 1'b0;
       else if (~RST_FULL_GEN ) begin 
        if (diff_pntr>= C_PF_ASSERT_VAL )
          prog_full_i <= #`TCQ 1'b1;
        else if  ((diff_pntr) < C_PF_ASSERT_VAL )
        prog_full_i <= #`TCQ 1'b0;
       else
         prog_full_i <= #`TCQ 1'b0;
        end 
       else
         prog_full_i <= #`TCQ prog_full_i;
       end
      end
     end
   end endgenerate // single_pf_const

   //-----------------------------------------------------------------------------
   // Generate PROG_FULL for multiple programmable threshold constants
   //-----------------------------------------------------------------------------
   generate if (C_PROG_FULL_TYPE == 2) begin : multiple_pf_const
     always @(posedge CLK or posedge RST_FULL_FF) begin
       //if (RST_FULL_FF)
       if (RST_FULL_FF && C_HAS_RST)
         prog_full_i   <= C_FULL_FLAGS_RST_VAL;
       else begin
         if (srst_wrst_busy)
           prog_full_i <= #`TCQ C_FULL_FLAGS_RST_VAL;
       else if (IS_ASYMMETRY == 0) begin 
         if (RST_FULL_GEN)
           prog_full_i <= #`TCQ 1'b0;
         else if (diff_pntr == C_PF_ASSERT_VAL && write_only_q)
           prog_full_i <= #`TCQ 1'b1;
         else if (diff_pntr == C_PF_NEGATE_VAL && read_only_q)
           prog_full_i <= #`TCQ 1'b0;
         else
           prog_full_i <= #`TCQ prog_full_i;
       end
       else begin
       if (RST_FULL_GEN)
        prog_full_i <= #`TCQ 1'b0;
       else if (~RST_FULL_GEN ) begin 
        if (diff_pntr >= C_PF_ASSERT_VAL )
          prog_full_i <= #`TCQ 1'b1;
       else if  (diff_pntr < C_PF_NEGATE_VAL)
         prog_full_i <= #`TCQ 1'b0;
       else
         prog_full_i <= #`TCQ prog_full_i;
        end 
       else
         prog_full_i <= #`TCQ prog_full_i;
       end
      end
     end
   end endgenerate //multiple_pf_const

   //-----------------------------------------------------------------------------
   // Generate PROG_FULL for single programmable threshold input port
   //-----------------------------------------------------------------------------
   wire [C_WR_PNTR_WIDTH-1:0] pf3_assert_val = (C_PRELOAD_LATENCY == 0) ? 
                                               PROG_FULL_THRESH - EXTRA_WORDS_PF: // FWFT
                                               PROG_FULL_THRESH; // STD
   generate if (C_PROG_FULL_TYPE == 3) begin : single_pf_input

     always @(posedge CLK or posedge RST_FULL_FF) begin//0
       //if (RST_FULL_FF)
       if (RST_FULL_FF && C_HAS_RST)
         prog_full_i   <= C_FULL_FLAGS_RST_VAL;
       else begin //1
         if (srst_wrst_busy)
           prog_full_i <= #`TCQ C_FULL_FLAGS_RST_VAL;
       else if (IS_ASYMMETRY == 0) begin//2 
         if (RST_FULL_GEN)
           prog_full_i <= #`TCQ 1'b0;
         else if (~almost_full_i) begin//3
           if (diff_pntr > pf3_assert_val)
             prog_full_i <= #`TCQ 1'b1;
           else if (diff_pntr == pf3_assert_val) begin//4
             if (read_only_q)
               prog_full_i <= #`TCQ 1'b0;
             else
               prog_full_i <= #`TCQ 1'b1;
           end else//4
             prog_full_i <= #`TCQ 1'b0;
         end else//3
           prog_full_i <= #`TCQ prog_full_i;
       end //2
       else begin//5
       if (RST_FULL_GEN)
        prog_full_i <= #`TCQ 1'b0;
       else if (~full_i ) begin//6 
        if (diff_pntr >= pf3_assert_val )
          prog_full_i <= #`TCQ 1'b1;
        else if  (diff_pntr < pf3_assert_val) begin//7
         prog_full_i <= #`TCQ 1'b0;
       end//7
       end//6
      else
           prog_full_i <= #`TCQ prog_full_i;
       end//5
     end//1
     end//0
   end endgenerate //single_pf_input
  
   //-----------------------------------------------------------------------------
   // Generate PROG_FULL for multiple programmable threshold input ports
   //-----------------------------------------------------------------------------
   wire [C_WR_PNTR_WIDTH-1:0] pf_assert_val = (C_PRELOAD_LATENCY == 0) ? 
                                               (PROG_FULL_THRESH_ASSERT -EXTRA_WORDS_PF) : // FWFT
                                               PROG_FULL_THRESH_ASSERT; // STD
   wire [C_WR_PNTR_WIDTH-1:0] pf_negate_val = (C_PRELOAD_LATENCY == 0) ? 
                                               (PROG_FULL_THRESH_NEGATE -EXTRA_WORDS_PF) : // FWFT
                                               PROG_FULL_THRESH_NEGATE; // STD

   generate if (C_PROG_FULL_TYPE == 4) begin : multiple_pf_inputs
     always @(posedge CLK or posedge RST_FULL_FF) begin
       if (RST_FULL_FF && C_HAS_RST)
         prog_full_i   <= C_FULL_FLAGS_RST_VAL;
       else begin
         if (srst_wrst_busy)
           prog_full_i <= #`TCQ C_FULL_FLAGS_RST_VAL;
       else if (IS_ASYMMETRY == 0) begin 
         if (RST_FULL_GEN)
           prog_full_i <= #`TCQ 1'b0;
         else if (~almost_full_i) begin
           if (diff_pntr >= pf_assert_val)
             prog_full_i <= #`TCQ 1'b1;
           else if ((diff_pntr == pf_negate_val && read_only_q) ||
                  diff_pntr < pf_negate_val)
             prog_full_i <= #`TCQ 1'b0;
           else
             prog_full_i <= #`TCQ prog_full_i;
         end else
           prog_full_i <= #`TCQ prog_full_i;
       end
       else begin
       if (RST_FULL_GEN)
        prog_full_i <= #`TCQ 1'b0;
       else if (~full_i ) begin 
        if (diff_pntr >= pf_assert_val )
          prog_full_i <= #`TCQ 1'b1;
       else if (diff_pntr < pf_negate_val) 
         prog_full_i <= #`TCQ 1'b0;
       else
         prog_full_i <= #`TCQ prog_full_i;
        end 
       else
         prog_full_i <= #`TCQ prog_full_i;
       end

     end
   end
   end endgenerate //multiple_pf_inputs

   //-----------------------------------------------------------------------------
   // Generate PROG_EMPTY
   //-----------------------------------------------------------------------------
   localparam  C_PE_ASSERT_VAL = (C_PRELOAD_LATENCY == 0) ?
                                  C_PROG_EMPTY_THRESH_ASSERT_VAL - 2: // FWFT
                                  C_PROG_EMPTY_THRESH_ASSERT_VAL; // STD
   localparam  C_PE_NEGATE_VAL = (C_PRELOAD_LATENCY == 0) ?
                                  C_PROG_EMPTY_THRESH_NEGATE_VAL - 2: // FWFT
                                  C_PROG_EMPTY_THRESH_NEGATE_VAL; // STD

   //-----------------------------------------------------------------------------
   // Generate PROG_EMPTY for single programmable threshold constant
   //-----------------------------------------------------------------------------
   generate if (C_PROG_EMPTY_TYPE == 1) begin : single_pe_const
     always @(posedge CLK or posedge rst_i) begin
       //if (rst_i) 
       if (rst_i && C_HAS_RST) 
         prog_empty_i  <= 1'b1;
       else begin
         if (srst_rrst_busy) 
           prog_empty_i <= #`TCQ 1'b1;
       else if (IS_ASYMMETRY == 0) begin 
         if (diff_pntr_pe == C_PE_ASSERT_VAL && read_only_q)
           prog_empty_i <= #`TCQ 1'b1;
         else if (diff_pntr_pe == C_PE_ASSERT_VAL && write_only_q)
           prog_empty_i <= #`TCQ 1'b0;
         else
           prog_empty_i <= #`TCQ prog_empty_i;
       end
       else begin
       if (~rst_i ) begin 
        if (diff_pntr_pe <= C_PE_ASSERT_VAL)
          prog_empty_i <= #`TCQ 1'b1;
        else if  (diff_pntr_pe > C_PE_ASSERT_VAL)
         prog_empty_i <= #`TCQ 1'b0;
        end 
       else
         prog_empty_i <= #`TCQ prog_empty_i;
       end
     end
     end
   end endgenerate // single_pe_const

   //-----------------------------------------------------------------------------
   // Generate PROG_EMPTY for multiple programmable threshold constants
   //-----------------------------------------------------------------------------
   generate if (C_PROG_EMPTY_TYPE == 2) begin : multiple_pe_const
     always @(posedge CLK or posedge rst_i) begin
       //if (rst_i)
       if (rst_i && C_HAS_RST) 
         prog_empty_i  <= 1'b1;
       else begin
         if (srst_rrst_busy)
           prog_empty_i <= #`TCQ 1'b1;
       else if (IS_ASYMMETRY == 0) begin 
         if (diff_pntr_pe == C_PE_ASSERT_VAL && read_only_q)
           prog_empty_i <= #`TCQ 1'b1;
         else if (diff_pntr_pe == C_PE_NEGATE_VAL && write_only_q)
           prog_empty_i <= #`TCQ 1'b0;
         else
           prog_empty_i <= #`TCQ prog_empty_i;
       end
       else begin
       if (~rst_i ) begin 
        if (diff_pntr_pe <= C_PE_ASSERT_VAL )
          prog_empty_i <= #`TCQ 1'b1;
        else if (diff_pntr_pe > C_PE_NEGATE_VAL) 
         prog_empty_i <= #`TCQ 1'b0;
       else
         prog_empty_i <= #`TCQ prog_empty_i;
        end 
       else
         prog_empty_i <= #`TCQ prog_empty_i;
       end

     end

     end
   end endgenerate //multiple_pe_const

   //-----------------------------------------------------------------------------
   // Generate PROG_EMPTY for single programmable threshold input port
   //-----------------------------------------------------------------------------
   wire [C_RD_PNTR_WIDTH-1:0] pe3_assert_val = (C_PRELOAD_LATENCY == 0) ?
                                               (PROG_EMPTY_THRESH -2) : // FWFT
                                                PROG_EMPTY_THRESH; // STD
   generate if (C_PROG_EMPTY_TYPE == 3) begin : single_pe_input
     always @(posedge CLK or posedge rst_i) begin
       //if (rst_i)
       if (rst_i && C_HAS_RST) 
         prog_empty_i  <= 1'b1;
       else begin
         if (srst_rrst_busy)
           prog_empty_i <= #`TCQ 1'b1;
       else if (IS_ASYMMETRY == 0) begin 
          if (~almost_full_i) begin
           if (diff_pntr_pe < pe3_assert_val)
             prog_empty_i <= #`TCQ 1'b1;
           else if (diff_pntr_pe == pe3_assert_val) begin
             if (write_only_q)
               prog_empty_i <= #`TCQ 1'b0;
             else
               prog_empty_i <= #`TCQ 1'b1;
           end else
             prog_empty_i <= #`TCQ 1'b0;
         end else
           prog_empty_i <= #`TCQ prog_empty_i;
       end
       else begin
        if (diff_pntr_pe <= pe3_assert_val )
          prog_empty_i <= #`TCQ 1'b1;
        else if  (diff_pntr_pe > pe3_assert_val)
         prog_empty_i <= #`TCQ 1'b0;
       else
         prog_empty_i <= #`TCQ prog_empty_i;
        end 
     end

     end
   end endgenerate // single_pe_input

   //-----------------------------------------------------------------------------
   // Generate PROG_EMPTY for multiple programmable threshold input ports
   //-----------------------------------------------------------------------------
   wire [C_RD_PNTR_WIDTH-1:0] pe4_assert_val = (C_PRELOAD_LATENCY == 0) ?
                                               (PROG_EMPTY_THRESH_ASSERT - 2) : // FWFT
                                                PROG_EMPTY_THRESH_ASSERT; // STD
   wire [C_RD_PNTR_WIDTH-1:0] pe4_negate_val = (C_PRELOAD_LATENCY == 0) ?
                                               (PROG_EMPTY_THRESH_NEGATE - 2) : // FWFT
                                                PROG_EMPTY_THRESH_NEGATE; // STD
   generate if (C_PROG_EMPTY_TYPE == 4) begin : multiple_pe_inputs
     always @(posedge CLK or posedge rst_i) begin
       //if (rst_i)
       if (rst_i && C_HAS_RST) 
         prog_empty_i  <= 1'b1;
       else begin
         if (srst_rrst_busy)
           prog_empty_i <= #`TCQ 1'b1;
      else if (IS_ASYMMETRY == 0) begin 
          if (~almost_full_i) begin
           if (diff_pntr_pe <= pe4_assert_val)
             prog_empty_i <= #`TCQ 1'b1;
           else if (((diff_pntr_pe == pe4_negate_val) && write_only_q) || 
                     (diff_pntr_pe > pe4_negate_val)) begin
             prog_empty_i <= #`TCQ 1'b0;
           end else
             prog_empty_i <= #`TCQ prog_empty_i;
         end else
           prog_empty_i <= #`TCQ prog_empty_i;
       end
       else begin
        if (diff_pntr_pe <= pe4_assert_val )
          prog_empty_i <= #`TCQ 1'b1;
        else if (diff_pntr_pe > pe4_negate_val) 
         prog_empty_i <= #`TCQ 1'b0;
       else
         prog_empty_i <= #`TCQ prog_empty_i;
        end 
     end
     end
   end endgenerate // multiple_pe_inputs

endmodule // fifo_generator_v12_0_bhv_ver_ss



/**************************************************************************
 * First-Word Fall-Through module (preload 0)
 **************************************************************************/
module fifo_generator_v12_0_bhv_ver_preload0
  #(
    parameter  C_DOUT_RST_VAL            = "",
    parameter  C_DOUT_WIDTH              = 8,
    parameter  C_HAS_RST                 = 0,
    parameter  C_ENABLE_RST_SYNC         = 0,
    parameter  C_HAS_SRST                = 0,
    parameter  C_USE_DOUT_RST            = 0,
    parameter  C_USE_ECC                 = 0,
    parameter  C_USERVALID_LOW           = 0,
    parameter  C_USERUNDERFLOW_LOW       = 0,
    parameter  C_MEMORY_TYPE             = 0,
    parameter  C_FIFO_TYPE               = 0
  )
  (
    //Inputs
    input                          RD_CLK,
    input                          RD_RST,
    input                          SRST,
    input                          WR_RST_BUSY,
    input                          RD_RST_BUSY,
    input                          RD_EN,
    input                          FIFOEMPTY,
    input       [C_DOUT_WIDTH-1:0] FIFODATA,
    input                          FIFOSBITERR,
    input                          FIFODBITERR,
   
    //Outputs
    output reg  [C_DOUT_WIDTH-1:0] USERDATA,
    output                         USERVALID,
    output                         USERUNDERFLOW,
    output                         USEREMPTY,
    output                         USERALMOSTEMPTY,
    output                         RAMVALID,
    output                         FIFORDEN,
    output reg                     USERSBITERR,
    output reg                     USERDBITERR,
    output reg                     STAGE2_REG_EN,
    output      [1:0]              VALID_STAGES 
  );

 //Internal signals
 wire                      preloadstage1;
 wire                      preloadstage2;
 reg                       ram_valid_i;
 reg                       read_data_valid_i;
 wire                      ram_regout_en;
 wire                      ram_rd_en;
 reg                       empty_i        = 1'b1;
 reg                       empty_q        = 1'b1;
 reg                       rd_en_q        = 1'b0;
 reg                       almost_empty_i = 1'b1;
 reg                       almost_empty_q = 1'b1;
 wire                      rd_rst_i;
 wire                      srst_i;


/*************************************************************************
* FUNCTIONS
*************************************************************************/

   /*************************************************************************
    * hexstr_conv
    *   Converts a string of type hex to a binary value (for C_DOUT_RST_VAL)
    ***********************************************************************/
    function [C_DOUT_WIDTH-1:0] hexstr_conv;
    input [(C_DOUT_WIDTH*8)-1:0] def_data;

    integer index,i,j;
    reg [3:0] bin;

    begin
      index = 0;
      hexstr_conv = 'b0;
      for( i=C_DOUT_WIDTH-1; i>=0; i=i-1 )
      begin
        case (def_data[7:0])
          8'b00000000 :
          begin
            bin = 4'b0000;
            i = -1;
          end
          8'b00110000 : bin = 4'b0000;
          8'b00110001 : bin = 4'b0001;
          8'b00110010 : bin = 4'b0010;
          8'b00110011 : bin = 4'b0011;
          8'b00110100 : bin = 4'b0100;
          8'b00110101 : bin = 4'b0101;
          8'b00110110 : bin = 4'b0110;
          8'b00110111 : bin = 4'b0111;
          8'b00111000 : bin = 4'b1000;
          8'b00111001 : bin = 4'b1001;
          8'b01000001 : bin = 4'b1010;
          8'b01000010 : bin = 4'b1011;
          8'b01000011 : bin = 4'b1100;
          8'b01000100 : bin = 4'b1101;
          8'b01000101 : bin = 4'b1110;
          8'b01000110 : bin = 4'b1111;
          8'b01100001 : bin = 4'b1010;
          8'b01100010 : bin = 4'b1011;
          8'b01100011 : bin = 4'b1100;
          8'b01100100 : bin = 4'b1101;
          8'b01100101 : bin = 4'b1110;
          8'b01100110 : bin = 4'b1111;
          default :
          begin
            bin = 4'bx;
          end
        endcase
        for( j=0; j<4; j=j+1)
        begin
          if ((index*4)+j < C_DOUT_WIDTH)
          begin
            hexstr_conv[(index*4)+j] = bin[j];
          end
        end
        index = index + 1;
        def_data = def_data >> 8;
      end
    end
  endfunction

   
   //*************************************************************************
   //  Set power-on states for regs
   //*************************************************************************
   initial begin
      ram_valid_i       = 1'b0;
      read_data_valid_i = 1'b0;
      USERDATA          = hexstr_conv(C_DOUT_RST_VAL);
      USERSBITERR       = 1'b0;
      USERDBITERR       = 1'b0;
   end //initial

   //***************************************************************************
   //  connect up optional reset
   //***************************************************************************
   assign rd_rst_i = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? RD_RST : 0;
   assign srst_i = C_HAS_SRST ? SRST || WR_RST_BUSY || RD_RST_BUSY : 0;

   localparam INVALID             = 0;
   localparam STAGE1_VALID        = 2;
   localparam STAGE2_VALID        = 1;
   localparam BOTH_STAGES_VALID   = 3;

   reg  [1:0] curr_fwft_state = INVALID;
   reg  [1:0] next_fwft_state = INVALID;

   generate if (C_FIFO_TYPE != 2) begin : gnll_fifo

      always @* begin
         case (curr_fwft_state)
            INVALID: begin
               if (~FIFOEMPTY)
                  next_fwft_state     <= STAGE1_VALID;
               else
                  next_fwft_state     <= INVALID;
               end
            STAGE1_VALID: begin
               if (FIFOEMPTY)
                  next_fwft_state     <= STAGE2_VALID;
               else
                  next_fwft_state     <= BOTH_STAGES_VALID;
               end
            STAGE2_VALID: begin
               if (FIFOEMPTY && RD_EN)
                  next_fwft_state     <= INVALID;
               else if (~FIFOEMPTY && RD_EN)
                  next_fwft_state     <= STAGE1_VALID;
               else if (~FIFOEMPTY && ~RD_EN)
                  next_fwft_state     <= BOTH_STAGES_VALID;
               else
                  next_fwft_state     <= STAGE2_VALID;
               end
            BOTH_STAGES_VALID: begin
               if (FIFOEMPTY && RD_EN)
                  next_fwft_state     <= STAGE2_VALID;
               else if (~FIFOEMPTY && RD_EN)
                  next_fwft_state     <= BOTH_STAGES_VALID;
               else
                  next_fwft_state     <= BOTH_STAGES_VALID;
               end
            default: next_fwft_state     <= INVALID;
         endcase
      end

      always @ (posedge rd_rst_i or posedge RD_CLK) begin
         if (rd_rst_i)
            curr_fwft_state  <= INVALID;
         else if (srst_i)
            curr_fwft_state  <= #`TCQ INVALID;
         else
            curr_fwft_state  <= #`TCQ next_fwft_state;
      end

      always @* begin
         case (curr_fwft_state)
            INVALID:           STAGE2_REG_EN <= 1'b0;
            STAGE1_VALID:      STAGE2_REG_EN <= 1'b1;
            STAGE2_VALID:      STAGE2_REG_EN <= 1'b0;
            BOTH_STAGES_VALID: STAGE2_REG_EN <= RD_EN;
            default:           STAGE2_REG_EN <= 1'b0;
         endcase
      end

    assign VALID_STAGES = curr_fwft_state;

     //***************************************************************************
     //  preloadstage2 indicates that stage2 needs to be updated. This is true
     //  whenever read_data_valid is false, and RAM_valid is true.
     //***************************************************************************
     assign preloadstage2 = ram_valid_i & (~read_data_valid_i | RD_EN);

     //***************************************************************************
     //  preloadstage1 indicates that stage1 needs to be updated. This is true
     //  whenever the RAM has data (RAM_EMPTY is false), and either RAM_Valid is
     //  false (indicating that Stage1 needs updating), or preloadstage2 is active
     //  (indicating that Stage2 is going to update, so Stage1, therefore, must
     //  also be updated to keep it valid.
     //***************************************************************************
     assign preloadstage1 = ((~ram_valid_i | preloadstage2) & ~FIFOEMPTY);
  
     //***************************************************************************
     // Calculate RAM_REGOUT_EN
     //  The output registers are controlled by the ram_regout_en signal.
     //  These registers should be updated either when the output in Stage2 is
     //  invalid (preloadstage2), OR when the user is reading, in which case the
     //  Stage2 value will go invalid unless it is replenished.
     //***************************************************************************
     assign ram_regout_en = preloadstage2;

     //***************************************************************************
     // Calculate RAM_RD_EN
     //   RAM_RD_EN will be asserted whenever the RAM needs to be read in order to
     //  update the value in Stage1.
     //   One case when this happens is when preloadstage1=true, which indicates
     //  that the data in Stage1 or Stage2 is invalid, and needs to automatically
     //  be updated.
     //   The other case is when the user is reading from the FIFO, which 
     // guarantees that Stage1 or Stage2 will be invalid on the next clock 
     // cycle, unless it is replinished by data from the memory. So, as long 
     // as the RAM has data in it, a read of the RAM should occur.
     //***************************************************************************
     assign ram_rd_en = (RD_EN & ~FIFOEMPTY) | preloadstage1;
   end endgenerate // gnll_fifo

   reg curr_state         = 0;
   reg next_state         = 0;
   reg leaving_empty_fwft = 0;
   reg going_empty_fwft   = 0;
   reg empty_i_q          = 0;
   reg ram_rd_en_fwft     = 0;
   generate if (C_FIFO_TYPE == 2) begin : gll_fifo
     always @* begin // FSM fo FWFT
       case (curr_state)
         1'b0: begin
           if (~FIFOEMPTY)
             next_state <= 1'b1;
           else
             next_state <= 1'b0;
           end
         1'b1: begin
           if (FIFOEMPTY && RD_EN)
             next_state <= 1'b0;
           else
             next_state <= 1'b1;
           end
         default: next_state <= 1'b0;
       endcase
     end

     always @ (posedge RD_CLK or posedge rd_rst_i) begin
        if (rd_rst_i) begin
           empty_i       <= 1'b1;
           empty_i_q     <= 1'b1;
           curr_state    <= 1'b0;
           ram_valid_i   <= 1'b0;
        end else if (srst_i) begin
           empty_i       <= #`TCQ 1'b1;
           empty_i_q     <= #`TCQ 1'b1;
           curr_state    <= #`TCQ 1'b0;
           ram_valid_i   <= #`TCQ 1'b0;
        end else begin
           empty_i       <= #`TCQ going_empty_fwft | (~leaving_empty_fwft & empty_i);
           empty_i_q     <= #`TCQ FIFOEMPTY;
           curr_state    <= #`TCQ next_state;
           ram_valid_i   <= #`TCQ next_state;
        end
     end //always

     wire                  fe_of_empty; 
     assign fe_of_empty   = empty_i_q & ~FIFOEMPTY;

     always @* begin // Finding leaving empty
       case (curr_state)
         1'b0:    leaving_empty_fwft <= fe_of_empty;
         1'b1:    leaving_empty_fwft <= 1'b1;
         default: leaving_empty_fwft <= 1'b0;
       endcase
     end

     always @* begin // Finding going empty
       case (curr_state)
         1'b1:    going_empty_fwft <= FIFOEMPTY & RD_EN;
         default: going_empty_fwft <= 1'b0;
       endcase
     end

     always @* begin // Generating FWFT rd_en
       case (curr_state)
         1'b0:    ram_rd_en_fwft <= ~FIFOEMPTY;
         1'b1:    ram_rd_en_fwft <= ~FIFOEMPTY & RD_EN;
         default: ram_rd_en_fwft <= 1'b0;
       endcase
     end

     assign ram_regout_en = ram_rd_en_fwft;
     assign ram_rd_en     = ram_rd_en_fwft;
   end endgenerate // gll_fifo


   //***************************************************************************
   // Calculate RAMVALID_P0_OUT
   //   RAMVALID_P0_OUT indicates that the data in Stage1 is valid.
   //
   //   If the RAM is being read from on this clock cycle (ram_rd_en=1), then
   //   RAMVALID_P0_OUT is certainly going to be true.
   //   If the RAM is not being read from, but the output registers are being
   //   updated to fill Stage2 (ram_regout_en=1), then Stage1 will be emptying,
   //   therefore causing RAMVALID_P0_OUT to be false.
   //   Otherwise, RAMVALID_P0_OUT will remain unchanged.
   //***************************************************************************
   // PROCESS regout_valid
   generate if (C_FIFO_TYPE < 2) begin : gnll_fifo_ram_valid
     always @ (posedge RD_CLK or posedge rd_rst_i) begin  
        if (rd_rst_i) begin 
           // asynchronous reset (active high)
           ram_valid_i     <= #`TCQ 1'b0;
        end else begin
           if (srst_i) begin 
              // synchronous reset (active high)
              ram_valid_i     <= #`TCQ 1'b0;
           end else begin
              if (ram_rd_en == 1'b1) begin
                 ram_valid_i   <= #`TCQ 1'b1;
              end else begin
                 if (ram_regout_en == 1'b1)
                   ram_valid_i <= #`TCQ 1'b0;
                 else
                   ram_valid_i <= #`TCQ ram_valid_i;
              end
           end //srst_i
        end //rd_rst_i
     end //always
   end endgenerate // gnll_fifo_ram_valid
   
   //***************************************************************************
   // Calculate READ_DATA_VALID
   //  READ_DATA_VALID indicates whether the value in Stage2 is valid or not.
   //  Stage2 has valid data whenever Stage1 had valid data and 
   //  ram_regout_en_i=1, such that the data in Stage1 is propogated 
   //  into Stage2.
   //***************************************************************************
   always @ (posedge RD_CLK or posedge rd_rst_i) begin
      if (rd_rst_i)
        read_data_valid_i <= #`TCQ 1'b0;
      else if (srst_i)
        read_data_valid_i <= #`TCQ 1'b0;
      else 
        read_data_valid_i <= #`TCQ ram_valid_i | (read_data_valid_i & ~RD_EN);
   end //always
   
   
   //**************************************************************************
   // Calculate EMPTY
   //  Defined as the inverse of READ_DATA_VALID
   //
   // Description:
   //
   //  If read_data_valid_i indicates that the output is not valid,
   // and there is no valid data on the output of the ram to preload it
   // with, then we will report empty.
   //
   //  If there is no valid data on the output of the ram and we are
   // reading, then the FIFO will go empty.
   //
   //**************************************************************************
   generate if (C_FIFO_TYPE < 2) begin : gnll_fifo_empty
     always @ (posedge RD_CLK or posedge rd_rst_i) begin
        if (rd_rst_i) begin
           // asynchronous reset (active high)
           empty_i <= #`TCQ 1'b1;
        end else begin
           if (srst_i) begin
              // synchronous reset (active high)
              empty_i <= #`TCQ 1'b1;
           end else begin
              // rising clock edge
              empty_i <= #`TCQ (~ram_valid_i & ~read_data_valid_i) | (~ram_valid_i & RD_EN);
           end
        end
     end //always
   end endgenerate // gnll_fifo_empty
   
   // Register RD_EN from user to calculate USERUNDERFLOW.
   // Register empty_i to calculate USERUNDERFLOW.
   always @ (posedge RD_CLK) begin
     rd_en_q <= #`TCQ RD_EN;
     empty_q <= #`TCQ empty_i;
   end //always
   
   
   //***************************************************************************
   // Calculate user_almost_empty
   //  user_almost_empty is defined such that, unless more words are written
   //  to the FIFO, the next read will cause the FIFO to go EMPTY.
   //
   //  In most cases, whenever the output registers are updated (due to a user
   // read or a preload condition), then user_almost_empty will update to
   // whatever RAM_EMPTY is.
   //
   //  The exception is when the output is valid, the user is not reading, and
   // Stage1 is not empty. In this condition, Stage1 will be preloaded from the
   // memory, so we need to make sure user_almost_empty deasserts properly under
   // this condition.
   //***************************************************************************
   always @ (posedge RD_CLK or posedge rd_rst_i)
     begin
        if (rd_rst_i) begin         // asynchronous reset (active high)
             almost_empty_i <= #`TCQ 1'b1;
             almost_empty_q <= #`TCQ 1'b1;
        end else begin // rising clock edge
           if (srst_i) begin          // synchronous reset (active high)
              almost_empty_i <= #`TCQ 1'b1;
              almost_empty_q <= #`TCQ 1'b1;
           end else begin
              if ((ram_regout_en) | (~FIFOEMPTY & read_data_valid_i & ~RD_EN)) begin
                 almost_empty_i <= #`TCQ FIFOEMPTY;
              end
              almost_empty_q   <= #`TCQ empty_i;
           end
        end
     end //always
   
   
   assign USEREMPTY       = empty_i;
   assign USERALMOSTEMPTY = almost_empty_i;
   assign FIFORDEN        = ram_rd_en;
   assign RAMVALID        = ram_valid_i;
   assign USERVALID       = C_USERVALID_LOW ? ~read_data_valid_i : read_data_valid_i;
   assign USERUNDERFLOW   = C_USERUNDERFLOW_LOW ? ~(empty_q & rd_en_q) : empty_q & rd_en_q;
  
  // BRAM resets synchronously
   always @ (posedge RD_CLK)
     begin
        if (rd_rst_i || srst_i) begin
          if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2)
            USERDATA     <= #`TCQ hexstr_conv(C_DOUT_RST_VAL);
        end
     end //always

 
   always @ (posedge RD_CLK or posedge rd_rst_i)
     begin
        if (rd_rst_i) begin //asynchronous reset (active high)
          if (C_USE_ECC == 0) begin // Reset S/DBITERR only if ECC is OFF
            USERSBITERR    <= #`TCQ 0;
            USERDBITERR    <= #`TCQ 0;
          end
          // DRAM resets asynchronously
          if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE == 2)  //asynchronous reset (active high)
            USERDATA     <= #`TCQ hexstr_conv(C_DOUT_RST_VAL);
        end else begin // rising clock edge
          if (srst_i) begin
            if (C_USE_ECC == 0) begin // Reset S/DBITERR only if ECC is OFF
              USERSBITERR  <= #`TCQ 0;
              USERDBITERR  <= #`TCQ 0;
            end
            if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE == 2)
              USERDATA   <= #`TCQ hexstr_conv(C_DOUT_RST_VAL);
          end else begin
            if (ram_regout_en) begin
               USERDATA     <= #`TCQ FIFODATA;
               USERSBITERR  <= #`TCQ FIFOSBITERR;
               USERDBITERR  <= #`TCQ FIFODBITERR;
            end
          end
        end
     end //always

endmodule

//-----------------------------------------------------------------------------
//
// Register Slice
//   Register one AXI channel on forward and/or reverse signal path
//
// Verilog-standard:  Verilog 2001
//--------------------------------------------------------------------------
//
// Structure:
//   reg_slice
//
//--------------------------------------------------------------------------

module fifo_generator_v12_0_axic_reg_slice #
  (
   parameter C_FAMILY     = "virtex7",
   parameter C_DATA_WIDTH = 32,
   parameter C_REG_CONFIG = 32'h00000000
   )
  (
   // System Signals
   input  wire                      ACLK,
   input  wire                      ARESET,

   // Slave side
   input  wire [C_DATA_WIDTH-1:0]   S_PAYLOAD_DATA,
   input  wire                      S_VALID,
   output wire                      S_READY,

   // Master side
   output wire [C_DATA_WIDTH-1:0]   M_PAYLOAD_DATA,
   output wire                      M_VALID,
   input  wire                      M_READY
   );

  generate
  ////////////////////////////////////////////////////////////////////
  //
  // Both FWD and REV mode
  //
  ////////////////////////////////////////////////////////////////////
    if (C_REG_CONFIG == 32'h00000000)
    begin
      reg [1:0] state;
      localparam [1:0] 
        ZERO = 2'b10,
        ONE  = 2'b11,
        TWO  = 2'b01;
      
      reg [C_DATA_WIDTH-1:0] storage_data1 = 0;
      reg [C_DATA_WIDTH-1:0] storage_data2 = 0;
      reg                    load_s1;
      wire                   load_s2;
      wire                   load_s1_from_s2;
      reg                    s_ready_i; //local signal of output
      wire                   m_valid_i; //local signal of output

      // assign local signal to its output signal
      assign S_READY = s_ready_i;
      assign M_VALID = m_valid_i;

      reg  areset_d1; // Reset delay register
      always @(posedge ACLK) begin
        areset_d1 <= ARESET;
      end
      
      // Load storage1 with either slave side data or from storage2
      always @(posedge ACLK) 
      begin
        if (load_s1)
          if (load_s1_from_s2)
            storage_data1 <= storage_data2;
          else
            storage_data1 <= S_PAYLOAD_DATA;        
      end

      // Load storage2 with slave side data
      always @(posedge ACLK) 
      begin
        if (load_s2)
          storage_data2 <= S_PAYLOAD_DATA;
      end

      assign M_PAYLOAD_DATA = storage_data1;

      // Always load s2 on a valid transaction even if it's unnecessary
      assign load_s2 = S_VALID & s_ready_i;

      // Loading s1
      always @ *
      begin
        if ( ((state == ZERO) && (S_VALID == 1)) || // Load when empty on slave transaction
             // Load when ONE if we both have read and write at the same time
             ((state == ONE) && (S_VALID == 1) && (M_READY == 1)) ||
             // Load when TWO and we have a transaction on Master side
             ((state == TWO) && (M_READY == 1)))
          load_s1 = 1'b1;
        else
          load_s1 = 1'b0;
      end // always @ *

      assign load_s1_from_s2 = (state == TWO);
                       
      // State Machine for handling output signals
      always @(posedge ACLK) begin
        if (ARESET) begin
          s_ready_i <= 1'b0;
          state <= ZERO;
        end else if (areset_d1) begin
          s_ready_i <= 1'b1;
        end else begin
          case (state)
            // No transaction stored locally
            ZERO: if (S_VALID) state <= ONE; // Got one so move to ONE

            // One transaction stored locally
            ONE: begin
              if (M_READY & ~S_VALID) state <= ZERO; // Read out one so move to ZERO
              if (~M_READY & S_VALID) begin
                state <= TWO;  // Got another one so move to TWO
                s_ready_i <= 1'b0;
              end
            end

            // TWO transaction stored locally
            TWO: if (M_READY) begin
              state <= ONE; // Read out one so move to ONE
              s_ready_i <= 1'b1;
            end
          endcase // case (state)
        end
      end // always @ (posedge ACLK)
      
      assign m_valid_i = state[0];

    end // if (C_REG_CONFIG == 1)
  ////////////////////////////////////////////////////////////////////
  //
  // 1-stage pipeline register with bubble cycle, both FWD and REV pipelining
  // Operates same as 1-deep FIFO
  //
  ////////////////////////////////////////////////////////////////////
    else if (C_REG_CONFIG == 32'h00000001)
    begin
      reg [C_DATA_WIDTH-1:0] storage_data1 = 0;
      reg                    s_ready_i; //local signal of output
      reg                    m_valid_i; //local signal of output

      // assign local signal to its output signal
      assign S_READY = s_ready_i;
      assign M_VALID = m_valid_i;

      reg  areset_d1; // Reset delay register
      always @(posedge ACLK) begin
        areset_d1 <= ARESET;
      end
      
      // Load storage1 with slave side data
      always @(posedge ACLK) 
      begin
        if (ARESET) begin
          s_ready_i <= 1'b0;
          m_valid_i <= 1'b0;
        end else if (areset_d1) begin
          s_ready_i <= 1'b1;
        end else if (m_valid_i & M_READY) begin
          s_ready_i <= 1'b1;
          m_valid_i <= 1'b0;
        end else if (S_VALID & s_ready_i) begin
          s_ready_i <= 1'b0;
          m_valid_i <= 1'b1;
        end
        if (~m_valid_i) begin
          storage_data1 <= S_PAYLOAD_DATA;        
        end
      end
      assign M_PAYLOAD_DATA = storage_data1;
    end // if (C_REG_CONFIG == 7)
    
    else begin : default_case
      // Passthrough
      assign M_PAYLOAD_DATA = S_PAYLOAD_DATA;
      assign M_VALID        = S_VALID;
      assign S_READY        = M_READY;      
    end

  endgenerate
endmodule // reg_slice
