diff options
Diffstat (limited to 'projects/U200/U200.ip_user_files/ipstatic/simulation')
| -rwxr-xr-x | projects/U200/U200.ip_user_files/ipstatic/simulation/blk_mem_gen_v8_4.v | 4522 | ||||
| -rwxr-xr-x | projects/U200/U200.ip_user_files/ipstatic/simulation/fifo_generator_vlog_beh.v | 10519 |
2 files changed, 15041 insertions, 0 deletions
diff --git a/projects/U200/U200.ip_user_files/ipstatic/simulation/blk_mem_gen_v8_4.v b/projects/U200/U200.ip_user_files/ipstatic/simulation/blk_mem_gen_v8_4.v new file mode 100755 index 0000000..73b8240 --- /dev/null +++ b/projects/U200/U200.ip_user_files/ipstatic/simulation/blk_mem_gen_v8_4.v @@ -0,0 +1,4522 @@ +/****************************************************************************** +-- (c) Copyright 2006 - 2013 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: blk_mem_gen_v8_4_4.v + * + * Description: + * This file is the Verilog behvarial model for the + * Block Memory Generator Core. + * + ***************************************************************************** + * Author: Xilinx + * + * History: Jan 11, 2006 Initial revision + * Jun 11, 2007 Added independent register stages for + * Port A and Port B (IP1_Jm/v2.5) + * Aug 28, 2007 Added mux pipeline stages feature (IP2_Jm/v2.6) + * Mar 13, 2008 Behavioral model optimizations + * April 07, 2009 : Added support for Spartan-6 and Virtex-6 + * features, including the following: + * (i) error injection, detection and/or correction + * (ii) reset priority + * (iii) special reset behavior + * + *****************************************************************************/ +`timescale 1ps/1ps + +module STATE_LOGIC_v8_4 (O, I0, I1, I2, I3, I4, I5); + + parameter INIT = 64'h0000000000000000; + + input I0, I1, I2, I3, I4, I5; + + output O; + + reg O; + reg tmp; + + always @( I5 or I4 or I3 or I2 or I1 or I0 ) begin + + tmp = I0 ^ I1 ^ I2 ^ I3 ^ I4 ^ I5; + + if ( tmp == 0 || tmp == 1) + + O = INIT[{I5, I4, I3, I2, I1, I0}]; + + end +endmodule + +module beh_vlog_muxf7_v8_4 (O, I0, I1, S); + + output O; + reg O; + + input I0, I1, S; + + always @(I0 or I1 or S) + if (S) + O = I1; + else + O = I0; +endmodule + +module beh_vlog_ff_clr_v8_4 (Q, C, CLR, D); + parameter INIT = 0; +localparam FLOP_DELAY = 100; + output Q; + + input C, CLR, D; + + reg Q; + + initial Q= 1'b0; + + always @(posedge C ) + if (CLR) + Q<= 1'b0; + else + Q<= #FLOP_DELAY D; + + +endmodule + +module beh_vlog_ff_pre_v8_4 (Q, C, D, PRE); + + parameter INIT = 0; +localparam FLOP_DELAY = 100; + output Q; + input C, D, PRE; + + reg Q; + + initial Q= 1'b0; + + always @(posedge C ) + if (PRE) + Q <= 1'b1; + else + Q <= #FLOP_DELAY D; + +endmodule + +module beh_vlog_ff_ce_clr_v8_4 (Q, C, CE, CLR, D); + + parameter INIT = 0; +localparam FLOP_DELAY = 100; + output Q; + input C, CE, CLR, D; + + reg Q; + + initial Q= 1'b0; + always @(posedge C ) + if (CLR) + Q <= 1'b0; + else if (CE) + Q <= #FLOP_DELAY D; + +endmodule + +module write_netlist_v8_4 +#( + parameter C_AXI_TYPE = 0 + ) + ( + S_ACLK, S_ARESETN, S_AXI_AWVALID, S_AXI_WVALID, S_AXI_BREADY, + w_last_c, bready_timeout_c, aw_ready_r, S_AXI_WREADY, S_AXI_BVALID, + S_AXI_WR_EN, addr_en_c, incr_addr_c, bvalid_c + ); + + input S_ACLK; + input S_ARESETN; + input S_AXI_AWVALID; + input S_AXI_WVALID; + input S_AXI_BREADY; + input w_last_c; + input bready_timeout_c; + output aw_ready_r; + output S_AXI_WREADY; + output S_AXI_BVALID; + output S_AXI_WR_EN; + output addr_en_c; + output incr_addr_c; + output bvalid_c; + //------------------------------------------------------------------------- + //AXI LITE + //------------------------------------------------------------------------- +generate if (C_AXI_TYPE == 0 ) begin : gbeh_axi_lite_sm + wire w_ready_r_7; + wire w_ready_c; + wire aw_ready_c; + wire NlwRenamedSignal_bvalid_c; + wire NlwRenamedSignal_incr_addr_c; + wire present_state_FSM_FFd3_13; + wire present_state_FSM_FFd2_14; + wire present_state_FSM_FFd1_15; + wire present_state_FSM_FFd4_16; + wire present_state_FSM_FFd4_In; + wire present_state_FSM_FFd3_In; + wire present_state_FSM_FFd2_In; + wire present_state_FSM_FFd1_In; + wire present_state_FSM_FFd4_In1_21; + wire [0:0] Mmux_aw_ready_c ; +begin + assign + S_AXI_WREADY = w_ready_r_7, + S_AXI_BVALID = NlwRenamedSignal_incr_addr_c, + S_AXI_WR_EN = NlwRenamedSignal_bvalid_c, + incr_addr_c = NlwRenamedSignal_incr_addr_c, + bvalid_c = NlwRenamedSignal_bvalid_c; + + assign NlwRenamedSignal_incr_addr_c = 1'b0; + + beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + aw_ready_r_2 ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( aw_ready_c), + .Q ( aw_ready_r) + ); + beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + w_ready_r ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( w_ready_c), + .Q ( w_ready_r_7) + ); + beh_vlog_ff_pre_v8_4 #( + .INIT (1'b1)) + present_state_FSM_FFd4 ( + .C ( S_ACLK), + .D ( present_state_FSM_FFd4_In), + .PRE ( S_ARESETN), + .Q ( present_state_FSM_FFd4_16) + ); + beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + present_state_FSM_FFd3 ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( present_state_FSM_FFd3_In), + .Q ( present_state_FSM_FFd3_13) + ); + beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + present_state_FSM_FFd2 ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( present_state_FSM_FFd2_In), + .Q ( present_state_FSM_FFd2_14) + ); +beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + present_state_FSM_FFd1 ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( present_state_FSM_FFd1_In), + .Q ( present_state_FSM_FFd1_15) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'h0000000055554440)) + present_state_FSM_FFd3_In1 ( + .I0 ( S_AXI_WVALID), + .I1 ( S_AXI_AWVALID), + .I2 ( present_state_FSM_FFd2_14), + .I3 ( present_state_FSM_FFd4_16), + .I4 ( present_state_FSM_FFd3_13), + .I5 (1'b0), + .O ( present_state_FSM_FFd3_In) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'h0000000088880800)) + present_state_FSM_FFd2_In1 ( + .I0 ( S_AXI_AWVALID), + .I1 ( S_AXI_WVALID), + .I2 ( bready_timeout_c), + .I3 ( present_state_FSM_FFd2_14), + .I4 ( present_state_FSM_FFd4_16), + .I5 (1'b0), + .O ( present_state_FSM_FFd2_In) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'h00000000AAAA2000)) + Mmux_addr_en_c_0_1 ( + .I0 ( S_AXI_AWVALID), + .I1 ( bready_timeout_c), + .I2 ( present_state_FSM_FFd2_14), + .I3 ( S_AXI_WVALID), + .I4 ( present_state_FSM_FFd4_16), + .I5 (1'b0), + .O ( addr_en_c) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'hF5F07570F5F05500)) + Mmux_w_ready_c_0_1 ( + .I0 ( S_AXI_WVALID), + .I1 ( bready_timeout_c), + .I2 ( S_AXI_AWVALID), + .I3 ( present_state_FSM_FFd3_13), + .I4 ( present_state_FSM_FFd4_16), + .I5 ( present_state_FSM_FFd2_14), + .O ( w_ready_c) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'h88808880FFFF8880)) + present_state_FSM_FFd1_In1 ( + .I0 ( S_AXI_WVALID), + .I1 ( bready_timeout_c), + .I2 ( present_state_FSM_FFd3_13), + .I3 ( present_state_FSM_FFd2_14), + .I4 ( present_state_FSM_FFd1_15), + .I5 ( S_AXI_BREADY), + .O ( present_state_FSM_FFd1_In) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'h00000000000000A8)) + Mmux_S_AXI_WR_EN_0_1 ( + .I0 ( S_AXI_WVALID), + .I1 ( present_state_FSM_FFd2_14), + .I2 ( present_state_FSM_FFd3_13), + .I3 (1'b0), + .I4 (1'b0), + .I5 (1'b0), + .O ( NlwRenamedSignal_bvalid_c) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h2F0F27072F0F2200)) + present_state_FSM_FFd4_In1 ( + .I0 ( S_AXI_WVALID), + .I1 ( bready_timeout_c), + .I2 ( S_AXI_AWVALID), + .I3 ( present_state_FSM_FFd3_13), + .I4 ( present_state_FSM_FFd4_16), + .I5 ( present_state_FSM_FFd2_14), + .O ( present_state_FSM_FFd4_In1_21) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h00000000000000F8)) + present_state_FSM_FFd4_In2 ( + .I0 ( present_state_FSM_FFd1_15), + .I1 ( S_AXI_BREADY), + .I2 ( present_state_FSM_FFd4_In1_21), + .I3 (1'b0), + .I4 (1'b0), + .I5 (1'b0), + .O ( present_state_FSM_FFd4_In) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'h7535753575305500)) + Mmux_aw_ready_c_0_1 ( + .I0 ( S_AXI_AWVALID), + .I1 ( bready_timeout_c), + .I2 ( S_AXI_WVALID), + .I3 ( present_state_FSM_FFd4_16), + .I4 ( present_state_FSM_FFd3_13), + .I5 ( present_state_FSM_FFd2_14), + .O ( Mmux_aw_ready_c[0]) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'h00000000000000F8)) + Mmux_aw_ready_c_0_2 ( + .I0 ( present_state_FSM_FFd1_15), + .I1 ( S_AXI_BREADY), + .I2 ( Mmux_aw_ready_c[0]), + .I3 (1'b0), + .I4 (1'b0), + .I5 (1'b0), + .O ( aw_ready_c) + ); +end +end +endgenerate + + //--------------------------------------------------------------------- + // AXI FULL + //--------------------------------------------------------------------- +generate if (C_AXI_TYPE == 1 ) begin : gbeh_axi_full_sm + wire w_ready_r_8; + wire w_ready_c; + wire aw_ready_c; + wire NlwRenamedSig_OI_bvalid_c; + wire present_state_FSM_FFd1_16; + wire present_state_FSM_FFd4_17; + wire present_state_FSM_FFd3_18; + wire present_state_FSM_FFd2_19; + wire present_state_FSM_FFd4_In; + wire present_state_FSM_FFd3_In; + wire present_state_FSM_FFd2_In; + wire present_state_FSM_FFd1_In; + wire present_state_FSM_FFd2_In1_24; + wire present_state_FSM_FFd4_In1_25; + wire N2; + wire N4; +begin +assign + S_AXI_WREADY = w_ready_r_8, + bvalid_c = NlwRenamedSig_OI_bvalid_c, + S_AXI_BVALID = 1'b0; + +beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + aw_ready_r_2 + ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( aw_ready_c), + .Q ( aw_ready_r) + ); +beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + w_ready_r + ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( w_ready_c), + .Q ( w_ready_r_8) + ); + beh_vlog_ff_pre_v8_4 #( + .INIT (1'b1)) + present_state_FSM_FFd4 + ( + .C ( S_ACLK), + .D ( present_state_FSM_FFd4_In), + .PRE ( S_ARESETN), + .Q ( present_state_FSM_FFd4_17) + ); +beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + present_state_FSM_FFd3 + ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( present_state_FSM_FFd3_In), + .Q ( present_state_FSM_FFd3_18) + ); +beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + present_state_FSM_FFd2 + ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( present_state_FSM_FFd2_In), + .Q ( present_state_FSM_FFd2_19) + ); + beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + present_state_FSM_FFd1 + ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( present_state_FSM_FFd1_In), + .Q ( present_state_FSM_FFd1_16) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000005540)) + present_state_FSM_FFd3_In1 + ( + .I0 ( S_AXI_WVALID), + .I1 ( present_state_FSM_FFd4_17), + .I2 ( S_AXI_AWVALID), + .I3 ( present_state_FSM_FFd3_18), + .I4 (1'b0), + .I5 (1'b0), + .O ( present_state_FSM_FFd3_In) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'hBF3FBB33AF0FAA00)) + Mmux_aw_ready_c_0_2 + ( + .I0 ( S_AXI_BREADY), + .I1 ( bready_timeout_c), + .I2 ( S_AXI_AWVALID), + .I3 ( present_state_FSM_FFd1_16), + .I4 ( present_state_FSM_FFd4_17), + .I5 ( NlwRenamedSig_OI_bvalid_c), + .O ( aw_ready_c) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'hAAAAAAAA20000000)) + Mmux_addr_en_c_0_1 + ( + .I0 ( S_AXI_AWVALID), + .I1 ( bready_timeout_c), + .I2 ( present_state_FSM_FFd2_19), + .I3 ( S_AXI_WVALID), + .I4 ( w_last_c), + .I5 ( present_state_FSM_FFd4_17), + .O ( addr_en_c) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h00000000000000A8)) + Mmux_S_AXI_WR_EN_0_1 + ( + .I0 ( S_AXI_WVALID), + .I1 ( present_state_FSM_FFd2_19), + .I2 ( present_state_FSM_FFd3_18), + .I3 (1'b0), + .I4 (1'b0), + .I5 (1'b0), + .O ( S_AXI_WR_EN) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000002220)) + Mmux_incr_addr_c_0_1 + ( + .I0 ( S_AXI_WVALID), + .I1 ( w_last_c), + .I2 ( present_state_FSM_FFd2_19), + .I3 ( present_state_FSM_FFd3_18), + .I4 (1'b0), + .I5 (1'b0), + .O ( incr_addr_c) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000008880)) + Mmux_aw_ready_c_0_11 + ( + .I0 ( S_AXI_WVALID), + .I1 ( w_last_c), + .I2 ( present_state_FSM_FFd2_19), + .I3 ( present_state_FSM_FFd3_18), + .I4 (1'b0), + .I5 (1'b0), + .O ( NlwRenamedSig_OI_bvalid_c) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h000000000000D5C0)) + present_state_FSM_FFd2_In1 + ( + .I0 ( w_last_c), + .I1 ( S_AXI_AWVALID), + .I2 ( present_state_FSM_FFd4_17), + .I3 ( present_state_FSM_FFd3_18), + .I4 (1'b0), + .I5 (1'b0), + .O ( present_state_FSM_FFd2_In1_24) + ); +STATE_LOGIC_v8_4 #( + .INIT (64'hFFFFAAAA08AAAAAA)) + present_state_FSM_FFd2_In2 + ( + .I0 ( present_state_FSM_FFd2_19), + .I1 ( S_AXI_AWVALID), + .I2 ( bready_timeout_c), + .I3 ( w_last_c), + .I4 ( S_AXI_WVALID), + .I5 ( present_state_FSM_FFd2_In1_24), + .O ( present_state_FSM_FFd2_In) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h00C0004000C00000)) + present_state_FSM_FFd4_In1 + ( + .I0 ( S_AXI_AWVALID), + .I1 ( w_last_c), + .I2 ( S_AXI_WVALID), + .I3 ( bready_timeout_c), + .I4 ( present_state_FSM_FFd3_18), + .I5 ( present_state_FSM_FFd2_19), + .O ( present_state_FSM_FFd4_In1_25) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h00000000FFFF88F8)) + present_state_FSM_FFd4_In2 + ( + .I0 ( present_state_FSM_FFd1_16), + .I1 ( S_AXI_BREADY), + .I2 ( present_state_FSM_FFd4_17), + .I3 ( S_AXI_AWVALID), + .I4 ( present_state_FSM_FFd4_In1_25), + .I5 (1'b0), + .O ( present_state_FSM_FFd4_In) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000000007)) + Mmux_w_ready_c_0_SW0 + ( + .I0 ( w_last_c), + .I1 ( S_AXI_WVALID), + .I2 (1'b0), + .I3 (1'b0), + .I4 (1'b0), + .I5 (1'b0), + .O ( N2) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'hFABAFABAFAAAF000)) + Mmux_w_ready_c_0_Q + ( + .I0 ( N2), + .I1 ( bready_timeout_c), + .I2 ( S_AXI_AWVALID), + .I3 ( present_state_FSM_FFd4_17), + .I4 ( present_state_FSM_FFd3_18), + .I5 ( present_state_FSM_FFd2_19), + .O ( w_ready_c) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000000008)) + Mmux_aw_ready_c_0_11_SW0 + ( + .I0 ( bready_timeout_c), + .I1 ( S_AXI_WVALID), + .I2 (1'b0), + .I3 (1'b0), + .I4 (1'b0), + .I5 (1'b0), + .O ( N4) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h88808880FFFF8880)) + present_state_FSM_FFd1_In1 + ( + .I0 ( w_last_c), + .I1 ( N4), + .I2 ( present_state_FSM_FFd2_19), + .I3 ( present_state_FSM_FFd3_18), + .I4 ( present_state_FSM_FFd1_16), + .I5 ( S_AXI_BREADY), + .O ( present_state_FSM_FFd1_In) + ); +end +end +endgenerate +endmodule + + +module read_netlist_v8_4 #( + parameter C_AXI_TYPE = 1, + parameter C_ADDRB_WIDTH = 12 + ) ( S_AXI_R_LAST_INT, S_ACLK, S_ARESETN, S_AXI_ARVALID, + S_AXI_RREADY,S_AXI_INCR_ADDR,S_AXI_ADDR_EN, + S_AXI_SINGLE_TRANS,S_AXI_MUX_SEL, S_AXI_R_LAST, S_AXI_ARREADY, + S_AXI_RLAST, S_AXI_RVALID, S_AXI_RD_EN, S_AXI_ARLEN); + + input S_AXI_R_LAST_INT; + input S_ACLK; + input S_ARESETN; + input S_AXI_ARVALID; + input S_AXI_RREADY; + output S_AXI_INCR_ADDR; + output S_AXI_ADDR_EN; + output S_AXI_SINGLE_TRANS; + output S_AXI_MUX_SEL; + output S_AXI_R_LAST; + output S_AXI_ARREADY; + output S_AXI_RLAST; + output S_AXI_RVALID; + output S_AXI_RD_EN; + input [7:0] S_AXI_ARLEN; + + wire present_state_FSM_FFd1_13 ; + wire present_state_FSM_FFd2_14 ; + wire gaxi_full_sm_outstanding_read_r_15 ; + wire gaxi_full_sm_ar_ready_r_16 ; + wire gaxi_full_sm_r_last_r_17 ; + wire NlwRenamedSig_OI_gaxi_full_sm_r_valid_r ; + wire gaxi_full_sm_r_valid_c ; + wire S_AXI_RREADY_gaxi_full_sm_r_valid_r_OR_9_o ; + wire gaxi_full_sm_ar_ready_c ; + wire gaxi_full_sm_outstanding_read_c ; + wire NlwRenamedSig_OI_S_AXI_R_LAST ; + wire S_AXI_ARLEN_7_GND_8_o_equal_1_o ; + wire present_state_FSM_FFd2_In ; + wire present_state_FSM_FFd1_In ; + wire Mmux_S_AXI_R_LAST13 ; + wire N01 ; + wire N2 ; + wire Mmux_gaxi_full_sm_ar_ready_c11 ; + wire N4 ; + wire N8 ; + wire N9 ; + wire N10 ; + wire N11 ; + wire N12 ; + wire N13 ; + assign + S_AXI_R_LAST = NlwRenamedSig_OI_S_AXI_R_LAST, + S_AXI_ARREADY = gaxi_full_sm_ar_ready_r_16, + S_AXI_RLAST = gaxi_full_sm_r_last_r_17, + S_AXI_RVALID = NlwRenamedSig_OI_gaxi_full_sm_r_valid_r; + + beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + gaxi_full_sm_outstanding_read_r ( + .C (S_ACLK), + .CLR(S_ARESETN), + .D(gaxi_full_sm_outstanding_read_c), + .Q(gaxi_full_sm_outstanding_read_r_15) + ); + beh_vlog_ff_ce_clr_v8_4 #( + .INIT (1'b0)) + gaxi_full_sm_r_valid_r ( + .C (S_ACLK), + .CE (S_AXI_RREADY_gaxi_full_sm_r_valid_r_OR_9_o), + .CLR (S_ARESETN), + .D (gaxi_full_sm_r_valid_c), + .Q (NlwRenamedSig_OI_gaxi_full_sm_r_valid_r) + ); + beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + gaxi_full_sm_ar_ready_r ( + .C (S_ACLK), + .CLR (S_ARESETN), + .D (gaxi_full_sm_ar_ready_c), + .Q (gaxi_full_sm_ar_ready_r_16) + ); + beh_vlog_ff_ce_clr_v8_4 #( + .INIT(1'b0)) + gaxi_full_sm_r_last_r ( + .C (S_ACLK), + .CE (S_AXI_RREADY_gaxi_full_sm_r_valid_r_OR_9_o), + .CLR (S_ARESETN), + .D (NlwRenamedSig_OI_S_AXI_R_LAST), + .Q (gaxi_full_sm_r_last_r_17) + ); + beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + present_state_FSM_FFd2 ( + .C ( S_ACLK), + .CLR ( S_ARESETN), + .D ( present_state_FSM_FFd2_In), + .Q ( present_state_FSM_FFd2_14) + ); + beh_vlog_ff_clr_v8_4 #( + .INIT (1'b0)) + present_state_FSM_FFd1 ( + .C (S_ACLK), + .CLR (S_ARESETN), + .D (present_state_FSM_FFd1_In), + .Q (present_state_FSM_FFd1_13) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h000000000000000B)) + S_AXI_RREADY_gaxi_full_sm_r_valid_r_OR_9_o1 ( + .I0 ( S_AXI_RREADY), + .I1 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I2 (1'b0), + .I3 (1'b0), + .I4 (1'b0), + .I5 (1'b0), + .O (S_AXI_RREADY_gaxi_full_sm_r_valid_r_OR_9_o) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000000008)) + Mmux_S_AXI_SINGLE_TRANS11 ( + .I0 (S_AXI_ARVALID), + .I1 (S_AXI_ARLEN_7_GND_8_o_equal_1_o), + .I2 (1'b0), + .I3 (1'b0), + .I4 (1'b0), + .I5 (1'b0), + .O (S_AXI_SINGLE_TRANS) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000000004)) + Mmux_S_AXI_ADDR_EN11 ( + .I0 (present_state_FSM_FFd1_13), + .I1 (S_AXI_ARVALID), + .I2 (1'b0), + .I3 (1'b0), + .I4 (1'b0), + .I5 (1'b0), + .O (S_AXI_ADDR_EN) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'hECEE2022EEEE2022)) + present_state_FSM_FFd2_In1 ( + .I0 ( S_AXI_ARVALID), + .I1 ( present_state_FSM_FFd1_13), + .I2 ( S_AXI_RREADY), + .I3 ( S_AXI_ARLEN_7_GND_8_o_equal_1_o), + .I4 ( present_state_FSM_FFd2_14), + .I5 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .O ( present_state_FSM_FFd2_In) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000044440444)) + Mmux_S_AXI_R_LAST131 ( + .I0 ( present_state_FSM_FFd1_13), + .I1 ( S_AXI_ARVALID), + .I2 ( present_state_FSM_FFd2_14), + .I3 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I4 ( S_AXI_RREADY), + .I5 (1'b0), + .O ( Mmux_S_AXI_R_LAST13) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h4000FFFF40004000)) + Mmux_S_AXI_INCR_ADDR11 ( + .I0 ( S_AXI_R_LAST_INT), + .I1 ( S_AXI_RREADY_gaxi_full_sm_r_valid_r_OR_9_o), + .I2 ( present_state_FSM_FFd2_14), + .I3 ( present_state_FSM_FFd1_13), + .I4 ( S_AXI_ARLEN_7_GND_8_o_equal_1_o), + .I5 ( Mmux_S_AXI_R_LAST13), + .O ( S_AXI_INCR_ADDR) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h00000000000000FE)) + S_AXI_ARLEN_7_GND_8_o_equal_1_o_7_SW0 ( + .I0 ( S_AXI_ARLEN[2]), + .I1 ( S_AXI_ARLEN[1]), + .I2 ( S_AXI_ARLEN[0]), + .I3 ( 1'b0), + .I4 ( 1'b0), + .I5 ( 1'b0), + .O ( N01) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000000001)) + S_AXI_ARLEN_7_GND_8_o_equal_1_o_7_Q ( + .I0 ( S_AXI_ARLEN[7]), + .I1 ( S_AXI_ARLEN[6]), + .I2 ( S_AXI_ARLEN[5]), + .I3 ( S_AXI_ARLEN[4]), + .I4 ( S_AXI_ARLEN[3]), + .I5 ( N01), + .O ( S_AXI_ARLEN_7_GND_8_o_equal_1_o) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000000007)) + Mmux_gaxi_full_sm_outstanding_read_c1_SW0 ( + .I0 ( S_AXI_ARVALID), + .I1 ( S_AXI_ARLEN_7_GND_8_o_equal_1_o), + .I2 ( 1'b0), + .I3 ( 1'b0), + .I4 ( 1'b0), + .I5 ( 1'b0), + .O ( N2) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0020000002200200)) + Mmux_gaxi_full_sm_outstanding_read_c1 ( + .I0 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I1 ( S_AXI_RREADY), + .I2 ( present_state_FSM_FFd1_13), + .I3 ( present_state_FSM_FFd2_14), + .I4 ( gaxi_full_sm_outstanding_read_r_15), + .I5 ( N2), + .O ( gaxi_full_sm_outstanding_read_c) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000000004555)) + Mmux_gaxi_full_sm_ar_ready_c12 ( + .I0 ( S_AXI_ARVALID), + .I1 ( S_AXI_RREADY), + .I2 ( present_state_FSM_FFd2_14), + .I3 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I4 ( 1'b0), + .I5 ( 1'b0), + .O ( Mmux_gaxi_full_sm_ar_ready_c11) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h00000000000000EF)) + Mmux_S_AXI_R_LAST11_SW0 ( + .I0 ( S_AXI_ARLEN_7_GND_8_o_equal_1_o), + .I1 ( S_AXI_RREADY), + .I2 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I3 ( 1'b0), + .I4 ( 1'b0), + .I5 ( 1'b0), + .O ( N4) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'hFCAAFC0A00AA000A)) + Mmux_S_AXI_R_LAST11 ( + .I0 ( S_AXI_ARVALID), + .I1 ( gaxi_full_sm_outstanding_read_r_15), + .I2 ( present_state_FSM_FFd2_14), + .I3 ( present_state_FSM_FFd1_13), + .I4 ( N4), + .I5 ( S_AXI_RREADY_gaxi_full_sm_r_valid_r_OR_9_o), + .O ( gaxi_full_sm_r_valid_c) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h00000000AAAAAA08)) + S_AXI_MUX_SEL1 ( + .I0 (present_state_FSM_FFd1_13), + .I1 (NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I2 (S_AXI_RREADY), + .I3 (present_state_FSM_FFd2_14), + .I4 (gaxi_full_sm_outstanding_read_r_15), + .I5 (1'b0), + .O (S_AXI_MUX_SEL) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'hF3F3F755A2A2A200)) + Mmux_S_AXI_RD_EN11 ( + .I0 ( present_state_FSM_FFd1_13), + .I1 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I2 ( S_AXI_RREADY), + .I3 ( gaxi_full_sm_outstanding_read_r_15), + .I4 ( present_state_FSM_FFd2_14), + .I5 ( S_AXI_ARVALID), + .O ( S_AXI_RD_EN) + ); + beh_vlog_muxf7_v8_4 present_state_FSM_FFd1_In3 ( + .I0 ( N8), + .I1 ( N9), + .S ( present_state_FSM_FFd1_13), + .O ( present_state_FSM_FFd1_In) + ); + + STATE_LOGIC_v8_4 #( + .INIT (64'h000000005410F4F0)) + present_state_FSM_FFd1_In3_F ( + .I0 ( S_AXI_RREADY), + .I1 ( present_state_FSM_FFd2_14), + .I2 ( S_AXI_ARVALID), + .I3 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I4 ( S_AXI_ARLEN_7_GND_8_o_equal_1_o), + .I5 ( 1'b0), + .O ( N8) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000072FF7272)) + present_state_FSM_FFd1_In3_G ( + .I0 ( present_state_FSM_FFd2_14), + .I1 ( S_AXI_R_LAST_INT), + .I2 ( gaxi_full_sm_outstanding_read_r_15), + .I3 ( S_AXI_RREADY), + .I4 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I5 ( 1'b0), + .O ( N9) + ); + beh_vlog_muxf7_v8_4 Mmux_gaxi_full_sm_ar_ready_c14 ( + .I0 ( N10), + .I1 ( N11), + .S ( present_state_FSM_FFd1_13), + .O ( gaxi_full_sm_ar_ready_c) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h00000000FFFF88A8)) + Mmux_gaxi_full_sm_ar_ready_c14_F ( + .I0 ( S_AXI_ARLEN_7_GND_8_o_equal_1_o), + .I1 ( S_AXI_RREADY), + .I2 ( present_state_FSM_FFd2_14), + .I3 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I4 ( Mmux_gaxi_full_sm_ar_ready_c11), + .I5 ( 1'b0), + .O ( N10) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h000000008D008D8D)) + Mmux_gaxi_full_sm_ar_ready_c14_G ( + .I0 ( present_state_FSM_FFd2_14), + .I1 ( S_AXI_R_LAST_INT), + .I2 ( gaxi_full_sm_outstanding_read_r_15), + .I3 ( S_AXI_RREADY), + .I4 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I5 ( 1'b0), + .O ( N11) + ); + beh_vlog_muxf7_v8_4 Mmux_S_AXI_R_LAST1 ( + .I0 ( N12), + .I1 ( N13), + .S ( present_state_FSM_FFd1_13), + .O ( NlwRenamedSig_OI_S_AXI_R_LAST) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h0000000088088888)) + Mmux_S_AXI_R_LAST1_F ( + .I0 ( S_AXI_ARLEN_7_GND_8_o_equal_1_o), + .I1 ( S_AXI_ARVALID), + .I2 ( present_state_FSM_FFd2_14), + .I3 ( S_AXI_RREADY), + .I4 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I5 ( 1'b0), + .O ( N12) + ); + STATE_LOGIC_v8_4 #( + .INIT (64'h00000000E400E4E4)) + Mmux_S_AXI_R_LAST1_G ( + .I0 ( present_state_FSM_FFd2_14), + .I1 ( gaxi_full_sm_outstanding_read_r_15), + .I2 ( S_AXI_R_LAST_INT), + .I3 ( S_AXI_RREADY), + .I4 ( NlwRenamedSig_OI_gaxi_full_sm_r_valid_r), + .I5 ( 1'b0), + .O ( N13) + ); + +endmodule + + +module blk_mem_axi_write_wrapper_beh_v8_4 + # ( + // AXI Interface related parameters start here + parameter C_INTERFACE_TYPE = 0, // 0: Native Interface; 1: AXI Interface + parameter C_AXI_TYPE = 0, // 0: AXI Lite; 1: AXI Full; + parameter C_AXI_SLAVE_TYPE = 0, // 0: MEMORY SLAVE; 1: PERIPHERAL SLAVE; + parameter C_MEMORY_TYPE = 0, // 0: SP-RAM, 1: SDP-RAM; 2: TDP-RAM; 3: DP-ROM; + parameter C_WRITE_DEPTH_A = 0, + parameter C_AXI_AWADDR_WIDTH = 32, + parameter C_ADDRA_WIDTH = 12, + parameter C_AXI_WDATA_WIDTH = 32, + parameter C_HAS_AXI_ID = 0, + parameter C_AXI_ID_WIDTH = 4, + // AXI OUTSTANDING WRITES + parameter C_AXI_OS_WR = 2 + ) + ( + // AXI Global Signals + input S_ACLK, + input S_ARESETN, + // AXI Full/Lite Slave Write Channel (write side) + input [C_AXI_ID_WIDTH-1:0] S_AXI_AWID, + input [C_AXI_AWADDR_WIDTH-1:0] S_AXI_AWADDR, + input [8-1:0] S_AXI_AWLEN, + input [2:0] S_AXI_AWSIZE, + input [1:0] S_AXI_AWBURST, + input S_AXI_AWVALID, + output S_AXI_AWREADY, + input S_AXI_WVALID, + output S_AXI_WREADY, + output reg [C_AXI_ID_WIDTH-1:0] S_AXI_BID = 0, + output S_AXI_BVALID, + input S_AXI_BREADY, + // Signals for BMG interface + output [C_ADDRA_WIDTH-1:0] S_AXI_AWADDR_OUT, + output S_AXI_WR_EN + ); + + localparam FLOP_DELAY = 100; // 100 ps + + localparam C_RANGE = ((C_AXI_WDATA_WIDTH == 8)?0: + ((C_AXI_WDATA_WIDTH==16)?1: + ((C_AXI_WDATA_WIDTH==32)?2: + ((C_AXI_WDATA_WIDTH==64)?3: + ((C_AXI_WDATA_WIDTH==128)?4: + ((C_AXI_WDATA_WIDTH==256)?5:0)))))); + + + + + wire bvalid_c ; + reg bready_timeout_c = 0; + wire [1:0] bvalid_rd_cnt_c; + reg bvalid_r = 0; + reg [2:0] bvalid_count_r = 0; + reg [((C_AXI_TYPE == 1 && C_AXI_SLAVE_TYPE == 0)? + C_AXI_AWADDR_WIDTH:C_ADDRA_WIDTH)-1:0] awaddr_reg = 0; + reg [1:0] bvalid_wr_cnt_r = 0; + reg [1:0] bvalid_rd_cnt_r = 0; + wire w_last_c ; + wire addr_en_c ; + wire incr_addr_c ; + wire aw_ready_r ; + wire dec_alen_c ; + reg bvalid_d1_c = 0; + reg [7:0] awlen_cntr_r = 0; + reg [7:0] awlen_int = 0; + reg [1:0] awburst_int = 0; + + integer total_bytes = 0; + integer wrap_boundary = 0; + integer wrap_base_addr = 0; + integer num_of_bytes_c = 0; + integer num_of_bytes_r = 0; + // Array to store BIDs + reg [C_AXI_ID_WIDTH-1:0] axi_bid_array[3:0] ; + wire S_AXI_BVALID_axi_wr_fsm; + + //------------------------------------- + //AXI WRITE FSM COMPONENT INSTANTIATION + //------------------------------------- + write_netlist_v8_4 #(.C_AXI_TYPE(C_AXI_TYPE)) axi_wr_fsm + ( + .S_ACLK(S_ACLK), + .S_ARESETN(S_ARESETN), + .S_AXI_AWVALID(S_AXI_AWVALID), + .aw_ready_r(aw_ready_r), + .S_AXI_WVALID(S_AXI_WVALID), + .S_AXI_WREADY(S_AXI_WREADY), + .S_AXI_BREADY(S_AXI_BREADY), + .S_AXI_WR_EN(S_AXI_WR_EN), + .w_last_c(w_last_c), + .bready_timeout_c(bready_timeout_c), + .addr_en_c(addr_en_c), + .incr_addr_c(incr_addr_c), + .bvalid_c(bvalid_c), + .S_AXI_BVALID (S_AXI_BVALID_axi_wr_fsm) + ); + + + //Wrap Address boundary calculation + always@(*) begin + num_of_bytes_c = 2**((C_AXI_TYPE == 1 && C_AXI_SLAVE_TYPE == 0)?S_AXI_AWSIZE:0); + total_bytes = (num_of_bytes_r)*(awlen_int+1); + wrap_base_addr = ((awaddr_reg)/((total_bytes==0)?1:total_bytes))*(total_bytes); + wrap_boundary = wrap_base_addr+total_bytes; + end + + //------------------------------------------------------------------------- + // BMG address generation + //------------------------------------------------------------------------- + always @(posedge S_ACLK or S_ARESETN) begin + if (S_ARESETN == 1'b1) begin + awaddr_reg <= 0; + num_of_bytes_r <= 0; + awburst_int <= 0; + end else begin + if (addr_en_c == 1'b1) begin + awaddr_reg <= #FLOP_DELAY S_AXI_AWADDR ; + num_of_bytes_r <= num_of_bytes_c; + awburst_int <= ((C_AXI_TYPE == 1 && C_AXI_SLAVE_TYPE == 0)?S_AXI_AWBURST:2'b01); + end else if (incr_addr_c == 1'b1) begin + if (awburst_int == 2'b10) begin + if(awaddr_reg == (wrap_boundary-num_of_bytes_r)) begin + awaddr_reg <= wrap_base_addr; + end else begin + awaddr_reg <= awaddr_reg + num_of_bytes_r; + end + end else if (awburst_int == 2'b01 || awburst_int == 2'b11) begin + awaddr_reg <= awaddr_reg + num_of_bytes_r; + end + end + end + end + + + assign S_AXI_AWADDR_OUT = ((C_AXI_TYPE == 1 && C_AXI_SLAVE_TYPE == 0)? + awaddr_reg[C_AXI_AWADDR_WIDTH-1:C_RANGE]:awaddr_reg); + + //------------------------------------------------------------------------- + // AXI wlast generation + //------------------------------------------------------------------------- + always @(posedge S_ACLK or S_ARESETN) begin + if (S_ARESETN == 1'b1) begin + awlen_cntr_r <= 0; + awlen_int <= 0; + end else begin + if (addr_en_c == 1'b1) begin + awlen_int <= #FLOP_DELAY (C_AXI_TYPE == 0?0:S_AXI_AWLEN) ; + awlen_cntr_r <= #FLOP_DELAY (C_AXI_TYPE == 0?0:S_AXI_AWLEN) ; + end else if (dec_alen_c == 1'b1) begin + awlen_cntr_r <= #FLOP_DELAY awlen_cntr_r - 1 ; + end + end + end + + assign w_last_c = (awlen_cntr_r == 0 && S_AXI_WVALID == 1'b1)?1'b1:1'b0; + + assign dec_alen_c = (incr_addr_c | w_last_c); + + //------------------------------------------------------------------------- + // Generation of bvalid counter for outstanding transactions + //------------------------------------------------------------------------- + always @(posedge S_ACLK or S_ARESETN) begin + if (S_ARESETN == 1'b1) begin + bvalid_count_r <= 0; + end else begin + // bvalid_count_r generation + if (bvalid_c == 1'b1 && bvalid_r == 1'b1 && S_AXI_BREADY == 1'b1) begin + bvalid_count_r <= #FLOP_DELAY bvalid_count_r ; + end else if (bvalid_c == 1'b1) begin + bvalid_count_r <= #FLOP_DELAY bvalid_count_r + 1 ; + end else if (bvalid_r == 1'b1 && S_AXI_BREADY == 1'b1 && bvalid_count_r != 0) begin + bvalid_count_r <= #FLOP_DELAY bvalid_count_r - 1 ; + end + end + end + + //------------------------------------------------------------------------- + // Generation of bvalid when BID is used + //------------------------------------------------------------------------- + generate if (C_HAS_AXI_ID == 1) begin:gaxi_bvalid_id_r + always @(posedge S_ACLK or S_ARESETN) begin + if (S_ARESETN == 1'b1) begin + bvalid_r <= 0; + bvalid_d1_c <= 0; + end else begin + // Delay the generation o bvalid_r for generation for BID + bvalid_d1_c <= bvalid_c; + + //external bvalid signal generation + if (bvalid_d1_c == 1'b1) begin + bvalid_r <= #FLOP_DELAY 1'b1 ; + end else if (bvalid_count_r <= 1 && S_AXI_BREADY == 1'b1) begin + bvalid_r <= #FLOP_DELAY 0 ; + end + end + end + end + endgenerate + + //------------------------------------------------------------------------- + // Generation of bvalid when BID is not used + //------------------------------------------------------------------------- + generate if(C_HAS_AXI_ID == 0) begin:gaxi_bvalid_noid_r + always @(posedge S_ACLK or S_ARESETN) begin + if (S_ARESETN == 1'b1) begin + bvalid_r <= 0; + end else begin + //external bvalid signal generation + if (bvalid_c == 1'b1) begin + bvalid_r <= #FLOP_DELAY 1'b1 ; + end else if (bvalid_count_r <= 1 && S_AXI_BREADY == 1'b1) begin + bvalid_r <= #FLOP_DELAY 0 ; + end + end + end + end + endgenerate + + //------------------------------------------------------------------------- + // Generation of Bready timeout + //------------------------------------------------------------------------- + always @(bvalid_count_r) begin + // bready_timeout_c generation + if(bvalid_count_r == C_AXI_OS_WR-1) begin + bready_timeout_c <= 1'b1; + end else begin + bready_timeout_c <= 1'b0; + end + end + + //------------------------------------------------------------------------- + // Generation of BID + //------------------------------------------------------------------------- + generate if(C_HAS_AXI_ID == 1) begin:gaxi_bid_gen + + always @(posedge S_ACLK or S_ARESETN) begin + if (S_ARESETN == 1'b1) begin + bvalid_wr_cnt_r <= 0; + bvalid_rd_cnt_r <= 0; + end else begin + // STORE AWID IN AN ARRAY + if(bvalid_c == 1'b1) begin + bvalid_wr_cnt_r <= bvalid_wr_cnt_r + 1; + end + // generate BID FROM AWID ARRAY + bvalid_rd_cnt_r <= #FLOP_DELAY bvalid_rd_cnt_c ; + S_AXI_BID <= axi_bid_array[bvalid_rd_cnt_c]; + end + end + + assign bvalid_rd_cnt_c = (bvalid_r == 1'b1 && S_AXI_BREADY == 1'b1)?bvalid_rd_cnt_r+1:bvalid_rd_cnt_r; + + //------------------------------------------------------------------------- + // Storing AWID for generation of BID + //------------------------------------------------------------------------- + always @(posedge S_ACLK or S_ARESETN) begin + if(S_ARESETN == 1'b1) begin + axi_bid_array[0] = 0; + axi_bid_array[1] = 0; + axi_bid_array[2] = 0; + axi_bid_array[3] = 0; + end else if(aw_ready_r == 1'b1 && S_AXI_AWVALID == 1'b1) begin + axi_bid_array[bvalid_wr_cnt_r] <= S_AXI_AWID; + end + end + + end + endgenerate + + assign S_AXI_BVALID = bvalid_r; + assign S_AXI_AWREADY = aw_ready_r; + + endmodule + +module blk_mem_axi_read_wrapper_beh_v8_4 +# ( + //// AXI Interface related parameters start here + parameter C_INTERFACE_TYPE = 0, + parameter C_AXI_TYPE = 0, + parameter C_AXI_SLAVE_TYPE = 0, + parameter C_MEMORY_TYPE = 0, + parameter C_WRITE_WIDTH_A = 4, + parameter C_WRITE_DEPTH_A = 32, + parameter C_ADDRA_WIDTH = 12, + parameter C_AXI_PIPELINE_STAGES = 0, + parameter C_AXI_ARADDR_WIDTH = 12, + parameter C_HAS_AXI_ID = 0, + parameter C_AXI_ID_WIDTH = 4, + parameter C_ADDRB_WIDTH = 12 + ) + ( + + //// AXI Global Signals + input S_ACLK, + input S_ARESETN, + //// AXI Full/Lite Slave Read (Read side) + input [C_AXI_ARADDR_WIDTH-1:0] S_AXI_ARADDR, + input [7:0] S_AXI_ARLEN, + input [2:0] S_AXI_ARSIZE, + input [1:0] S_AXI_ARBURST, + input S_AXI_ARVALID, + output S_AXI_ARREADY, + output S_AXI_RLAST, + output S_AXI_RVALID, + input S_AXI_RREADY, + input [C_AXI_ID_WIDTH-1:0] S_AXI_ARID, + output reg [C_AXI_ID_WIDTH-1:0] S_AXI_RID = 0, + //// AXI Full/Lite Read Address Signals to BRAM + output [C_ADDRB_WIDTH-1:0] S_AXI_ARADDR_OUT, + output S_AXI_RD_EN + ); + + localparam FLOP_DELAY = 100; // 100 ps + localparam C_RANGE = ((C_WRITE_WIDTH_A == 8)?0: + ((C_WRITE_WIDTH_A==16)?1: + ((C_WRITE_WIDTH_A==32)?2: + ((C_WRITE_WIDTH_A==64)?3: + ((C_WRITE_WIDTH_A==128)?4: + ((C_WRITE_WIDTH_A==256)?5:0)))))); + + + + reg [C_AXI_ID_WIDTH-1:0] ar_id_r=0; + wire addr_en_c; + wire rd_en_c; + wire incr_addr_c; + wire single_trans_c; + wire dec_alen_c; + wire mux_sel_c; + wire r_last_c; + wire r_last_int_c; + wire [C_ADDRB_WIDTH-1 : 0] araddr_out; + + reg [7:0] arlen_int_r=0; + reg [7:0] arlen_cntr=8'h01; + reg [1:0] arburst_int_c=0; + reg [1:0] arburst_int_r=0; + reg [((C_AXI_TYPE == 1 && C_AXI_SLAVE_TYPE == 0)? + C_AXI_ARADDR_WIDTH:C_ADDRA_WIDTH)-1:0] araddr_reg =0; + integer num_of_bytes_c = 0; + integer total_bytes = 0; + integer num_of_bytes_r = 0; + integer wrap_base_addr_r = 0; + integer wrap_boundary_r = 0; + + reg [7:0] arlen_int_c=0; + integer total_bytes_c = 0; + integer wrap_base_addr_c = 0; + integer wrap_boundary_c = 0; + + assign dec_alen_c = incr_addr_c | r_last_int_c; + + + read_netlist_v8_4 + #(.C_AXI_TYPE (1), + .C_ADDRB_WIDTH (C_ADDRB_WIDTH)) + axi_read_fsm ( + .S_AXI_INCR_ADDR(incr_addr_c), + .S_AXI_ADDR_EN(addr_en_c), + .S_AXI_SINGLE_TRANS(single_trans_c), + .S_AXI_MUX_SEL(mux_sel_c), + .S_AXI_R_LAST(r_last_c), + .S_AXI_R_LAST_INT(r_last_int_c), + + //// AXI Global Signals + .S_ACLK(S_ACLK), + .S_ARESETN(S_ARESETN), + //// AXI Full/Lite Slave Read (Read side) + .S_AXI_ARLEN(S_AXI_ARLEN), + .S_AXI_ARVALID(S_AXI_ARVALID), + .S_AXI_ARREADY(S_AXI_ARREADY), + .S_AXI_RLAST(S_AXI_RLAST), + .S_AXI_RVALID(S_AXI_RVALID), + .S_AXI_RREADY(S_AXI_RREADY), + //// AXI Full/Lite Read Address Signals to BRAM + .S_AXI_RD_EN(rd_en_c) + ); + + always@(*) begin + num_of_bytes_c = 2**((C_AXI_TYPE == 1 && C_AXI_SLAVE_TYPE == 0)?S_AXI_ARSIZE:0); + total_bytes = (num_of_bytes_r)*(arlen_int_r+1); + wrap_base_addr_r = ((araddr_reg)/(total_bytes==0?1:total_bytes))*(total_bytes); + wrap_boundary_r = wrap_base_addr_r+total_bytes; + + //////// combinatorial from interface + arlen_int_c = (C_AXI_TYPE == 0?0:S_AXI_ARLEN); + total_bytes_c = (num_of_bytes_c)*(arlen_int_c+1); + wrap_base_addr_c = ((S_AXI_ARADDR)/(total_bytes_c==0?1:total_bytes_c))*(total_bytes_c); + wrap_boundary_c = wrap_base_addr_c+total_bytes_c; + + arburst_int_c = ((C_AXI_TYPE == 1 && C_AXI_SLAVE_TYPE == 0)?S_AXI_ARBURST:1); + end + + ////------------------------------------------------------------------------- + //// BMG address generation + ////------------------------------------------------------------------------- + always @(posedge S_ACLK or S_ARESETN) begin + if (S_ARESETN == 1'b1) begin + araddr_reg <= 0; + arburst_int_r <= 0; + num_of_bytes_r <= 0; + end else begin + if (incr_addr_c == 1'b1 && addr_en_c == 1'b1 && single_trans_c == 1'b0) begin + arburst_int_r <= arburst_int_c; + num_of_bytes_r <= num_of_bytes_c; + if (arburst_int_c == 2'b10) begin + if(S_AXI_ARADDR == (wrap_boundary_c-num_of_bytes_c)) begin + araddr_reg <= wrap_base_addr_c; + end else begin + araddr_reg <= S_AXI_ARADDR + num_of_bytes_c; + end + end else if (arburst_int_c == 2'b01 || arburst_int_c == 2'b11) begin + araddr_reg <= S_AXI_ARADDR + num_of_bytes_c; + end + + end else if (addr_en_c == 1'b1) begin + araddr_reg <= S_AXI_ARADDR; + num_of_bytes_r <= num_of_bytes_c; + arburst_int_r <= arburst_int_c; + end else if (incr_addr_c == 1'b1) begin + if (arburst_int_r == 2'b10) begin + if(araddr_reg == (wrap_boundary_r-num_of_bytes_r)) begin + araddr_reg <= wrap_base_addr_r; + end else begin + araddr_reg <= araddr_reg + num_of_bytes_r; + end + end else if (arburst_int_r == 2'b01 || arburst_int_r == 2'b11) begin + araddr_reg <= araddr_reg + num_of_bytes_r; + end + end + end + end + +assign araddr_out = ((C_AXI_TYPE == 1 && C_AXI_SLAVE_TYPE == 0)?araddr_reg[C_AXI_ARADDR_WIDTH-1:C_RANGE]:araddr_reg); + + + ////----------------------------------------------------------------------- + //// Counter to generate r_last_int_c from registered ARLEN - AXI FULL FSM + ////----------------------------------------------------------------------- + always @(posedge S_ACLK or S_ARESETN) begin + if (S_ARESETN == 1'b1) begin + arlen_cntr <= 8'h01; + arlen_int_r <= 0; + end else begin + if (addr_en_c == 1'b1 && dec_alen_c == 1'b1 && single_trans_c == 1'b0) begin + arlen_int_r <= (C_AXI_TYPE == 0?0:S_AXI_ARLEN) ; + arlen_cntr <= S_AXI_ARLEN - 1'b1; + end else if (addr_en_c == 1'b1) begin + arlen_int_r <= (C_AXI_TYPE == 0?0:S_AXI_ARLEN) ; + arlen_cntr <= (C_AXI_TYPE == 0?0:S_AXI_ARLEN) ; + end else if (dec_alen_c == 1'b1) begin + arlen_cntr <= arlen_cntr - 1'b1 ; + end + else begin + arlen_cntr <= arlen_cntr; + end + end + end + + assign r_last_int_c = (arlen_cntr == 0 && S_AXI_RREADY == 1'b1)?1'b1:1'b0; + + + ////------------------------------------------------------------------------ + //// AXI FULL FSM + //// Mux Selection of ARADDR + //// ARADDR is driven out from the read fsm based on the mux_sel_c + //// Based on mux_sel either ARADDR is given out or the latched ARADDR is + //// given out to BRAM + ////------------------------------------------------------------------------ + assign S_AXI_ARADDR_OUT = (mux_sel_c == 1'b0)?((C_AXI_TYPE == 1 && C_AXI_SLAVE_TYPE == 0)?S_AXI_ARADDR[C_AXI_ARADDR_WIDTH-1:C_RANGE]:S_AXI_ARADDR):araddr_out; + + ////------------------------------------------------------------------------ + //// Assign output signals - AXI FULL FSM + ////------------------------------------------------------------------------ + assign S_AXI_RD_EN = rd_en_c; + + generate if (C_HAS_AXI_ID == 1) begin:gaxi_bvalid_id_r + always @(posedge S_ACLK or S_ARESETN) begin + if (S_ARESETN == 1'b1) begin + S_AXI_RID <= 0; + ar_id_r <= 0; + end else begin + if (addr_en_c == 1'b1 && rd_en_c == 1'b1) begin + S_AXI_RID <= S_AXI_ARID; + ar_id_r <= S_AXI_ARID; + end else if (addr_en_c == 1'b1 && rd_en_c == 1'b0) begin + ar_id_r <= S_AXI_ARID; + end else if (rd_en_c == 1'b1) begin + S_AXI_RID <= ar_id_r; + end + end + end + end + endgenerate + +endmodule + +module blk_mem_axi_regs_fwd_v8_4 + #(parameter C_DATA_WIDTH = 8 + )( + input ACLK, + input ARESET, + input S_VALID, + output S_READY, + input [C_DATA_WIDTH-1:0] S_PAYLOAD_DATA, + output M_VALID, + input M_READY, + output reg [C_DATA_WIDTH-1:0] M_PAYLOAD_DATA + ); + + reg [C_DATA_WIDTH-1:0] STORAGE_DATA; + wire S_READY_I; + reg M_VALID_I; + reg [1:0] ARESET_D; + + //assign local signal to its output signal + assign S_READY = S_READY_I; + assign M_VALID = M_VALID_I; + + always @(posedge ACLK) begin + ARESET_D <= {ARESET_D[0], ARESET}; + end + + //Save payload data whenever we have a transaction on the slave side + always @(posedge ACLK or ARESET) begin + if (ARESET == 1'b1) begin + STORAGE_DATA <= 0; + end else begin + if(S_VALID == 1'b1 && S_READY_I == 1'b1 ) begin + STORAGE_DATA <= S_PAYLOAD_DATA; + end + end + end + + always @(posedge ACLK) begin + M_PAYLOAD_DATA = STORAGE_DATA; + end + + //M_Valid set to high when we have a completed transfer on slave side + //Is removed on a M_READY except if we have a new transfer on the slave side + + always @(posedge ACLK or ARESET_D) begin + if (ARESET_D != 2'b00) begin + M_VALID_I <= 1'b0; + end else begin + if (S_VALID == 1'b1) begin + //Always set M_VALID_I when slave side is valid + M_VALID_I <= 1'b1; + end else if (M_READY == 1'b1 ) begin + //Clear (or keep) when no slave side is valid but master side is ready + M_VALID_I <= 1'b0; + end + end + end + + //Slave Ready is either when Master side drives M_READY or we have space in our storage data + assign S_READY_I = (M_READY || (!M_VALID_I)) && !(|(ARESET_D)); + + endmodule + +//***************************************************************************** +// Output Register Stage module +// +// This module builds the output register stages of the memory. This module is +// instantiated in the main memory module (blk_mem_gen_v8_4_4) which is +// declared/implemented further down in this file. +//***************************************************************************** +module blk_mem_gen_v8_4_4_output_stage + #(parameter C_FAMILY = "virtex7", + parameter C_XDEVICEFAMILY = "virtex7", + parameter C_RST_TYPE = "SYNC", + parameter C_HAS_RST = 0, + parameter C_RSTRAM = 0, + parameter C_RST_PRIORITY = "CE", + parameter C_INIT_VAL = "0", + parameter C_HAS_EN = 0, + parameter C_HAS_REGCE = 0, + parameter C_DATA_WIDTH = 32, + parameter C_ADDRB_WIDTH = 10, + parameter C_HAS_MEM_OUTPUT_REGS = 0, + parameter C_USE_SOFTECC = 0, + parameter C_USE_ECC = 0, + parameter NUM_STAGES = 1, + parameter C_EN_ECC_PIPE = 0, + parameter FLOP_DELAY = 100 + ) + ( + input CLK, + input RST, + input EN, + input REGCE, + input [C_DATA_WIDTH-1:0] DIN_I, + output reg [C_DATA_WIDTH-1:0] DOUT, + input SBITERR_IN_I, + input DBITERR_IN_I, + output reg SBITERR, + output reg DBITERR, + input [C_ADDRB_WIDTH-1:0] RDADDRECC_IN_I, + input ECCPIPECE, + output reg [C_ADDRB_WIDTH-1:0] RDADDRECC +); + +//****************************** +// Port and Generic Definitions +//****************************** + ////////////////////////////////////////////////////////////////////////// + // Generic Definitions + ////////////////////////////////////////////////////////////////////////// + // C_FAMILY,C_XDEVICEFAMILY: Designates architecture targeted. The following + // options are available - "spartan3", "spartan6", + // "virtex4", "virtex5", "virtex6" and "virtex6l". + // C_RST_TYPE : Type of reset - Synchronous or Asynchronous + // C_HAS_RST : Determines the presence of the RST port + // C_RSTRAM : Determines if special reset behavior is used + // C_RST_PRIORITY : Determines the priority between CE and SR + // C_INIT_VAL : Initialization value + // C_HAS_EN : Determines the presence of the EN port + // C_HAS_REGCE : Determines the presence of the REGCE port + // C_DATA_WIDTH : Memory write/read width + // C_ADDRB_WIDTH : Width of the ADDRB input port + // C_HAS_MEM_OUTPUT_REGS : Designates the use of a register at the output + // of the RAM primitive + // C_USE_SOFTECC : Determines if the Soft ECC feature is used or + // not. Only applicable Spartan-6 + // C_USE_ECC : Determines if the ECC feature is used or + // not. Only applicable for V5 and V6 + // NUM_STAGES : Determines the number of output stages + // FLOP_DELAY : Constant delay for register assignments + ////////////////////////////////////////////////////////////////////////// + // Port Definitions + ////////////////////////////////////////////////////////////////////////// + // CLK : Clock to synchronize all read and write operations + // RST : Reset input to reset memory outputs to a user-defined + // reset state + // EN : Enable all read and write operations + // REGCE : Register Clock Enable to control each pipeline output + // register stages + // DIN : Data input to the Output stage. + // DOUT : Final Data output + // SBITERR_IN : SBITERR input signal to the Output stage. + // SBITERR : Final SBITERR Output signal. + // DBITERR_IN : DBITERR input signal to the Output stage. + // DBITERR : Final DBITERR Output signal. + // RDADDRECC_IN : RDADDRECC input signal to the Output stage. + // RDADDRECC : Final RDADDRECC Output signal. + ////////////////////////////////////////////////////////////////////////// + +// Fix for CR-509792 + + localparam REG_STAGES = (NUM_STAGES < 2) ? 1 : NUM_STAGES-1; + + // Declare the pipeline registers + // (includes mem output reg, mux pipeline stages, and mux output reg) + reg [C_DATA_WIDTH*REG_STAGES-1:0] out_regs; + reg [C_ADDRB_WIDTH*REG_STAGES-1:0] rdaddrecc_regs; + reg [REG_STAGES-1:0] sbiterr_regs; + reg [REG_STAGES-1:0] dbiterr_regs; + + reg [C_DATA_WIDTH*8-1:0] init_str = C_INIT_VAL; + reg [C_DATA_WIDTH-1:0] init_val ; + + //********************************************* + // Wire off optional inputs based on parameters + //********************************************* + wire en_i; + wire regce_i; + wire rst_i; + + // Internal signals + reg [C_DATA_WIDTH-1:0] DIN; + reg [C_ADDRB_WIDTH-1:0] RDADDRECC_IN; + reg SBITERR_IN; + reg DBITERR_IN; + + + // Internal enable for output registers is tied to user EN or '1' depending + // on parameters + assign en_i = (C_HAS_EN==0 || EN); + + // Internal register enable for output registers is tied to user REGCE, EN or + // '1' depending on parameters + // For V4 ECC, REGCE is always 1 + // Virtex-4 ECC Not Yet Supported + assign regce_i = ((C_HAS_REGCE==1) && REGCE) || + ((C_HAS_REGCE==0) && (C_HAS_EN==0 || EN)); + + //Internal SRR is tied to user RST or '0' depending on parameters + assign rst_i = (C_HAS_RST==1) && RST; + + //**************************************************** + // Power on: load up the output registers and latches + //**************************************************** + initial begin + if (!($sscanf(init_str, "%h", init_val))) begin + init_val = 0; + end + DOUT = init_val; + RDADDRECC = 0; + SBITERR = 1'b0; + DBITERR = 1'b0; + DIN = {(C_DATA_WIDTH){1'b0}}; + RDADDRECC_IN = 0; + SBITERR_IN = 0; + DBITERR_IN = 0; + // This will be one wider than need, but 0 is an error + out_regs = {(REG_STAGES+1){init_val}}; + rdaddrecc_regs = 0; + sbiterr_regs = {(REG_STAGES+1){1'b0}}; + dbiterr_regs = {(REG_STAGES+1){1'b0}}; + end + + //*********************************************** + // NUM_STAGES = 0 (No output registers. RAM only) + //*********************************************** + generate if (NUM_STAGES == 0) begin : zero_stages + always @* begin + DOUT = DIN; + RDADDRECC = RDADDRECC_IN; + SBITERR = SBITERR_IN; + DBITERR = DBITERR_IN; + end + end + endgenerate + + generate if (C_EN_ECC_PIPE == 0) begin : no_ecc_pipe_reg + always @* begin + DIN = DIN_I; + SBITERR_IN = SBITERR_IN_I; + DBITERR_IN = DBITERR_IN_I; + RDADDRECC_IN = RDADDRECC_IN_I; + end + end + endgenerate + + generate if (C_EN_ECC_PIPE == 1) begin : with_ecc_pipe_reg + always @(posedge CLK) begin + if(ECCPIPECE == 1) begin + DIN <= #FLOP_DELAY DIN_I; + SBITERR_IN <= #FLOP_DELAY SBITERR_IN_I; + DBITERR_IN <= #FLOP_DELAY DBITERR_IN_I; + RDADDRECC_IN <= #FLOP_DELAY RDADDRECC_IN_I; + end + end + end + endgenerate + + + //*********************************************** + // NUM_STAGES = 1 + // (Mem Output Reg only or Mux Output Reg only) + //*********************************************** + + // Possible valid combinations: + // Note: C_HAS_MUX_OUTPUT_REGS_*=0 when (C_RSTRAM_*=1) + // +-----------------------------------------+ + // | C_RSTRAM_* | Reset Behavior | + // +----------------+------------------------+ + // | 0 | Normal Behavior | + // +----------------+------------------------+ + // | 1 | Special Behavior | + // +----------------+------------------------+ + // + // Normal = REGCE gates reset, as in the case of all families except S3ADSP. + // Special = EN gates reset, as in the case of S3ADSP. + + generate if (NUM_STAGES == 1 && + (C_RSTRAM == 0 || (C_RSTRAM == 1 && (C_XDEVICEFAMILY != "spartan3adsp" && C_XDEVICEFAMILY != "aspartan3adsp" )) || + C_HAS_MEM_OUTPUT_REGS == 0 || C_HAS_RST == 0)) + begin : one_stages_norm + + always @(posedge CLK) begin + if (C_RST_PRIORITY == "CE") begin //REGCE has priority + if (regce_i && rst_i) begin + DOUT <= #FLOP_DELAY init_val; + RDADDRECC <= #FLOP_DELAY 0; + SBITERR <= #FLOP_DELAY 1'b0; + DBITERR <= #FLOP_DELAY 1'b0; + end else if (regce_i) begin + DOUT <= #FLOP_DELAY DIN; + RDADDRECC <= #FLOP_DELAY RDADDRECC_IN; + SBITERR <= #FLOP_DELAY SBITERR_IN; + DBITERR <= #FLOP_DELAY DBITERR_IN; + end //Output signal assignments + end else begin //RST has priority + if (rst_i) begin + DOUT <= #FLOP_DELAY init_val; + RDADDRECC <= #FLOP_DELAY RDADDRECC_IN; + SBITERR <= #FLOP_DELAY 1'b0; + DBITERR <= #FLOP_DELAY 1'b0; + end else if (regce_i) begin + DOUT <= #FLOP_DELAY DIN; + RDADDRECC <= #FLOP_DELAY RDADDRECC_IN; + SBITERR <= #FLOP_DELAY SBITERR_IN; + DBITERR <= #FLOP_DELAY DBITERR_IN; + end //Output signal assignments + end //end Priority conditions + end //end RST Type conditions + end //end one_stages_norm generate statement + endgenerate + + // Special Reset Behavior for S3ADSP + generate if (NUM_STAGES == 1 && C_RSTRAM == 1 && (C_XDEVICEFAMILY =="spartan3adsp" || C_XDEVICEFAMILY =="aspartan3adsp")) + begin : one_stage_splbhv + always @(posedge CLK) begin + if (en_i && rst_i) begin + DOUT <= #FLOP_DELAY init_val; + end else if (regce_i && !rst_i) begin + DOUT <= #FLOP_DELAY DIN; + end //Output signal assignments + end //end CLK + end //end one_stage_splbhv generate statement + endgenerate + + //************************************************************ + // NUM_STAGES > 1 + // Mem Output Reg + Mux Output Reg + // or + // Mem Output Reg + Mux Pipeline Stages (>0) + Mux Output Reg + // or + // Mux Pipeline Stages (>0) + Mux Output Reg + //************************************************************* + generate if (NUM_STAGES > 1) begin : multi_stage + //Asynchronous Reset + always @(posedge CLK) begin + if (C_RST_PRIORITY == "CE") begin //REGCE has priority + if (regce_i && rst_i) begin + DOUT <= #FLOP_DELAY init_val; + RDADDRECC <= #FLOP_DELAY 0; + SBITERR <= #FLOP_DELAY 1'b0; + DBITERR <= #FLOP_DELAY 1'b0; + end else if (regce_i) begin + DOUT <= #FLOP_DELAY + out_regs[C_DATA_WIDTH*(NUM_STAGES-2)+:C_DATA_WIDTH]; + RDADDRECC <= #FLOP_DELAY rdaddrecc_regs[C_ADDRB_WIDTH*(NUM_STAGES-2)+:C_ADDRB_WIDTH]; + SBITERR <= #FLOP_DELAY sbiterr_regs[NUM_STAGES-2]; + DBITERR <= #FLOP_DELAY dbiterr_regs[NUM_STAGES-2]; + end //Output signal assignments + end else begin //RST has priority + if (rst_i) begin + DOUT <= #FLOP_DELAY init_val; + RDADDRECC <= #FLOP_DELAY 0; + SBITERR <= #FLOP_DELAY 1'b0; + DBITERR <= #FLOP_DELAY 1'b0; + end else if (regce_i) begin + DOUT <= #FLOP_DELAY + out_regs[C_DATA_WIDTH*(NUM_STAGES-2)+:C_DATA_WIDTH]; + RDADDRECC <= #FLOP_DELAY rdaddrecc_regs[C_ADDRB_WIDTH*(NUM_STAGES-2)+:C_ADDRB_WIDTH]; + SBITERR <= #FLOP_DELAY sbiterr_regs[NUM_STAGES-2]; + DBITERR <= #FLOP_DELAY dbiterr_regs[NUM_STAGES-2]; + end //Output signal assignments + end //end Priority conditions + // Shift the data through the output stages + if (en_i) begin + out_regs <= #FLOP_DELAY (out_regs << C_DATA_WIDTH) | DIN; + rdaddrecc_regs <= #FLOP_DELAY (rdaddrecc_regs << C_ADDRB_WIDTH) | RDADDRECC_IN; + sbiterr_regs <= #FLOP_DELAY (sbiterr_regs << 1) | SBITERR_IN; + dbiterr_regs <= #FLOP_DELAY (dbiterr_regs << 1) | DBITERR_IN; + end + end //end CLK + end //end multi_stage generate statement + endgenerate +endmodule + +module blk_mem_gen_v8_4_4_softecc_output_reg_stage + #(parameter C_DATA_WIDTH = 32, + parameter C_ADDRB_WIDTH = 10, + parameter C_HAS_SOFTECC_OUTPUT_REGS_B= 0, + parameter C_USE_SOFTECC = 0, + parameter FLOP_DELAY = 100 + ) + ( + input CLK, + input [C_DATA_WIDTH-1:0] DIN, + output reg [C_DATA_WIDTH-1:0] DOUT, + input SBITERR_IN, + input DBITERR_IN, + output reg SBITERR, + output reg DBITERR, + input [C_ADDRB_WIDTH-1:0] RDADDRECC_IN, + output reg [C_ADDRB_WIDTH-1:0] RDADDRECC +); + +//****************************** +// Port and Generic Definitions +//****************************** + ////////////////////////////////////////////////////////////////////////// + // Generic Definitions + ////////////////////////////////////////////////////////////////////////// + // C_DATA_WIDTH : Memory write/read width + // C_ADDRB_WIDTH : Width of the ADDRB input port + // C_HAS_SOFTECC_OUTPUT_REGS_B : Designates the use of a register at the output + // of the RAM primitive + // C_USE_SOFTECC : Determines if the Soft ECC feature is used or + // not. Only applicable Spartan-6 + // FLOP_DELAY : Constant delay for register assignments + ////////////////////////////////////////////////////////////////////////// + // Port Definitions + ////////////////////////////////////////////////////////////////////////// + // CLK : Clock to synchronize all read and write operations + // DIN : Data input to the Output stage. + // DOUT : Final Data output + // SBITERR_IN : SBITERR input signal to the Output stage. + // SBITERR : Final SBITERR Output signal. + // DBITERR_IN : DBITERR input signal to the Output stage. + // DBITERR : Final DBITERR Output signal. + // RDADDRECC_IN : RDADDRECC input signal to the Output stage. + // RDADDRECC : Final RDADDRECC Output signal. + ////////////////////////////////////////////////////////////////////////// + + reg [C_DATA_WIDTH-1:0] dout_i = 0; + reg sbiterr_i = 0; + reg dbiterr_i = 0; + reg [C_ADDRB_WIDTH-1:0] rdaddrecc_i = 0; + + //*********************************************** + // NO OUTPUT REGISTERS. + //*********************************************** + generate if (C_HAS_SOFTECC_OUTPUT_REGS_B==0) begin : no_output_stage + always @* begin + DOUT = DIN; + RDADDRECC = RDADDRECC_IN; + SBITERR = SBITERR_IN; + DBITERR = DBITERR_IN; + end + end + endgenerate + + //*********************************************** + // WITH OUTPUT REGISTERS. + //*********************************************** + generate if (C_HAS_SOFTECC_OUTPUT_REGS_B==1) begin : has_output_stage + always @(posedge CLK) begin + dout_i <= #FLOP_DELAY DIN; + rdaddrecc_i <= #FLOP_DELAY RDADDRECC_IN; + sbiterr_i <= #FLOP_DELAY SBITERR_IN; + dbiterr_i <= #FLOP_DELAY DBITERR_IN; + end + + always @* begin + DOUT = dout_i; + RDADDRECC = rdaddrecc_i; + SBITERR = sbiterr_i; + DBITERR = dbiterr_i; + end //end always + end //end in_or_out_stage generate statement + endgenerate + +endmodule + + +//***************************************************************************** +// Main Memory module +// +// This module is the top-level behavioral model and this implements the RAM +//***************************************************************************** +module blk_mem_gen_v8_4_4_mem_module + #(parameter C_CORENAME = "blk_mem_gen_v8_4_4", + parameter C_FAMILY = "virtex7", + parameter C_XDEVICEFAMILY = "virtex7", + parameter C_MEM_TYPE = 2, + parameter C_BYTE_SIZE = 9, + parameter C_USE_BRAM_BLOCK = 0, + parameter C_ALGORITHM = 1, + parameter C_PRIM_TYPE = 3, + parameter C_LOAD_INIT_FILE = 0, + parameter C_INIT_FILE_NAME = "", + parameter C_INIT_FILE = "", + parameter C_USE_DEFAULT_DATA = 0, + parameter C_DEFAULT_DATA = "0", + parameter C_RST_TYPE = "SYNC", + parameter C_HAS_RSTA = 0, + parameter C_RST_PRIORITY_A = "CE", + parameter C_RSTRAM_A = 0, + parameter C_INITA_VAL = "0", + parameter C_HAS_ENA = 1, + parameter C_HAS_REGCEA = 0, + parameter C_USE_BYTE_WEA = 0, + parameter C_WEA_WIDTH = 1, + parameter C_WRITE_MODE_A = "WRITE_FIRST", + parameter C_WRITE_WIDTH_A = 32, + parameter C_READ_WIDTH_A = 32, + parameter C_WRITE_DEPTH_A = 64, + parameter C_READ_DEPTH_A = 64, + parameter C_ADDRA_WIDTH = 5, + parameter C_HAS_RSTB = 0, + parameter C_RST_PRIORITY_B = "CE", + parameter C_RSTRAM_B = 0, + parameter C_INITB_VAL = "", + parameter C_HAS_ENB = 1, + parameter C_HAS_REGCEB = 0, + parameter C_USE_BYTE_WEB = 0, + parameter C_WEB_WIDTH = 1, + parameter C_WRITE_MODE_B = "WRITE_FIRST", + parameter C_WRITE_WIDTH_B = 32, + parameter C_READ_WIDTH_B = 32, + parameter C_WRITE_DEPTH_B = 64, + parameter C_READ_DEPTH_B = 64, + parameter C_ADDRB_WIDTH = 5, + parameter C_HAS_MEM_OUTPUT_REGS_A = 0, + parameter C_HAS_MEM_OUTPUT_REGS_B = 0, + parameter C_HAS_MUX_OUTPUT_REGS_A = 0, + parameter C_HAS_MUX_OUTPUT_REGS_B = 0, + parameter C_HAS_SOFTECC_INPUT_REGS_A = 0, + parameter C_HAS_SOFTECC_OUTPUT_REGS_B= 0, + parameter C_MUX_PIPELINE_STAGES = 0, + parameter C_USE_SOFTECC = 0, + parameter C_USE_ECC = 0, + parameter C_HAS_INJECTERR = 0, + parameter C_SIM_COLLISION_CHECK = "NONE", + parameter C_COMMON_CLK = 1, + parameter FLOP_DELAY = 100, + parameter C_DISABLE_WARN_BHV_COLL = 0, + parameter C_EN_ECC_PIPE = 0, + parameter C_DISABLE_WARN_BHV_RANGE = 0 + ) + (input CLKA, + input RSTA, + input ENA, + input REGCEA, + input [C_WEA_WIDTH-1:0] WEA, + input [C_ADDRA_WIDTH-1:0] ADDRA, + input [C_WRITE_WIDTH_A-1:0] DINA, + output [C_READ_WIDTH_A-1:0] DOUTA, + input CLKB, + input RSTB, + input ENB, + input REGCEB, + input [C_WEB_WIDTH-1:0] WEB, + input [C_ADDRB_WIDTH-1:0] ADDRB, + input [C_WRITE_WIDTH_B-1:0] DINB, + output [C_READ_WIDTH_B-1:0] DOUTB, + input INJECTSBITERR, + input INJECTDBITERR, + input ECCPIPECE, + input SLEEP, + output SBITERR, + output DBITERR, + output [C_ADDRB_WIDTH-1:0] RDADDRECC + ); +//****************************** +// Port and Generic Definitions +//****************************** + ////////////////////////////////////////////////////////////////////////// + // Generic Definitions + ////////////////////////////////////////////////////////////////////////// + // C_CORENAME : Instance name of the Block Memory Generator core + // C_FAMILY,C_XDEVICEFAMILY: Designates architecture targeted. The following + // options are available - "spartan3", "spartan6", + // "virtex4", "virtex5", "virtex6" and "virtex6l". + // C_MEM_TYPE : Designates memory type. + // It can be + // 0 - Single Port Memory + // 1 - Simple Dual Port Memory + // 2 - True Dual Port Memory + // 3 - Single Port Read Only Memory + // 4 - Dual Port Read Only Memory + // C_BYTE_SIZE : Size of a byte (8 or 9 bits) + // C_ALGORITHM : Designates the algorithm method used + // for constructing the memory. + // It can be Fixed_Primitives, Minimum_Area or + // Low_Power + // C_PRIM_TYPE : Designates the user selected primitive used to + // construct the memory. + // + // C_LOAD_INIT_FILE : Designates the use of an initialization file to + // initialize memory contents. + // C_INIT_FILE_NAME : Memory initialization file name. + // C_USE_DEFAULT_DATA : Designates whether to fill remaining + // initialization space with default data + // C_DEFAULT_DATA : Default value of all memory locations + // not initialized by the memory + // initialization file. + // C_RST_TYPE : Type of reset - Synchronous or Asynchronous + // C_HAS_RSTA : Determines the presence of the RSTA port + // C_RST_PRIORITY_A : Determines the priority between CE and SR for + // Port A. + // C_RSTRAM_A : Determines if special reset behavior is used for + // Port A + // C_INITA_VAL : The initialization value for Port A + // C_HAS_ENA : Determines the presence of the ENA port + // C_HAS_REGCEA : Determines the presence of the REGCEA port + // C_USE_BYTE_WEA : Determines if the Byte Write is used or not. + // C_WEA_WIDTH : The width of the WEA port + // C_WRITE_MODE_A : Configurable write mode for Port A. It can be + // WRITE_FIRST, READ_FIRST or NO_CHANGE. + // C_WRITE_WIDTH_A : Memory write width for Port A. + // C_READ_WIDTH_A : Memory read width for Port A. + // C_WRITE_DEPTH_A : Memory write depth for Port A. + // C_READ_DEPTH_A : Memory read depth for Port A. + // C_ADDRA_WIDTH : Width of the ADDRA input port + // C_HAS_RSTB : Determines the presence of the RSTB port + // C_RST_PRIORITY_B : Determines the priority between CE and SR for + // Port B. + // C_RSTRAM_B : Determines if special reset behavior is used for + // Port B + // C_INITB_VAL : The initialization value for Port B + // C_HAS_ENB : Determines the presence of the ENB port + // C_HAS_REGCEB : Determines the presence of the REGCEB port + // C_USE_BYTE_WEB : Determines if the Byte Write is used or not. + // C_WEB_WIDTH : The width of the WEB port + // C_WRITE_MODE_B : Configurable write mode for Port B. It can be + // WRITE_FIRST, READ_FIRST or NO_CHANGE. + // C_WRITE_WIDTH_B : Memory write width for Port B. + // C_READ_WIDTH_B : Memory read width for Port B. + // C_WRITE_DEPTH_B : Memory write depth for Port B. + // C_READ_DEPTH_B : Memory read depth for Port B. + // C_ADDRB_WIDTH : Width of the ADDRB input port + // C_HAS_MEM_OUTPUT_REGS_A : Designates the use of a register at the output + // of the RAM primitive for Port A. + // C_HAS_MEM_OUTPUT_REGS_B : Designates the use of a register at the output + // of the RAM primitive for Port B. + // C_HAS_MUX_OUTPUT_REGS_A : Designates the use of a register at the output + // of the MUX for Port A. + // C_HAS_MUX_OUTPUT_REGS_B : Designates the use of a register at the output + // of the MUX for Port B. + // C_MUX_PIPELINE_STAGES : Designates the number of pipeline stages in + // between the muxes. + // C_USE_SOFTECC : Determines if the Soft ECC feature is used or + // not. Only applicable Spartan-6 + // C_USE_ECC : Determines if the ECC feature is used or + // not. Only applicable for V5 and V6 + // C_HAS_INJECTERR : Determines if the error injection pins + // are present or not. If the ECC feature + // is not used, this value is defaulted to + // 0, else the following are the allowed + // values: + // 0 : No INJECTSBITERR or INJECTDBITERR pins + // 1 : Only INJECTSBITERR pin exists + // 2 : Only INJECTDBITERR pin exists + // 3 : Both INJECTSBITERR and INJECTDBITERR pins exist + // C_SIM_COLLISION_CHECK : Controls the disabling of Unisim model collision + // warnings. It can be "ALL", "NONE", + // "Warnings_Only" or "Generate_X_Only". + // C_COMMON_CLK : Determins if the core has a single CLK input. + // C_DISABLE_WARN_BHV_COLL : Controls the Behavioral Model Collision warnings + // C_DISABLE_WARN_BHV_RANGE: Controls the Behavioral Model Out of Range + // warnings + ////////////////////////////////////////////////////////////////////////// + // Port Definitions + ////////////////////////////////////////////////////////////////////////// + // CLKA : Clock to synchronize all read and write operations of Port A. + // RSTA : Reset input to reset memory outputs to a user-defined + // reset state for Port A. + // ENA : Enable all read and write operations of Port A. + // REGCEA : Register Clock Enable to control each pipeline output + // register stages for Port A. + // WEA : Write Enable to enable all write operations of Port A. + // ADDRA : Address of Port A. + // DINA : Data input of Port A. + // DOUTA : Data output of Port A. + // CLKB : Clock to synchronize all read and write operations of Port B. + // RSTB : Reset input to reset memory outputs to a user-defined + // reset state for Port B. + // ENB : Enable all read and write operations of Port B. + // REGCEB : Register Clock Enable to control each pipeline output + // register stages for Port B. + // WEB : Write Enable to enable all write operations of Port B. + // ADDRB : Address of Port B. + // DINB : Data input of Port B. + // DOUTB : Data output of Port B. + // INJECTSBITERR : Single Bit ECC Error Injection Pin. + // INJECTDBITERR : Double Bit ECC Error Injection Pin. + // SBITERR : Output signal indicating that a Single Bit ECC Error has been + // detected and corrected. + // DBITERR : Output signal indicating that a Double Bit ECC Error has been + // detected. + // RDADDRECC : Read Address Output signal indicating address at which an + // ECC error has occurred. + ////////////////////////////////////////////////////////////////////////// + + +// Note: C_CORENAME parameter is hard-coded to "blk_mem_gen_v8_4_4" and it is +// only used by this module to print warning messages. It is neither passed +// down from blk_mem_gen_v8_4_4_xst.v nor present in the instantiation template +// coregen generates + + //*************************************************************************** + // constants for the core behavior + //*************************************************************************** + // file handles for logging + //-------------------------------------------------- + localparam ADDRFILE = 32'h8000_0001; //stdout for addr out of range + localparam COLLFILE = 32'h8000_0001; //stdout for coll detection + localparam ERRFILE = 32'h8000_0001; //stdout for file I/O errors + + // other constants + //-------------------------------------------------- + localparam COLL_DELAY = 100; // 100 ps + + // locally derived parameters to determine memory shape + //----------------------------------------------------- + + localparam CHKBIT_WIDTH = (C_WRITE_WIDTH_A>57 ? 8 : (C_WRITE_WIDTH_A>26 ? 7 : (C_WRITE_WIDTH_A>11 ? 6 : (C_WRITE_WIDTH_A>4 ? 5 : (C_WRITE_WIDTH_A<5 ? 4 :0))))); + + localparam MIN_WIDTH_A = (C_WRITE_WIDTH_A < C_READ_WIDTH_A) ? + C_WRITE_WIDTH_A : C_READ_WIDTH_A; + localparam MIN_WIDTH_B = (C_WRITE_WIDTH_B < C_READ_WIDTH_B) ? + C_WRITE_WIDTH_B : C_READ_WIDTH_B; + localparam MIN_WIDTH = (MIN_WIDTH_A < MIN_WIDTH_B) ? + MIN_WIDTH_A : MIN_WIDTH_B; + + localparam MAX_DEPTH_A = (C_WRITE_DEPTH_A > C_READ_DEPTH_A) ? + C_WRITE_DEPTH_A : C_READ_DEPTH_A; + localparam MAX_DEPTH_B = (C_WRITE_DEPTH_B > C_READ_DEPTH_B) ? + C_WRITE_DEPTH_B : C_READ_DEPTH_B; + localparam MAX_DEPTH = (MAX_DEPTH_A > MAX_DEPTH_B) ? + MAX_DEPTH_A : MAX_DEPTH_B; + + + // locally derived parameters to assist memory access + //---------------------------------------------------- + // Calculate the width ratios of each port with respect to the narrowest + // port + localparam WRITE_WIDTH_RATIO_A = C_WRITE_WIDTH_A/MIN_WIDTH; + localparam READ_WIDTH_RATIO_A = C_READ_WIDTH_A/MIN_WIDTH; + localparam WRITE_WIDTH_RATIO_B = C_WRITE_WIDTH_B/MIN_WIDTH; + localparam READ_WIDTH_RATIO_B = C_READ_WIDTH_B/MIN_WIDTH; + + // To modify the LSBs of the 'wider' data to the actual + // address value + //---------------------------------------------------- + localparam WRITE_ADDR_A_DIV = C_WRITE_WIDTH_A/MIN_WIDTH_A; + localparam READ_ADDR_A_DIV = C_READ_WIDTH_A/MIN_WIDTH_A; + localparam WRITE_ADDR_B_DIV = C_WRITE_WIDTH_B/MIN_WIDTH_B; + localparam READ_ADDR_B_DIV = C_READ_WIDTH_B/MIN_WIDTH_B; + + // If byte writes aren't being used, make sure BYTE_SIZE is not + // wider than the memory elements to avoid compilation warnings + localparam BYTE_SIZE = (C_BYTE_SIZE < MIN_WIDTH) ? C_BYTE_SIZE : MIN_WIDTH; + + // The memory + reg [MIN_WIDTH-1:0] memory [0:MAX_DEPTH-1]; + reg [MIN_WIDTH-1:0] temp_mem_array [0:MAX_DEPTH-1]; + reg [C_WRITE_WIDTH_A+CHKBIT_WIDTH-1:0] doublebit_error = 3; + // ECC error arrays + reg sbiterr_arr [0:MAX_DEPTH-1]; + reg dbiterr_arr [0:MAX_DEPTH-1]; + + reg softecc_sbiterr_arr [0:MAX_DEPTH-1]; + reg softecc_dbiterr_arr [0:MAX_DEPTH-1]; + // Memory output 'latches' + reg [C_READ_WIDTH_A-1:0] memory_out_a; + reg [C_READ_WIDTH_B-1:0] memory_out_b; + + // ECC error inputs and outputs from output_stage module: + reg sbiterr_in; + wire sbiterr_sdp; + reg dbiterr_in; + wire dbiterr_sdp; + + wire [C_READ_WIDTH_B-1:0] dout_i; + wire dbiterr_i; + wire sbiterr_i; + wire [C_ADDRB_WIDTH-1:0] rdaddrecc_i; + + reg [C_ADDRB_WIDTH-1:0] rdaddrecc_in; + wire [C_ADDRB_WIDTH-1:0] rdaddrecc_sdp; + + // Reset values + reg [C_READ_WIDTH_A-1:0] inita_val; + reg [C_READ_WIDTH_B-1:0] initb_val; + + // Collision detect + reg is_collision; + reg is_collision_a, is_collision_delay_a; + reg is_collision_b, is_collision_delay_b; + + // Temporary variables for initialization + //--------------------------------------- + integer status; + integer initfile; + integer meminitfile; + // data input buffer + reg [C_WRITE_WIDTH_A-1:0] mif_data; + reg [C_WRITE_WIDTH_A-1:0] mem_data; + // string values in hex + reg [C_READ_WIDTH_A*8-1:0] inita_str = C_INITA_VAL; + reg [C_READ_WIDTH_B*8-1:0] initb_str = C_INITB_VAL; + reg [C_WRITE_WIDTH_A*8-1:0] default_data_str = C_DEFAULT_DATA; + // initialization filename + reg [1023*8-1:0] init_file_str = C_INIT_FILE_NAME; + reg [1023*8-1:0] mem_init_file_str = C_INIT_FILE; + + + //Constants used to calculate the effective address widths for each of the + //four ports. + integer cnt = 1; + integer write_addr_a_width, read_addr_a_width; + integer write_addr_b_width, read_addr_b_width; + + localparam C_FAMILY_LOCALPARAM = (C_FAMILY=="virtexuplushbm"?"virtex7":(C_FAMILY=="zynquplusrfsoc"?"virtex7":(C_FAMILY=="zynquplus"?"virtex7":(C_FAMILY=="kintexuplus"?"virtex7":(C_FAMILY=="virtexuplus"?"virtex7":(C_FAMILY=="virtexu"?"virtex7":(C_FAMILY=="kintexu" ? "virtex7":(C_FAMILY=="virtex7" ? "virtex7" : (C_FAMILY=="virtex7l" ? "virtex7" : (C_FAMILY=="qvirtex7" ? "virtex7" : (C_FAMILY=="qvirtex7l" ? "virtex7" : (C_FAMILY=="kintex7" ? "virtex7" : (C_FAMILY=="kintex7l" ? "virtex7" : (C_FAMILY=="qkintex7" ? "virtex7" : (C_FAMILY=="qkintex7l" ? "virtex7" : (C_FAMILY=="artix7" ? "virtex7" : (C_FAMILY=="artix7l" ? "virtex7" : (C_FAMILY=="qartix7" ? "virtex7" : (C_FAMILY=="qartix7l" ? "virtex7" : (C_FAMILY=="aartix7" ? "virtex7" : (C_FAMILY=="zynq" ? "virtex7" : (C_FAMILY=="azynq" ? "virtex7" : (C_FAMILY=="qzynq" ? "virtex7" : C_FAMILY))))))))))))))))))))))); + + // Internal configuration parameters + //--------------------------------------------- + localparam SINGLE_PORT = (C_MEM_TYPE==0 || C_MEM_TYPE==3); + localparam IS_ROM = (C_MEM_TYPE==3 || C_MEM_TYPE==4); + localparam HAS_A_WRITE = (!IS_ROM); + localparam HAS_B_WRITE = (C_MEM_TYPE==2); + localparam HAS_A_READ = (C_MEM_TYPE!=1); + localparam HAS_B_READ = (!SINGLE_PORT); + localparam HAS_B_PORT = (HAS_B_READ || HAS_B_WRITE); + + // Calculate the mux pipeline register stages for Port A and Port B + //------------------------------------------------------------------ + localparam MUX_PIPELINE_STAGES_A = (C_HAS_MUX_OUTPUT_REGS_A) ? + C_MUX_PIPELINE_STAGES : 0; + localparam MUX_PIPELINE_STAGES_B = (C_HAS_MUX_OUTPUT_REGS_B) ? + C_MUX_PIPELINE_STAGES : 0; + + // Calculate total number of register stages in the core + // ----------------------------------------------------- + localparam NUM_OUTPUT_STAGES_A = (C_HAS_MEM_OUTPUT_REGS_A+MUX_PIPELINE_STAGES_A+C_HAS_MUX_OUTPUT_REGS_A); + + localparam NUM_OUTPUT_STAGES_B = (C_HAS_MEM_OUTPUT_REGS_B+MUX_PIPELINE_STAGES_B+C_HAS_MUX_OUTPUT_REGS_B); + + wire ena_i; + wire enb_i; + wire reseta_i; + wire resetb_i; + wire [C_WEA_WIDTH-1:0] wea_i; + wire [C_WEB_WIDTH-1:0] web_i; + wire rea_i; + wire reb_i; + wire rsta_outp_stage; + wire rstb_outp_stage; + // ECC SBITERR/DBITERR Outputs + // The ECC Behavior is modeled by the behavioral models only for Virtex-6. + // For Virtex-5, these outputs will be tied to 0. + assign SBITERR = ((C_MEM_TYPE == 1 && C_USE_ECC == 1) || C_USE_SOFTECC == 1)?sbiterr_sdp:0; + assign DBITERR = ((C_MEM_TYPE == 1 && C_USE_ECC == 1) || C_USE_SOFTECC == 1)?dbiterr_sdp:0; + assign RDADDRECC = (((C_FAMILY_LOCALPARAM == "virtex7") && C_MEM_TYPE == 1 && C_USE_ECC == 1) || C_USE_SOFTECC == 1)?rdaddrecc_sdp:0; + + + // This effectively wires off optional inputs + assign ena_i = (C_HAS_ENA==0) || ENA; + assign enb_i = ((C_HAS_ENB==0) || ENB) && HAS_B_PORT; + // To match RTL : In RTL, write enable of the primitive is tied to all 1's and + // the enable of the primitive is ANDing of wea(0) and ena. so eventually, the + // write operation depends on both enable and write enable. So, the below code + // which is actually doing the write operation only on enable ignoring the wea + // is removed to be in consistent with RTL. + // To Fix CR855535 (The fix to this CR is reverted to match RTL) + //assign wea_i = (HAS_A_WRITE == 1 && C_MEM_TYPE == 1 &&C_USE_ECC == 1 && C_HAS_ENA == 1 && ENA == 1) ? 'b1 :(HAS_A_WRITE == 1 && C_MEM_TYPE == 1 &&C_USE_ECC == 1 && C_HAS_ENA == 0) ? WEA : (HAS_A_WRITE && ena_i && C_USE_ECC == 0) ? WEA : 'b0; + assign wea_i = (HAS_A_WRITE && ena_i) ? WEA : 'b0; + assign web_i = (HAS_B_WRITE && enb_i) ? WEB : 'b0; + assign rea_i = (HAS_A_READ) ? ena_i : 'b0; + assign reb_i = (HAS_B_READ) ? enb_i : 'b0; + + // These signals reset the memory latches + + assign reseta_i = + ((C_HAS_RSTA==1 && RSTA && NUM_OUTPUT_STAGES_A==0) || + (C_HAS_RSTA==1 && RSTA && C_RSTRAM_A==1)); + + assign resetb_i = + ((C_HAS_RSTB==1 && RSTB && NUM_OUTPUT_STAGES_B==0) || + (C_HAS_RSTB==1 && RSTB && C_RSTRAM_B==1)); + + // Tasks to access the memory + //--------------------------- + //************** + // write_a + //************** + task write_a + (input reg [C_ADDRA_WIDTH-1:0] addr, + input reg [C_WEA_WIDTH-1:0] byte_en, + input reg [C_WRITE_WIDTH_A-1:0] data, + input inj_sbiterr, + input inj_dbiterr); + reg [C_WRITE_WIDTH_A-1:0] current_contents; + reg [C_ADDRA_WIDTH-1:0] address; + integer i; + begin + // Shift the address by the ratio + address = (addr/WRITE_ADDR_A_DIV); + if (address >= C_WRITE_DEPTH_A) begin + if (!C_DISABLE_WARN_BHV_RANGE) begin + $fdisplay(ADDRFILE, + "%0s WARNING: Address %0h is outside range for A Write", + C_CORENAME, addr); + end + + // valid address + end else begin + + // Combine w/ byte writes + if (C_USE_BYTE_WEA) begin + + // Get the current memory contents + if (WRITE_WIDTH_RATIO_A == 1) begin + // Workaround for IUS 5.5 part-select issue + current_contents = memory[address]; + end else begin + for (i = 0; i < WRITE_WIDTH_RATIO_A; i = i + 1) begin + current_contents[MIN_WIDTH*i+:MIN_WIDTH] + = memory[address*WRITE_WIDTH_RATIO_A + i]; + end + end + + // Apply incoming bytes + if (C_WEA_WIDTH == 1) begin + // Workaround for IUS 5.5 part-select issue + if (byte_en[0]) begin + current_contents = data; + end + end else begin + for (i = 0; i < C_WEA_WIDTH; i = i + 1) begin + if (byte_en[i]) begin + current_contents[BYTE_SIZE*i+:BYTE_SIZE] + = data[BYTE_SIZE*i+:BYTE_SIZE]; + end + end + end + + // No byte-writes, overwrite the whole word + end else begin + current_contents = data; + end + + // Insert double bit errors: + if (C_USE_ECC == 1) begin + if ((C_HAS_INJECTERR == 2 || C_HAS_INJECTERR == 3) && inj_dbiterr == 1'b1) begin +// Modified for Implementing CR_859399 + current_contents[0] = !(current_contents[30]); + current_contents[1] = !(current_contents[62]); + + /*current_contents[0] = !(current_contents[0]); + current_contents[1] = !(current_contents[1]);*/ + end + end + + // Insert softecc double bit errors: + if (C_USE_SOFTECC == 1) begin + if ((C_HAS_INJECTERR == 2 || C_HAS_INJECTERR == 3) && inj_dbiterr == 1'b1) begin + doublebit_error[C_WRITE_WIDTH_A+CHKBIT_WIDTH-1:2] = doublebit_error[C_WRITE_WIDTH_A+CHKBIT_WIDTH-3:0]; + doublebit_error[0] = doublebit_error[C_WRITE_WIDTH_A+CHKBIT_WIDTH-1]; + doublebit_error[1] = doublebit_error[C_WRITE_WIDTH_A+CHKBIT_WIDTH-2]; + current_contents = current_contents ^ doublebit_error[C_WRITE_WIDTH_A-1:0]; + end + end + + // Write data to memory + if (WRITE_WIDTH_RATIO_A == 1) begin + // Workaround for IUS 5.5 part-select issue + memory[address*WRITE_WIDTH_RATIO_A] = current_contents; + end else begin + for (i = 0; i < WRITE_WIDTH_RATIO_A; i = i + 1) begin + memory[address*WRITE_WIDTH_RATIO_A + i] + = current_contents[MIN_WIDTH*i+:MIN_WIDTH]; + end + end + + // Store the address at which error is injected: + if ((C_FAMILY_LOCALPARAM == "virtex7") && C_USE_ECC == 1) begin + if ((C_HAS_INJECTERR == 1 && inj_sbiterr == 1'b1) || + (C_HAS_INJECTERR == 3 && inj_sbiterr == 1'b1 && inj_dbiterr != 1'b1)) + begin + sbiterr_arr[addr] = 1; + end else begin + sbiterr_arr[addr] = 0; + end + + if ((C_HAS_INJECTERR == 2 || C_HAS_INJECTERR == 3) && inj_dbiterr == 1'b1) begin + dbiterr_arr[addr] = 1; + end else begin + dbiterr_arr[addr] = 0; + end + end + + // Store the address at which softecc error is injected: + if (C_USE_SOFTECC == 1) begin + if ((C_HAS_INJECTERR == 1 && inj_sbiterr == 1'b1) || + (C_HAS_INJECTERR == 3 && inj_sbiterr == 1'b1 && inj_dbiterr != 1'b1)) + begin + softecc_sbiterr_arr[addr] = 1; + end else begin + softecc_sbiterr_arr[addr] = 0; + end + + if ((C_HAS_INJECTERR == 2 || C_HAS_INJECTERR == 3) && inj_dbiterr == 1'b1) begin + softecc_dbiterr_arr[addr] = 1; + end else begin + softecc_dbiterr_arr[addr] = 0; + end + end + + end + end + endtask + + //************** + // write_b + //************** + task write_b + (input reg [C_ADDRB_WIDTH-1:0] addr, + input reg [C_WEB_WIDTH-1:0] byte_en, + input reg [C_WRITE_WIDTH_B-1:0] data); + reg [C_WRITE_WIDTH_B-1:0] current_contents; + reg [C_ADDRB_WIDTH-1:0] address; + integer i; + begin + // Shift the address by the ratio + address = (addr/WRITE_ADDR_B_DIV); + if (address >= C_WRITE_DEPTH_B) begin + if (!C_DISABLE_WARN_BHV_RANGE) begin + $fdisplay(ADDRFILE, + "%0s WARNING: Address %0h is outside range for B Write", + C_CORENAME, addr); + end + + // valid address + end else begin + + // Combine w/ byte writes + if (C_USE_BYTE_WEB) begin + + // Get the current memory contents + if (WRITE_WIDTH_RATIO_B == 1) begin + // Workaround for IUS 5.5 part-select issue + current_contents = memory[address]; + end else begin + for (i = 0; i < WRITE_WIDTH_RATIO_B; i = i + 1) begin + current_contents[MIN_WIDTH*i+:MIN_WIDTH] + = memory[address*WRITE_WIDTH_RATIO_B + i]; + end + end + + // Apply incoming bytes + if (C_WEB_WIDTH == 1) begin + // Workaround for IUS 5.5 part-select issue + if (byte_en[0]) begin + current_contents = data; + end + end else begin + for (i = 0; i < C_WEB_WIDTH; i = i + 1) begin + if (byte_en[i]) begin + current_contents[BYTE_SIZE*i+:BYTE_SIZE] + = data[BYTE_SIZE*i+:BYTE_SIZE]; + end + end + end + + // No byte-writes, overwrite the whole word + end else begin + current_contents = data; + end + + // Write data to memory + if (WRITE_WIDTH_RATIO_B == 1) begin + // Workaround for IUS 5.5 part-select issue + memory[address*WRITE_WIDTH_RATIO_B] = current_contents; + end else begin + for (i = 0; i < WRITE_WIDTH_RATIO_B; i = i + 1) begin + memory[address*WRITE_WIDTH_RATIO_B + i] + = current_contents[MIN_WIDTH*i+:MIN_WIDTH]; + end + end + end + end + endtask + + //************** + // read_a + //************** + task read_a + (input reg [C_ADDRA_WIDTH-1:0] addr, + input reg reset); + reg [C_ADDRA_WIDTH-1:0] address; + integer i; + begin + + if (reset) begin + memory_out_a <= #FLOP_DELAY inita_val; + end else begin + // Shift the address by the ratio + address = (addr/READ_ADDR_A_DIV); + if (address >= C_READ_DEPTH_A) begin + if (!C_DISABLE_WARN_BHV_RANGE) begin + $fdisplay(ADDRFILE, + "%0s WARNING: Address %0h is outside range for A Read", + C_CORENAME, addr); + end + memory_out_a <= #FLOP_DELAY 'bX; + // valid address + end else begin + if (READ_WIDTH_RATIO_A==1) begin + memory_out_a <= #FLOP_DELAY memory[address*READ_WIDTH_RATIO_A]; + end else begin + // Increment through the 'partial' words in the memory + for (i = 0; i < READ_WIDTH_RATIO_A; i = i + 1) begin + memory_out_a[MIN_WIDTH*i+:MIN_WIDTH] + <= #FLOP_DELAY memory[address*READ_WIDTH_RATIO_A + i]; + end + end //end READ_WIDTH_RATIO_A==1 loop + + end //end valid address loop + end //end reset-data assignment loops + end + endtask + + //************** + // read_b + //************** + task read_b + (input reg [C_ADDRB_WIDTH-1:0] addr, + input reg reset); + reg [C_ADDRB_WIDTH-1:0] address; + integer i; + begin + + if (reset) begin + memory_out_b <= #FLOP_DELAY initb_val; + sbiterr_in <= #FLOP_DELAY 1'b0; + dbiterr_in <= #FLOP_DELAY 1'b0; + rdaddrecc_in <= #FLOP_DELAY 0; + end else begin + // Shift the address + address = (addr/READ_ADDR_B_DIV); + if (address >= C_READ_DEPTH_B) begin + if (!C_DISABLE_WARN_BHV_RANGE) begin + $fdisplay(ADDRFILE, + "%0s WARNING: Address %0h is outside range for B Read", + C_CORENAME, addr); + end + memory_out_b <= #FLOP_DELAY 'bX; + sbiterr_in <= #FLOP_DELAY 1'bX; + dbiterr_in <= #FLOP_DELAY 1'bX; + rdaddrecc_in <= #FLOP_DELAY 'bX; + // valid address + end else begin + if (READ_WIDTH_RATIO_B==1) begin + memory_out_b <= #FLOP_DELAY memory[address*READ_WIDTH_RATIO_B]; + end else begin + // Increment through the 'partial' words in the memory + for (i = 0; i < READ_WIDTH_RATIO_B; i = i + 1) begin + memory_out_b[MIN_WIDTH*i+:MIN_WIDTH] + <= #FLOP_DELAY memory[address*READ_WIDTH_RATIO_B + i]; + end + end + + if ((C_FAMILY_LOCALPARAM == "virtex7") && C_USE_ECC == 1) begin + rdaddrecc_in <= #FLOP_DELAY addr; + if (sbiterr_arr[addr] == 1) begin + sbiterr_in <= #FLOP_DELAY 1'b1; + end else begin + sbiterr_in <= #FLOP_DELAY 1'b0; + end + + if (dbiterr_arr[addr] == 1) begin + dbiterr_in <= #FLOP_DELAY 1'b1; + end else begin + dbiterr_in <= #FLOP_DELAY 1'b0; + end + + end else if (C_USE_SOFTECC == 1) begin + rdaddrecc_in <= #FLOP_DELAY addr; + if (softecc_sbiterr_arr[addr] == 1) begin + sbiterr_in <= #FLOP_DELAY 1'b1; + end else begin + sbiterr_in <= #FLOP_DELAY 1'b0; + end + + if (softecc_dbiterr_arr[addr] == 1) begin + dbiterr_in <= #FLOP_DELAY 1'b1; + end else begin + dbiterr_in <= #FLOP_DELAY 1'b0; + end + end else begin + rdaddrecc_in <= #FLOP_DELAY 0; + dbiterr_in <= #FLOP_DELAY 1'b0; + sbiterr_in <= #FLOP_DELAY 1'b0; + end //end SOFTECC Loop + end //end Valid address loop + end //end reset-data assignment loops + end + endtask + + //************** + // reset_a + //************** + task reset_a (input reg reset); + begin + if (reset) memory_out_a <= #FLOP_DELAY inita_val; + end + endtask + + //************** + // reset_b + //************** + task reset_b (input reg reset); + begin + if (reset) memory_out_b <= #FLOP_DELAY initb_val; + end + endtask + + //************** + // init_memory + //************** + task init_memory; + integer i, j, addr_step; + integer status; + reg [C_WRITE_WIDTH_A-1:0] default_data; + begin + default_data = 0; + + //Display output message indicating that the behavioral model is being + //initialized + if (C_USE_DEFAULT_DATA || C_LOAD_INIT_FILE) $display(" Block Memory Generator module loading initial data..."); + + // Convert the default to hex + if (C_USE_DEFAULT_DATA) begin + if (default_data_str == "") begin + $fdisplay(ERRFILE, "%0s ERROR: C_DEFAULT_DATA is empty!", C_CORENAME); + $finish; + end else begin + status = $sscanf(default_data_str, "%h", default_data); + if (status == 0) begin + $fdisplay(ERRFILE, {"%0s ERROR: Unsuccessful hexadecimal read", + "from C_DEFAULT_DATA: %0s"}, + C_CORENAME, C_DEFAULT_DATA); + $finish; + end + end + end + + // Step by WRITE_ADDR_A_DIV through the memory via the + // Port A write interface to hit every location once + addr_step = WRITE_ADDR_A_DIV; + + // 'write' to every location with default (or 0) + for (i = 0; i < C_WRITE_DEPTH_A*addr_step; i = i + addr_step) begin + write_a(i, {C_WEA_WIDTH{1'b1}}, default_data, 1'b0, 1'b0); + end + + // Get specialized data from the MIF file + if (C_LOAD_INIT_FILE) begin + if (init_file_str == "") begin + $fdisplay(ERRFILE, "%0s ERROR: C_INIT_FILE_NAME is empty!", + C_CORENAME); + $finish; + end else begin + initfile = $fopen(init_file_str, "r"); + if (initfile == 0) begin + $fdisplay(ERRFILE, {"%0s, ERROR: Problem opening", + "C_INIT_FILE_NAME: %0s!"}, + C_CORENAME, init_file_str); + $finish; + end else begin + // loop through the mif file, loading in the data + for (i = 0; i < C_WRITE_DEPTH_A*addr_step; i = i + addr_step) begin + status = $fscanf(initfile, "%b", mif_data); + if (status > 0) begin + write_a(i, {C_WEA_WIDTH{1'b1}}, mif_data, 1'b0, 1'b0); + end + end + $fclose(initfile); + end //initfile + end //init_file_str + end //C_LOAD_INIT_FILE + + + if (C_USE_BRAM_BLOCK) begin + // Get specialized data from the MIF file + if (C_INIT_FILE != "NONE") begin + if (mem_init_file_str == "") begin + $fdisplay(ERRFILE, "%0s ERROR: C_INIT_FILE is empty!", + C_CORENAME); + $finish; + end else begin + meminitfile = $fopen(mem_init_file_str, "r"); + if (meminitfile == 0) begin + $fdisplay(ERRFILE, {"%0s, ERROR: Problem opening", + "C_INIT_FILE: %0s!"}, + C_CORENAME, mem_init_file_str); + $finish; + end else begin + // loop through the mif file, loading in the data + $readmemh(mem_init_file_str, memory ); + for (j = 0; j < MAX_DEPTH-1 ; j = j + 1) begin + end + $fclose(meminitfile); + end //meminitfile + end //mem_init_file_str + end //C_INIT_FILE + end //C_USE_BRAM_BLOCK + + //Display output message indicating that the behavioral model is done + //initializing + if (C_USE_DEFAULT_DATA || C_LOAD_INIT_FILE) + $display(" Block Memory Generator data initialization complete."); + end + endtask + + //************** + // log2roundup + //************** + function integer log2roundup (input integer data_value); + integer width; + integer cnt; + begin + width = 0; + + if (data_value > 1) begin + for(cnt=1 ; cnt < data_value ; cnt = cnt * 2) begin + width = width + 1; + end //loop + end //if + + log2roundup = width; + + end //log2roundup + endfunction + + + //******************* + // collision_check + //******************* + function integer collision_check (input reg [C_ADDRA_WIDTH-1:0] addr_a, + input integer iswrite_a, + input reg [C_ADDRB_WIDTH-1:0] addr_b, + input integer iswrite_b); + reg c_aw_bw, c_aw_br, c_ar_bw; + integer scaled_addra_to_waddrb_width; + integer scaled_addrb_to_waddrb_width; + integer scaled_addra_to_waddra_width; + integer scaled_addrb_to_waddra_width; + integer scaled_addra_to_raddrb_width; + integer scaled_addrb_to_raddrb_width; + integer scaled_addra_to_raddra_width; + integer scaled_addrb_to_raddra_width; + + + + begin + + c_aw_bw = 0; + c_aw_br = 0; + c_ar_bw = 0; + + //If write_addr_b_width is smaller, scale both addresses to that width for + //comparing write_addr_a and write_addr_b; addr_a starts as C_ADDRA_WIDTH, + //scale it down to write_addr_b_width. addr_b starts as C_ADDRB_WIDTH, + //scale it down to write_addr_b_width. Once both are scaled to + //write_addr_b_width, compare. + scaled_addra_to_waddrb_width = ((addr_a)/ + 2**(C_ADDRA_WIDTH-write_addr_b_width)); + scaled_addrb_to_waddrb_width = ((addr_b)/ + 2**(C_ADDRB_WIDTH-write_addr_b_width)); + + //If write_addr_a_width is smaller, scale both addresses to that width for + //comparing write_addr_a and write_addr_b; addr_a starts as C_ADDRA_WIDTH, + //scale it down to write_addr_a_width. addr_b starts as C_ADDRB_WIDTH, + //scale it down to write_addr_a_width. Once both are scaled to + //write_addr_a_width, compare. + scaled_addra_to_waddra_width = ((addr_a)/ + 2**(C_ADDRA_WIDTH-write_addr_a_width)); + scaled_addrb_to_waddra_width = ((addr_b)/ + 2**(C_ADDRB_WIDTH-write_addr_a_width)); + + //If read_addr_b_width is smaller, scale both addresses to that width for + //comparing write_addr_a and read_addr_b; addr_a starts as C_ADDRA_WIDTH, + //scale it down to read_addr_b_width. addr_b starts as C_ADDRB_WIDTH, + //scale it down to read_addr_b_width. Once both are scaled to + //read_addr_b_width, compare. + scaled_addra_to_raddrb_width = ((addr_a)/ + 2**(C_ADDRA_WIDTH-read_addr_b_width)); + scaled_addrb_to_raddrb_width = ((addr_b)/ + 2**(C_ADDRB_WIDTH-read_addr_b_width)); + + //If read_addr_a_width is smaller, scale both addresses to that width for + //comparing read_addr_a and write_addr_b; addr_a starts as C_ADDRA_WIDTH, + //scale it down to read_addr_a_width. addr_b starts as C_ADDRB_WIDTH, + //scale it down to read_addr_a_width. Once both are scaled to + //read_addr_a_width, compare. + scaled_addra_to_raddra_width = ((addr_a)/ + 2**(C_ADDRA_WIDTH-read_addr_a_width)); + scaled_addrb_to_raddra_width = ((addr_b)/ + 2**(C_ADDRB_WIDTH-read_addr_a_width)); + + //Look for a write-write collision. In order for a write-write + //collision to exist, both ports must have a write transaction. + if (iswrite_a && iswrite_b) begin + if (write_addr_a_width > write_addr_b_width) begin + if (scaled_addra_to_waddrb_width == scaled_addrb_to_waddrb_width) begin + c_aw_bw = 1; + end else begin + c_aw_bw = 0; + end + end else begin + if (scaled_addrb_to_waddra_width == scaled_addra_to_waddra_width) begin + c_aw_bw = 1; + end else begin + c_aw_bw = 0; + end + end //width + end //iswrite_a and iswrite_b + + //If the B port is reading (which means it is enabled - so could be + //a TX_WRITE or TX_READ), then check for a write-read collision). + //This could happen whether or not a write-write collision exists due + //to asymmetric write/read ports. + if (iswrite_a) begin + if (write_addr_a_width > read_addr_b_width) begin + if (scaled_addra_to_raddrb_width == scaled_addrb_to_raddrb_width) begin + c_aw_br = 1; + end else begin + c_aw_br = 0; + end + end else begin + if (scaled_addrb_to_waddra_width == scaled_addra_to_waddra_width) begin + c_aw_br = 1; + end else begin + c_aw_br = 0; + end + end //width + end //iswrite_a + + //If the A port is reading (which means it is enabled - so could be + // a TX_WRITE or TX_READ), then check for a write-read collision). + //This could happen whether or not a write-write collision exists due + // to asymmetric write/read ports. + if (iswrite_b) begin + if (read_addr_a_width > write_addr_b_width) begin + if (scaled_addra_to_waddrb_width == scaled_addrb_to_waddrb_width) begin + c_ar_bw = 1; + end else begin + c_ar_bw = 0; + end + end else begin + if (scaled_addrb_to_raddra_width == scaled_addra_to_raddra_width) begin + c_ar_bw = 1; + end else begin + c_ar_bw = 0; + end + end //width + end //iswrite_b + + + + collision_check = c_aw_bw | c_aw_br | c_ar_bw; + + end + endfunction + + //******************************* + // power on values + //******************************* + initial begin + // Load up the memory + init_memory; + // Load up the output registers and latches + if ($sscanf(inita_str, "%h", inita_val)) begin + memory_out_a = inita_val; + end else begin + memory_out_a = 0; + end + if ($sscanf(initb_str, "%h", initb_val)) begin + memory_out_b = initb_val; + end else begin + memory_out_b = 0; + end + + sbiterr_in = 1'b0; + dbiterr_in = 1'b0; + rdaddrecc_in = 0; + + // Determine the effective address widths for each of the 4 ports + write_addr_a_width = C_ADDRA_WIDTH - log2roundup(WRITE_ADDR_A_DIV); + read_addr_a_width = C_ADDRA_WIDTH - log2roundup(READ_ADDR_A_DIV); + write_addr_b_width = C_ADDRB_WIDTH - log2roundup(WRITE_ADDR_B_DIV); + read_addr_b_width = C_ADDRB_WIDTH - log2roundup(READ_ADDR_B_DIV); + + $display("Block Memory Generator module %m is using a behavioral model for simulation which will not precisely model memory collision behavior."); + + end + + //*************************************************************************** + // These are the main blocks which schedule read and write operations + // Note that the reset priority feature at the latch stage is only supported + // for Spartan-6. For other families, the default priority at the latch stage + // is "CE" + //*************************************************************************** + // Synchronous clocks: schedule port operations with respect to + // both write operating modes + generate + if(C_COMMON_CLK && (C_WRITE_MODE_A == "WRITE_FIRST") && (C_WRITE_MODE_B == + "WRITE_FIRST")) begin : com_clk_sched_wf_wf + always @(posedge CLKA) begin + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + + if (rea_i) read_a(ADDRA, reseta_i); + + //Read B + if (reb_i) read_b(ADDRB, resetb_i); + end + end + else + if(C_COMMON_CLK && (C_WRITE_MODE_A == "READ_FIRST") && (C_WRITE_MODE_B == + "WRITE_FIRST")) begin : com_clk_sched_rf_wf + always @(posedge CLKA) begin + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + //Read B + if (reb_i) read_b(ADDRB, resetb_i); + //Read A + if (rea_i) read_a(ADDRA, reseta_i); + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + end + end + else + if(C_COMMON_CLK && (C_WRITE_MODE_A == "WRITE_FIRST") && (C_WRITE_MODE_B == + "READ_FIRST")) begin : com_clk_sched_wf_rf + always @(posedge CLKA) begin + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Read A + if (rea_i) read_a(ADDRA, reseta_i); + //Read B + if (reb_i) read_b(ADDRB, resetb_i); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + end + end + else + if(C_COMMON_CLK && (C_WRITE_MODE_A == "READ_FIRST") && (C_WRITE_MODE_B == + "READ_FIRST")) begin : com_clk_sched_rf_rf + always @(posedge CLKA) begin + //Read A + if (rea_i) read_a(ADDRA, reseta_i); + //Read B + if (reb_i) read_b(ADDRB, resetb_i); + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + end + end + else if(C_COMMON_CLK && (C_WRITE_MODE_A =="WRITE_FIRST") && (C_WRITE_MODE_B == + "NO_CHANGE")) begin : com_clk_sched_wf_nc + always @(posedge CLKA) begin + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Read A + if (rea_i) read_a(ADDRA, reseta_i); + //Read B + if (reb_i && (!web_i || resetb_i)) read_b(ADDRB, resetb_i); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + end + end + else if(C_COMMON_CLK && (C_WRITE_MODE_A =="READ_FIRST") && (C_WRITE_MODE_B == + "NO_CHANGE")) begin : com_clk_sched_rf_nc + always @(posedge CLKA) begin + //Read A + if (rea_i) read_a(ADDRA, reseta_i); + //Read B + if (reb_i && (!web_i || resetb_i)) read_b(ADDRB, resetb_i); + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + end + end + else if(C_COMMON_CLK && (C_WRITE_MODE_A =="NO_CHANGE") && (C_WRITE_MODE_B == + "WRITE_FIRST")) begin : com_clk_sched_nc_wf + always @(posedge CLKA) begin + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + //Read A + if (rea_i && (!wea_i || reseta_i)) read_a(ADDRA, reseta_i); + //Read B + if (reb_i) read_b(ADDRB, resetb_i); + end + end + else if(C_COMMON_CLK && (C_WRITE_MODE_A =="NO_CHANGE") && (C_WRITE_MODE_B == + "READ_FIRST")) begin : com_clk_sched_nc_rf + always @(posedge CLKA) begin + //Read B + if (reb_i) read_b(ADDRB, resetb_i); + //Read A + if (rea_i && (!wea_i || reseta_i)) read_a(ADDRA, reseta_i); + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + end + end + else if(C_COMMON_CLK && (C_WRITE_MODE_A =="NO_CHANGE") && (C_WRITE_MODE_B == + "NO_CHANGE")) begin : com_clk_sched_nc_nc + always @(posedge CLKA) begin + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + //Read A + if (rea_i && (!wea_i || reseta_i)) read_a(ADDRA, reseta_i); + //Read B + if (reb_i && (!web_i || resetb_i)) read_b(ADDRB, resetb_i); + end + end + else if(C_COMMON_CLK) begin: com_clk_sched_default + always @(posedge CLKA) begin + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + //Read A + if (rea_i) read_a(ADDRA, reseta_i); + //Read B + if (reb_i) read_b(ADDRB, resetb_i); + end + end + endgenerate + + // Asynchronous clocks: port operation is independent + generate + if((!C_COMMON_CLK) && (C_WRITE_MODE_A == "WRITE_FIRST")) begin : async_clk_sched_clka_wf + always @(posedge CLKA) begin + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Read A + if (rea_i) read_a(ADDRA, reseta_i); + end + end + else if((!C_COMMON_CLK) && (C_WRITE_MODE_A == "READ_FIRST")) begin : async_clk_sched_clka_rf + always @(posedge CLKA) begin + //Read A + if (rea_i) read_a(ADDRA, reseta_i); + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + end + end + else if((!C_COMMON_CLK) && (C_WRITE_MODE_A == "NO_CHANGE")) begin : async_clk_sched_clka_nc + always @(posedge CLKA) begin + //Write A + if (wea_i) write_a(ADDRA, wea_i, DINA, INJECTSBITERR, INJECTDBITERR); + //Read A + if (rea_i && (!wea_i || reseta_i)) read_a(ADDRA, reseta_i); + end + end + endgenerate + + generate + if ((!C_COMMON_CLK) && (C_WRITE_MODE_B == "WRITE_FIRST")) begin: async_clk_sched_clkb_wf + always @(posedge CLKB) begin + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + //Read B + if (reb_i) read_b(ADDRB, resetb_i); + end + end + else if ((!C_COMMON_CLK) && (C_WRITE_MODE_B == "READ_FIRST")) begin: async_clk_sched_clkb_rf + always @(posedge CLKB) begin + //Read B + if (reb_i) read_b(ADDRB, resetb_i); + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + end + end + else if ((!C_COMMON_CLK) && (C_WRITE_MODE_B == "NO_CHANGE")) begin: async_clk_sched_clkb_nc + always @(posedge CLKB) begin + //Write B + if (web_i) write_b(ADDRB, web_i, DINB); + //Read B + if (reb_i && (!web_i || resetb_i)) read_b(ADDRB, resetb_i); + end + end + endgenerate + + + //*************************************************************** + // Instantiate the variable depth output register stage module + //*************************************************************** + // Port A + + assign rsta_outp_stage = RSTA & (~SLEEP); + + blk_mem_gen_v8_4_4_output_stage + #(.C_FAMILY (C_FAMILY), + .C_XDEVICEFAMILY (C_XDEVICEFAMILY), + .C_RST_TYPE ("SYNC"), + .C_HAS_RST (C_HAS_RSTA), + .C_RSTRAM (C_RSTRAM_A), + .C_RST_PRIORITY (C_RST_PRIORITY_A), + .C_INIT_VAL (C_INITA_VAL), + .C_HAS_EN (C_HAS_ENA), + .C_HAS_REGCE (C_HAS_REGCEA), + .C_DATA_WIDTH (C_READ_WIDTH_A), + .C_ADDRB_WIDTH (C_ADDRB_WIDTH), + .C_HAS_MEM_OUTPUT_REGS (C_HAS_MEM_OUTPUT_REGS_A), + .C_USE_SOFTECC (C_USE_SOFTECC), + .C_USE_ECC (C_USE_ECC), + .NUM_STAGES (NUM_OUTPUT_STAGES_A), + .C_EN_ECC_PIPE (0), + .FLOP_DELAY (FLOP_DELAY)) + reg_a + (.CLK (CLKA), + .RST (rsta_outp_stage),//(RSTA), + .EN (ENA), + .REGCE (REGCEA), + .DIN_I (memory_out_a), + .DOUT (DOUTA), + .SBITERR_IN_I (1'b0), + .DBITERR_IN_I (1'b0), + .SBITERR (), + .DBITERR (), + .RDADDRECC_IN_I ({C_ADDRB_WIDTH{1'b0}}), + .ECCPIPECE (1'b0), + .RDADDRECC () + ); + + assign rstb_outp_stage = RSTB & (~SLEEP); + + // Port B + blk_mem_gen_v8_4_4_output_stage + #(.C_FAMILY (C_FAMILY), + .C_XDEVICEFAMILY (C_XDEVICEFAMILY), + .C_RST_TYPE ("SYNC"), + .C_HAS_RST (C_HAS_RSTB), + .C_RSTRAM (C_RSTRAM_B), + .C_RST_PRIORITY (C_RST_PRIORITY_B), + .C_INIT_VAL (C_INITB_VAL), + .C_HAS_EN (C_HAS_ENB), + .C_HAS_REGCE (C_HAS_REGCEB), + .C_DATA_WIDTH (C_READ_WIDTH_B), + .C_ADDRB_WIDTH (C_ADDRB_WIDTH), + .C_HAS_MEM_OUTPUT_REGS (C_HAS_MEM_OUTPUT_REGS_B), + .C_USE_SOFTECC (C_USE_SOFTECC), + .C_USE_ECC (C_USE_ECC), + .NUM_STAGES (NUM_OUTPUT_STAGES_B), + .C_EN_ECC_PIPE (C_EN_ECC_PIPE), + .FLOP_DELAY (FLOP_DELAY)) + reg_b + (.CLK (CLKB), + .RST (rstb_outp_stage),//(RSTB), + .EN (ENB), + .REGCE (REGCEB), + .DIN_I (memory_out_b), + .DOUT (dout_i), + .SBITERR_IN_I (sbiterr_in), + .DBITERR_IN_I (dbiterr_in), + .SBITERR (sbiterr_i), + .DBITERR (dbiterr_i), + .RDADDRECC_IN_I (rdaddrecc_in), + .ECCPIPECE (ECCPIPECE), + .RDADDRECC (rdaddrecc_i) + ); + + //*************************************************************** + // Instantiate the Input and Output register stages + //*************************************************************** +blk_mem_gen_v8_4_4_softecc_output_reg_stage + #(.C_DATA_WIDTH (C_READ_WIDTH_B), + .C_ADDRB_WIDTH (C_ADDRB_WIDTH), + .C_HAS_SOFTECC_OUTPUT_REGS_B (C_HAS_SOFTECC_OUTPUT_REGS_B), + .C_USE_SOFTECC (C_USE_SOFTECC), + .FLOP_DELAY (FLOP_DELAY)) + has_softecc_output_reg_stage + (.CLK (CLKB), + .DIN (dout_i), + .DOUT (DOUTB), + .SBITERR_IN (sbiterr_i), + .DBITERR_IN (dbiterr_i), + .SBITERR (sbiterr_sdp), + .DBITERR (dbiterr_sdp), + .RDADDRECC_IN (rdaddrecc_i), + .RDADDRECC (rdaddrecc_sdp) +); + + //**************************************************** + // Synchronous collision checks + //**************************************************** +// CR 780544 : To make verilog model's collison warnings in consistant with +// vhdl model, the non-blocking assignments are replaced with blocking +// assignments. + generate if (!C_DISABLE_WARN_BHV_COLL && C_COMMON_CLK) begin : sync_coll + always @(posedge CLKA) begin + // Possible collision if both are enabled and the addresses match + if (ena_i && enb_i) begin + if (wea_i || web_i) begin + is_collision = collision_check(ADDRA, wea_i, ADDRB, web_i); + end else begin + is_collision = 0; + end + end else begin + is_collision = 0; + end + + // If the write port is in READ_FIRST mode, there is no collision + if (C_WRITE_MODE_A=="READ_FIRST" && wea_i && !web_i) begin + is_collision = 0; + end + if (C_WRITE_MODE_B=="READ_FIRST" && web_i && !wea_i) begin + is_collision = 0; + end + + // Only flag if one of the accesses is a write + if (is_collision && (wea_i || web_i)) begin + $fwrite(COLLFILE, "%0s collision detected at time: %0d, ", + C_CORENAME, $time); + $fwrite(COLLFILE, "Instance: %m, A %0s address: %0h, B %0s address: %0h\n", + wea_i ? "write" : "read", ADDRA, + web_i ? "write" : "read", ADDRB); + end + end + + //**************************************************** + // Asynchronous collision checks + //**************************************************** + end else if (!C_DISABLE_WARN_BHV_COLL && !C_COMMON_CLK) begin : async_coll + + // Delay A and B addresses in order to mimic setup/hold times + wire [C_ADDRA_WIDTH-1:0] #COLL_DELAY addra_delay = ADDRA; + wire [0:0] #COLL_DELAY wea_delay = wea_i; + wire #COLL_DELAY ena_delay = ena_i; + wire [C_ADDRB_WIDTH-1:0] #COLL_DELAY addrb_delay = ADDRB; + wire [0:0] #COLL_DELAY web_delay = web_i; + wire #COLL_DELAY enb_delay = enb_i; + + // Do the checks w/rt A + always @(posedge CLKA) begin + // Possible collision if both are enabled and the addresses match + if (ena_i && enb_i) begin + if (wea_i || web_i) begin + is_collision_a = collision_check(ADDRA, wea_i, ADDRB, web_i); + end else begin + is_collision_a = 0; + end + end else begin + is_collision_a = 0; + end + + if (ena_i && enb_delay) begin + if(wea_i || web_delay) begin + is_collision_delay_a = collision_check(ADDRA, wea_i, addrb_delay, + web_delay); + end else begin + is_collision_delay_a = 0; + end + end else begin + is_collision_delay_a = 0; + end + + // Only flag if B access is a write + if (is_collision_a && web_i) begin + $fwrite(COLLFILE, "%0s collision detected at time: %0d, ", + C_CORENAME, $time); + $fwrite(COLLFILE, "Instance: %m, A %0s address: %0h, B write address: %0h\n", + wea_i ? "write" : "read", ADDRA, ADDRB); + + end else if (is_collision_delay_a && web_delay) begin + $fwrite(COLLFILE, "%0s collision detected at time: %0d, ", + C_CORENAME, $time); + $fwrite(COLLFILE, "Instance: %m, A %0s address: %0h, B write address: %0h\n", + wea_i ? "write" : "read", ADDRA, addrb_delay); + end + + end + + // Do the checks w/rt B + always @(posedge CLKB) begin + + // Possible collision if both are enabled and the addresses match + if (ena_i && enb_i) begin + if (wea_i || web_i) begin + is_collision_b = collision_check(ADDRA, wea_i, ADDRB, web_i); + end else begin + is_collision_b = 0; + end + end else begin + is_collision_b = 0; + end + + if (ena_delay && enb_i) begin + if (wea_delay || web_i) begin + is_collision_delay_b = collision_check(addra_delay, wea_delay, ADDRB, + web_i); + end else begin + is_collision_delay_b = 0; + end + end else begin + is_collision_delay_b = 0; + end + + + // Only flag if A access is a write + if (is_collision_b && wea_i) begin + $fwrite(COLLFILE, "%0s collision detected at time: %0d, ", + C_CORENAME, $time); + $fwrite(COLLFILE, "Instance: %m, A write address: %0h, B %s address: %0h\n", + ADDRA, web_i ? "write" : "read", ADDRB); + + end else if (is_collision_delay_b && wea_delay) begin + $fwrite(COLLFILE, "%0s collision detected at time: %0d, ", + C_CORENAME, $time); + $fwrite(COLLFILE, "Instance: %m, A write address: %0h, B %s address: %0h\n", + addra_delay, web_i ? "write" : "read", ADDRB); + end + + end + end + endgenerate + +endmodule +//***************************************************************************** +// Top module wraps Input register and Memory module +// +// This module is the top-level behavioral model and this implements the memory +// module and the input registers +//***************************************************************************** +module blk_mem_gen_v8_4_4 + #(parameter C_CORENAME = "blk_mem_gen_v8_4_4", + parameter C_FAMILY = "virtex7", + parameter C_XDEVICEFAMILY = "virtex7", + parameter C_ELABORATION_DIR = "", + parameter C_INTERFACE_TYPE = 0, + parameter C_USE_BRAM_BLOCK = 0, + parameter C_CTRL_ECC_ALGO = "NONE", + parameter C_ENABLE_32BIT_ADDRESS = 0, + parameter C_AXI_TYPE = 0, + parameter C_AXI_SLAVE_TYPE = 0, + parameter C_HAS_AXI_ID = 0, + parameter C_AXI_ID_WIDTH = 4, + parameter C_MEM_TYPE = 2, + parameter C_BYTE_SIZE = 9, + parameter C_ALGORITHM = 1, + parameter C_PRIM_TYPE = 3, + parameter C_LOAD_INIT_FILE = 0, + parameter C_INIT_FILE_NAME = "", + parameter C_INIT_FILE = "", + parameter C_USE_DEFAULT_DATA = 0, + parameter C_DEFAULT_DATA = "0", + //parameter C_RST_TYPE = "SYNC", + parameter C_HAS_RSTA = 0, + parameter C_RST_PRIORITY_A = "CE", + parameter C_RSTRAM_A = 0, + parameter C_INITA_VAL = "0", + parameter C_HAS_ENA = 1, + parameter C_HAS_REGCEA = 0, + parameter C_USE_BYTE_WEA = 0, + parameter C_WEA_WIDTH = 1, + parameter C_WRITE_MODE_A = "WRITE_FIRST", + parameter C_WRITE_WIDTH_A = 32, + parameter C_READ_WIDTH_A = 32, + parameter C_WRITE_DEPTH_A = 64, + parameter C_READ_DEPTH_A = 64, + parameter C_ADDRA_WIDTH = 5, + parameter C_HAS_RSTB = 0, + parameter C_RST_PRIORITY_B = "CE", + parameter C_RSTRAM_B = 0, + parameter C_INITB_VAL = "", + parameter C_HAS_ENB = 1, + parameter C_HAS_REGCEB = 0, + parameter C_USE_BYTE_WEB = 0, + parameter C_WEB_WIDTH = 1, + parameter C_WRITE_MODE_B = "WRITE_FIRST", + parameter C_WRITE_WIDTH_B = 32, + parameter C_READ_WIDTH_B = 32, + parameter C_WRITE_DEPTH_B = 64, + parameter C_READ_DEPTH_B = 64, + parameter C_ADDRB_WIDTH = 5, + parameter C_HAS_MEM_OUTPUT_REGS_A = 0, + parameter C_HAS_MEM_OUTPUT_REGS_B = 0, + parameter C_HAS_MUX_OUTPUT_REGS_A = 0, + parameter C_HAS_MUX_OUTPUT_REGS_B = 0, + parameter C_HAS_SOFTECC_INPUT_REGS_A = 0, + parameter C_HAS_SOFTECC_OUTPUT_REGS_B= 0, + parameter C_MUX_PIPELINE_STAGES = 0, + parameter C_USE_SOFTECC = 0, + parameter C_READ_LATENCY_A = 1, + parameter C_READ_LATENCY_B = 1, + parameter C_USE_ECC = 0, + parameter C_EN_ECC_PIPE = 0, + parameter C_HAS_INJECTERR = 0, + parameter C_SIM_COLLISION_CHECK = "NONE", + parameter C_COMMON_CLK = 1, + parameter C_DISABLE_WARN_BHV_COLL = 0, + parameter C_EN_SLEEP_PIN = 0, + parameter C_USE_URAM = 0, + parameter C_EN_RDADDRA_CHG = 0, + parameter C_EN_RDADDRB_CHG = 0, + parameter C_EN_DEEPSLEEP_PIN = 0, + parameter C_EN_SHUTDOWN_PIN = 0, + parameter C_EN_SAFETY_CKT = 0, + parameter C_COUNT_36K_BRAM = "", + parameter C_COUNT_18K_BRAM = "", + parameter C_EST_POWER_SUMMARY = "", + parameter C_DISABLE_WARN_BHV_RANGE = 0 + + ) + (input clka, + input rsta, + input ena, + input regcea, + input [C_WEA_WIDTH-1:0] wea, + input [C_ADDRA_WIDTH-1:0] addra, + input [C_WRITE_WIDTH_A-1:0] dina, + output [C_READ_WIDTH_A-1:0] douta, + input clkb, + input rstb, + input enb, + input regceb, + input [C_WEB_WIDTH-1:0] web, + input [C_ADDRB_WIDTH-1:0] addrb, + input [C_WRITE_WIDTH_B-1:0] dinb, + output [C_READ_WIDTH_B-1:0] doutb, + input injectsbiterr, + input injectdbiterr, + output sbiterr, + output dbiterr, + output [C_ADDRB_WIDTH-1:0] rdaddrecc, + input eccpipece, + input sleep, + input deepsleep, + input shutdown, + output rsta_busy, + output rstb_busy, + //AXI BMG Input and Output Port Declarations + + //AXI Global Signals + input s_aclk, + input s_aresetn, + + //AXI Full/lite slave write (write side) + input [C_AXI_ID_WIDTH-1:0] s_axi_awid, + input [31:0] s_axi_awaddr, + input [7:0] s_axi_awlen, + input [2:0] s_axi_awsize, + input [1:0] s_axi_awburst, + input s_axi_awvalid, + output s_axi_awready, + input [C_WRITE_WIDTH_A-1:0] s_axi_wdata, + input [C_WEA_WIDTH-1:0] s_axi_wstrb, + input s_axi_wlast, + input s_axi_wvalid, + output s_axi_wready, + output [C_AXI_ID_WIDTH-1:0] s_axi_bid, + output [1:0] s_axi_bresp, + output s_axi_bvalid, + input s_axi_bready, + + //AXI Full/lite slave read (write side) + input [C_AXI_ID_WIDTH-1:0] s_axi_arid, + input [31:0] s_axi_araddr, + input [7:0] s_axi_arlen, + input [2:0] s_axi_arsize, + input [1:0] s_axi_arburst, + input s_axi_arvalid, + output s_axi_arready, + output [C_AXI_ID_WIDTH-1:0] s_axi_rid, + output [C_WRITE_WIDTH_B-1:0] s_axi_rdata, + output [1:0] s_axi_rresp, + output s_axi_rlast, + output s_axi_rvalid, + input s_axi_rready, + + //AXI Full/lite sideband signals + input s_axi_injectsbiterr, + input s_axi_injectdbiterr, + output s_axi_sbiterr, + output s_axi_dbiterr, + output [C_ADDRB_WIDTH-1:0] s_axi_rdaddrecc + + ); +//****************************** +// Port and Generic Definitions +//****************************** + ////////////////////////////////////////////////////////////////////////// + // Generic Definitions + ////////////////////////////////////////////////////////////////////////// + // C_CORENAME : Instance name of the Block Memory Generator core + // C_FAMILY,C_XDEVICEFAMILY: Designates architecture targeted. The following + // options are available - "spartan3", "spartan6", + // "virtex4", "virtex5", "virtex6" and "virtex6l". + // C_MEM_TYPE : Designates memory type. + // It can be + // 0 - Single Port Memory + // 1 - Simple Dual Port Memory + // 2 - True Dual Port Memory + // 3 - Single Port Read Only Memory + // 4 - Dual Port Read Only Memory + // C_BYTE_SIZE : Size of a byte (8 or 9 bits) + // C_ALGORITHM : Designates the algorithm method used + // for constructing the memory. + // It can be Fixed_Primitives, Minimum_Area or + // Low_Power + // C_PRIM_TYPE : Designates the user selected primitive used to + // construct the memory. + // + // C_LOAD_INIT_FILE : Designates the use of an initialization file to + // initialize memory contents. + // C_INIT_FILE_NAME : Memory initialization file name. + // C_USE_DEFAULT_DATA : Designates whether to fill remaining + // initialization space with default data + // C_DEFAULT_DATA : Default value of all memory locations + // not initialized by the memory + // initialization file. + // C_RST_TYPE : Type of reset - Synchronous or Asynchronous + // C_HAS_RSTA : Determines the presence of the RSTA port + // C_RST_PRIORITY_A : Determines the priority between CE and SR for + // Port A. + // C_RSTRAM_A : Determines if special reset behavior is used for + // Port A + // C_INITA_VAL : The initialization value for Port A + // C_HAS_ENA : Determines the presence of the ENA port + // C_HAS_REGCEA : Determines the presence of the REGCEA port + // C_USE_BYTE_WEA : Determines if the Byte Write is used or not. + // C_WEA_WIDTH : The width of the WEA port + // C_WRITE_MODE_A : Configurable write mode for Port A. It can be + // WRITE_FIRST, READ_FIRST or NO_CHANGE. + // C_WRITE_WIDTH_A : Memory write width for Port A. + // C_READ_WIDTH_A : Memory read width for Port A. + // C_WRITE_DEPTH_A : Memory write depth for Port A. + // C_READ_DEPTH_A : Memory read depth for Port A. + // C_ADDRA_WIDTH : Width of the ADDRA input port + // C_HAS_RSTB : Determines the presence of the RSTB port + // C_RST_PRIORITY_B : Determines the priority between CE and SR for + // Port B. + // C_RSTRAM_B : Determines if special reset behavior is used for + // Port B + // C_INITB_VAL : The initialization value for Port B + // C_HAS_ENB : Determines the presence of the ENB port + // C_HAS_REGCEB : Determines the presence of the REGCEB port + // C_USE_BYTE_WEB : Determines if the Byte Write is used or not. + // C_WEB_WIDTH : The width of the WEB port + // C_WRITE_MODE_B : Configurable write mode for Port B. It can be + // WRITE_FIRST, READ_FIRST or NO_CHANGE. + // C_WRITE_WIDTH_B : Memory write width for Port B. + // C_READ_WIDTH_B : Memory read width for Port B. + // C_WRITE_DEPTH_B : Memory write depth for Port B. + // C_READ_DEPTH_B : Memory read depth for Port B. + // C_ADDRB_WIDTH : Width of the ADDRB input port + // C_HAS_MEM_OUTPUT_REGS_A : Designates the use of a register at the output + // of the RAM primitive for Port A. + // C_HAS_MEM_OUTPUT_REGS_B : Designates the use of a register at the output + // of the RAM primitive for Port B. + // C_HAS_MUX_OUTPUT_REGS_A : Designates the use of a register at the output + // of the MUX for Port A. + // C_HAS_MUX_OUTPUT_REGS_B : Designates the use of a register at the output + // of the MUX for Port B. + // C_HAS_SOFTECC_INPUT_REGS_A : + // C_HAS_SOFTECC_OUTPUT_REGS_B : + // C_MUX_PIPELINE_STAGES : Designates the number of pipeline stages in + // between the muxes. + // C_USE_SOFTECC : Determines if the Soft ECC feature is used or + // not. Only applicable Spartan-6 + // C_USE_ECC : Determines if the ECC feature is used or + // not. Only applicable for V5 and V6 + // C_HAS_INJECTERR : Determines if the error injection pins + // are present or not. If the ECC feature + // is not used, this value is defaulted to + // 0, else the following are the allowed + // values: + // 0 : No INJECTSBITERR or INJECTDBITERR pins + // 1 : Only INJECTSBITERR pin exists + // 2 : Only INJECTDBITERR pin exists + // 3 : Both INJECTSBITERR and INJECTDBITERR pins exist + // C_SIM_COLLISION_CHECK : Controls the disabling of Unisim model collision + // warnings. It can be "ALL", "NONE", + // "Warnings_Only" or "Generate_X_Only". + // C_COMMON_CLK : Determins if the core has a single CLK input. + // C_DISABLE_WARN_BHV_COLL : Controls the Behavioral Model Collision warnings + // C_DISABLE_WARN_BHV_RANGE: Controls the Behavioral Model Out of Range + // warnings + ////////////////////////////////////////////////////////////////////////// + // Port Definitions + ////////////////////////////////////////////////////////////////////////// + // CLKA : Clock to synchronize all read and write operations of Port A. + // RSTA : Reset input to reset memory outputs to a user-defined + // reset state for Port A. + // ENA : Enable all read and write operations of Port A. + // REGCEA : Register Clock Enable to control each pipeline output + // register stages for Port A. + // WEA : Write Enable to enable all write operations of Port A. + // ADDRA : Address of Port A. + // DINA : Data input of Port A. + // DOUTA : Data output of Port A. + // CLKB : Clock to synchronize all read and write operations of Port B. + // RSTB : Reset input to reset memory outputs to a user-defined + // reset state for Port B. + // ENB : Enable all read and write operations of Port B. + // REGCEB : Register Clock Enable to control each pipeline output + // register stages for Port B. + // WEB : Write Enable to enable all write operations of Port B. + // ADDRB : Address of Port B. + // DINB : Data input of Port B. + // DOUTB : Data output of Port B. + // INJECTSBITERR : Single Bit ECC Error Injection Pin. + // INJECTDBITERR : Double Bit ECC Error Injection Pin. + // SBITERR : Output signal indicating that a Single Bit ECC Error has been + // detected and corrected. + // DBITERR : Output signal indicating that a Double Bit ECC Error has been + // detected. + // RDADDRECC : Read Address Output signal indicating address at which an + // ECC error has occurred. + ////////////////////////////////////////////////////////////////////////// + + wire SBITERR; + wire DBITERR; + wire S_AXI_AWREADY; + wire S_AXI_WREADY; + wire S_AXI_BVALID; + wire S_AXI_ARREADY; + wire S_AXI_RLAST; + wire S_AXI_RVALID; + wire S_AXI_SBITERR; + wire S_AXI_DBITERR; + + wire [C_WEA_WIDTH-1:0] WEA = wea; + wire [C_ADDRA_WIDTH-1:0] ADDRA = addra; + wire [C_WRITE_WIDTH_A-1:0] DINA = dina; + wire [C_READ_WIDTH_A-1:0] DOUTA; + wire [C_WEB_WIDTH-1:0] WEB = web; + wire [C_ADDRB_WIDTH-1:0] ADDRB = addrb; + wire [C_WRITE_WIDTH_B-1:0] DINB = dinb; + wire [C_READ_WIDTH_B-1:0] DOUTB; + wire [C_ADDRB_WIDTH-1:0] RDADDRECC; + wire [C_AXI_ID_WIDTH-1:0] S_AXI_AWID = s_axi_awid; + wire [31:0] S_AXI_AWADDR = s_axi_awaddr; + wire [7:0] S_AXI_AWLEN = s_axi_awlen; + wire [2:0] S_AXI_AWSIZE = s_axi_awsize; + wire [1:0] S_AXI_AWBURST = s_axi_awburst; + wire [C_WRITE_WIDTH_A-1:0] S_AXI_WDATA = s_axi_wdata; + wire [C_WEA_WIDTH-1:0] S_AXI_WSTRB = s_axi_wstrb; + wire [C_AXI_ID_WIDTH-1:0] S_AXI_BID; + wire [1:0] S_AXI_BRESP; + wire [C_AXI_ID_WIDTH-1:0] S_AXI_ARID = s_axi_arid; + wire [31:0] S_AXI_ARADDR = s_axi_araddr; + wire [7:0] S_AXI_ARLEN = s_axi_arlen; + wire [2:0] S_AXI_ARSIZE = s_axi_arsize; + wire [1:0] S_AXI_ARBURST = s_axi_arburst; + wire [C_AXI_ID_WIDTH-1:0] S_AXI_RID; + wire [C_WRITE_WIDTH_B-1:0] S_AXI_RDATA; + wire [1:0] S_AXI_RRESP; + wire [C_ADDRB_WIDTH-1:0] S_AXI_RDADDRECC; + // Added to fix the simulation warning #CR731605 + wire [C_WEB_WIDTH-1:0] WEB_parameterized = 0; + wire ECCPIPECE; + wire SLEEP; + reg RSTA_BUSY = 0; + reg RSTB_BUSY = 0; + // Declaration of internal signals to avoid warnings #927399 + wire CLKA; + wire RSTA; + wire ENA; + wire REGCEA; + wire CLKB; + wire RSTB; + wire ENB; + wire REGCEB; + wire INJECTSBITERR; + wire INJECTDBITERR; + wire S_ACLK; + wire S_ARESETN; + wire S_AXI_AWVALID; + wire S_AXI_WLAST; + wire S_AXI_WVALID; + wire S_AXI_BREADY; + wire S_AXI_ARVALID; + wire S_AXI_RREADY; + wire S_AXI_INJECTSBITERR; + wire S_AXI_INJECTDBITERR; + + assign CLKA = clka; + assign RSTA = rsta; + assign ENA = ena; + assign REGCEA = regcea; + assign CLKB = clkb; + assign RSTB = rstb; + assign ENB = enb; + assign REGCEB = regceb; + assign INJECTSBITERR = injectsbiterr; + assign INJECTDBITERR = injectdbiterr; + assign ECCPIPECE = eccpipece; + assign SLEEP = sleep; + assign sbiterr = SBITERR; + assign dbiterr = DBITERR; + assign S_ACLK = s_aclk; + assign S_ARESETN = s_aresetn; + 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 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 S_AXI_INJECTSBITERR = s_axi_injectsbiterr; + assign S_AXI_INJECTDBITERR = s_axi_injectdbiterr; + assign s_axi_sbiterr = S_AXI_SBITERR; + assign s_axi_dbiterr = S_AXI_DBITERR; + + assign rsta_busy = RSTA_BUSY; + assign rstb_busy = RSTB_BUSY; + + assign doutb = DOUTB; + assign douta = DOUTA; + assign rdaddrecc = RDADDRECC; + assign s_axi_bid = S_AXI_BID; + assign s_axi_bresp = S_AXI_BRESP; + assign s_axi_rid = S_AXI_RID; + assign s_axi_rdata = S_AXI_RDATA; + assign s_axi_rresp = S_AXI_RRESP; + assign s_axi_rdaddrecc = S_AXI_RDADDRECC; + + localparam FLOP_DELAY = 100; // 100 ps + + reg injectsbiterr_in; + reg injectdbiterr_in; + reg rsta_in; + reg ena_in; + reg regcea_in; + reg [C_WEA_WIDTH-1:0] wea_in; + reg [C_ADDRA_WIDTH-1:0] addra_in; + reg [C_WRITE_WIDTH_A-1:0] dina_in; + + wire [C_ADDRA_WIDTH-1:0] s_axi_awaddr_out_c; + wire [C_ADDRB_WIDTH-1:0] s_axi_araddr_out_c; + wire s_axi_wr_en_c; + wire s_axi_rd_en_c; + wire s_aresetn_a_c; + wire [7:0] s_axi_arlen_c ; + + + wire [C_AXI_ID_WIDTH-1 : 0] s_axi_rid_c; + wire [C_WRITE_WIDTH_B-1 : 0] s_axi_rdata_c; + wire [1:0] s_axi_rresp_c; + wire s_axi_rlast_c; + wire s_axi_rvalid_c; + wire s_axi_rready_c; + wire regceb_c; + + localparam C_AXI_PAYLOAD = (C_HAS_MUX_OUTPUT_REGS_B == 1)?C_WRITE_WIDTH_B+C_AXI_ID_WIDTH+3:C_AXI_ID_WIDTH+3; + wire [C_AXI_PAYLOAD-1 : 0] s_axi_payload_c; + wire [C_AXI_PAYLOAD-1 : 0] m_axi_payload_c; + +// Safety logic related signals + + reg [4:0] RSTA_SHFT_REG = 0; + reg POR_A = 0; + reg [4:0] RSTB_SHFT_REG = 0; + reg POR_B = 0; + + reg ENA_dly = 0; + reg ENA_dly_D = 0; + + reg ENB_dly = 0; + reg ENB_dly_D = 0; + + wire RSTA_I_SAFE; + wire RSTB_I_SAFE; + + wire ENA_I_SAFE; + wire ENB_I_SAFE; + + reg ram_rstram_a_busy = 0; + reg ram_rstreg_a_busy = 0; + reg ram_rstram_b_busy = 0; + reg ram_rstreg_b_busy = 0; + + reg ENA_dly_reg = 0; + reg ENB_dly_reg = 0; + + reg ENA_dly_reg_D = 0; + reg ENB_dly_reg_D = 0; + + //************** + // log2roundup + //************** + function integer log2roundup (input integer data_value); + integer width; + integer cnt; + begin + width = 0; + + if (data_value > 1) begin + for(cnt=1 ; cnt < data_value ; cnt = cnt * 2) begin + width = width + 1; + end //loop + end //if + + log2roundup = width; + + end //log2roundup + endfunction + + //************** + // log2int + //************** + function integer log2int (input integer data_value); + integer width; + integer cnt; + begin + width = 0; + cnt= data_value; + + for(cnt=data_value ; cnt >1 ; cnt = cnt / 2) begin + width = width + 1; + end //loop + + log2int = width; + + end //log2int + endfunction + + //************************************************************************** + // FUNCTION : divroundup + // Returns the ceiling value of the division + // Data_value - the quantity to be divided, dividend + // Divisor - the value to divide the data_value by + //************************************************************************** + function integer divroundup (input integer data_value,input integer divisor); + integer div; + begin + div = data_value/divisor; + if ((data_value % divisor) != 0) begin + div = div+1; + end //if + divroundup = div; + end //if + endfunction + + localparam AXI_FULL_MEMORY_SLAVE = ((C_AXI_SLAVE_TYPE == 0 && C_AXI_TYPE == 1)?1:0); + localparam C_AXI_ADDR_WIDTH_MSB = C_ADDRA_WIDTH+log2roundup(C_WRITE_WIDTH_A/8); + localparam C_AXI_ADDR_WIDTH = C_AXI_ADDR_WIDTH_MSB; + + //Data Width Number of LSB address bits to be discarded + //1 to 16 1 + //17 to 32 2 + //33 to 64 3 + //65 to 128 4 + //129 to 256 5 + //257 to 512 6 + //513 to 1024 7 + // The following two constants determine this. + + localparam LOWER_BOUND_VAL = (log2roundup(divroundup(C_WRITE_WIDTH_A,8) == 0))?0:(log2roundup(divroundup(C_WRITE_WIDTH_A,8))); + localparam C_AXI_ADDR_WIDTH_LSB = ((AXI_FULL_MEMORY_SLAVE == 1)?0:LOWER_BOUND_VAL); + localparam C_AXI_OS_WR = 2; + + //*********************************************** + // INPUT REGISTERS. + //*********************************************** + generate if (C_HAS_SOFTECC_INPUT_REGS_A==0) begin : no_softecc_input_reg_stage + always @* begin + injectsbiterr_in = INJECTSBITERR; + injectdbiterr_in = INJECTDBITERR; + rsta_in = RSTA; + ena_in = ENA; + regcea_in = REGCEA; + wea_in = WEA; + addra_in = ADDRA; + dina_in = DINA; + end //end always + end //end no_softecc_input_reg_stage + endgenerate + + generate if (C_HAS_SOFTECC_INPUT_REGS_A==1) begin : has_softecc_input_reg_stage + always @(posedge CLKA) begin + injectsbiterr_in <= #FLOP_DELAY INJECTSBITERR; + injectdbiterr_in <= #FLOP_DELAY INJECTDBITERR; + rsta_in <= #FLOP_DELAY RSTA; + ena_in <= #FLOP_DELAY ENA; + regcea_in <= #FLOP_DELAY REGCEA; + wea_in <= #FLOP_DELAY WEA; + addra_in <= #FLOP_DELAY ADDRA; + dina_in <= #FLOP_DELAY DINA; + end //end always + end //end input_reg_stages generate statement + endgenerate + + //************************************************************************** + // NO SAFETY LOGIC + //************************************************************************** + + generate + if (C_EN_SAFETY_CKT == 0) begin : NO_SAFETY_CKT_GEN + assign ENA_I_SAFE = ena_in; + assign ENB_I_SAFE = ENB; + assign RSTA_I_SAFE = rsta_in; + assign RSTB_I_SAFE = RSTB; + end + endgenerate + + //*************************************************************************** + // SAFETY LOGIC + // Power-ON Reset Generation + //*************************************************************************** + generate + if (C_EN_SAFETY_CKT == 1) begin + always @(posedge clka) RSTA_SHFT_REG <= #FLOP_DELAY {RSTA_SHFT_REG[3:0],1'b1} ; + always @(posedge clka) POR_A <= #FLOP_DELAY RSTA_SHFT_REG[4] ^ RSTA_SHFT_REG[0]; + always @(posedge clkb) RSTB_SHFT_REG <= #FLOP_DELAY {RSTB_SHFT_REG[3:0],1'b1} ; + always @(posedge clkb) POR_B <= #FLOP_DELAY RSTB_SHFT_REG[4] ^ RSTB_SHFT_REG[0]; + + assign RSTA_I_SAFE = rsta_in | POR_A; + assign RSTB_I_SAFE = (C_MEM_TYPE == 0 || C_MEM_TYPE == 3) ? 1'b0 : (RSTB | POR_B); + end + endgenerate + + //----------------------------------------------------------------------------- + // -- RSTA/B_BUSY Generation + //----------------------------------------------------------------------------- + + generate + if ((C_HAS_MEM_OUTPUT_REGS_A==0 || (C_HAS_MEM_OUTPUT_REGS_A==1 && C_RSTRAM_A==1)) && (C_EN_SAFETY_CKT == 1)) begin : RSTA_BUSY_NO_REG + always @(*) ram_rstram_a_busy = RSTA_I_SAFE | ENA_dly | ENA_dly_D; + always @(posedge clka) RSTA_BUSY <= #FLOP_DELAY ram_rstram_a_busy; + end + endgenerate + + generate + if (C_HAS_MEM_OUTPUT_REGS_A==1 && C_RSTRAM_A==0 && C_EN_SAFETY_CKT == 1) begin : RSTA_BUSY_WITH_REG + always @(*) ram_rstreg_a_busy = RSTA_I_SAFE | ENA_dly_reg | ENA_dly_reg_D; + always @(posedge clka) RSTA_BUSY <= #FLOP_DELAY ram_rstreg_a_busy; + end + endgenerate + + generate + if ( (C_MEM_TYPE == 0 || C_MEM_TYPE == 3) && C_EN_SAFETY_CKT == 1) begin : SPRAM_RST_BUSY + always @(*) RSTB_BUSY = 1'b0; + end + endgenerate + + generate + if ( (C_HAS_MEM_OUTPUT_REGS_B==0 || (C_HAS_MEM_OUTPUT_REGS_B==1 && C_RSTRAM_B==1)) && (C_MEM_TYPE != 0 && C_MEM_TYPE != 3) && C_EN_SAFETY_CKT == 1) begin : RSTB_BUSY_NO_REG + always @(*) ram_rstram_b_busy = RSTB_I_SAFE | ENB_dly | ENB_dly_D; + always @(posedge clkb) RSTB_BUSY <= #FLOP_DELAY ram_rstram_b_busy; + end + endgenerate + + generate + if (C_HAS_MEM_OUTPUT_REGS_B==1 && C_RSTRAM_B==0 && C_MEM_TYPE != 0 && C_MEM_TYPE != 3 && C_EN_SAFETY_CKT == 1) begin : RSTB_BUSY_WITH_REG + always @(*) ram_rstreg_b_busy = RSTB_I_SAFE | ENB_dly_reg | ENB_dly_reg_D; + always @(posedge clkb) RSTB_BUSY <= #FLOP_DELAY ram_rstreg_b_busy; + end + endgenerate + + //----------------------------------------------------------------------------- + // -- ENA/ENB Generation + //----------------------------------------------------------------------------- + + generate + if ((C_HAS_MEM_OUTPUT_REGS_A==0 || (C_HAS_MEM_OUTPUT_REGS_A==1 && C_RSTRAM_A==1)) && C_EN_SAFETY_CKT == 1) begin : ENA_NO_REG + always @(posedge clka) begin + ENA_dly <= #FLOP_DELAY RSTA_I_SAFE; + ENA_dly_D <= #FLOP_DELAY ENA_dly; + end + assign ENA_I_SAFE = (C_HAS_ENA == 0)? 1'b1 : (ENA_dly_D | ena_in); + end + endgenerate + + generate + if ( (C_HAS_MEM_OUTPUT_REGS_A==1 && C_RSTRAM_A==0) && C_EN_SAFETY_CKT == 1) begin : ENA_WITH_REG + always @(posedge clka) begin + ENA_dly_reg <= #FLOP_DELAY RSTA_I_SAFE; + ENA_dly_reg_D <= #FLOP_DELAY ENA_dly_reg; + end + assign ENA_I_SAFE = (C_HAS_ENA == 0)? 1'b1 : (ENA_dly_reg_D | ena_in); + end + endgenerate + + generate + if (C_MEM_TYPE == 0 || C_MEM_TYPE == 3) begin : SPRAM_ENB + assign ENB_I_SAFE = 1'b0; + end + endgenerate + + generate + if ((C_HAS_MEM_OUTPUT_REGS_B==0 || (C_HAS_MEM_OUTPUT_REGS_B==1 && C_RSTRAM_B==1)) && C_MEM_TYPE != 0 && C_MEM_TYPE != 3 && C_EN_SAFETY_CKT == 1) begin : ENB_NO_REG + always @(posedge clkb) begin : PROC_ENB_GEN + ENB_dly <= #FLOP_DELAY RSTB_I_SAFE; + ENB_dly_D <= #FLOP_DELAY ENB_dly; + end + assign ENB_I_SAFE = (C_HAS_ENB == 0)? 1'b1 : (ENB_dly_D | ENB); + end + endgenerate + + generate + if (C_HAS_MEM_OUTPUT_REGS_B==1 && C_RSTRAM_B==0 && C_MEM_TYPE != 0 && C_MEM_TYPE != 3 && C_EN_SAFETY_CKT == 1)begin : ENB_WITH_REG + always @(posedge clkb) begin : PROC_ENB_GEN + ENB_dly_reg <= #FLOP_DELAY RSTB_I_SAFE; + ENB_dly_reg_D <= #FLOP_DELAY ENB_dly_reg; + end + assign ENB_I_SAFE = (C_HAS_ENB == 0)? 1'b1 : (ENB_dly_reg_D | ENB); + end + endgenerate + + generate if ((C_INTERFACE_TYPE == 0) && (C_ENABLE_32BIT_ADDRESS == 0)) begin : native_mem_module +blk_mem_gen_v8_4_4_mem_module + #(.C_CORENAME (C_CORENAME), + .C_FAMILY (C_FAMILY), + .C_XDEVICEFAMILY (C_XDEVICEFAMILY), + .C_MEM_TYPE (C_MEM_TYPE), + .C_BYTE_SIZE (C_BYTE_SIZE), + .C_ALGORITHM (C_ALGORITHM), + .C_USE_BRAM_BLOCK (C_USE_BRAM_BLOCK), + .C_PRIM_TYPE (C_PRIM_TYPE), + .C_LOAD_INIT_FILE (C_LOAD_INIT_FILE), + .C_INIT_FILE_NAME (C_INIT_FILE_NAME), + .C_INIT_FILE (C_INIT_FILE), + .C_USE_DEFAULT_DATA (C_USE_DEFAULT_DATA), + .C_DEFAULT_DATA (C_DEFAULT_DATA), + .C_RST_TYPE ("SYNC"), + .C_HAS_RSTA (C_HAS_RSTA), + .C_RST_PRIORITY_A (C_RST_PRIORITY_A), + .C_RSTRAM_A (C_RSTRAM_A), + .C_INITA_VAL (C_INITA_VAL), + .C_HAS_ENA (C_HAS_ENA), + .C_HAS_REGCEA (C_HAS_REGCEA), + .C_USE_BYTE_WEA (C_USE_BYTE_WEA), + .C_WEA_WIDTH (C_WEA_WIDTH), + .C_WRITE_MODE_A (C_WRITE_MODE_A), + .C_WRITE_WIDTH_A (C_WRITE_WIDTH_A), + .C_READ_WIDTH_A (C_READ_WIDTH_A), + .C_WRITE_DEPTH_A (C_WRITE_DEPTH_A), + .C_READ_DEPTH_A (C_READ_DEPTH_A), + .C_ADDRA_WIDTH (C_ADDRA_WIDTH), + .C_HAS_RSTB (C_HAS_RSTB), + .C_RST_PRIORITY_B (C_RST_PRIORITY_B), + .C_RSTRAM_B (C_RSTRAM_B), + .C_INITB_VAL (C_INITB_VAL), + .C_HAS_ENB (C_HAS_ENB), + .C_HAS_REGCEB (C_HAS_REGCEB), + .C_USE_BYTE_WEB (C_USE_BYTE_WEB), + .C_WEB_WIDTH (C_WEB_WIDTH), + .C_WRITE_MODE_B (C_WRITE_MODE_B), + .C_WRITE_WIDTH_B (C_WRITE_WIDTH_B), + .C_READ_WIDTH_B (C_READ_WIDTH_B), + .C_WRITE_DEPTH_B (C_WRITE_DEPTH_B), + .C_READ_DEPTH_B (C_READ_DEPTH_B), + .C_ADDRB_WIDTH (C_ADDRB_WIDTH), + .C_HAS_MEM_OUTPUT_REGS_A (C_HAS_MEM_OUTPUT_REGS_A), + .C_HAS_MEM_OUTPUT_REGS_B (C_HAS_MEM_OUTPUT_REGS_B), + .C_HAS_MUX_OUTPUT_REGS_A (C_HAS_MUX_OUTPUT_REGS_A), + .C_HAS_MUX_OUTPUT_REGS_B (C_HAS_MUX_OUTPUT_REGS_B), + .C_HAS_SOFTECC_INPUT_REGS_A (C_HAS_SOFTECC_INPUT_REGS_A), + .C_HAS_SOFTECC_OUTPUT_REGS_B (C_HAS_SOFTECC_OUTPUT_REGS_B), + .C_MUX_PIPELINE_STAGES (C_MUX_PIPELINE_STAGES), + .C_USE_SOFTECC (C_USE_SOFTECC), + .C_USE_ECC (C_USE_ECC), + .C_HAS_INJECTERR (C_HAS_INJECTERR), + .C_SIM_COLLISION_CHECK (C_SIM_COLLISION_CHECK), + .C_COMMON_CLK (C_COMMON_CLK), + .FLOP_DELAY (FLOP_DELAY), + .C_DISABLE_WARN_BHV_COLL (C_DISABLE_WARN_BHV_COLL), + .C_EN_ECC_PIPE (C_EN_ECC_PIPE), + .C_DISABLE_WARN_BHV_RANGE (C_DISABLE_WARN_BHV_RANGE)) + blk_mem_gen_v8_4_4_inst + (.CLKA (CLKA), + .RSTA (RSTA_I_SAFE),//(rsta_in), + .ENA (ENA_I_SAFE),//(ena_in), + .REGCEA (regcea_in), + .WEA (wea_in), + .ADDRA (addra_in), + .DINA (dina_in), + .DOUTA (DOUTA), + .CLKB (CLKB), + .RSTB (RSTB_I_SAFE),//(RSTB), + .ENB (ENB_I_SAFE),//(ENB), + .REGCEB (REGCEB), + .WEB (WEB), + .ADDRB (ADDRB), + .DINB (DINB), + .DOUTB (DOUTB), + .INJECTSBITERR (injectsbiterr_in), + .INJECTDBITERR (injectdbiterr_in), + .ECCPIPECE (ECCPIPECE), + .SLEEP (SLEEP), + .SBITERR (SBITERR), + .DBITERR (DBITERR), + .RDADDRECC (RDADDRECC) + ); + end + endgenerate + + generate if((C_INTERFACE_TYPE == 0) && (C_ENABLE_32BIT_ADDRESS == 1)) begin : native_mem_mapped_module + + localparam C_ADDRA_WIDTH_ACTUAL = log2roundup(C_WRITE_DEPTH_A); + localparam C_ADDRB_WIDTH_ACTUAL = log2roundup(C_WRITE_DEPTH_B); + + localparam C_ADDRA_WIDTH_MSB = C_ADDRA_WIDTH_ACTUAL+log2int(C_WRITE_WIDTH_A/8); + localparam C_ADDRB_WIDTH_MSB = C_ADDRB_WIDTH_ACTUAL+log2int(C_WRITE_WIDTH_B/8); + // localparam C_ADDRA_WIDTH_MSB = C_ADDRA_WIDTH_ACTUAL+log2roundup(C_WRITE_WIDTH_A/8); + // localparam C_ADDRB_WIDTH_MSB = C_ADDRB_WIDTH_ACTUAL+log2roundup(C_WRITE_WIDTH_B/8); + localparam C_MEM_MAP_ADDRA_WIDTH_MSB = C_ADDRA_WIDTH_MSB; + localparam C_MEM_MAP_ADDRB_WIDTH_MSB = C_ADDRB_WIDTH_MSB; + + // Data Width Number of LSB address bits to be discarded + // 1 to 16 1 + // 17 to 32 2 + // 33 to 64 3 + // 65 to 128 4 + // 129 to 256 5 + // 257 to 512 6 + // 513 to 1024 7 + // The following two constants determine this. + + localparam MEM_MAP_LOWER_BOUND_VAL_A = (log2int(divroundup(C_WRITE_WIDTH_A,8)==0)) ? 0:(log2int(divroundup(C_WRITE_WIDTH_A,8))); + localparam MEM_MAP_LOWER_BOUND_VAL_B = (log2int(divroundup(C_WRITE_WIDTH_B,8)==0)) ? 0:(log2int(divroundup(C_WRITE_WIDTH_B,8))); + localparam C_MEM_MAP_ADDRA_WIDTH_LSB = MEM_MAP_LOWER_BOUND_VAL_A; + localparam C_MEM_MAP_ADDRB_WIDTH_LSB = MEM_MAP_LOWER_BOUND_VAL_B; + + wire [C_ADDRB_WIDTH_ACTUAL-1 :0] rdaddrecc_i; + wire [C_ADDRB_WIDTH-1:C_MEM_MAP_ADDRB_WIDTH_MSB] msb_zero_i; + wire [C_MEM_MAP_ADDRB_WIDTH_LSB-1:0] lsb_zero_i; + + assign msb_zero_i = 0; + assign lsb_zero_i = 0; + assign RDADDRECC = {msb_zero_i,rdaddrecc_i,lsb_zero_i}; + +blk_mem_gen_v8_4_4_mem_module + #(.C_CORENAME (C_CORENAME), + .C_FAMILY (C_FAMILY), + .C_XDEVICEFAMILY (C_XDEVICEFAMILY), + .C_MEM_TYPE (C_MEM_TYPE), + .C_BYTE_SIZE (C_BYTE_SIZE), + .C_USE_BRAM_BLOCK (C_USE_BRAM_BLOCK), + .C_ALGORITHM (C_ALGORITHM), + .C_PRIM_TYPE (C_PRIM_TYPE), + .C_LOAD_INIT_FILE (C_LOAD_INIT_FILE), + .C_INIT_FILE_NAME (C_INIT_FILE_NAME), + .C_INIT_FILE (C_INIT_FILE), + .C_USE_DEFAULT_DATA (C_USE_DEFAULT_DATA), + .C_DEFAULT_DATA (C_DEFAULT_DATA), + .C_RST_TYPE ("SYNC"), + .C_HAS_RSTA (C_HAS_RSTA), + .C_RST_PRIORITY_A (C_RST_PRIORITY_A), + .C_RSTRAM_A (C_RSTRAM_A), + .C_INITA_VAL (C_INITA_VAL), + .C_HAS_ENA (C_HAS_ENA), + .C_HAS_REGCEA (C_HAS_REGCEA), + .C_USE_BYTE_WEA (C_USE_BYTE_WEA), + .C_WEA_WIDTH (C_WEA_WIDTH), + .C_WRITE_MODE_A (C_WRITE_MODE_A), + .C_WRITE_WIDTH_A (C_WRITE_WIDTH_A), + .C_READ_WIDTH_A (C_READ_WIDTH_A), + .C_WRITE_DEPTH_A (C_WRITE_DEPTH_A), + .C_READ_DEPTH_A (C_READ_DEPTH_A), + .C_ADDRA_WIDTH (C_ADDRA_WIDTH_ACTUAL), + .C_HAS_RSTB (C_HAS_RSTB), + .C_RST_PRIORITY_B (C_RST_PRIORITY_B), + .C_RSTRAM_B (C_RSTRAM_B), + .C_INITB_VAL (C_INITB_VAL), + .C_HAS_ENB (C_HAS_ENB), + .C_HAS_REGCEB (C_HAS_REGCEB), + .C_USE_BYTE_WEB (C_USE_BYTE_WEB), + .C_WEB_WIDTH (C_WEB_WIDTH), + .C_WRITE_MODE_B (C_WRITE_MODE_B), + .C_WRITE_WIDTH_B (C_WRITE_WIDTH_B), + .C_READ_WIDTH_B (C_READ_WIDTH_B), + .C_WRITE_DEPTH_B (C_WRITE_DEPTH_B), + .C_READ_DEPTH_B (C_READ_DEPTH_B), + .C_ADDRB_WIDTH (C_ADDRB_WIDTH_ACTUAL), + .C_HAS_MEM_OUTPUT_REGS_A (C_HAS_MEM_OUTPUT_REGS_A), + .C_HAS_MEM_OUTPUT_REGS_B (C_HAS_MEM_OUTPUT_REGS_B), + .C_HAS_MUX_OUTPUT_REGS_A (C_HAS_MUX_OUTPUT_REGS_A), + .C_HAS_MUX_OUTPUT_REGS_B (C_HAS_MUX_OUTPUT_REGS_B), + .C_HAS_SOFTECC_INPUT_REGS_A (C_HAS_SOFTECC_INPUT_REGS_A), + .C_HAS_SOFTECC_OUTPUT_REGS_B (C_HAS_SOFTECC_OUTPUT_REGS_B), + .C_MUX_PIPELINE_STAGES (C_MUX_PIPELINE_STAGES), + .C_USE_SOFTECC (C_USE_SOFTECC), + .C_USE_ECC (C_USE_ECC), + .C_HAS_INJECTERR (C_HAS_INJECTERR), + .C_SIM_COLLISION_CHECK (C_SIM_COLLISION_CHECK), + .C_COMMON_CLK (C_COMMON_CLK), + .FLOP_DELAY (FLOP_DELAY), + .C_DISABLE_WARN_BHV_COLL (C_DISABLE_WARN_BHV_COLL), + .C_EN_ECC_PIPE (C_EN_ECC_PIPE), + .C_DISABLE_WARN_BHV_RANGE (C_DISABLE_WARN_BHV_RANGE)) + blk_mem_gen_v8_4_4_inst + (.CLKA (CLKA), + .RSTA (RSTA_I_SAFE),//(rsta_in), + .ENA (ENA_I_SAFE),//(ena_in), + .REGCEA (regcea_in), + .WEA (wea_in), + .ADDRA (addra_in[C_MEM_MAP_ADDRA_WIDTH_MSB-1:C_MEM_MAP_ADDRA_WIDTH_LSB]), + .DINA (dina_in), + .DOUTA (DOUTA), + .CLKB (CLKB), + .RSTB (RSTB_I_SAFE),//(RSTB), + .ENB (ENB_I_SAFE),//(ENB), + .REGCEB (REGCEB), + .WEB (WEB), + .ADDRB (ADDRB[C_MEM_MAP_ADDRB_WIDTH_MSB-1:C_MEM_MAP_ADDRB_WIDTH_LSB]), + .DINB (DINB), + .DOUTB (DOUTB), + .INJECTSBITERR (injectsbiterr_in), + .INJECTDBITERR (injectdbiterr_in), + .ECCPIPECE (ECCPIPECE), + .SLEEP (SLEEP), + .SBITERR (SBITERR), + .DBITERR (DBITERR), + .RDADDRECC (rdaddrecc_i) + ); + end + endgenerate + + generate if (C_HAS_MEM_OUTPUT_REGS_B == 0 && C_HAS_MUX_OUTPUT_REGS_B == 0 ) begin : no_regs + assign S_AXI_RDATA = s_axi_rdata_c; + assign S_AXI_RLAST = s_axi_rlast_c; + assign S_AXI_RVALID = s_axi_rvalid_c; + assign S_AXI_RID = s_axi_rid_c; + assign S_AXI_RRESP = s_axi_rresp_c; + assign s_axi_rready_c = S_AXI_RREADY; + end + endgenerate + + generate if (C_HAS_MEM_OUTPUT_REGS_B == 1) begin : has_regceb + assign regceb_c = s_axi_rvalid_c && s_axi_rready_c; + end + endgenerate + + generate if (C_HAS_MEM_OUTPUT_REGS_B == 0) begin : no_regceb + assign regceb_c = REGCEB; + end + endgenerate + + generate if (C_HAS_MUX_OUTPUT_REGS_B == 1) begin : only_core_op_regs + assign s_axi_payload_c = {s_axi_rid_c,s_axi_rdata_c,s_axi_rresp_c,s_axi_rlast_c}; + assign S_AXI_RID = m_axi_payload_c[C_AXI_PAYLOAD-1 : C_AXI_PAYLOAD-C_AXI_ID_WIDTH]; + assign S_AXI_RDATA = m_axi_payload_c[C_AXI_PAYLOAD-C_AXI_ID_WIDTH-1 : C_AXI_PAYLOAD-C_AXI_ID_WIDTH-C_WRITE_WIDTH_B]; + assign S_AXI_RRESP = m_axi_payload_c[2:1]; + assign S_AXI_RLAST = m_axi_payload_c[0]; + end + endgenerate + + generate if (C_HAS_MEM_OUTPUT_REGS_B == 1) begin : only_emb_op_regs + assign s_axi_payload_c = {s_axi_rid_c,s_axi_rresp_c,s_axi_rlast_c}; + assign S_AXI_RDATA = s_axi_rdata_c; + assign S_AXI_RID = m_axi_payload_c[C_AXI_PAYLOAD-1 : C_AXI_PAYLOAD-C_AXI_ID_WIDTH]; + assign S_AXI_RRESP = m_axi_payload_c[2:1]; + assign S_AXI_RLAST = m_axi_payload_c[0]; + end + endgenerate + + generate if (C_HAS_MUX_OUTPUT_REGS_B == 1 || C_HAS_MEM_OUTPUT_REGS_B == 1) begin : has_regs_fwd + + blk_mem_axi_regs_fwd_v8_4 + #(.C_DATA_WIDTH (C_AXI_PAYLOAD)) + axi_regs_inst ( + .ACLK (S_ACLK), + .ARESET (s_aresetn_a_c), + .S_VALID (s_axi_rvalid_c), + .S_READY (s_axi_rready_c), + .S_PAYLOAD_DATA (s_axi_payload_c), + .M_VALID (S_AXI_RVALID), + .M_READY (S_AXI_RREADY), + .M_PAYLOAD_DATA (m_axi_payload_c) + ); + end + endgenerate + + generate if (C_INTERFACE_TYPE == 1) begin : axi_mem_module + +assign s_aresetn_a_c = !S_ARESETN; +assign S_AXI_BRESP = 2'b00; +assign s_axi_rresp_c = 2'b00; +assign s_axi_arlen_c = (C_AXI_TYPE == 1)?S_AXI_ARLEN:8'h0; + + blk_mem_axi_write_wrapper_beh_v8_4 + #(.C_INTERFACE_TYPE (C_INTERFACE_TYPE), + .C_AXI_TYPE (C_AXI_TYPE), + .C_AXI_SLAVE_TYPE (C_AXI_SLAVE_TYPE), + .C_MEMORY_TYPE (C_MEM_TYPE), + .C_WRITE_DEPTH_A (C_WRITE_DEPTH_A), + .C_AXI_AWADDR_WIDTH ((AXI_FULL_MEMORY_SLAVE == 1)?C_AXI_ADDR_WIDTH:C_AXI_ADDR_WIDTH-C_AXI_ADDR_WIDTH_LSB), + .C_HAS_AXI_ID (C_HAS_AXI_ID), + .C_AXI_ID_WIDTH (C_AXI_ID_WIDTH), + .C_ADDRA_WIDTH (C_ADDRA_WIDTH), + .C_AXI_WDATA_WIDTH (C_WRITE_WIDTH_A), + .C_AXI_OS_WR (C_AXI_OS_WR)) + axi_wr_fsm ( + // AXI Global Signals + .S_ACLK (S_ACLK), + .S_ARESETN (s_aresetn_a_c), + // AXI Full/Lite Slave Write interface + .S_AXI_AWADDR (S_AXI_AWADDR[C_AXI_ADDR_WIDTH_MSB-1:C_AXI_ADDR_WIDTH_LSB]), + .S_AXI_AWLEN (S_AXI_AWLEN), + .S_AXI_AWID (S_AXI_AWID), + .S_AXI_AWSIZE (S_AXI_AWSIZE), + .S_AXI_AWBURST (S_AXI_AWBURST), + .S_AXI_AWVALID (S_AXI_AWVALID), + .S_AXI_AWREADY (S_AXI_AWREADY), + .S_AXI_WVALID (S_AXI_WVALID), + .S_AXI_WREADY (S_AXI_WREADY), + .S_AXI_BVALID (S_AXI_BVALID), + .S_AXI_BREADY (S_AXI_BREADY), + .S_AXI_BID (S_AXI_BID), + // Signals for BRAM interfac( + .S_AXI_AWADDR_OUT (s_axi_awaddr_out_c), + .S_AXI_WR_EN (s_axi_wr_en_c) + ); + + blk_mem_axi_read_wrapper_beh_v8_4 + #(.C_INTERFACE_TYPE (C_INTERFACE_TYPE), + .C_AXI_TYPE (C_AXI_TYPE), + .C_AXI_SLAVE_TYPE (C_AXI_SLAVE_TYPE), + .C_MEMORY_TYPE (C_MEM_TYPE), + .C_WRITE_WIDTH_A (C_WRITE_WIDTH_A), + .C_ADDRA_WIDTH (C_ADDRA_WIDTH), + .C_AXI_PIPELINE_STAGES (1), + .C_AXI_ARADDR_WIDTH ((AXI_FULL_MEMORY_SLAVE == 1)?C_AXI_ADDR_WIDTH:C_AXI_ADDR_WIDTH-C_AXI_ADDR_WIDTH_LSB), + .C_HAS_AXI_ID (C_HAS_AXI_ID), + .C_AXI_ID_WIDTH (C_AXI_ID_WIDTH), + .C_ADDRB_WIDTH (C_ADDRB_WIDTH)) + axi_rd_sm( + //AXI Global Signals + .S_ACLK (S_ACLK), + .S_ARESETN (s_aresetn_a_c), + //AXI Full/Lite Read Side + .S_AXI_ARADDR (S_AXI_ARADDR[C_AXI_ADDR_WIDTH_MSB-1:C_AXI_ADDR_WIDTH_LSB]), + .S_AXI_ARLEN (s_axi_arlen_c), + .S_AXI_ARSIZE (S_AXI_ARSIZE), + .S_AXI_ARBURST (S_AXI_ARBURST), + .S_AXI_ARVALID (S_AXI_ARVALID), + .S_AXI_ARREADY (S_AXI_ARREADY), + .S_AXI_RLAST (s_axi_rlast_c), + .S_AXI_RVALID (s_axi_rvalid_c), + .S_AXI_RREADY (s_axi_rready_c), + .S_AXI_ARID (S_AXI_ARID), + .S_AXI_RID (s_axi_rid_c), + //AXI Full/Lite Read FSM Outputs + .S_AXI_ARADDR_OUT (s_axi_araddr_out_c), + .S_AXI_RD_EN (s_axi_rd_en_c) + ); + +blk_mem_gen_v8_4_4_mem_module + #(.C_CORENAME (C_CORENAME), + .C_FAMILY (C_FAMILY), + .C_XDEVICEFAMILY (C_XDEVICEFAMILY), + .C_MEM_TYPE (C_MEM_TYPE), + .C_BYTE_SIZE (C_BYTE_SIZE), + .C_USE_BRAM_BLOCK (C_USE_BRAM_BLOCK), + .C_ALGORITHM (C_ALGORITHM), + .C_PRIM_TYPE (C_PRIM_TYPE), + .C_LOAD_INIT_FILE (C_LOAD_INIT_FILE), + .C_INIT_FILE_NAME (C_INIT_FILE_NAME), + .C_INIT_FILE (C_INIT_FILE), + .C_USE_DEFAULT_DATA (C_USE_DEFAULT_DATA), + .C_DEFAULT_DATA (C_DEFAULT_DATA), + .C_RST_TYPE ("SYNC"), + .C_HAS_RSTA (C_HAS_RSTA), + .C_RST_PRIORITY_A (C_RST_PRIORITY_A), + .C_RSTRAM_A (C_RSTRAM_A), + .C_INITA_VAL (C_INITA_VAL), + .C_HAS_ENA (1), + .C_HAS_REGCEA (C_HAS_REGCEA), + .C_USE_BYTE_WEA (1), + .C_WEA_WIDTH (C_WEA_WIDTH), + .C_WRITE_MODE_A (C_WRITE_MODE_A), + .C_WRITE_WIDTH_A (C_WRITE_WIDTH_A), + .C_READ_WIDTH_A (C_READ_WIDTH_A), + .C_WRITE_DEPTH_A (C_WRITE_DEPTH_A), + .C_READ_DEPTH_A (C_READ_DEPTH_A), + .C_ADDRA_WIDTH (C_ADDRA_WIDTH), + .C_HAS_RSTB (C_HAS_RSTB), + .C_RST_PRIORITY_B (C_RST_PRIORITY_B), + .C_RSTRAM_B (C_RSTRAM_B), + .C_INITB_VAL (C_INITB_VAL), + .C_HAS_ENB (1), + .C_HAS_REGCEB (C_HAS_MEM_OUTPUT_REGS_B), + .C_USE_BYTE_WEB (1), + .C_WEB_WIDTH (C_WEB_WIDTH), + .C_WRITE_MODE_B (C_WRITE_MODE_B), + .C_WRITE_WIDTH_B (C_WRITE_WIDTH_B), + .C_READ_WIDTH_B (C_READ_WIDTH_B), + .C_WRITE_DEPTH_B (C_WRITE_DEPTH_B), + .C_READ_DEPTH_B (C_READ_DEPTH_B), + .C_ADDRB_WIDTH (C_ADDRB_WIDTH), + .C_HAS_MEM_OUTPUT_REGS_A (0), + .C_HAS_MEM_OUTPUT_REGS_B (C_HAS_MEM_OUTPUT_REGS_B), + .C_HAS_MUX_OUTPUT_REGS_A (0), + .C_HAS_MUX_OUTPUT_REGS_B (0), + .C_HAS_SOFTECC_INPUT_REGS_A (C_HAS_SOFTECC_INPUT_REGS_A), + .C_HAS_SOFTECC_OUTPUT_REGS_B (C_HAS_SOFTECC_OUTPUT_REGS_B), + .C_MUX_PIPELINE_STAGES (C_MUX_PIPELINE_STAGES), + .C_USE_SOFTECC (C_USE_SOFTECC), + .C_USE_ECC (C_USE_ECC), + .C_HAS_INJECTERR (C_HAS_INJECTERR), + .C_SIM_COLLISION_CHECK (C_SIM_COLLISION_CHECK), + .C_COMMON_CLK (C_COMMON_CLK), + .FLOP_DELAY (FLOP_DELAY), + .C_DISABLE_WARN_BHV_COLL (C_DISABLE_WARN_BHV_COLL), + .C_EN_ECC_PIPE (0), + .C_DISABLE_WARN_BHV_RANGE (C_DISABLE_WARN_BHV_RANGE)) + blk_mem_gen_v8_4_4_inst + (.CLKA (S_ACLK), + .RSTA (s_aresetn_a_c), + .ENA (s_axi_wr_en_c), + .REGCEA (regcea_in), + .WEA (S_AXI_WSTRB), + .ADDRA (s_axi_awaddr_out_c), + .DINA (S_AXI_WDATA), + .DOUTA (DOUTA), + .CLKB (S_ACLK), + .RSTB (s_aresetn_a_c), + .ENB (s_axi_rd_en_c), + .REGCEB (regceb_c), + .WEB (WEB_parameterized), + .ADDRB (s_axi_araddr_out_c), + .DINB (DINB), + .DOUTB (s_axi_rdata_c), + .INJECTSBITERR (injectsbiterr_in), + .INJECTDBITERR (injectdbiterr_in), + .SBITERR (SBITERR), + .DBITERR (DBITERR), + .ECCPIPECE (1'b0), + .SLEEP (1'b0), + .RDADDRECC (RDADDRECC) + ); + end + endgenerate +endmodule + + + diff --git a/projects/U200/U200.ip_user_files/ipstatic/simulation/fifo_generator_vlog_beh.v b/projects/U200/U200.ip_user_files/ipstatic/simulation/fifo_generator_vlog_beh.v new file mode 100755 index 0000000..e5067fe --- /dev/null +++ b/projects/U200/U200.ip_user_files/ipstatic/simulation/fifo_generator_vlog_beh.v @@ -0,0 +1,10519 @@ +/* + ******************************************************************************* + * + * 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_v13_2_5_bhv_ver_as + * | + * +-fifo_generator_v13_2_5_bhv_ver_ss + * | + * +-fifo_generator_v13_2_5_bhv_ver_preload0 + * + ******************************************************************************* + * Description: + * + * The Verilog behavioral model for the FIFO Generator. + * + * The behavioral model has three parts: + * - The behavioral model for independent clocks FIFOs (_as) + * - The behavioral model for common clock FIFOs (_ss) + * - The "preload logic" block which implements First-word Fall-through + * + ******************************************************************************* + * Description: + * The verilog behavioral model for the FIFO generator core. + * + ******************************************************************************* + */ + +`timescale 1ps/1ps +`ifndef TCQ + `define TCQ 100 +`endif + + +/******************************************************************************* + * Declaration of top-level module + ******************************************************************************/ +module fifo_generator_vlog_beh + #( + //----------------------------------------------------------------------- + // Generic Declarations + //----------------------------------------------------------------------- + parameter C_COMMON_CLOCK = 0, + parameter C_COUNT_TYPE = 0, + parameter C_DATA_COUNT_WIDTH = 2, + parameter C_DEFAULT_VALUE = "", + parameter C_DIN_WIDTH = 8, + parameter C_DOUT_RST_VAL = "", + parameter C_DOUT_WIDTH = 8, + parameter C_ENABLE_RLOCS = 0, + parameter C_FAMILY = "", + parameter C_FULL_FLAGS_RST_VAL = 1, + parameter C_HAS_ALMOST_EMPTY = 0, + parameter C_HAS_ALMOST_FULL = 0, + parameter C_HAS_BACKUP = 0, + parameter C_HAS_DATA_COUNT = 0, + parameter C_HAS_INT_CLK = 0, + parameter C_HAS_MEMINIT_FILE = 0, + parameter C_HAS_OVERFLOW = 0, + parameter C_HAS_RD_DATA_COUNT = 0, + parameter C_HAS_RD_RST = 0, + parameter C_HAS_RST = 1, + parameter C_HAS_SRST = 0, + parameter C_HAS_UNDERFLOW = 0, + parameter C_HAS_VALID = 0, + parameter C_HAS_WR_ACK = 0, + parameter C_HAS_WR_DATA_COUNT = 0, + parameter C_HAS_WR_RST = 0, + parameter C_IMPLEMENTATION_TYPE = 0, + parameter C_INIT_WR_PNTR_VAL = 0, + parameter C_MEMORY_TYPE = 1, + parameter C_MIF_FILE_NAME = "", + parameter C_OPTIMIZATION_MODE = 0, + parameter C_OVERFLOW_LOW = 0, + parameter C_EN_SAFETY_CKT = 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; + wire wr_rst_busy_o; + wire wr_rst_busy_ntve; + wire wr_rst_busy_axis; + wire wr_rst_busy_wach; + wire wr_rst_busy_wdch; + wire wr_rst_busy_wrch; + wire wr_rst_busy_rach; + wire wr_rst_busy_rdch; + + + + 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 | wr_rst_busy_o; + assign wr_rst_busy = wr_rst_busy_o; + 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_v13_2_5_CONV_VER + #( + .C_COMMON_CLOCK (C_COMMON_CLOCK), + .C_INTERFACE_TYPE (C_INTERFACE_TYPE), + .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_EN_SAFETY_CKT (C_EN_SAFETY_CKT), + .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_v13_2_5_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_o (wr_rst_busy_o), + .wr_rst_busy (wr_rst_busy_i), + .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 == "virtexuplus" || C_FAMILY == "zynquplus" || C_FAMILY == "kintexuplus" || C_FAMILY == "virtexuplushbm") ? 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_v13_2_5_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; + 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 + reg rst_d1 = 0 ; + reg rst_d2 = 0 ; + reg [3:0] axi_rst = 4'h0 ; + always @ (posedge inverted_reset or posedge S_ACLK) begin + if (inverted_reset) begin + rst_d1 <= 1'b1; + rst_d2 <= 1'b1; + axi_rst <= 4'hf; + end else begin + rst_d1 <= #`TCQ 1'b0; + rst_d2 <= #`TCQ rst_d1; + axi_rst <= #`TCQ {axi_rst[2:0],1'b0}; + end + end + + assign axi_rs_rst = axi_rst[3];//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_v13_2_5_CONV_VER + #( + .C_FAMILY (C_FAMILY), + .C_COMMON_CLOCK (C_COMMON_CLOCK), + .C_INTERFACE_TYPE (C_INTERFACE_TYPE), + .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_EN_SAFETY_CKT ((C_IMPLEMENTATION_TYPE_AXIS == 1 || C_IMPLEMENTATION_TYPE_AXIS == 11) ? 1 : 0), + .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_v13_2_5_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_v13_2_5_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_v13_2_5_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_v13_2_5_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 (inverted_reset), + + // 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_v13_2_5_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_INTERFACE_TYPE (C_INTERFACE_TYPE), + .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_EN_SAFETY_CKT ((C_IMPLEMENTATION_TYPE_WACH == 1 || C_IMPLEMENTATION_TYPE_WACH == 11) ? 1 : 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_v13_2_5_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_v13_2_5_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 (inverted_reset), + + // 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_v13_2_5_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_v13_2_5_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_INTERFACE_TYPE (C_INTERFACE_TYPE), + .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_EN_SAFETY_CKT ((C_IMPLEMENTATION_TYPE_WDCH == 1 || C_IMPLEMENTATION_TYPE_WDCH == 11) ? 1 : 0), + .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_v13_2_5_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_v13_2_5_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 (inverted_reset), + + // 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_MASTER_CE == 1) ? wrch_we & M_ACLK_EN : wrch_we; + assign wrch_rd_en = (C_HAS_SLAVE_CE == 1) ? wrch_re & S_ACLK_EN : wrch_re; + + fifo_generator_v13_2_5_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_INTERFACE_TYPE (C_INTERFACE_TYPE), + .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_EN_SAFETY_CKT ((C_IMPLEMENTATION_TYPE_WRCH == 1 || C_IMPLEMENTATION_TYPE_WRCH == 11) ? 1 : 0), + .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_v13_2_5_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_v13_2_5_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 (inverted_reset), + + // 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_v13_2_5_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_INTERFACE_TYPE (C_INTERFACE_TYPE), + .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_EN_SAFETY_CKT ((C_IMPLEMENTATION_TYPE_RACH == 1 || C_IMPLEMENTATION_TYPE_RACH == 11) ? 1 : 0), + .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_v13_2_5_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_v13_2_5_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 (inverted_reset), + + // 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_v13_2_5_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_MASTER_CE == 1) ? rdch_we & M_ACLK_EN : rdch_we; + assign rdch_rd_en = (C_HAS_SLAVE_CE == 1) ? rdch_re & S_ACLK_EN : rdch_re; + + fifo_generator_v13_2_5_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_INTERFACE_TYPE (C_INTERFACE_TYPE), + .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_EN_SAFETY_CKT ((C_IMPLEMENTATION_TYPE_RDCH == 1 || C_IMPLEMENTATION_TYPE_RDCH == 11) ? 1 : 0), + .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_v13_2_5_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_v13_2_5_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 (inverted_reset), + + // 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_v13_2_5 + + + +/******************************************************************************* + * Declaration of top-level module for Conventional FIFO + ******************************************************************************/ +module fifo_generator_v13_2_5_CONV_VER + #( + parameter C_COMMON_CLOCK = 0, + parameter C_INTERFACE_TYPE = 0, + parameter C_EN_SAFETY_CKT = 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_o, + 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 == "virtexuplus" || C_FAMILY == "zynquplus" || C_FAMILY == "kintexuplus" || C_FAMILY == "virtexuplushbm") ? 1 : 0; + + //Internal reset signals + reg rd_rst_asreg = 1'b0; + reg rd_rst_asreg_d1 = 1'b0; + reg rd_rst_asreg_d2 = 1'b0; + reg rd_rst_asreg_d3 = 1'b0; + reg rd_rst_reg = 1'b0; + reg rd_rst_comb = 1'b1; + reg rd_rst_comb_d1 = 1'b0; + reg wr_rst_d0 = 1'b0; + reg wr_rst_d1 = 1'b0; + reg wr_rst_d2 = 1'b0; + reg rd_rst_d0 = 1'b0; + reg rd_rst_d1 = 1'b0; + reg rd_rst_d2 = 1'b0; + reg rd_rst_d3 = 1'b0; + reg wrrst_done = 1'b0; + reg rdrst_done = 1'b0; + reg wr_rst_asreg = 1'b0; + reg wr_rst_asreg_d1 = 1'b0; + reg wr_rst_asreg_d2 = 1'b0; + reg wr_rst_asreg_d3 = 1'b0; + reg rd_rst_wr_d0 = 1'b0; + reg rd_rst_wr_d1 = 1'b0; + reg rd_rst_wr_d2 = 1'b0; + reg wr_rst_reg = 1'b0; + reg rst_active_i = 1'b1; + reg rst_delayed_d1 = 1'b1; + reg rst_delayed_d2 = 1'b1; + reg wr_rst_comb = 1'b1; + reg wr_rst_comb_d1 = 1'b0; + wire wr_rst_i; + wire rd_rst_i; + wire rst_i; + + //Internal reset signals + reg rst_asreg = 1'b0; + reg srst_asreg = 1'b0; + reg rst_asreg_d1 = 1'b0; + reg rst_asreg_d2 = 1'b0; + reg srst_asreg_d1 = 1'b0; + reg srst_asreg_d2 = 1'b0; + reg rst_reg = 1'b0; + reg srst_reg = 1'b0; + reg rst_comb = 1'b1; + reg rst_comb_d1 = 1'b0; + wire srst_comb; + reg rst_full_gen_i = 0; + reg rst_full_ff_i = 0; + reg [2:0] sckt_ff0_bsy_o_i = {3{1'b0}}; + + 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 fifo_empty_fb; + 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; + wire sckt_wr_rst_i; + wire sckt_rd_rst_i; + reg sckt_wr_rst_i_q = 1'b0; + + wire w_fab_read_data_valid_i; + wire w_read_data_valid_i; + wire w_ram_valid_i; + // 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; + assign wr_rst_busy_o = wr_rst_busy | rst_full_gen_i | sckt_ff0_bsy_o_i[2]; + generate if (C_FULL_FLAGS_RST_VAL == 0 && C_EN_SAFETY_CKT == 1) begin : gsckt_bsy_o + wire clk_i = C_COMMON_CLOCK ? CLK : WR_CLK; + always @ (posedge clk_i) + sckt_ff0_bsy_o_i <= {sckt_ff0_bsy_o_i[1:0],wr_rst_busy}; + end endgenerate +// 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_ss + //Common Clock Behavioral Model + fifo_generator_v13_2_5_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_EN_SAFETY_CKT?0:C_HAS_RST), + .C_HAS_SRST (C_EN_SAFETY_CKT?1: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_EN_SAFETY_CKT (C_EN_SAFETY_CKT), + .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 + ( + .SAFETY_CKT_WR_RST (sckt_wr_rst_i), + .CLK (CLK), + .RST (C_EN_SAFETY_CKT?1'b0:rst_i), + .SRST (C_EN_SAFETY_CKT?sckt_wr_rst_i: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), + .EMPTY_FB (fifo_empty_fb), + .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_as + //Independent Clocks Behavioral Model + fifo_generator_v13_2_5_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_EN_SAFETY_CKT?0: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_EN_SAFETY_CKT (C_EN_SAFETY_CKT), + .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 + ( + .SAFETY_CKT_WR_RST (sckt_wr_rst_i), + .SAFETY_CKT_RD_RST (sckt_rd_rst_i), + .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), + .EMPTY_FB (fifo_empty_fb), + .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), + .fab_read_data_valid_i (w_fab_read_data_valid_i), + .read_data_valid_i (w_read_data_valid_i), + .ram_valid_i (w_ram_valid_i), + .DBITERR (dbiterr_fifo_out) + ); +end + +2 : begin : ll_afifo_inst + fifo_generator_v13_2_5_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_as + //Independent Clocks Behavioral Model + fifo_generator_v13_2_5_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_EN_SAFETY_CKT?0: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_EN_SAFETY_CKT (C_EN_SAFETY_CKT), + .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 + ( + .SAFETY_CKT_WR_RST (sckt_wr_rst_i), + .SAFETY_CKT_RD_RST (sckt_rd_rst_i), + .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), + .EMPTY_FB (fifo_empty_fb), + .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_fwft + + + fifo_generator_v13_2_5_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_EMBEDDED_REG (C_USE_EMBEDDED_REG), + .C_USE_ECC (C_USE_ECC), + .C_USERVALID_LOW (C_VALID_LOW), + .C_USERUNDERFLOW_LOW (C_UNDERFLOW_LOW), + .C_EN_SAFETY_CKT (C_EN_SAFETY_CKT), + .C_MEMORY_TYPE (C_MEMORY_TYPE), + .C_FIFO_TYPE (C_FIFO_TYPE) + ) + fgpl0 + ( + .SAFETY_CKT_RD_RST(safety_ckt_rd_rst), + .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), + .fab_read_data_valid_i_o (w_fab_read_data_valid_i), + .read_data_valid_i_o (w_read_data_valid_i), + .ram_valid_i_o (w_ram_valid_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 = C_EN_SAFETY_CKT ? fifo_empty_fb : 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 <= 1; + ALMOSTEMPTY_P0_OUT_Q <= 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 <= 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_v13_2_5_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_EN_SAFETY_CKT (C_EN_SAFETY_CKT), + .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 + ( + .SAFETY_CKT_RD_RST(safety_ckt_rd_rst), + .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) && (C_USE_EMBEDDED_REG < 3) ) 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) && (C_USE_EMBEDDED_REG < 3) ) 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 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) && (C_USE_EMBEDDED_REG == 3) ) begin : block30_both + if (C_COMMON_CLOCK == 0) begin : block_ic_both + 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_both + endgenerate + + generate + if (C_USE_FWFT_DATA_COUNT==1 && (C_RD_DATA_COUNT_WIDTH>C_RD_PNTR_WIDTH) && (C_USE_EMBEDDED_REG == 3) ) begin : block3_both + if (C_COMMON_CLOCK == 0) begin : block_ic_both + 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_both + else begin + assign RD_DATA_COUNT = RD_DATA_COUNT_FIFO_OUT; + end + end //block3_both + endgenerate + + + //If we are not using extra logic for the FWFT data count, + //then connect RD_DATA_COUNT to the RD_DATA_COUNT from the + //internal FIFO instance + generate + if (C_USE_FWFT_DATA_COUNT==0 ) begin : block31 + assign RD_DATA_COUNT = RD_DATA_COUNT_FIFO_OUT; + end + endgenerate + + //Always connect WR_DATA_COUNT to the WR_DATA_COUNT from the internal + //FIFO instance + generate + if (C_USE_FWFT_DATA_COUNT==1) begin : block4 + assign WR_DATA_COUNT = WR_DATA_COUNT_FIFO_OUT; + end + else begin : block4 + assign WR_DATA_COUNT = WR_DATA_COUNT_FIFO_OUT; + end + endgenerate + + + //Connect other flags to the internal FIFO instance + assign FULL = FULL_FIFO_OUT; + assign ALMOST_FULL = ALMOST_FULL_FIFO_OUT; + assign WR_ACK = WR_ACK_FIFO_OUT; + assign OVERFLOW = OVERFLOW_FIFO_OUT; + assign PROG_FULL = PROG_FULL_FIFO_OUT; + assign PROG_EMPTY = PROG_EMPTY_FIFO_OUT; + + + /************************************************************************** + * find_log2 + * Returns the 'log2' value for the input value for the supported ratios + ***************************************************************************/ + function integer find_log2; + input integer int_val; + integer i,j; + begin + i = 1; + j = 0; + for (i = 1; i < int_val; i = i*2) begin + j = j + 1; + end + find_log2 = j; + end + endfunction + + // if an asynchronous FIFO has been selected, display a message that the FIFO + // will not be cycle-accurate in simulation + initial begin + if (C_IMPLEMENTATION_TYPE == 2) begin + $display("WARNING: Behavioral models for independent clock FIFO configurations do not model synchronization delays. The behavioral models are functionally correct, and will represent the behavior of the configured FIFO. See the FIFO Generator User Guide for more information."); + end else if (C_MEMORY_TYPE == 4) begin + $display("FAILURE : Behavioral models do not support built-in FIFO configurations. Please use post-synthesis or post-implement simulation in Vivado."); + $finish; + end + + if (C_WR_PNTR_WIDTH != find_log2(C_WR_DEPTH)) begin + $display("FAILURE : C_WR_PNTR_WIDTH is not log2 of C_WR_DEPTH."); + $finish; + end + + if (C_RD_PNTR_WIDTH != find_log2(C_RD_DEPTH)) begin + $display("FAILURE : C_RD_PNTR_WIDTH is not log2 of C_RD_DEPTH."); + $finish; + end + + if (C_USE_ECC == 1) begin + if (C_DIN_WIDTH != C_DOUT_WIDTH) begin + $display("FAILURE : C_DIN_WIDTH and C_DOUT_WIDTH must be equal for ECC configuration."); + $finish; + end + if (C_DIN_WIDTH == 1 && C_ERROR_INJECTION_TYPE > 1) begin + $display("FAILURE : C_DIN_WIDTH and C_DOUT_WIDTH must be > 1 for double bit error injection."); + $finish; + end + end + + end //initial + + /************************************************************************** + * Internal reset logic + **************************************************************************/ + assign wr_rst_i = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? wr_rst_reg|sckt_wr_rst_i : 0; + assign rd_rst_i = (C_HAS_RST == 1 || C_ENABLE_RST_SYNC == 0) ? rd_rst_reg|sckt_rd_rst_i : 0; + assign rst_i = C_HAS_RST ? rst_reg|sckt_wr_rst_i : 0; + + wire rst_2_sync; + wire clk_2_sync = (C_COMMON_CLOCK == 1) ? CLK : WR_CLK; + + localparam RST_SYNC_STAGES = C_EN_SAFETY_CKT == 0 ? C_COMMON_CLOCK ? C_SYNCHRONIZER_STAGE : C_SYNCHRONIZER_STAGE+2 : 5; + localparam RST_BUSY_LEN = 4; + reg wr_rst_busy_i = 0; + reg rd_rst_busy_i = 0; + generate + if (C_ENABLE_RST_SYNC == 0 || (C_HAS_RST == 0 && C_HAS_SRST == 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 wr_rst_busy_o = 1'b0; + assign rd_rst_busy = 1'b0; + assign sckt_wr_rst_i = 1'b0; + assign sckt_rd_rst_i = 1'b0; + end // gnrst_sync + else if (C_ENABLE_RST_SYNC == 1 && C_HAS_RST == 1 && C_COMMON_CLOCK == 0 && C_EN_SAFETY_CKT == 0) begin : g7s_ic_rst_nsckt + reg [1:0] arst_sync_wr = 2'b11; + reg [1:0] arst_sync_rd = 2'b11; + reg [RST_SYNC_STAGES-1:0] sckt_wr_rst_rd = 0; + reg [RST_SYNC_STAGES-1:0] sckt_rd_rst_wr = 0; + reg [3:0] rd_rst_wr_ext = 0; + reg [1:0] wr_rst_rd_ext = 0; + reg sckt_wr_rst_ic = 0; + reg sckt_rd_rst_ic = 0; + + assign rst_2_sync = arst_sync_wr[1]; + + always @(posedge WR_CLK or posedge rst_delayed) begin + if (rst_delayed == 1'b1) + arst_sync_wr <= #`TCQ 2'b11; + else + arst_sync_wr <= #`TCQ {arst_sync_wr[0], rst_delayed}; + end + + always @(posedge RD_CLK or posedge rst_delayed) begin + if (rst_delayed == 1'b1) + arst_sync_rd <= #`TCQ 2'b11; + else + arst_sync_rd <= #`TCQ {arst_sync_rd[0], rst_delayed}; + end + always @(posedge WR_CLK) begin + sckt_rd_rst_wr <= #`TCQ {sckt_rd_rst_wr[RST_SYNC_STAGES-2:0], sckt_rd_rst_ic}; + end + always @(posedge WR_CLK or posedge arst_sync_wr[1]) begin + if (arst_sync_wr[1]) begin + sckt_wr_rst_ic <= #`TCQ 1'b1; + wr_rst_busy_i <= #`TCQ 1'b1; + rd_rst_wr_ext <= #`TCQ {RST_SYNC_STAGES{1'b0}}; + end else begin + rd_rst_wr_ext <= #`TCQ {rd_rst_wr_ext[2:0], sckt_rd_rst_wr[RST_SYNC_STAGES-1]}; + if (rd_rst_wr_ext[1] && ~rd_rst_wr_ext[0]) + sckt_wr_rst_ic <= #`TCQ 1'b0; + else if (rd_rst_wr_ext[3] && ~rd_rst_wr_ext[2]) + wr_rst_busy_i <= #`TCQ 1'b0; + end + end + always @(posedge RD_CLK) begin + sckt_wr_rst_rd <= #`TCQ {sckt_wr_rst_rd[RST_SYNC_STAGES-2:0], sckt_wr_rst_ic}; + end + always @(posedge RD_CLK or posedge arst_sync_rd[1]) begin + if (arst_sync_rd[1]) begin + sckt_rd_rst_ic <= #`TCQ 1'b1; + rd_rst_busy_i <= #`TCQ 1'b1; + wr_rst_rd_ext <= #`TCQ {RST_SYNC_STAGES{1'b0}}; + end else begin + wr_rst_rd_ext <= #`TCQ {wr_rst_rd_ext[0], sckt_wr_rst_rd[RST_SYNC_STAGES-1]}; + if (wr_rst_rd_ext[1]) begin + sckt_rd_rst_ic <= #`TCQ 1'b0; + rd_rst_busy_i <= #`TCQ 1'b0; + end + end + end + + assign rd_rst_busy = rd_rst_busy_i; + assign wr_rst_busy = wr_rst_busy_i; + assign wr_rst_busy_o = wr_rst_busy_i; + assign sckt_wr_rst_i = sckt_wr_rst_ic|arst_sync_wr[1]; + assign sckt_rd_rst_i = sckt_rd_rst_ic|arst_sync_rd[1]; + end // g7s_ic_rst_nsckt + else if (C_ENABLE_RST_SYNC == 1 && C_HAS_RST == 1 && C_COMMON_CLOCK == 0 && C_EN_SAFETY_CKT == 1) begin : g7s_ic_rst_sckt + reg [RST_SYNC_STAGES-1:0] arst_sync_wr = {RST_SYNC_STAGES{1'b1}}; + reg [RST_SYNC_STAGES-1:0] arst_sync_rd = {RST_SYNC_STAGES{1'b1}}; + reg [RST_SYNC_STAGES-1:0] sckt_wr_rst_rd = 0; + reg [RST_SYNC_STAGES-1:0] sckt_rd_rst_wr = 0; + reg [3:0] rd_rst_wr_ext = 0; + reg [1:0] wr_rst_rd_ext = 0; + reg sckt_wr_rst_ic = 0; + reg sckt_rd_rst_ic = 0; + + always @(posedge WR_CLK) begin + arst_sync_wr <= #`TCQ {arst_sync_wr[RST_SYNC_STAGES-2:0], rst_delayed}; + sckt_rd_rst_wr <= #`TCQ {sckt_rd_rst_wr[RST_SYNC_STAGES-2:0], sckt_rd_rst_ic}; + rd_rst_wr_ext <= #`TCQ {rd_rst_wr_ext[2:0], sckt_rd_rst_wr[RST_SYNC_STAGES-1]}; + if (arst_sync_wr[RST_SYNC_STAGES-1]) begin + sckt_wr_rst_ic <= #`TCQ 1'b1; + wr_rst_busy_i <= #`TCQ 1'b1; + end else if (rd_rst_wr_ext[1] && ~rd_rst_wr_ext[0]) + sckt_wr_rst_ic <= #`TCQ 1'b0; + else if (rd_rst_wr_ext[3] && ~rd_rst_wr_ext[2]) + wr_rst_busy_i <= #`TCQ 1'b0; + end + always @(posedge RD_CLK) begin + arst_sync_rd <= #`TCQ {arst_sync_rd[RST_SYNC_STAGES-2:0], rst_delayed}; + sckt_wr_rst_rd <= #`TCQ {sckt_wr_rst_rd[RST_SYNC_STAGES-2:0], arst_sync_wr[RST_SYNC_STAGES-1]}; + wr_rst_rd_ext <= #`TCQ {wr_rst_rd_ext[0], sckt_wr_rst_rd[RST_SYNC_STAGES-1]}; + if (arst_sync_rd[RST_SYNC_STAGES-1]) begin + sckt_rd_rst_ic <= #`TCQ 1'b1; + rd_rst_busy_i <= #`TCQ 1'b1; + end else if (wr_rst_rd_ext[1]) begin + sckt_rd_rst_ic <= #`TCQ 1'b0; + rd_rst_busy_i <= #`TCQ 1'b0; + end + end + + assign rd_rst_busy = rd_rst_busy_i; + assign wr_rst_busy = wr_rst_busy_i; + assign wr_rst_busy_o = wr_rst_busy_i; + assign sckt_wr_rst_i = sckt_wr_rst_ic; + assign sckt_rd_rst_i = sckt_rd_rst_ic; + end // g7s_ic_rst_sckt + else if (C_ENABLE_RST_SYNC == 1 && C_HAS_RST == 1 && C_COMMON_CLOCK == 1 && C_EN_SAFETY_CKT == 0) begin : g7s_cc_rst_nsckt + reg [1:0] arst_sync_wr = 0; + reg [RST_BUSY_LEN-1:0] sckt_wr_rst_cc = 0; + assign rst_2_sync = arst_sync_wr[1]; + + always @(posedge CLK or posedge rst_delayed) begin + if (rst_delayed == 1'b1) + arst_sync_wr <= #`TCQ 2'b11; + else + arst_sync_wr <= #`TCQ {arst_sync_wr[0], rst_delayed}; + end + + always @(posedge CLK) begin + sckt_wr_rst_cc <= #`TCQ {sckt_wr_rst_cc[RST_BUSY_LEN-2:0], arst_sync_wr[RST_SYNC_STAGES-1]}; + end + + assign sckt_wr_rst_i = |sckt_wr_rst_cc[RST_BUSY_LEN-3:0] | arst_sync_wr[1]; + assign sckt_rd_rst_i = sckt_wr_rst_i; + assign wr_rst_busy = |sckt_wr_rst_cc | arst_sync_wr[1]; + assign rd_rst_busy = |sckt_wr_rst_cc; + assign wr_rst_busy_o = |sckt_wr_rst_cc; + end // g7s_cc_rst_nsckt + else if (C_ENABLE_RST_SYNC == 1 && C_HAS_RST == 1 && C_COMMON_CLOCK == 1 && C_EN_SAFETY_CKT == 1) begin : g7s_cc_rst_sckt + reg [RST_SYNC_STAGES-1:0] arst_sync_wr = 0; + reg [RST_BUSY_LEN-1:0] sckt_wr_rst_cc = 0; + + always @(posedge CLK) begin + arst_sync_wr <= #`TCQ {arst_sync_wr[RST_SYNC_STAGES-2:0], rst_delayed}; + sckt_wr_rst_cc <= #`TCQ {sckt_wr_rst_cc[RST_BUSY_LEN-2:0], arst_sync_wr[RST_SYNC_STAGES-1]}; + end + + assign sckt_wr_rst_i = |sckt_wr_rst_cc[RST_BUSY_LEN-3:0]; + assign sckt_rd_rst_i = sckt_wr_rst_i; + assign wr_rst_busy = |sckt_wr_rst_cc; + assign rd_rst_busy = |sckt_wr_rst_cc; + assign wr_rst_busy_o = |sckt_wr_rst_cc; + end // g7s_cc_rst_sckt + else if (C_ENABLE_RST_SYNC == 1 && 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; + assign sckt_wr_rst_i = rst_reg; + always @* rst_full_ff_i <= 1'b0; + 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 // g8s_cc_rst + else if (IS_8SERIES != 1 && C_HAS_SRST == 1 && C_COMMON_CLOCK == 1) begin : g7s_cc_srst + assign wr_rst_busy = srst_delayed; + assign rd_rst_busy = srst_delayed; + assign rst_2_sync = srst_delayed; + assign sckt_wr_rst_i = srst_delayed; + always @* rst_full_ff_i <= 1'b0; + end // g7s_cc_srst + 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 && C_EN_SAFETY_CKT == 0) 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 wr_rst_busy;//1'b0; + rst_d2 <= #`TCQ rst_d1; + rst_d3 <= #`TCQ rst_d2 | sckt_wr_rst_i; + rst_d4 <= #`TCQ rst_d3; + end + end + end + + always @* rst_full_ff_i <= C_HAS_SRST ? 1'b0 : rst_d2 | sckt_wr_rst_i; + always @* rst_full_gen_i <= C_HAS_SRST ? rst_d4 : rst_d3; + + end else if (C_EN_SAFETY_CKT == 1 && C_FULL_FLAGS_RST_VAL == 0) begin : gnrst_full_sckt + always @* rst_full_ff_i <= C_HAS_SRST ? 1'b0 : (C_COMMON_CLOCK == 0) ? wr_rst_i : rst_i; + always @* rst_full_gen_i <= 1'b0; + 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_HAS_SRST ? 1'b0 : (C_COMMON_CLOCK == 0) ? wr_rst_i : rst_i; + always @* rst_full_gen_i <= 1'b0; + end + endgenerate // grstd1 + +endmodule //fifo_generator_v13_2_5_CONV_VER + + +module fifo_generator_v13_2_5_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_v13_2_5_sync_stage + +/******************************************************************************* + * Declaration of Independent-Clocks FIFO Module + ******************************************************************************/ +module fifo_generator_v13_2_5_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_EN_SAFETY_CKT = 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 SAFETY_CKT_WR_RST, + input SAFETY_CKT_RD_RST, + 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, + input fab_read_data_valid_i, + input read_data_valid_i, + input ram_valid_i, + 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 EMPTY_FB = 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 == "virtexuplus" || C_FAMILY == "zynquplus" || C_FAMILY == "kintexuplus" || C_FAMILY == "virtexuplushbm") ? 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 C_USE_ECC_1 = (C_USE_ECC == 1 || C_USE_ECC ==2) ? 1:0; + localparam ENABLE_ERR_INJECTION = C_USE_ECC_1 && 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; + reg fab_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 <= 1'b0; + else + ram_rd_en_d1 <= #`TCQ ram_rd_en; + end + end + endgenerate + + generate + if (C_PRELOAD_LATENCY == 2 && C_USE_EMBEDDED_REG == 3) begin : grd_d1 + always @ (posedge RD_CLK or posedge rd_rst_i) begin + if (rd_rst_i) + ram_rd_en_d1 <= 1'b0; + else + ram_rd_en_d1 <= #`TCQ ram_rd_en; + fab_rd_en_d1 <= #`TCQ ram_rd_en_d1; + end + end + endgenerate + + + + // Write pointer adjustment based on pointers width for EMPTY/ALMOST_EMPTY generation + generate + if (C_RD_PNTR_WIDTH > C_WR_PNTR_WIDTH) begin : rdg // Read depth greater than write depth + assign adj_wr_pntr_rd[C_RD_PNTR_WIDTH-1:C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH] = wr_pntr_rd; + assign adj_wr_pntr_rd[C_RD_PNTR_WIDTH-C_WR_PNTR_WIDTH-1:0] = 0; + end else begin : rdl // Read depth lesser than or equal to write depth + assign adj_wr_pntr_rd = wr_pntr_rd[C_WR_PNTR_WIDTH-1:C_WR_PNTR_WIDTH-C_RD_PNTR_WIDTH]; + end + endgenerate + + // Generate Empty and Almost Empty + // ram_rd_en used to determine EMPTY should depend on the EMPTY. + assign ram_rd_en = RD_EN & !EMPTY; + assign empty_int = ((adj_wr_pntr_rd == rd_pntr) || (ram_rd_en && (adj_wr_pntr_rd == (rd_pntr+1'h1)))); + assign almost_empty_int = ((adj_wr_pntr_rd == (rd_pntr+1'h1)) || (ram_rd_en && (adj_wr_pntr_rd == (rd_pntr+2'h2)))); + + // Register Empty and Almost Empty + always @ (posedge RD_CLK or posedge rd_rst_i) + begin + if (rd_rst_i && C_EN_SAFETY_CKT == 0) begin + EMPTY <= 1'b1; + ALMOST_EMPTY <= 1'b1; + rd_data_count_int <= {C_RD_PNTR_WIDTH{1'b0}}; + end else if (SAFETY_CKT_RD_RST && C_EN_SAFETY_CKT) begin + EMPTY <= 1'b1; + ALMOST_EMPTY <= 1'b1; + rd_data_count_int <= {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 + always @ (posedge RD_CLK or posedge rd_rst_i) + begin + if (rd_rst_i && C_EN_SAFETY_CKT == 0) begin + EMPTY_FB <= 1'b1; + end else begin + if (SAFETY_CKT_RD_RST && C_EN_SAFETY_CKT) + EMPTY_FB <= #`TCQ 1'b1; + else if (empty_int) + EMPTY_FB <= #`TCQ 1'b1; + else + EMPTY_FB <= #`TCQ 1'b0; + 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 & C_HAS_RST) begin + FULL <= C_FULL_FLAGS_RST_VAL; + ALMOST_FULL <= C_FULL_FLAGS_RST_VAL; + end else if (SAFETY_CKT_WR_RST & C_EN_SAFETY_CKT) begin + FULL <= C_FULL_FLAGS_RST_VAL; + ALMOST_FULL <= 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 <= {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 <= 0; + stage2_valid <= 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_out1; + wire valid_out2; + 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 [1:0] err_type_both = 0; + reg [C_DOUT_WIDTH-1:0] ideal_dout = 0; + reg [C_DOUT_WIDTH-1:0] ideal_dout_d1 = 0; + reg [C_DOUT_WIDTH-1:0] ideal_dout_both = 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; + reg valid_d2 = 0; + + //user specified value for reseting the size of the fifo + reg [C_DOUT_WIDTH-1:0] dout_reset_val = 0; + + //temporary registers for WR_RESPONSE_LATENCY feature + + integer tmp_wr_listsize; + integer tmp_rd_listsize; + + //Signal for registered version of prog full and empty + + //Threshold values for Programmable Flags + integer prog_empty_actual_thresh_assert; + integer prog_empty_actual_thresh_negate; + integer prog_full_actual_thresh_assert; + integer prog_full_actual_thresh_negate; + + + /**************************************************************************** + * Function Declarations + ***************************************************************************/ + + /************************************************************************** + * write_fifo + * This task writes a word to the FIFO memory and updates the + * write pointer. + * FIFO size is relative to write domain. + ***************************************************************************/ + task write_fifo; + begin + memory[wr_ptr] <= DIN; + wr_pntr <= #`TCQ wr_pntr + 1; + // Store the type of error injection (double/single) on write + case (C_ERROR_INJECTION_TYPE) + 3: ecc_err[wr_ptr] <= {INJECTDBITERR,INJECTSBITERR}; + 2: ecc_err[wr_ptr] <= {INJECTDBITERR,1'b0}; + 1: ecc_err[wr_ptr] <= {1'b0,INJECTSBITERR}; + default: ecc_err[wr_ptr] <= 0; + endcase + // (Works opposite to core: wr_ptr is a DOWN counter) + if (wr_ptr == 0) begin + wr_ptr <= C_WR_DEPTH - 1; + end else begin + wr_ptr <= wr_ptr - 1; + end + end + endtask // write_fifo + + /************************************************************************** + * read_fifo + * This task reads a word from the FIFO memory and updates the read + * pointer. It's output is the ideal_dout bus. + * FIFO size is relative to write domain. + ***************************************************************************/ + task read_fifo; + integer i; + reg [C_DOUT_WIDTH-1:0] tmp_dout; + reg [C_DIN_WIDTH-1:0] memory_read; + reg [31:0] tmp_rd_ptr; + reg [31:0] rd_ptr_high; + reg [31:0] rd_ptr_low; + reg [1:0] tmp_ecc_err; + begin + rd_pntr <= #`TCQ rd_pntr + 1; + // output is wider than input + if (reads_per_write == 0) begin + tmp_dout = 0; + tmp_rd_ptr = (rd_ptr << log2_writes_per_read)+(writes_per_read-1); + for (i = writes_per_read - 1; i >= 0; i = i - 1) begin + tmp_dout = tmp_dout << C_DIN_WIDTH; + tmp_dout = tmp_dout | memory[tmp_rd_ptr]; + + // (Works opposite to core: rd_ptr is a DOWN counter) + if (tmp_rd_ptr == 0) begin + tmp_rd_ptr = C_WR_DEPTH - 1; + end else begin + tmp_rd_ptr = tmp_rd_ptr - 1; + end + end + + // output is symmetric + end else if (reads_per_write == 1) begin + tmp_dout = memory[rd_ptr][C_DIN_WIDTH-1:0]; + // Retreive the error injection type. Based on the error injection type + // corrupt the output data. + tmp_ecc_err = ecc_err[rd_ptr]; + if (ENABLE_ERR_INJECTION && C_DIN_WIDTH == C_DOUT_WIDTH) begin + if (tmp_ecc_err[1]) begin // Corrupt the output data only for double bit error + if (C_DOUT_WIDTH == 1) begin + $display("FAILURE : Data width must be >= 2 for double bit error injection."); + $finish; + end else if (C_DOUT_WIDTH == 2) + tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2]}; + else + tmp_dout = {~tmp_dout[C_DOUT_WIDTH-1],~tmp_dout[C_DOUT_WIDTH-2],(tmp_dout << 2)}; + end else begin + tmp_dout = tmp_dout[C_DOUT_WIDTH-1:0]; + end + err_type <= {tmp_ecc_err[1], tmp_ecc_err[0] & !tmp_ecc_err[1]}; + end else begin + err_type <= 0; + end + + // input is wider than output + end else begin + rd_ptr_high = rd_ptr >> log2_reads_per_write; + rd_ptr_low = rd_ptr & (reads_per_write - 1); + memory_read = memory[rd_ptr_high]; + tmp_dout = memory_read >> (rd_ptr_low*C_DOUT_WIDTH); + end + ideal_dout <= tmp_dout; + + // (Works opposite to core: rd_ptr is a DOWN counter) + if (rd_ptr == 0) begin + rd_ptr <= C_RD_DEPTH - 1; + end else begin + rd_ptr <= rd_ptr - 1; + end + end + endtask + + /************************************************************************** + * log2_val + * Returns the 'log2' value for the input value for the supported ratios + ***************************************************************************/ + function [31:0] log2_val; + input [31:0] binary_val; + + begin + if (binary_val == 8) begin + log2_val = 3; + end else if (binary_val == 4) begin + log2_val = 2; + end else begin + log2_val = 1; + end + end + endfunction + + /*********************************************************************** + * hexstr_conv + * Converts a string of type hex to a binary value (for C_DOUT_RST_VAL) + ***********************************************************************/ + function [C_DOUT_WIDTH-1:0] hexstr_conv; + input [(C_DOUT_WIDTH*8)-1:0] def_data; + + integer index,i,j; + reg [3:0] bin; + + begin + index = 0; + hexstr_conv = 'b0; + for( i=C_DOUT_WIDTH-1; i>=0; i=i-1 ) + begin + case (def_data[7:0]) + 8'b00000000 : + begin + bin = 4'b0000; + i = -1; + end + 8'b00110000 : bin = 4'b0000; + 8'b00110001 : bin = 4'b0001; + 8'b00110010 : bin = 4'b0010; + 8'b00110011 : bin = 4'b0011; + 8'b00110100 : bin = 4'b0100; + 8'b00110101 : bin = 4'b0101; + 8'b00110110 : bin = 4'b0110; + 8'b00110111 : bin = 4'b0111; + 8'b00111000 : bin = 4'b1000; + 8'b00111001 : bin = 4'b1001; + 8'b01000001 : bin = 4'b1010; + 8'b01000010 : bin = 4'b1011; + 8'b01000011 : bin = 4'b1100; + 8'b01000100 : bin = 4'b1101; + 8'b01000101 : bin = 4'b1110; + 8'b01000110 : bin = 4'b1111; + 8'b01100001 : bin = 4'b1010; + 8'b01100010 : bin = 4'b1011; + 8'b01100011 : bin = 4'b1100; + 8'b01100100 : bin = 4'b1101; + 8'b01100101 : bin = 4'b1110; + 8'b01100110 : bin = 4'b1111; + default : + begin + bin = 4'bx; + end + endcase + for( j=0; j<4; j=j+1) + begin + if ((index*4)+j < C_DOUT_WIDTH) + begin + hexstr_conv[(index*4)+j] = bin[j]; + end + end + index = index + 1; + def_data = def_data >> 8; + end + end + endfunction + + /************************************************************************* + * Initialize Signals for clean power-on simulation + *************************************************************************/ + initial begin + num_wr_bits = 0; + num_rd_bits = 0; + next_num_wr_bits = 0; + next_num_rd_bits = 0; + rd_ptr = C_RD_DEPTH - 1; + wr_ptr = C_WR_DEPTH - 1; + wr_pntr = 0; + rd_pntr = 0; + rd_ptr_wrclk = rd_ptr; + wr_ptr_rdclk = wr_ptr; + dout_reset_val = hexstr_conv(C_DOUT_RST_VAL); + ideal_dout = dout_reset_val; + err_type = 0; + err_type_d1 = 0; + err_type_both = 0; + ideal_dout_d1 = dout_reset_val; + ideal_wr_ack = 1'b0; + ideal_valid = 1'b0; + valid_d1 = 1'b0; + valid_d2 = 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]; + + //*************************************************************************** + // Safety-ckt logic with embedded reg/fabric reg + //*************************************************************************** + generate + if ((C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1) && C_EN_SAFETY_CKT==1 && C_USE_EMBEDDED_REG < 3) begin + + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d1; + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d2; + reg [1:0] rst_delayed_sft1 =1; + reg [1:0] rst_delayed_sft2 =1; + reg [1:0] rst_delayed_sft3 =1; + reg [1:0] rst_delayed_sft4 =1; + + // if (C_HAS_VALID == 1) begin + // assign valid_out = valid_d1; + // end + + always@(posedge RD_CLK) + begin + rst_delayed_sft1 <= #`TCQ rd_rst_i; + rst_delayed_sft2 <= #`TCQ rst_delayed_sft1; + rst_delayed_sft3 <= #`TCQ rst_delayed_sft2; + rst_delayed_sft4 <= #`TCQ rst_delayed_sft3; + end + always@(posedge rst_delayed_sft4 or posedge rd_rst_i or posedge RD_CLK) + begin + if( rst_delayed_sft4 == 1'b1 || rd_rst_i == 1'b1) + ram_rd_en_d1 <= #`TCQ 1'b0; + else + ram_rd_en_d1 <= #`TCQ ram_rd_en; + end + + always@(posedge rst_delayed_sft2 or posedge RD_CLK) + begin + if (rst_delayed_sft2 == 1'b1) begin + if (C_USE_DOUT_RST == 1'b1) begin + @(posedge RD_CLK) + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + end + else begin + if (ram_rd_en_d1) begin + ideal_dout_d1 <= #`TCQ ideal_dout; + err_type_d1[0] <= #`TCQ err_type[0]; + err_type_d1[1] <= #`TCQ err_type[1]; + end + end + end + end + endgenerate + +//*************************************************************************** + // Safety-ckt logic with embedded reg + fabric reg + //*************************************************************************** + generate + if ((C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1) && C_EN_SAFETY_CKT==1 && C_USE_EMBEDDED_REG == 3) begin + + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d1; + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d2; + reg [1:0] rst_delayed_sft1 =1; + reg [1:0] rst_delayed_sft2 =1; + reg [1:0] rst_delayed_sft3 =1; + reg [1:0] rst_delayed_sft4 =1; + + always@(posedge RD_CLK) begin + rst_delayed_sft1 <= #`TCQ rd_rst_i; + rst_delayed_sft2 <= #`TCQ rst_delayed_sft1; + rst_delayed_sft3 <= #`TCQ rst_delayed_sft2; + rst_delayed_sft4 <= #`TCQ rst_delayed_sft3; + end + always@(posedge rst_delayed_sft4 or posedge rd_rst_i or posedge RD_CLK) begin + if( rst_delayed_sft4 == 1'b1 || rd_rst_i == 1'b1) + ram_rd_en_d1 <= #`TCQ 1'b0; + else begin + ram_rd_en_d1 <= #`TCQ ram_rd_en; + fab_rd_en_d1 <= #`TCQ ram_rd_en_d1; + end + end + + always@(posedge rst_delayed_sft2 or posedge RD_CLK) begin + if (rst_delayed_sft2 == 1'b1) begin + if (C_USE_DOUT_RST == 1'b1) begin + @(posedge RD_CLK) + ideal_dout_d1 <= #`TCQ dout_reset_val; + ideal_dout_both <= #`TCQ dout_reset_val; + end + end else begin + if (ram_rd_en_d1) begin + ideal_dout_both <= #`TCQ ideal_dout; + err_type_both[0] <= #`TCQ err_type[0]; + err_type_both[1] <= #`TCQ err_type[1]; + end + + if (fab_rd_en_d1) begin + ideal_dout_d1 <= #`TCQ ideal_dout_both; + err_type_d1[0] <= #`TCQ err_type_both[0]; + err_type_d1[1] <= #`TCQ err_type_both[1]; + end + end + end + end + endgenerate + + //*************************************************************************** + // 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_out1 = (C_PRELOAD_LATENCY==2 && + (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1) && C_USE_EMBEDDED_REG < 3)? + valid_d1: valid_i; + assign valid_out2 = (C_PRELOAD_LATENCY==2 && + (C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1) && C_USE_EMBEDDED_REG == 3)? + valid_d2: valid_i; + assign valid_out = (C_USE_EMBEDDED_REG == 3) ? valid_out2 : valid_out1; + 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 <= 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_USE_EMBEDDED_REG < 3) begin: rdc_fwft_ext_both + 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 <= 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 + end + endgenerate + + + generate if (C_USE_EMBEDDED_REG == 3) begin + 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}; + wire [C_RD_PNTR_WIDTH:0] diff_rd_wr_1; + // assign diff_rd_wr_1 = diff_rd_wr +2'h2; + + 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 (fab_read_data_valid_i == 1'b0 && ((ram_valid_i == 1'b0 && read_data_valid_i ==1'b0) || (ram_valid_i == 1'b0 && read_data_valid_i ==1'b1) || (ram_valid_i == 1'b1 && read_data_valid_i ==1'b0) || (ram_valid_i == 1'b1 && read_data_valid_i ==1'b1))) + // rdc_fwft_ext_as <= 1'b0; + //else if (fab_read_data_valid_i == 1'b1 && ((ram_valid_i == 1'b0 && read_data_valid_i ==1'b0) || (ram_valid_i == 1'b0 && read_data_valid_i ==1'b1))) + // rdc_fwft_ext_as <= 1'b1; + //else + rdc_fwft_ext_as <= diff_rd_wr + 2'h2 ; + end + + + +end +end +end +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 <= 1'b0; + valid_d2 <= 1'b0; + end else begin + valid_d1 <= #`TCQ valid_i; + valid_d2 <= #`TCQ valid_d1; + end +// if (C_USE_EMBEDDED_REG == 3 && (C_EN_SAFETY_CKT == 0 || C_EN_SAFETY_CKT == 1 ) begin + // valid_d2 <= #`TCQ valid_d1; + // end + end + end + endgenerate + + //Capture delayed version of dout + /************************************************************************** + *embedded/fabric reg with no safety ckt + **************************************************************************/ + generate + if (C_USE_EMBEDDED_REG < 3) begin + always @(posedge RD_CLK or posedge rd_rst_i) begin + if (rd_rst_i == 1'b1) begin + if (C_USE_DOUT_RST == 1'b1) begin + @(posedge RD_CLK) + ideal_dout_d1 <= #`TCQ dout_reset_val; + ideal_dout <= #`TCQ dout_reset_val; + end + // 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 + +end +endgenerate +/************************************************************************** + *embedded + fabric reg with no safety ckt + **************************************************************************/ + +generate + if (C_USE_EMBEDDED_REG == 3) begin + always @(posedge RD_CLK or posedge rd_rst_i) begin + if (rd_rst_i == 1'b1) begin + if (C_USE_DOUT_RST == 1'b1) begin + @(posedge RD_CLK) + ideal_dout <= #`TCQ dout_reset_val; + ideal_dout_d1 <= #`TCQ dout_reset_val; + ideal_dout_both <= #`TCQ dout_reset_val; + end + // Reset err_type only if ECC is not selected + if (C_USE_ECC == 0) begin + err_type_d1 <= #`TCQ 0; + err_type_both <= #`TCQ 0; + end + end else begin + if (ram_rd_en_d1) begin + ideal_dout_both <= #`TCQ ideal_dout; + err_type_both <= #`TCQ err_type; + end + if (fab_rd_en_d1) begin + ideal_dout_d1 <= #`TCQ ideal_dout_both; + err_type_d1 <= #`TCQ err_type_both; + end + end + end + end +endgenerate + + + /************************************************************************** + * 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_v13_2_5_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_v13_2_5_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_wp + if (wr_rst_i == 1'b1 && C_EN_SAFETY_CKT == 0) + wr_pntr <= 0; + else if (C_EN_SAFETY_CKT == 1 && SAFETY_CKT_WR_RST == 1'b1) + wr_pntr <= #`TCQ 0; + end + 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 <= 0; + next_num_wr_bits = 0; + wr_ptr <= C_WR_DEPTH - 1; + rd_ptr_wrclk <= C_RD_DEPTH - 1; + ideal_wr_ack <= 0; + ideal_wr_count <= 0; + tmp_wr_listsize = 0; + rd_ptr_wrclk_next <= 0; + wr_pntr_rd1 <= 0; + + end else begin //wr_rst_i==0 + + wr_pntr_rd1 <= #`TCQ wr_pntr; + + //Determine the current number of words in the FIFO + tmp_wr_listsize = (C_DEPTH_RATIO_RD > 1) ? num_wr_bits/C_DOUT_WIDTH : + num_wr_bits/C_DIN_WIDTH; + rd_ptr_wrclk_next = rd_ptr; + if (rd_ptr_wrclk < rd_ptr_wrclk_next) begin + next_num_wr_bits = num_wr_bits - + C_DOUT_WIDTH*(rd_ptr_wrclk + C_RD_DEPTH + - rd_ptr_wrclk_next); + end else begin + next_num_wr_bits = num_wr_bits - + C_DOUT_WIDTH*(rd_ptr_wrclk - rd_ptr_wrclk_next); + end + + //If this is a write, handle the write by adding the value + // to the linked list, and updating all outputs appropriately + if (WR_EN == 1'b1) begin + if (FULL == 1'b1) begin + + //If the FIFO is full, do NOT perform the write, + // update flags accordingly + if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD + >= C_FIFO_WR_DEPTH) begin + //write unsuccessful - do not change contents + + //Do not acknowledge the write + ideal_wr_ack <= #`TCQ 0; + //Reminder that FIFO is still full + + ideal_wr_count <= #`TCQ num_write_words_sized_i; + + //If the FIFO is one from full, but reporting full + end else + if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD == + C_FIFO_WR_DEPTH-1) begin + //No change to FIFO + + //Write not successful + ideal_wr_ack <= #`TCQ 0; + //With DEPTH-1 words in the FIFO, it is almost_full + + ideal_wr_count <= #`TCQ num_write_words_sized_i; + + + //If the FIFO is completely empty, but it is + // reporting FULL for some reason (like reset) + end else + if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD <= + C_FIFO_WR_DEPTH-2) begin + //No change to FIFO + + //Write not successful + ideal_wr_ack <= #`TCQ 0; + //FIFO is really not close to full, so change flag status. + + ideal_wr_count <= #`TCQ num_write_words_sized_i; + end //(tmp_wr_listsize == 0) + + end else begin + + //If the FIFO is full, do NOT perform the write, + // update flags accordingly + if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD >= + C_FIFO_WR_DEPTH) begin + //write unsuccessful - do not change contents + + //Do not acknowledge the write + ideal_wr_ack <= #`TCQ 0; + //Reminder that FIFO is still full + + ideal_wr_count <= #`TCQ num_write_words_sized_i; + + //If the FIFO is one from full + end else + if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD == + C_FIFO_WR_DEPTH-1) begin + //Add value on DIN port to FIFO + write_fifo; + next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH; + + //Write successful, so issue acknowledge + // and no error + ideal_wr_ack <= #`TCQ 1; + //This write is CAUSING the FIFO to go full + + ideal_wr_count <= #`TCQ num_write_words_sized_i; + + //If the FIFO is 2 from full + end else + if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD == + C_FIFO_WR_DEPTH-2) begin + //Add value on DIN port to FIFO + write_fifo; + next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH; + //Write successful, so issue acknowledge + // and no error + ideal_wr_ack <= #`TCQ 1; + //Still 2 from full + + ideal_wr_count <= #`TCQ num_write_words_sized_i; + + //If the FIFO is not close to being full + end else + if ((tmp_wr_listsize + C_DEPTH_RATIO_RD - 1)/C_DEPTH_RATIO_RD < + C_FIFO_WR_DEPTH-2) begin + //Add value on DIN port to FIFO + write_fifo; + next_num_wr_bits = next_num_wr_bits + C_DIN_WIDTH; + //Write successful, so issue acknowledge + // and no error + ideal_wr_ack <= #`TCQ 1; + //Not even close to full. + + ideal_wr_count <= num_write_words_sized_i; + + end + + end + + end else begin //(WR_EN == 1'b1) + + //If user did not attempt a write, then do not + // give ack or err + ideal_wr_ack <= #`TCQ 0; + ideal_wr_count <= #`TCQ num_write_words_sized_i; + end + num_wr_bits <= #`TCQ next_num_wr_bits; + rd_ptr_wrclk <= #`TCQ rd_ptr; + + end //wr_rst_i==0 + end // gen_fifo_w + + + /*************************************************************************** + * Programmable FULL flags + ***************************************************************************/ + + wire [C_WR_PNTR_WIDTH-1:0] pf_thr_assert_val; + wire [C_WR_PNTR_WIDTH-1:0] pf_thr_negate_val; + + generate if (C_PRELOAD_REGS == 1 && C_PRELOAD_LATENCY == 0) begin : FWFT + assign pf_thr_assert_val = C_PROG_FULL_THRESH_ASSERT_VAL - EXTRA_WORDS_DC; + assign pf_thr_negate_val = C_PROG_FULL_THRESH_NEGATE_VAL - EXTRA_WORDS_DC; + end else begin // STD + assign pf_thr_assert_val = C_PROG_FULL_THRESH_ASSERT_VAL; + assign pf_thr_negate_val = C_PROG_FULL_THRESH_NEGATE_VAL; + end endgenerate + + always @(posedge WR_CLK or posedge wr_rst_i) begin + + if (wr_rst_i == 1'b1) begin + diff_pntr <= 0; + end else begin + if (ram_wr_en) + diff_pntr <= #`TCQ (wr_pntr - adj_rd_pntr_wr + 2'h1); + else if (!ram_wr_en) + diff_pntr <= #`TCQ (wr_pntr - adj_rd_pntr_wr); + end + end + + + always @(posedge WR_CLK or posedge RST_FULL_FF) begin : gen_pf + + if (RST_FULL_FF & C_HAS_RST) begin + ideal_prog_full <= C_FULL_FLAGS_RST_VAL; + end else if (SAFETY_CKT_WR_RST & C_EN_SAFETY_CKT) begin + ideal_prog_full <= 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 & C_HAS_RST) begin + diff_pntr_rd <= 0; + ideal_prog_empty <= 1'b1; + end else if (SAFETY_CKT_RD_RST & C_EN_SAFETY_CKT) begin + diff_pntr_rd <= 0; + ideal_prog_empty <= 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 + + always @(posedge RD_CLK or posedge rd_rst_i) begin : gen_fifo_rp + if (rd_rst_i && C_EN_SAFETY_CKT == 0) + rd_pntr <= 0; + else if (C_EN_SAFETY_CKT == 1 && SAFETY_CKT_RD_RST == 1'b1) + rd_pntr <= #`TCQ 0; + end + + always @(posedge RD_CLK or posedge rd_rst_i) begin : gen_fifo_r_as + + /****** Reset fifo (case 1)***************************************/ + if (rd_rst_i & C_HAS_RST) begin + num_rd_bits <= 0; + next_num_rd_bits = 0; + rd_ptr <= C_RD_DEPTH -1; + rd_pntr_wr1 <= 0; + wr_ptr_rdclk <= C_WR_DEPTH -1; + + // DRAM resets asynchronously + if (C_MEMORY_TYPE == 2 && C_USE_DOUT_RST == 1) + ideal_dout <= dout_reset_val; + + // Reset err_type only if ECC is not selected + if (C_USE_ECC == 0) begin + err_type <= 0; + err_type_d1 <= 0; + err_type_both <= 0; + end + ideal_valid <= 1'b0; + ideal_rd_count <= 0; + + end else if (SAFETY_CKT_RD_RST & C_EN_SAFETY_CKT) begin + num_rd_bits <= 0; + next_num_rd_bits = 0; + rd_ptr <= C_RD_DEPTH -1; + rd_pntr_wr1 <= 0; + wr_ptr_rdclk <= C_WR_DEPTH -1; + + // DRAM resets asynchronously + if (C_MEMORY_TYPE == 2 && C_USE_DOUT_RST == 1) + ideal_dout <= dout_reset_val; + + // Reset err_type only if ECC is not selected + if (C_USE_ECC == 0) begin + err_type <= 0; + err_type_d1 <= 0; + err_type_both <= 0; + end + ideal_valid <= 1'b0; + ideal_rd_count <= 0; + end else begin //rd_rst_i==0 + + rd_pntr_wr1 <= #`TCQ rd_pntr; + + //Determine the current number of words in the FIFO + tmp_rd_listsize = (C_DEPTH_RATIO_WR > 1) ? num_rd_bits/C_DIN_WIDTH : + num_rd_bits/C_DOUT_WIDTH; + wr_ptr_rdclk_next = wr_ptr; + + if (wr_ptr_rdclk < wr_ptr_rdclk_next) begin + next_num_rd_bits = num_rd_bits + + C_DIN_WIDTH*(wr_ptr_rdclk +C_WR_DEPTH + - wr_ptr_rdclk_next); + end else begin + next_num_rd_bits = num_rd_bits + + C_DIN_WIDTH*(wr_ptr_rdclk - wr_ptr_rdclk_next); + end + + /*****************************************************************/ + // Read Operation - Read Latency 1 + /*****************************************************************/ + if (C_PRELOAD_LATENCY==1 || C_PRELOAD_LATENCY==2) begin + ideal_valid <= #`TCQ 1'b0; + + if (ram_rd_en == 1'b1) begin + + if (EMPTY == 1'b1) begin + + //If the FIFO is completely empty, and is reporting empty + if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0) + begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + //Reminder that FIFO is still empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + end // if (tmp_rd_listsize <= 0) + + //If the FIFO is one from empty, but it is reporting empty + else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1) + begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + //Note that FIFO is no longer empty, but is almost empty (has one word left) + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if (tmp_rd_listsize == 1) + + //If the FIFO is two from empty, and is reporting empty + else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2) + begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + //Fifo has two words, so is neither empty or almost empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if (tmp_rd_listsize == 2) + + //If the FIFO is not close to empty, but is reporting that it is + // Treat the FIFO as empty this time, but unset EMPTY flags. + if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) && (tmp_rd_listsize/C_DEPTH_RATIO_WR<C_FIFO_RD_DEPTH)) + begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + //Note that the FIFO is No Longer Empty or Almost Empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1)) + end // else: if(ideal_empty == 1'b1) + + else //if (ideal_empty == 1'b0) + begin + + //If the FIFO is completely full, and we are successfully reading from it + if (tmp_rd_listsize/C_DEPTH_RATIO_WR >= C_FIFO_RD_DEPTH) + begin + //Read the value from the FIFO + read_fifo; + next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; + + //Acknowledge the read from the FIFO, no error + ideal_valid <= #`TCQ 1'b1; + //Not close to empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if (tmp_rd_listsize == C_FIFO_RD_DEPTH) + + //If the FIFO is not close to being empty + else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) && (tmp_rd_listsize/C_DEPTH_RATIO_WR<=C_FIFO_RD_DEPTH)) + begin + //Read the value from the FIFO + read_fifo; + next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; + + //Acknowledge the read from the FIFO, no error + ideal_valid <= #`TCQ 1'b1; + //Not close to empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1)) + + //If the FIFO is two from empty + else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2) + begin + //Read the value from the FIFO + read_fifo; + next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; + + //Acknowledge the read from the FIFO, no error + ideal_valid <= #`TCQ 1'b1; + //Fifo is not yet empty. It is going almost_empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if (tmp_rd_listsize == 2) + + //If the FIFO is one from empty + else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR == 1)) + begin + //Read the value from the FIFO + read_fifo; + next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; + + //Acknowledge the read from the FIFO, no error + ideal_valid <= #`TCQ 1'b1; + //Note that FIFO is GOING empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if (tmp_rd_listsize == 1) + + + //If the FIFO is completely empty + else if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0) + begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if (tmp_rd_listsize <= 0) + + end // if (ideal_empty == 1'b0) + + end //(RD_EN == 1'b1) + + else //if (RD_EN == 1'b0) + begin + //If user did not attempt a read, do not give an ack or err + ideal_valid <= #`TCQ 1'b0; + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // else: !if(RD_EN == 1'b1) + + /*****************************************************************/ + // Read Operation - Read Latency 0 + /*****************************************************************/ + end else if (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) begin + ideal_valid <= #`TCQ 1'b0; + if (ram_rd_en == 1'b1) begin + + if (EMPTY == 1'b1) begin + + //If the FIFO is completely empty, and is reporting empty + if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0) begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + //Reminder that FIFO is still empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + //If the FIFO is one from empty, but it is reporting empty + end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1) begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + //Note that FIFO is no longer empty, but is almost empty (has one word left) + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + //If the FIFO is two from empty, and is reporting empty + end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2) begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + //Fifo has two words, so is neither empty or almost empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + //If the FIFO is not close to empty, but is reporting that it is + // Treat the FIFO as empty this time, but unset EMPTY flags. + end else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) && + (tmp_rd_listsize/C_DEPTH_RATIO_WR<C_FIFO_RD_DEPTH)) begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + //Note that the FIFO is No Longer Empty or Almost Empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if ((tmp_rd_listsize > 2) && (tmp_rd_listsize<=C_FIFO_RD_DEPTH-1)) + + end else begin + + //If the FIFO is completely full, and we are successfully reading from it + if (tmp_rd_listsize/C_DEPTH_RATIO_WR >= C_FIFO_RD_DEPTH) begin + //Read the value from the FIFO + read_fifo; + next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; + + //Acknowledge the read from the FIFO, no error + ideal_valid <= #`TCQ 1'b1; + //Not close to empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + //If the FIFO is not close to being empty + end else if ((tmp_rd_listsize/C_DEPTH_RATIO_WR > 2) && + (tmp_rd_listsize/C_DEPTH_RATIO_WR<=C_FIFO_RD_DEPTH)) begin + //Read the value from the FIFO + read_fifo; + next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; + + //Acknowledge the read from the FIFO, no error + ideal_valid <= #`TCQ 1'b1; + //Not close to empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + //If the FIFO is two from empty + end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 2) begin + //Read the value from the FIFO + read_fifo; + next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; + + //Acknowledge the read from the FIFO, no error + ideal_valid <= #`TCQ 1'b1; + //Fifo is not yet empty. It is going almost_empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + //If the FIFO is one from empty + end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR == 1) begin + //Read the value from the FIFO + read_fifo; + next_num_rd_bits = next_num_rd_bits - C_DOUT_WIDTH; + + //Acknowledge the read from the FIFO, no error + ideal_valid <= #`TCQ 1'b1; + //Note that FIFO is GOING empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + //If the FIFO is completely empty + end else if (tmp_rd_listsize/C_DEPTH_RATIO_WR <= 0) begin + //Do not change the contents of the FIFO + + //Do not acknowledge the read from empty FIFO + ideal_valid <= #`TCQ 1'b0; + //Reminder that FIFO is still empty + + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // if (tmp_rd_listsize <= 0) + + end // if (ideal_empty == 1'b0) + + end else begin//(RD_EN == 1'b0) + + + //If user did not attempt a read, do not give an ack or err + ideal_valid <= #`TCQ 1'b0; + ideal_rd_count <= #`TCQ num_read_words_sized_i; + + end // else: !if(RD_EN == 1'b1) + end //if (C_PRELOAD_REGS==1 && C_PRELOAD_LATENCY==0) + + num_rd_bits <= #`TCQ next_num_rd_bits; + wr_ptr_rdclk <= #`TCQ wr_ptr; + end //rd_rst_i==0 + end //always gen_fifo_r_as + +endmodule // fifo_generator_v13_2_5_bhv_ver_as + + +/******************************************************************************* + * Declaration of Low Latency Asynchronous FIFO + ******************************************************************************/ +module fifo_generator_v13_2_5_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_v13_2_5_beh_ver_ll_afifo + +/******************************************************************************* + * Declaration of top-level module + ******************************************************************************/ +module fifo_generator_v13_2_5_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_EN_SAFETY_CKT = 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 SAFETY_CKT_WR_RST, + 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 reg EMPTY_FB = 1'b1, + 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 == "virtexuplus" || C_FAMILY == "zynquplus" || C_FAMILY == "kintexuplus" || C_FAMILY == "virtexuplushbm") ? 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 C_USE_ECC_1 = (C_USE_ECC == 1 || C_USE_ECC ==2) ? 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; + reg ram_rd_en_d1 = 1'b0; + reg fab_rd_en_d1 = 1'b0; + wire srst_rrst_busy; + + + + //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 [1:0] err_type_both = 0; + reg [C_DOUT_WIDTH-1:0] ideal_dout = 0; + reg [C_DOUT_WIDTH-1:0] ideal_dout_d1 = 0; + reg [C_DOUT_WIDTH-1:0] ideal_dout_both = 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; + reg valid_both = 0; + reg valid_d2 = 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; + err_type_d1 = 0; + err_type_both = 0; + ideal_dout_d1 = dout_reset_val; + ideal_dout_both = dout_reset_val; + ideal_wr_ack = 1'b0; + ideal_valid = 1'b0; + valid_d1 = 1'b0; + valid_both = 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 + localparam C_FWFT_ENABLED = (C_PRELOAD_LATENCY == 0 && C_PRELOAD_REGS == 1)? + 1: 0; + assign fwft_enabled = (C_PRELOAD_LATENCY == 0 && C_PRELOAD_REGS == 1)? + 1: 0; + assign ideal_dout_out= ((C_USE_EMBEDDED_REG>0 && (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>0 && (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>0 && (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; + //saftey_ckt with one register + + generate + if ((C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1) && C_EN_SAFETY_CKT==1 && (C_USE_EMBEDDED_REG == 1 || C_USE_EMBEDDED_REG == 2 )) begin + + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d1; + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d2; + reg [1:0] rst_delayed_sft1 =1; + reg [1:0] rst_delayed_sft2 =1; + reg [1:0] rst_delayed_sft3 =1; + reg [1:0] rst_delayed_sft4 =1; + + always@(posedge CLK) + begin + rst_delayed_sft1 <= #`TCQ rst_i; + rst_delayed_sft2 <= #`TCQ rst_delayed_sft1; + rst_delayed_sft3 <= #`TCQ rst_delayed_sft2; + rst_delayed_sft4 <= #`TCQ rst_delayed_sft3; + end + always@(posedge rst_delayed_sft2 or posedge rst_i or posedge CLK) + begin + if( rst_delayed_sft2 == 1'b1 || rst_i == 1'b1) begin + ram_rd_en_d1 <= #`TCQ 1'b0; + valid_d1 <= #`TCQ 1'b0; + end + else begin + ram_rd_en_d1 <= #`TCQ (RD_EN && ~(empty_i)); + valid_d1 <= #`TCQ valid_i; + end + end + + always@(posedge rst_delayed_sft2 or posedge CLK) + begin + if (rst_delayed_sft2 == 1'b1) begin + if (C_USE_DOUT_RST == 1'b1) begin + @(posedge CLK) + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + end + else if (srst_rrst_busy == 1'b1) begin + if (C_USE_DOUT_RST == 1'b1) begin + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + end else if (ram_rd_en_d1) begin + ideal_dout_d1 <= #`TCQ ideal_dout; + err_type_d1[0] <= #`TCQ err_type[0]; + err_type_d1[1] <= #`TCQ err_type[1]; + end + end + end //if + endgenerate + +//safety ckt with both registers + +generate + if ((C_MEMORY_TYPE==0 || C_MEMORY_TYPE==1) && C_EN_SAFETY_CKT==1 && C_USE_EMBEDDED_REG == 3) begin + + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d1; + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d2; + reg [1:0] rst_delayed_sft1 =1; + reg [1:0] rst_delayed_sft2 =1; + reg [1:0] rst_delayed_sft3 =1; + reg [1:0] rst_delayed_sft4 =1; + + always@(posedge CLK) begin + rst_delayed_sft1 <= #`TCQ rst_i; + rst_delayed_sft2 <= #`TCQ rst_delayed_sft1; + rst_delayed_sft3 <= #`TCQ rst_delayed_sft2; + rst_delayed_sft4 <= #`TCQ rst_delayed_sft3; + end + always@(posedge rst_delayed_sft2 or posedge rst_i or posedge CLK) begin + if (rst_delayed_sft2 == 1'b1 || rst_i == 1'b1) begin + ram_rd_en_d1 <= #`TCQ 1'b0; + valid_d1 <= #`TCQ 1'b0; + end else begin + ram_rd_en_d1 <= #`TCQ (RD_EN && ~(empty_i)); + fab_rd_en_d1 <= #`TCQ ram_rd_en_d1; + valid_both <= #`TCQ valid_i; + valid_d1 <= #`TCQ valid_both; + end + end + + always@(posedge rst_delayed_sft2 or posedge CLK) begin + if (rst_delayed_sft2 == 1'b1) begin + if (C_USE_DOUT_RST == 1'b1) begin + @(posedge CLK) + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + end else if (srst_rrst_busy == 1'b1) begin + if (C_USE_DOUT_RST == 1'b1) begin + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + end else begin + if (ram_rd_en_d1) begin + ideal_dout_both <= #`TCQ ideal_dout; + err_type_both[0] <= #`TCQ err_type[0]; + err_type_both[1] <= #`TCQ err_type[1]; + end + if (fab_rd_en_d1) begin + ideal_dout_d1 <= #`TCQ ideal_dout_both; + err_type_d1[0] <= #`TCQ err_type_both[0]; + err_type_d1[1] <= #`TCQ err_type_both[1]; + end + end + end + end //if + endgenerate + + + //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_EN_SAFETY_CKT ? SAFETY_CKT_WR_RST : C_HAS_SRST ? (SRST | WR_RST_BUSY) : 0; + assign rst_i = C_HAS_RST ? RST : 0; + assign srst_wrst_busy = srst_i; + assign srst_rrst_busy = srst_i; + + /************************************************************************** + * Assorted registers for delayed versions of signals + **************************************************************************/ + //Capture delayed version of valid + generate if (C_HAS_VALID == 1 && (C_USE_EMBEDDED_REG <3)) begin : blockVL20 + always @(posedge CLK or posedge rst_i) begin + if (rst_i == 1'b1) begin + valid_d1 <= 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 + + generate if (C_HAS_VALID == 1 && (C_USE_EMBEDDED_REG == 3)) begin + always @(posedge CLK or posedge rst_i) begin + if (rst_i == 1'b1) begin + valid_d1 <= 1'b0; + valid_both <= 1'b0; + end else begin + if (srst_rrst_busy) begin + valid_d1 <= #`TCQ 1'b0; + valid_both <= #`TCQ 1'b0; + + end else begin + valid_both <= #`TCQ valid_i; + valid_d1 <= #`TCQ valid_both; + 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 + + //reg ram_rd_en_d1 = 1'b0; + //Capture delayed version of dout + generate if (C_EN_SAFETY_CKT == 0 && (C_USE_EMBEDDED_REG<3)) begin + 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) begin + err_type_d1 <= #`TCQ 0; + err_type_both <= #`TCQ 0; + end + // DRAM and SRAM reset asynchronously + if ((C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3) && C_USE_DOUT_RST == 1) begin + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + ram_rd_en_d1 <= #`TCQ 1'b0; + if (C_USE_DOUT_RST == 1) begin + @(posedge CLK) + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + 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) begin + err_type_d1 <= #`TCQ 0; + err_type_both <= #`TCQ 0; + end + // 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) begin + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + if (C_USE_DOUT_RST == 1) begin + // @(posedge CLK) + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + end else begin + if (ram_rd_en_d1 ) begin + ideal_dout_d1 <= #`TCQ ideal_dout; + err_type_d1 <= #`TCQ err_type; + end + end + end + end // always +end +endgenerate + +//no safety ckt with both registers + generate if (C_EN_SAFETY_CKT == 0 && (C_USE_EMBEDDED_REG==3)) begin + always @(posedge CLK or posedge rst_i) begin + if (rst_i == 1'b1) begin + ram_rd_en_d1 <= #`TCQ 1'b0; + fab_rd_en_d1 <= #`TCQ 1'b0; + // Reset err_type only if ECC is not selected + if (C_USE_ECC == 0) begin + err_type_d1 <= #`TCQ 0; + err_type_both <= #`TCQ 0; + end + // DRAM and SRAM reset asynchronously + if ((C_MEMORY_TYPE == 2 || C_MEMORY_TYPE == 3) && C_USE_DOUT_RST == 1) begin + ideal_dout_d1 <= #`TCQ dout_reset_val; + ideal_dout_both <= #`TCQ dout_reset_val; + + end + if (C_USE_DOUT_RST == 1) begin + @(posedge CLK) + ideal_dout_d1 <= #`TCQ dout_reset_val; + ideal_dout_both <= #`TCQ dout_reset_val; + end + end else begin + if (srst_rrst_busy) begin + ram_rd_en_d1 <= #`TCQ 1'b0; + fab_rd_en_d1 <= #`TCQ 1'b0; + // Reset err_type only if ECC is not selected + if (C_USE_ECC == 0) begin + err_type_d1 <= #`TCQ 0; + err_type_both <= #`TCQ 0; + end + // 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) begin + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + if (C_USE_DOUT_RST == 1) begin + ideal_dout_d1 <= #`TCQ dout_reset_val; + end + end else begin + ram_rd_en_d1 <= #`TCQ RD_EN & ~EMPTY; + fab_rd_en_d1 <= #`TCQ (ram_rd_en_d1); + if (ram_rd_en_d1 ) begin + ideal_dout_both <= #`TCQ ideal_dout; + err_type_both <= #`TCQ err_type; + end + if (fab_rd_en_d1 ) begin + ideal_dout_d1 <= #`TCQ ideal_dout_both; + err_type_d1 <= #`TCQ err_type_both; + end + end + end + end // always +end +endgenerate + /************************************************************************** + * 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 && C_EN_SAFETY_CKT == 0) begin + wr_pntr <= 0; + rd_pntr <= 0; + end else begin + if (srst_i) begin + wr_pntr <= #`TCQ 0; + 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) begin + ideal_dout <= #`TCQ dout_reset_val; + ideal_dout_both <= #`TCQ dout_reset_val; + end + 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) begin + err_type <= #`TCQ 0; + err_type_d1 <= 0; + err_type_both <= 0; + end + 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) begin + err_type <= #`TCQ 0; + err_type_d1 <= #`TCQ 0; + err_type_both <= #`TCQ 0; + end + 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); + + generate if (C_HAS_RST == 1) begin : grst_full + always @(posedge CLK or posedge RST_FULL_FF) begin + if (RST_FULL_FF & C_HAS_RST) + full_i <= C_FULL_FLAGS_RST_VAL; + else + full_i <= #`TCQ ram_full_comb; + end + end endgenerate + + generate if (C_HAS_SRST == 1) begin : gsrst_full + always @(posedge CLK) begin + if (srst_wrst_busy) + full_i <= #`TCQ C_FULL_FLAGS_RST_VAL; + else + full_i <= #`TCQ ram_full_comb; + end + end endgenerate + + generate if (C_HAS_RST == 0 && C_HAS_SRST == 0) begin : gnrst_full + always @(posedge CLK) begin + full_i <= #`TCQ ram_full_comb; + end + end endgenerate + + //----------------------------------------------------------------------------- + // 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 + always @(posedge CLK or posedge rst_i) begin + if (rst_i && C_EN_SAFETY_CKT == 0) begin + EMPTY_FB <= 1'b1; + end else begin + if (srst_rrst_busy || (SAFETY_CKT_WR_RST && C_EN_SAFETY_CKT)) + EMPTY_FB <= #`TCQ 1'b1; + else + EMPTY_FB <= #`TCQ ram_empty_comb; + end + end // always + + //----------------------------------------------------------------------------- + // 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); + + + generate if (C_HAS_RST == 1) begin : grst_afull + always @(posedge CLK or posedge RST_FULL_FF) begin + if (RST_FULL_FF & C_HAS_RST) + almost_full_i <= C_FULL_FLAGS_RST_VAL; + else + almost_full_i <= #`TCQ ram_afull_comb; + end + end endgenerate + + generate if (C_HAS_SRST == 1) begin : gsrst_afull + always @(posedge CLK) begin + if (srst_wrst_busy) + almost_full_i <= #`TCQ C_FULL_FLAGS_RST_VAL; + else + almost_full_i <= #`TCQ ram_afull_comb; + end + end endgenerate + + generate if (C_HAS_RST == 0 && C_HAS_SRST == 0) begin : gnrst_afull + always @(posedge CLK) begin + almost_full_i <= #`TCQ ram_afull_comb; + end + end endgenerate + + //----------------------------------------------------------------------------- + // 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_v13_2_5_bhv_ver_ss + + + +/************************************************************************** + * First-Word Fall-Through module (preload 0) + **************************************************************************/ +module fifo_generator_v13_2_5_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_EMBEDDED_REG = 0, + parameter C_EN_SAFETY_CKT = 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 SAFETY_CKT_RD_RST, + 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 fab_read_data_valid_i_o, + output read_data_valid_i_o, + output ram_valid_i_o, + output [1:0] VALID_STAGES + ); + //Internal signals + wire preloadstage1; + wire preloadstage2; + reg ram_valid_i; + reg fab_valid; + reg read_data_valid_i; + reg fab_read_data_valid_i; + reg fab_read_data_valid_i_1; + reg ram_valid_i_d; + reg read_data_valid_i_d; + reg fab_read_data_valid_i_d; + wire ram_regout_en; + reg ram_regout_en_d1; + reg ram_regout_en_d2; + wire fab_regout_en; + wire ram_rd_en; + reg empty_i = 1'b1; + reg empty_sckt = 1'b1; + reg sckt_rrst_q = 1'b0; + reg sckt_rrst_done = 1'b0; + 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; + reg [C_DOUT_WIDTH-1:0] userdata_both; + wire uservalid_both; + wire uservalid_one; + reg user_sbiterr_both = 1'b0; + reg user_dbiterr_both = 1'b0; + +assign ram_valid_i_o = ram_valid_i; +assign read_data_valid_i_o = read_data_valid_i; +assign fab_read_data_valid_i_o = fab_read_data_valid_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; + fab_valid = 1'b0; + read_data_valid_i = 1'b0; + fab_read_data_valid_i = 1'b0; + fab_read_data_valid_i_1 = 1'b0; + USERDATA = hexstr_conv(C_DOUT_RST_VAL); + userdata_both = hexstr_conv(C_DOUT_RST_VAL); + USERSBITERR = 1'b0; + USERDBITERR = 1'b0; + user_sbiterr_both = 1'b0; + user_dbiterr_both = 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_EN_SAFETY_CKT ? SAFETY_CKT_RD_RST : C_HAS_SRST ? SRST : 0; + + reg sckt_rd_rst_fwft = 1'b0; + reg fwft_rst_done_i = 1'b0; + wire fwft_rst_done; + assign fwft_rst_done = 1'b1;//C_EN_SAFETY_CKT ? fwft_rst_done_i : 1'b1; + always @ (posedge RD_CLK) begin + sckt_rd_rst_fwft <= #`TCQ SAFETY_CKT_RD_RST; + end + + always @ (posedge rd_rst_i or posedge RD_CLK) begin + if (rd_rst_i) + fwft_rst_done_i <= 1'b0; + else if (sckt_rd_rst_fwft & ~SAFETY_CKT_RD_RST) + fwft_rst_done_i <= #`TCQ 1'b1; + end + + 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_USE_EMBEDDED_REG < 3 && C_FIFO_TYPE != 2) begin + 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 && C_EN_SAFETY_CKT == 0) + 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; + ram_valid_i <= 1'b0; + end else if (srst_i) begin + empty_i <= #`TCQ 1'b1; + empty_i_q <= #`TCQ 1'b1; + 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; + ram_valid_i <= #`TCQ next_state; + end + end //always + + always @ (posedge RD_CLK or posedge rd_rst_i) begin + if (rd_rst_i && C_EN_SAFETY_CKT == 0) begin + curr_state <= 1'b0; + end else if (srst_i) begin + curr_state <= #`TCQ 1'b0; + end else begin + curr_state <= #`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_regout_en_d1 = ram_rd_en_fwft; + //assign ram_regout_en_d2 = 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. + //*************************************************************************** + + generate if(C_USE_EMBEDDED_REG < 3) begin + 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 +end +endgenerate + + + + //************************************************************************** + // 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 && C_USE_EMBEDDED_REG < 3) 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. + //*************************************************************************** + generate if ( C_USE_EMBEDDED_REG < 3) begin + 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 +end +endgenerate + + + + // BRAM resets synchronously + generate + if (C_EN_SAFETY_CKT==0 && C_USE_EMBEDDED_REG < 3) begin + always @ ( posedge rd_rst_i) + begin + if (rd_rst_i || srst_i) begin + if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2) + @(posedge RD_CLK) + 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) begin //asynchronous reset (active high) + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + end + 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) begin + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + end + end else if (fwft_rst_done) begin + if (ram_regout_en) begin + USERDATA <= #`TCQ FIFODATA; + USERSBITERR <= #`TCQ FIFOSBITERR; + USERDBITERR <= #`TCQ FIFODBITERR; + end + end + end + end //always + end //if + endgenerate +//safety ckt with one register +generate + if (C_EN_SAFETY_CKT==1 && C_USE_EMBEDDED_REG < 3) begin + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d1; + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d2; + reg [1:0] rst_delayed_sft1 =1; + reg [1:0] rst_delayed_sft2 =1; + reg [1:0] rst_delayed_sft3 =1; + reg [1:0] rst_delayed_sft4 =1; + + always@(posedge RD_CLK) + begin + rst_delayed_sft1 <= #`TCQ rd_rst_i; + rst_delayed_sft2 <= #`TCQ rst_delayed_sft1; + rst_delayed_sft3 <= #`TCQ rst_delayed_sft2; + rst_delayed_sft4 <= #`TCQ rst_delayed_sft3; + end + always @ (posedge RD_CLK) + begin + if (rd_rst_i || srst_i) begin + if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2 && rst_delayed_sft1 == 1'b1) begin + @(posedge RD_CLK) + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + end + 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)begin //asynchronous reset (active high) + //@(posedge RD_CLK) + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + end + 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) begin + // @(posedge RD_CLK) + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + end + end else if (fwft_rst_done) begin + if (ram_regout_en == 1'b1 && rd_rst_i == 1'b0) begin + USERDATA <= #`TCQ FIFODATA; + USERSBITERR <= #`TCQ FIFOSBITERR; + USERDBITERR <= #`TCQ FIFODBITERR; + end + end + end + end //always + end //if +endgenerate + + +generate if (C_USE_EMBEDDED_REG == 3 && C_FIFO_TYPE != 2) begin + + + 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 && C_EN_SAFETY_CKT == 0) + curr_fwft_state <= INVALID; + else if (srst_i) + curr_fwft_state <= #`TCQ INVALID; + else + curr_fwft_state <= #`TCQ next_fwft_state; + end + + always @ (posedge RD_CLK or posedge rd_rst_i) begin : proc_delay + if (rd_rst_i == 1) begin + ram_regout_en_d1 <= #`TCQ 1'b0; + end + else begin + if (srst_i == 1'b1) + ram_regout_en_d1 <= #`TCQ 1'b0; + else + ram_regout_en_d1 <= #`TCQ ram_regout_en; + end + end //always + // assign fab_regout_en = ((ram_regout_en_d1 & ~(ram_regout_en_d2) & empty_i) | (RD_EN & !empty_i)); + assign fab_regout_en = ((ram_valid_i == 1'b0 || ram_valid_i == 1'b1) && read_data_valid_i == 1'b1 && fab_read_data_valid_i == 1'b0 )? 1'b1: ((ram_valid_i == 1'b0 || ram_valid_i == 1'b1) && read_data_valid_i == 1'b1 && fab_read_data_valid_i == 1'b1) ? RD_EN : 1'b0; + + always @ (posedge RD_CLK or posedge rd_rst_i) begin : proc_delay1 + if (rd_rst_i == 1) begin + ram_regout_en_d2 <= #`TCQ 1'b0; + end + else begin + if (srst_i == 1'b1) + ram_regout_en_d2 <= #`TCQ 1'b0; + else + ram_regout_en_d2 <= #`TCQ ram_regout_en_d1; + end + end //always + + + + 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 + + always @ (posedge RD_CLK) begin + ram_valid_i_d <= #`TCQ ram_valid_i; + read_data_valid_i_d <= #`TCQ read_data_valid_i; + fab_read_data_valid_i_d <= #`TCQ fab_read_data_valid_i; + + 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 = (ram_valid_i == 1'b1 && (read_data_valid_i == 1'b0 || fab_read_data_valid_i == 1'b0)) ? 1'b1 : (read_data_valid_i == 1'b1 && fab_read_data_valid_i == 1'b1 && ram_valid_i == 1'b1) ? RD_EN : 1'b0; + + //*************************************************************************** + // 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 | ~ fab_read_data_valid_i) & ~FIFOEMPTY) | preloadstage1; + end + endgenerate // gnll_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 && C_USE_EMBEDDED_REG == 3) begin : gnll_fifo_fab_valid + + + always @ (posedge RD_CLK or posedge rd_rst_i) begin + if (rd_rst_i) begin + // asynchronous reset (active high) + fab_valid <= #`TCQ 1'b0; + end else begin + if (srst_i) begin + // synchronous reset (active high) + fab_valid <= #`TCQ 1'b0; + end else begin + if (ram_regout_en == 1'b1) begin + fab_valid <= #`TCQ 1'b1; + end else begin + if (fab_regout_en == 1'b1) + fab_valid <= #`TCQ 1'b0; + else + fab_valid <= #`TCQ fab_valid; + end + end //srst_i + end //rd_rst_i + end //always + end endgenerate // gnll_fifo_fab_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. + //*************************************************************************** + generate if(C_USE_EMBEDDED_REG == 3) begin + 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 begin + if (ram_regout_en == 1'b1) begin + read_data_valid_i <= #`TCQ 1'b1; + end else begin + if (fab_regout_en == 1'b1) + read_data_valid_i <= #`TCQ 1'b0; + else + read_data_valid_i <= #`TCQ read_data_valid_i; + end + end + end //always +end +endgenerate + +//generate if(C_USE_EMBEDDED_REG == 3) begin +// 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; +// +// if (ram_regout_en == 1'b1) begin +// fab_read_data_valid_i <= #`TCQ 1'b0; +// end else begin +// if (fab_regout_en == 1'b1) +// fab_read_data_valid_i <= #`TCQ 1'b1; +// else +// fab_read_data_valid_i <= #`TCQ fab_read_data_valid_i; +// end +// end //always +//end +//endgenerate + + generate if(C_USE_EMBEDDED_REG == 3 ) begin + always @ (posedge RD_CLK or posedge rd_rst_i) begin :fabout_dvalid + if (rd_rst_i) + fab_read_data_valid_i <= #`TCQ 1'b0; + else if (srst_i) + fab_read_data_valid_i <= #`TCQ 1'b0; + else + fab_read_data_valid_i <= #`TCQ fab_valid | (fab_read_data_valid_i & ~RD_EN); + end //always +end +endgenerate + +always @ (posedge RD_CLK ) begin : proc_del1 + begin + fab_read_data_valid_i_1 <= #`TCQ fab_read_data_valid_i; + end + 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 && C_USE_EMBEDDED_REG == 3 ) begin : gnll_fifo_empty_both + 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 (~fab_valid & ~fab_read_data_valid_i) | (~fab_valid & RD_EN); + end + end + end //always + end endgenerate // gnll_fifo_empty_both + + // 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. + //*************************************************************************** + reg FIFOEMPTY_1; + generate if (C_USE_EMBEDDED_REG == 3 ) begin + always @(posedge RD_CLK) begin + FIFOEMPTY_1 <= #`TCQ FIFOEMPTY; + end + end +endgenerate + generate if (C_USE_EMBEDDED_REG == 3 ) begin + 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 ((fab_regout_en) | (ram_valid_i & fab_read_data_valid_i & ~RD_EN)) begin + almost_empty_i <= #`TCQ (~ram_valid_i); + end + almost_empty_q <= #`TCQ empty_i; + end + end + end //always +end +endgenerate + always @ (posedge RD_CLK or posedge rd_rst_i) begin + if (rd_rst_i) begin + empty_sckt <= #`TCQ 1'b1; + sckt_rrst_q <= #`TCQ 1'b0; + sckt_rrst_done <= #`TCQ 1'b0; + end else begin + sckt_rrst_q <= #`TCQ SAFETY_CKT_RD_RST; + if (sckt_rrst_q && ~SAFETY_CKT_RD_RST) begin + sckt_rrst_done <= #`TCQ 1'b1; + end else if (sckt_rrst_done) begin + // rising clock edge + empty_sckt <= #`TCQ 1'b0; + end + end + end //always + + +// assign USEREMPTY = C_EN_SAFETY_CKT ? (sckt_rrst_done ? empty_i : empty_sckt) : empty_i; + assign USEREMPTY = empty_i; + assign USERALMOSTEMPTY = almost_empty_i; + assign FIFORDEN = ram_rd_en; + assign RAMVALID = (C_USE_EMBEDDED_REG == 3)? fab_valid : ram_valid_i; + assign uservalid_both = (C_USERVALID_LOW && C_USE_EMBEDDED_REG == 3) ? ~fab_read_data_valid_i : ((C_USERVALID_LOW == 0 && C_USE_EMBEDDED_REG == 3) ? fab_read_data_valid_i : 1'b0); + assign uservalid_one = (C_USERVALID_LOW && C_USE_EMBEDDED_REG < 3) ? ~read_data_valid_i :((C_USERVALID_LOW == 0 && C_USE_EMBEDDED_REG < 3) ? read_data_valid_i : 1'b0); + assign USERVALID = (C_USE_EMBEDDED_REG == 3) ? uservalid_both : uservalid_one; + assign USERUNDERFLOW = C_USERUNDERFLOW_LOW ? ~(empty_q & rd_en_q) : empty_q & rd_en_q; +//no safety ckt with both reg +generate + if (C_EN_SAFETY_CKT==0 && C_USE_EMBEDDED_REG == 3 ) begin + 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); + userdata_both <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + user_sbiterr_both <= #`TCQ 0; + user_dbiterr_both <= #`TCQ 0; + 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; + user_sbiterr_both <= #`TCQ 0; + user_dbiterr_both <= #`TCQ 0; + end + // DRAM resets asynchronously + if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE == 2) begin //asynchronous reset (active high) + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + userdata_both <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + user_sbiterr_both <= #`TCQ 0; + user_dbiterr_both <= #`TCQ 0; + end + 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; + user_sbiterr_both <= #`TCQ 0; + user_dbiterr_both <= #`TCQ 0; + end + if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE == 2) begin + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + userdata_both <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + user_sbiterr_both <= #`TCQ 0; + user_dbiterr_both <= #`TCQ 0; + end + end else begin + if (fwft_rst_done) begin + if (ram_regout_en) begin + userdata_both <= #`TCQ FIFODATA; + user_dbiterr_both <= #`TCQ FIFODBITERR; + user_sbiterr_both <= #`TCQ FIFOSBITERR; + end + if (fab_regout_en) begin + USERDATA <= #`TCQ userdata_both; + USERDBITERR <= #`TCQ user_dbiterr_both; + USERSBITERR <= #`TCQ user_sbiterr_both; + end + end + end + end + end //always + end //if + endgenerate + +//safety_ckt with both registers + generate + if (C_EN_SAFETY_CKT==1 && C_USE_EMBEDDED_REG == 3) begin + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d1; + reg [C_DOUT_WIDTH-1:0] dout_rst_val_d2; + reg [1:0] rst_delayed_sft1 =1; + reg [1:0] rst_delayed_sft2 =1; + reg [1:0] rst_delayed_sft3 =1; + reg [1:0] rst_delayed_sft4 =1; + + always@(posedge RD_CLK) begin + rst_delayed_sft1 <= #`TCQ rd_rst_i; + rst_delayed_sft2 <= #`TCQ rst_delayed_sft1; + rst_delayed_sft3 <= #`TCQ rst_delayed_sft2; + rst_delayed_sft4 <= #`TCQ rst_delayed_sft3; + end + always @ (posedge RD_CLK) begin + if (rd_rst_i || srst_i) begin + if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE < 2 && rst_delayed_sft1 == 1'b1) begin + @(posedge RD_CLK) + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + userdata_both <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + user_sbiterr_both <= #`TCQ 0; + user_dbiterr_both <= #`TCQ 0; + end + 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; + user_sbiterr_both <= #`TCQ 0; + user_dbiterr_both <= #`TCQ 0; + end + // DRAM resets asynchronously + if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE == 2)begin //asynchronous reset (active high) + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + userdata_both <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + user_sbiterr_both <= #`TCQ 0; + user_dbiterr_both <= #`TCQ 0; + end + 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; + user_sbiterr_both <= #`TCQ 0; + user_dbiterr_both <= #`TCQ 0; + end + if (C_USE_DOUT_RST == 1 && C_MEMORY_TYPE == 2) begin + USERDATA <= #`TCQ hexstr_conv(C_DOUT_RST_VAL); + end + end else if (fwft_rst_done) begin + if (ram_regout_en == 1'b1 && rd_rst_i == 1'b0) begin + userdata_both <= #`TCQ FIFODATA; + user_dbiterr_both <= #`TCQ FIFODBITERR; + user_sbiterr_both <= #`TCQ FIFOSBITERR; + end + if (fab_regout_en == 1'b1 && rd_rst_i == 1'b0) begin + USERDATA <= #`TCQ userdata_both; + USERDBITERR <= #`TCQ user_dbiterr_both; + USERSBITERR <= #`TCQ user_sbiterr_both; + end + end + end + end //always + end //if +endgenerate + +endmodule //fifo_generator_v13_2_5_bhv_ver_preload0 + + +//----------------------------------------------------------------------------- +// +// Register Slice +// Register one AXI channel on forward and/or reverse signal path +// +// Verilog-standard: Verilog 2001 +//-------------------------------------------------------------------------- +// +// Structure: +// reg_slice +// +//-------------------------------------------------------------------------- + +module fifo_generator_v13_2_5_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 + ); + + localparam RST_SYNC_STAGES = 5; + localparam RST_BUSY_LEN = 6; + reg [1:0] arst_sync_wr = 2'b11; + reg [RST_BUSY_LEN-1:0] sckt_wr_rst_cc = 0; + wire sync_reset; + wire extnd_reset; + + + always @(posedge ARESET or posedge ACLK) begin + if (ARESET) + arst_sync_wr <= 2'b11; + else + arst_sync_wr <= #`TCQ {arst_sync_wr[0], 1'b0}; + end + + always @(posedge ACLK) begin + sckt_wr_rst_cc <= #`TCQ {sckt_wr_rst_cc[RST_BUSY_LEN-2:0], arst_sync_wr[1]}; + end + + assign sync_reset = |sckt_wr_rst_cc[RST_BUSY_LEN-5:0] | arst_sync_wr[1]; + assign extnd_reset = |sckt_wr_rst_cc | arst_sync_wr[1]; + 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 <= extnd_reset; + 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 (sync_reset || extnd_reset) begin + s_ready_i <= 1'b0; + state <= ZERO; + end else if (areset_d1 && ~extnd_reset) 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 <= extnd_reset; + end + + // Load storage1 with slave side data + always @(posedge ACLK) + begin + if (sync_reset || extnd_reset) begin + s_ready_i <= 1'b0; + m_valid_i <= 1'b0; + end else if (areset_d1 && ~extnd_reset) 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 |
