/*
 *******************************************************************************
 *
 * 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 100
`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

   // if an asynchronous FIFO has been selected, display a message that the FIFO
   //   will not be cycle-accurate in simulation
   initial begin
      if (C_IMPLEMENTATION_TYPE == 2) begin
         $display("WARNING: Behavioral models for independent clock FIFO configurations do not model synchronization delays. The behavioral models are functionally correct, and will represent the behavior of the configured FIFO. See the FIFO Generator User Guide for more information.");
      end else if (C_MEMORY_TYPE == 4) begin
         $display("FAILURE : Behavioral models do not support built-in FIFO configurations. Please use post-synthesis or post-implement simulation in Vivado.");
         $finish;
      end

      if (C_WR_PNTR_WIDTH != find_log2(C_WR_DEPTH)) begin
         $display("FAILURE : C_WR_PNTR_WIDTH is not log2 of C_WR_DEPTH.");
         $finish;
      end

      if (C_RD_PNTR_WIDTH != find_log2(C_RD_DEPTH)) begin
         $display("FAILURE : C_RD_PNTR_WIDTH is not log2 of C_RD_DEPTH.");
         $finish;
      end

      if (C_USE_ECC == 1) begin
         if (C_DIN_WIDTH != C_DOUT_WIDTH) begin
            $display("FAILURE : C_DIN_WIDTH and C_DOUT_WIDTH must be equal for ECC configuration.");
            $finish;
         end
         if (C_DIN_WIDTH == 1 && C_ERROR_INJECTION_TYPE > 1) begin
            $display("FAILURE : C_DIN_WIDTH and C_DOUT_WIDTH must be > 1 for double bit error injection.");
            $finish;
         end
      end

   end //initial

  /**************************************************************************
  * 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
   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
      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
             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
