diff --git a/memory/fpga/fifo_generator_v12_0/simulation/fifo_generator_vlog_beh.v b/memory/fpga/fifo_generator_v12_0/simulation/fifo_generator_vlog_beh.v new file mode 100755 index 0000000..b35dc51 --- /dev/null +++ b/memory/fpga/fifo_generator_v12_0/simulation/fifo_generator_vlog_beh.v @@ -0,0 +1,9168 @@ +/* + ******************************************************************************* + * + * 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 + + + /************************************************************************** + * 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 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 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 diff --git a/memory/fpga/sim/fifo_async_104x32.v b/memory/fpga/sim/fifo_async_104x32.v new file mode 100644 index 0000000..0d7e8f1 --- /dev/null +++ b/memory/fpga/sim/fifo_async_104x32.v @@ -0,0 +1,526 @@ +// (c) Copyright 1995-2015 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. +// +// DO NOT MODIFY THIS FILE. + + +// IP VLNV: xilinx.com:ip:fifo_generator:12.0 +// IP Revision: 4 + +`timescale 1ns/1ps + +(* DowngradeIPIdentifiedWarnings = "yes" *) +module fifo_async_104x32 ( + rst, + wr_clk, + rd_clk, + din, + wr_en, + rd_en, + dout, + full, + empty, + valid, + prog_full +); + +input wire rst; +(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 write_clk CLK" *) +input wire wr_clk; +(* X_INTERFACE_INFO = "xilinx.com:signal:clock:1.0 read_clk CLK" *) +input wire rd_clk; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_write:1.0 FIFO_WRITE WR_DATA" *) +input wire [103 : 0] din; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_write:1.0 FIFO_WRITE WR_EN" *) +input wire wr_en; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_read:1.0 FIFO_READ RD_EN" *) +input wire rd_en; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_read:1.0 FIFO_READ RD_DATA" *) +output wire [103 : 0] dout; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_write:1.0 FIFO_WRITE FULL" *) +output wire full; +(* X_INTERFACE_INFO = "xilinx.com:interface:fifo_read:1.0 FIFO_READ EMPTY" *) +output wire empty; +output wire valid; +output wire prog_full; + + //fifo_generator_v12_0 + +fifo_generator_vlog_beh #( + .C_COMMON_CLOCK(0), + .C_COUNT_TYPE(0), + .C_DATA_COUNT_WIDTH(5), + .C_DEFAULT_VALUE("BlankString"), + .C_DIN_WIDTH(104), + .C_DOUT_RST_VAL("0"), + .C_DOUT_WIDTH(104), + .C_ENABLE_RLOCS(0), + .C_FAMILY("zynq"), + .C_FULL_FLAGS_RST_VAL(0), + .C_HAS_ALMOST_EMPTY(0), + .C_HAS_ALMOST_FULL(0), + .C_HAS_BACKUP(0), + .C_HAS_DATA_COUNT(0), + .C_HAS_INT_CLK(0), + .C_HAS_MEMINIT_FILE(0), + .C_HAS_OVERFLOW(0), + .C_HAS_RD_DATA_COUNT(0), + .C_HAS_RD_RST(0), + .C_HAS_RST(1), + .C_HAS_SRST(0), + .C_HAS_UNDERFLOW(0), + .C_HAS_VALID(1), + .C_HAS_WR_ACK(0), + .C_HAS_WR_DATA_COUNT(0), + .C_HAS_WR_RST(0), + .C_IMPLEMENTATION_TYPE(2), + .C_INIT_WR_PNTR_VAL(0), + .C_MEMORY_TYPE(2), + .C_MIF_FILE_NAME("BlankString"), + .C_OPTIMIZATION_MODE(0), + .C_OVERFLOW_LOW(0), + .C_PRELOAD_LATENCY(1), + .C_PRELOAD_REGS(0), + .C_PRIM_FIFO_TYPE("512x72"), + .C_PROG_EMPTY_THRESH_ASSERT_VAL(2), + .C_PROG_EMPTY_THRESH_NEGATE_VAL(3), + .C_PROG_EMPTY_TYPE(0), + .C_PROG_FULL_THRESH_ASSERT_VAL(16), + .C_PROG_FULL_THRESH_NEGATE_VAL(15), + .C_PROG_FULL_TYPE(1), + .C_RD_DATA_COUNT_WIDTH(5), + .C_RD_DEPTH(32), + .C_RD_FREQ(1), + .C_RD_PNTR_WIDTH(5), + .C_UNDERFLOW_LOW(0), + .C_USE_DOUT_RST(1), + .C_USE_ECC(0), + .C_USE_EMBEDDED_REG(0), + .C_USE_PIPELINE_REG(0), + .C_POWER_SAVING_MODE(0), + .C_USE_FIFO16_FLAGS(0), + .C_USE_FWFT_DATA_COUNT(0), + .C_VALID_LOW(0), + .C_WR_ACK_LOW(0), + .C_WR_DATA_COUNT_WIDTH(5), + .C_WR_DEPTH(32), + .C_WR_FREQ(1), + .C_WR_PNTR_WIDTH(5), + .C_WR_RESPONSE_LATENCY(1), + .C_MSGON_VAL(1), + .C_ENABLE_RST_SYNC(1), + .C_ERROR_INJECTION_TYPE(0), + .C_SYNCHRONIZER_STAGE(2), + .C_INTERFACE_TYPE(0), + .C_AXI_TYPE(1), + .C_HAS_AXI_WR_CHANNEL(1), + .C_HAS_AXI_RD_CHANNEL(1), + .C_HAS_SLAVE_CE(0), + .C_HAS_MASTER_CE(0), + .C_ADD_NGC_CONSTRAINT(0), + .C_USE_COMMON_OVERFLOW(0), + .C_USE_COMMON_UNDERFLOW(0), + .C_USE_DEFAULT_SETTINGS(0), + .C_AXI_ID_WIDTH(1), + .C_AXI_ADDR_WIDTH(32), + .C_AXI_DATA_WIDTH(64), + .C_AXI_LEN_WIDTH(8), + .C_AXI_LOCK_WIDTH(1), + .C_HAS_AXI_ID(0), + .C_HAS_AXI_AWUSER(0), + .C_HAS_AXI_WUSER(0), + .C_HAS_AXI_BUSER(0), + .C_HAS_AXI_ARUSER(0), + .C_HAS_AXI_RUSER(0), + .C_AXI_ARUSER_WIDTH(1), + .C_AXI_AWUSER_WIDTH(1), + .C_AXI_WUSER_WIDTH(1), + .C_AXI_BUSER_WIDTH(1), + .C_AXI_RUSER_WIDTH(1), + .C_HAS_AXIS_TDATA(1), + .C_HAS_AXIS_TID(0), + .C_HAS_AXIS_TDEST(0), + .C_HAS_AXIS_TUSER(1), + .C_HAS_AXIS_TREADY(1), + .C_HAS_AXIS_TLAST(0), + .C_HAS_AXIS_TSTRB(0), + .C_HAS_AXIS_TKEEP(0), + .C_AXIS_TDATA_WIDTH(8), + .C_AXIS_TID_WIDTH(1), + .C_AXIS_TDEST_WIDTH(1), + .C_AXIS_TUSER_WIDTH(4), + .C_AXIS_TSTRB_WIDTH(1), + .C_AXIS_TKEEP_WIDTH(1), + .C_WACH_TYPE(0), + .C_WDCH_TYPE(0), + .C_WRCH_TYPE(0), + .C_RACH_TYPE(0), + .C_RDCH_TYPE(0), + .C_AXIS_TYPE(0), + .C_IMPLEMENTATION_TYPE_WACH(1), + .C_IMPLEMENTATION_TYPE_WDCH(1), + .C_IMPLEMENTATION_TYPE_WRCH(1), + .C_IMPLEMENTATION_TYPE_RACH(1), + .C_IMPLEMENTATION_TYPE_RDCH(1), + .C_IMPLEMENTATION_TYPE_AXIS(1), + .C_APPLICATION_TYPE_WACH(0), + .C_APPLICATION_TYPE_WDCH(0), + .C_APPLICATION_TYPE_WRCH(0), + .C_APPLICATION_TYPE_RACH(0), + .C_APPLICATION_TYPE_RDCH(0), + .C_APPLICATION_TYPE_AXIS(0), + .C_PRIM_FIFO_TYPE_WACH("512x36"), + .C_PRIM_FIFO_TYPE_WDCH("1kx36"), + .C_PRIM_FIFO_TYPE_WRCH("512x36"), + .C_PRIM_FIFO_TYPE_RACH("512x36"), + .C_PRIM_FIFO_TYPE_RDCH("1kx36"), + .C_PRIM_FIFO_TYPE_AXIS("1kx18"), + .C_USE_ECC_WACH(0), + .C_USE_ECC_WDCH(0), + .C_USE_ECC_WRCH(0), + .C_USE_ECC_RACH(0), + .C_USE_ECC_RDCH(0), + .C_USE_ECC_AXIS(0), + .C_ERROR_INJECTION_TYPE_WACH(0), + .C_ERROR_INJECTION_TYPE_WDCH(0), + .C_ERROR_INJECTION_TYPE_WRCH(0), + .C_ERROR_INJECTION_TYPE_RACH(0), + .C_ERROR_INJECTION_TYPE_RDCH(0), + .C_ERROR_INJECTION_TYPE_AXIS(0), + .C_DIN_WIDTH_WACH(32), + .C_DIN_WIDTH_WDCH(64), + .C_DIN_WIDTH_WRCH(2), + .C_DIN_WIDTH_RACH(32), + .C_DIN_WIDTH_RDCH(64), + .C_DIN_WIDTH_AXIS(1), + .C_WR_DEPTH_WACH(16), + .C_WR_DEPTH_WDCH(1024), + .C_WR_DEPTH_WRCH(16), + .C_WR_DEPTH_RACH(16), + .C_WR_DEPTH_RDCH(1024), + .C_WR_DEPTH_AXIS(1024), + .C_WR_PNTR_WIDTH_WACH(4), + .C_WR_PNTR_WIDTH_WDCH(10), + .C_WR_PNTR_WIDTH_WRCH(4), + .C_WR_PNTR_WIDTH_RACH(4), + .C_WR_PNTR_WIDTH_RDCH(10), + .C_WR_PNTR_WIDTH_AXIS(10), + .C_HAS_DATA_COUNTS_WACH(0), + .C_HAS_DATA_COUNTS_WDCH(0), + .C_HAS_DATA_COUNTS_WRCH(0), + .C_HAS_DATA_COUNTS_RACH(0), + .C_HAS_DATA_COUNTS_RDCH(0), + .C_HAS_DATA_COUNTS_AXIS(0), + .C_HAS_PROG_FLAGS_WACH(0), + .C_HAS_PROG_FLAGS_WDCH(0), + .C_HAS_PROG_FLAGS_WRCH(0), + .C_HAS_PROG_FLAGS_RACH(0), + .C_HAS_PROG_FLAGS_RDCH(0), + .C_HAS_PROG_FLAGS_AXIS(0), + .C_PROG_FULL_TYPE_WACH(0), + .C_PROG_FULL_TYPE_WDCH(0), + .C_PROG_FULL_TYPE_WRCH(0), + .C_PROG_FULL_TYPE_RACH(0), + .C_PROG_FULL_TYPE_RDCH(0), + .C_PROG_FULL_TYPE_AXIS(0), + .C_PROG_FULL_THRESH_ASSERT_VAL_WACH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_WDCH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_WRCH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_RACH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_RDCH(1023), + .C_PROG_FULL_THRESH_ASSERT_VAL_AXIS(1023), + .C_PROG_EMPTY_TYPE_WACH(0), + .C_PROG_EMPTY_TYPE_WDCH(0), + .C_PROG_EMPTY_TYPE_WRCH(0), + .C_PROG_EMPTY_TYPE_RACH(0), + .C_PROG_EMPTY_TYPE_RDCH(0), + .C_PROG_EMPTY_TYPE_AXIS(0), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_WACH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_WDCH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_WRCH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_RACH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_RDCH(1022), + .C_PROG_EMPTY_THRESH_ASSERT_VAL_AXIS(1022), + .C_REG_SLICE_MODE_WACH(0), + .C_REG_SLICE_MODE_WDCH(0), + .C_REG_SLICE_MODE_WRCH(0), + .C_REG_SLICE_MODE_RACH(0), + .C_REG_SLICE_MODE_RDCH(0), + .C_REG_SLICE_MODE_AXIS(0) + ) inst ( + .backup(1'D0), + .backup_marker(1'D0), + .clk(1'D0), + .rst(rst), + .srst(1'D0), + .wr_clk(wr_clk), + .wr_rst(1'D0), + .rd_clk(rd_clk), + .rd_rst(1'D0), + .din(din), + .wr_en(wr_en), + .rd_en(rd_en), + .prog_empty_thresh(5'B0), + .prog_empty_thresh_assert(5'B0), + .prog_empty_thresh_negate(5'B0), + .prog_full_thresh(5'B0), + .prog_full_thresh_assert(5'B0), + .prog_full_thresh_negate(5'B0), + .int_clk(1'D0), + .injectdbiterr(1'D0), + .injectsbiterr(1'D0), + .sleep(1'D0), + .dout(dout), + .full(full), + .almost_full(), + .wr_ack(), + .overflow(), + .empty(empty), + .almost_empty(), + .valid(valid), + .underflow(), + .data_count(), + .rd_data_count(), + .wr_data_count(), + .prog_full(prog_full), + .prog_empty(), + .sbiterr(), + .dbiterr(), + .wr_rst_busy(), + .rd_rst_busy(), + .m_aclk(1'D0), + .s_aclk(1'D0), + .s_aresetn(1'D0), + .m_aclk_en(1'D0), + .s_aclk_en(1'D0), + .s_axi_awid(1'B0), + .s_axi_awaddr(32'B0), + .s_axi_awlen(8'B0), + .s_axi_awsize(3'B0), + .s_axi_awburst(2'B0), + .s_axi_awlock(1'B0), + .s_axi_awcache(4'B0), + .s_axi_awprot(3'B0), + .s_axi_awqos(4'B0), + .s_axi_awregion(4'B0), + .s_axi_awuser(1'B0), + .s_axi_awvalid(1'D0), + .s_axi_awready(), + .s_axi_wid(1'B0), + .s_axi_wdata(64'B0), + .s_axi_wstrb(8'B0), + .s_axi_wlast(1'D0), + .s_axi_wuser(1'B0), + .s_axi_wvalid(1'D0), + .s_axi_wready(), + .s_axi_bid(), + .s_axi_bresp(), + .s_axi_buser(), + .s_axi_bvalid(), + .s_axi_bready(1'D0), + .m_axi_awid(), + .m_axi_awaddr(), + .m_axi_awlen(), + .m_axi_awsize(), + .m_axi_awburst(), + .m_axi_awlock(), + .m_axi_awcache(), + .m_axi_awprot(), + .m_axi_awqos(), + .m_axi_awregion(), + .m_axi_awuser(), + .m_axi_awvalid(), + .m_axi_awready(1'D0), + .m_axi_wid(), + .m_axi_wdata(), + .m_axi_wstrb(), + .m_axi_wlast(), + .m_axi_wuser(), + .m_axi_wvalid(), + .m_axi_wready(1'D0), + .m_axi_bid(1'B0), + .m_axi_bresp(2'B0), + .m_axi_buser(1'B0), + .m_axi_bvalid(1'D0), + .m_axi_bready(), + .s_axi_arid(1'B0), + .s_axi_araddr(32'B0), + .s_axi_arlen(8'B0), + .s_axi_arsize(3'B0), + .s_axi_arburst(2'B0), + .s_axi_arlock(1'B0), + .s_axi_arcache(4'B0), + .s_axi_arprot(3'B0), + .s_axi_arqos(4'B0), + .s_axi_arregion(4'B0), + .s_axi_aruser(1'B0), + .s_axi_arvalid(1'D0), + .s_axi_arready(), + .s_axi_rid(), + .s_axi_rdata(), + .s_axi_rresp(), + .s_axi_rlast(), + .s_axi_ruser(), + .s_axi_rvalid(), + .s_axi_rready(1'D0), + .m_axi_arid(), + .m_axi_araddr(), + .m_axi_arlen(), + .m_axi_arsize(), + .m_axi_arburst(), + .m_axi_arlock(), + .m_axi_arcache(), + .m_axi_arprot(), + .m_axi_arqos(), + .m_axi_arregion(), + .m_axi_aruser(), + .m_axi_arvalid(), + .m_axi_arready(1'D0), + .m_axi_rid(1'B0), + .m_axi_rdata(64'B0), + .m_axi_rresp(2'B0), + .m_axi_rlast(1'D0), + .m_axi_ruser(1'B0), + .m_axi_rvalid(1'D0), + .m_axi_rready(), + .s_axis_tvalid(1'D0), + .s_axis_tready(), + .s_axis_tdata(8'B0), + .s_axis_tstrb(1'B0), + .s_axis_tkeep(1'B0), + .s_axis_tlast(1'D0), + .s_axis_tid(1'B0), + .s_axis_tdest(1'B0), + .s_axis_tuser(4'B0), + .m_axis_tvalid(), + .m_axis_tready(1'D0), + .m_axis_tdata(), + .m_axis_tstrb(), + .m_axis_tkeep(), + .m_axis_tlast(), + .m_axis_tid(), + .m_axis_tdest(), + .m_axis_tuser(), + .axi_aw_injectsbiterr(1'D0), + .axi_aw_injectdbiterr(1'D0), + .axi_aw_prog_full_thresh(4'B0), + .axi_aw_prog_empty_thresh(4'B0), + .axi_aw_data_count(), + .axi_aw_wr_data_count(), + .axi_aw_rd_data_count(), + .axi_aw_sbiterr(), + .axi_aw_dbiterr(), + .axi_aw_overflow(), + .axi_aw_underflow(), + .axi_aw_prog_full(), + .axi_aw_prog_empty(), + .axi_w_injectsbiterr(1'D0), + .axi_w_injectdbiterr(1'D0), + .axi_w_prog_full_thresh(10'B0), + .axi_w_prog_empty_thresh(10'B0), + .axi_w_data_count(), + .axi_w_wr_data_count(), + .axi_w_rd_data_count(), + .axi_w_sbiterr(), + .axi_w_dbiterr(), + .axi_w_overflow(), + .axi_w_underflow(), + .axi_w_prog_full(), + .axi_w_prog_empty(), + .axi_b_injectsbiterr(1'D0), + .axi_b_injectdbiterr(1'D0), + .axi_b_prog_full_thresh(4'B0), + .axi_b_prog_empty_thresh(4'B0), + .axi_b_data_count(), + .axi_b_wr_data_count(), + .axi_b_rd_data_count(), + .axi_b_sbiterr(), + .axi_b_dbiterr(), + .axi_b_overflow(), + .axi_b_underflow(), + .axi_b_prog_full(), + .axi_b_prog_empty(), + .axi_ar_injectsbiterr(1'D0), + .axi_ar_injectdbiterr(1'D0), + .axi_ar_prog_full_thresh(4'B0), + .axi_ar_prog_empty_thresh(4'B0), + .axi_ar_data_count(), + .axi_ar_wr_data_count(), + .axi_ar_rd_data_count(), + .axi_ar_sbiterr(), + .axi_ar_dbiterr(), + .axi_ar_overflow(), + .axi_ar_underflow(), + .axi_ar_prog_full(), + .axi_ar_prog_empty(), + .axi_r_injectsbiterr(1'D0), + .axi_r_injectdbiterr(1'D0), + .axi_r_prog_full_thresh(10'B0), + .axi_r_prog_empty_thresh(10'B0), + .axi_r_data_count(), + .axi_r_wr_data_count(), + .axi_r_rd_data_count(), + .axi_r_sbiterr(), + .axi_r_dbiterr(), + .axi_r_overflow(), + .axi_r_underflow(), + .axi_r_prog_full(), + .axi_r_prog_empty(), + .axis_injectsbiterr(1'D0), + .axis_injectdbiterr(1'D0), + .axis_prog_full_thresh(10'B0), + .axis_prog_empty_thresh(10'B0), + .axis_data_count(), + .axis_wr_data_count(), + .axis_rd_data_count(), + .axis_sbiterr(), + .axis_dbiterr(), + .axis_overflow(), + .axis_underflow(), + .axis_prog_full(), + .axis_prog_empty() + ); +endmodule