URL
https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk
Subversion Repositories pcie_ds_dma
[/] [pcie_ds_dma/] [trunk/] [core/] [ds_dma64/] [pcie_src/] [pcie_core64_m1/] [source/] [pcie_blk_ll_credit.v] - Rev 12
Go to most recent revision | Compare with Previous | Blame | View Log
//----------------------------------------------------------------------------- // // (c) Copyright 2009-2010 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. // //----------------------------------------------------------------------------- // Project : V5-Block Plus for PCI Express // File : pcie_blk_ll_credit.v //-------------------------------------------------------------------------------- //-------------------------------------------------------------------------------- //-- //-- Description: Rx Credit Calculation. This module will compute the credit //-- availability of the various queue types. //-- //-------------------------------------------------------------------------------- `timescale 1ns/1ns `ifndef Tcq `define Tcq 1 `endif module pcie_blk_ll_credit //{{{ Module Port/Parameters #( parameter C_STREAMING = 0, parameter C_CALENDAR_STREAMING = 4, parameter C_CALENDAR_LEN = 9, parameter C_CALENDAR_SUB_LEN = 12, //RxStream=68, TxCpl=08, SUB_SEQ=FF parameter C_CALENDAR_SEQ = 72'h68_08_68_2C_68_08_68_0C_FF, //S Tc S T1 S Tc S T2 F //CPLLim: tPHl=20,tNPHl=24,tCHl=28,tPDl=2C,tNPDl=30,tCDl=34 //RFC: rPHa=40,rPHr=60,rNPHa=44,rNPHr=64,rPDa=4C,rPDr=6C parameter C_CALENDAR_SUB_SEQ = 96'h40_60_44_64_4C_6C_20_24_28_2C_30_34, parameter MPS = 3'b101, parameter LEGACY_EP = 0, //These parameters are only used for SV assertions, and are set via //defparams via "board.v". parameter BFM_INIT_FC_PH = 0, parameter BFM_INIT_FC_PD = 0, parameter BFM_INIT_FC_NPH = 0, parameter BFM_INIT_FC_NPD = 0, parameter BFM_INIT_FC_CPLH = 0, parameter BFM_INIT_FC_CPLD = 0 ) ( // PCIe Block clock and reset input wire clk, input wire rst_n, // PCIe Block Management Interface output reg [6:0] mgmt_stats_credit_sel, input wire [11:0] mgmt_stats_credit, // PCIe Soft Macro Trn Interface output reg [7:0] trn_pfc_ph_cl = 0, output reg [7:0] trn_pfc_nph_cl = 0, output reg [7:0] trn_pfc_cplh_cl = 0, output reg trn_pfc_cplh_cl_upd = 0, output reg [11:0] trn_pfc_pd_cl = 0, output reg [11:0] trn_pfc_npd_cl = 0, output reg [11:0] trn_pfc_cpld_cl = 0, input trn_lnk_up_n, output reg [7:0] trn_rfc_ph_av = 0, output reg [11:0] trn_rfc_pd_av = 0, output reg [7:0] trn_rfc_nph_av = 0, output wire [11:0] trn_rfc_npd_av, output wire [7:0] trn_rfc_cplh_av, output wire [11:0] trn_rfc_cpld_av, // I/O to Rx Arb, for Streaming Credit Data input wire trn_rcpl_streaming_n, output reg [7:0] rx_ch_credits_received = 0, output reg rx_ch_credits_received_inc = 0, // I/O for Tx Cpl Data output reg [7:0] tx_ch_credits_consumed = 0, // I/O for Tx PD output reg [11:0] tx_pd_credits_available = 0, output reg [11:0] tx_pd_credits_consumed = 0, output reg [11:0] tx_npd_credits_available = 0, output reg [11:0] tx_npd_credits_consumed = 0, output reg [11:0] tx_cd_credits_available = 0, output wire [11:0] tx_cd_credits_consumed, input wire clear_cpl_count, output reg pd_credit_limited = 1, output reg npd_credit_limited = 1, output reg cd_credit_limited = 1, input wire l0_stats_cfg_transmitted ); //}}} //{{{ Functions, Regs, Wires, Parameters reg [11:0] reg_ph_alloc = 0; reg [11:0] reg_nph_alloc = 0; reg [11:0] reg_pd_alloc = 0; reg [11:0] reg_recvd = 0; reg [6:0] mgmt_stats_credit_sel_d = 0; wire service_stream; reg service_rxrcd_ch = 0; wire service_txcpl; reg service_txcon_pd = 0; reg service_txcon_npd = 0; reg service_txcon_cd = 0; reg service_txcon_ch = 0; reg service_txcon_pd_d = 0; reg service_txcon_npd_d = 0; reg service_txcon_cd_d = 0; reg service_txlim_ph = 0; reg service_txlim_nph = 0; reg service_txlim_ch = 0; reg service_txlim_pd = 0; reg service_txlim_npd = 0; reg service_txlim_cd = 0; reg service_txlim_ph_d = 0; reg service_txlim_nph_d = 0; reg service_txlim_ch_d = 0; reg service_txlim_pd_d = 0; reg service_txlim_npd_d = 0; reg service_txlim_cd_d = 0; reg service_rxall_ph = 0; reg service_rxrcd_ph = 0; reg service_rxall_nph = 0; reg service_rxrcd_nph = 0; reg service_rxall_pd = 0; reg service_rxrcd_pd = 0; reg service_rxall_ph_d = 0; reg service_rxall_nph_d = 0; reg service_rxall_pd_d = 0; reg service_rxrcd_ph_d = 0; reg service_rxrcd_nph_d = 0; reg service_rxrcd_pd_d = 0; reg service_rxrcd_ph_d2 = 0; reg service_rxrcd_nph_d2 = 0; reg service_rxrcd_pd_d2 = 0; reg trn_pfc_ph_cl_upd = 0; reg trn_pfc_nph_cl_upd = 0; reg trn_pfc_pd_cl_upd = 0; reg trn_pfc_npd_cl_upd = 0; reg trn_pfc_cpld_cl_upd = 0; reg pd_credit_limited_upd = 0; reg npd_credit_limited_upd = 0; reg cd_credit_limited_upd = 0; reg [11:0] tx_cd_credits_consumed_int = 0; reg [11:0] tx_cd_credits_consumed_all = 0; reg [11:0] tx_cd_credits_consumed_trn = 0; reg [11:0] tx_cd_credits_consumed_diff = 0; reg [11:0] l0_stats_cfg_transmitted_cnt = 0; reg [11:0] mgmt_stats_credit_d = 0; wire [7:0] cal_seq_out; wire [1:0] cal_tag_out; wire [6:0] cal_sub_seq_out; wire [6:0] cal_seq_init_out; wire [7:0] old_cal_seq_out; wire [1:0] old_cal_tag_out; wire [6:0] old_cal_sub_seq_out; reg [3:0] cal_addr = (C_CALENDAR_LEN - 1)%16; wire cal_enable; reg [4:0] initial_header_read_cntr = 0; reg initial_header_read = 1; integer i,j; assign trn_rfc_npd_av = 0; assign trn_rfc_cplh_av = 0; assign trn_rfc_cpld_av = 0; // ============================== // VC localparam VC0 = 2'b00; // ============================== // Channel localparam CREDIT_SEL_PH = 3'b000; localparam CREDIT_SEL_NPH = 3'b001; localparam CREDIT_SEL_CH = 3'b010; localparam CREDIT_SEL_PD = 3'b011; localparam CREDIT_SEL_NPD = 3'b100; localparam CREDIT_SEL_CD = 3'b101; `define CREDIT_SEL_PH 3'h0 `define CREDIT_SEL_NPH 3'h1 `define CREDIT_SEL_CH 3'h2 `define CREDIT_SEL_PD 3'h3 `define CREDIT_SEL_NPD 3'h4 `define CREDIT_SEL_CD 3'h5 // ============================== // Credit Type Information localparam CREDIT_TX_CONS = 2'b00; localparam CREDIT_TX_LIM = 2'b01; localparam CREDIT_RX_ALLO = 2'b10; localparam CREDIT_RX_RCVD = 2'b11; `define CREDIT_TX_CONS 3'h0 `define CREDIT_TX_LIM 3'h1 `define CREDIT_RX_ALLO 3'h2 `define CREDIT_RX_RCVD 3'h3 // ============================== function integer numsrl (input integer length); begin if (length%16 == 0) numsrl = length/16; else numsrl = (length[31:4]+1); end endfunction function integer parsecal (input integer index, input reg [127:0] CAL_SEQ, input integer CAL_LEN, input integer numsrl); integer g; begin for (g=0; g<numsrl*16; g=g+1) if (g>=CAL_LEN) parsecal[g] = 0; else parsecal[g] = CAL_SEQ[index + g*8]; end endfunction function integer tagcal (input integer index, input reg [127:0] CAL_SEQ, input integer CAL_LEN, input integer numsrl); integer g; reg [5:0] S; begin for (g=0; g<numsrl*16; g=g+1) begin S[5] = CAL_SEQ[g*8+7]; S[4] = CAL_SEQ[g*8+6]; S[3] = CAL_SEQ[g*8+5]; S[2] = CAL_SEQ[g*8+4]; S[1] = CAL_SEQ[g*8+3]; S[0] = CAL_SEQ[g*8+2]; if (g>=CAL_LEN) tagcal[g] = 0; else if ((S[5:0] == { `CREDIT_TX_CONS , `CREDIT_SEL_PD }) || (S[5:0] == { `CREDIT_TX_LIM , `CREDIT_SEL_PD })) tagcal[g] = 1; //PD = 11 else if ((S[5:0] == { `CREDIT_TX_CONS , `CREDIT_SEL_NPD }) || (S[5:0] == { `CREDIT_TX_LIM , `CREDIT_SEL_NPD })) tagcal[g] = index; //NPD = 10 else if ((S[5:0] == { `CREDIT_TX_CONS , `CREDIT_SEL_CD }) || (S[5:0] == { `CREDIT_TX_LIM , `CREDIT_SEL_CD })) tagcal[g] = !index; //CD = 01 else tagcal[g] = 0; //everything else = 00 end end endfunction //}}} //{{{ Instantiate SRLs for Calendar parameter number_srls = numsrl(C_CALENDAR_LEN); parameter number_srls_sub = numsrl(C_CALENDAR_SUB_LEN); parameter [number_srls*16-1:0] CALTAGINIT1 = tagcal(1, C_CALENDAR_SEQ,C_CALENDAR_LEN,number_srls); parameter [number_srls*16-1:0] CALTAGINIT0 = tagcal(0, C_CALENDAR_SEQ,C_CALENDAR_LEN,number_srls); parameter [number_srls*16-1:0] CALINIT7 = parsecal(7, C_CALENDAR_SEQ,C_CALENDAR_LEN,number_srls); parameter [number_srls*16-1:0] CALINIT6 = parsecal(6, C_CALENDAR_SEQ,C_CALENDAR_LEN,number_srls); parameter [number_srls*16-1:0] CALINIT5 = parsecal(5, C_CALENDAR_SEQ,C_CALENDAR_LEN,number_srls); parameter [number_srls*16-1:0] CALINIT4 = parsecal(4, C_CALENDAR_SEQ,C_CALENDAR_LEN,number_srls); parameter [number_srls*16-1:0] CALINIT3 = parsecal(3, C_CALENDAR_SEQ,C_CALENDAR_LEN,number_srls); parameter [number_srls*16-1:0] CALINIT2 = parsecal(2, C_CALENDAR_SEQ,C_CALENDAR_LEN,number_srls); parameter [number_srls_sub*16-1:0] CALSUBINIT6 = parsecal(6, C_CALENDAR_SUB_SEQ,C_CALENDAR_SUB_LEN,number_srls_sub); parameter [number_srls_sub*16-1:0] CALSUBINIT5 = parsecal(5, C_CALENDAR_SUB_SEQ,C_CALENDAR_SUB_LEN,number_srls_sub); parameter [number_srls_sub*16-1:0] CALSUBINIT4 = parsecal(4, C_CALENDAR_SUB_SEQ,C_CALENDAR_SUB_LEN,number_srls_sub); parameter [number_srls_sub*16-1:0] CALSUBINIT3 = parsecal(3, C_CALENDAR_SUB_SEQ,C_CALENDAR_SUB_LEN,number_srls_sub); parameter [number_srls_sub*16-1:0] CALSUBINIT2 = parsecal(2, C_CALENDAR_SUB_SEQ,C_CALENDAR_SUB_LEN,number_srls_sub); parameter CAL_SUB_ADDR = (C_CALENDAR_SUB_LEN - 1)%16; always @(posedge clk) begin if (~rst_n) begin cal_addr <= #`Tcq (C_CALENDAR_LEN - 1)%16; end else if (!cal_enable) begin cal_addr <= #`Tcq cal_addr - 1; end end always @(posedge clk) begin if (~rst_n) begin initial_header_read <= #`Tcq 1; initial_header_read_cntr <= #`Tcq 'h0; end else begin if (initial_header_read_cntr < 'd16) begin initial_header_read_cntr <= #`Tcq initial_header_read_cntr + 1; initial_header_read <= #`Tcq 1; end else begin initial_header_read <= #`Tcq 0; end end end assign cal_enable = !((!pd_credit_limited && (cal_tag_out[1:0]==2'b11)) || (!npd_credit_limited && (cal_tag_out[1:0]==2'b10) && LEGACY_EP) || (!cd_credit_limited && (cal_tag_out[1:0]==2'b01))); assign cal_seq_out[1:0] = 2'b00; assign cal_sub_seq_out[1:0] = 2'b00; assign old_cal_seq_out[1:0] = 2'b00; assign old_cal_sub_seq_out[1:0] = 2'b00; // old SRL, left for comparison //synthesis translate_off genvar j_srl; generate for (j_srl=0; j_srl<number_srls; j_srl=j_srl+1) begin: old_srl_gen SRL16E #(.INIT(CALTAGINIT1[15:0])) srl_cal_tag1 (.D(old_cal_tag_out[1]),.Q(old_cal_tag_out[1]),.CLK(clk),.CE(cal_enable), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0])); SRL16E #(.INIT(CALTAGINIT0[15:0])) srl_cal_tag0 (.D(old_cal_tag_out[0]),.Q(old_cal_tag_out[0]),.CLK(clk),.CE(cal_enable), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0])); SRL16E #(.INIT(CALINIT7[15:0])) srl_cal7 (.D(old_cal_seq_out[7]),.Q(old_cal_seq_out[7]),.CLK(clk),.CE(cal_enable), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0])); SRL16E #(.INIT(CALINIT6[15:0])) srl_cal6 (.D(old_cal_seq_out[6]),.Q(old_cal_seq_out[6]),.CLK(clk),.CE(cal_enable), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0])); SRL16E #(.INIT(CALINIT5[15:0])) srl_cal5 (.D(old_cal_seq_out[5]),.Q(old_cal_seq_out[5]),.CLK(clk),.CE(cal_enable), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0])); SRL16E #(.INIT(CALINIT4[15:0])) srl_cal4 (.D(old_cal_seq_out[4]),.Q(old_cal_seq_out[4]),.CLK(clk),.CE(cal_enable), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0])); SRL16E #(.INIT(CALINIT3[15:0])) srl_cal3 (.D(old_cal_seq_out[3]),.Q(old_cal_seq_out[3]),.CLK(clk),.CE(cal_enable), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0])); SRL16E #(.INIT(CALINIT2[15:0])) srl_cal2 (.D(old_cal_seq_out[2]),.Q(old_cal_seq_out[2]),.CLK(clk),.CE(cal_enable), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0])); end endgenerate //synthesis translate_on genvar i_srl; generate for (i_srl=0; i_srl<number_srls; i_srl=i_srl+1) begin: srl_gen my_SRL16E #(.INIT(CALTAGINIT1[15:0])) srl_cal_tag1 (.D(cal_tag_out[1]),.Q(cal_tag_out[1]),.CLK(clk),.CE(cal_enable & rst_n), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALTAGINIT0[15:0])) srl_cal_tag0 (.D(cal_tag_out[0]),.Q(cal_tag_out[0]),.CLK(clk),.CE(cal_enable & rst_n), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALINIT7[15:0])) srl_cal7 (.D(cal_seq_out[7]),.Q(cal_seq_out[7]),.CLK(clk),.CE(cal_enable & rst_n), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALINIT6[15:0])) srl_cal6 (.D(cal_seq_out[6]),.Q(cal_seq_out[6]),.CLK(clk),.CE(cal_enable & rst_n), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALINIT5[15:0])) srl_cal5 (.D(cal_seq_out[5]),.Q(cal_seq_out[5]),.CLK(clk),.CE(cal_enable & rst_n), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALINIT4[15:0])) srl_cal4 (.D(cal_seq_out[4]),.Q(cal_seq_out[4]),.CLK(clk),.CE(cal_enable & rst_n), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALINIT3[15:0])) srl_cal3 (.D(cal_seq_out[3]),.Q(cal_seq_out[3]),.CLK(clk),.CE(cal_enable & rst_n), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALINIT2[15:0])) srl_cal2 (.D(cal_seq_out[2]),.Q(cal_seq_out[2]),.CLK(clk),.CE(cal_enable & rst_n), .A3(cal_addr[3]),.A2(cal_addr[2]),.A1(cal_addr[1]),.A0(cal_addr[0]), .RST_N(rst_n)); end endgenerate /* 0000_0000_0000_0000 6 1111_1101_1111_1011 5 0000_1110_0001_1100 4 0011_0000_0110_0000 3 0101_0110_1010_1101 2 OOOO_OOOO_OOOO_OOOO 1 OOOO_OOOO_OOOO_OOOO 0 2222 3312 2223 3122 048c 0440 48c0 4404 1234 5671 2345 6712 20 PHli 24 NPHli 28 CHli 2c PDli 30 PHli 34 CDli 14 ConCD */ assign cal_seq_init_out[6] = 0; // assign cal_seq_init_out[5] = 1; my_SRL16E #(.INIT(16'b1111_1101_1111_1011)) srl_init_cal5 (.D(cal_seq_init_out[5]),.Q(cal_seq_init_out[5]),.CLK(clk),.CE(1'b1), .A3(1'b1),.A2(1'b1),.A1(1'b1),.A0(1'b1), .RST_N(rst_n)); my_SRL16E #(.INIT(16'b0000_1110_0001_1100)) srl_init_cal4 (.D(cal_seq_init_out[4]),.Q(cal_seq_init_out[4]),.CLK(clk),.CE(1'b1), .A3(1'b1),.A2(1'b1),.A1(1'b1),.A0(1'b1), .RST_N(rst_n)); my_SRL16E #(.INIT(16'b0011_0000_0110_0000)) srl_init_cal3 (.D(cal_seq_init_out[3]),.Q(cal_seq_init_out[3]),.CLK(clk),.CE(1'b1), .A3(1'b1),.A2(1'b1),.A1(1'b1),.A0(1'b1), .RST_N(rst_n)); my_SRL16E #(.INIT(16'b0101_0110_1010_1101)) srl_init_cal2 (.D(cal_seq_init_out[2]),.Q(cal_seq_init_out[2]),.CLK(clk),.CE(1'b1), .A3(1'b1),.A2(1'b1),.A1(1'b1),.A0(1'b1), .RST_N(rst_n)); assign cal_seq_init_out[1] = 0; assign cal_seq_init_out[0] = 0; // old SRL, left for comparison //synthesis translate_off genvar j_ssrl; generate for (j_ssrl=0; j_ssrl<number_srls_sub; j_ssrl=j_ssrl+1) begin: old_sub_srl_gen SRL16E #(.INIT(CALSUBINIT6[15:0])) srl_sub_cal6 (.D(old_cal_sub_seq_out[6]),.Q(old_cal_sub_seq_out[6]),.CLK(clk),.CE(cal_seq_out[7]), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0])); SRL16E #(.INIT(CALSUBINIT5[15:0])) srl_sub_cal5 (.D(old_cal_sub_seq_out[5]),.Q(old_cal_sub_seq_out[5]),.CLK(clk),.CE(cal_seq_out[7]), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0])); SRL16E #(.INIT(CALSUBINIT4[15:0])) srl_sub_cal4 (.D(old_cal_sub_seq_out[4]),.Q(old_cal_sub_seq_out[4]),.CLK(clk),.CE(cal_seq_out[7]), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0])); SRL16E #(.INIT(CALSUBINIT3[15:0])) srl_sub_cal3 (.D(old_cal_sub_seq_out[3]),.Q(old_cal_sub_seq_out[3]),.CLK(clk),.CE(cal_seq_out[7]), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0])); SRL16E #(.INIT(CALSUBINIT2[15:0])) srl_sub_cal2 (.D(old_cal_sub_seq_out[2]),.Q(old_cal_sub_seq_out[2]),.CLK(clk),.CE(cal_seq_out[7]), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0])); end endgenerate //synthesis translate_on genvar i_ssrl; generate for (i_ssrl=0; i_ssrl<number_srls_sub; i_ssrl=i_ssrl+1) begin: sub_srl_gen my_SRL16E #(.INIT(CALSUBINIT6[15:0])) srl_sub_cal6 (.D(cal_sub_seq_out[6]),.Q(cal_sub_seq_out[6]),.CLK(clk),.CE(cal_seq_out[7] & rst_n), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALSUBINIT5[15:0])) srl_sub_cal5 (.D(cal_sub_seq_out[5]),.Q(cal_sub_seq_out[5]),.CLK(clk),.CE(cal_seq_out[7] & rst_n), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALSUBINIT4[15:0])) srl_sub_cal4 (.D(cal_sub_seq_out[4]),.Q(cal_sub_seq_out[4]),.CLK(clk),.CE(cal_seq_out[7] & rst_n), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALSUBINIT3[15:0])) srl_sub_cal3 (.D(cal_sub_seq_out[3]),.Q(cal_sub_seq_out[3]),.CLK(clk),.CE(cal_seq_out[7] & rst_n), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0]), .RST_N(rst_n)); my_SRL16E #(.INIT(CALSUBINIT2[15:0])) srl_sub_cal2 (.D(cal_sub_seq_out[2]),.Q(cal_sub_seq_out[2]),.CLK(clk),.CE(cal_seq_out[7] & rst_n), .A3(CAL_SUB_ADDR[3]),.A2(CAL_SUB_ADDR[2]),.A1(CAL_SUB_ADDR[1]),.A0(CAL_SUB_ADDR[0]), .RST_N(rst_n)); end endgenerate //}}} //{{{ Parse Calendar & Trigger for Service of Streaming or Tx Cpl Credit Data always @(posedge clk) begin if (~rst_n || trn_lnk_up_n) begin mgmt_stats_credit_sel <= #`Tcq 'h0; mgmt_stats_credit_sel_d <= #`Tcq 'h0; service_rxall_ph <= #`Tcq 1'b0; service_rxall_nph <= #`Tcq 1'b0; service_rxall_pd <= #`Tcq 1'b0; service_rxrcd_ph <= #`Tcq 1'b0; service_rxrcd_nph <= #`Tcq 1'b0; service_rxrcd_ch <= #`Tcq 1'b0; service_rxrcd_pd <= #`Tcq 1'b0; service_txcon_ch <= #`Tcq 1'b0; service_txcon_pd <= #`Tcq 1'b0; service_txcon_npd <= #`Tcq 1'b0; service_txcon_cd <= #`Tcq 1'b0; service_txlim_ph <= #`Tcq 1'b0; service_txlim_nph <= #`Tcq 1'b0; service_txlim_ch <= #`Tcq 1'b0; service_txlim_pd <= #`Tcq 1'b0; service_txlim_npd <= #`Tcq 1'b0; service_txlim_cd <= #`Tcq 1'b0; end else begin // mgmt_stats_credit_sel <= #`Tcq {(cal_seq_out[7] || initial_header_read )? cal_sub_seq_out[6:2]:cal_seq_out[6:2], VC0}; mgmt_stats_credit_sel <= #`Tcq {initial_header_read ? cal_seq_init_out[6:2] : cal_seq_out[7] ? cal_sub_seq_out[6:2] : cal_seq_out[6:2], VC0}; mgmt_stats_credit_sel_d <= #`Tcq mgmt_stats_credit_sel; service_rxall_ph <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_RX_ALLO,CREDIT_SEL_PH}; //0x40 service_rxall_nph <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_RX_ALLO,CREDIT_SEL_NPH};//0x44 service_rxall_pd <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_RX_ALLO,CREDIT_SEL_PD}; //0x4C service_rxrcd_ph <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_RX_RCVD,CREDIT_SEL_PH}; //0x60 service_rxrcd_nph <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_RX_RCVD,CREDIT_SEL_NPH};//0x64 service_rxrcd_ch <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_RX_RCVD,CREDIT_SEL_CH}; //0x68 (streaming) service_rxrcd_pd <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_RX_RCVD,CREDIT_SEL_PD}; //0x6C service_txcon_ch <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_CONS,CREDIT_SEL_CH}; //0x08 (tx cpl fix) service_txcon_pd <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_CONS,CREDIT_SEL_PD}; //0x0C (tx PDcredit fix2) service_txcon_npd <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_CONS,CREDIT_SEL_NPD};//0x10 (tx NPDcredit fix2) service_txcon_cd <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_CONS,CREDIT_SEL_CD}; //0x14 (tx CDcredit fix2) service_txlim_ph <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_LIM, CREDIT_SEL_PH}; //0x20 service_txlim_nph <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_LIM, CREDIT_SEL_NPH};//0x24 service_txlim_ch <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_LIM, CREDIT_SEL_CH}; //0x28 service_txlim_pd <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_LIM, CREDIT_SEL_PD}; //0x2C (tx PDcredit fix1) service_txlim_npd <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_LIM, CREDIT_SEL_NPD};//0x30 (tx NPDcredit fix1) service_txlim_cd <= #`Tcq mgmt_stats_credit_sel_d[6:2] == {CREDIT_TX_LIM, CREDIT_SEL_CD}; //0x34 (tx CDcredit fix1) end end assign service_stream = service_rxrcd_ch; assign service_txcpl = service_txcon_ch; //}}} //{{{ Capture Credit Data for Streaming Mode always @(posedge clk) begin if (~rst_n) begin rx_ch_credits_received <= #`Tcq 0; rx_ch_credits_received_inc <= #`Tcq 0; // requested CplH-rcvd when service_stream=1 // wait 2 cycles for data end else if (service_stream) begin rx_ch_credits_received <= #`Tcq mgmt_stats_credit[7:0]; rx_ch_credits_received_inc <= #`Tcq (mgmt_stats_credit[7:0] != rx_ch_credits_received); end else begin rx_ch_credits_received_inc <= #`Tcq 0; end end //}}} //{{{ Capture Credit Data for Tx Cpl Issue always @(posedge clk) begin if (~rst_n) begin tx_ch_credits_consumed <= #`Tcq 0; end else if (service_txcpl) begin tx_ch_credits_consumed <= #`Tcq mgmt_stats_credit[7:0]; end end //}}} //{{{ Capture Credit Data for Tx Blocking Data Credit Issue always @(posedge clk) begin if (~rst_n) begin service_txcon_pd_d <= #`Tcq 0; service_txcon_npd_d <= #`Tcq 0; service_txcon_cd_d <= #`Tcq 0; tx_pd_credits_consumed <= #`Tcq 0; tx_pd_credits_available <= #`Tcq 0; tx_npd_credits_consumed <= #`Tcq 0; tx_npd_credits_available <= #`Tcq 0; tx_cd_credits_consumed_all <= #`Tcq 0; tx_cd_credits_consumed_trn <= #`Tcq 0; tx_cd_credits_consumed_int <= #`Tcq 0; tx_cd_credits_consumed_diff <= #`Tcq 'h0; tx_cd_credits_available <= #`Tcq 0; l0_stats_cfg_transmitted_cnt <= #`Tcq 'h0; end else begin service_txcon_pd_d <= #`Tcq service_txcon_pd; service_txcon_npd_d <= #`Tcq service_txcon_npd; service_txcon_cd_d <= #`Tcq service_txcon_cd; if (service_txcon_pd_d) begin tx_pd_credits_consumed <= #`Tcq mgmt_stats_credit_d[11:0]; tx_pd_credits_available <= #`Tcq trn_pfc_pd_cl - mgmt_stats_credit_d[11:0]; end if (LEGACY_EP && service_txcon_npd_d) begin tx_npd_credits_consumed <= #`Tcq mgmt_stats_credit_d[11:0]; tx_npd_credits_available <= #`Tcq trn_pfc_npd_cl - mgmt_stats_credit_d[11:0]; end if (service_txcon_cd_d) begin tx_cd_credits_consumed_int <= #`Tcq mgmt_stats_credit_d[11:0]; tx_cd_credits_consumed_diff<= #`Tcq mgmt_stats_credit_d[11:0] - tx_cd_credits_consumed_int; tx_cd_credits_available <= #`Tcq trn_pfc_cpld_cl - mgmt_stats_credit_d[11:0]; end else begin tx_cd_credits_consumed_diff<= #`Tcq 'h0; end tx_cd_credits_consumed_all <= #`Tcq tx_cd_credits_consumed_all + tx_cd_credits_consumed_diff; tx_cd_credits_consumed_trn <= #`Tcq tx_cd_credits_consumed_all - l0_stats_cfg_transmitted_cnt; if (clear_cpl_count) l0_stats_cfg_transmitted_cnt <= #`Tcq 0; else l0_stats_cfg_transmitted_cnt <= #`Tcq l0_stats_cfg_transmitted_cnt + l0_stats_cfg_transmitted; end end assign tx_cd_credits_consumed = tx_cd_credits_consumed_all; //}}} //{{{ Capture Credit Data for RFC always @(posedge clk) begin if (~rst_n) begin service_rxall_ph_d <= #`Tcq 0; service_rxall_nph_d <= #`Tcq 0; service_rxall_pd_d <= #`Tcq 0; service_rxrcd_ph_d <= #`Tcq 0; service_rxrcd_nph_d <= #`Tcq 0; service_rxrcd_pd_d <= #`Tcq 0; service_rxrcd_ph_d2 <= #`Tcq 0; service_rxrcd_nph_d2<= #`Tcq 0; service_rxrcd_pd_d2 <= #`Tcq 0; reg_ph_alloc <= #`Tcq 0; reg_nph_alloc <= #`Tcq 0; reg_pd_alloc <= #`Tcq 0; reg_recvd <= #`Tcq 0; trn_rfc_ph_av <= #`Tcq 0; trn_rfc_nph_av <= #`Tcq 0; trn_rfc_pd_av <= #`Tcq 0; end else begin service_rxall_ph_d <= #`Tcq service_rxall_ph; service_rxall_nph_d <= #`Tcq service_rxall_nph; service_rxall_pd_d <= #`Tcq service_rxall_pd; service_rxrcd_ph_d <= #`Tcq service_rxrcd_ph; service_rxrcd_nph_d <= #`Tcq service_rxrcd_nph; service_rxrcd_pd_d <= #`Tcq service_rxrcd_pd; service_rxrcd_ph_d2 <= #`Tcq service_rxrcd_ph_d; service_rxrcd_nph_d2<= #`Tcq service_rxrcd_nph_d; service_rxrcd_pd_d2 <= #`Tcq service_rxrcd_pd_d; if (service_rxall_ph_d) reg_ph_alloc <= #`Tcq mgmt_stats_credit_d; if (service_rxall_nph_d) reg_nph_alloc <= #`Tcq mgmt_stats_credit_d; if (service_rxall_pd_d) reg_pd_alloc <= #`Tcq mgmt_stats_credit_d; if (service_rxrcd_ph_d || service_rxrcd_nph_d || service_rxrcd_pd_d) reg_recvd <= #`Tcq mgmt_stats_credit_d; if (service_rxrcd_ph_d2) trn_rfc_ph_av <= #`Tcq reg_ph_alloc - reg_recvd; if (service_rxrcd_nph_d2) trn_rfc_nph_av <= #`Tcq reg_nph_alloc - reg_recvd; if (service_rxrcd_pd_d2) trn_rfc_pd_av <= #`Tcq reg_pd_alloc - reg_recvd; end end //}}} always @(posedge clk) begin if (~rst_n) begin mgmt_stats_credit_d <= #`Tcq 'h0; service_txlim_ph_d <= #`Tcq 1'b0; service_txlim_nph_d <= #`Tcq 1'b0; service_txlim_ch_d <= #`Tcq 1'b0; service_txlim_pd_d <= #`Tcq 1'b0; service_txlim_npd_d <= #`Tcq 1'b0; service_txlim_cd_d <= #`Tcq 1'b0; trn_pfc_ph_cl <= #`Tcq 'h0; trn_pfc_nph_cl <= #`Tcq 'h0; trn_pfc_cplh_cl <= #`Tcq 'h0; trn_pfc_pd_cl <= #`Tcq 'h0; trn_pfc_npd_cl <= #`Tcq 'h0; trn_pfc_cpld_cl <= #`Tcq 'h0; trn_pfc_ph_cl_upd <= #`Tcq 1'b0; trn_pfc_nph_cl_upd <= #`Tcq 1'b0; trn_pfc_cplh_cl_upd <= #`Tcq 1'b0; trn_pfc_pd_cl_upd <= #`Tcq 1'b0; trn_pfc_npd_cl_upd <= #`Tcq 1'b0; trn_pfc_cpld_cl_upd <= #`Tcq 1'b0; end else begin mgmt_stats_credit_d <= #`Tcq mgmt_stats_credit; service_txlim_ph_d <= #`Tcq service_txlim_ph; service_txlim_nph_d <= #`Tcq service_txlim_nph; service_txlim_ch_d <= #`Tcq service_txlim_ch; service_txlim_pd_d <= #`Tcq service_txlim_pd; service_txlim_npd_d <= #`Tcq service_txlim_npd; service_txlim_cd_d <= #`Tcq service_txlim_cd; if (service_txlim_ph_d) begin trn_pfc_ph_cl <= #`Tcq mgmt_stats_credit_d[7:0]; trn_pfc_ph_cl_upd <= #`Tcq 1'b1; end if (service_txlim_nph_d) begin trn_pfc_nph_cl <= #`Tcq mgmt_stats_credit_d[7:0]; trn_pfc_nph_cl_upd <= #`Tcq 1'b1; end if (service_txlim_ch_d) begin trn_pfc_cplh_cl <= #`Tcq mgmt_stats_credit_d[7:0]; trn_pfc_cplh_cl_upd <= #`Tcq 1'b1; end if (service_txlim_pd_d) begin trn_pfc_pd_cl <= #`Tcq (mgmt_stats_credit_d[11:0] == 0) ? 12'hfff : mgmt_stats_credit_d[11:0]; trn_pfc_pd_cl_upd <= #`Tcq 1'b1; end if (service_txlim_npd_d) begin trn_pfc_npd_cl <= #`Tcq (mgmt_stats_credit_d[11:0] == 0) ? 12'hfff : mgmt_stats_credit_d[11:0]; trn_pfc_npd_cl_upd <= #`Tcq 1'b1; end if (service_txlim_cd_d) begin trn_pfc_cpld_cl <= #`Tcq mgmt_stats_credit_d[11:0]; trn_pfc_cpld_cl_upd <= #`Tcq 1'b1; end end end always @(posedge clk) begin if (~rst_n) begin pd_credit_limited <= #`Tcq 1'b1; //assume restricted until find out otherwise npd_credit_limited <= #`Tcq 1'b1; //assume restricted until find out otherwise cd_credit_limited <= #`Tcq 1'b1; //assume restricted until find out otherwise pd_credit_limited_upd <= #`Tcq 1'b0; npd_credit_limited_upd <= #`Tcq 1'b0; cd_credit_limited_upd <= #`Tcq 1'b0; end else begin if (!pd_credit_limited_upd && trn_pfc_ph_cl_upd && trn_pfc_pd_cl_upd) begin pd_credit_limited <= #`Tcq trn_pfc_pd_cl < (trn_pfc_ph_cl*8*(2**MPS)); pd_credit_limited_upd <= #`Tcq 1'b1; end if (!npd_credit_limited_upd && trn_pfc_nph_cl_upd && trn_pfc_npd_cl_upd) begin npd_credit_limited <= #`Tcq (trn_pfc_npd_cl < trn_pfc_nph_cl) && LEGACY_EP; npd_credit_limited_upd <= #`Tcq 1'b1; end if (!cd_credit_limited_upd && trn_pfc_cplh_cl_upd && trn_pfc_cpld_cl_upd) begin cd_credit_limited <= #`Tcq trn_pfc_cpld_cl < (trn_pfc_cplh_cl*8*(2**MPS)); cd_credit_limited_upd <= #`Tcq 1'b1; end end end //{{{ Assertions `ifdef SV //synthesis translate_off ASSERT_DETECT_POSTED_LIMITED: assert property (@(posedge clk) rst_n[*256] |-> (BFM_INIT_FC_PH<BFM_INIT_FC_PD*8*(MPS+1)) ? pd_credit_limited : ~pd_credit_limited ) else $fatal; ASSERT_DETECT_NONPOSTED_LIMITED: assert property (@(posedge clk) rst_n[*256] |-> ((BFM_INIT_FC_NPH<BFM_INIT_FC_NPD)&&LEGACY_EP) ? npd_credit_limited : ~npd_credit_limited ) else $fatal; ASSERT_DETECT_COMPLETION_LIMITED: assert property (@(posedge clk) rst_n[*256] |-> (BFM_INIT_FC_CPLH<BFM_INIT_FC_CPLD*8*(MPS+1)) ? cd_credit_limited : ~cd_credit_limited ) else $fatal; ASSERT_POSTED_LIMITED_POLL1: assert property (@(posedge clk) rst_n[*256] ##1 pd_credit_limited |-> ##[1:16] (mgmt_stats_credit_sel == 7'h2C) ) else $fatal; ASSERT_POSTED_LIMITED_POLL2: assert property (@(posedge clk) rst_n[*256] ##1 pd_credit_limited |-> ##[1:16] (mgmt_stats_credit_sel == 7'h0C) ) else $fatal; ASSERT_POSTED_NOT_LIMITED_POLL: assert property (@(posedge clk) rst_n[*256] ##1 ((cal_seq_out[6:0]==7'h2C) || (cal_seq_out[6:0]==7'h0C))|-> pd_credit_limited ) else $fatal; ASSERT_NONPOSTED_LIMITED_POLL1: assert property (@(posedge clk) rst_n[*256] ##1 npd_credit_limited |-> ##[1:16] (mgmt_stats_credit_sel == 7'h30) ) else $fatal; ASSERT_NONPOSTED_LIMITED_POLL2: assert property (@(posedge clk) rst_n[*256] ##1 npd_credit_limited |-> ##[1:16] (mgmt_stats_credit_sel == 7'h10) ) else $fatal; ASSERT_NONPOSTED_NOT_LIMITED_POLL:assert property (@(posedge clk) rst_n[*256] ##1 ((cal_seq_out[6:0]==7'h30) || (cal_seq_out[6:0]==7'h10))|-> npd_credit_limited ) else $fatal; ASSERT_COMPLETION_LIMITED_POLL1: assert property (@(posedge clk) rst_n[*256] ##1 cd_credit_limited |-> ##[1:16] (mgmt_stats_credit_sel == 7'h34) ) else $fatal; ASSERT_COMPLETION_LIMITED_POLL2: assert property (@(posedge clk) rst_n[*256] ##1 cd_credit_limited |-> ##[1:16] (mgmt_stats_credit_sel == 7'h14) ) else $fatal; ASSERT_COMPLETION_NOT_LIMITED_POLL:assert property (@(posedge clk) rst_n[*256] ##1 ((cal_seq_out[6:0]==7'h34) || (cal_seq_out[6:0]==7'h14))|-> cd_credit_limited ) else $fatal; ASSERT_NEVER_POLL_ZEROS: assert property (@(posedge clk) //assume we never poll 00 rst_n |-> ##1 (mgmt_stats_credit_sel != 7'h00) ) else $fatal; ASSERT_NEVER_POLL_X_S: assert property (@(posedge clk) rst_n |-> ((^mgmt_stats_credit_sel) == 1'b0) || ((^mgmt_stats_credit_sel) == 1'b1) ) else $fatal; ASSERT_MATCH_CAL_TAG : assert property (@(posedge clk) rst_n |-> ##1 (old_cal_tag_out == cal_tag_out)) else $fatal; ASSERT_MATCH_CAL_SEQ : assert property (@(posedge clk) rst_n |-> ##1 (old_cal_seq_out == cal_seq_out)) else $fatal; ASSERT_MATCH_CAL_SUB_SEQ : assert property (@(posedge clk) rst_n |-> ##1 (old_cal_sub_seq_out == cal_sub_seq_out)) else $fatal; //synthesis translate_on `endif //}}} endmodule // pcie_blk_ll_credit module my_SRL16E #( parameter INIT = 16'h0000 )( output Q, input A0, input A1, input A2, input A3, input CE, input CLK, input RST_N, input D ); reg [15:0] data = INIT; assign Q = data[{A3, A2, A1, A0}]; always @(posedge CLK) begin if (RST_N == 1'b0) {data[15:0]} <= #1 INIT; else if (CE == 1'b1) begin {data[15:0]} <= #1 {data[14:0], D}; end end endmodule
Go to most recent revision | Compare with Previous | Blame | View Log