/*verilator lint_off IMPLICIT*/ /*verilator lint_off WIDTH*/ /*verilator lint_off LITENDIAN*/ /* verilator lint_off COMBDLY*/ /* ******************************************************************************* * * FIFO Generator - Verilog Behavioral Model * ******************************************************************************* * * (c) Copyright 1995 - 2009 Xilinx, Inc. All rights reserved. * * This file contains confidential and proprietary information * of Xilinx, Inc. and is protected under U.S. and * international copyright and other intellectual property * laws. * * DISCLAIMER * This disclaimer is not a license and does not grant any * rights to the materials distributed herewith. Except as * otherwise provided in a valid license issued to you by * Xilinx, and to the maximum extent permitted by applicable * law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND * WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES * AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING * BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- * INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and * (2) Xilinx shall not be liable (whether in contract or tort, * including negligence, or under any other theory of * liability) for any loss or damage of any kind or nature * related to, arising under or in connection with these * materials, including for any direct, or any indirect, * special, incidental, or consequential loss or damage * (including loss of data, profits, goodwill, or any type of * loss or damage suffered as a result of any action brought * by a third party) even if such damage or loss was * reasonably foreseeable or Xilinx had been advised of the * possibility of the same. * * CRITICAL APPLICATIONS * Xilinx products are not designed or intended to be fail- * safe, or for use in any application requiring fail-safe * performance, such as life-support or safety devices or * systems, Class III medical devices, nuclear facilities, * applications related to the deployment of airbags, or any * other applications that could lead to death, personal * injury, or severe property or environmental damage * (individually and collectively, "Critical * Applications"). Customer assumes the sole risk and * liability of any use of Xilinx products in Critical * Applications, subject only to applicable laws and * regulations governing limitations on product liability. * * THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS * PART OF THIS FILE AT ALL TIMES. * ******************************************************************************* ******************************************************************************* * * Filename: fifo_generator_vlog_beh.v * * Author : Xilinx * ******************************************************************************* * Structure: * * fifo_generator_vlog_beh.v * | * +-fifo_generator_v12_0_bhv_ver_as * | * +-fifo_generator_v12_0_bhv_ver_ss * | * +-fifo_generator_v12_0_bhv_ver_preload0 * ******************************************************************************* * Description: * * The Verilog behavioral model for the FIFO Generator. * * The behavioral model has three parts: * - The behavioral model for independent clocks FIFOs (_as) * - The behavioral model for common clock FIFOs (_ss) * - The "preload logic" block which implements First-word Fall-through * ******************************************************************************* * Description: * The verilog behavioral model for the FIFO generator core. * ******************************************************************************* */ //`timescale 1ps/1ps `ifndef TCQ `define TCQ 0.1 `endif /******************************************************************************* * Declaration of top-level module ******************************************************************************/ module fifo_generator_vlog_beh #( //----------------------------------------------------------------------- // Generic Declarations //----------------------------------------------------------------------- parameter C_COMMON_CLOCK = 0, parameter C_COUNT_TYPE = 0, parameter C_DATA_COUNT_WIDTH = 2, parameter C_DEFAULT_VALUE = "", parameter C_DIN_WIDTH = 8, parameter C_DOUT_RST_VAL = "", parameter C_DOUT_WIDTH = 8, parameter C_ENABLE_RLOCS = 0, parameter C_FAMILY = "", parameter C_FULL_FLAGS_RST_VAL = 1, parameter C_HAS_ALMOST_EMPTY = 0, parameter C_HAS_ALMOST_FULL = 0, parameter C_HAS_BACKUP = 0, parameter C_HAS_DATA_COUNT = 0, parameter C_HAS_INT_CLK = 0, parameter C_HAS_MEMINIT_FILE = 0, parameter C_HAS_OVERFLOW = 0, parameter C_HAS_RD_DATA_COUNT = 0, parameter C_HAS_RD_RST = 0, parameter C_HAS_RST = 1, parameter C_HAS_SRST = 0, parameter C_HAS_UNDERFLOW = 0, parameter C_HAS_VALID = 0, parameter C_HAS_WR_ACK = 0, parameter C_HAS_WR_DATA_COUNT = 0, parameter C_HAS_WR_RST = 0, parameter C_IMPLEMENTATION_TYPE = 0, parameter C_INIT_WR_PNTR_VAL = 0, parameter C_MEMORY_TYPE = 1, parameter C_MIF_FILE_NAME = "", parameter C_OPTIMIZATION_MODE = 0, parameter C_OVERFLOW_LOW = 0, parameter C_PRELOAD_LATENCY = 1, parameter C_PRELOAD_REGS = 0, parameter C_PRIM_FIFO_TYPE = "4kx4", parameter C_PROG_EMPTY_THRESH_ASSERT_VAL = 0, parameter C_PROG_EMPTY_THRESH_NEGATE_VAL = 0, parameter C_PROG_EMPTY_TYPE = 0, parameter C_PROG_FULL_THRESH_ASSERT_VAL = 0, parameter C_PROG_FULL_THRESH_NEGATE_VAL = 0, parameter C_PROG_FULL_TYPE = 0, parameter C_RD_DATA_COUNT_WIDTH = 2, parameter C_RD_DEPTH = 256, parameter C_RD_FREQ = 1, parameter C_RD_PNTR_WIDTH = 8, parameter C_UNDERFLOW_LOW = 0, parameter C_USE_DOUT_RST = 0, parameter C_USE_ECC = 0, parameter C_USE_EMBEDDED_REG = 0, parameter C_USE_PIPELINE_REG = 0, parameter C_POWER_SAVING_MODE = 0, parameter C_USE_FIFO16_FLAGS = 0, parameter C_USE_FWFT_DATA_COUNT = 0, parameter C_VALID_LOW = 0, parameter C_WR_ACK_LOW = 0, parameter C_WR_DATA_COUNT_WIDTH = 2, parameter C_WR_DEPTH = 256, parameter C_WR_FREQ = 1, parameter C_WR_PNTR_WIDTH = 8, parameter C_WR_RESPONSE_LATENCY = 1, parameter C_MSGON_VAL = 1, parameter C_ENABLE_RST_SYNC = 1, parameter C_ERROR_INJECTION_TYPE = 0, parameter C_SYNCHRONIZER_STAGE = 2, // AXI Interface related parameters start here parameter C_INTERFACE_TYPE = 0, // 0: Native Interface, 1: AXI4 Stream, 2: AXI4/AXI3 parameter C_AXI_TYPE = 0, // 1: AXI4, 2: AXI4 Lite, 3: AXI3 parameter C_HAS_AXI_WR_CHANNEL = 0, parameter C_HAS_AXI_RD_CHANNEL = 0, parameter C_HAS_SLAVE_CE = 0, parameter C_HAS_MASTER_CE = 0, parameter C_ADD_NGC_CONSTRAINT = 0, parameter C_USE_COMMON_UNDERFLOW = 0, parameter C_USE_COMMON_OVERFLOW = 0, parameter C_USE_DEFAULT_SETTINGS = 0, // AXI Full/Lite parameter C_AXI_ID_WIDTH = 0, parameter C_AXI_ADDR_WIDTH = 0, parameter C_AXI_DATA_WIDTH = 0, parameter C_AXI_LEN_WIDTH = 8, parameter C_AXI_LOCK_WIDTH = 2, parameter C_HAS_AXI_ID = 0, parameter C_HAS_AXI_AWUSER = 0, parameter C_HAS_AXI_WUSER = 0, parameter C_HAS_AXI_BUSER = 0, parameter C_HAS_AXI_ARUSER = 0, parameter C_HAS_AXI_RUSER = 0, parameter C_AXI_ARUSER_WIDTH = 0, parameter C_AXI_AWUSER_WIDTH = 0, parameter C_AXI_WUSER_WIDTH = 0, parameter C_AXI_BUSER_WIDTH = 0, parameter C_AXI_RUSER_WIDTH = 0, // AXI Streaming parameter C_HAS_AXIS_TDATA = 0, parameter C_HAS_AXIS_TID = 0, parameter C_HAS_AXIS_TDEST = 0, parameter C_HAS_AXIS_TUSER = 0, parameter C_HAS_AXIS_TREADY = 0, parameter C_HAS_AXIS_TLAST = 0, parameter C_HAS_AXIS_TSTRB = 0, parameter C_HAS_AXIS_TKEEP = 0, parameter C_AXIS_TDATA_WIDTH = 1, parameter C_AXIS_TID_WIDTH = 1, parameter C_AXIS_TDEST_WIDTH = 1, parameter C_AXIS_TUSER_WIDTH = 1, parameter C_AXIS_TSTRB_WIDTH = 1, parameter C_AXIS_TKEEP_WIDTH = 1, // AXI Channel Type // WACH --> Write Address Channel // WDCH --> Write Data Channel // WRCH --> Write Response Channel // RACH --> Read Address Channel // RDCH --> Read Data Channel // AXIS --> AXI Streaming parameter C_WACH_TYPE = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logic parameter C_WDCH_TYPE = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie parameter C_WRCH_TYPE = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie parameter C_RACH_TYPE = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie parameter C_RDCH_TYPE = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie parameter C_AXIS_TYPE = 0, // 0 = FIFO, 1 = Register Slice, 2 = Pass Through Logie // AXI Implementation Type // 1 = Common Clock Block RAM FIFO // 2 = Common Clock Distributed RAM FIFO // 11 = Independent Clock Block RAM FIFO // 12 = Independent Clock Distributed RAM FIFO parameter C_IMPLEMENTATION_TYPE_WACH = 0, parameter C_IMPLEMENTATION_TYPE_WDCH = 0, parameter C_IMPLEMENTATION_TYPE_WRCH = 0, parameter C_IMPLEMENTATION_TYPE_RACH = 0, parameter C_IMPLEMENTATION_TYPE_RDCH = 0, parameter C_IMPLEMENTATION_TYPE_AXIS = 0, // AXI FIFO Type // 0 = Data FIFO // 1 = Packet FIFO // 2 = Low Latency Sync FIFO // 3 = Low Latency Async FIFO parameter C_APPLICATION_TYPE_WACH = 0, parameter C_APPLICATION_TYPE_WDCH = 0, parameter C_APPLICATION_TYPE_WRCH = 0, parameter C_APPLICATION_TYPE_RACH = 0, parameter C_APPLICATION_TYPE_RDCH = 0, parameter C_APPLICATION_TYPE_AXIS = 0, // AXI Built-in FIFO Primitive Type // 512x36, 1kx18, 2kx9, 4kx4, etc parameter C_PRIM_FIFO_TYPE_WACH = "512x36", parameter C_PRIM_FIFO_TYPE_WDCH = "512x36", parameter C_PRIM_FIFO_TYPE_WRCH = "512x36", parameter C_PRIM_FIFO_TYPE_RACH = "512x36", parameter C_PRIM_FIFO_TYPE_RDCH = "512x36", parameter C_PRIM_FIFO_TYPE_AXIS = "512x36", // Enable ECC // 0 = ECC disabled // 1 = ECC enabled parameter C_USE_ECC_WACH = 0, parameter C_USE_ECC_WDCH = 0, parameter C_USE_ECC_WRCH = 0, parameter C_USE_ECC_RACH = 0, parameter C_USE_ECC_RDCH = 0, parameter C_USE_ECC_AXIS = 0, // ECC Error Injection Type // 0 = No Error Injection // 1 = Single Bit Error Injection // 2 = Double Bit Error Injection // 3 = Single Bit and Double Bit Error Injection parameter C_ERROR_INJECTION_TYPE_WACH = 0, parameter C_ERROR_INJECTION_TYPE_WDCH = 0, parameter C_ERROR_INJECTION_TYPE_WRCH = 0, parameter C_ERROR_INJECTION_TYPE_RACH = 0, parameter C_ERROR_INJECTION_TYPE_RDCH = 0, parameter C_ERROR_INJECTION_TYPE_AXIS = 0, // Input Data Width // Accumulation of all AXI input signal's width parameter C_DIN_WIDTH_WACH = 1, parameter C_DIN_WIDTH_WDCH = 1, parameter C_DIN_WIDTH_WRCH = 1, parameter C_DIN_WIDTH_RACH = 1, parameter C_DIN_WIDTH_RDCH = 1, parameter C_DIN_WIDTH_AXIS = 1, parameter C_WR_DEPTH_WACH = 16, parameter C_WR_DEPTH_WDCH = 16, parameter C_WR_DEPTH_WRCH = 16, parameter C_WR_DEPTH_RACH = 16, parameter C_WR_DEPTH_RDCH = 16, parameter C_WR_DEPTH_AXIS = 16, parameter C_WR_PNTR_WIDTH_WACH = 4, parameter C_WR_PNTR_WIDTH_WDCH = 4, parameter C_WR_PNTR_WIDTH_WRCH = 4, parameter C_WR_PNTR_WIDTH_RACH = 4, parameter C_WR_PNTR_WIDTH_RDCH = 4, parameter C_WR_PNTR_WIDTH_AXIS = 4, parameter C_HAS_DATA_COUNTS_WACH = 0, parameter C_HAS_DATA_COUNTS_WDCH = 0, parameter C_HAS_DATA_COUNTS_WRCH = 0, parameter C_HAS_DATA_COUNTS_RACH = 0, parameter C_HAS_DATA_COUNTS_RDCH = 0, parameter C_HAS_DATA_COUNTS_AXIS = 0, parameter C_HAS_PROG_FLAGS_WACH = 0, parameter C_HAS_PROG_FLAGS_WDCH = 0, parameter C_HAS_PROG_FLAGS_WRCH = 0, parameter C_HAS_PROG_FLAGS_RACH = 0, parameter C_HAS_PROG_FLAGS_RDCH = 0, parameter C_HAS_PROG_FLAGS_AXIS = 0, parameter C_PROG_FULL_TYPE_WACH = 0, parameter C_PROG_FULL_TYPE_WDCH = 0, parameter C_PROG_FULL_TYPE_WRCH = 0, parameter C_PROG_FULL_TYPE_RACH = 0, parameter C_PROG_FULL_TYPE_RDCH = 0, parameter C_PROG_FULL_TYPE_AXIS = 0, parameter C_PROG_FULL_THRESH_ASSERT_VAL_WACH = 0, parameter C_PROG_FULL_THRESH_ASSERT_VAL_WDCH = 0, parameter C_PROG_FULL_THRESH_ASSERT_VAL_WRCH = 0, parameter C_PROG_FULL_THRESH_ASSERT_VAL_RACH = 0, parameter C_PROG_FULL_THRESH_ASSERT_VAL_RDCH = 0, parameter C_PROG_FULL_THRESH_ASSERT_VAL_AXIS = 0, parameter C_PROG_EMPTY_TYPE_WACH = 0, parameter C_PROG_EMPTY_TYPE_WDCH = 0, parameter C_PROG_EMPTY_TYPE_WRCH = 0, parameter C_PROG_EMPTY_TYPE_RACH = 0, parameter C_PROG_EMPTY_TYPE_RDCH = 0, parameter C_PROG_EMPTY_TYPE_AXIS = 0, parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_WACH = 0, parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_WDCH = 0, parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_WRCH = 0, parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_RACH = 0, parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_RDCH = 0, parameter C_PROG_EMPTY_THRESH_ASSERT_VAL_AXIS = 0, parameter C_REG_SLICE_MODE_WACH = 0, parameter C_REG_SLICE_MODE_WDCH = 0, parameter C_REG_SLICE_MODE_WRCH = 0, parameter C_REG_SLICE_MODE_RACH = 0, parameter C_REG_SLICE_MODE_RDCH = 0, parameter C_REG_SLICE_MODE_AXIS = 0 ) ( //------------------------------------------------------------------------------ // Input and Output Declarations //------------------------------------------------------------------------------ // Conventional FIFO Interface Signals input backup, input backup_marker, input clk, input rst, input srst, input wr_clk, input wr_rst, input rd_clk, input rd_rst, input [C_DIN_WIDTH-1:0] din, input wr_en, input rd_en, // Optional inputs input [C_RD_PNTR_WIDTH-1:0] prog_empty_thresh, input [C_RD_PNTR_WIDTH-1:0] prog_empty_thresh_assert, input [C_RD_PNTR_WIDTH-1:0] prog_empty_thresh_negate, input [C_WR_PNTR_WIDTH-1:0] prog_full_thresh, input [C_WR_PNTR_WIDTH-1:0] prog_full_thresh_assert, input [C_WR_PNTR_WIDTH-1:0] prog_full_thresh_negate, input int_clk, input injectdbiterr, input injectsbiterr, input sleep, output [C_DOUT_WIDTH-1:0] dout, output full, output almost_full, output wr_ack, output overflow, output empty, output almost_empty, output valid, output underflow, output [C_DATA_COUNT_WIDTH-1:0] data_count, output [C_RD_DATA_COUNT_WIDTH-1:0] rd_data_count, output [C_WR_DATA_COUNT_WIDTH-1:0] wr_data_count, output prog_full, output prog_empty, output sbiterr, output dbiterr, output wr_rst_busy, output rd_rst_busy, // AXI Global Signal input m_aclk, input s_aclk, input s_aresetn, input s_aclk_en, input m_aclk_en, // AXI Full/Lite Slave Write Channel (write side) input [C_AXI_ID_WIDTH-1:0] s_axi_awid, input [C_AXI_ADDR_WIDTH-1:0] s_axi_awaddr, input [C_AXI_LEN_WIDTH-1:0] s_axi_awlen, input [3-1:0] s_axi_awsize, input [2-1:0] s_axi_awburst, input [C_AXI_LOCK_WIDTH-1:0] s_axi_awlock, input [4-1:0] s_axi_awcache, input [3-1:0] s_axi_awprot, input [4-1:0] s_axi_awqos, input [4-1:0] s_axi_awregion, input [C_AXI_AWUSER_WIDTH-1:0] s_axi_awuser, input s_axi_awvalid, output s_axi_awready, input [C_AXI_ID_WIDTH-1:0] s_axi_wid, input [C_AXI_DATA_WIDTH-1:0] s_axi_wdata, input [C_AXI_DATA_WIDTH/8-1:0] s_axi_wstrb, input s_axi_wlast, input [C_AXI_WUSER_WIDTH-1:0] s_axi_wuser, input s_axi_wvalid, output s_axi_wready, output [C_AXI_ID_WIDTH-1:0] s_axi_bid, output [2-1:0] s_axi_bresp, output [C_AXI_BUSER_WIDTH-1:0] s_axi_buser, output s_axi_bvalid, input s_axi_bready, // AXI Full/Lite Master Write Channel (read side) output [C_AXI_ID_WIDTH-1:0] m_axi_awid, output [C_AXI_ADDR_WIDTH-1:0] m_axi_awaddr, output [C_AXI_LEN_WIDTH-1:0] m_axi_awlen, output [3-1:0] m_axi_awsize, output [2-1:0] m_axi_awburst, output [C_AXI_LOCK_WIDTH-1:0] m_axi_awlock, output [4-1:0] m_axi_awcache, output [3-1:0] m_axi_awprot, output [4-1:0] m_axi_awqos, output [4-1:0] m_axi_awregion, output [C_AXI_AWUSER_WIDTH-1:0] m_axi_awuser, output m_axi_awvalid, input m_axi_awready, output [C_AXI_ID_WIDTH-1:0] m_axi_wid, output [C_AXI_DATA_WIDTH-1:0] m_axi_wdata, output [C_AXI_DATA_WIDTH/8-1:0] m_axi_wstrb, output m_axi_wlast, output [C_AXI_WUSER_WIDTH-1:0] m_axi_wuser, output m_axi_wvalid, input m_axi_wready, input [C_AXI_ID_WIDTH-1:0] m_axi_bid, input [2-1:0] m_axi_bresp, input [C_AXI_BUSER_WIDTH-1:0] m_axi_buser, input m_axi_bvalid, output m_axi_bready, // AXI Full/Lite Slave Read Channel (write side) input [C_AXI_ID_WIDTH-1:0] s_axi_arid, input [C_AXI_ADDR_WIDTH-1:0] s_axi_araddr, input [C_AXI_LEN_WIDTH-1:0] s_axi_arlen, input [3-1:0] s_axi_arsize, input [2-1:0] s_axi_arburst, input [C_AXI_LOCK_WIDTH-1:0] s_axi_arlock, input [4-1:0] s_axi_arcache, input [3-1:0] s_axi_arprot, input [4-1:0] s_axi_arqos, input [4-1:0] s_axi_arregion, input [C_AXI_ARUSER_WIDTH-1:0] s_axi_aruser, input s_axi_arvalid, output s_axi_arready, output [C_AXI_ID_WIDTH-1:0] s_axi_rid, output [C_AXI_DATA_WIDTH-1:0] s_axi_rdata, output [2-1:0] s_axi_rresp, output s_axi_rlast, output [C_AXI_RUSER_WIDTH-1:0] s_axi_ruser, output s_axi_rvalid, input s_axi_rready, // AXI Full/Lite Master Read Channel (read side) output [C_AXI_ID_WIDTH-1:0] m_axi_arid, output [C_AXI_ADDR_WIDTH-1:0] m_axi_araddr, output [C_AXI_LEN_WIDTH-1:0] m_axi_arlen, output [3-1:0] m_axi_arsize, output [2-1:0] m_axi_arburst, output [C_AXI_LOCK_WIDTH-1:0] m_axi_arlock, output [4-1:0] m_axi_arcache, output [3-1:0] m_axi_arprot, output [4-1:0] m_axi_arqos, output [4-1:0] m_axi_arregion, output [C_AXI_ARUSER_WIDTH-1:0] m_axi_aruser, output m_axi_arvalid, input m_axi_arready, input [C_AXI_ID_WIDTH-1:0] m_axi_rid, input [C_AXI_DATA_WIDTH-1:0] m_axi_rdata, input [2-1:0] m_axi_rresp, input m_axi_rlast, input [C_AXI_RUSER_WIDTH-1:0] m_axi_ruser, input m_axi_rvalid, output m_axi_rready, // AXI Streaming Slave Signals (Write side) input s_axis_tvalid, output s_axis_tready, input [C_AXIS_TDATA_WIDTH-1:0] s_axis_tdata, input [C_AXIS_TSTRB_WIDTH-1:0] s_axis_tstrb, input [C_AXIS_TKEEP_WIDTH-1:0] s_axis_tkeep, input s_axis_tlast, input [C_AXIS_TID_WIDTH-1:0] s_axis_tid, input [C_AXIS_TDEST_WIDTH-1:0] s_axis_tdest, input [C_AXIS_TUSER_WIDTH-1:0] s_axis_tuser, // AXI Streaming Master Signals (Read side) output m_axis_tvalid, input m_axis_tready, output [C_AXIS_TDATA_WIDTH-1:0] m_axis_tdata, output [C_AXIS_TSTRB_WIDTH-1:0] m_axis_tstrb, output [C_AXIS_TKEEP_WIDTH-1:0] m_axis_tkeep, output m_axis_tlast, output [C_AXIS_TID_WIDTH-1:0] m_axis_tid, output [C_AXIS_TDEST_WIDTH-1:0] m_axis_tdest, output [C_AXIS_TUSER_WIDTH-1:0] m_axis_tuser, // AXI Full/Lite Write Address Channel signals input axi_aw_injectsbiterr, input axi_aw_injectdbiterr, input [C_WR_PNTR_WIDTH_WACH-1:0] axi_aw_prog_full_thresh, input [C_WR_PNTR_WIDTH_WACH-1:0] axi_aw_prog_empty_thresh, output [C_WR_PNTR_WIDTH_WACH:0] axi_aw_data_count, output [C_WR_PNTR_WIDTH_WACH:0] axi_aw_wr_data_count, output [C_WR_PNTR_WIDTH_WACH:0] axi_aw_rd_data_count, output axi_aw_sbiterr, output axi_aw_dbiterr, output axi_aw_overflow, output axi_aw_underflow, output axi_aw_prog_full, output axi_aw_prog_empty, // AXI Full/Lite Write Data Channel signals input axi_w_injectsbiterr, input axi_w_injectdbiterr, input [C_WR_PNTR_WIDTH_WDCH-1:0] axi_w_prog_full_thresh, input [C_WR_PNTR_WIDTH_WDCH-1:0] axi_w_prog_empty_thresh, output [C_WR_PNTR_WIDTH_WDCH:0] axi_w_data_count, output [C_WR_PNTR_WIDTH_WDCH:0] axi_w_wr_data_count, output [C_WR_PNTR_WIDTH_WDCH:0] axi_w_rd_data_count, output axi_w_sbiterr, output axi_w_dbiterr, output axi_w_overflow, output axi_w_underflow, output axi_w_prog_full, output axi_w_prog_empty, // AXI Full/Lite Write Response Channel signals input axi_b_injectsbiterr, input axi_b_injectdbiterr, input [C_WR_PNTR_WIDTH_WRCH-1:0] axi_b_prog_full_thresh, input [C_WR_PNTR_WIDTH_WRCH-1:0] axi_b_prog_empty_thresh, output [C_WR_PNTR_WIDTH_WRCH:0] axi_b_data_count, output [C_WR_PNTR_WIDTH_WRCH:0] axi_b_wr_data_count, output [C_WR_PNTR_WIDTH_WRCH:0] axi_b_rd_data_count, output axi_b_sbiterr, output axi_b_dbiterr, output axi_b_overflow, output axi_b_underflow, output axi_b_prog_full, output axi_b_prog_empty, // AXI Full/Lite Read Address Channel signals input axi_ar_injectsbiterr, input axi_ar_injectdbiterr, input [C_WR_PNTR_WIDTH_RACH-1:0] axi_ar_prog_full_thresh, input [C_WR_PNTR_WIDTH_RACH-1:0] axi_ar_prog_empty_thresh, output [C_WR_PNTR_WIDTH_RACH:0] axi_ar_data_count, output [C_WR_PNTR_WIDTH_RACH:0] axi_ar_wr_data_count, output [C_WR_PNTR_WIDTH_RACH:0] axi_ar_rd_data_count, output axi_ar_sbiterr, output axi_ar_dbiterr, output axi_ar_overflow, output axi_ar_underflow, output axi_ar_prog_full, output axi_ar_prog_empty, // AXI Full/Lite Read Data Channel Signals input axi_r_injectsbiterr, input axi_r_injectdbiterr, input [C_WR_PNTR_WIDTH_RDCH-1:0] axi_r_prog_full_thresh, input [C_WR_PNTR_WIDTH_RDCH-1:0] axi_r_prog_empty_thresh, output [C_WR_PNTR_WIDTH_RDCH:0] axi_r_data_count, output [C_WR_PNTR_WIDTH_RDCH:0] axi_r_wr_data_count, output [C_WR_PNTR_WIDTH_RDCH:0] axi_r_rd_data_count, output axi_r_sbiterr, output axi_r_dbiterr, output axi_r_overflow, output axi_r_underflow, output axi_r_prog_full, output axi_r_prog_empty, // AXI Streaming FIFO Related Signals input axis_injectsbiterr, input axis_injectdbiterr, input [C_WR_PNTR_WIDTH_AXIS-1:0] axis_prog_full_thresh, input [C_WR_PNTR_WIDTH_AXIS-1:0] axis_prog_empty_thresh, output [C_WR_PNTR_WIDTH_AXIS:0] axis_data_count, output [C_WR_PNTR_WIDTH_AXIS:0] axis_wr_data_count, output [C_WR_PNTR_WIDTH_AXIS:0] axis_rd_data_count, output axis_sbiterr, output axis_dbiterr, output axis_overflow, output axis_underflow, output axis_prog_full, output axis_prog_empty ); wire BACKUP; wire BACKUP_MARKER; wire CLK; wire RST; wire SRST; wire WR_CLK; wire WR_RST; wire RD_CLK; wire RD_RST; wire [C_DIN_WIDTH-1:0] DIN; wire WR_EN; wire RD_EN; wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH; wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT; wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE; wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH; wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT; wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE; wire INT_CLK; wire INJECTDBITERR; wire INJECTSBITERR; wire SLEEP; wire [C_DOUT_WIDTH-1:0] DOUT; wire FULL; wire ALMOST_FULL; wire WR_ACK; wire OVERFLOW; wire EMPTY; wire ALMOST_EMPTY; wire VALID; wire UNDERFLOW; wire [C_DATA_COUNT_WIDTH-1:0] DATA_COUNT; wire [C_RD_DATA_COUNT_WIDTH-1:0] RD_DATA_COUNT; wire [C_WR_DATA_COUNT_WIDTH-1:0] WR_DATA_COUNT; wire PROG_FULL; wire PROG_EMPTY; wire SBITERR; wire DBITERR; wire WR_RST_BUSY; wire RD_RST_BUSY; wire M_ACLK; wire S_ACLK; wire S_ARESETN; wire S_ACLK_EN; wire M_ACLK_EN; wire [C_AXI_ID_WIDTH-1:0] S_AXI_AWID; wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR; wire [C_AXI_LEN_WIDTH-1:0] S_AXI_AWLEN; wire [3-1:0] S_AXI_AWSIZE; wire [2-1:0] S_AXI_AWBURST; wire [C_AXI_LOCK_WIDTH-1:0] S_AXI_AWLOCK; wire [4-1:0] S_AXI_AWCACHE; wire [3-1:0] S_AXI_AWPROT; wire [4-1:0] S_AXI_AWQOS; wire [4-1:0] S_AXI_AWREGION; wire [C_AXI_AWUSER_WIDTH-1:0] S_AXI_AWUSER; wire S_AXI_AWVALID; wire S_AXI_AWREADY; wire [C_AXI_ID_WIDTH-1:0] S_AXI_WID; wire [C_AXI_DATA_WIDTH-1:0] S_AXI_WDATA; wire [C_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB; wire S_AXI_WLAST; wire [C_AXI_WUSER_WIDTH-1:0] S_AXI_WUSER; wire S_AXI_WVALID; wire S_AXI_WREADY; wire [C_AXI_ID_WIDTH-1:0] S_AXI_BID; wire [2-1:0] S_AXI_BRESP; wire [C_AXI_BUSER_WIDTH-1:0] S_AXI_BUSER; wire S_AXI_BVALID; wire S_AXI_BREADY; wire [C_AXI_ID_WIDTH-1:0] M_AXI_AWID; wire [C_AXI_ADDR_WIDTH-1:0] M_AXI_AWADDR; wire [C_AXI_LEN_WIDTH-1:0] M_AXI_AWLEN; wire [3-1:0] M_AXI_AWSIZE; wire [2-1:0] M_AXI_AWBURST; wire [C_AXI_LOCK_WIDTH-1:0] M_AXI_AWLOCK; wire [4-1:0] M_AXI_AWCACHE; wire [3-1:0] M_AXI_AWPROT; wire [4-1:0] M_AXI_AWQOS; wire [4-1:0] M_AXI_AWREGION; wire [C_AXI_AWUSER_WIDTH-1:0] M_AXI_AWUSER; wire M_AXI_AWVALID; wire M_AXI_AWREADY; wire [C_AXI_ID_WIDTH-1:0] M_AXI_WID; wire [C_AXI_DATA_WIDTH-1:0] M_AXI_WDATA; wire [C_AXI_DATA_WIDTH/8-1:0] M_AXI_WSTRB; wire M_AXI_WLAST; wire [C_AXI_WUSER_WIDTH-1:0] M_AXI_WUSER; wire M_AXI_WVALID; wire M_AXI_WREADY; wire [C_AXI_ID_WIDTH-1:0] M_AXI_BID; wire [2-1:0] M_AXI_BRESP; wire [C_AXI_BUSER_WIDTH-1:0] M_AXI_BUSER; wire M_AXI_BVALID; wire M_AXI_BREADY; wire [C_AXI_ID_WIDTH-1:0] S_AXI_ARID; wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_ARADDR; wire [C_AXI_LEN_WIDTH-1:0] S_AXI_ARLEN; wire [3-1:0] S_AXI_ARSIZE; wire [2-1:0] S_AXI_ARBURST; wire [C_AXI_LOCK_WIDTH-1:0] S_AXI_ARLOCK; wire [4-1:0] S_AXI_ARCACHE; wire [3-1:0] S_AXI_ARPROT; wire [4-1:0] S_AXI_ARQOS; wire [4-1:0] S_AXI_ARREGION; wire [C_AXI_ARUSER_WIDTH-1:0] S_AXI_ARUSER; wire S_AXI_ARVALID; wire S_AXI_ARREADY; wire [C_AXI_ID_WIDTH-1:0] S_AXI_RID; wire [C_AXI_DATA_WIDTH-1:0] S_AXI_RDATA; wire [2-1:0] S_AXI_RRESP; wire S_AXI_RLAST; wire [C_AXI_RUSER_WIDTH-1:0] S_AXI_RUSER; wire S_AXI_RVALID; wire S_AXI_RREADY; wire [C_AXI_ID_WIDTH-1:0] M_AXI_ARID; wire [C_AXI_ADDR_WIDTH-1:0] M_AXI_ARADDR; wire [C_AXI_LEN_WIDTH-1:0] M_AXI_ARLEN; wire [3-1:0] M_AXI_ARSIZE; wire [2-1:0] M_AXI_ARBURST; wire [C_AXI_LOCK_WIDTH-1:0] M_AXI_ARLOCK; wire [4-1:0] M_AXI_ARCACHE; wire [3-1:0] M_AXI_ARPROT; wire [4-1:0] M_AXI_ARQOS; wire [4-1:0] M_AXI_ARREGION; wire [C_AXI_ARUSER_WIDTH-1:0] M_AXI_ARUSER; wire M_AXI_ARVALID; wire M_AXI_ARREADY; wire [C_AXI_ID_WIDTH-1:0] M_AXI_RID; wire [C_AXI_DATA_WIDTH-1:0] M_AXI_RDATA; wire [2-1:0] M_AXI_RRESP; wire M_AXI_RLAST; wire [C_AXI_RUSER_WIDTH-1:0] M_AXI_RUSER; wire M_AXI_RVALID; wire M_AXI_RREADY; wire S_AXIS_TVALID; wire S_AXIS_TREADY; wire [C_AXIS_TDATA_WIDTH-1:0] S_AXIS_TDATA; wire [C_AXIS_TSTRB_WIDTH-1:0] S_AXIS_TSTRB; wire [C_AXIS_TKEEP_WIDTH-1:0] S_AXIS_TKEEP; wire S_AXIS_TLAST; wire [C_AXIS_TID_WIDTH-1:0] S_AXIS_TID; wire [C_AXIS_TDEST_WIDTH-1:0] S_AXIS_TDEST; wire [C_AXIS_TUSER_WIDTH-1:0] S_AXIS_TUSER; wire M_AXIS_TVALID; wire M_AXIS_TREADY; wire [C_AXIS_TDATA_WIDTH-1:0] M_AXIS_TDATA; wire [C_AXIS_TSTRB_WIDTH-1:0] M_AXIS_TSTRB; wire [C_AXIS_TKEEP_WIDTH-1:0] M_AXIS_TKEEP; wire M_AXIS_TLAST; wire [C_AXIS_TID_WIDTH-1:0] M_AXIS_TID; wire [C_AXIS_TDEST_WIDTH-1:0] M_AXIS_TDEST; wire [C_AXIS_TUSER_WIDTH-1:0] M_AXIS_TUSER; wire AXI_AW_INJECTSBITERR; wire AXI_AW_INJECTDBITERR; wire [C_WR_PNTR_WIDTH_WACH-1:0] AXI_AW_PROG_FULL_THRESH; wire [C_WR_PNTR_WIDTH_WACH-1:0] AXI_AW_PROG_EMPTY_THRESH; wire [C_WR_PNTR_WIDTH_WACH:0] AXI_AW_DATA_COUNT; wire [C_WR_PNTR_WIDTH_WACH:0] AXI_AW_WR_DATA_COUNT; wire [C_WR_PNTR_WIDTH_WACH:0] AXI_AW_RD_DATA_COUNT; wire AXI_AW_SBITERR; wire AXI_AW_DBITERR; wire AXI_AW_OVERFLOW; wire AXI_AW_UNDERFLOW; wire AXI_AW_PROG_FULL; wire AXI_AW_PROG_EMPTY; wire AXI_W_INJECTSBITERR; wire AXI_W_INJECTDBITERR; wire [C_WR_PNTR_WIDTH_WDCH-1:0] AXI_W_PROG_FULL_THRESH; wire [C_WR_PNTR_WIDTH_WDCH-1:0] AXI_W_PROG_EMPTY_THRESH; wire [C_WR_PNTR_WIDTH_WDCH:0] AXI_W_DATA_COUNT; wire [C_WR_PNTR_WIDTH_WDCH:0] AXI_W_WR_DATA_COUNT; wire [C_WR_PNTR_WIDTH_WDCH:0] AXI_W_RD_DATA_COUNT; wire AXI_W_SBITERR; wire AXI_W_DBITERR; wire AXI_W_OVERFLOW; wire AXI_W_UNDERFLOW; wire AXI_W_PROG_FULL; wire AXI_W_PROG_EMPTY; wire AXI_B_INJECTSBITERR; wire AXI_B_INJECTDBITERR; wire [C_WR_PNTR_WIDTH_WRCH-1:0] AXI_B_PROG_FULL_THRESH; wire [C_WR_PNTR_WIDTH_WRCH-1:0] AXI_B_PROG_EMPTY_THRESH; wire [C_WR_PNTR_WIDTH_WRCH:0] AXI_B_DATA_COUNT; wire [C_WR_PNTR_WIDTH_WRCH:0] AXI_B_WR_DATA_COUNT; wire [C_WR_PNTR_WIDTH_WRCH:0] AXI_B_RD_DATA_COUNT; wire AXI_B_SBITERR; wire AXI_B_DBITERR; wire AXI_B_OVERFLOW; wire AXI_B_UNDERFLOW; wire AXI_B_PROG_FULL; wire AXI_B_PROG_EMPTY; wire AXI_AR_INJECTSBITERR; wire AXI_AR_INJECTDBITERR; wire [C_WR_PNTR_WIDTH_RACH-1:0] AXI_AR_PROG_FULL_THRESH; wire [C_WR_PNTR_WIDTH_RACH-1:0] AXI_AR_PROG_EMPTY_THRESH; wire [C_WR_PNTR_WIDTH_RACH:0] AXI_AR_DATA_COUNT; wire [C_WR_PNTR_WIDTH_RACH:0] AXI_AR_WR_DATA_COUNT; wire [C_WR_PNTR_WIDTH_RACH:0] AXI_AR_RD_DATA_COUNT; wire AXI_AR_SBITERR; wire AXI_AR_DBITERR; wire AXI_AR_OVERFLOW; wire AXI_AR_UNDERFLOW; wire AXI_AR_PROG_FULL; wire AXI_AR_PROG_EMPTY; wire AXI_R_INJECTSBITERR; wire AXI_R_INJECTDBITERR; wire [C_WR_PNTR_WIDTH_RDCH-1:0] AXI_R_PROG_FULL_THRESH; wire [C_WR_PNTR_WIDTH_RDCH-1:0] AXI_R_PROG_EMPTY_THRESH; wire [C_WR_PNTR_WIDTH_RDCH:0] AXI_R_DATA_COUNT; wire [C_WR_PNTR_WIDTH_RDCH:0] AXI_R_WR_DATA_COUNT; wire [C_WR_PNTR_WIDTH_RDCH:0] AXI_R_RD_DATA_COUNT; wire AXI_R_SBITERR; wire AXI_R_DBITERR; wire AXI_R_OVERFLOW; wire AXI_R_UNDERFLOW; wire AXI_R_PROG_FULL; wire AXI_R_PROG_EMPTY; wire AXIS_INJECTSBITERR; wire AXIS_INJECTDBITERR; wire [C_WR_PNTR_WIDTH_AXIS-1:0] AXIS_PROG_FULL_THRESH; wire [C_WR_PNTR_WIDTH_AXIS-1:0] AXIS_PROG_EMPTY_THRESH; wire [C_WR_PNTR_WIDTH_AXIS:0] AXIS_DATA_COUNT; wire [C_WR_PNTR_WIDTH_AXIS:0] AXIS_WR_DATA_COUNT; wire [C_WR_PNTR_WIDTH_AXIS:0] AXIS_RD_DATA_COUNT; wire AXIS_SBITERR; wire AXIS_DBITERR; wire AXIS_OVERFLOW; wire AXIS_UNDERFLOW; wire AXIS_PROG_FULL; wire AXIS_PROG_EMPTY; wire [C_WR_DATA_COUNT_WIDTH-1:0] wr_data_count_in; wire wr_rst_int; wire rd_rst_int; function integer find_log2; input integer int_val; integer i,j; begin i = 1; j = 0; for (i = 1; i < int_val; i = i*2) begin j = j + 1; end find_log2 = j; end endfunction // Conventional FIFO Interface Signals assign BACKUP = backup; assign BACKUP_MARKER = backup_marker; assign CLK = clk; assign RST = rst; assign SRST = srst; assign WR_CLK = wr_clk; assign WR_RST = wr_rst; assign RD_CLK = rd_clk; assign RD_RST = rd_rst; assign WR_EN = wr_en; assign RD_EN = rd_en; assign INT_CLK = int_clk; assign INJECTDBITERR = injectdbiterr; assign INJECTSBITERR = injectsbiterr; assign SLEEP = sleep; assign full = FULL; assign almost_full = ALMOST_FULL; assign wr_ack = WR_ACK; assign overflow = OVERFLOW; assign empty = EMPTY; assign almost_empty = ALMOST_EMPTY; assign valid = VALID; assign underflow = UNDERFLOW; assign prog_full = PROG_FULL; assign prog_empty = PROG_EMPTY; assign sbiterr = SBITERR; assign dbiterr = DBITERR; assign wr_rst_busy = WR_RST_BUSY; assign rd_rst_busy = RD_RST_BUSY; assign M_ACLK = m_aclk; assign S_ACLK = s_aclk; assign S_ARESETN = s_aresetn; assign S_ACLK_EN = s_aclk_en; assign M_ACLK_EN = m_aclk_en; assign S_AXI_AWVALID = s_axi_awvalid; assign s_axi_awready = S_AXI_AWREADY; assign S_AXI_WLAST = s_axi_wlast; assign S_AXI_WVALID = s_axi_wvalid; assign s_axi_wready = S_AXI_WREADY; assign s_axi_bvalid = S_AXI_BVALID; assign S_AXI_BREADY = s_axi_bready; assign m_axi_awvalid = M_AXI_AWVALID; assign M_AXI_AWREADY = m_axi_awready; assign m_axi_wlast = M_AXI_WLAST; assign m_axi_wvalid = M_AXI_WVALID; assign M_AXI_WREADY = m_axi_wready; assign M_AXI_BVALID = m_axi_bvalid; assign m_axi_bready = M_AXI_BREADY; assign S_AXI_ARVALID = s_axi_arvalid; assign s_axi_arready = S_AXI_ARREADY; assign s_axi_rlast = S_AXI_RLAST; assign s_axi_rvalid = S_AXI_RVALID; assign S_AXI_RREADY = s_axi_rready; assign m_axi_arvalid = M_AXI_ARVALID; assign M_AXI_ARREADY = m_axi_arready; assign M_AXI_RLAST = m_axi_rlast; assign M_AXI_RVALID = m_axi_rvalid; assign m_axi_rready = M_AXI_RREADY; assign S_AXIS_TVALID = s_axis_tvalid; assign s_axis_tready = S_AXIS_TREADY; assign S_AXIS_TLAST = s_axis_tlast; assign m_axis_tvalid = M_AXIS_TVALID; assign M_AXIS_TREADY = m_axis_tready; assign m_axis_tlast = M_AXIS_TLAST; assign AXI_AW_INJECTSBITERR = axi_aw_injectsbiterr; assign AXI_AW_INJECTDBITERR = axi_aw_injectdbiterr; assign axi_aw_sbiterr = AXI_AW_SBITERR; assign axi_aw_dbiterr = AXI_AW_DBITERR; assign axi_aw_overflow = AXI_AW_OVERFLOW; assign axi_aw_underflow = AXI_AW_UNDERFLOW; assign axi_aw_prog_full = AXI_AW_PROG_FULL; assign axi_aw_prog_empty = AXI_AW_PROG_EMPTY; assign AXI_W_INJECTSBITERR = axi_w_injectsbiterr; assign AXI_W_INJECTDBITERR = axi_w_injectdbiterr; assign axi_w_sbiterr = AXI_W_SBITERR; assign axi_w_dbiterr = AXI_W_DBITERR; assign axi_w_overflow = AXI_W_OVERFLOW; assign axi_w_underflow = AXI_W_UNDERFLOW; assign axi_w_prog_full = AXI_W_PROG_FULL; assign axi_w_prog_empty = AXI_W_PROG_EMPTY; assign AXI_B_INJECTSBITERR = axi_b_injectsbiterr; assign AXI_B_INJECTDBITERR = axi_b_injectdbiterr; assign axi_b_sbiterr = AXI_B_SBITERR; assign axi_b_dbiterr = AXI_B_DBITERR; assign axi_b_overflow = AXI_B_OVERFLOW; assign axi_b_underflow = AXI_B_UNDERFLOW; assign axi_b_prog_full = AXI_B_PROG_FULL; assign axi_b_prog_empty = AXI_B_PROG_EMPTY; assign AXI_AR_INJECTSBITERR = axi_ar_injectsbiterr; assign AXI_AR_INJECTDBITERR = axi_ar_injectdbiterr; assign axi_ar_sbiterr = AXI_AR_SBITERR; assign axi_ar_dbiterr = AXI_AR_DBITERR; assign axi_ar_overflow = AXI_AR_OVERFLOW; assign axi_ar_underflow = AXI_AR_UNDERFLOW; assign axi_ar_prog_full = AXI_AR_PROG_FULL; assign axi_ar_prog_empty = AXI_AR_PROG_EMPTY; assign AXI_R_INJECTSBITERR = axi_r_injectsbiterr; assign AXI_R_INJECTDBITERR = axi_r_injectdbiterr; assign axi_r_sbiterr = AXI_R_SBITERR; assign axi_r_dbiterr = AXI_R_DBITERR; assign axi_r_overflow = AXI_R_OVERFLOW; assign axi_r_underflow = AXI_R_UNDERFLOW; assign axi_r_prog_full = AXI_R_PROG_FULL; assign axi_r_prog_empty = AXI_R_PROG_EMPTY; assign AXIS_INJECTSBITERR = axis_injectsbiterr; assign AXIS_INJECTDBITERR = axis_injectdbiterr; assign axis_sbiterr = AXIS_SBITERR; assign axis_dbiterr = AXIS_DBITERR; assign axis_overflow = AXIS_OVERFLOW; assign axis_underflow = AXIS_UNDERFLOW; assign axis_prog_full = AXIS_PROG_FULL; assign axis_prog_empty = AXIS_PROG_EMPTY; assign DIN = din; assign PROG_EMPTY_THRESH = prog_empty_thresh; assign PROG_EMPTY_THRESH_ASSERT = prog_empty_thresh_assert; assign PROG_EMPTY_THRESH_NEGATE = prog_empty_thresh_negate; assign PROG_FULL_THRESH = prog_full_thresh; assign PROG_FULL_THRESH_ASSERT = prog_full_thresh_assert; assign PROG_FULL_THRESH_NEGATE = prog_full_thresh_negate; assign dout = DOUT; assign data_count = DATA_COUNT; assign rd_data_count = RD_DATA_COUNT; assign wr_data_count = WR_DATA_COUNT; assign S_AXI_AWID = s_axi_awid; assign S_AXI_AWADDR = s_axi_awaddr; assign S_AXI_AWLEN = s_axi_awlen; assign S_AXI_AWSIZE = s_axi_awsize; assign S_AXI_AWBURST = s_axi_awburst; assign S_AXI_AWLOCK = s_axi_awlock; assign S_AXI_AWCACHE = s_axi_awcache; assign S_AXI_AWPROT = s_axi_awprot; assign S_AXI_AWQOS = s_axi_awqos; assign S_AXI_AWREGION = s_axi_awregion; assign S_AXI_AWUSER = s_axi_awuser; assign S_AXI_WID = s_axi_wid; assign S_AXI_WDATA = s_axi_wdata; assign S_AXI_WSTRB = s_axi_wstrb; assign S_AXI_WUSER = s_axi_wuser; assign s_axi_bid = S_AXI_BID; assign s_axi_bresp = S_AXI_BRESP; assign s_axi_buser = S_AXI_BUSER; assign m_axi_awid = M_AXI_AWID; assign m_axi_awaddr = M_AXI_AWADDR; assign m_axi_awlen = M_AXI_AWLEN; assign m_axi_awsize = M_AXI_AWSIZE; assign m_axi_awburst = M_AXI_AWBURST; assign m_axi_awlock = M_AXI_AWLOCK; assign m_axi_awcache = M_AXI_AWCACHE; assign m_axi_awprot = M_AXI_AWPROT; assign m_axi_awqos = M_AXI_AWQOS; assign m_axi_awregion = M_AXI_AWREGION; assign m_axi_awuser = M_AXI_AWUSER; assign m_axi_wid = M_AXI_WID; assign m_axi_wdata = M_AXI_WDATA; assign m_axi_wstrb = M_AXI_WSTRB; assign m_axi_wuser = M_AXI_WUSER; assign M_AXI_BID = m_axi_bid; assign M_AXI_BRESP = m_axi_bresp; assign M_AXI_BUSER = m_axi_buser; assign S_AXI_ARID = s_axi_arid; assign S_AXI_ARADDR = s_axi_araddr; assign S_AXI_ARLEN = s_axi_arlen; assign S_AXI_ARSIZE = s_axi_arsize; assign S_AXI_ARBURST = s_axi_arburst; assign S_AXI_ARLOCK = s_axi_arlock; assign S_AXI_ARCACHE = s_axi_arcache; assign S_AXI_ARPROT = s_axi_arprot; assign S_AXI_ARQOS = s_axi_arqos; assign S_AXI_ARREGION = s_axi_arregion; assign S_AXI_ARUSER = s_axi_aruser; assign s_axi_rid = S_AXI_RID; assign s_axi_rdata = S_AXI_RDATA; assign s_axi_rresp = S_AXI_RRESP; assign s_axi_ruser = S_AXI_RUSER; assign m_axi_arid = M_AXI_ARID; assign m_axi_araddr = M_AXI_ARADDR; assign m_axi_arlen = M_AXI_ARLEN; assign m_axi_arsize = M_AXI_ARSIZE; assign m_axi_arburst = M_AXI_ARBURST; assign m_axi_arlock = M_AXI_ARLOCK; assign m_axi_arcache = M_AXI_ARCACHE; assign m_axi_arprot = M_AXI_ARPROT; assign m_axi_arqos = M_AXI_ARQOS; assign m_axi_arregion = M_AXI_ARREGION; assign m_axi_aruser = M_AXI_ARUSER; assign M_AXI_RID = m_axi_rid; assign M_AXI_RDATA = m_axi_rdata; assign M_AXI_RRESP = m_axi_rresp; assign M_AXI_RUSER = m_axi_ruser; assign S_AXIS_TDATA = s_axis_tdata; assign S_AXIS_TSTRB = s_axis_tstrb; assign S_AXIS_TKEEP = s_axis_tkeep; assign S_AXIS_TID = s_axis_tid; assign S_AXIS_TDEST = s_axis_tdest; assign S_AXIS_TUSER = s_axis_tuser; assign m_axis_tdata = M_AXIS_TDATA; assign m_axis_tstrb = M_AXIS_TSTRB; assign m_axis_tkeep = M_AXIS_TKEEP; assign m_axis_tid = M_AXIS_TID; assign m_axis_tdest = M_AXIS_TDEST; assign m_axis_tuser = M_AXIS_TUSER; assign AXI_AW_PROG_FULL_THRESH = axi_aw_prog_full_thresh; assign AXI_AW_PROG_EMPTY_THRESH = axi_aw_prog_empty_thresh; assign axi_aw_data_count = AXI_AW_DATA_COUNT; assign axi_aw_wr_data_count = AXI_AW_WR_DATA_COUNT; assign axi_aw_rd_data_count = AXI_AW_RD_DATA_COUNT; assign AXI_W_PROG_FULL_THRESH = axi_w_prog_full_thresh; assign AXI_W_PROG_EMPTY_THRESH = axi_w_prog_empty_thresh; assign axi_w_data_count = AXI_W_DATA_COUNT; assign axi_w_wr_data_count = AXI_W_WR_DATA_COUNT; assign axi_w_rd_data_count = AXI_W_RD_DATA_COUNT; assign AXI_B_PROG_FULL_THRESH = axi_b_prog_full_thresh; assign AXI_B_PROG_EMPTY_THRESH = axi_b_prog_empty_thresh; assign axi_b_data_count = AXI_B_DATA_COUNT; assign axi_b_wr_data_count = AXI_B_WR_DATA_COUNT; assign axi_b_rd_data_count = AXI_B_RD_DATA_COUNT; assign AXI_AR_PROG_FULL_THRESH = axi_ar_prog_full_thresh; assign AXI_AR_PROG_EMPTY_THRESH = axi_ar_prog_empty_thresh; assign axi_ar_data_count = AXI_AR_DATA_COUNT; assign axi_ar_wr_data_count = AXI_AR_WR_DATA_COUNT; assign axi_ar_rd_data_count = AXI_AR_RD_DATA_COUNT; assign AXI_R_PROG_FULL_THRESH = axi_r_prog_full_thresh; assign AXI_R_PROG_EMPTY_THRESH = axi_r_prog_empty_thresh; assign axi_r_data_count = AXI_R_DATA_COUNT; assign axi_r_wr_data_count = AXI_R_WR_DATA_COUNT; assign axi_r_rd_data_count = AXI_R_RD_DATA_COUNT; assign AXIS_PROG_FULL_THRESH = axis_prog_full_thresh; assign AXIS_PROG_EMPTY_THRESH = axis_prog_empty_thresh; assign axis_data_count = AXIS_DATA_COUNT; assign axis_wr_data_count = AXIS_WR_DATA_COUNT; assign axis_rd_data_count = AXIS_RD_DATA_COUNT; generate if (C_INTERFACE_TYPE == 0) begin : conv_fifo FIFO_GENERATOR_v12_0_CONV_VER #( .C_COMMON_CLOCK (C_COMMON_CLOCK), .C_COUNT_TYPE (C_COUNT_TYPE), .C_DATA_COUNT_WIDTH (C_DATA_COUNT_WIDTH), .C_DEFAULT_VALUE (C_DEFAULT_VALUE), .C_DIN_WIDTH (C_DIN_WIDTH), .C_DOUT_RST_VAL (C_USE_DOUT_RST == 1 ? C_DOUT_RST_VAL : 0), .C_DOUT_WIDTH (C_DOUT_WIDTH), .C_ENABLE_RLOCS (C_ENABLE_RLOCS), .C_FAMILY (C_FAMILY), .C_FULL_FLAGS_RST_VAL (C_FULL_FLAGS_RST_VAL), .C_HAS_ALMOST_EMPTY (C_HAS_ALMOST_EMPTY), .C_HAS_ALMOST_FULL (C_HAS_ALMOST_FULL), .C_HAS_BACKUP (C_HAS_BACKUP), .C_HAS_DATA_COUNT (C_HAS_DATA_COUNT), .C_HAS_INT_CLK (C_HAS_INT_CLK), .C_HAS_MEMINIT_FILE (C_HAS_MEMINIT_FILE), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_HAS_RD_DATA_COUNT (C_HAS_RD_DATA_COUNT), .C_HAS_RD_RST (C_HAS_RD_RST), .C_HAS_RST (C_HAS_RST), .C_HAS_SRST (C_HAS_SRST), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_HAS_VALID (C_HAS_VALID), .C_HAS_WR_ACK (C_HAS_WR_ACK), .C_HAS_WR_DATA_COUNT (C_HAS_WR_DATA_COUNT), .C_HAS_WR_RST (C_HAS_WR_RST), .C_IMPLEMENTATION_TYPE (C_IMPLEMENTATION_TYPE), .C_INIT_WR_PNTR_VAL (C_INIT_WR_PNTR_VAL), .C_MEMORY_TYPE (C_MEMORY_TYPE), .C_MIF_FILE_NAME (C_MIF_FILE_NAME), .C_OPTIMIZATION_MODE (C_OPTIMIZATION_MODE), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_PRELOAD_LATENCY (C_PRELOAD_LATENCY), .C_PRELOAD_REGS (C_PRELOAD_REGS), .C_PRIM_FIFO_TYPE (C_PRIM_FIFO_TYPE), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL), .C_PROG_EMPTY_THRESH_NEGATE_VAL (C_PROG_EMPTY_THRESH_NEGATE_VAL), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL), .C_PROG_FULL_THRESH_NEGATE_VAL (C_PROG_FULL_THRESH_NEGATE_VAL), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE), .C_RD_DATA_COUNT_WIDTH (C_RD_DATA_COUNT_WIDTH), .C_RD_DEPTH (C_RD_DEPTH), .C_RD_FREQ (C_RD_FREQ), .C_RD_PNTR_WIDTH (C_RD_PNTR_WIDTH), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_USE_DOUT_RST (C_USE_DOUT_RST), .C_USE_ECC (C_USE_ECC), .C_USE_EMBEDDED_REG (C_USE_EMBEDDED_REG), .C_USE_FIFO16_FLAGS (C_USE_FIFO16_FLAGS), .C_USE_FWFT_DATA_COUNT (C_USE_FWFT_DATA_COUNT), .C_VALID_LOW (C_VALID_LOW), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_WR_DATA_COUNT_WIDTH (C_WR_DATA_COUNT_WIDTH), .C_WR_DEPTH (C_WR_DEPTH), .C_WR_FREQ (C_WR_FREQ), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH), .C_WR_RESPONSE_LATENCY (C_WR_RESPONSE_LATENCY), .C_MSGON_VAL (C_MSGON_VAL), .C_ENABLE_RST_SYNC (C_ENABLE_RST_SYNC), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE), .C_AXI_TYPE (C_AXI_TYPE), .C_SYNCHRONIZER_STAGE (C_SYNCHRONIZER_STAGE) ) fifo_generator_v12_0_conv_dut ( .BACKUP (BACKUP), .BACKUP_MARKER (BACKUP_MARKER), .CLK (CLK), .RST (RST), .SRST (SRST), .WR_CLK (WR_CLK), .WR_RST (WR_RST), .RD_CLK (RD_CLK), .RD_RST (RD_RST), .DIN (DIN), .WR_EN (WR_EN), .RD_EN (RD_EN), .PROG_EMPTY_THRESH (PROG_EMPTY_THRESH), .PROG_EMPTY_THRESH_ASSERT (PROG_EMPTY_THRESH_ASSERT), .PROG_EMPTY_THRESH_NEGATE (PROG_EMPTY_THRESH_NEGATE), .PROG_FULL_THRESH (PROG_FULL_THRESH), .PROG_FULL_THRESH_ASSERT (PROG_FULL_THRESH_ASSERT), .PROG_FULL_THRESH_NEGATE (PROG_FULL_THRESH_NEGATE), .INT_CLK (INT_CLK), .INJECTDBITERR (INJECTDBITERR), .INJECTSBITERR (INJECTSBITERR), .DOUT (DOUT), .FULL (FULL), .ALMOST_FULL (ALMOST_FULL), .WR_ACK (WR_ACK), .OVERFLOW (OVERFLOW), .EMPTY (EMPTY), .ALMOST_EMPTY (ALMOST_EMPTY), .VALID (VALID), .UNDERFLOW (UNDERFLOW), .DATA_COUNT (DATA_COUNT), .RD_DATA_COUNT (RD_DATA_COUNT), .WR_DATA_COUNT (wr_data_count_in), .PROG_FULL (PROG_FULL), .PROG_EMPTY (PROG_EMPTY), .SBITERR (SBITERR), .DBITERR (DBITERR), .wr_rst_busy (wr_rst_busy), .rd_rst_busy (rd_rst_busy), .wr_rst_i_out (wr_rst_int), .rd_rst_i_out (rd_rst_int) ); end endgenerate localparam IS_8SERIES = (C_FAMILY == "virtexu" || C_FAMILY == "kintexu" || C_FAMILY == "artixu" || C_FAMILY == "virtexum" || C_FAMILY == "zynque") ? 1 : 0; localparam C_AXI_SIZE_WIDTH = 3; localparam C_AXI_BURST_WIDTH = 2; localparam C_AXI_CACHE_WIDTH = 4; localparam C_AXI_PROT_WIDTH = 3; localparam C_AXI_QOS_WIDTH = 4; localparam C_AXI_REGION_WIDTH = 4; localparam C_AXI_BRESP_WIDTH = 2; localparam C_AXI_RRESP_WIDTH = 2; localparam IS_AXI_STREAMING = C_INTERFACE_TYPE == 1 ? 1 : 0; localparam TDATA_OFFSET = C_HAS_AXIS_TDATA == 1 ? C_DIN_WIDTH_AXIS-C_AXIS_TDATA_WIDTH : C_DIN_WIDTH_AXIS; localparam TSTRB_OFFSET = C_HAS_AXIS_TSTRB == 1 ? TDATA_OFFSET-C_AXIS_TSTRB_WIDTH : TDATA_OFFSET; localparam TKEEP_OFFSET = C_HAS_AXIS_TKEEP == 1 ? TSTRB_OFFSET-C_AXIS_TKEEP_WIDTH : TSTRB_OFFSET; localparam TID_OFFSET = C_HAS_AXIS_TID == 1 ? TKEEP_OFFSET-C_AXIS_TID_WIDTH : TKEEP_OFFSET; localparam TDEST_OFFSET = C_HAS_AXIS_TDEST == 1 ? TID_OFFSET-C_AXIS_TDEST_WIDTH : TID_OFFSET; localparam TUSER_OFFSET = C_HAS_AXIS_TUSER == 1 ? TDEST_OFFSET-C_AXIS_TUSER_WIDTH : TDEST_OFFSET; localparam LOG_DEPTH_AXIS = find_log2(C_WR_DEPTH_AXIS); localparam LOG_WR_DEPTH = find_log2(C_WR_DEPTH); function [LOG_DEPTH_AXIS-1:0] bin2gray; input [LOG_DEPTH_AXIS-1:0] x; begin bin2gray = x ^ (x>>1); end endfunction function [LOG_DEPTH_AXIS-1:0] gray2bin; input [LOG_DEPTH_AXIS-1:0] x; integer i; begin gray2bin[LOG_DEPTH_AXIS-1] = x[LOG_DEPTH_AXIS-1]; for(i=LOG_DEPTH_AXIS-2; i>=0; i=i-1) begin gray2bin[i] = gray2bin[i+1] ^ x[i]; end end endfunction wire [(LOG_WR_DEPTH)-1 : 0] w_cnt_gc_asreg_last; wire [LOG_WR_DEPTH-1 : 0] w_q [0:C_SYNCHRONIZER_STAGE] ; wire [LOG_WR_DEPTH-1 : 0] w_q_temp [1:C_SYNCHRONIZER_STAGE] ; reg [LOG_WR_DEPTH-1 : 0] w_cnt_rd = 0; reg [LOG_WR_DEPTH-1 : 0] w_cnt = 0; reg [LOG_WR_DEPTH-1 : 0] w_cnt_gc = 0; reg [LOG_WR_DEPTH-1 : 0] r_cnt = 0; wire [LOG_WR_DEPTH : 0] adj_w_cnt_rd_pad; wire [LOG_WR_DEPTH : 0] r_inv_pad; wire [LOG_WR_DEPTH-1 : 0] d_cnt; reg [LOG_WR_DEPTH : 0] d_cnt_pad = 0; reg adj_w_cnt_rd_pad_0 = 0; reg r_inv_pad_0 = 0; genvar l; generate for (l = 1; ((l <= C_SYNCHRONIZER_STAGE) && (C_HAS_DATA_COUNTS_AXIS == 3 && C_INTERFACE_TYPE == 0) ); l = l + 1) begin : g_cnt_sync_stage fifo_generator_v12_0_sync_stage #( .C_WIDTH (LOG_WR_DEPTH) ) rd_stg_inst ( .RST (rd_rst_int), .CLK (RD_CLK), .DIN (w_q[l-1]), .DOUT (w_q[l]) ); end endgenerate // gpkt_cnt_sync_stage generate if (C_INTERFACE_TYPE == 0 && C_HAS_DATA_COUNTS_AXIS == 3) begin : fifo_ic_adapter assign wr_eop_ad = WR_EN & !(FULL); assign rd_eop_ad = RD_EN & !(EMPTY); always @ (posedge wr_rst_int or posedge WR_CLK) begin if (wr_rst_int) w_cnt <= 1'b0; else if (wr_eop_ad) w_cnt <= w_cnt + 1; end always @ (posedge wr_rst_int or posedge WR_CLK) begin if (wr_rst_int) w_cnt_gc <= 1'b0; else w_cnt_gc <= bin2gray(w_cnt); end assign w_q[0] = w_cnt_gc; assign w_cnt_gc_asreg_last = w_q[C_SYNCHRONIZER_STAGE]; always @ (posedge rd_rst_int or posedge RD_CLK) begin if (rd_rst_int) w_cnt_rd <= 1'b0; else w_cnt_rd <= gray2bin(w_cnt_gc_asreg_last); end always @ (posedge rd_rst_int or posedge RD_CLK) begin if (rd_rst_int) r_cnt <= 1'b0; else if (rd_eop_ad) r_cnt <= r_cnt + 1; end // Take the difference of write and read packet count // Logic is similar to rd_pe_as assign adj_w_cnt_rd_pad[LOG_WR_DEPTH : 1] = w_cnt_rd; assign r_inv_pad[LOG_WR_DEPTH : 1] = ~r_cnt; assign adj_w_cnt_rd_pad[0] = adj_w_cnt_rd_pad_0; assign r_inv_pad[0] = r_inv_pad_0; always @ ( rd_eop_ad ) begin if (!rd_eop_ad) begin adj_w_cnt_rd_pad_0 <= 1'b1; r_inv_pad_0 <= 1'b1; end else begin adj_w_cnt_rd_pad_0 <= 1'b0; r_inv_pad_0 <= 1'b0; end end always @ (posedge rd_rst_int or posedge RD_CLK) begin if (rd_rst_int) d_cnt_pad <= 1'b0; else d_cnt_pad <= adj_w_cnt_rd_pad + r_inv_pad ; end assign d_cnt = d_cnt_pad [LOG_WR_DEPTH : 1] ; assign WR_DATA_COUNT = d_cnt; end endgenerate // fifo_ic_adapter generate if (C_INTERFACE_TYPE == 0 && C_HAS_DATA_COUNTS_AXIS != 3) begin : fifo_icn_adapter assign WR_DATA_COUNT = wr_data_count_in; end endgenerate // fifo_icn_adapter wire inverted_reset = ~S_ARESETN; wire axi_rs_rst; reg rst_d1 = 0 ; reg rst_d2 = 0 ; wire [C_DIN_WIDTH_AXIS-1:0] axis_din ; wire [C_DIN_WIDTH_AXIS-1:0] axis_dout ; wire axis_full ; wire axis_almost_full ; wire axis_empty ; wire axis_s_axis_tready; wire axis_m_axis_tvalid; wire axis_wr_en ; wire axis_rd_en ; wire axis_we ; wire axis_re ; wire [C_WR_PNTR_WIDTH_AXIS:0] axis_dc; reg axis_pkt_read = 1'b0; wire axis_rd_rst; wire axis_wr_rst; generate if (C_INTERFACE_TYPE > 0 && (C_AXIS_TYPE == 1 || C_WACH_TYPE == 1 || C_WDCH_TYPE == 1 || C_WRCH_TYPE == 1 || C_RACH_TYPE == 1 || C_RDCH_TYPE == 1)) begin : gaxi_rs_rst always @ (posedge inverted_reset or posedge S_ACLK) begin if (inverted_reset) begin rst_d1 <= 1'b1; rst_d2 <= 1'b1; end else begin rst_d1 <= #`TCQ 1'b0; rst_d2 <= #`TCQ rst_d1; end end assign axi_rs_rst = rst_d2; end endgenerate // gaxi_rs_rst generate if (IS_AXI_STREAMING == 1 && C_AXIS_TYPE == 0) begin : axi_streaming // Write protection when almost full or prog_full is high assign axis_we = (C_PROG_FULL_TYPE_AXIS != 0) ? axis_s_axis_tready & S_AXIS_TVALID : (C_APPLICATION_TYPE_AXIS == 1) ? axis_s_axis_tready & S_AXIS_TVALID : S_AXIS_TVALID; // Read protection when almost empty or prog_empty is high assign axis_re = (C_PROG_EMPTY_TYPE_AXIS != 0) ? axis_m_axis_tvalid & M_AXIS_TREADY : (C_APPLICATION_TYPE_AXIS == 1) ? axis_m_axis_tvalid & M_AXIS_TREADY : M_AXIS_TREADY; assign axis_wr_en = (C_HAS_SLAVE_CE == 1) ? axis_we & S_ACLK_EN : axis_we; assign axis_rd_en = (C_HAS_MASTER_CE == 1) ? axis_re & M_ACLK_EN : axis_re; FIFO_GENERATOR_v12_0_CONV_VER #( .C_FAMILY (C_FAMILY), .C_COMMON_CLOCK (C_COMMON_CLOCK), .C_MEMORY_TYPE ((C_IMPLEMENTATION_TYPE_AXIS == 1 || C_IMPLEMENTATION_TYPE_AXIS == 11) ? 1 : (C_IMPLEMENTATION_TYPE_AXIS == 2 || C_IMPLEMENTATION_TYPE_AXIS == 12) ? 2 : 4), .C_IMPLEMENTATION_TYPE ((C_IMPLEMENTATION_TYPE_AXIS == 1 || C_IMPLEMENTATION_TYPE_AXIS == 2) ? 0 : (C_IMPLEMENTATION_TYPE_AXIS == 11 || C_IMPLEMENTATION_TYPE_AXIS == 12) ? 2 : 6), .C_PRELOAD_REGS (1), // always FWFT for AXI .C_PRELOAD_LATENCY (0), // always FWFT for AXI .C_DIN_WIDTH (C_DIN_WIDTH_AXIS), .C_WR_DEPTH (C_WR_DEPTH_AXIS), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH_AXIS), .C_DOUT_WIDTH (C_DIN_WIDTH_AXIS), .C_RD_DEPTH (C_WR_DEPTH_AXIS), .C_RD_PNTR_WIDTH (C_WR_PNTR_WIDTH_AXIS), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE_AXIS), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL_AXIS), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE_AXIS), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL_AXIS), .C_USE_ECC (C_USE_ECC_AXIS), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE_AXIS), .C_HAS_ALMOST_EMPTY (0), .C_HAS_ALMOST_FULL (C_APPLICATION_TYPE_AXIS == 1 ? 1: 0), .C_AXI_TYPE (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE), .C_USE_EMBEDDED_REG (C_USE_EMBEDDED_REG), .C_FIFO_TYPE (C_APPLICATION_TYPE_AXIS == 1 ? 0: C_APPLICATION_TYPE_AXIS), .C_SYNCHRONIZER_STAGE (C_SYNCHRONIZER_STAGE), .C_HAS_WR_RST (0), .C_HAS_RD_RST (0), .C_HAS_RST (1), .C_HAS_SRST (0), .C_DOUT_RST_VAL (0), .C_HAS_VALID (0), .C_VALID_LOW (C_VALID_LOW), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_HAS_WR_ACK (0), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_HAS_DATA_COUNT ((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_AXIS == 1) ? 1 : 0), .C_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_AXIS + 1), .C_HAS_RD_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_AXIS == 1) ? 1 : 0), .C_RD_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_AXIS + 1), .C_USE_FWFT_DATA_COUNT (1), // use extra logic is always true .C_HAS_WR_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_AXIS == 1) ? 1 : 0), .C_WR_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_AXIS + 1), .C_FULL_FLAGS_RST_VAL (1), .C_USE_DOUT_RST (0), .C_MSGON_VAL (C_MSGON_VAL), .C_ENABLE_RST_SYNC (1), .C_COUNT_TYPE (C_COUNT_TYPE), .C_DEFAULT_VALUE (C_DEFAULT_VALUE), .C_ENABLE_RLOCS (C_ENABLE_RLOCS), .C_HAS_BACKUP (C_HAS_BACKUP), .C_HAS_INT_CLK (C_HAS_INT_CLK), .C_MIF_FILE_NAME (C_MIF_FILE_NAME), .C_HAS_MEMINIT_FILE (C_HAS_MEMINIT_FILE), .C_INIT_WR_PNTR_VAL (C_INIT_WR_PNTR_VAL), .C_OPTIMIZATION_MODE (C_OPTIMIZATION_MODE), .C_PRIM_FIFO_TYPE (C_PRIM_FIFO_TYPE), .C_RD_FREQ (C_RD_FREQ), .C_USE_FIFO16_FLAGS (C_USE_FIFO16_FLAGS), .C_WR_FREQ (C_WR_FREQ), .C_WR_RESPONSE_LATENCY (C_WR_RESPONSE_LATENCY) ) fifo_generator_v12_0_axis_dut ( .CLK (S_ACLK), .WR_CLK (S_ACLK), .RD_CLK (M_ACLK), .RST (inverted_reset), .SRST (1'b0), .WR_RST (inverted_reset), .RD_RST (inverted_reset), .WR_EN (axis_wr_en), .RD_EN (axis_rd_en), .PROG_FULL_THRESH (AXIS_PROG_FULL_THRESH), .PROG_FULL_THRESH_ASSERT ({C_WR_PNTR_WIDTH_AXIS{1'b0}}), .PROG_FULL_THRESH_NEGATE ({C_WR_PNTR_WIDTH_AXIS{1'b0}}), .PROG_EMPTY_THRESH (AXIS_PROG_EMPTY_THRESH), .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_AXIS{1'b0}}), .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_AXIS{1'b0}}), .INJECTDBITERR (AXIS_INJECTDBITERR), .INJECTSBITERR (AXIS_INJECTSBITERR), .DIN (axis_din), .DOUT (axis_dout), .FULL (axis_full), .EMPTY (axis_empty), .ALMOST_FULL (axis_almost_full), .PROG_FULL (AXIS_PROG_FULL), .ALMOST_EMPTY (), .PROG_EMPTY (AXIS_PROG_EMPTY), .WR_ACK (), .OVERFLOW (AXIS_OVERFLOW), .VALID (), .UNDERFLOW (AXIS_UNDERFLOW), .DATA_COUNT (axis_dc), .RD_DATA_COUNT (AXIS_RD_DATA_COUNT), .WR_DATA_COUNT (AXIS_WR_DATA_COUNT), .SBITERR (AXIS_SBITERR), .DBITERR (AXIS_DBITERR), .wr_rst_busy (wr_rst_busy_axis), .rd_rst_busy (rd_rst_busy_axis), .wr_rst_i_out (axis_wr_rst), .rd_rst_i_out (axis_rd_rst), .BACKUP (BACKUP), .BACKUP_MARKER (BACKUP_MARKER), .INT_CLK (INT_CLK) ); assign axis_s_axis_tready = (IS_8SERIES == 0) ? ~axis_full : (C_IMPLEMENTATION_TYPE_AXIS == 5 || C_IMPLEMENTATION_TYPE_AXIS == 13) ? ~(axis_full | wr_rst_busy_axis) : ~axis_full; assign axis_m_axis_tvalid = (C_APPLICATION_TYPE_AXIS != 1) ? ~axis_empty : ~axis_empty & axis_pkt_read; assign S_AXIS_TREADY = axis_s_axis_tready; assign M_AXIS_TVALID = axis_m_axis_tvalid; end endgenerate // axi_streaming wire axis_wr_eop; reg axis_wr_eop_d1 = 1'b0; wire axis_rd_eop; integer axis_pkt_cnt; generate if (C_APPLICATION_TYPE_AXIS == 1 && C_COMMON_CLOCK == 1) begin : gaxis_pkt_fifo_cc assign axis_wr_eop = axis_wr_en & S_AXIS_TLAST; assign axis_rd_eop = axis_rd_en & axis_dout[0]; always @ (posedge inverted_reset or posedge S_ACLK) begin if (inverted_reset) axis_pkt_read <= 1'b0; else if (axis_rd_eop && (axis_pkt_cnt == 1) && ~axis_wr_eop_d1) axis_pkt_read <= 1'b0; else if ((axis_pkt_cnt > 0) || (axis_almost_full && ~axis_empty)) axis_pkt_read <= 1'b1; end always @ (posedge inverted_reset or posedge S_ACLK) begin if (inverted_reset) axis_wr_eop_d1 <= 1'b0; else axis_wr_eop_d1 <= axis_wr_eop; end always @ (posedge inverted_reset or posedge S_ACLK) begin if (inverted_reset) axis_pkt_cnt <= 0; else if (axis_wr_eop_d1 && ~axis_rd_eop) axis_pkt_cnt <= axis_pkt_cnt + 1; else if (axis_rd_eop && ~axis_wr_eop_d1) axis_pkt_cnt <= axis_pkt_cnt - 1; end end endgenerate // gaxis_pkt_fifo_cc reg [LOG_DEPTH_AXIS-1 : 0] axis_wpkt_cnt_gc = 0; wire [(LOG_DEPTH_AXIS)-1 : 0] axis_wpkt_cnt_gc_asreg_last; wire axis_rd_has_rst; wire [0:C_SYNCHRONIZER_STAGE] axis_af_q ; wire [LOG_DEPTH_AXIS-1 : 0] wpkt_q [0:C_SYNCHRONIZER_STAGE] ; wire [1:C_SYNCHRONIZER_STAGE] axis_af_q_temp = 0; wire [LOG_DEPTH_AXIS-1 : 0] wpkt_q_temp [1:C_SYNCHRONIZER_STAGE] ; reg [LOG_DEPTH_AXIS-1 : 0] axis_wpkt_cnt_rd = 0; reg [LOG_DEPTH_AXIS-1 : 0] axis_wpkt_cnt = 0; reg [LOG_DEPTH_AXIS-1 : 0] axis_rpkt_cnt = 0; wire [LOG_DEPTH_AXIS : 0] adj_axis_wpkt_cnt_rd_pad; wire [LOG_DEPTH_AXIS : 0] rpkt_inv_pad; wire [LOG_DEPTH_AXIS-1 : 0] diff_pkt_cnt; reg [LOG_DEPTH_AXIS : 0] diff_pkt_cnt_pad = 0; reg adj_axis_wpkt_cnt_rd_pad_0 = 0; reg rpkt_inv_pad_0 = 0; wire axis_af_rd ; generate if (C_HAS_RST == 1) begin : rst_blk_has assign axis_rd_has_rst = axis_rd_rst; end endgenerate //rst_blk_has generate if (C_HAS_RST == 0) begin :rst_blk_no assign axis_rd_has_rst = 1'b0; end endgenerate //rst_blk_no genvar i; generate for (i = 1; ((i <= C_SYNCHRONIZER_STAGE) && (C_APPLICATION_TYPE_AXIS == 1 && C_COMMON_CLOCK == 0) ); i = i + 1) begin : gpkt_cnt_sync_stage fifo_generator_v12_0_sync_stage #( .C_WIDTH (LOG_DEPTH_AXIS) ) rd_stg_inst ( .RST (axis_rd_has_rst), .CLK (M_ACLK), .DIN (wpkt_q[i-1]), .DOUT (wpkt_q[i]) ); fifo_generator_v12_0_sync_stage #( .C_WIDTH (1) ) wr_stg_inst ( .RST (axis_rd_has_rst), .CLK (M_ACLK), .DIN (axis_af_q[i-1]), .DOUT (axis_af_q[i]) ); end endgenerate // gpkt_cnt_sync_stage generate if (C_APPLICATION_TYPE_AXIS == 1 && C_COMMON_CLOCK == 0) begin : gaxis_pkt_fifo_ic assign axis_wr_eop = axis_wr_en & S_AXIS_TLAST; assign axis_rd_eop = axis_rd_en & axis_dout[0]; always @ (posedge axis_rd_has_rst or posedge M_ACLK) begin if (axis_rd_has_rst) axis_pkt_read <= 1'b0; else if (axis_rd_eop && (diff_pkt_cnt == 1)) axis_pkt_read <= 1'b0; else if ((diff_pkt_cnt > 0) || (axis_af_rd && ~axis_empty)) axis_pkt_read <= 1'b1; end always @ (posedge axis_wr_rst or posedge S_ACLK) begin if (axis_wr_rst) axis_wpkt_cnt <= 1'b0; else if (axis_wr_eop) axis_wpkt_cnt <= axis_wpkt_cnt + 1; end always @ (posedge axis_wr_rst or posedge S_ACLK) begin if (axis_wr_rst) axis_wpkt_cnt_gc <= 1'b0; else axis_wpkt_cnt_gc <= bin2gray(axis_wpkt_cnt); end assign wpkt_q[0] = axis_wpkt_cnt_gc; assign axis_wpkt_cnt_gc_asreg_last = wpkt_q[C_SYNCHRONIZER_STAGE]; assign axis_af_q[0] = axis_almost_full; //assign axis_af_q[1:C_SYNCHRONIZER_STAGE] = axis_af_q_temp[1:C_SYNCHRONIZER_STAGE]; assign axis_af_rd = axis_af_q[C_SYNCHRONIZER_STAGE]; always @ (posedge axis_rd_has_rst or posedge M_ACLK) begin if (axis_rd_has_rst) axis_wpkt_cnt_rd <= 1'b0; else axis_wpkt_cnt_rd <= gray2bin(axis_wpkt_cnt_gc_asreg_last); end always @ (posedge axis_rd_rst or posedge M_ACLK) begin if (axis_rd_has_rst) axis_rpkt_cnt <= 1'b0; else if (axis_rd_eop) axis_rpkt_cnt <= axis_rpkt_cnt + 1; end // Take the difference of write and read packet count // Logic is similar to rd_pe_as assign adj_axis_wpkt_cnt_rd_pad[LOG_DEPTH_AXIS : 1] = axis_wpkt_cnt_rd; assign rpkt_inv_pad[LOG_DEPTH_AXIS : 1] = ~axis_rpkt_cnt; assign adj_axis_wpkt_cnt_rd_pad[0] = adj_axis_wpkt_cnt_rd_pad_0; assign rpkt_inv_pad[0] = rpkt_inv_pad_0; always @ ( axis_rd_eop ) begin if (!axis_rd_eop) begin adj_axis_wpkt_cnt_rd_pad_0 <= 1'b1; rpkt_inv_pad_0 <= 1'b1; end else begin adj_axis_wpkt_cnt_rd_pad_0 <= 1'b0; rpkt_inv_pad_0 <= 1'b0; end end always @ (posedge axis_rd_rst or posedge M_ACLK) begin if (axis_rd_has_rst) diff_pkt_cnt_pad <= 1'b0; else diff_pkt_cnt_pad <= adj_axis_wpkt_cnt_rd_pad + rpkt_inv_pad ; end assign diff_pkt_cnt = diff_pkt_cnt_pad [LOG_DEPTH_AXIS : 1] ; end endgenerate // gaxis_pkt_fifo_ic // Generate the accurate data count for axi stream packet fifo configuration reg [C_WR_PNTR_WIDTH_AXIS:0] axis_dc_pkt_fifo = 0; generate if (IS_AXI_STREAMING == 1 && C_HAS_DATA_COUNTS_AXIS == 1 && C_APPLICATION_TYPE_AXIS == 1) begin : gdc_pkt always @ (posedge inverted_reset or posedge S_ACLK) begin if (inverted_reset) axis_dc_pkt_fifo <= 0; else if (axis_wr_en && (~axis_rd_en)) axis_dc_pkt_fifo <= #`TCQ axis_dc_pkt_fifo + 1; else if (~axis_wr_en && axis_rd_en) axis_dc_pkt_fifo <= #`TCQ axis_dc_pkt_fifo - 1; end assign AXIS_DATA_COUNT = axis_dc_pkt_fifo; end endgenerate // gdc_pkt generate if (IS_AXI_STREAMING == 1 && C_HAS_DATA_COUNTS_AXIS == 0 && C_APPLICATION_TYPE_AXIS == 1) begin : gndc_pkt assign AXIS_DATA_COUNT = 0; end endgenerate // gndc_pkt generate if (IS_AXI_STREAMING == 1 && C_APPLICATION_TYPE_AXIS != 1) begin : gdc assign AXIS_DATA_COUNT = axis_dc; end endgenerate // gdc // Register Slice for Write Address Channel generate if (C_AXIS_TYPE == 1) begin : gaxis_reg_slice assign axis_wr_en = (C_HAS_SLAVE_CE == 1) ? S_AXIS_TVALID & S_ACLK_EN : S_AXIS_TVALID; assign axis_rd_en = (C_HAS_MASTER_CE == 1) ? M_AXIS_TREADY & M_ACLK_EN : M_AXIS_TREADY; fifo_generator_v12_0_axic_reg_slice #( .C_FAMILY (C_FAMILY), .C_DATA_WIDTH (C_DIN_WIDTH_AXIS), .C_REG_CONFIG (C_REG_SLICE_MODE_AXIS) ) axis_reg_slice_inst ( // System Signals .ACLK (S_ACLK), .ARESET (axi_rs_rst), // Slave side .S_PAYLOAD_DATA (axis_din), .S_VALID (axis_wr_en), .S_READY (S_AXIS_TREADY), // Master side .M_PAYLOAD_DATA (axis_dout), .M_VALID (M_AXIS_TVALID), .M_READY (axis_rd_en) ); end endgenerate // gaxis_reg_slice generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TDATA == 1) begin : tdata assign axis_din[C_DIN_WIDTH_AXIS-1:TDATA_OFFSET] = S_AXIS_TDATA; assign M_AXIS_TDATA = axis_dout[C_DIN_WIDTH_AXIS-1:TDATA_OFFSET]; end endgenerate generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TSTRB == 1) begin : tstrb assign axis_din[TDATA_OFFSET-1:TSTRB_OFFSET] = S_AXIS_TSTRB; assign M_AXIS_TSTRB = axis_dout[TDATA_OFFSET-1:TSTRB_OFFSET]; end endgenerate generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TKEEP == 1) begin : tkeep assign axis_din[TSTRB_OFFSET-1:TKEEP_OFFSET] = S_AXIS_TKEEP; assign M_AXIS_TKEEP = axis_dout[TSTRB_OFFSET-1:TKEEP_OFFSET]; end endgenerate generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TID == 1) begin : tid assign axis_din[TKEEP_OFFSET-1:TID_OFFSET] = S_AXIS_TID; assign M_AXIS_TID = axis_dout[TKEEP_OFFSET-1:TID_OFFSET]; end endgenerate generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TDEST == 1) begin : tdest assign axis_din[TID_OFFSET-1:TDEST_OFFSET] = S_AXIS_TDEST; assign M_AXIS_TDEST = axis_dout[TID_OFFSET-1:TDEST_OFFSET]; end endgenerate generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TUSER == 1) begin : tuser assign axis_din[TDEST_OFFSET-1:TUSER_OFFSET] = S_AXIS_TUSER; assign M_AXIS_TUSER = axis_dout[TDEST_OFFSET-1:TUSER_OFFSET]; end endgenerate generate if ((IS_AXI_STREAMING == 1 || C_AXIS_TYPE == 1) && C_HAS_AXIS_TLAST == 1) begin : tlast assign axis_din[0] = S_AXIS_TLAST; assign M_AXIS_TLAST = axis_dout[0]; end endgenerate //########################################################################### // AXI FULL Write Channel (axi_write_channel) //########################################################################### localparam IS_AXI_FULL = ((C_INTERFACE_TYPE == 2) && (C_AXI_TYPE != 2)) ? 1 : 0; localparam IS_AXI_LITE = ((C_INTERFACE_TYPE == 2) && (C_AXI_TYPE == 2)) ? 1 : 0; localparam IS_AXI_FULL_WACH = ((IS_AXI_FULL == 1) && (C_WACH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0; localparam IS_AXI_FULL_WDCH = ((IS_AXI_FULL == 1) && (C_WDCH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0; localparam IS_AXI_FULL_WRCH = ((IS_AXI_FULL == 1) && (C_WRCH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0; localparam IS_AXI_FULL_RACH = ((IS_AXI_FULL == 1) && (C_RACH_TYPE == 0) && C_HAS_AXI_RD_CHANNEL == 1) ? 1 : 0; localparam IS_AXI_FULL_RDCH = ((IS_AXI_FULL == 1) && (C_RDCH_TYPE == 0) && C_HAS_AXI_RD_CHANNEL == 1) ? 1 : 0; localparam IS_AXI_LITE_WACH = ((IS_AXI_LITE == 1) && (C_WACH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0; localparam IS_AXI_LITE_WDCH = ((IS_AXI_LITE == 1) && (C_WDCH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0; localparam IS_AXI_LITE_WRCH = ((IS_AXI_LITE == 1) && (C_WRCH_TYPE == 0) && C_HAS_AXI_WR_CHANNEL == 1) ? 1 : 0; localparam IS_AXI_LITE_RACH = ((IS_AXI_LITE == 1) && (C_RACH_TYPE == 0) && C_HAS_AXI_RD_CHANNEL == 1) ? 1 : 0; localparam IS_AXI_LITE_RDCH = ((IS_AXI_LITE == 1) && (C_RDCH_TYPE == 0) && C_HAS_AXI_RD_CHANNEL == 1) ? 1 : 0; localparam IS_WR_ADDR_CH = ((IS_AXI_FULL_WACH == 1) || (IS_AXI_LITE_WACH == 1)) ? 1 : 0; localparam IS_WR_DATA_CH = ((IS_AXI_FULL_WDCH == 1) || (IS_AXI_LITE_WDCH == 1)) ? 1 : 0; localparam IS_WR_RESP_CH = ((IS_AXI_FULL_WRCH == 1) || (IS_AXI_LITE_WRCH == 1)) ? 1 : 0; localparam IS_RD_ADDR_CH = ((IS_AXI_FULL_RACH == 1) || (IS_AXI_LITE_RACH == 1)) ? 1 : 0; localparam IS_RD_DATA_CH = ((IS_AXI_FULL_RDCH == 1) || (IS_AXI_LITE_RDCH == 1)) ? 1 : 0; localparam AWID_OFFSET = (C_AXI_TYPE != 2 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_WACH - C_AXI_ID_WIDTH : C_DIN_WIDTH_WACH; localparam AWADDR_OFFSET = AWID_OFFSET - C_AXI_ADDR_WIDTH; localparam AWLEN_OFFSET = C_AXI_TYPE != 2 ? AWADDR_OFFSET - C_AXI_LEN_WIDTH : AWADDR_OFFSET; localparam AWSIZE_OFFSET = C_AXI_TYPE != 2 ? AWLEN_OFFSET - C_AXI_SIZE_WIDTH : AWLEN_OFFSET; localparam AWBURST_OFFSET = C_AXI_TYPE != 2 ? AWSIZE_OFFSET - C_AXI_BURST_WIDTH : AWSIZE_OFFSET; localparam AWLOCK_OFFSET = C_AXI_TYPE != 2 ? AWBURST_OFFSET - C_AXI_LOCK_WIDTH : AWBURST_OFFSET; localparam AWCACHE_OFFSET = C_AXI_TYPE != 2 ? AWLOCK_OFFSET - C_AXI_CACHE_WIDTH : AWLOCK_OFFSET; localparam AWPROT_OFFSET = AWCACHE_OFFSET - C_AXI_PROT_WIDTH; localparam AWQOS_OFFSET = AWPROT_OFFSET - C_AXI_QOS_WIDTH; localparam AWREGION_OFFSET = C_AXI_TYPE == 1 ? AWQOS_OFFSET - C_AXI_REGION_WIDTH : AWQOS_OFFSET; localparam AWUSER_OFFSET = C_HAS_AXI_AWUSER == 1 ? AWREGION_OFFSET-C_AXI_AWUSER_WIDTH : AWREGION_OFFSET; localparam WID_OFFSET = (C_AXI_TYPE == 3 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_WDCH - C_AXI_ID_WIDTH : C_DIN_WIDTH_WDCH; localparam WDATA_OFFSET = WID_OFFSET - C_AXI_DATA_WIDTH; localparam WSTRB_OFFSET = WDATA_OFFSET - C_AXI_DATA_WIDTH/8; localparam WUSER_OFFSET = C_HAS_AXI_WUSER == 1 ? WSTRB_OFFSET-C_AXI_WUSER_WIDTH : WSTRB_OFFSET; localparam BID_OFFSET = (C_AXI_TYPE != 2 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_WRCH - C_AXI_ID_WIDTH : C_DIN_WIDTH_WRCH; localparam BRESP_OFFSET = BID_OFFSET - C_AXI_BRESP_WIDTH; localparam BUSER_OFFSET = C_HAS_AXI_BUSER == 1 ? BRESP_OFFSET-C_AXI_BUSER_WIDTH : BRESP_OFFSET; wire [C_DIN_WIDTH_WACH-1:0] wach_din ; wire [C_DIN_WIDTH_WACH-1:0] wach_dout ; wire [C_DIN_WIDTH_WACH-1:0] wach_dout_pkt ; wire wach_full ; wire wach_almost_full ; wire wach_prog_full ; wire wach_empty ; wire wach_almost_empty ; wire wach_prog_empty ; wire [C_DIN_WIDTH_WDCH-1:0] wdch_din ; wire [C_DIN_WIDTH_WDCH-1:0] wdch_dout ; wire wdch_full ; wire wdch_almost_full ; wire wdch_prog_full ; wire wdch_empty ; wire wdch_almost_empty ; wire wdch_prog_empty ; wire [C_DIN_WIDTH_WRCH-1:0] wrch_din ; wire [C_DIN_WIDTH_WRCH-1:0] wrch_dout ; wire wrch_full ; wire wrch_almost_full ; wire wrch_prog_full ; wire wrch_empty ; wire wrch_almost_empty ; wire wrch_prog_empty ; wire axi_aw_underflow_i; wire axi_w_underflow_i ; wire axi_b_underflow_i ; wire axi_aw_overflow_i ; wire axi_w_overflow_i ; wire axi_b_overflow_i ; wire axi_wr_underflow_i; wire axi_wr_overflow_i ; wire wach_s_axi_awready; wire wach_m_axi_awvalid; wire wach_wr_en ; wire wach_rd_en ; wire wdch_s_axi_wready ; wire wdch_m_axi_wvalid ; wire wdch_wr_en ; wire wdch_rd_en ; wire wrch_s_axi_bvalid ; wire wrch_m_axi_bready ; wire wrch_wr_en ; wire wrch_rd_en ; wire txn_count_up ; wire txn_count_down ; wire awvalid_en ; wire awvalid_pkt ; wire awready_pkt ; integer wr_pkt_count ; wire wach_we ; wire wach_re ; wire wdch_we ; wire wdch_re ; wire wrch_we ; wire wrch_re ; generate if (IS_WR_ADDR_CH == 1) begin : axi_write_address_channel // Write protection when almost full or prog_full is high assign wach_we = (C_PROG_FULL_TYPE_WACH != 0) ? wach_s_axi_awready & S_AXI_AWVALID : S_AXI_AWVALID; // Read protection when almost empty or prog_empty is high assign wach_re = (C_PROG_EMPTY_TYPE_WACH != 0 && C_APPLICATION_TYPE_WACH == 1) ? wach_m_axi_awvalid & awready_pkt & awvalid_en : (C_PROG_EMPTY_TYPE_WACH != 0 && C_APPLICATION_TYPE_WACH != 1) ? M_AXI_AWREADY && wach_m_axi_awvalid : (C_PROG_EMPTY_TYPE_WACH == 0 && C_APPLICATION_TYPE_WACH == 1) ? awready_pkt & awvalid_en : (C_PROG_EMPTY_TYPE_WACH == 0 && C_APPLICATION_TYPE_WACH != 1) ? M_AXI_AWREADY : 1'b0; assign wach_wr_en = (C_HAS_SLAVE_CE == 1) ? wach_we & S_ACLK_EN : wach_we; assign wach_rd_en = (C_HAS_MASTER_CE == 1) ? wach_re & M_ACLK_EN : wach_re; FIFO_GENERATOR_v12_0_CONV_VER #( .C_FAMILY (C_FAMILY), .C_COMMON_CLOCK (C_COMMON_CLOCK), .C_MEMORY_TYPE ((C_IMPLEMENTATION_TYPE_WACH == 1 || C_IMPLEMENTATION_TYPE_WACH == 11) ? 1 : (C_IMPLEMENTATION_TYPE_WACH == 2 || C_IMPLEMENTATION_TYPE_WACH == 12) ? 2 : 4), .C_IMPLEMENTATION_TYPE ((C_IMPLEMENTATION_TYPE_WACH == 1 || C_IMPLEMENTATION_TYPE_WACH == 2) ? 0 : (C_IMPLEMENTATION_TYPE_WACH == 11 || C_IMPLEMENTATION_TYPE_WACH == 12) ? 2 : 6), .C_PRELOAD_REGS (1), // always FWFT for AXI .C_PRELOAD_LATENCY (0), // always FWFT for AXI .C_DIN_WIDTH (C_DIN_WIDTH_WACH), .C_WR_DEPTH (C_WR_DEPTH_WACH), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH_WACH), .C_DOUT_WIDTH (C_DIN_WIDTH_WACH), .C_RD_DEPTH (C_WR_DEPTH_WACH), .C_RD_PNTR_WIDTH (C_WR_PNTR_WIDTH_WACH), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE_WACH), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL_WACH), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE_WACH), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL_WACH), .C_USE_ECC (C_USE_ECC_WACH), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE_WACH), .C_HAS_ALMOST_EMPTY (0), .C_HAS_ALMOST_FULL (0), .C_AXI_TYPE (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE), .C_FIFO_TYPE ((C_APPLICATION_TYPE_WACH == 1)?0:C_APPLICATION_TYPE_WACH), .C_SYNCHRONIZER_STAGE (C_SYNCHRONIZER_STAGE), .C_HAS_WR_RST (0), .C_HAS_RD_RST (0), .C_HAS_RST (1), .C_HAS_SRST (0), .C_DOUT_RST_VAL (0), .C_HAS_VALID (0), .C_VALID_LOW (C_VALID_LOW), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_HAS_WR_ACK (0), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_HAS_DATA_COUNT ((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_WACH == 1) ? 1 : 0), .C_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_WACH + 1), .C_HAS_RD_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WACH == 1) ? 1 : 0), .C_RD_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_WACH + 1), .C_USE_FWFT_DATA_COUNT (1), // use extra logic is always true .C_HAS_WR_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WACH == 1) ? 1 : 0), .C_WR_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_WACH + 1), .C_FULL_FLAGS_RST_VAL (1), .C_USE_EMBEDDED_REG (0), .C_USE_DOUT_RST (0), .C_MSGON_VAL (C_MSGON_VAL), .C_ENABLE_RST_SYNC (1), .C_COUNT_TYPE (C_COUNT_TYPE), .C_DEFAULT_VALUE (C_DEFAULT_VALUE), .C_ENABLE_RLOCS (C_ENABLE_RLOCS), .C_HAS_BACKUP (C_HAS_BACKUP), .C_HAS_INT_CLK (C_HAS_INT_CLK), .C_MIF_FILE_NAME (C_MIF_FILE_NAME), .C_HAS_MEMINIT_FILE (C_HAS_MEMINIT_FILE), .C_INIT_WR_PNTR_VAL (C_INIT_WR_PNTR_VAL), .C_OPTIMIZATION_MODE (C_OPTIMIZATION_MODE), .C_PRIM_FIFO_TYPE (C_PRIM_FIFO_TYPE), .C_RD_FREQ (C_RD_FREQ), .C_USE_FIFO16_FLAGS (C_USE_FIFO16_FLAGS), .C_WR_FREQ (C_WR_FREQ), .C_WR_RESPONSE_LATENCY (C_WR_RESPONSE_LATENCY) ) fifo_generator_v12_0_wach_dut ( .CLK (S_ACLK), .WR_CLK (S_ACLK), .RD_CLK (M_ACLK), .RST (inverted_reset), .SRST (1'b0), .WR_RST (inverted_reset), .RD_RST (inverted_reset), .WR_EN (wach_wr_en), .RD_EN (wach_rd_en), .PROG_FULL_THRESH (AXI_AW_PROG_FULL_THRESH), .PROG_FULL_THRESH_ASSERT ({C_WR_PNTR_WIDTH_WACH{1'b0}}), .PROG_FULL_THRESH_NEGATE ({C_WR_PNTR_WIDTH_WACH{1'b0}}), .PROG_EMPTY_THRESH (AXI_AW_PROG_EMPTY_THRESH), .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_WACH{1'b0}}), .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_WACH{1'b0}}), .INJECTDBITERR (AXI_AW_INJECTDBITERR), .INJECTSBITERR (AXI_AW_INJECTSBITERR), .DIN (wach_din), .DOUT (wach_dout_pkt), .FULL (wach_full), .EMPTY (wach_empty), .ALMOST_FULL (), .PROG_FULL (AXI_AW_PROG_FULL), .ALMOST_EMPTY (), .PROG_EMPTY (AXI_AW_PROG_EMPTY), .WR_ACK (), .OVERFLOW (axi_aw_overflow_i), .VALID (), .UNDERFLOW (axi_aw_underflow_i), .DATA_COUNT (AXI_AW_DATA_COUNT), .RD_DATA_COUNT (AXI_AW_RD_DATA_COUNT), .WR_DATA_COUNT (AXI_AW_WR_DATA_COUNT), .SBITERR (AXI_AW_SBITERR), .DBITERR (AXI_AW_DBITERR), .wr_rst_busy (wr_rst_busy_wach), .rd_rst_busy (rd_rst_busy_wach), .wr_rst_i_out (), .rd_rst_i_out (), .BACKUP (BACKUP), .BACKUP_MARKER (BACKUP_MARKER), .INT_CLK (INT_CLK) ); assign wach_s_axi_awready = (IS_8SERIES == 0) ? ~wach_full : (C_IMPLEMENTATION_TYPE_WACH == 5 || C_IMPLEMENTATION_TYPE_WACH == 13) ? ~(wach_full | wr_rst_busy_wach) : ~wach_full; assign wach_m_axi_awvalid = ~wach_empty; assign S_AXI_AWREADY = wach_s_axi_awready; assign AXI_AW_UNDERFLOW = C_USE_COMMON_UNDERFLOW == 0 ? axi_aw_underflow_i : 0; assign AXI_AW_OVERFLOW = C_USE_COMMON_OVERFLOW == 0 ? axi_aw_overflow_i : 0; end endgenerate // axi_write_address_channel // Register Slice for Write Address Channel generate if (C_WACH_TYPE == 1) begin : gwach_reg_slice fifo_generator_v12_0_axic_reg_slice #( .C_FAMILY (C_FAMILY), .C_DATA_WIDTH (C_DIN_WIDTH_WACH), .C_REG_CONFIG (C_REG_SLICE_MODE_WACH) ) wach_reg_slice_inst ( // System Signals .ACLK (S_ACLK), .ARESET (axi_rs_rst), // Slave side .S_PAYLOAD_DATA (wach_din), .S_VALID (S_AXI_AWVALID), .S_READY (S_AXI_AWREADY), // Master side .M_PAYLOAD_DATA (wach_dout), .M_VALID (M_AXI_AWVALID), .M_READY (M_AXI_AWREADY) ); end endgenerate // gwach_reg_slice generate if (C_APPLICATION_TYPE_WACH == 1 && C_HAS_AXI_WR_CHANNEL == 1) begin : axi_mm_pkt_fifo_wr fifo_generator_v12_0_axic_reg_slice #( .C_FAMILY (C_FAMILY), .C_DATA_WIDTH (C_DIN_WIDTH_WACH), .C_REG_CONFIG (1) ) wach_pkt_reg_slice_inst ( // System Signals .ACLK (S_ACLK), .ARESET (inverted_reset), // Slave side .S_PAYLOAD_DATA (wach_dout_pkt), .S_VALID (awvalid_pkt), .S_READY (awready_pkt), // Master side .M_PAYLOAD_DATA (wach_dout), .M_VALID (M_AXI_AWVALID), .M_READY (M_AXI_AWREADY) ); assign awvalid_pkt = wach_m_axi_awvalid && awvalid_en; assign txn_count_up = wdch_s_axi_wready && wdch_wr_en && wdch_din[0]; assign txn_count_down = wach_m_axi_awvalid && awready_pkt && awvalid_en; always@(posedge S_ACLK or posedge inverted_reset) begin if(inverted_reset == 1) begin wr_pkt_count <= 0; end else begin if(txn_count_up == 1 && txn_count_down == 0) begin wr_pkt_count <= wr_pkt_count + 1; end else if(txn_count_up == 0 && txn_count_down == 1) begin wr_pkt_count <= wr_pkt_count - 1; end end end //Always end assign awvalid_en = (wr_pkt_count > 0)?1:0; end endgenerate generate if (C_APPLICATION_TYPE_WACH != 1) begin : axi_mm_fifo_wr assign awvalid_en = 1; assign wach_dout = wach_dout_pkt; assign M_AXI_AWVALID = wach_m_axi_awvalid; end endgenerate generate if (IS_WR_DATA_CH == 1) begin : axi_write_data_channel // Write protection when almost full or prog_full is high assign wdch_we = (C_PROG_FULL_TYPE_WDCH != 0) ? wdch_s_axi_wready & S_AXI_WVALID : S_AXI_WVALID; // Read protection when almost empty or prog_empty is high assign wdch_re = (C_PROG_EMPTY_TYPE_WDCH != 0) ? wdch_m_axi_wvalid & M_AXI_WREADY : M_AXI_WREADY; assign wdch_wr_en = (C_HAS_SLAVE_CE == 1) ? wdch_we & S_ACLK_EN : wdch_we; assign wdch_rd_en = (C_HAS_MASTER_CE == 1) ? wdch_re & M_ACLK_EN : wdch_re; FIFO_GENERATOR_v12_0_CONV_VER #( .C_FAMILY (C_FAMILY), .C_COMMON_CLOCK (C_COMMON_CLOCK), .C_MEMORY_TYPE ((C_IMPLEMENTATION_TYPE_WDCH == 1 || C_IMPLEMENTATION_TYPE_WDCH == 11) ? 1 : (C_IMPLEMENTATION_TYPE_WDCH == 2 || C_IMPLEMENTATION_TYPE_WDCH == 12) ? 2 : 4), .C_IMPLEMENTATION_TYPE ((C_IMPLEMENTATION_TYPE_WDCH == 1 || C_IMPLEMENTATION_TYPE_WDCH == 2) ? 0 : (C_IMPLEMENTATION_TYPE_WDCH == 11 || C_IMPLEMENTATION_TYPE_WDCH == 12) ? 2 : 6), .C_PRELOAD_REGS (1), // always FWFT for AXI .C_PRELOAD_LATENCY (0), // always FWFT for AXI .C_DIN_WIDTH (C_DIN_WIDTH_WDCH), .C_WR_DEPTH (C_WR_DEPTH_WDCH), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH_WDCH), .C_DOUT_WIDTH (C_DIN_WIDTH_WDCH), .C_RD_DEPTH (C_WR_DEPTH_WDCH), .C_RD_PNTR_WIDTH (C_WR_PNTR_WIDTH_WDCH), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE_WDCH), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL_WDCH), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE_WDCH), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL_WDCH), .C_USE_ECC (C_USE_ECC_WDCH), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE_WDCH), .C_HAS_ALMOST_EMPTY (0), .C_HAS_ALMOST_FULL (0), .C_AXI_TYPE (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE), .C_FIFO_TYPE (C_APPLICATION_TYPE_WDCH), .C_SYNCHRONIZER_STAGE (C_SYNCHRONIZER_STAGE), .C_HAS_WR_RST (0), .C_HAS_RD_RST (0), .C_HAS_RST (1), .C_HAS_SRST (0), .C_DOUT_RST_VAL (0), .C_HAS_VALID (0), .C_VALID_LOW (C_VALID_LOW), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_HAS_WR_ACK (0), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_HAS_DATA_COUNT ((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_WDCH == 1) ? 1 : 0), .C_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_WDCH + 1), .C_HAS_RD_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WDCH == 1) ? 1 : 0), .C_RD_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_WDCH + 1), .C_USE_FWFT_DATA_COUNT (1), // use extra logic is always true .C_HAS_WR_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WDCH == 1) ? 1 : 0), .C_WR_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_WDCH + 1), .C_FULL_FLAGS_RST_VAL (1), .C_USE_EMBEDDED_REG (0), .C_USE_DOUT_RST (0), .C_MSGON_VAL (C_MSGON_VAL), .C_ENABLE_RST_SYNC (1), .C_COUNT_TYPE (C_COUNT_TYPE), .C_DEFAULT_VALUE (C_DEFAULT_VALUE), .C_ENABLE_RLOCS (C_ENABLE_RLOCS), .C_HAS_BACKUP (C_HAS_BACKUP), .C_HAS_INT_CLK (C_HAS_INT_CLK), .C_MIF_FILE_NAME (C_MIF_FILE_NAME), .C_HAS_MEMINIT_FILE (C_HAS_MEMINIT_FILE), .C_INIT_WR_PNTR_VAL (C_INIT_WR_PNTR_VAL), .C_OPTIMIZATION_MODE (C_OPTIMIZATION_MODE), .C_PRIM_FIFO_TYPE (C_PRIM_FIFO_TYPE), .C_RD_FREQ (C_RD_FREQ), .C_USE_FIFO16_FLAGS (C_USE_FIFO16_FLAGS), .C_WR_FREQ (C_WR_FREQ), .C_WR_RESPONSE_LATENCY (C_WR_RESPONSE_LATENCY) ) fifo_generator_v12_0_wdch_dut ( .CLK (S_ACLK), .WR_CLK (S_ACLK), .RD_CLK (M_ACLK), .RST (inverted_reset), .SRST (1'b0), .WR_RST (inverted_reset), .RD_RST (inverted_reset), .WR_EN (wdch_wr_en), .RD_EN (wdch_rd_en), .PROG_FULL_THRESH (AXI_W_PROG_FULL_THRESH), .PROG_FULL_THRESH_ASSERT ({C_WR_PNTR_WIDTH_WDCH{1'b0}}), .PROG_FULL_THRESH_NEGATE ({C_WR_PNTR_WIDTH_WDCH{1'b0}}), .PROG_EMPTY_THRESH (AXI_W_PROG_EMPTY_THRESH), .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_WDCH{1'b0}}), .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_WDCH{1'b0}}), .INJECTDBITERR (AXI_W_INJECTDBITERR), .INJECTSBITERR (AXI_W_INJECTSBITERR), .DIN (wdch_din), .DOUT (wdch_dout), .FULL (wdch_full), .EMPTY (wdch_empty), .ALMOST_FULL (), .PROG_FULL (AXI_W_PROG_FULL), .ALMOST_EMPTY (), .PROG_EMPTY (AXI_W_PROG_EMPTY), .WR_ACK (), .OVERFLOW (axi_w_overflow_i), .VALID (), .UNDERFLOW (axi_w_underflow_i), .DATA_COUNT (AXI_W_DATA_COUNT), .RD_DATA_COUNT (AXI_W_RD_DATA_COUNT), .WR_DATA_COUNT (AXI_W_WR_DATA_COUNT), .SBITERR (AXI_W_SBITERR), .DBITERR (AXI_W_DBITERR), .wr_rst_busy (wr_rst_busy_wdch), .rd_rst_busy (rd_rst_busy_wdch), .wr_rst_i_out (), .rd_rst_i_out (), .BACKUP (BACKUP), .BACKUP_MARKER (BACKUP_MARKER), .INT_CLK (INT_CLK) ); assign wdch_s_axi_wready = (IS_8SERIES == 0) ? ~wdch_full : (C_IMPLEMENTATION_TYPE_WDCH == 5 || C_IMPLEMENTATION_TYPE_WDCH == 13) ? ~(wdch_full | wr_rst_busy_wdch) : ~wdch_full; assign wdch_m_axi_wvalid = ~wdch_empty; assign S_AXI_WREADY = wdch_s_axi_wready; assign M_AXI_WVALID = wdch_m_axi_wvalid; assign AXI_W_UNDERFLOW = C_USE_COMMON_UNDERFLOW == 0 ? axi_w_underflow_i : 0; assign AXI_W_OVERFLOW = C_USE_COMMON_OVERFLOW == 0 ? axi_w_overflow_i : 0; end endgenerate // axi_write_data_channel // Register Slice for Write Data Channel generate if (C_WDCH_TYPE == 1) begin : gwdch_reg_slice fifo_generator_v12_0_axic_reg_slice #( .C_FAMILY (C_FAMILY), .C_DATA_WIDTH (C_DIN_WIDTH_WDCH), .C_REG_CONFIG (C_REG_SLICE_MODE_WDCH) ) wdch_reg_slice_inst ( // System Signals .ACLK (S_ACLK), .ARESET (axi_rs_rst), // Slave side .S_PAYLOAD_DATA (wdch_din), .S_VALID (S_AXI_WVALID), .S_READY (S_AXI_WREADY), // Master side .M_PAYLOAD_DATA (wdch_dout), .M_VALID (M_AXI_WVALID), .M_READY (M_AXI_WREADY) ); end endgenerate // gwdch_reg_slice generate if (IS_WR_RESP_CH == 1) begin : axi_write_resp_channel // Write protection when almost full or prog_full is high assign wrch_we = (C_PROG_FULL_TYPE_WRCH != 0) ? wrch_m_axi_bready & M_AXI_BVALID : M_AXI_BVALID; // Read protection when almost empty or prog_empty is high assign wrch_re = (C_PROG_EMPTY_TYPE_WRCH != 0) ? wrch_s_axi_bvalid & S_AXI_BREADY : S_AXI_BREADY; assign wrch_wr_en = (C_HAS_SLAVE_CE == 1) ? wrch_we & S_ACLK_EN : wrch_we; assign wrch_rd_en = (C_HAS_MASTER_CE == 1) ? wrch_re & M_ACLK_EN : wrch_re; FIFO_GENERATOR_v12_0_CONV_VER #( .C_FAMILY (C_FAMILY), .C_COMMON_CLOCK (C_COMMON_CLOCK), .C_MEMORY_TYPE ((C_IMPLEMENTATION_TYPE_WRCH == 1 || C_IMPLEMENTATION_TYPE_WRCH == 11) ? 1 : (C_IMPLEMENTATION_TYPE_WRCH == 2 || C_IMPLEMENTATION_TYPE_WRCH == 12) ? 2 : 4), .C_IMPLEMENTATION_TYPE ((C_IMPLEMENTATION_TYPE_WRCH == 1 || C_IMPLEMENTATION_TYPE_WRCH == 2) ? 0 : (C_IMPLEMENTATION_TYPE_WRCH == 11 || C_IMPLEMENTATION_TYPE_WRCH == 12) ? 2 : 6), .C_PRELOAD_REGS (1), // always FWFT for AXI .C_PRELOAD_LATENCY (0), // always FWFT for AXI .C_DIN_WIDTH (C_DIN_WIDTH_WRCH), .C_WR_DEPTH (C_WR_DEPTH_WRCH), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH_WRCH), .C_DOUT_WIDTH (C_DIN_WIDTH_WRCH), .C_RD_DEPTH (C_WR_DEPTH_WRCH), .C_RD_PNTR_WIDTH (C_WR_PNTR_WIDTH_WRCH), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE_WRCH), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL_WRCH), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE_WRCH), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL_WRCH), .C_USE_ECC (C_USE_ECC_WRCH), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE_WRCH), .C_HAS_ALMOST_EMPTY (0), .C_HAS_ALMOST_FULL (0), .C_AXI_TYPE (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE), .C_FIFO_TYPE (C_APPLICATION_TYPE_WRCH), .C_SYNCHRONIZER_STAGE (C_SYNCHRONIZER_STAGE), .C_HAS_WR_RST (0), .C_HAS_RD_RST (0), .C_HAS_RST (1), .C_HAS_SRST (0), .C_DOUT_RST_VAL (0), .C_HAS_VALID (0), .C_VALID_LOW (C_VALID_LOW), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_HAS_WR_ACK (0), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_HAS_DATA_COUNT ((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_WRCH == 1) ? 1 : 0), .C_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_WRCH + 1), .C_HAS_RD_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WRCH == 1) ? 1 : 0), .C_RD_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_WRCH + 1), .C_USE_FWFT_DATA_COUNT (1), // use extra logic is always true .C_HAS_WR_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_WRCH == 1) ? 1 : 0), .C_WR_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_WRCH + 1), .C_FULL_FLAGS_RST_VAL (1), .C_USE_EMBEDDED_REG (0), .C_USE_DOUT_RST (0), .C_MSGON_VAL (C_MSGON_VAL), .C_ENABLE_RST_SYNC (1), .C_COUNT_TYPE (C_COUNT_TYPE), .C_DEFAULT_VALUE (C_DEFAULT_VALUE), .C_ENABLE_RLOCS (C_ENABLE_RLOCS), .C_HAS_BACKUP (C_HAS_BACKUP), .C_HAS_INT_CLK (C_HAS_INT_CLK), .C_MIF_FILE_NAME (C_MIF_FILE_NAME), .C_HAS_MEMINIT_FILE (C_HAS_MEMINIT_FILE), .C_INIT_WR_PNTR_VAL (C_INIT_WR_PNTR_VAL), .C_OPTIMIZATION_MODE (C_OPTIMIZATION_MODE), .C_PRIM_FIFO_TYPE (C_PRIM_FIFO_TYPE), .C_RD_FREQ (C_RD_FREQ), .C_USE_FIFO16_FLAGS (C_USE_FIFO16_FLAGS), .C_WR_FREQ (C_WR_FREQ), .C_WR_RESPONSE_LATENCY (C_WR_RESPONSE_LATENCY) ) fifo_generator_v12_0_wrch_dut ( .CLK (S_ACLK), .WR_CLK (M_ACLK), .RD_CLK (S_ACLK), .RST (inverted_reset), .SRST (1'b0), .WR_RST (inverted_reset), .RD_RST (inverted_reset), .WR_EN (wrch_wr_en), .RD_EN (wrch_rd_en), .PROG_FULL_THRESH (AXI_B_PROG_FULL_THRESH), .PROG_FULL_THRESH_ASSERT ({C_WR_PNTR_WIDTH_WRCH{1'b0}}), .PROG_FULL_THRESH_NEGATE ({C_WR_PNTR_WIDTH_WRCH{1'b0}}), .PROG_EMPTY_THRESH (AXI_B_PROG_EMPTY_THRESH), .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_WRCH{1'b0}}), .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_WRCH{1'b0}}), .INJECTDBITERR (AXI_B_INJECTDBITERR), .INJECTSBITERR (AXI_B_INJECTSBITERR), .DIN (wrch_din), .DOUT (wrch_dout), .FULL (wrch_full), .EMPTY (wrch_empty), .ALMOST_FULL (), .ALMOST_EMPTY (), .PROG_FULL (AXI_B_PROG_FULL), .PROG_EMPTY (AXI_B_PROG_EMPTY), .WR_ACK (), .OVERFLOW (axi_b_overflow_i), .VALID (), .UNDERFLOW (axi_b_underflow_i), .DATA_COUNT (AXI_B_DATA_COUNT), .RD_DATA_COUNT (AXI_B_RD_DATA_COUNT), .WR_DATA_COUNT (AXI_B_WR_DATA_COUNT), .SBITERR (AXI_B_SBITERR), .DBITERR (AXI_B_DBITERR), .wr_rst_busy (wr_rst_busy_wrch), .rd_rst_busy (rd_rst_busy_wrch), .wr_rst_i_out (), .rd_rst_i_out (), .BACKUP (BACKUP), .BACKUP_MARKER (BACKUP_MARKER), .INT_CLK (INT_CLK) ); assign wrch_s_axi_bvalid = ~wrch_empty; assign wrch_m_axi_bready = (IS_8SERIES == 0) ? ~wrch_full : (C_IMPLEMENTATION_TYPE_WRCH == 5 || C_IMPLEMENTATION_TYPE_WRCH == 13) ? ~(wrch_full | wr_rst_busy_wrch) : ~wrch_full; assign S_AXI_BVALID = wrch_s_axi_bvalid; assign M_AXI_BREADY = wrch_m_axi_bready; assign AXI_B_UNDERFLOW = C_USE_COMMON_UNDERFLOW == 0 ? axi_b_underflow_i : 0; assign AXI_B_OVERFLOW = C_USE_COMMON_OVERFLOW == 0 ? axi_b_overflow_i : 0; end endgenerate // axi_write_resp_channel // Register Slice for Write Response Channel generate if (C_WRCH_TYPE == 1) begin : gwrch_reg_slice fifo_generator_v12_0_axic_reg_slice #( .C_FAMILY (C_FAMILY), .C_DATA_WIDTH (C_DIN_WIDTH_WRCH), .C_REG_CONFIG (C_REG_SLICE_MODE_WRCH) ) wrch_reg_slice_inst ( // System Signals .ACLK (S_ACLK), .ARESET (axi_rs_rst), // Slave side .S_PAYLOAD_DATA (wrch_din), .S_VALID (M_AXI_BVALID), .S_READY (M_AXI_BREADY), // Master side .M_PAYLOAD_DATA (wrch_dout), .M_VALID (S_AXI_BVALID), .M_READY (S_AXI_BREADY) ); end endgenerate // gwrch_reg_slice assign axi_wr_underflow_i = C_USE_COMMON_UNDERFLOW == 1 ? (axi_aw_underflow_i || axi_w_underflow_i || axi_b_underflow_i) : 0; assign axi_wr_overflow_i = C_USE_COMMON_OVERFLOW == 1 ? (axi_aw_overflow_i || axi_w_overflow_i || axi_b_overflow_i) : 0; generate if (IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) begin : axi_wach_output assign M_AXI_AWADDR = wach_dout[AWID_OFFSET-1:AWADDR_OFFSET]; assign M_AXI_AWLEN = wach_dout[AWADDR_OFFSET-1:AWLEN_OFFSET]; assign M_AXI_AWSIZE = wach_dout[AWLEN_OFFSET-1:AWSIZE_OFFSET]; assign M_AXI_AWBURST = wach_dout[AWSIZE_OFFSET-1:AWBURST_OFFSET]; assign M_AXI_AWLOCK = wach_dout[AWBURST_OFFSET-1:AWLOCK_OFFSET]; assign M_AXI_AWCACHE = wach_dout[AWLOCK_OFFSET-1:AWCACHE_OFFSET]; assign M_AXI_AWPROT = wach_dout[AWCACHE_OFFSET-1:AWPROT_OFFSET]; assign M_AXI_AWQOS = wach_dout[AWPROT_OFFSET-1:AWQOS_OFFSET]; assign wach_din[AWID_OFFSET-1:AWADDR_OFFSET] = S_AXI_AWADDR; assign wach_din[AWADDR_OFFSET-1:AWLEN_OFFSET] = S_AXI_AWLEN; assign wach_din[AWLEN_OFFSET-1:AWSIZE_OFFSET] = S_AXI_AWSIZE; assign wach_din[AWSIZE_OFFSET-1:AWBURST_OFFSET] = S_AXI_AWBURST; assign wach_din[AWBURST_OFFSET-1:AWLOCK_OFFSET] = S_AXI_AWLOCK; assign wach_din[AWLOCK_OFFSET-1:AWCACHE_OFFSET] = S_AXI_AWCACHE; assign wach_din[AWCACHE_OFFSET-1:AWPROT_OFFSET] = S_AXI_AWPROT; assign wach_din[AWPROT_OFFSET-1:AWQOS_OFFSET] = S_AXI_AWQOS; end endgenerate // axi_wach_output generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_AXI_TYPE == 1) begin : axi_awregion assign M_AXI_AWREGION = wach_dout[AWQOS_OFFSET-1:AWREGION_OFFSET]; end endgenerate // axi_awregion generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_AXI_TYPE != 1) begin : naxi_awregion assign M_AXI_AWREGION = 0; end endgenerate // naxi_awregion generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_AWUSER == 1) begin : axi_awuser assign M_AXI_AWUSER = wach_dout[AWREGION_OFFSET-1:AWUSER_OFFSET]; end endgenerate // axi_awuser generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_AWUSER == 0) begin : naxi_awuser assign M_AXI_AWUSER = 0; end endgenerate // naxi_awuser generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : axi_awid assign M_AXI_AWID = wach_dout[C_DIN_WIDTH_WACH-1:AWID_OFFSET]; end endgenerate //axi_awid generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_ID == 0) begin : naxi_awid assign M_AXI_AWID = 0; end endgenerate //naxi_awid generate if (IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) begin : axi_wdch_output assign M_AXI_WDATA = wdch_dout[WID_OFFSET-1:WDATA_OFFSET]; assign M_AXI_WSTRB = wdch_dout[WDATA_OFFSET-1:WSTRB_OFFSET]; assign M_AXI_WLAST = wdch_dout[0]; assign wdch_din[WID_OFFSET-1:WDATA_OFFSET] = S_AXI_WDATA; assign wdch_din[WDATA_OFFSET-1:WSTRB_OFFSET] = S_AXI_WSTRB; assign wdch_din[0] = S_AXI_WLAST; end endgenerate // axi_wdch_output generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && C_HAS_AXI_ID == 1 && C_AXI_TYPE == 3) begin assign M_AXI_WID = wdch_dout[C_DIN_WIDTH_WDCH-1:WID_OFFSET]; end endgenerate generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && (C_HAS_AXI_ID == 0 || C_AXI_TYPE != 3)) begin assign M_AXI_WID = 0; end endgenerate generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && C_HAS_AXI_WUSER == 1 ) begin assign M_AXI_WUSER = wdch_dout[WSTRB_OFFSET-1:WUSER_OFFSET]; end endgenerate generate if (C_HAS_AXI_WUSER == 0) begin assign M_AXI_WUSER = 0; end endgenerate generate if (IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) begin : axi_wrch_output assign S_AXI_BRESP = wrch_dout[BID_OFFSET-1:BRESP_OFFSET]; assign wrch_din[BID_OFFSET-1:BRESP_OFFSET] = M_AXI_BRESP; end endgenerate // axi_wrch_output generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_BUSER == 1) begin : axi_buser assign S_AXI_BUSER = wrch_dout[BRESP_OFFSET-1:BUSER_OFFSET]; end endgenerate // axi_buser generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_BUSER == 0) begin : naxi_buser assign S_AXI_BUSER = 0; end endgenerate // naxi_buser generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : axi_bid assign S_AXI_BID = wrch_dout[C_DIN_WIDTH_WRCH-1:BID_OFFSET]; end endgenerate // axi_bid generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_ID == 0) begin : naxi_bid assign S_AXI_BID = 0 ; end endgenerate // naxi_bid generate if (IS_AXI_LITE_WACH == 1 || (IS_AXI_LITE == 1 && C_WACH_TYPE == 1)) begin : axi_wach_output1 assign wach_din = {S_AXI_AWADDR, S_AXI_AWPROT}; assign M_AXI_AWADDR = wach_dout[C_DIN_WIDTH_WACH-1:AWADDR_OFFSET]; assign M_AXI_AWPROT = wach_dout[AWADDR_OFFSET-1:AWPROT_OFFSET]; end endgenerate // axi_wach_output1 generate if (IS_AXI_LITE_WDCH == 1 || (IS_AXI_LITE == 1 && C_WDCH_TYPE == 1)) begin : axi_wdch_output1 assign wdch_din = {S_AXI_WDATA, S_AXI_WSTRB}; assign M_AXI_WDATA = wdch_dout[C_DIN_WIDTH_WDCH-1:WDATA_OFFSET]; assign M_AXI_WSTRB = wdch_dout[WDATA_OFFSET-1:WSTRB_OFFSET]; end endgenerate // axi_wdch_output1 generate if (IS_AXI_LITE_WRCH == 1 || (IS_AXI_LITE == 1 && C_WRCH_TYPE == 1)) begin : axi_wrch_output1 assign wrch_din = M_AXI_BRESP; assign S_AXI_BRESP = wrch_dout[C_DIN_WIDTH_WRCH-1:BRESP_OFFSET]; end endgenerate // axi_wrch_output1 generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_AWUSER == 1) begin : gwach_din1 assign wach_din[AWREGION_OFFSET-1:AWUSER_OFFSET] = S_AXI_AWUSER; end endgenerate // gwach_din1 generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : gwach_din2 assign wach_din[C_DIN_WIDTH_WACH-1:AWID_OFFSET] = S_AXI_AWID; end endgenerate // gwach_din2 generate if ((IS_AXI_FULL_WACH == 1 || (IS_AXI_FULL == 1 && C_WACH_TYPE == 1)) && C_AXI_TYPE == 1) begin : gwach_din3 assign wach_din[AWQOS_OFFSET-1:AWREGION_OFFSET] = S_AXI_AWREGION; end endgenerate // gwach_din3 generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && C_HAS_AXI_WUSER == 1) begin : gwdch_din1 assign wdch_din[WSTRB_OFFSET-1:WUSER_OFFSET] = S_AXI_WUSER; end endgenerate // gwdch_din1 generate if ((IS_AXI_FULL_WDCH == 1 || (IS_AXI_FULL == 1 && C_WDCH_TYPE == 1)) && C_HAS_AXI_ID == 1 && C_AXI_TYPE == 3) begin : gwdch_din2 assign wdch_din[C_DIN_WIDTH_WDCH-1:WID_OFFSET] = S_AXI_WID; end endgenerate // gwdch_din2 generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_BUSER == 1) begin : gwrch_din1 assign wrch_din[BRESP_OFFSET-1:BUSER_OFFSET] = M_AXI_BUSER; end endgenerate // gwrch_din1 generate if ((IS_AXI_FULL_WRCH == 1 || (IS_AXI_FULL == 1 && C_WRCH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : gwrch_din2 assign wrch_din[C_DIN_WIDTH_WRCH-1:BID_OFFSET] = M_AXI_BID; end endgenerate // gwrch_din2 //end of axi_write_channel //########################################################################### // AXI FULL Read Channel (axi_read_channel) //########################################################################### wire [C_DIN_WIDTH_RACH-1:0] rach_din ; wire [C_DIN_WIDTH_RACH-1:0] rach_dout ; wire [C_DIN_WIDTH_RACH-1:0] rach_dout_pkt ; wire rach_full ; wire rach_almost_full ; wire rach_prog_full ; wire rach_empty ; wire rach_almost_empty ; wire rach_prog_empty ; wire [C_DIN_WIDTH_RDCH-1:0] rdch_din ; wire [C_DIN_WIDTH_RDCH-1:0] rdch_dout ; wire rdch_full ; wire rdch_almost_full ; wire rdch_prog_full ; wire rdch_empty ; wire rdch_almost_empty ; wire rdch_prog_empty ; wire axi_ar_underflow_i ; wire axi_r_underflow_i ; wire axi_ar_overflow_i ; wire axi_r_overflow_i ; wire axi_rd_underflow_i ; wire axi_rd_overflow_i ; wire rach_s_axi_arready ; wire rach_m_axi_arvalid ; wire rach_wr_en ; wire rach_rd_en ; wire rdch_m_axi_rready ; wire rdch_s_axi_rvalid ; wire rdch_wr_en ; wire rdch_rd_en ; wire arvalid_pkt ; wire arready_pkt ; wire arvalid_en ; wire rdch_rd_ok ; wire accept_next_pkt ; integer rdch_free_space ; integer rdch_commited_space ; wire rach_we ; wire rach_re ; wire rdch_we ; wire rdch_re ; localparam ARID_OFFSET = (C_AXI_TYPE != 2 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_RACH - C_AXI_ID_WIDTH : C_DIN_WIDTH_RACH; localparam ARADDR_OFFSET = ARID_OFFSET - C_AXI_ADDR_WIDTH; localparam ARLEN_OFFSET = C_AXI_TYPE != 2 ? ARADDR_OFFSET - C_AXI_LEN_WIDTH : ARADDR_OFFSET; localparam ARSIZE_OFFSET = C_AXI_TYPE != 2 ? ARLEN_OFFSET - C_AXI_SIZE_WIDTH : ARLEN_OFFSET; localparam ARBURST_OFFSET = C_AXI_TYPE != 2 ? ARSIZE_OFFSET - C_AXI_BURST_WIDTH : ARSIZE_OFFSET; localparam ARLOCK_OFFSET = C_AXI_TYPE != 2 ? ARBURST_OFFSET - C_AXI_LOCK_WIDTH : ARBURST_OFFSET; localparam ARCACHE_OFFSET = C_AXI_TYPE != 2 ? ARLOCK_OFFSET - C_AXI_CACHE_WIDTH : ARLOCK_OFFSET; localparam ARPROT_OFFSET = ARCACHE_OFFSET - C_AXI_PROT_WIDTH; localparam ARQOS_OFFSET = ARPROT_OFFSET - C_AXI_QOS_WIDTH; localparam ARREGION_OFFSET = C_AXI_TYPE == 1 ? ARQOS_OFFSET - C_AXI_REGION_WIDTH : ARQOS_OFFSET; localparam ARUSER_OFFSET = C_HAS_AXI_ARUSER == 1 ? ARREGION_OFFSET-C_AXI_ARUSER_WIDTH : ARREGION_OFFSET; localparam RID_OFFSET = (C_AXI_TYPE != 2 && C_HAS_AXI_ID == 1) ? C_DIN_WIDTH_RDCH - C_AXI_ID_WIDTH : C_DIN_WIDTH_RDCH; localparam RDATA_OFFSET = RID_OFFSET - C_AXI_DATA_WIDTH; localparam RRESP_OFFSET = RDATA_OFFSET - C_AXI_RRESP_WIDTH; localparam RUSER_OFFSET = C_HAS_AXI_RUSER == 1 ? RRESP_OFFSET-C_AXI_RUSER_WIDTH : RRESP_OFFSET; generate if (IS_RD_ADDR_CH == 1) begin : axi_read_addr_channel // Write protection when almost full or prog_full is high assign rach_we = (C_PROG_FULL_TYPE_RACH != 0) ? rach_s_axi_arready & S_AXI_ARVALID : S_AXI_ARVALID; // Read protection when almost empty or prog_empty is high // assign rach_rd_en = (C_PROG_EMPTY_TYPE_RACH != 5) ? rach_m_axi_arvalid & M_AXI_ARREADY : M_AXI_ARREADY && arvalid_en; assign rach_re = (C_PROG_EMPTY_TYPE_RACH != 0 && C_APPLICATION_TYPE_RACH == 1) ? rach_m_axi_arvalid & arready_pkt & arvalid_en : (C_PROG_EMPTY_TYPE_RACH != 0 && C_APPLICATION_TYPE_RACH != 1) ? M_AXI_ARREADY && rach_m_axi_arvalid : (C_PROG_EMPTY_TYPE_RACH == 0 && C_APPLICATION_TYPE_RACH == 1) ? arready_pkt & arvalid_en : (C_PROG_EMPTY_TYPE_RACH == 0 && C_APPLICATION_TYPE_RACH != 1) ? M_AXI_ARREADY : 1'b0; assign rach_wr_en = (C_HAS_SLAVE_CE == 1) ? rach_we & S_ACLK_EN : rach_we; assign rach_rd_en = (C_HAS_MASTER_CE == 1) ? rach_re & M_ACLK_EN : rach_re; FIFO_GENERATOR_v12_0_CONV_VER #( .C_FAMILY (C_FAMILY), .C_COMMON_CLOCK (C_COMMON_CLOCK), .C_MEMORY_TYPE ((C_IMPLEMENTATION_TYPE_RACH == 1 || C_IMPLEMENTATION_TYPE_RACH == 11) ? 1 : (C_IMPLEMENTATION_TYPE_RACH == 2 || C_IMPLEMENTATION_TYPE_RACH == 12) ? 2 : 4), .C_IMPLEMENTATION_TYPE ((C_IMPLEMENTATION_TYPE_RACH == 1 || C_IMPLEMENTATION_TYPE_RACH == 2) ? 0 : (C_IMPLEMENTATION_TYPE_RACH == 11 || C_IMPLEMENTATION_TYPE_RACH == 12) ? 2 : 6), .C_PRELOAD_REGS (1), // always FWFT for AXI .C_PRELOAD_LATENCY (0), // always FWFT for AXI .C_DIN_WIDTH (C_DIN_WIDTH_RACH), .C_WR_DEPTH (C_WR_DEPTH_RACH), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH_RACH), .C_DOUT_WIDTH (C_DIN_WIDTH_RACH), .C_RD_DEPTH (C_WR_DEPTH_RACH), .C_RD_PNTR_WIDTH (C_WR_PNTR_WIDTH_RACH), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE_RACH), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL_RACH), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE_RACH), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL_RACH), .C_USE_ECC (C_USE_ECC_RACH), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE_RACH), .C_HAS_ALMOST_EMPTY (0), .C_HAS_ALMOST_FULL (0), .C_AXI_TYPE (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE), .C_FIFO_TYPE ((C_APPLICATION_TYPE_RACH == 1)?0:C_APPLICATION_TYPE_RACH), .C_SYNCHRONIZER_STAGE (C_SYNCHRONIZER_STAGE), .C_HAS_WR_RST (0), .C_HAS_RD_RST (0), .C_HAS_RST (1), .C_HAS_SRST (0), .C_DOUT_RST_VAL (0), .C_HAS_VALID (0), .C_VALID_LOW (C_VALID_LOW), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_HAS_WR_ACK (0), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_HAS_DATA_COUNT ((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_RACH == 1) ? 1 : 0), .C_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_RACH + 1), .C_HAS_RD_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_RACH == 1) ? 1 : 0), .C_RD_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_RACH + 1), .C_USE_FWFT_DATA_COUNT (1), // use extra logic is always true .C_HAS_WR_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_RACH == 1) ? 1 : 0), .C_WR_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_RACH + 1), .C_FULL_FLAGS_RST_VAL (1), .C_USE_EMBEDDED_REG (0), .C_USE_DOUT_RST (0), .C_MSGON_VAL (C_MSGON_VAL), .C_ENABLE_RST_SYNC (1), .C_COUNT_TYPE (C_COUNT_TYPE), .C_DEFAULT_VALUE (C_DEFAULT_VALUE), .C_ENABLE_RLOCS (C_ENABLE_RLOCS), .C_HAS_BACKUP (C_HAS_BACKUP), .C_HAS_INT_CLK (C_HAS_INT_CLK), .C_MIF_FILE_NAME (C_MIF_FILE_NAME), .C_HAS_MEMINIT_FILE (C_HAS_MEMINIT_FILE), .C_INIT_WR_PNTR_VAL (C_INIT_WR_PNTR_VAL), .C_OPTIMIZATION_MODE (C_OPTIMIZATION_MODE), .C_PRIM_FIFO_TYPE (C_PRIM_FIFO_TYPE), .C_RD_FREQ (C_RD_FREQ), .C_USE_FIFO16_FLAGS (C_USE_FIFO16_FLAGS), .C_WR_FREQ (C_WR_FREQ), .C_WR_RESPONSE_LATENCY (C_WR_RESPONSE_LATENCY) ) fifo_generator_v12_0_rach_dut ( .CLK (S_ACLK), .WR_CLK (S_ACLK), .RD_CLK (M_ACLK), .RST (inverted_reset), .SRST (1'b0), .WR_RST (inverted_reset), .RD_RST (inverted_reset), .WR_EN (rach_wr_en), .RD_EN (rach_rd_en), .PROG_FULL_THRESH (AXI_AR_PROG_FULL_THRESH), .PROG_FULL_THRESH_ASSERT ({C_WR_PNTR_WIDTH_RACH{1'b0}}), .PROG_FULL_THRESH_NEGATE ({C_WR_PNTR_WIDTH_RACH{1'b0}}), .PROG_EMPTY_THRESH (AXI_AR_PROG_EMPTY_THRESH), .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_RACH{1'b0}}), .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_RACH{1'b0}}), .INJECTDBITERR (AXI_AR_INJECTDBITERR), .INJECTSBITERR (AXI_AR_INJECTSBITERR), .DIN (rach_din), .DOUT (rach_dout_pkt), .FULL (rach_full), .EMPTY (rach_empty), .ALMOST_FULL (), .ALMOST_EMPTY (), .PROG_FULL (AXI_AR_PROG_FULL), .PROG_EMPTY (AXI_AR_PROG_EMPTY), .WR_ACK (), .OVERFLOW (axi_ar_overflow_i), .VALID (), .UNDERFLOW (axi_ar_underflow_i), .DATA_COUNT (AXI_AR_DATA_COUNT), .RD_DATA_COUNT (AXI_AR_RD_DATA_COUNT), .WR_DATA_COUNT (AXI_AR_WR_DATA_COUNT), .SBITERR (AXI_AR_SBITERR), .DBITERR (AXI_AR_DBITERR), .wr_rst_busy (wr_rst_busy_rach), .rd_rst_busy (rd_rst_busy_rach), .wr_rst_i_out (), .rd_rst_i_out (), .BACKUP (BACKUP), .BACKUP_MARKER (BACKUP_MARKER), .INT_CLK (INT_CLK) ); assign rach_s_axi_arready = (IS_8SERIES == 0) ? ~rach_full : (C_IMPLEMENTATION_TYPE_RACH == 5 || C_IMPLEMENTATION_TYPE_RACH == 13) ? ~(rach_full | wr_rst_busy_rach) : ~rach_full; assign rach_m_axi_arvalid = ~rach_empty; assign S_AXI_ARREADY = rach_s_axi_arready; assign AXI_AR_UNDERFLOW = C_USE_COMMON_UNDERFLOW == 0 ? axi_ar_underflow_i : 0; assign AXI_AR_OVERFLOW = C_USE_COMMON_OVERFLOW == 0 ? axi_ar_overflow_i : 0; end endgenerate // axi_read_addr_channel // Register Slice for Read Address Channel generate if (C_RACH_TYPE == 1) begin : grach_reg_slice fifo_generator_v12_0_axic_reg_slice #( .C_FAMILY (C_FAMILY), .C_DATA_WIDTH (C_DIN_WIDTH_RACH), .C_REG_CONFIG (C_REG_SLICE_MODE_RACH) ) rach_reg_slice_inst ( // System Signals .ACLK (S_ACLK), .ARESET (axi_rs_rst), // Slave side .S_PAYLOAD_DATA (rach_din), .S_VALID (S_AXI_ARVALID), .S_READY (S_AXI_ARREADY), // Master side .M_PAYLOAD_DATA (rach_dout), .M_VALID (M_AXI_ARVALID), .M_READY (M_AXI_ARREADY) ); end endgenerate // grach_reg_slice // Register Slice for Read Address Channel for MM Packet FIFO generate if (C_RACH_TYPE == 0 && C_APPLICATION_TYPE_RACH == 1) begin : grach_reg_slice_mm_pkt_fifo fifo_generator_v12_0_axic_reg_slice #( .C_FAMILY (C_FAMILY), .C_DATA_WIDTH (C_DIN_WIDTH_RACH), .C_REG_CONFIG (1) ) reg_slice_mm_pkt_fifo_inst ( // System Signals .ACLK (S_ACLK), .ARESET (inverted_reset), // Slave side .S_PAYLOAD_DATA (rach_dout_pkt), .S_VALID (arvalid_pkt), .S_READY (arready_pkt), // Master side .M_PAYLOAD_DATA (rach_dout), .M_VALID (M_AXI_ARVALID), .M_READY (M_AXI_ARREADY) ); end endgenerate // grach_reg_slice_mm_pkt_fifo generate if (C_RACH_TYPE == 0 && C_APPLICATION_TYPE_RACH != 1) begin : grach_m_axi_arvalid assign M_AXI_ARVALID = rach_m_axi_arvalid; assign rach_dout = rach_dout_pkt; end endgenerate // grach_m_axi_arvalid generate if (C_APPLICATION_TYPE_RACH == 1 && C_HAS_AXI_RD_CHANNEL == 1) begin : axi_mm_pkt_fifo_rd assign rdch_rd_ok = rdch_s_axi_rvalid && rdch_rd_en; assign arvalid_pkt = rach_m_axi_arvalid && arvalid_en; assign accept_next_pkt = rach_m_axi_arvalid && arready_pkt && arvalid_en; always@(posedge S_ACLK or posedge inverted_reset) begin if(inverted_reset) begin rdch_commited_space <= 0; end else begin if(rdch_rd_ok && !accept_next_pkt) begin rdch_commited_space <= rdch_commited_space-1; end else if(!rdch_rd_ok && accept_next_pkt) begin rdch_commited_space <= rdch_commited_space+(rach_dout_pkt[ARADDR_OFFSET-1:ARLEN_OFFSET]+1); end else if(rdch_rd_ok && accept_next_pkt) begin rdch_commited_space <= rdch_commited_space+(rach_dout_pkt[ARADDR_OFFSET-1:ARLEN_OFFSET]); end end end //Always end always@(*) begin rdch_free_space <= (C_WR_DEPTH_RDCH-(rdch_commited_space+rach_dout_pkt[ARADDR_OFFSET-1:ARLEN_OFFSET]+1)); end assign arvalid_en = (rdch_free_space >= 0)?1:0; end endgenerate generate if (C_APPLICATION_TYPE_RACH != 1) begin : axi_mm_fifo_rd assign arvalid_en = 1; end endgenerate generate if (IS_RD_DATA_CH == 1) begin : axi_read_data_channel // Write protection when almost full or prog_full is high assign rdch_we = (C_PROG_FULL_TYPE_RDCH != 0) ? rdch_m_axi_rready & M_AXI_RVALID : M_AXI_RVALID; // Read protection when almost empty or prog_empty is high assign rdch_re = (C_PROG_EMPTY_TYPE_RDCH != 0) ? rdch_s_axi_rvalid & S_AXI_RREADY : S_AXI_RREADY; assign rdch_wr_en = (C_HAS_SLAVE_CE == 1) ? rdch_we & S_ACLK_EN : rdch_we; assign rdch_rd_en = (C_HAS_MASTER_CE == 1) ? rdch_re & M_ACLK_EN : rdch_re; FIFO_GENERATOR_v12_0_CONV_VER #( .C_FAMILY (C_FAMILY), .C_COMMON_CLOCK (C_COMMON_CLOCK), .C_MEMORY_TYPE ((C_IMPLEMENTATION_TYPE_RDCH == 1 || C_IMPLEMENTATION_TYPE_RDCH == 11) ? 1 : (C_IMPLEMENTATION_TYPE_RDCH == 2 || C_IMPLEMENTATION_TYPE_RDCH == 12) ? 2 : 4), .C_IMPLEMENTATION_TYPE ((C_IMPLEMENTATION_TYPE_RDCH == 1 || C_IMPLEMENTATION_TYPE_RDCH == 2) ? 0 : (C_IMPLEMENTATION_TYPE_RDCH == 11 || C_IMPLEMENTATION_TYPE_RDCH == 12) ? 2 : 6), .C_PRELOAD_REGS (1), // always FWFT for AXI .C_PRELOAD_LATENCY (0), // always FWFT for AXI .C_DIN_WIDTH (C_DIN_WIDTH_RDCH), .C_WR_DEPTH (C_WR_DEPTH_RDCH), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH_RDCH), .C_DOUT_WIDTH (C_DIN_WIDTH_RDCH), .C_RD_DEPTH (C_WR_DEPTH_RDCH), .C_RD_PNTR_WIDTH (C_WR_PNTR_WIDTH_RDCH), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE_RDCH), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL_RDCH), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE_RDCH), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL_RDCH), .C_USE_ECC (C_USE_ECC_RDCH), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE_RDCH), .C_HAS_ALMOST_EMPTY (0), .C_HAS_ALMOST_FULL (0), .C_AXI_TYPE (C_INTERFACE_TYPE == 1 ? 0 : C_AXI_TYPE), .C_FIFO_TYPE (C_APPLICATION_TYPE_RDCH), .C_SYNCHRONIZER_STAGE (C_SYNCHRONIZER_STAGE), .C_HAS_WR_RST (0), .C_HAS_RD_RST (0), .C_HAS_RST (1), .C_HAS_SRST (0), .C_DOUT_RST_VAL (0), .C_HAS_VALID (0), .C_VALID_LOW (C_VALID_LOW), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_HAS_WR_ACK (0), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_HAS_DATA_COUNT ((C_COMMON_CLOCK == 1 && C_HAS_DATA_COUNTS_RDCH == 1) ? 1 : 0), .C_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_RDCH + 1), .C_HAS_RD_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_RDCH == 1) ? 1 : 0), .C_RD_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_RDCH + 1), .C_USE_FWFT_DATA_COUNT (1), // use extra logic is always true .C_HAS_WR_DATA_COUNT ((C_COMMON_CLOCK == 0 && C_HAS_DATA_COUNTS_RDCH == 1) ? 1 : 0), .C_WR_DATA_COUNT_WIDTH (C_WR_PNTR_WIDTH_RDCH + 1), .C_FULL_FLAGS_RST_VAL (1), .C_USE_EMBEDDED_REG (0), .C_USE_DOUT_RST (0), .C_MSGON_VAL (C_MSGON_VAL), .C_ENABLE_RST_SYNC (1), .C_COUNT_TYPE (C_COUNT_TYPE), .C_DEFAULT_VALUE (C_DEFAULT_VALUE), .C_ENABLE_RLOCS (C_ENABLE_RLOCS), .C_HAS_BACKUP (C_HAS_BACKUP), .C_HAS_INT_CLK (C_HAS_INT_CLK), .C_MIF_FILE_NAME (C_MIF_FILE_NAME), .C_HAS_MEMINIT_FILE (C_HAS_MEMINIT_FILE), .C_INIT_WR_PNTR_VAL (C_INIT_WR_PNTR_VAL), .C_OPTIMIZATION_MODE (C_OPTIMIZATION_MODE), .C_PRIM_FIFO_TYPE (C_PRIM_FIFO_TYPE), .C_RD_FREQ (C_RD_FREQ), .C_USE_FIFO16_FLAGS (C_USE_FIFO16_FLAGS), .C_WR_FREQ (C_WR_FREQ), .C_WR_RESPONSE_LATENCY (C_WR_RESPONSE_LATENCY) ) fifo_generator_v12_0_rdch_dut ( .CLK (S_ACLK), .WR_CLK (M_ACLK), .RD_CLK (S_ACLK), .RST (inverted_reset), .SRST (1'b0), .WR_RST (inverted_reset), .RD_RST (inverted_reset), .WR_EN (rdch_wr_en), .RD_EN (rdch_rd_en), .PROG_FULL_THRESH (AXI_R_PROG_FULL_THRESH), .PROG_FULL_THRESH_ASSERT ({C_WR_PNTR_WIDTH_RDCH{1'b0}}), .PROG_FULL_THRESH_NEGATE ({C_WR_PNTR_WIDTH_RDCH{1'b0}}), .PROG_EMPTY_THRESH (AXI_R_PROG_EMPTY_THRESH), .PROG_EMPTY_THRESH_ASSERT ({C_WR_PNTR_WIDTH_RDCH{1'b0}}), .PROG_EMPTY_THRESH_NEGATE ({C_WR_PNTR_WIDTH_RDCH{1'b0}}), .INJECTDBITERR (AXI_R_INJECTDBITERR), .INJECTSBITERR (AXI_R_INJECTSBITERR), .DIN (rdch_din), .DOUT (rdch_dout), .FULL (rdch_full), .EMPTY (rdch_empty), .ALMOST_FULL (), .ALMOST_EMPTY (), .PROG_FULL (AXI_R_PROG_FULL), .PROG_EMPTY (AXI_R_PROG_EMPTY), .WR_ACK (), .OVERFLOW (axi_r_overflow_i), .VALID (), .UNDERFLOW (axi_r_underflow_i), .DATA_COUNT (AXI_R_DATA_COUNT), .RD_DATA_COUNT (AXI_R_RD_DATA_COUNT), .WR_DATA_COUNT (AXI_R_WR_DATA_COUNT), .SBITERR (AXI_R_SBITERR), .DBITERR (AXI_R_DBITERR), .wr_rst_busy (wr_rst_busy_rdch), .rd_rst_busy (rd_rst_busy_rdch), .wr_rst_i_out (), .rd_rst_i_out (), .BACKUP (BACKUP), .BACKUP_MARKER (BACKUP_MARKER), .INT_CLK (INT_CLK) ); assign rdch_s_axi_rvalid = ~rdch_empty; assign rdch_m_axi_rready = (IS_8SERIES == 0) ? ~rdch_full : (C_IMPLEMENTATION_TYPE_RDCH == 5 || C_IMPLEMENTATION_TYPE_RDCH == 13) ? ~(rdch_full | wr_rst_busy_rdch) : ~rdch_full; assign S_AXI_RVALID = rdch_s_axi_rvalid; assign M_AXI_RREADY = rdch_m_axi_rready; assign AXI_R_UNDERFLOW = C_USE_COMMON_UNDERFLOW == 0 ? axi_r_underflow_i : 0; assign AXI_R_OVERFLOW = C_USE_COMMON_OVERFLOW == 0 ? axi_r_overflow_i : 0; end endgenerate //axi_read_data_channel // Register Slice for read Data Channel generate if (C_RDCH_TYPE == 1) begin : grdch_reg_slice fifo_generator_v12_0_axic_reg_slice #( .C_FAMILY (C_FAMILY), .C_DATA_WIDTH (C_DIN_WIDTH_RDCH), .C_REG_CONFIG (C_REG_SLICE_MODE_RDCH) ) rdch_reg_slice_inst ( // System Signals .ACLK (S_ACLK), .ARESET (axi_rs_rst), // Slave side .S_PAYLOAD_DATA (rdch_din), .S_VALID (M_AXI_RVALID), .S_READY (M_AXI_RREADY), // Master side .M_PAYLOAD_DATA (rdch_dout), .M_VALID (S_AXI_RVALID), .M_READY (S_AXI_RREADY) ); end endgenerate // grdch_reg_slice assign axi_rd_underflow_i = C_USE_COMMON_UNDERFLOW == 1 ? (axi_ar_underflow_i || axi_r_underflow_i) : 0; assign axi_rd_overflow_i = C_USE_COMMON_OVERFLOW == 1 ? (axi_ar_overflow_i || axi_r_overflow_i) : 0; generate if (IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) begin : axi_full_rach_output assign M_AXI_ARADDR = rach_dout[ARID_OFFSET-1:ARADDR_OFFSET]; assign M_AXI_ARLEN = rach_dout[ARADDR_OFFSET-1:ARLEN_OFFSET]; assign M_AXI_ARSIZE = rach_dout[ARLEN_OFFSET-1:ARSIZE_OFFSET]; assign M_AXI_ARBURST = rach_dout[ARSIZE_OFFSET-1:ARBURST_OFFSET]; assign M_AXI_ARLOCK = rach_dout[ARBURST_OFFSET-1:ARLOCK_OFFSET]; assign M_AXI_ARCACHE = rach_dout[ARLOCK_OFFSET-1:ARCACHE_OFFSET]; assign M_AXI_ARPROT = rach_dout[ARCACHE_OFFSET-1:ARPROT_OFFSET]; assign M_AXI_ARQOS = rach_dout[ARPROT_OFFSET-1:ARQOS_OFFSET]; assign rach_din[ARID_OFFSET-1:ARADDR_OFFSET] = S_AXI_ARADDR; assign rach_din[ARADDR_OFFSET-1:ARLEN_OFFSET] = S_AXI_ARLEN; assign rach_din[ARLEN_OFFSET-1:ARSIZE_OFFSET] = S_AXI_ARSIZE; assign rach_din[ARSIZE_OFFSET-1:ARBURST_OFFSET] = S_AXI_ARBURST; assign rach_din[ARBURST_OFFSET-1:ARLOCK_OFFSET] = S_AXI_ARLOCK; assign rach_din[ARLOCK_OFFSET-1:ARCACHE_OFFSET] = S_AXI_ARCACHE; assign rach_din[ARCACHE_OFFSET-1:ARPROT_OFFSET] = S_AXI_ARPROT; assign rach_din[ARPROT_OFFSET-1:ARQOS_OFFSET] = S_AXI_ARQOS; end endgenerate // axi_full_rach_output generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_AXI_TYPE == 1) begin : axi_arregion assign M_AXI_ARREGION = rach_dout[ARQOS_OFFSET-1:ARREGION_OFFSET]; end endgenerate // axi_arregion generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_AXI_TYPE != 1) begin : naxi_arregion assign M_AXI_ARREGION = 0; end endgenerate // naxi_arregion generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ARUSER == 1) begin : axi_aruser assign M_AXI_ARUSER = rach_dout[ARREGION_OFFSET-1:ARUSER_OFFSET]; end endgenerate // axi_aruser generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ARUSER == 0) begin : naxi_aruser assign M_AXI_ARUSER = 0; end endgenerate // naxi_aruser generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : axi_arid assign M_AXI_ARID = rach_dout[C_DIN_WIDTH_RACH-1:ARID_OFFSET]; end endgenerate // axi_arid generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ID == 0) begin : naxi_arid assign M_AXI_ARID = 0; end endgenerate // naxi_arid generate if (IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) begin : axi_full_rdch_output assign S_AXI_RDATA = rdch_dout[RID_OFFSET-1:RDATA_OFFSET]; assign S_AXI_RRESP = rdch_dout[RDATA_OFFSET-1:RRESP_OFFSET]; assign S_AXI_RLAST = rdch_dout[0]; assign rdch_din[RID_OFFSET-1:RDATA_OFFSET] = M_AXI_RDATA; assign rdch_din[RDATA_OFFSET-1:RRESP_OFFSET] = M_AXI_RRESP; assign rdch_din[0] = M_AXI_RLAST; end endgenerate // axi_full_rdch_output generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_RUSER == 1) begin : axi_full_ruser_output assign S_AXI_RUSER = rdch_dout[RRESP_OFFSET-1:RUSER_OFFSET]; end endgenerate // axi_full_ruser_output generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_RUSER == 0) begin : axi_full_nruser_output assign S_AXI_RUSER = 0; end endgenerate // axi_full_nruser_output generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : axi_rid assign S_AXI_RID = rdch_dout[C_DIN_WIDTH_RDCH-1:RID_OFFSET]; end endgenerate // axi_rid generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_ID == 0) begin : naxi_rid assign S_AXI_RID = 0; end endgenerate // naxi_rid generate if (IS_AXI_LITE_RACH == 1 || (IS_AXI_LITE == 1 && C_RACH_TYPE == 1)) begin : axi_lite_rach_output1 assign rach_din = {S_AXI_ARADDR, S_AXI_ARPROT}; assign M_AXI_ARADDR = rach_dout[C_DIN_WIDTH_RACH-1:ARADDR_OFFSET]; assign M_AXI_ARPROT = rach_dout[ARADDR_OFFSET-1:ARPROT_OFFSET]; end endgenerate // axi_lite_rach_output generate if (IS_AXI_LITE_RDCH == 1 || (IS_AXI_LITE == 1 && C_RDCH_TYPE == 1)) begin : axi_lite_rdch_output1 assign rdch_din = {M_AXI_RDATA, M_AXI_RRESP}; assign S_AXI_RDATA = rdch_dout[C_DIN_WIDTH_RDCH-1:RDATA_OFFSET]; assign S_AXI_RRESP = rdch_dout[RDATA_OFFSET-1:RRESP_OFFSET]; end endgenerate // axi_lite_rdch_output generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ARUSER == 1) begin : grach_din1 assign rach_din[ARREGION_OFFSET-1:ARUSER_OFFSET] = S_AXI_ARUSER; end endgenerate // grach_din1 generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : grach_din2 assign rach_din[C_DIN_WIDTH_RACH-1:ARID_OFFSET] = S_AXI_ARID; end endgenerate // grach_din2 generate if ((IS_AXI_FULL_RACH == 1 || (IS_AXI_FULL == 1 && C_RACH_TYPE == 1)) && C_AXI_TYPE == 1) begin assign rach_din[ARQOS_OFFSET-1:ARREGION_OFFSET] = S_AXI_ARREGION; end endgenerate generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_RUSER == 1) begin : grdch_din1 assign rdch_din[RRESP_OFFSET-1:RUSER_OFFSET] = M_AXI_RUSER; end endgenerate // grdch_din1 generate if ((IS_AXI_FULL_RDCH == 1 || (IS_AXI_FULL == 1 && C_RDCH_TYPE == 1)) && C_HAS_AXI_ID == 1) begin : grdch_din2 assign rdch_din[C_DIN_WIDTH_RDCH-1:RID_OFFSET] = M_AXI_RID; end endgenerate // grdch_din2 //end of axi_read_channel generate if (C_INTERFACE_TYPE == 1 && C_USE_COMMON_UNDERFLOW == 1) begin : gaxi_comm_uf assign UNDERFLOW = (C_HAS_AXI_WR_CHANNEL == 1 && C_HAS_AXI_RD_CHANNEL == 1) ? (axi_wr_underflow_i || axi_rd_underflow_i) : (C_HAS_AXI_WR_CHANNEL == 1 && C_HAS_AXI_RD_CHANNEL == 0) ? axi_wr_underflow_i : (C_HAS_AXI_WR_CHANNEL == 0 && C_HAS_AXI_RD_CHANNEL == 1) ? axi_rd_underflow_i : 0; end endgenerate // gaxi_comm_uf generate if (C_INTERFACE_TYPE == 1 && C_USE_COMMON_OVERFLOW == 1) begin : gaxi_comm_of assign OVERFLOW = (C_HAS_AXI_WR_CHANNEL == 1 && C_HAS_AXI_RD_CHANNEL == 1) ? (axi_wr_overflow_i || axi_rd_overflow_i) : (C_HAS_AXI_WR_CHANNEL == 1 && C_HAS_AXI_RD_CHANNEL == 0) ? axi_wr_overflow_i : (C_HAS_AXI_WR_CHANNEL == 0 && C_HAS_AXI_RD_CHANNEL == 1) ? axi_rd_overflow_i : 0; end endgenerate // gaxi_comm_of //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- // Pass Through Logic or Wiring Logic //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- //------------------------------------------------------------------------- // Pass Through Logic for Read Channel //------------------------------------------------------------------------- // Wiring logic for Write Address Channel generate if (C_WACH_TYPE == 2) begin : gwach_pass_through assign M_AXI_AWID = S_AXI_AWID; assign M_AXI_AWADDR = S_AXI_AWADDR; assign M_AXI_AWLEN = S_AXI_AWLEN; assign M_AXI_AWSIZE = S_AXI_AWSIZE; assign M_AXI_AWBURST = S_AXI_AWBURST; assign M_AXI_AWLOCK = S_AXI_AWLOCK; assign M_AXI_AWCACHE = S_AXI_AWCACHE; assign M_AXI_AWPROT = S_AXI_AWPROT; assign M_AXI_AWQOS = S_AXI_AWQOS; assign M_AXI_AWREGION = S_AXI_AWREGION; assign M_AXI_AWUSER = S_AXI_AWUSER; assign S_AXI_AWREADY = M_AXI_AWREADY; assign M_AXI_AWVALID = S_AXI_AWVALID; end endgenerate // gwach_pass_through; // Wiring logic for Write Data Channel generate if (C_WDCH_TYPE == 2) begin : gwdch_pass_through assign M_AXI_WID = S_AXI_WID; assign M_AXI_WDATA = S_AXI_WDATA; assign M_AXI_WSTRB = S_AXI_WSTRB; assign M_AXI_WLAST = S_AXI_WLAST; assign M_AXI_WUSER = S_AXI_WUSER; assign S_AXI_WREADY = M_AXI_WREADY; assign M_AXI_WVALID = S_AXI_WVALID; end endgenerate // gwdch_pass_through; // Wiring logic for Write Response Channel generate if (C_WRCH_TYPE == 2) begin : gwrch_pass_through assign S_AXI_BID = M_AXI_BID; assign S_AXI_BRESP = M_AXI_BRESP; assign S_AXI_BUSER = M_AXI_BUSER; assign M_AXI_BREADY = S_AXI_BREADY; assign S_AXI_BVALID = M_AXI_BVALID; end endgenerate // gwrch_pass_through; //------------------------------------------------------------------------- // Pass Through Logic for Read Channel //------------------------------------------------------------------------- // Wiring logic for Read Address Channel generate if (C_RACH_TYPE == 2) begin : grach_pass_through assign M_AXI_ARID = S_AXI_ARID; assign M_AXI_ARADDR = S_AXI_ARADDR; assign M_AXI_ARLEN = S_AXI_ARLEN; assign M_AXI_ARSIZE = S_AXI_ARSIZE; assign M_AXI_ARBURST = S_AXI_ARBURST; assign M_AXI_ARLOCK = S_AXI_ARLOCK; assign M_AXI_ARCACHE = S_AXI_ARCACHE; assign M_AXI_ARPROT = S_AXI_ARPROT; assign M_AXI_ARQOS = S_AXI_ARQOS; assign M_AXI_ARREGION = S_AXI_ARREGION; assign M_AXI_ARUSER = S_AXI_ARUSER; assign S_AXI_ARREADY = M_AXI_ARREADY; assign M_AXI_ARVALID = S_AXI_ARVALID; end endgenerate // grach_pass_through; // Wiring logic for Read Data Channel generate if (C_RDCH_TYPE == 2) begin : grdch_pass_through assign S_AXI_RID = M_AXI_RID; assign S_AXI_RLAST = M_AXI_RLAST; assign S_AXI_RUSER = M_AXI_RUSER; assign S_AXI_RDATA = M_AXI_RDATA; assign S_AXI_RRESP = M_AXI_RRESP; assign S_AXI_RVALID = M_AXI_RVALID; assign M_AXI_RREADY = S_AXI_RREADY; end endgenerate // grdch_pass_through; // Wiring logic for AXI Streaming generate if (C_AXIS_TYPE == 2) begin : gaxis_pass_through assign M_AXIS_TDATA = S_AXIS_TDATA; assign M_AXIS_TSTRB = S_AXIS_TSTRB; assign M_AXIS_TKEEP = S_AXIS_TKEEP; assign M_AXIS_TID = S_AXIS_TID; assign M_AXIS_TDEST = S_AXIS_TDEST; assign M_AXIS_TUSER = S_AXIS_TUSER; assign M_AXIS_TLAST = S_AXIS_TLAST; assign S_AXIS_TREADY = M_AXIS_TREADY; assign M_AXIS_TVALID = S_AXIS_TVALID; end endgenerate // gaxis_pass_through; endmodule //FIFO_GENERATOR_v12_0 /******************************************************************************* * Declaration of top-level module for Conventional FIFO ******************************************************************************/ module FIFO_GENERATOR_v12_0_CONV_VER #( parameter C_COMMON_CLOCK = 0, parameter C_COUNT_TYPE = 0, parameter C_DATA_COUNT_WIDTH = 2, parameter C_DEFAULT_VALUE = "", parameter C_DIN_WIDTH = 8, parameter C_DOUT_RST_VAL = "", parameter C_DOUT_WIDTH = 8, parameter C_ENABLE_RLOCS = 0, parameter C_FAMILY = "virtex7", //Not allowed in Verilog model parameter C_FULL_FLAGS_RST_VAL = 1, parameter C_HAS_ALMOST_EMPTY = 0, parameter C_HAS_ALMOST_FULL = 0, parameter C_HAS_BACKUP = 0, parameter C_HAS_DATA_COUNT = 0, parameter C_HAS_INT_CLK = 0, parameter C_HAS_MEMINIT_FILE = 0, parameter C_HAS_OVERFLOW = 0, parameter C_HAS_RD_DATA_COUNT = 0, parameter C_HAS_RD_RST = 0, parameter C_HAS_RST = 0, parameter C_HAS_SRST = 0, parameter C_HAS_UNDERFLOW = 0, parameter C_HAS_VALID = 0, parameter C_HAS_WR_ACK = 0, parameter C_HAS_WR_DATA_COUNT = 0, parameter C_HAS_WR_RST = 0, parameter C_IMPLEMENTATION_TYPE = 0, parameter C_INIT_WR_PNTR_VAL = 0, parameter C_MEMORY_TYPE = 1, parameter C_MIF_FILE_NAME = "", parameter C_OPTIMIZATION_MODE = 0, parameter C_OVERFLOW_LOW = 0, parameter C_PRELOAD_LATENCY = 1, parameter C_PRELOAD_REGS = 0, parameter C_PRIM_FIFO_TYPE = "", parameter C_PROG_EMPTY_THRESH_ASSERT_VAL = 0, parameter C_PROG_EMPTY_THRESH_NEGATE_VAL = 0, parameter C_PROG_EMPTY_TYPE = 0, parameter C_PROG_FULL_THRESH_ASSERT_VAL = 0, parameter C_PROG_FULL_THRESH_NEGATE_VAL = 0, parameter C_PROG_FULL_TYPE = 0, parameter C_RD_DATA_COUNT_WIDTH = 2, parameter C_RD_DEPTH = 256, parameter C_RD_FREQ = 1, parameter C_RD_PNTR_WIDTH = 8, parameter C_UNDERFLOW_LOW = 0, parameter C_USE_DOUT_RST = 0, parameter C_USE_ECC = 0, parameter C_USE_EMBEDDED_REG = 0, parameter C_USE_FIFO16_FLAGS = 0, parameter C_USE_FWFT_DATA_COUNT = 0, parameter C_VALID_LOW = 0, parameter C_WR_ACK_LOW = 0, parameter C_WR_DATA_COUNT_WIDTH = 2, parameter C_WR_DEPTH = 256, parameter C_WR_FREQ = 1, parameter C_WR_PNTR_WIDTH = 8, parameter C_WR_RESPONSE_LATENCY = 1, parameter C_MSGON_VAL = 1, parameter C_ENABLE_RST_SYNC = 1, parameter C_ERROR_INJECTION_TYPE = 0, parameter C_FIFO_TYPE = 0, parameter C_SYNCHRONIZER_STAGE = 2, parameter C_AXI_TYPE = 0 ) ( input BACKUP, input BACKUP_MARKER, input CLK, input RST, input SRST, input WR_CLK, input WR_RST, input RD_CLK, input RD_RST, input [C_DIN_WIDTH-1:0] DIN, input WR_EN, input RD_EN, input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH, input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT, input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE, input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH, input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT, input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE, input INT_CLK, input INJECTDBITERR, input INJECTSBITERR, output [C_DOUT_WIDTH-1:0] DOUT, output FULL, output ALMOST_FULL, output WR_ACK, output OVERFLOW, output EMPTY, output ALMOST_EMPTY, output VALID, output UNDERFLOW, output [C_DATA_COUNT_WIDTH-1:0] DATA_COUNT, output [C_RD_DATA_COUNT_WIDTH-1:0] RD_DATA_COUNT, output [C_WR_DATA_COUNT_WIDTH-1:0] WR_DATA_COUNT, output PROG_FULL, output PROG_EMPTY, output SBITERR, output DBITERR, output wr_rst_busy, output rd_rst_busy, output wr_rst_i_out, output rd_rst_i_out ); /* ****************************************************************************** * Definition of Parameters ****************************************************************************** * C_COMMON_CLOCK : Common Clock (1), Independent Clocks (0) * C_COUNT_TYPE : *not used * C_DATA_COUNT_WIDTH : Width of DATA_COUNT bus * C_DEFAULT_VALUE : *not used * C_DIN_WIDTH : Width of DIN bus * C_DOUT_RST_VAL : Reset value of DOUT * C_DOUT_WIDTH : Width of DOUT bus * C_ENABLE_RLOCS : *not used * C_FAMILY : not used in bhv model * C_FULL_FLAGS_RST_VAL : Full flags rst val (0 or 1) * C_HAS_ALMOST_EMPTY : 1=Core has ALMOST_EMPTY flag * C_HAS_ALMOST_FULL : 1=Core has ALMOST_FULL flag * C_HAS_BACKUP : *not used * C_HAS_DATA_COUNT : 1=Core has DATA_COUNT bus * C_HAS_INT_CLK : not used in bhv model * C_HAS_MEMINIT_FILE : *not used * C_HAS_OVERFLOW : 1=Core has OVERFLOW flag * C_HAS_RD_DATA_COUNT : 1=Core has RD_DATA_COUNT bus * C_HAS_RD_RST : *not used * C_HAS_RST : 1=Core has Async Rst * C_HAS_SRST : 1=Core has Sync Rst * C_HAS_UNDERFLOW : 1=Core has UNDERFLOW flag * C_HAS_VALID : 1=Core has VALID flag * C_HAS_WR_ACK : 1=Core has WR_ACK flag * C_HAS_WR_DATA_COUNT : 1=Core has WR_DATA_COUNT bus * C_HAS_WR_RST : *not used * C_IMPLEMENTATION_TYPE : 0=Common-Clock Bram/Dram * 1=Common-Clock ShiftRam * 2=Indep. Clocks Bram/Dram * 3=Virtex-4 Built-in * 4=Virtex-5 Built-in * C_INIT_WR_PNTR_VAL : *not used * C_MEMORY_TYPE : 1=Block RAM * 2=Distributed RAM * 3=Shift RAM * 4=Built-in FIFO * C_MIF_FILE_NAME : *not used * C_OPTIMIZATION_MODE : *not used * C_OVERFLOW_LOW : 1=OVERFLOW active low * C_PRELOAD_LATENCY : Latency of read: 0, 1, 2 * C_PRELOAD_REGS : 1=Use output registers * C_PRIM_FIFO_TYPE : not used in bhv model * C_PROG_EMPTY_THRESH_ASSERT_VAL: PROG_EMPTY assert threshold * C_PROG_EMPTY_THRESH_NEGATE_VAL: PROG_EMPTY negate threshold * C_PROG_EMPTY_TYPE : 0=No programmable empty * 1=Single prog empty thresh constant * 2=Multiple prog empty thresh constants * 3=Single prog empty thresh input * 4=Multiple prog empty thresh inputs * C_PROG_FULL_THRESH_ASSERT_VAL : PROG_FULL assert threshold * C_PROG_FULL_THRESH_NEGATE_VAL : PROG_FULL negate threshold * C_PROG_FULL_TYPE : 0=No prog full * 1=Single prog full thresh constant * 2=Multiple prog full thresh constants * 3=Single prog full thresh input * 4=Multiple prog full thresh inputs * C_RD_DATA_COUNT_WIDTH : Width of RD_DATA_COUNT bus * C_RD_DEPTH : Depth of read interface (2^N) * C_RD_FREQ : not used in bhv model * C_RD_PNTR_WIDTH : always log2(C_RD_DEPTH) * C_UNDERFLOW_LOW : 1=UNDERFLOW active low * C_USE_DOUT_RST : 1=Resets DOUT on RST * C_USE_ECC : Used for error injection purpose * C_USE_EMBEDDED_REG : 1=Use BRAM embedded output register * C_USE_FIFO16_FLAGS : not used in bhv model * C_USE_FWFT_DATA_COUNT : 1=Use extra logic for FWFT data count * C_VALID_LOW : 1=VALID active low * C_WR_ACK_LOW : 1=WR_ACK active low * C_WR_DATA_COUNT_WIDTH : Width of WR_DATA_COUNT bus * C_WR_DEPTH : Depth of write interface (2^N) * C_WR_FREQ : not used in bhv model * C_WR_PNTR_WIDTH : always log2(C_WR_DEPTH) * C_WR_RESPONSE_LATENCY : *not used * C_MSGON_VAL : *not used by bhv model * C_ENABLE_RST_SYNC : 0 = Use WR_RST & RD_RST * 1 = Use RST * C_ERROR_INJECTION_TYPE : 0 = No error injection * 1 = Single bit error injection only * 2 = Double bit error injection only * 3 = Single and double bit error injection ****************************************************************************** * Definition of Ports ****************************************************************************** * BACKUP : Not used * BACKUP_MARKER: Not used * CLK : Clock * DIN : Input data bus * PROG_EMPTY_THRESH : Threshold for Programmable Empty Flag * PROG_EMPTY_THRESH_ASSERT: Threshold for Programmable Empty Flag * PROG_EMPTY_THRESH_NEGATE: Threshold for Programmable Empty Flag * PROG_FULL_THRESH : Threshold for Programmable Full Flag * PROG_FULL_THRESH_ASSERT : Threshold for Programmable Full Flag * PROG_FULL_THRESH_NEGATE : Threshold for Programmable Full Flag * RD_CLK : Read Domain Clock * RD_EN : Read enable * RD_RST : Read Reset * RST : Asynchronous Reset * SRST : Synchronous Reset * WR_CLK : Write Domain Clock * WR_EN : Write enable * WR_RST : Write Reset * INT_CLK : Internal Clock * INJECTSBITERR: Inject Signle bit error * INJECTDBITERR: Inject Double bit error * ALMOST_EMPTY : One word remaining in FIFO * ALMOST_FULL : One empty space remaining in FIFO * DATA_COUNT : Number of data words in fifo( synchronous to CLK) * DOUT : Output data bus * EMPTY : Empty flag * FULL : Full flag * OVERFLOW : Last write rejected * PROG_EMPTY : Programmable Empty Flag * PROG_FULL : Programmable Full Flag * RD_DATA_COUNT: Number of data words in fifo (synchronous to RD_CLK) * UNDERFLOW : Last read rejected * VALID : Last read acknowledged, DOUT bus VALID * WR_ACK : Last write acknowledged * WR_DATA_COUNT: Number of data words in fifo (synchronous to WR_CLK) * SBITERR : Single Bit ECC Error Detected * DBITERR : Double Bit ECC Error Detected ****************************************************************************** */ //---------------------------------------------------------------------------- //- Internal Signals for delayed input signals //- All the input signals except Clock are delayed by 100 ps and then given to //- the models. //---------------------------------------------------------------------------- reg rst_delayed ; reg empty_fb ; reg srst_delayed ; reg wr_rst_delayed ; reg rd_rst_delayed ; reg wr_en_delayed ; reg rd_en_delayed ; reg [C_DIN_WIDTH-1:0] din_delayed ; reg [C_RD_PNTR_WIDTH-1:0] prog_empty_thresh_delayed ; reg [C_RD_PNTR_WIDTH-1:0] prog_empty_thresh_assert_delayed ; reg [C_RD_PNTR_WIDTH-1:0] prog_empty_thresh_negate_delayed ; reg [C_WR_PNTR_WIDTH-1:0] prog_full_thresh_delayed ; reg [C_WR_PNTR_WIDTH-1:0] prog_full_thresh_assert_delayed ; reg [C_WR_PNTR_WIDTH-1:0] prog_full_thresh_negate_delayed ; reg injectdbiterr_delayed ; reg injectsbiterr_delayed ; wire empty_p0_out; always @* rst_delayed <= #`TCQ RST ; always @* empty_fb <= #`TCQ empty_p0_out ; always @* srst_delayed <= #`TCQ SRST ; always @* wr_rst_delayed <= #`TCQ WR_RST ; always @* rd_rst_delayed <= #`TCQ RD_RST ; always @* din_delayed <= #`TCQ DIN ; always @* wr_en_delayed <= #`TCQ WR_EN ; always @* rd_en_delayed <= #`TCQ RD_EN ; always @* prog_empty_thresh_delayed <= #`TCQ PROG_EMPTY_THRESH ; always @* prog_empty_thresh_assert_delayed <= #`TCQ PROG_EMPTY_THRESH_ASSERT ; always @* prog_empty_thresh_negate_delayed <= #`TCQ PROG_EMPTY_THRESH_NEGATE ; always @* prog_full_thresh_delayed <= #`TCQ PROG_FULL_THRESH ; always @* prog_full_thresh_assert_delayed <= #`TCQ PROG_FULL_THRESH_ASSERT ; always @* prog_full_thresh_negate_delayed <= #`TCQ PROG_FULL_THRESH_NEGATE ; always @* injectdbiterr_delayed <= #`TCQ INJECTDBITERR ; always @* injectsbiterr_delayed <= #`TCQ INJECTSBITERR ; /***************************************************************************** * Derived parameters ****************************************************************************/ //There are 2 Verilog behavioral models // 0 = Common-Clock FIFO/ShiftRam FIFO // 1 = Independent Clocks FIFO // 2 = Low Latency Synchronous FIFO // 3 = Low Latency Asynchronous FIFO localparam C_VERILOG_IMPL = (C_FIFO_TYPE == 3) ? 2 : (C_IMPLEMENTATION_TYPE == 2) ? 1 : 0; localparam IS_8SERIES = (C_FAMILY == "virtexu" || C_FAMILY == "kintexu" || C_FAMILY == "artixu" || C_FAMILY == "virtexum" || C_FAMILY == "zynque") ? 1 : 0; //Internal reset signals reg rd_rst_asreg = 0; reg rd_rst_asreg_d1 = 0; reg rd_rst_asreg_d2 = 0; reg rd_rst_asreg_d3 = 0; reg rd_rst_reg = 0; wire rd_rst_comb; reg wr_rst_d0 = 0; reg wr_rst_d1 = 0; reg wr_rst_d2 = 0; reg rd_rst_d0 = 0; reg rd_rst_d1 = 0; reg rd_rst_d2 = 0; reg rd_rst_d3 = 0; reg wrrst_done = 0; reg rdrst_done = 0; reg wr_rst_asreg = 0; reg wr_rst_asreg_d1 = 0; reg wr_rst_asreg_d2 = 0; reg wr_rst_asreg_d3 = 0; reg rd_rst_wr_d0 = 0; reg rd_rst_wr_d1 = 0; reg rd_rst_wr_d2 = 0; reg wr_rst_reg = 0; reg rst_active_i = 1'b1; reg rst_delayed_d1 = 1'b1; reg rst_delayed_d2 = 1'b1; wire wr_rst_comb; wire wr_rst_i; wire rd_rst_i; wire rst_i; //Internal reset signals reg rst_asreg = 0; reg srst_asreg = 0; reg rst_asreg_d1 = 0; reg rst_asreg_d2 = 0; reg srst_asreg_d1 = 0; reg srst_asreg_d2 = 0; reg rst_reg = 0; reg srst_reg = 0; wire rst_comb; wire srst_comb; reg rst_full_gen_i = 0; reg rst_full_ff_i = 0; wire RD_CLK_P0_IN; wire RST_P0_IN; wire RD_EN_FIFO_IN; wire RD_EN_P0_IN; wire ALMOST_EMPTY_FIFO_OUT; wire ALMOST_FULL_FIFO_OUT; wire [C_DATA_COUNT_WIDTH-1:0] DATA_COUNT_FIFO_OUT; wire [C_DOUT_WIDTH-1:0] DOUT_FIFO_OUT; wire EMPTY_FIFO_OUT; wire FULL_FIFO_OUT; wire OVERFLOW_FIFO_OUT; wire PROG_EMPTY_FIFO_OUT; wire PROG_FULL_FIFO_OUT; wire VALID_FIFO_OUT; wire [C_RD_DATA_COUNT_WIDTH-1:0] RD_DATA_COUNT_FIFO_OUT; wire UNDERFLOW_FIFO_OUT; wire WR_ACK_FIFO_OUT; wire [C_WR_DATA_COUNT_WIDTH-1:0] WR_DATA_COUNT_FIFO_OUT; //*************************************************************************** // Internal Signals // The core uses either the internal_ wires or the preload0_ wires depending // on whether the core uses Preload0 or not. // When using preload0, the internal signals connect the internal core to // the preload logic, and the external core's interfaces are tied to the // preload0 signals from the preload logic. //*************************************************************************** wire [C_DOUT_WIDTH-1:0] DATA_P0_OUT; wire VALID_P0_OUT; wire EMPTY_P0_OUT; wire ALMOSTEMPTY_P0_OUT; reg EMPTY_P0_OUT_Q; reg ALMOSTEMPTY_P0_OUT_Q; wire UNDERFLOW_P0_OUT; wire RDEN_P0_OUT; wire [C_DOUT_WIDTH-1:0] DATA_P0_IN; wire EMPTY_P0_IN; reg [31:0] DATA_COUNT_FWFT; reg SS_FWFT_WR ; reg SS_FWFT_RD ; wire sbiterr_fifo_out; wire dbiterr_fifo_out; wire inject_sbit_err; wire inject_dbit_err; // Assign 0 if not selected to avoid 'X' propogation to S/DBITERR. assign inject_sbit_err = ((C_ERROR_INJECTION_TYPE == 1) || (C_ERROR_INJECTION_TYPE == 3)) ? injectsbiterr_delayed : 0; assign inject_dbit_err = ((C_ERROR_INJECTION_TYPE == 2) || (C_ERROR_INJECTION_TYPE == 3)) ? injectdbiterr_delayed : 0; assign wr_rst_i_out = wr_rst_i; assign rd_rst_i_out = rd_rst_i; // Choose the behavioral model to instantiate based on the C_VERILOG_IMPL // parameter (1=Independent Clocks, 0=Common Clock) localparam FULL_FLAGS_RST_VAL = (C_HAS_SRST == 1) ? 0 : C_FULL_FLAGS_RST_VAL; generate case (C_VERILOG_IMPL) 0 : begin : block1 //Common Clock Behavioral Model fifo_generator_v12_0_bhv_ver_ss #( .C_FAMILY (C_FAMILY), .C_DATA_COUNT_WIDTH (C_DATA_COUNT_WIDTH), .C_DIN_WIDTH (C_DIN_WIDTH), .C_DOUT_RST_VAL (C_DOUT_RST_VAL), .C_DOUT_WIDTH (C_DOUT_WIDTH), .C_FULL_FLAGS_RST_VAL (FULL_FLAGS_RST_VAL), .C_HAS_ALMOST_EMPTY (C_HAS_ALMOST_EMPTY), .C_HAS_ALMOST_FULL ((C_AXI_TYPE == 0 && C_FIFO_TYPE == 1) ? 1 : C_HAS_ALMOST_FULL), .C_HAS_DATA_COUNT (C_HAS_DATA_COUNT), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_HAS_RD_DATA_COUNT (C_HAS_RD_DATA_COUNT), .C_HAS_RST (C_HAS_RST), .C_HAS_SRST (C_HAS_SRST), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_HAS_VALID (C_HAS_VALID), .C_HAS_WR_ACK (C_HAS_WR_ACK), .C_HAS_WR_DATA_COUNT (C_HAS_WR_DATA_COUNT), .C_IMPLEMENTATION_TYPE (C_IMPLEMENTATION_TYPE), .C_MEMORY_TYPE (C_MEMORY_TYPE), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_PRELOAD_LATENCY (C_PRELOAD_LATENCY), .C_PRELOAD_REGS (C_PRELOAD_REGS), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL), .C_PROG_EMPTY_THRESH_NEGATE_VAL (C_PROG_EMPTY_THRESH_NEGATE_VAL), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL), .C_PROG_FULL_THRESH_NEGATE_VAL (C_PROG_FULL_THRESH_NEGATE_VAL), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE), .C_RD_DATA_COUNT_WIDTH (C_RD_DATA_COUNT_WIDTH), .C_RD_DEPTH (C_RD_DEPTH), .C_RD_PNTR_WIDTH (C_RD_PNTR_WIDTH), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_USE_DOUT_RST (C_USE_DOUT_RST), .C_USE_EMBEDDED_REG (C_USE_EMBEDDED_REG), .C_USE_FWFT_DATA_COUNT (C_USE_FWFT_DATA_COUNT), .C_VALID_LOW (C_VALID_LOW), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_WR_DATA_COUNT_WIDTH (C_WR_DATA_COUNT_WIDTH), .C_WR_DEPTH (C_WR_DEPTH), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH), .C_USE_ECC (C_USE_ECC), .C_ENABLE_RST_SYNC (C_ENABLE_RST_SYNC), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE), .C_FIFO_TYPE (C_FIFO_TYPE) ) gen_ss ( .CLK (CLK), .RST (rst_i), .SRST (srst_delayed), .RST_FULL_GEN (rst_full_gen_i), .RST_FULL_FF (rst_full_ff_i), .DIN (din_delayed), .WR_EN (wr_en_delayed), .RD_EN (RD_EN_FIFO_IN), .RD_EN_USER (rd_en_delayed), .USER_EMPTY_FB (empty_fb), .PROG_EMPTY_THRESH (prog_empty_thresh_delayed), .PROG_EMPTY_THRESH_ASSERT (prog_empty_thresh_assert_delayed), .PROG_EMPTY_THRESH_NEGATE (prog_empty_thresh_negate_delayed), .PROG_FULL_THRESH (prog_full_thresh_delayed), .PROG_FULL_THRESH_ASSERT (prog_full_thresh_assert_delayed), .PROG_FULL_THRESH_NEGATE (prog_full_thresh_negate_delayed), .INJECTSBITERR (inject_sbit_err), .INJECTDBITERR (inject_dbit_err), .DOUT (DOUT_FIFO_OUT), .FULL (FULL_FIFO_OUT), .ALMOST_FULL (ALMOST_FULL_FIFO_OUT), .WR_ACK (WR_ACK_FIFO_OUT), .OVERFLOW (OVERFLOW_FIFO_OUT), .EMPTY (EMPTY_FIFO_OUT), .ALMOST_EMPTY (ALMOST_EMPTY_FIFO_OUT), .VALID (VALID_FIFO_OUT), .UNDERFLOW (UNDERFLOW_FIFO_OUT), .DATA_COUNT (DATA_COUNT_FIFO_OUT), .RD_DATA_COUNT (RD_DATA_COUNT_FIFO_OUT), .WR_DATA_COUNT (WR_DATA_COUNT_FIFO_OUT), .PROG_FULL (PROG_FULL_FIFO_OUT), .PROG_EMPTY (PROG_EMPTY_FIFO_OUT), .WR_RST_BUSY (wr_rst_busy), .RD_RST_BUSY (rd_rst_busy), .SBITERR (sbiterr_fifo_out), .DBITERR (dbiterr_fifo_out) ); end 1 : begin : block1 //Independent Clocks Behavioral Model fifo_generator_v12_0_bhv_ver_as #( .C_FAMILY (C_FAMILY), .C_DATA_COUNT_WIDTH (C_DATA_COUNT_WIDTH), .C_DIN_WIDTH (C_DIN_WIDTH), .C_DOUT_RST_VAL (C_DOUT_RST_VAL), .C_DOUT_WIDTH (C_DOUT_WIDTH), .C_FULL_FLAGS_RST_VAL (C_FULL_FLAGS_RST_VAL), .C_HAS_ALMOST_EMPTY (C_HAS_ALMOST_EMPTY), .C_HAS_ALMOST_FULL (C_HAS_ALMOST_FULL), .C_HAS_DATA_COUNT (C_HAS_DATA_COUNT), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_HAS_RD_DATA_COUNT (C_HAS_RD_DATA_COUNT), .C_HAS_RST (C_HAS_RST), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_HAS_VALID (C_HAS_VALID), .C_HAS_WR_ACK (C_HAS_WR_ACK), .C_HAS_WR_DATA_COUNT (C_HAS_WR_DATA_COUNT), .C_IMPLEMENTATION_TYPE (C_IMPLEMENTATION_TYPE), .C_MEMORY_TYPE (C_MEMORY_TYPE), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_PRELOAD_LATENCY (C_PRELOAD_LATENCY), .C_PRELOAD_REGS (C_PRELOAD_REGS), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL), .C_PROG_EMPTY_THRESH_NEGATE_VAL (C_PROG_EMPTY_THRESH_NEGATE_VAL), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL), .C_PROG_FULL_THRESH_NEGATE_VAL (C_PROG_FULL_THRESH_NEGATE_VAL), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE), .C_RD_DATA_COUNT_WIDTH (C_RD_DATA_COUNT_WIDTH), .C_RD_DEPTH (C_RD_DEPTH), .C_RD_PNTR_WIDTH (C_RD_PNTR_WIDTH), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_USE_DOUT_RST (C_USE_DOUT_RST), .C_USE_EMBEDDED_REG (C_USE_EMBEDDED_REG), .C_USE_FWFT_DATA_COUNT (C_USE_FWFT_DATA_COUNT), .C_VALID_LOW (C_VALID_LOW), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_WR_DATA_COUNT_WIDTH (C_WR_DATA_COUNT_WIDTH), .C_WR_DEPTH (C_WR_DEPTH), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH), .C_USE_ECC (C_USE_ECC), .C_SYNCHRONIZER_STAGE (C_SYNCHRONIZER_STAGE), .C_ENABLE_RST_SYNC (C_ENABLE_RST_SYNC), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE) ) gen_as ( .WR_CLK (WR_CLK), .RD_CLK (RD_CLK), .RST (rst_i), .RST_FULL_GEN (rst_full_gen_i), .RST_FULL_FF (rst_full_ff_i), .WR_RST (wr_rst_i), .RD_RST (rd_rst_i), .DIN (din_delayed), .WR_EN (wr_en_delayed), .RD_EN (RD_EN_FIFO_IN), .RD_EN_USER (rd_en_delayed), .PROG_EMPTY_THRESH (prog_empty_thresh_delayed), .PROG_EMPTY_THRESH_ASSERT (prog_empty_thresh_assert_delayed), .PROG_EMPTY_THRESH_NEGATE (prog_empty_thresh_negate_delayed), .PROG_FULL_THRESH (prog_full_thresh_delayed), .PROG_FULL_THRESH_ASSERT (prog_full_thresh_assert_delayed), .PROG_FULL_THRESH_NEGATE (prog_full_thresh_negate_delayed), .INJECTSBITERR (inject_sbit_err), .INJECTDBITERR (inject_dbit_err), .USER_EMPTY_FB (EMPTY_P0_OUT), .DOUT (DOUT_FIFO_OUT), .FULL (FULL_FIFO_OUT), .ALMOST_FULL (ALMOST_FULL_FIFO_OUT), .WR_ACK (WR_ACK_FIFO_OUT), .OVERFLOW (OVERFLOW_FIFO_OUT), .EMPTY (EMPTY_FIFO_OUT), .ALMOST_EMPTY (ALMOST_EMPTY_FIFO_OUT), .VALID (VALID_FIFO_OUT), .UNDERFLOW (UNDERFLOW_FIFO_OUT), .RD_DATA_COUNT (RD_DATA_COUNT_FIFO_OUT), .WR_DATA_COUNT (WR_DATA_COUNT_FIFO_OUT), .PROG_FULL (PROG_FULL_FIFO_OUT), .PROG_EMPTY (PROG_EMPTY_FIFO_OUT), .SBITERR (sbiterr_fifo_out), .DBITERR (dbiterr_fifo_out) ); end 2 : begin : ll_afifo_inst fifo_generator_v12_0_beh_ver_ll_afifo #( .C_DIN_WIDTH (C_DIN_WIDTH), .C_DOUT_RST_VAL (C_DOUT_RST_VAL), .C_DOUT_WIDTH (C_DOUT_WIDTH), .C_FULL_FLAGS_RST_VAL (C_FULL_FLAGS_RST_VAL), .C_HAS_RD_DATA_COUNT (C_HAS_RD_DATA_COUNT), .C_HAS_WR_DATA_COUNT (C_HAS_WR_DATA_COUNT), .C_RD_DEPTH (C_RD_DEPTH), .C_RD_PNTR_WIDTH (C_RD_PNTR_WIDTH), .C_USE_DOUT_RST (C_USE_DOUT_RST), .C_WR_DATA_COUNT_WIDTH (C_WR_DATA_COUNT_WIDTH), .C_WR_DEPTH (C_WR_DEPTH), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH), .C_FIFO_TYPE (C_FIFO_TYPE) ) gen_ll_afifo ( .DIN (din_delayed), .RD_CLK (RD_CLK), .RD_EN (rd_en_delayed), .WR_RST (wr_rst_i), .RD_RST (rd_rst_i), .WR_CLK (WR_CLK), .WR_EN (wr_en_delayed), .DOUT (DOUT), .EMPTY (EMPTY), .FULL (FULL) ); end default : begin : block1 //Independent Clocks Behavioral Model fifo_generator_v12_0_bhv_ver_as #( .C_FAMILY (C_FAMILY), .C_DATA_COUNT_WIDTH (C_DATA_COUNT_WIDTH), .C_DIN_WIDTH (C_DIN_WIDTH), .C_DOUT_RST_VAL (C_DOUT_RST_VAL), .C_DOUT_WIDTH (C_DOUT_WIDTH), .C_FULL_FLAGS_RST_VAL (C_FULL_FLAGS_RST_VAL), .C_HAS_ALMOST_EMPTY (C_HAS_ALMOST_EMPTY), .C_HAS_ALMOST_FULL (C_HAS_ALMOST_FULL), .C_HAS_DATA_COUNT (C_HAS_DATA_COUNT), .C_HAS_OVERFLOW (C_HAS_OVERFLOW), .C_HAS_RD_DATA_COUNT (C_HAS_RD_DATA_COUNT), .C_HAS_RST (C_HAS_RST), .C_HAS_UNDERFLOW (C_HAS_UNDERFLOW), .C_HAS_VALID (C_HAS_VALID), .C_HAS_WR_ACK (C_HAS_WR_ACK), .C_HAS_WR_DATA_COUNT (C_HAS_WR_DATA_COUNT), .C_IMPLEMENTATION_TYPE (C_IMPLEMENTATION_TYPE), .C_MEMORY_TYPE (C_MEMORY_TYPE), .C_OVERFLOW_LOW (C_OVERFLOW_LOW), .C_PRELOAD_LATENCY (C_PRELOAD_LATENCY), .C_PRELOAD_REGS (C_PRELOAD_REGS), .C_PROG_EMPTY_THRESH_ASSERT_VAL (C_PROG_EMPTY_THRESH_ASSERT_VAL), .C_PROG_EMPTY_THRESH_NEGATE_VAL (C_PROG_EMPTY_THRESH_NEGATE_VAL), .C_PROG_EMPTY_TYPE (C_PROG_EMPTY_TYPE), .C_PROG_FULL_THRESH_ASSERT_VAL (C_PROG_FULL_THRESH_ASSERT_VAL), .C_PROG_FULL_THRESH_NEGATE_VAL (C_PROG_FULL_THRESH_NEGATE_VAL), .C_PROG_FULL_TYPE (C_PROG_FULL_TYPE), .C_RD_DATA_COUNT_WIDTH (C_RD_DATA_COUNT_WIDTH), .C_RD_DEPTH (C_RD_DEPTH), .C_RD_PNTR_WIDTH (C_RD_PNTR_WIDTH), .C_UNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_USE_DOUT_RST (C_USE_DOUT_RST), .C_USE_EMBEDDED_REG (C_USE_EMBEDDED_REG), .C_USE_FWFT_DATA_COUNT (C_USE_FWFT_DATA_COUNT), .C_VALID_LOW (C_VALID_LOW), .C_WR_ACK_LOW (C_WR_ACK_LOW), .C_WR_DATA_COUNT_WIDTH (C_WR_DATA_COUNT_WIDTH), .C_WR_DEPTH (C_WR_DEPTH), .C_WR_PNTR_WIDTH (C_WR_PNTR_WIDTH), .C_USE_ECC (C_USE_ECC), .C_SYNCHRONIZER_STAGE (C_SYNCHRONIZER_STAGE), .C_ENABLE_RST_SYNC (C_ENABLE_RST_SYNC), .C_ERROR_INJECTION_TYPE (C_ERROR_INJECTION_TYPE) ) gen_as ( .WR_CLK (WR_CLK), .RD_CLK (RD_CLK), .RST (rst_i), .RST_FULL_GEN (rst_full_gen_i), .RST_FULL_FF (rst_full_ff_i), .WR_RST (wr_rst_i), .RD_RST (rd_rst_i), .DIN (din_delayed), .WR_EN (wr_en_delayed), .RD_EN (RD_EN_FIFO_IN), .RD_EN_USER (rd_en_delayed), .PROG_EMPTY_THRESH (prog_empty_thresh_delayed), .PROG_EMPTY_THRESH_ASSERT (prog_empty_thresh_assert_delayed), .PROG_EMPTY_THRESH_NEGATE (prog_empty_thresh_negate_delayed), .PROG_FULL_THRESH (prog_full_thresh_delayed), .PROG_FULL_THRESH_ASSERT (prog_full_thresh_assert_delayed), .PROG_FULL_THRESH_NEGATE (prog_full_thresh_negate_delayed), .INJECTSBITERR (inject_sbit_err), .INJECTDBITERR (inject_dbit_err), .USER_EMPTY_FB (EMPTY_P0_OUT), .DOUT (DOUT_FIFO_OUT), .FULL (FULL_FIFO_OUT), .ALMOST_FULL (ALMOST_FULL_FIFO_OUT), .WR_ACK (WR_ACK_FIFO_OUT), .OVERFLOW (OVERFLOW_FIFO_OUT), .EMPTY (EMPTY_FIFO_OUT), .ALMOST_EMPTY (ALMOST_EMPTY_FIFO_OUT), .VALID (VALID_FIFO_OUT), .UNDERFLOW (UNDERFLOW_FIFO_OUT), .RD_DATA_COUNT (RD_DATA_COUNT_FIFO_OUT), .WR_DATA_COUNT (WR_DATA_COUNT_FIFO_OUT), .PROG_FULL (PROG_FULL_FIFO_OUT), .PROG_EMPTY (PROG_EMPTY_FIFO_OUT), .SBITERR (sbiterr_fifo_out), .DBITERR (dbiterr_fifo_out) ); end endcase endgenerate //************************************************************************** // Connect Internal Signals // (Signals labeled internal_*) // In the normal case, these signals tie directly to the FIFO's inputs and // outputs. // In the case of Preload Latency 0 or 1, there are intermediate // signals between the internal FIFO and the preload logic. //************************************************************************** //*********************************************** // If First-Word Fall-Through, instantiate // the preload0 (FWFT) module //*********************************************** wire rd_en_to_fwft_fifo; wire sbiterr_fwft; wire dbiterr_fwft; wire [C_DOUT_WIDTH-1:0] dout_fwft; wire empty_fwft; wire rd_en_fifo_in; wire stage2_reg_en_i; wire [1:0] valid_stages_i; wire rst_fwft; //wire empty_p0_out; reg [C_SYNCHRONIZER_STAGE-1:0] pkt_empty_sync = 'b1; localparam IS_FWFT = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ? 1 : 0; localparam IS_PKT_FIFO = (C_FIFO_TYPE == 1) ? 1 : 0; localparam IS_AXIS_PKT_FIFO = (C_FIFO_TYPE == 1 && C_AXI_TYPE == 0) ? 1 : 0; assign rst_fwft = (C_COMMON_CLOCK == 0) ? rd_rst_i : (C_HAS_RST == 1) ? rst_i : 1'b0; generate if (IS_FWFT == 1 && C_FIFO_TYPE != 3) begin : block2 fifo_generator_v12_0_bhv_ver_preload0 #( .C_DOUT_RST_VAL (C_DOUT_RST_VAL), .C_DOUT_WIDTH (C_DOUT_WIDTH), .C_HAS_RST (C_HAS_RST), .C_ENABLE_RST_SYNC (C_ENABLE_RST_SYNC), .C_HAS_SRST (C_HAS_SRST), .C_USE_DOUT_RST (C_USE_DOUT_RST), .C_USE_ECC (C_USE_ECC), .C_USERVALID_LOW (C_VALID_LOW), .C_USERUNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_MEMORY_TYPE (C_MEMORY_TYPE), .C_FIFO_TYPE (C_FIFO_TYPE) ) fgpl0 ( .RD_CLK (RD_CLK_P0_IN), .RD_RST (RST_P0_IN), .SRST (srst_delayed), .WR_RST_BUSY (wr_rst_busy), .RD_RST_BUSY (rd_rst_busy), .RD_EN (RD_EN_P0_IN), .FIFOEMPTY (EMPTY_P0_IN), .FIFODATA (DATA_P0_IN), .FIFOSBITERR (sbiterr_fifo_out), .FIFODBITERR (dbiterr_fifo_out), // Output .USERDATA (dout_fwft), .USERVALID (VALID_P0_OUT), .USEREMPTY (empty_fwft), .USERALMOSTEMPTY (ALMOSTEMPTY_P0_OUT), .USERUNDERFLOW (UNDERFLOW_P0_OUT), .RAMVALID (), .FIFORDEN (rd_en_fifo_in), .USERSBITERR (sbiterr_fwft), .USERDBITERR (dbiterr_fwft), .STAGE2_REG_EN (stage2_reg_en_i), .VALID_STAGES (valid_stages_i) ); //*********************************************** // Connect inputs to preload (FWFT) module //*********************************************** //Connect the RD_CLK of the Preload (FWFT) module to CLK if we // have a common-clock FIFO, or RD_CLK if we have an // independent clock FIFO assign RD_CLK_P0_IN = ((C_VERILOG_IMPL == 0) ? CLK : RD_CLK); assign RST_P0_IN = (C_COMMON_CLOCK == 0) ? rd_rst_i : (C_HAS_RST == 1) ? rst_i : 0; assign RD_EN_P0_IN = (C_FIFO_TYPE != 1) ? rd_en_delayed : rd_en_to_fwft_fifo; assign EMPTY_P0_IN = EMPTY_FIFO_OUT; assign DATA_P0_IN = DOUT_FIFO_OUT; //*********************************************** // Connect outputs from preload (FWFT) module //*********************************************** assign VALID = VALID_P0_OUT ; assign ALMOST_EMPTY = ALMOSTEMPTY_P0_OUT; assign UNDERFLOW = UNDERFLOW_P0_OUT ; assign RD_EN_FIFO_IN = rd_en_fifo_in; //*********************************************** // Create DATA_COUNT from First-Word Fall-Through // data count //*********************************************** assign DATA_COUNT = (C_USE_FWFT_DATA_COUNT == 0)? DATA_COUNT_FIFO_OUT: (C_DATA_COUNT_WIDTH>C_RD_PNTR_WIDTH) ? DATA_COUNT_FWFT[C_RD_PNTR_WIDTH:0] : DATA_COUNT_FWFT[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH-C_DATA_COUNT_WIDTH+1]; //*********************************************** // Create DATA_COUNT from First-Word Fall-Through // data count //*********************************************** always @ (posedge RD_CLK_P0_IN or posedge RST_P0_IN) begin if (RST_P0_IN) begin EMPTY_P0_OUT_Q <= #`TCQ 1; ALMOSTEMPTY_P0_OUT_Q <= #`TCQ 1; end else begin EMPTY_P0_OUT_Q <= #`TCQ empty_p0_out; // EMPTY_P0_OUT_Q <= #`TCQ EMPTY_FIFO_OUT; ALMOSTEMPTY_P0_OUT_Q <= #`TCQ ALMOSTEMPTY_P0_OUT; end end //always //*********************************************** // logic for common-clock data count when FWFT is selected //*********************************************** initial begin SS_FWFT_RD = 1'b0; DATA_COUNT_FWFT = 0 ; SS_FWFT_WR = 1'b0 ; end //initial //*********************************************** // common-clock data count is implemented as an // up-down counter. SS_FWFT_WR and SS_FWFT_RD // are the up/down enables for the counter. //*********************************************** always @ (RD_EN or VALID_P0_OUT or WR_EN or FULL_FIFO_OUT or empty_p0_out) begin if (C_VALID_LOW == 1) begin SS_FWFT_RD = (C_FIFO_TYPE != 1) ? (RD_EN && ~VALID_P0_OUT) : (~empty_p0_out && RD_EN && ~VALID_P0_OUT) ; end else begin SS_FWFT_RD = (C_FIFO_TYPE != 1) ? (RD_EN && VALID_P0_OUT) : (~empty_p0_out && RD_EN && VALID_P0_OUT) ; end SS_FWFT_WR = (WR_EN && (~FULL_FIFO_OUT)) ; end //*********************************************** // common-clock data count is implemented as an // up-down counter for FWFT. This always block // calculates the counter. //*********************************************** always @ (posedge RD_CLK_P0_IN or posedge RST_P0_IN) begin if (RST_P0_IN) begin DATA_COUNT_FWFT <= #`TCQ 0; end else begin //if (srst_delayed && (C_HAS_SRST == 1) ) begin if ((srst_delayed | wr_rst_busy | rd_rst_busy) && (C_HAS_SRST == 1) ) begin DATA_COUNT_FWFT <= #`TCQ 0; end else begin case ( {SS_FWFT_WR, SS_FWFT_RD}) 2'b00: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT ; 2'b01: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT - 1 ; 2'b10: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT + 1 ; 2'b11: DATA_COUNT_FWFT <= #`TCQ DATA_COUNT_FWFT ; endcase end //if SRST end //IF RST end //always end endgenerate // : block2 // AXI Streaming Packet FIFO reg [C_WR_PNTR_WIDTH-1:0] wr_pkt_count = 0; reg [C_RD_PNTR_WIDTH-1:0] rd_pkt_count = 0; reg [C_RD_PNTR_WIDTH-1:0] rd_pkt_count_plus1 = 0; reg [C_RD_PNTR_WIDTH-1:0] rd_pkt_count_reg = 0; reg partial_packet = 0; reg stage1_eop_d1 = 0; reg rd_en_fifo_in_d1 = 0; reg eop_at_stage2 = 0; reg ram_pkt_empty = 0; reg ram_pkt_empty_d1 = 0; wire [C_DOUT_WIDTH-1:0] dout_p0_out; wire packet_empty_wr; wire wr_rst_fwft_pkt_fifo; wire dummy_wr_eop; wire ram_wr_en_pkt_fifo; wire wr_eop; wire ram_rd_en_compare; wire stage1_eop; wire pkt_ready_to_read; wire rd_en_2_stage2; // Generate Dummy WR_EOP for partial packet (Only for AXI Streaming) // When Packet EMPTY is high, and FIFO is full, then generate the dummy WR_EOP // When dummy WR_EOP is high, mask the actual EOP to avoid double increment of // write packet count generate if (IS_FWFT == 1 && IS_AXIS_PKT_FIFO == 1) begin // gdummy_wr_eop always @ (posedge wr_rst_fwft_pkt_fifo or posedge WR_CLK) begin if (wr_rst_fwft_pkt_fifo) partial_packet <= 1'b0; else begin if (srst_delayed | wr_rst_busy | rd_rst_busy) partial_packet <= #`TCQ 1'b0; else if (ALMOST_FULL_FIFO_OUT && ram_wr_en_pkt_fifo && packet_empty_wr && (~din_delayed[0])) partial_packet <= #`TCQ 1'b1; else if (partial_packet && din_delayed[0] && ram_wr_en_pkt_fifo) partial_packet <= #`TCQ 1'b0; end end end endgenerate // gdummy_wr_eop generate if (IS_FWFT == 1 && IS_PKT_FIFO == 1) begin // gpkt_fifo_fwft assign wr_rst_fwft_pkt_fifo = (C_COMMON_CLOCK == 0) ? wr_rst_i : (C_HAS_RST == 1) ? rst_i:1'b0; assign dummy_wr_eop = ALMOST_FULL_FIFO_OUT && ram_wr_en_pkt_fifo && packet_empty_wr && (~din_delayed[0]) && (~partial_packet); assign packet_empty_wr = (C_COMMON_CLOCK == 1) ? empty_p0_out : pkt_empty_sync[C_SYNCHRONIZER_STAGE-1]; always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin if (rst_fwft) begin stage1_eop_d1 <= 1'b0; rd_en_fifo_in_d1 <= 1'b0; end else begin if (srst_delayed | wr_rst_busy | rd_rst_busy) begin stage1_eop_d1 <= #`TCQ 1'b0; rd_en_fifo_in_d1 <= #`TCQ 1'b0; end else begin stage1_eop_d1 <= #`TCQ stage1_eop; rd_en_fifo_in_d1 <= #`TCQ rd_en_fifo_in; end end end assign stage1_eop = (rd_en_fifo_in_d1) ? DOUT_FIFO_OUT[0] : stage1_eop_d1; assign ram_wr_en_pkt_fifo = wr_en_delayed && (~FULL_FIFO_OUT); assign wr_eop = ram_wr_en_pkt_fifo && ((din_delayed[0] && (~partial_packet)) || dummy_wr_eop); assign ram_rd_en_compare = stage2_reg_en_i && stage1_eop; fifo_generator_v12_0_bhv_ver_preload0 #( .C_DOUT_RST_VAL (C_DOUT_RST_VAL), .C_DOUT_WIDTH (C_DOUT_WIDTH), .C_HAS_RST (C_HAS_RST), .C_HAS_SRST (C_HAS_SRST), .C_USE_DOUT_RST (C_USE_DOUT_RST), .C_USE_ECC (C_USE_ECC), .C_USERVALID_LOW (C_VALID_LOW), .C_USERUNDERFLOW_LOW (C_UNDERFLOW_LOW), .C_ENABLE_RST_SYNC (C_ENABLE_RST_SYNC), .C_MEMORY_TYPE (C_MEMORY_TYPE), .C_FIFO_TYPE (2) // Enable low latency fwft logic ) pkt_fifo_fwft ( .RD_CLK (RD_CLK_P0_IN), .RD_RST (rst_fwft), .SRST (srst_delayed), .WR_RST_BUSY (wr_rst_busy), .RD_RST_BUSY (rd_rst_busy), .RD_EN (rd_en_delayed), .FIFOEMPTY (pkt_ready_to_read), .FIFODATA (dout_fwft), .FIFOSBITERR (sbiterr_fwft), .FIFODBITERR (dbiterr_fwft), // Output .USERDATA (dout_p0_out), .USERVALID (), .USEREMPTY (empty_p0_out), .USERALMOSTEMPTY (), .USERUNDERFLOW (), .RAMVALID (), .FIFORDEN (rd_en_2_stage2), .USERSBITERR (SBITERR), .USERDBITERR (DBITERR), .STAGE2_REG_EN (), .VALID_STAGES () ); assign pkt_ready_to_read = ~(!(ram_pkt_empty || empty_fwft) && ((valid_stages_i[0] && valid_stages_i[1]) || eop_at_stage2)); assign rd_en_to_fwft_fifo = ~empty_fwft && rd_en_2_stage2; always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin if (rst_fwft) eop_at_stage2 <= 1'b0; else if (stage2_reg_en_i) eop_at_stage2 <= #`TCQ stage1_eop; end //--------------------------------------------------------------------------- // Write and Read Packet Count //--------------------------------------------------------------------------- always @ (posedge wr_rst_fwft_pkt_fifo or posedge WR_CLK) begin if (wr_rst_fwft_pkt_fifo) wr_pkt_count <= 0; else if (srst_delayed | wr_rst_busy | rd_rst_busy) wr_pkt_count <= #`TCQ 0; else if (wr_eop) wr_pkt_count <= #`TCQ wr_pkt_count + 1; end end endgenerate // gpkt_fifo_fwft assign DOUT = (C_FIFO_TYPE != 1) ? dout_fwft : dout_p0_out; assign EMPTY = (C_FIFO_TYPE != 1) ? empty_fwft : empty_p0_out; generate if (IS_FWFT == 1 && IS_PKT_FIFO == 1 && C_COMMON_CLOCK == 1) begin // grss_pkt_cnt always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin if (rst_fwft) begin rd_pkt_count <= 0; rd_pkt_count_plus1 <= 1; end else if (srst_delayed | wr_rst_busy | rd_rst_busy) begin rd_pkt_count <= #`TCQ 0; rd_pkt_count_plus1 <= #`TCQ 1; end else if (stage2_reg_en_i && stage1_eop) begin rd_pkt_count <= #`TCQ rd_pkt_count + 1; rd_pkt_count_plus1 <= #`TCQ rd_pkt_count_plus1 + 1; end end always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin if (rst_fwft) begin ram_pkt_empty <= 1'b1; ram_pkt_empty_d1 <= 1'b1; end else if (SRST | wr_rst_busy | rd_rst_busy) begin ram_pkt_empty <= #`TCQ 1'b1; ram_pkt_empty_d1 <= #`TCQ 1'b1; end else if ((rd_pkt_count == wr_pkt_count) && wr_eop) begin ram_pkt_empty <= #`TCQ 1'b0; ram_pkt_empty_d1 <= #`TCQ 1'b0; end else if (ram_pkt_empty_d1 && rd_en_to_fwft_fifo) begin ram_pkt_empty <= #`TCQ 1'b1; end else if ((rd_pkt_count_plus1 == wr_pkt_count) && ~wr_eop && ~ALMOST_FULL_FIFO_OUT && ram_rd_en_compare) begin ram_pkt_empty_d1 <= #`TCQ 1'b1; end end end endgenerate //grss_pkt_cnt localparam SYNC_STAGE_WIDTH = (C_SYNCHRONIZER_STAGE+1)*C_WR_PNTR_WIDTH; reg [SYNC_STAGE_WIDTH-1:0] wr_pkt_count_q = 0; reg [C_WR_PNTR_WIDTH-1:0] wr_pkt_count_b2g = 0; wire [C_WR_PNTR_WIDTH-1:0] wr_pkt_count_rd; generate if (IS_FWFT == 1 && IS_PKT_FIFO == 1 && C_COMMON_CLOCK == 0) begin // gras_pkt_cnt // Delay the write packet count in write clock domain to accomodate the binary to gray conversion delay always @ (posedge wr_rst_fwft_pkt_fifo or posedge WR_CLK) begin if (wr_rst_fwft_pkt_fifo) wr_pkt_count_b2g <= 0; else wr_pkt_count_b2g <= #`TCQ wr_pkt_count; end // Synchronize the delayed write packet count in read domain, and also compensate the gray to binay conversion delay always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin if (rst_fwft) wr_pkt_count_q <= 0; else wr_pkt_count_q <= #`TCQ {wr_pkt_count_q[SYNC_STAGE_WIDTH-C_WR_PNTR_WIDTH-1:0],wr_pkt_count_b2g}; end always @* begin if (stage1_eop) rd_pkt_count <= rd_pkt_count_reg + 1; else rd_pkt_count <= rd_pkt_count_reg; end assign wr_pkt_count_rd = wr_pkt_count_q[SYNC_STAGE_WIDTH-1:SYNC_STAGE_WIDTH-C_WR_PNTR_WIDTH]; always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin if (rst_fwft) rd_pkt_count_reg <= 0; else if (rd_en_fifo_in) rd_pkt_count_reg <= #`TCQ rd_pkt_count; end always @ (posedge rst_fwft or posedge RD_CLK_P0_IN) begin if (rst_fwft) begin ram_pkt_empty <= 1'b1; ram_pkt_empty_d1 <= 1'b1; end else if (rd_pkt_count != wr_pkt_count_rd) begin ram_pkt_empty <= #`TCQ 1'b0; ram_pkt_empty_d1 <= #`TCQ 1'b0; end else if (ram_pkt_empty_d1 && rd_en_to_fwft_fifo) begin ram_pkt_empty <= #`TCQ 1'b1; end else if ((rd_pkt_count == wr_pkt_count_rd) && stage2_reg_en_i) begin ram_pkt_empty_d1 <= #`TCQ 1'b1; end end // Synchronize the empty in write domain always @ (posedge wr_rst_fwft_pkt_fifo or posedge WR_CLK) begin if (wr_rst_fwft_pkt_fifo) pkt_empty_sync <= 'b1; else pkt_empty_sync <= #`TCQ {pkt_empty_sync[C_SYNCHRONIZER_STAGE-2:0], empty_p0_out}; end end endgenerate //gras_pkt_cnt generate if (IS_FWFT == 0 || C_FIFO_TYPE == 3) begin : STD_FIFO //*********************************************** // If NOT First-Word Fall-Through, wire the outputs // of the internal _ss or _as FIFO directly to the // output, and do not instantiate the preload0 // module. //*********************************************** assign RD_CLK_P0_IN = 0; assign RST_P0_IN = 0; assign RD_EN_P0_IN = 0; assign RD_EN_FIFO_IN = rd_en_delayed; assign DOUT = DOUT_FIFO_OUT; assign DATA_P0_IN = 0; assign VALID = VALID_FIFO_OUT; assign EMPTY = EMPTY_FIFO_OUT; assign ALMOST_EMPTY = ALMOST_EMPTY_FIFO_OUT; assign EMPTY_P0_IN = 0; assign UNDERFLOW = UNDERFLOW_FIFO_OUT; assign DATA_COUNT = DATA_COUNT_FIFO_OUT; assign SBITERR = sbiterr_fifo_out; assign DBITERR = dbiterr_fifo_out; end endgenerate // STD_FIFO generate if (IS_FWFT == 1 && C_FIFO_TYPE != 1) begin : NO_PKT_FIFO assign empty_p0_out = empty_fwft; assign SBITERR = sbiterr_fwft; assign DBITERR = dbiterr_fwft; assign DOUT = dout_fwft; assign RD_EN_P0_IN = (C_FIFO_TYPE != 1) ? rd_en_delayed : rd_en_to_fwft_fifo; end endgenerate // NO_PKT_FIFO //*********************************************** // Connect user flags to internal signals //*********************************************** //If we are using extra logic for the FWFT data count, then override the //RD_DATA_COUNT output when we are EMPTY or ALMOST_EMPTY. //RD_DATA_COUNT is 0 when EMPTY and 1 when ALMOST_EMPTY. generate if (C_USE_FWFT_DATA_COUNT==1 && (C_RD_DATA_COUNT_WIDTH>C_RD_PNTR_WIDTH) ) begin : block3 if (C_COMMON_CLOCK == 0) begin : block_ic assign RD_DATA_COUNT = (EMPTY_P0_OUT_Q | RST_P0_IN) ? 0 : (ALMOSTEMPTY_P0_OUT_Q ? 1 : RD_DATA_COUNT_FIFO_OUT); end //block_ic else begin assign RD_DATA_COUNT = RD_DATA_COUNT_FIFO_OUT; end end //block3 endgenerate //If we are using extra logic for the FWFT data count, then override the //RD_DATA_COUNT output when we are EMPTY or ALMOST_EMPTY. //Due to asymmetric ports, RD_DATA_COUNT is 0 when EMPTY or ALMOST_EMPTY. generate if (C_USE_FWFT_DATA_COUNT==1 && (C_RD_DATA_COUNT_WIDTH <=C_RD_PNTR_WIDTH) ) begin : block30 if (C_COMMON_CLOCK == 0) begin : block_ic assign RD_DATA_COUNT = (EMPTY_P0_OUT_Q | RST_P0_IN) ? 0 : (ALMOSTEMPTY_P0_OUT_Q ? 0 : RD_DATA_COUNT_FIFO_OUT); end else begin assign RD_DATA_COUNT = RD_DATA_COUNT_FIFO_OUT; end end //block30 endgenerate //If we are not using extra logic for the FWFT data count, //then connect RD_DATA_COUNT to the RD_DATA_COUNT from the //internal FIFO instance generate if (C_USE_FWFT_DATA_COUNT==0 ) begin : block31 assign RD_DATA_COUNT = RD_DATA_COUNT_FIFO_OUT; end endgenerate //Always connect WR_DATA_COUNT to the WR_DATA_COUNT from the internal //FIFO instance generate if (C_USE_FWFT_DATA_COUNT==1) begin : block4 assign WR_DATA_COUNT = WR_DATA_COUNT_FIFO_OUT; end else begin : block4 assign WR_DATA_COUNT = WR_DATA_COUNT_FIFO_OUT; end endgenerate //Connect other flags to the internal FIFO instance assign FULL = FULL_FIFO_OUT; assign ALMOST_FULL = ALMOST_FULL_FIFO_OUT; assign WR_ACK = WR_ACK_FIFO_OUT; assign OVERFLOW = OVERFLOW_FIFO_OUT; assign PROG_FULL = PROG_FULL_FIFO_OUT; assign PROG_EMPTY = PROG_EMPTY_FIFO_OUT; /************************************************************************** * find_log2 * Returns the 'log2' value for the input value for the supported ratios ***************************************************************************/ function integer find_log2; input integer int_val; integer i,j; begin i = 1; j = 0; for (i = 1; i < int_val; i = i*2) begin j = j + 1; end find_log2 = j; end endfunction /************************************************************************** * Internal reset logic **************************************************************************/ assign wr_rst_i = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? wr_rst_reg : 0; assign rd_rst_i = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? rd_rst_reg : 0; assign rst_i = C_HAS_RST ? rst_reg : 0; wire rst_2_sync; wire clk_2_sync = (C_COMMON_CLOCK == 1) ? CLK : WR_CLK; generate if (C_ENABLE_RST_SYNC == 0) begin : gnrst_sync always @* begin wr_rst_reg <= wr_rst_delayed; rd_rst_reg <= rd_rst_delayed; rst_reg <= 1'b0; srst_reg <= 1'b0; end assign rst_2_sync = wr_rst_delayed; assign wr_rst_busy = 1'b0; assign rd_rst_busy = 1'b0; end else if (C_HAS_RST == 1 && C_COMMON_CLOCK == 0) begin : g7s_ic_rst assign wr_rst_comb = !wr_rst_asreg_d2 && wr_rst_asreg; assign rd_rst_comb = !rd_rst_asreg_d2 && rd_rst_asreg; assign rst_2_sync = rst_delayed; assign wr_rst_busy = 1'b0; assign rd_rst_busy = 1'b0; always @(posedge WR_CLK or posedge rst_delayed) begin if (rst_delayed == 1'b1) begin wr_rst_asreg <= #`TCQ 1'b1; end else begin if (wr_rst_asreg_d1 == 1'b1) begin wr_rst_asreg <= #`TCQ 1'b0; end else begin wr_rst_asreg <= #`TCQ wr_rst_asreg; end end end always @(posedge WR_CLK) begin wr_rst_asreg_d1 <= #`TCQ wr_rst_asreg; wr_rst_asreg_d2 <= #`TCQ wr_rst_asreg_d1; end always @(posedge WR_CLK or posedge wr_rst_comb) begin if (wr_rst_comb == 1'b1) begin wr_rst_reg <= #`TCQ 1'b1; end else begin wr_rst_reg <= #`TCQ 1'b0; end end always @(posedge RD_CLK or posedge rst_delayed) begin if (rst_delayed == 1'b1) begin rd_rst_asreg <= #`TCQ 1'b1; end else begin if (rd_rst_asreg_d1 == 1'b1) begin rd_rst_asreg <= #`TCQ 1'b0; end else begin rd_rst_asreg <= #`TCQ rd_rst_asreg; end end end always @(posedge RD_CLK) begin rd_rst_asreg_d1 <= #`TCQ rd_rst_asreg; rd_rst_asreg_d2 <= #`TCQ rd_rst_asreg_d1; end always @(posedge RD_CLK or posedge rd_rst_comb) begin if (rd_rst_comb == 1'b1) begin rd_rst_reg <= #`TCQ 1'b1; end else begin rd_rst_reg <= #`TCQ 1'b0; end end end else if (C_HAS_RST == 1 && C_COMMON_CLOCK == 1) begin : g7s_cc_rst assign rst_comb = !rst_asreg_d2 && rst_asreg; assign rst_2_sync = rst_delayed; assign wr_rst_busy = 1'b0; assign rd_rst_busy = 1'b0; always @(posedge CLK or posedge rst_delayed) begin if (rst_delayed == 1'b1) begin rst_asreg <= #`TCQ 1'b1; end else begin if (rst_asreg_d1 == 1'b1) begin rst_asreg <= #`TCQ 1'b0; end else begin rst_asreg <= #`TCQ rst_asreg; end end end always @(posedge CLK) begin rst_asreg_d1 <= #`TCQ rst_asreg; rst_asreg_d2 <= #`TCQ rst_asreg_d1; end always @(posedge CLK or posedge rst_comb) begin if (rst_comb == 1'b1) begin rst_reg <= #`TCQ 1'b1; end else begin rst_reg <= #`TCQ 1'b0; end end end else if (IS_8SERIES == 1 && C_HAS_SRST == 1 && C_COMMON_CLOCK == 1) begin : g8s_cc_rst assign wr_rst_busy = (C_MEMORY_TYPE != 4) ? rst_reg : rst_active_i; assign rd_rst_busy = rst_reg; assign rst_2_sync = srst_delayed; always @* rst_full_ff_i <= rst_reg; always @* rst_full_gen_i <= C_FULL_FLAGS_RST_VAL == 1 ? rst_active_i : 0; always @(posedge CLK) begin rst_delayed_d1 <= #`TCQ srst_delayed; rst_delayed_d2 <= #`TCQ rst_delayed_d1; if (rst_reg || rst_delayed_d2) begin rst_active_i <= #`TCQ 1'b1; end else begin rst_active_i <= #`TCQ rst_reg; end end always @(posedge CLK) begin if (~rst_reg && srst_delayed) begin rst_reg <= #`TCQ 1'b1; end else if (rst_reg) begin rst_reg <= #`TCQ 1'b0; end else begin rst_reg <= #`TCQ rst_reg; end end end else begin assign wr_rst_busy = 1'b0; assign rd_rst_busy = 1'b0; end // end g8s_cc_rst endgenerate reg rst_d1 = 1'b0; reg rst_d2 = 1'b0; reg rst_d3 = 1'b0; reg rst_d4 = 1'b0; generate if ((C_HAS_RST == 1 || C_HAS_SRST == 1 || C_ENABLE_RST_SYNC == 0) && C_FULL_FLAGS_RST_VAL == 1) begin : grstd1 // RST_FULL_GEN replaces the reset falling edge detection used to de-assert // FULL, ALMOST_FULL & PROG_FULL flags if C_FULL_FLAGS_RST_VAL = 1. // RST_FULL_FF goes to the reset pin of the final flop of FULL, ALMOST_FULL & // PROG_FULL always @ (posedge rst_2_sync or posedge clk_2_sync) begin if (rst_2_sync) begin rst_d1 <= 1'b1; rst_d2 <= 1'b1; rst_d3 <= 1'b1; rst_d4 <= 1'b0; end else begin if (srst_delayed) begin rst_d1 <= #`TCQ 1'b1; rst_d2 <= #`TCQ 1'b1; rst_d3 <= #`TCQ 1'b1; rst_d4 <= #`TCQ 1'b0; end else begin rst_d1 <= #`TCQ 1'b0; rst_d2 <= #`TCQ rst_d1; rst_d3 <= #`TCQ rst_d2; rst_d4 <= #`TCQ rst_d3; end end end always @* rst_full_ff_i <= (C_HAS_SRST == 0) ? rst_d2 : 1'b0 ; always @* rst_full_gen_i <= rst_d4; end else if ((C_HAS_RST == 1 || C_HAS_SRST == 1 || C_ENABLE_RST_SYNC == 0) && C_FULL_FLAGS_RST_VAL == 0) begin : gnrst_full always @* rst_full_ff_i <= (C_COMMON_CLOCK == 0) ? wr_rst_i : rst_i; end endgenerate // grstd1 endmodule //FIFO_GENERATOR_v12_0_CONV_VER module fifo_generator_v12_0_sync_stage #( parameter C_WIDTH = 10 ) ( input RST, input CLK, input [C_WIDTH-1:0] DIN, output reg [C_WIDTH-1:0] DOUT = 0 ); always @ (posedge RST or posedge CLK) begin if (RST) DOUT <= 0; else DOUT <= #`TCQ DIN; end endmodule // fifo_generator_v12_0_sync_stage /******************************************************************************* * Declaration of Independent-Clocks FIFO Module ******************************************************************************/ module fifo_generator_v12_0_bhv_ver_as /*************************************************************************** * Declare user parameters and their defaults ***************************************************************************/ #( parameter C_FAMILY = "virtex7", parameter C_DATA_COUNT_WIDTH = 2, parameter C_DIN_WIDTH = 8, parameter C_DOUT_RST_VAL = "", parameter C_DOUT_WIDTH = 8, parameter C_FULL_FLAGS_RST_VAL = 1, parameter C_HAS_ALMOST_EMPTY = 0, parameter C_HAS_ALMOST_FULL = 0, parameter C_HAS_DATA_COUNT = 0, parameter C_HAS_OVERFLOW = 0, parameter C_HAS_RD_DATA_COUNT = 0, parameter C_HAS_RST = 0, parameter C_HAS_UNDERFLOW = 0, parameter C_HAS_VALID = 0, parameter C_HAS_WR_ACK = 0, parameter C_HAS_WR_DATA_COUNT = 0, parameter C_IMPLEMENTATION_TYPE = 0, parameter C_MEMORY_TYPE = 1, parameter C_OVERFLOW_LOW = 0, parameter C_PRELOAD_LATENCY = 1, parameter C_PRELOAD_REGS = 0, parameter C_PROG_EMPTY_THRESH_ASSERT_VAL = 0, parameter C_PROG_EMPTY_THRESH_NEGATE_VAL = 0, parameter C_PROG_EMPTY_TYPE = 0, parameter C_PROG_FULL_THRESH_ASSERT_VAL = 0, parameter C_PROG_FULL_THRESH_NEGATE_VAL = 0, parameter C_PROG_FULL_TYPE = 0, parameter C_RD_DATA_COUNT_WIDTH = 2, parameter C_RD_DEPTH = 256, parameter C_RD_PNTR_WIDTH = 8, parameter C_UNDERFLOW_LOW = 0, parameter C_USE_DOUT_RST = 0, parameter C_USE_EMBEDDED_REG = 0, parameter C_USE_FWFT_DATA_COUNT = 0, parameter C_VALID_LOW = 0, parameter C_WR_ACK_LOW = 0, parameter C_WR_DATA_COUNT_WIDTH = 2, parameter C_WR_DEPTH = 256, parameter C_WR_PNTR_WIDTH = 8, parameter C_USE_ECC = 0, parameter C_ENABLE_RST_SYNC = 1, parameter C_ERROR_INJECTION_TYPE = 0, parameter C_SYNCHRONIZER_STAGE = 2 ) /*************************************************************************** * Declare Input and Output Ports ***************************************************************************/ ( input [C_DIN_WIDTH-1:0] DIN, input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH, input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT, input [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE, input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH, input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT, input [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE, input RD_CLK, input RD_EN, input RD_EN_USER, input RST, input RST_FULL_GEN, input RST_FULL_FF, input WR_RST, input RD_RST, input WR_CLK, input WR_EN, input INJECTDBITERR, input INJECTSBITERR, input USER_EMPTY_FB, output reg ALMOST_EMPTY = 1'b1, output reg ALMOST_FULL = C_FULL_FLAGS_RST_VAL, output [C_DOUT_WIDTH-1:0] DOUT, output reg EMPTY = 1'b1, output reg FULL = C_FULL_FLAGS_RST_VAL, output OVERFLOW, output PROG_EMPTY, output PROG_FULL, output VALID, output [C_RD_DATA_COUNT_WIDTH-1:0] RD_DATA_COUNT, output UNDERFLOW, output WR_ACK, output [C_WR_DATA_COUNT_WIDTH-1:0] WR_DATA_COUNT, output SBITERR, output DBITERR ); reg [C_RD_PNTR_WIDTH:0] rd_data_count_int = 0; reg [C_WR_PNTR_WIDTH:0] wr_data_count_int = 0; reg [C_WR_PNTR_WIDTH:0] wdc_fwft_ext_as = 0; /*************************************************************************** * Parameters used as constants **************************************************************************/ localparam IS_8SERIES = (C_FAMILY == "virtexu" || C_FAMILY == "kintexu" || C_FAMILY == "artixu" || C_FAMILY == "virtexum" || C_FAMILY == "zynque") ? 1 : 0; //When RST is present, set FULL reset value to '1'. //If core has no RST, make sure FULL powers-on as '0'. localparam C_DEPTH_RATIO_WR = (C_WR_DEPTH>C_RD_DEPTH) ? (C_WR_DEPTH/C_RD_DEPTH) : 1; localparam C_DEPTH_RATIO_RD = (C_RD_DEPTH>C_WR_DEPTH) ? (C_RD_DEPTH/C_WR_DEPTH) : 1; localparam C_FIFO_WR_DEPTH = C_WR_DEPTH - 1; localparam C_FIFO_RD_DEPTH = C_RD_DEPTH - 1; // C_DEPTH_RATIO_WR | C_DEPTH_RATIO_RD | C_PNTR_WIDTH | EXTRA_WORDS_DC // -----------------|------------------|-----------------|--------------- // 1 | 8 | C_RD_PNTR_WIDTH | 2 // 1 | 4 | C_RD_PNTR_WIDTH | 2 // 1 | 2 | C_RD_PNTR_WIDTH | 2 // 1 | 1 | C_WR_PNTR_WIDTH | 2 // 2 | 1 | C_WR_PNTR_WIDTH | 4 // 4 | 1 | C_WR_PNTR_WIDTH | 8 // 8 | 1 | C_WR_PNTR_WIDTH | 16 localparam C_PNTR_WIDTH = (C_WR_PNTR_WIDTH>=C_RD_PNTR_WIDTH) ? C_WR_PNTR_WIDTH : C_RD_PNTR_WIDTH; wire [C_PNTR_WIDTH:0] EXTRA_WORDS_DC = (C_DEPTH_RATIO_WR == 1) ? 2 : (2 * C_DEPTH_RATIO_WR/C_DEPTH_RATIO_RD); localparam [31:0] reads_per_write = C_DIN_WIDTH/C_DOUT_WIDTH; localparam [31:0] log2_reads_per_write = log2_val(reads_per_write); localparam [31:0] writes_per_read = C_DOUT_WIDTH/C_DIN_WIDTH; localparam [31:0] log2_writes_per_read = log2_val(writes_per_read); /************************************************************************** * FIFO Contents Tracking and Data Count Calculations *************************************************************************/ // Memory which will be used to simulate a FIFO reg [C_DIN_WIDTH-1:0] memory[C_WR_DEPTH-1:0]; // Local parameters used to determine whether to inject ECC error or not localparam SYMMETRIC_PORT = (C_DIN_WIDTH == C_DOUT_WIDTH) ? 1 : 0; localparam ERR_INJECTION = (C_ERROR_INJECTION_TYPE != 0) ? 1 : 0; localparam ENABLE_ERR_INJECTION = C_USE_ECC && SYMMETRIC_PORT && ERR_INJECTION; // Array that holds the error injection type (single/double bit error) on // a specific write operation, which is returned on read to corrupt the // output data. reg [1:0] ecc_err[C_WR_DEPTH-1:0]; //The amount of data stored in the FIFO at any time is given // by num_wr_bits (in the WR_CLK domain) and num_rd_bits (in the RD_CLK // domain. //num_wr_bits is calculated by considering the total words in the FIFO, // and the state of the read pointer (which may not have yet crossed clock // domains.) //num_rd_bits is calculated by considering the total words in the FIFO, // and the state of the write pointer (which may not have yet crossed clock // domains.) reg [31:0] num_wr_bits; reg [31:0] num_rd_bits; reg [31:0] next_num_wr_bits; reg [31:0] next_num_rd_bits; //The write pointer - tracks write operations // (Works opposite to core: wr_ptr is a DOWN counter) reg [31:0] wr_ptr; reg [C_WR_PNTR_WIDTH-1:0] wr_pntr = 0; // UP counter: Rolls back to 0 when reaches to max value. reg [C_WR_PNTR_WIDTH-1:0] wr_pntr_rd1 = 0; reg [C_WR_PNTR_WIDTH-1:0] wr_pntr_rd2 = 0; reg [C_WR_PNTR_WIDTH-1:0] wr_pntr_rd3 = 0; wire [C_RD_PNTR_WIDTH-1:0] adj_wr_pntr_rd; reg [C_WR_PNTR_WIDTH-1:0] wr_pntr_rd = 0; wire wr_rst_i = WR_RST; reg wr_rst_d1 =0; //The read pointer - tracks read operations // (rd_ptr Works opposite to core: rd_ptr is a DOWN counter) reg [31:0] rd_ptr; reg [C_RD_PNTR_WIDTH-1:0] rd_pntr = 0; // UP counter: Rolls back to 0 when reaches to max value. reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr1 = 0; reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr2 = 0; reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr3 = 0; reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr4 = 0; wire [C_WR_PNTR_WIDTH-1:0] adj_rd_pntr_wr; reg [C_RD_PNTR_WIDTH-1:0] rd_pntr_wr = 0; wire rd_rst_i = RD_RST; wire ram_rd_en; wire empty_int; wire almost_empty_int; wire ram_wr_en; wire full_int; wire almost_full_int; reg ram_rd_en_d1 = 1'b0; // Delayed ram_rd_en is needed only for STD Embedded register option generate if (C_PRELOAD_LATENCY == 2) begin : grd_d always @ (posedge RD_CLK or posedge rd_rst_i) begin if (rd_rst_i) ram_rd_en_d1 <= #`TCQ 1'b0; else ram_rd_en_d1 <= #`TCQ ram_rd_en; end end endgenerate // Write pointer adjustment based on pointers width for EMPTY/ALMOST_EMPTY generation //ANDREAS: NOP generate if (C_RD_PNTR_WIDTH > C_WR_PNTR_WIDTH) begin : rdg // Read depth greater than write depth assign adj_wr_pntr_rd[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr_rd; assign adj_wr_pntr_rd[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1:0] = 0; end else begin : rdl // Read depth lesser than or equal to write depth assign adj_wr_pntr_rd = wr_pntr_rd[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH]; end endgenerate // Generate Empty and Almost Empty // ram_rd_en used to determine EMPTY should depend on the EMPTY. assign ram_rd_en = RD_EN & !EMPTY; assign empty_int = ((adj_wr_pntr_rd == rd_pntr) || (ram_rd_en && (adj_wr_pntr_rd == (rd_pntr+1'h1)))); assign almost_empty_int = ((adj_wr_pntr_rd == (rd_pntr+1'h1)) || (ram_rd_en && (adj_wr_pntr_rd == (rd_pntr+2'h2)))); // Register Empty and Almost Empty always @ (posedge RD_CLK or posedge rd_rst_i) begin if (rd_rst_i) begin EMPTY <= #`TCQ 1'b1; ALMOST_EMPTY <= #`TCQ 1'b1; rd_data_count_int <= #`TCQ {C_RD_PNTR_WIDTH{1'b0}}; end else begin rd_data_count_int <= #`TCQ {(adj_wr_pntr_rd[C_RD_PNTR_WIDTH-1:0] - rd_pntr[C_RD_PNTR_WIDTH-1:0]), 1'b0}; if (empty_int) EMPTY <= #`TCQ 1'b1; else EMPTY <= #`TCQ 1'b0; if (!EMPTY) begin if (almost_empty_int) ALMOST_EMPTY <= #`TCQ 1'b1; else ALMOST_EMPTY <= #`TCQ 1'b0; end end // rd_rst_i end // always // Read pointer adjustment based on pointers width for EMPTY/ALMOST_EMPTY generation generate if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin : wdg // Write depth greater than read depth assign adj_rd_pntr_wr[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH] = rd_pntr_wr; assign adj_rd_pntr_wr[C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH-1:0] = 0; end else begin : wdl // Write depth lesser than or equal to read depth assign adj_rd_pntr_wr = rd_pntr_wr[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH]; end endgenerate // Generate FULL and ALMOST_FULL // ram_wr_en used to determine FULL should depend on the FULL. assign ram_wr_en = WR_EN & !FULL; assign full_int = ((adj_rd_pntr_wr == (wr_pntr+1'h1)) || (ram_wr_en && (adj_rd_pntr_wr == (wr_pntr+2'h2)))); assign almost_full_int = ((adj_rd_pntr_wr == (wr_pntr+2'h2)) || (ram_wr_en && (adj_rd_pntr_wr == (wr_pntr+3'h3)))); // Register FULL and ALMOST_FULL Empty always @ (posedge WR_CLK or posedge RST_FULL_FF) begin if (RST_FULL_FF) begin FULL <= #`TCQ C_FULL_FLAGS_RST_VAL; ALMOST_FULL <= #`TCQ C_FULL_FLAGS_RST_VAL; end else begin if (full_int) begin FULL <= #`TCQ 1'b1; end else begin FULL <= #`TCQ 1'b0; end if (RST_FULL_GEN) begin ALMOST_FULL <= #`TCQ 1'b0; end else if (!FULL) begin if (almost_full_int) ALMOST_FULL <= #`TCQ 1'b1; else ALMOST_FULL <= #`TCQ 1'b0; end end // wr_rst_i end // always always @ (posedge WR_CLK or posedge wr_rst_i) begin if (wr_rst_i) begin wr_data_count_int <= #`TCQ {C_WR_DATA_COUNT_WIDTH{1'b0}}; end else begin wr_data_count_int <= #`TCQ {(wr_pntr[C_WR_PNTR_WIDTH-1:0] - adj_rd_pntr_wr[C_WR_PNTR_WIDTH-1:0]), 1'b0}; end // wr_rst_i end // always // Determine which stage in FWFT registers are valid reg stage1_valid = 0; reg stage2_valid = 0; generate if (C_PRELOAD_LATENCY == 0) begin : grd_fwft_proc always @ (posedge RD_CLK or posedge rd_rst_i) begin if (rd_rst_i) begin stage1_valid <= #`TCQ 0; stage2_valid <= #`TCQ 0; end else begin if (!stage1_valid && !stage2_valid) begin if (!EMPTY) stage1_valid <= #`TCQ 1'b1; else stage1_valid <= #`TCQ 1'b0; end else if (stage1_valid && !stage2_valid) begin if (EMPTY) begin stage1_valid <= #`TCQ 1'b0; stage2_valid <= #`TCQ 1'b1; end else begin stage1_valid <= #`TCQ 1'b1; stage2_valid <= #`TCQ 1'b1; end end else if (!stage1_valid && stage2_valid) begin if (EMPTY && RD_EN_USER) begin stage1_valid <= #`TCQ 1'b0; stage2_valid <= #`TCQ 1'b0; end else if (!EMPTY && RD_EN_USER) begin stage1_valid <= #`TCQ 1'b1; stage2_valid <= #`TCQ 1'b0; end else if (!EMPTY && !RD_EN_USER) begin stage1_valid <= #`TCQ 1'b1; stage2_valid <= #`TCQ 1'b1; end else begin stage1_valid <= #`TCQ 1'b0; stage2_valid <= #`TCQ 1'b1; end end else if (stage1_valid && stage2_valid) begin if (EMPTY && RD_EN_USER) begin stage1_valid <= #`TCQ 1'b0; stage2_valid <= #`TCQ 1'b1; end else begin stage1_valid <= #`TCQ 1'b1; stage2_valid <= #`TCQ 1'b1; end end else begin stage1_valid <= #`TCQ 1'b0; stage2_valid <= #`TCQ 1'b0; end end // rd_rst_i end // always end endgenerate //Pointers passed into opposite clock domain reg [31:0] wr_ptr_rdclk; reg [31:0] wr_ptr_rdclk_next; reg [31:0] rd_ptr_wrclk; reg [31:0] rd_ptr_wrclk_next; //Amount of data stored in the FIFO scaled to the narrowest (deepest) port // (Do not include data in FWFT stages) //Used to calculate PROG_EMPTY. wire [31:0] num_read_words_pe = num_rd_bits/(C_DOUT_WIDTH/C_DEPTH_RATIO_WR); //Amount of data stored in the FIFO scaled to the narrowest (deepest) port // (Do not include data in FWFT stages) //Used to calculate PROG_FULL. wire [31:0] num_write_words_pf = num_wr_bits/(C_DIN_WIDTH/C_DEPTH_RATIO_RD); /************************** * Read Data Count *************************/ reg [31:0] num_read_words_dc; reg [C_RD_DATA_COUNT_WIDTH-1:0] num_read_words_sized_i; always @(num_rd_bits) begin if (C_USE_FWFT_DATA_COUNT) begin //If using extra logic for FWFT Data Counts, // then scale FIFO contents to read domain, // and add two read words for FWFT stages //This value is only a temporary value and not used in the code. num_read_words_dc = (num_rd_bits/C_DOUT_WIDTH+2); //Trim the read words for use with RD_DATA_COUNT num_read_words_sized_i = num_read_words_dc[C_RD_PNTR_WIDTH : C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH+1]; end else begin //If not using extra logic for FWFT Data Counts, // then scale FIFO contents to read domain. //This value is only a temporary value and not used in the code. num_read_words_dc = num_rd_bits/C_DOUT_WIDTH; //Trim the read words for use with RD_DATA_COUNT num_read_words_sized_i = num_read_words_dc[C_RD_PNTR_WIDTH-1 : C_RD_PNTR_WIDTH-C_RD_DATA_COUNT_WIDTH]; end //if (C_USE_FWFT_DATA_COUNT) end //always /************************** * Write Data Count *************************/ reg [31:0] num_write_words_dc; reg [C_WR_DATA_COUNT_WIDTH-1:0] num_write_words_sized_i; always @(num_wr_bits) begin if (C_USE_FWFT_DATA_COUNT) begin //Calculate the Data Count value for the number of write words, // when using First-Word Fall-Through with extra logic for Data // Counts. This takes into consideration the number of words that // are expected to be stored in the FWFT register stages (it always // assumes they are filled). //This value is scaled to the Write Domain. //The expression (((A-1)/B))+1 divides A/B, but takes the // ceiling of the result. //When num_wr_bits==0, set the result manually to prevent // division errors. //EXTRA_WORDS_DC is the number of words added to write_words // due to FWFT. //This value is only a temporary value and not used in the code. num_write_words_dc = (num_wr_bits==0) ? EXTRA_WORDS_DC : (((num_wr_bits-1)/C_DIN_WIDTH)+1) + EXTRA_WORDS_DC ; //Trim the write words for use with WR_DATA_COUNT num_write_words_sized_i = num_write_words_dc[C_WR_PNTR_WIDTH : C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH+1]; end else begin //Calculate the Data Count value for the number of write words, when NOT // using First-Word Fall-Through with extra logic for Data Counts. This // calculates only the number of words in the internal FIFO. //The expression (((A-1)/B))+1 divides A/B, but takes the // ceiling of the result. //This value is scaled to the Write Domain. //When num_wr_bits==0, set the result manually to prevent // division errors. //This value is only a temporary value and not used in the code. num_write_words_dc = (num_wr_bits==0) ? 0 : ((num_wr_bits-1)/C_DIN_WIDTH)+1; //Trim the read words for use with RD_DATA_COUNT num_write_words_sized_i = num_write_words_dc[C_WR_PNTR_WIDTH-1 : C_WR_PNTR_WIDTH-C_WR_DATA_COUNT_WIDTH]; end //if (C_USE_FWFT_DATA_COUNT) end //always /*************************************************************************** * Internal registers and wires **************************************************************************/ //Temporary signals used for calculating the model's outputs. These //are only used in the assign statements immediately following wire, //parameter, and function declarations. wire [C_DOUT_WIDTH-1:0] ideal_dout_out; wire valid_i; wire valid_out; wire underflow_i; //Ideal FIFO signals. These are the raw output of the behavioral model, //which behaves like an ideal FIFO. reg [1:0] err_type = 0; reg [1:0] err_type_d1 = 0; reg [C_DOUT_WIDTH-1:0] ideal_dout = 0; reg [C_DOUT_WIDTH-1:0] ideal_dout_d1 = 0; reg ideal_wr_ack = 0; reg ideal_valid = 0; reg ideal_overflow = C_OVERFLOW_LOW; reg ideal_underflow = C_UNDERFLOW_LOW; reg ideal_prog_full = 0; reg ideal_prog_empty = 1; reg [C_WR_DATA_COUNT_WIDTH-1 : 0] ideal_wr_count = 0; reg [C_RD_DATA_COUNT_WIDTH-1 : 0] ideal_rd_count = 0; //Assorted reg values for delayed versions of signals reg valid_d1 = 0; //user specified value for reseting the size of the fifo reg [C_DOUT_WIDTH-1:0] dout_reset_val = 0; //temporary registers for WR_RESPONSE_LATENCY feature integer tmp_wr_listsize; integer tmp_rd_listsize; //Signal for registered version of prog full and empty //Threshold values for Programmable Flags integer prog_empty_actual_thresh_assert; integer prog_empty_actual_thresh_negate; integer prog_full_actual_thresh_assert; integer prog_full_actual_thresh_negate; /**************************************************************************** * Function Declarations ***************************************************************************/ /************************************************************************** * write_fifo * This task writes a word to the FIFO memory and updates the * write pointer. * FIFO size is relative to write domain. ***************************************************************************/ task write_fifo; begin //ANDREAS:$display("writing %x %d %m", DIN,wr_pntr); memory[wr_ptr] <= DIN; wr_pntr <= #`TCQ wr_pntr + 1; // Store the type of error injection (double/single) on write case (C_ERROR_INJECTION_TYPE) 3: ecc_err[wr_ptr] <= {INJECTDBITERR,INJECTSBITERR}; 2: ecc_err[wr_ptr] <= {INJECTDBITERR,1'b0}; 1: ecc_err[wr_ptr] <= {1'b0,INJECTSBITERR}; default: ecc_err[wr_ptr] <= 0; endcase // (Works opposite to core: wr_ptr is a DOWN counter) if (wr_ptr == 0) begin wr_ptr <= C_WR_DEPTH - 1; end else begin wr_ptr <= wr_ptr - 1; end end endtask // write_fifo /************************************************************************** * read_fifo * This task reads a word from the FIFO memory and updates the read * pointer. It's output is the ideal_dout bus. * FIFO size is relative to write domain. ***************************************************************************/ task read_fifo; integer i; reg [C_DOUT_WIDTH-1:0] tmp_dout; reg [C_DIN_WIDTH-1:0] memory_read; reg [31:0] tmp_rd_ptr; reg [31:0] rd_ptr_high; reg [31:0] rd_ptr_low; reg [1:0] tmp_ecc_err; begin rd_pntr <= #`TCQ rd_pntr + 1; // output is wider than input if (reads_per_write == 0) begin tmp_dout = 0; tmp_rd_ptr = (rd_ptr << log2_writes_per_read)+(writes_per_read-1); for (i = writes_per_read - 1; i >= 0; i = i - 1) begin tmp_dout = tmp_dout << C_DIN_WIDTH; tmp_dout = tmp_dout | memory[tmp_rd_ptr]; // (Works opposite to core: rd_ptr is a DOWN counter) if (tmp_rd_ptr == 0) begin tmp_rd_ptr = C_WR_DEPTH - 1; end else begin tmp_rd_ptr = tmp_rd_ptr - 1; end end // output is symmetric end else if (reads_per_write == 1) begin tmp_dout = memory[rd_ptr][C_DIN_WIDTH-1:0]; // Retreive the error injection type. Based on the error injection type // corrupt the output data. tmp_ecc_err = ecc_err[rd_ptr]; if (ENABLE_ERR_INJECTION && C_DIN_WIDTH == C_DOUT_WIDTH) begin if (tmp_ecc_err[1]) begin // Corrupt the output data only for double bit error if (C_DOUT_WIDTH == 1) begin $display("FAILURE : Data width must be >= 2 for double bit error injection."); $finish; end else if (C_DOUT_WIDTH == 2) tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2]}; else tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2],(tmp_dout << 2)}; end else begin tmp_dout = tmp_dout[C_DOUT_WIDTH-1:0]; end err_type <= {tmp_ecc_err[1], tmp_ecc_err[0] & !tmp_ecc_err[1]}; end else begin err_type <= 0; end // input is wider than output end else begin rd_ptr_high = rd_ptr >> log2_reads_per_write; rd_ptr_low = rd_ptr & (reads_per_write - 1); memory_read = memory[rd_ptr_high]; tmp_dout = memory_read >> (rd_ptr_low*C_DOUT_WIDTH); end ideal_dout <= tmp_dout; // (Works opposite to core: rd_ptr is a DOWN counter) if (rd_ptr == 0) begin rd_ptr <= C_RD_DEPTH - 1; end else begin rd_ptr <= rd_ptr - 1; end end endtask /************************************************************************** * log2_val * Returns the 'log2' value for the input value for the supported ratios ***************************************************************************/ function [31:0] log2_val; input [31:0] binary_val; begin if (binary_val == 8) begin log2_val = 3; end else if (binary_val == 4) begin log2_val = 2; end else begin log2_val = 1; end end endfunction /*********************************************************************** * hexstr_conv * Converts a string of type hex to a binary value (for C_DOUT_RST_VAL) ***********************************************************************/ function [C_DOUT_WIDTH-1:0] hexstr_conv; input [(C_DOUT_WIDTH*8)-1:0] def_data; integer index,i,j; reg [3:0] bin; begin index = 0; hexstr_conv = 'b0; for( i=C_DOUT_WIDTH-1; i>=0; i=i-1 ) begin case (def_data[7:0]) 8'b00000000 : begin bin = 4'b0000; i = -1; end 8'b00110000 : bin = 4'b0000; 8'b00110001 : bin = 4'b0001; 8'b00110010 : bin = 4'b0010; 8'b00110011 : bin = 4'b0011; 8'b00110100 : bin = 4'b0100; 8'b00110101 : bin = 4'b0101; 8'b00110110 : bin = 4'b0110; 8'b00110111 : bin = 4'b0111; 8'b00111000 : bin = 4'b1000; 8'b00111001 : bin = 4'b1001; 8'b01000001 : bin = 4'b1010; 8'b01000010 : bin = 4'b1011; 8'b01000011 : bin = 4'b1100; 8'b01000100 : bin = 4'b1101; 8'b01000101 : bin = 4'b1110; 8'b01000110 : bin = 4'b1111; 8'b01100001 : bin = 4'b1010; 8'b01100010 : bin = 4'b1011; 8'b01100011 : bin = 4'b1100; 8'b01100100 : bin = 4'b1101; 8'b01100101 : bin = 4'b1110; 8'b01100110 : bin = 4'b1111; default : begin bin = 4'bx; end endcase for( j=0; j<4; j=j+1) begin if ((index*4)+j < C_DOUT_WIDTH) begin hexstr_conv[(index*4)+j] = bin[j]; end end index = index + 1; def_data = def_data >> 8; end end endfunction /************************************************************************* * Initialize Signals for clean power-on simulation *************************************************************************/ initial begin num_wr_bits = 0; num_rd_bits = 0; next_num_wr_bits = 0; next_num_rd_bits = 0; rd_ptr = C_RD_DEPTH - 1; wr_ptr = C_WR_DEPTH - 1; wr_pntr = 0; rd_pntr = 0; rd_ptr_wrclk = rd_ptr; wr_ptr_rdclk = wr_ptr; dout_reset_val = hexstr_conv(C_DOUT_RST_VAL); ideal_dout = dout_reset_val; err_type = 0; ideal_dout_d1 = dout_reset_val; ideal_wr_ack = 1'b0; ideal_valid = 1'b0; valid_d1 = 1'b0; ideal_overflow = C_OVERFLOW_LOW; ideal_underflow = C_UNDERFLOW_LOW; ideal_wr_count = 0; ideal_rd_count = 0; ideal_prog_full = 1'b0; ideal_prog_empty = 1'b1; end /************************************************************************* * Connect the module inputs and outputs to the internal signals of the * behavioral model. *************************************************************************/ //Inputs /* wire [C_DIN_WIDTH-1:0] DIN; wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH; wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_ASSERT; wire [C_RD_PNTR_WIDTH-1:0] PROG_EMPTY_THRESH_NEGATE; wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH; wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_ASSERT; wire [C_WR_PNTR_WIDTH-1:0] PROG_FULL_THRESH_NEGATE; wire RD_CLK; wire RD_EN; wire RST; wire WR_CLK; wire WR_EN; */ //*************************************************************************** // Dout may change behavior based on latency //*************************************************************************** assign ideal_dout_out[C_DOUT_WIDTH-1:0] = (C_PRELOAD_LATENCY==2 && (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1))? ideal_dout_d1: ideal_dout; assign DOUT[C_DOUT_WIDTH-1:0] = ideal_dout_out; //*************************************************************************** // Assign SBITERR and DBITERR based on latency //*************************************************************************** assign SBITERR = (C_ERROR_INJECTION_TYPE == 1 || C_ERROR_INJECTION_TYPE == 3) && (C_PRELOAD_LATENCY == 2 && (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ? err_type_d1[0]: err_type[0]; assign DBITERR = (C_ERROR_INJECTION_TYPE == 2 || C_ERROR_INJECTION_TYPE == 3) && (C_PRELOAD_LATENCY==2 && (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1)) ? err_type_d1[1]: err_type[1]; //*************************************************************************** // Overflow may be active-low //*************************************************************************** generate if (C_HAS_OVERFLOW==1) begin : blockOF1 assign OVERFLOW = ideal_overflow ? !C_OVERFLOW_LOW : C_OVERFLOW_LOW; end endgenerate assign PROG_EMPTY = ideal_prog_empty; assign PROG_FULL = ideal_prog_full; //*************************************************************************** // Valid may change behavior based on latency or active-low //*************************************************************************** generate if (C_HAS_VALID==1) begin : blockVL1 assign valid_i = (C_PRELOAD_LATENCY==0) ? (RD_EN & ~EMPTY) : ideal_valid; assign valid_out = (C_PRELOAD_LATENCY==2 && (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1))? valid_d1: valid_i; assign VALID = valid_out ? !C_VALID_LOW : C_VALID_LOW; end endgenerate //*************************************************************************** // Underflow may change behavior based on latency or active-low //*************************************************************************** generate if (C_HAS_UNDERFLOW==1) begin : blockUF1 assign underflow_i = (C_PRELOAD_LATENCY==0) ? (RD_EN & EMPTY) : ideal_underflow; assign UNDERFLOW = underflow_i ? !C_UNDERFLOW_LOW : C_UNDERFLOW_LOW; end endgenerate //*************************************************************************** // Write acknowledge may be active low //*************************************************************************** generate if (C_HAS_WR_ACK==1) begin : blockWK1 assign WR_ACK = ideal_wr_ack ? !C_WR_ACK_LOW : C_WR_ACK_LOW; end endgenerate //*************************************************************************** // Generate RD_DATA_COUNT if Use Extra Logic option is selected //*************************************************************************** generate if (C_HAS_WR_DATA_COUNT == 1 && C_USE_FWFT_DATA_COUNT == 1) begin : wdc_fwft_ext reg [C_PNTR_WIDTH-1:0] adjusted_wr_pntr = 0; reg [C_PNTR_WIDTH-1:0] adjusted_rd_pntr = 0; wire [C_PNTR_WIDTH-1:0] diff_wr_rd_tmp; wire [C_PNTR_WIDTH:0] diff_wr_rd; reg [C_PNTR_WIDTH:0] wr_data_count_i = 0; always @* begin if (C_WR_PNTR_WIDTH > C_RD_PNTR_WIDTH) begin adjusted_wr_pntr = wr_pntr; adjusted_rd_pntr = 0; adjusted_rd_pntr[C_PNTR_WIDTH-1:C_PNTR_WIDTH-C_RD_PNTR_WIDTH] = rd_pntr_wr; end else if (C_WR_PNTR_WIDTH < C_RD_PNTR_WIDTH) begin adjusted_rd_pntr = rd_pntr_wr; adjusted_wr_pntr = 0; adjusted_wr_pntr[C_PNTR_WIDTH-1:C_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr; end else begin adjusted_wr_pntr = wr_pntr; adjusted_rd_pntr = rd_pntr_wr; end end // always @* assign diff_wr_rd_tmp = adjusted_wr_pntr - adjusted_rd_pntr; assign diff_wr_rd = {1'b0,diff_wr_rd_tmp}; always @ (posedge wr_rst_i or posedge WR_CLK) begin if (wr_rst_i) wr_data_count_i <= #`TCQ 0; else wr_data_count_i <= #`TCQ diff_wr_rd + EXTRA_WORDS_DC; end // always @ (posedge WR_CLK or posedge WR_CLK) always @* begin if (C_WR_PNTR_WIDTH >= C_RD_PNTR_WIDTH) wdc_fwft_ext_as = wr_data_count_i[C_PNTR_WIDTH:0]; else wdc_fwft_ext_as = wr_data_count_i[C_PNTR_WIDTH:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH]; end // always @* end // wdc_fwft_ext endgenerate //*************************************************************************** // Generate RD_DATA_COUNT if Use Extra Logic option is selected //*************************************************************************** reg [C_RD_PNTR_WIDTH:0] rdc_fwft_ext_as = 0; generate if (C_HAS_RD_DATA_COUNT == 1 && C_USE_FWFT_DATA_COUNT == 1) begin : rdc_fwft_ext reg [C_RD_PNTR_WIDTH-1:0] adjusted_wr_pntr_rd = 0; wire [C_RD_PNTR_WIDTH-1:0] diff_rd_wr_tmp; wire [C_RD_PNTR_WIDTH:0] diff_rd_wr; always @* begin if (C_RD_PNTR_WIDTH > C_WR_PNTR_WIDTH) begin adjusted_wr_pntr_rd = 0; adjusted_wr_pntr_rd[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr_rd; end else begin adjusted_wr_pntr_rd = wr_pntr_rd[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH]; end end // always @* assign diff_rd_wr_tmp = adjusted_wr_pntr_rd - rd_pntr; assign diff_rd_wr = {1'b0,diff_rd_wr_tmp}; always @ (posedge rd_rst_i or posedge RD_CLK) begin if (rd_rst_i) begin rdc_fwft_ext_as <= #`TCQ 0; end else begin if (!stage2_valid) rdc_fwft_ext_as <= #`TCQ 0; else if (!stage1_valid && stage2_valid) rdc_fwft_ext_as <= #`TCQ 1; else rdc_fwft_ext_as <= #`TCQ diff_rd_wr + 2'h2; end end // always @ (posedge WR_CLK or posedge WR_CLK) end // rdc_fwft_ext endgenerate //*************************************************************************** // Assign the read data count value only if it is selected, // otherwise output zeros. //*************************************************************************** generate if (C_HAS_RD_DATA_COUNT == 1) begin : grdc assign RD_DATA_COUNT[C_RD_DATA_COUNT_WIDTH-1:0] = C_USE_FWFT_DATA_COUNT ? rdc_fwft_ext_as[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH+1-C_RD_DATA_COUNT_WIDTH] : rd_data_count_int[C_RD_PNTR_WIDTH:C_RD_PNTR_WIDTH+1-C_RD_DATA_COUNT_WIDTH]; end endgenerate generate if (C_HAS_RD_DATA_COUNT == 0) begin : gnrdc assign RD_DATA_COUNT[C_RD_DATA_COUNT_WIDTH-1:0] = {C_RD_DATA_COUNT_WIDTH{1'b0}}; end endgenerate //*************************************************************************** // Assign the write data count value only if it is selected, // otherwise output zeros //*************************************************************************** generate if (C_HAS_WR_DATA_COUNT == 1) begin : gwdc assign WR_DATA_COUNT[C_WR_DATA_COUNT_WIDTH-1:0] = (C_USE_FWFT_DATA_COUNT == 1) ? wdc_fwft_ext_as[C_WR_PNTR_WIDTH:C_WR_PNTR_WIDTH+1-C_WR_DATA_COUNT_WIDTH] : wr_data_count_int[C_WR_PNTR_WIDTH:C_WR_PNTR_WIDTH+1-C_WR_DATA_COUNT_WIDTH]; end endgenerate generate if (C_HAS_WR_DATA_COUNT == 0) begin : gnwdc assign WR_DATA_COUNT[C_WR_DATA_COUNT_WIDTH-1:0] = {C_WR_DATA_COUNT_WIDTH{1'b0}}; end endgenerate /************************************************************************** * Assorted registers for delayed versions of signals **************************************************************************/ //Capture delayed version of valid generate if (C_HAS_VALID==1) begin : blockVL2 always @(posedge RD_CLK or posedge rd_rst_i) begin if (rd_rst_i == 1'b1) begin valid_d1 <= #`TCQ 1'b0; end else begin valid_d1 <= #`TCQ valid_i; end end end endgenerate //Capture delayed version of dout always @(posedge RD_CLK or posedge rd_rst_i) begin if (rd_rst_i == 1'b1) begin // Reset err_type only if ECC is not selected if (C_USE_ECC == 0) err_type_d1 <= #`TCQ 0; end else if (ram_rd_en_d1) begin ideal_dout_d1 <= #`TCQ ideal_dout; err_type_d1 <= #`TCQ err_type; end end /************************************************************************** * Overflow and Underflow Flag calculation * (handled separately because they don't support rst) **************************************************************************/ generate if (C_HAS_OVERFLOW == 1 && IS_8SERIES == 0) begin : g7s_ovflw always @(posedge WR_CLK) begin ideal_overflow <= #`TCQ WR_EN & FULL; end end else if (C_HAS_OVERFLOW == 1 && IS_8SERIES == 1) begin : g8s_ovflw always @(posedge WR_CLK) begin //ideal_overflow <= #`TCQ WR_EN & (FULL | wr_rst_i); ideal_overflow <= #`TCQ WR_EN & (FULL ); end end endgenerate generate if (C_HAS_UNDERFLOW == 1 && IS_8SERIES == 0) begin : g7s_unflw always @(posedge RD_CLK) begin ideal_underflow <= #`TCQ EMPTY & RD_EN; end end else if (C_HAS_UNDERFLOW == 1 && IS_8SERIES == 1) begin : g8s_unflw always @(posedge RD_CLK) begin ideal_underflow <= #`TCQ (EMPTY) & RD_EN; //ideal_underflow <= #`TCQ (rd_rst_i | EMPTY) & RD_EN; end end endgenerate /************************************************************************** * Write/Read Pointer Synchronization **************************************************************************/ localparam NO_OF_SYNC_STAGE_INC_G2B = C_SYNCHRONIZER_STAGE + 1; wire [C_WR_PNTR_WIDTH-1:0] wr_pntr_sync_stgs [0:NO_OF_SYNC_STAGE_INC_G2B]; wire [C_RD_PNTR_WIDTH-1:0] rd_pntr_sync_stgs [0:NO_OF_SYNC_STAGE_INC_G2B]; genvar gss; generate for (gss = 1; gss <= NO_OF_SYNC_STAGE_INC_G2B; gss = gss + 1) begin : Sync_stage_inst fifo_generator_v12_0_sync_stage #( .C_WIDTH (C_WR_PNTR_WIDTH) ) rd_stg_inst ( .RST (rd_rst_i), .CLK (RD_CLK), .DIN (wr_pntr_sync_stgs[gss-1]), .DOUT (wr_pntr_sync_stgs[gss]) ); fifo_generator_v12_0_sync_stage #( .C_WIDTH (C_RD_PNTR_WIDTH) ) wr_stg_inst ( .RST (wr_rst_i), .CLK (WR_CLK), .DIN (rd_pntr_sync_stgs[gss-1]), .DOUT (rd_pntr_sync_stgs[gss]) ); end endgenerate // Sync_stage_inst assign wr_pntr_sync_stgs[0] = wr_pntr_rd1; assign rd_pntr_sync_stgs[0] = rd_pntr_wr1; always@* begin wr_pntr_rd <= wr_pntr_sync_stgs[NO_OF_SYNC_STAGE_INC_G2B]; rd_pntr_wr <= rd_pntr_sync_stgs[NO_OF_SYNC_STAGE_INC_G2B]; end /************************************************************************** * Write Domain Logic **************************************************************************/ reg [C_WR_PNTR_WIDTH-1:0] diff_pntr = 0; always @(posedge WR_CLK or posedge wr_rst_i) begin : gen_fifo_w /****** Reset fifo (case 1)***************************************/ if (wr_rst_i == 1'b1) begin num_wr_bits <= #`TCQ 0; next_num_wr_bits = #`TCQ 0; wr_ptr <= #`TCQ C_WR_DEPTH - 1; rd_ptr_wrclk <= #`TCQ C_RD_DEPTH - 1; ideal_wr_ack <= #`TCQ 0; ideal_wr_count <= #`TCQ 0; tmp_wr_listsize = #`TCQ 0; rd_ptr_wrclk_next <= #`TCQ 0; wr_pntr <= #`TCQ 0; wr_pntr_rd1 <= #`TCQ 0; end else begin //wr_rst_i==0 wr_pntr_rd1 <= #`TCQ wr_pntr; //Determine the current number of words in the FIFO tmp_wr_listsize = (C_DEPTH_RATIO_RD > 1) ? num_wr_bits/C_DOUT_WIDTH : num_wr_bits/C_DIN_WIDTH; rd_ptr_wrclk_next = rd_ptr; if (rd_ptr_wrclk < rd_ptr_wrclk_next) begin next_num_wr_bits = num_wr_bits - C_DOUT_WIDTH*(rd_ptr_wrclk + C_RD_DEPTH - rd_ptr_wrclk_next); end else begin next_num_wr_bits = num_wr_bits - C_DOUT_WIDTH*(rd_ptr_wrclk - rd_ptr_wrclk_next); end //If this is a write, handle the write by adding the value // to the linked list, and updating all outputs appropriately if (WR_EN == 1'b1) begin if (FULL == 1'b1) begin //If the FIFO is full, do NOT perform the write, // update flags accordingly if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD >= C_FIFO_WR_DEPTH) begin //write unsuccessful - do not change contents //Do not acknowledge the write ideal_wr_ack <= #`TCQ 0; //Reminder that FIFO is still full ideal_wr_count <= #`TCQ num_write_words_sized_i; //If the FIFO is one from full, but reporting full end else if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD == C_FIFO_WR_DEPTH-1) begin //No change to FIFO //Write not successful ideal_wr_ack <= #`TCQ 0; //With DEPTH-1 words in the FIFO, it is almost_full ideal_wr_count <= #`TCQ num_write_words_sized_i; //If the FIFO is completely empty, but it is // reporting FULL for some reason (like reset) end else if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD <= C_FIFO_WR_DEPTH-2) begin //No change to FIFO //Write not successful ideal_wr_ack <= #`TCQ 0; //FIFO is really not close to full, so change flag status. ideal_wr_count <= #`TCQ num_write_words_sized_i; end //(tmp_wr_listsize == 0) end else begin //If the FIFO is full, do NOT perform the write, // update flags accordingly if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD >= C_FIFO_WR_DEPTH) begin //write unsuccessful - do not change contents //Do not acknowledge the write ideal_wr_ack <= #`TCQ 0; //Reminder that FIFO is still full ideal_wr_count <= #`TCQ num_write_words_sized_i; //If the FIFO is one from full end else if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD == C_FIFO_WR_DEPTH-1) begin //Add value on DIN port to FIFO write_fifo; next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH; //Write successful, so issue acknowledge // and no error ideal_wr_ack <= #`TCQ 1; //This write is CAUSING the FIFO to go full ideal_wr_count <= #`TCQ num_write_words_sized_i; //If the FIFO is 2 from full end else if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD == C_FIFO_WR_DEPTH-2) begin //Add value on DIN port to FIFO $display("two from full"); write_fifo; next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH; //Write successful, so issue acknowledge // and no error ideal_wr_ack <= #`TCQ 1; //Still 2 from full ideal_wr_count <= #`TCQ num_write_words_sized_i; //If the FIFO is not close to being full end else if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD < C_FIFO_WR_DEPTH-2) begin //Add value on DIN port to FIFO write_fifo; next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH; //Write successful, so issue acknowledge // and no error ideal_wr_ack <= #`TCQ 1; //Not even close to full. ideal_wr_count <= num_write_words_sized_i; end end end else begin //(WR_EN == 1'b1) //If user did not attempt a write, then do not // give ack or err ideal_wr_ack <= #`TCQ 0; ideal_wr_count <= #`TCQ num_write_words_sized_i; end num_wr_bits <= #`TCQ next_num_wr_bits; rd_ptr_wrclk <= #`TCQ rd_ptr; end //wr_rst_i==0 end // gen_fifo_w /*************************************************************************** * Programmable FULL flags ***************************************************************************/ wire [C_WR_PNTR_WIDTH-1:0] pf_thr_assert_val; wire [C_WR_PNTR_WIDTH-1:0] pf_thr_negate_val; generate if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) begin : FWFT assign pf_thr_assert_val = C_PROG_FULL_THRESH_ASSERT_VAL - EXTRA_WORDS_DC; assign pf_thr_negate_val = C_PROG_FULL_THRESH_NEGATE_VAL - EXTRA_WORDS_DC; end else begin // STD assign pf_thr_assert_val = C_PROG_FULL_THRESH_ASSERT_VAL; assign pf_thr_negate_val = C_PROG_FULL_THRESH_NEGATE_VAL; end endgenerate always @(posedge WR_CLK or posedge wr_rst_i) begin if (wr_rst_i == 1'b1) begin diff_pntr <= 0; end else begin if (ram_wr_en) diff_pntr <= #`TCQ (wr_pntr - adj_rd_pntr_wr + 2'h1); else if (!ram_wr_en) diff_pntr <= #`TCQ (wr_pntr - adj_rd_pntr_wr); end end always @(posedge WR_CLK or posedge RST_FULL_FF) begin : gen_pf if (RST_FULL_FF == 1'b1) begin ideal_prog_full <= #`TCQ C_FULL_FLAGS_RST_VAL; end else begin if (RST_FULL_GEN) ideal_prog_full <= #`TCQ 0; //Single Programmable Full Constant Threshold else if (C_PROG_FULL_TYPE == 1) begin if (FULL == 0) begin if (diff_pntr >= pf_thr_assert_val) ideal_prog_full <= #`TCQ 1; else ideal_prog_full <= #`TCQ 0; end else ideal_prog_full <= #`TCQ ideal_prog_full; //Two Programmable Full Constant Thresholds end else if (C_PROG_FULL_TYPE == 2) begin if (FULL == 0) begin if (diff_pntr >= pf_thr_assert_val) ideal_prog_full <= #`TCQ 1; else if (diff_pntr < pf_thr_negate_val) ideal_prog_full <= #`TCQ 0; else ideal_prog_full <= #`TCQ ideal_prog_full; end else ideal_prog_full <= #`TCQ ideal_prog_full; //Single Programmable Full Threshold Input end else if (C_PROG_FULL_TYPE == 3) begin if (FULL == 0) begin if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) begin // FWFT if (diff_pntr >= (PROG_FULL_THRESH - EXTRA_WORDS_DC)) ideal_prog_full <= #`TCQ 1; else ideal_prog_full <= #`TCQ 0; end else begin // STD if (diff_pntr >= PROG_FULL_THRESH) ideal_prog_full <= #`TCQ 1; else ideal_prog_full <= #`TCQ 0; end end else ideal_prog_full <= #`TCQ ideal_prog_full; //Two Programmable Full Threshold Inputs end else if (C_PROG_FULL_TYPE == 4) begin if (FULL == 0) begin if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) begin // FWFT if (diff_pntr >= (PROG_FULL_THRESH_ASSERT - EXTRA_WORDS_DC)) ideal_prog_full <= #`TCQ 1; else if (diff_pntr < (PROG_FULL_THRESH_NEGATE - EXTRA_WORDS_DC)) ideal_prog_full <= #`TCQ 0; else ideal_prog_full <= #`TCQ ideal_prog_full; end else begin // STD if (diff_pntr >= PROG_FULL_THRESH_ASSERT) ideal_prog_full <= #`TCQ 1; else if (diff_pntr < PROG_FULL_THRESH_NEGATE) ideal_prog_full <= #`TCQ 0; else ideal_prog_full <= #`TCQ ideal_prog_full; end end else ideal_prog_full <= #`TCQ ideal_prog_full; end // C_PROG_FULL_TYPE end //wr_rst_i==0 end // /************************************************************************** * Read Domain Logic **************************************************************************/ /********************************************************* * Programmable EMPTY flags *********************************************************/ //Determine the Assert and Negate thresholds for Programmable Empty wire [C_RD_PNTR_WIDTH-1:0] pe_thr_assert_val; wire [C_RD_PNTR_WIDTH-1:0] pe_thr_negate_val; reg [C_RD_PNTR_WIDTH-1:0] diff_pntr_rd = 0; always @(posedge RD_CLK or posedge rd_rst_i) begin : gen_pe if (rd_rst_i) begin diff_pntr_rd <= #`TCQ 0; ideal_prog_empty <= #`TCQ 1'b1; end else begin if (ram_rd_en) diff_pntr_rd <= #`TCQ (adj_wr_pntr_rd - rd_pntr) - 1'h1; else if (!ram_rd_en) diff_pntr_rd <= #`TCQ (adj_wr_pntr_rd - rd_pntr); else diff_pntr_rd <= #`TCQ diff_pntr_rd; if (C_PROG_EMPTY_TYPE == 1) begin if (EMPTY == 0) begin if (diff_pntr_rd <= pe_thr_assert_val) ideal_prog_empty <= #`TCQ 1; else ideal_prog_empty <= #`TCQ 0; end else ideal_prog_empty <= #`TCQ ideal_prog_empty; end else if (C_PROG_EMPTY_TYPE == 2) begin if (EMPTY == 0) begin if (diff_pntr_rd <= pe_thr_assert_val) ideal_prog_empty <= #`TCQ 1; else if (diff_pntr_rd > pe_thr_negate_val) ideal_prog_empty <= #`TCQ 0; else ideal_prog_empty <= #`TCQ ideal_prog_empty; end else ideal_prog_empty <= #`TCQ ideal_prog_empty; end else if (C_PROG_EMPTY_TYPE == 3) begin if (EMPTY == 0) begin if (diff_pntr_rd <= pe_thr_assert_val) ideal_prog_empty <= #`TCQ 1; else ideal_prog_empty <= #`TCQ 0; end else ideal_prog_empty <= #`TCQ ideal_prog_empty; end else if (C_PROG_EMPTY_TYPE == 4) begin if (EMPTY == 0) begin if (diff_pntr_rd <= pe_thr_assert_val) ideal_prog_empty <= #`TCQ 1; else if (diff_pntr_rd > pe_thr_negate_val) ideal_prog_empty <= #`TCQ 0; else ideal_prog_empty <= #`TCQ ideal_prog_empty; end else ideal_prog_empty <= #`TCQ ideal_prog_empty; end //C_PROG_EMPTY_TYPE end end // gen_pe generate if (C_PROG_EMPTY_TYPE == 3) begin : single_pe_thr_input assign pe_thr_assert_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ? PROG_EMPTY_THRESH - 2'h2 : PROG_EMPTY_THRESH; end endgenerate // single_pe_thr_input generate if (C_PROG_EMPTY_TYPE == 4) begin : multiple_pe_thr_input assign pe_thr_assert_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ? PROG_EMPTY_THRESH_ASSERT - 2'h2 : PROG_EMPTY_THRESH_ASSERT; assign pe_thr_negate_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ? PROG_EMPTY_THRESH_NEGATE - 2'h2 : PROG_EMPTY_THRESH_NEGATE; end endgenerate // multiple_pe_thr_input generate if (C_PROG_EMPTY_TYPE < 3) begin : single_multiple_pe_thr_const assign pe_thr_assert_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ? C_PROG_EMPTY_THRESH_ASSERT_VAL - 2'h2 : C_PROG_EMPTY_THRESH_ASSERT_VAL; assign pe_thr_negate_val = (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) ? C_PROG_EMPTY_THRESH_NEGATE_VAL - 2'h2 : C_PROG_EMPTY_THRESH_NEGATE_VAL; end endgenerate // single_multiple_pe_thr_const // block memory has a synchronous reset always @(posedge RD_CLK) begin : gen_fifo_blkmemdout // make it consistent with the core. if (rd_rst_i) begin // Reset err_type only if ECC is not selected if (C_USE_ECC == 0 && C_MEMORY_TYPE < 2) err_type <= #`TCQ 0; // BRAM resets synchronously if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2) begin ideal_dout <= #`TCQ dout_reset_val; ideal_dout_d1 <= #`TCQ dout_reset_val; end end end //always always @(posedge RD_CLK or posedge rd_rst_i) begin : gen_fifo_r /****** Reset fifo (case 1)***************************************/ if (rd_rst_i) begin num_rd_bits <= #`TCQ 0; next_num_rd_bits = #`TCQ 0; rd_ptr <= #`TCQ C_RD_DEPTH -1; rd_pntr <= #`TCQ 0; rd_pntr_wr1 <= #`TCQ 0; wr_ptr_rdclk <= #`TCQ C_WR_DEPTH -1; // DRAM resets asynchronously if (C_MEMORY_TYPE == 2 && C_USE_DOUT_RST == 1) ideal_dout <= #`TCQ dout_reset_val; // Reset err_type only if ECC is not selected if (C_USE_ECC == 0) err_type <= #`TCQ 0; ideal_valid <= #`TCQ 1'b0; ideal_rd_count <= #`TCQ 0; end else begin //rd_rst_i==0 rd_pntr_wr1 <= #`TCQ rd_pntr; //Determine the current number of words in the FIFO tmp_rd_listsize = (C_DEPTH_RATIO_WR > 1) ? num_rd_bits/C_DIN_WIDTH : num_rd_bits/C_DOUT_WIDTH; wr_ptr_rdclk_next = wr_ptr; if (wr_ptr_rdclk < wr_ptr_rdclk_next) begin next_num_rd_bits = num_rd_bits + C_DIN_WIDTH*(wr_ptr_rdclk +C_WR_DEPTH - wr_ptr_rdclk_next); end else begin next_num_rd_bits = num_rd_bits + C_DIN_WIDTH*(wr_ptr_rdclk - wr_ptr_rdclk_next); end /*****************************************************************/ // Read Operation - Read Latency 1 /*****************************************************************/ if (C_PRELOAD_LATENCY==1 || C_PRELOAD_LATENCY==2) begin ideal_valid <= #`TCQ 1'b0; if (ram_rd_en == 1'b1) begin if (EMPTY == 1'b1) begin //If the FIFO is completely empty, and is reporting empty if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0) begin //Do not change the contents of the FIFO //Do not acknowledge the read from empty FIFO ideal_valid <= #`TCQ 1'b0; //Reminder that FIFO is still empty ideal_rd_count <= #`TCQ num_read_words_sized_i; end // if (tmp_rd_listsize <= 0) //If the FIFO is one from empty, but it is reporting empty else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1) begin //Do not change the contents of the FIFO //Do not acknowledge the read from empty FIFO ideal_valid <= #`TCQ 1'b0; //Note that FIFO is no longer empty, but is almost empty (has one word left) ideal_rd_count <= #`TCQ num_read_words_sized_i; end // if (tmp_rd_listsize == 1) //If the FIFO is two from empty, and is reporting empty else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2) begin //Do not change the contents of the FIFO //Do not acknowledge the read from empty FIFO ideal_valid <= #`TCQ 1'b0; //Fifo has two words, so is neither empty or almost empty ideal_rd_count <= #`TCQ num_read_words_sized_i; end // if (tmp_rd_listsize == 2) //If the FIFO is not close to empty, but is reporting that it is // Treat the FIFO as empty this time, but unset EMPTY flags. if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) && (tmp_rd_listsize/C_DEPTH_RATIO_WR 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