module NV_NVDLA_SDP_WDMA_intr (
   nvdla_core_clk //|< i
  ,nvdla_core_rstn //|< i
  ,dma_wr_req_rdy //|< i
  ,dma_wr_req_vld //|< i
  ,dma_wr_rsp_complete //|< i
  ,intr_req_ptr //|< i
  ,intr_req_pvld //|< i
  ,op_load //|< i
  ,pwrbus_ram_pd //|< i
  ,reg2dp_ew_alu_algo //|< i
  ,reg2dp_ew_alu_bypass //|< i
  ,reg2dp_ew_bypass //|< i
  ,reg2dp_op_en //|< i
  ,reg2dp_output_dst //|< i
  ,reg2dp_perf_dma_en //|< i
  ,dp2reg_wdma_stall //|> o
  ,sdp2glb_done_intr_pd //|> o
  );
input [1:0] reg2dp_ew_alu_algo;
input reg2dp_ew_alu_bypass;
input reg2dp_ew_bypass;
input reg2dp_op_en;
input reg2dp_output_dst;
input reg2dp_perf_dma_en;
output [31:0] dp2reg_wdma_stall;
input intr_req_ptr;
input intr_req_pvld;
input [31:0] pwrbus_ram_pd;
input nvdla_core_clk;
input nvdla_core_rstn;
input dma_wr_req_rdy;
input dma_wr_req_vld;
input dma_wr_rsp_complete;
output [1:0] sdp2glb_done_intr_pd;
input op_load;
reg [31:0] dp2reg_wdma_stall;
reg [1:0] sdp2glb_done_intr_pd;
reg stl_adv;
reg [31:0] stl_cnt_cur;
reg [33:0] stl_cnt_dec;
reg [33:0] stl_cnt_ext;
reg [33:0] stl_cnt_inc;
reg [33:0] stl_cnt_mod;
reg [33:0] stl_cnt_new;
reg [33:0] stl_cnt_nxt;
wire cfg_mode_eql;
wire cfg_mode_pdp;
wire cfg_mode_quite;
wire dp2reg_wdma_stall_dec;
wire intr0_internal;
wire intr0_wr;
wire intr1_internal;
wire intr1_wr;
wire intr_fifo_rd_pd;
wire intr_fifo_rd_prdy;
wire intr_fifo_rd_pvld;
wire intr_fifo_wr_pd;
wire intr_fifo_wr_pvld;
wire mon_intr_fifo_rd_pvld;
wire wdma_stall_cnt_cen;
wire wdma_stall_cnt_clr;
wire wdma_stall_cnt_inc;
//============================
// CFG
//============================
assign cfg_mode_eql = (reg2dp_ew_bypass== 1'h0 )
                      & (reg2dp_ew_alu_bypass== 1'h0 )
                      & (reg2dp_ew_alu_algo== 2'h3 );
assign cfg_mode_pdp = reg2dp_output_dst== 1'h1 ;
assign cfg_mode_quite = cfg_mode_eql | cfg_mode_pdp;
//==============
// Interrupt
//==============
assign intr_fifo_wr_pvld = intr_req_pvld & !cfg_mode_quite;
assign intr_fifo_wr_pd = intr_req_ptr;
NV_NVDLA_SDP_WDMA_DAT_DMAIF_intr_fifo u_NV_NVDLA_SDP_WDMA_DAT_DMAIF_intr_fifo (
   .nvdla_core_clk (nvdla_core_clk) //|< i
  ,.nvdla_core_rstn (nvdla_core_rstn) //|< i
  ,.intr_fifo_wr_pvld (intr_fifo_wr_pvld) //|< w
  ,.intr_fifo_wr_pd (intr_fifo_wr_pd) //|< w
  ,.intr_fifo_rd_prdy (intr_fifo_rd_prdy) //|< w
  ,.intr_fifo_rd_pvld (intr_fifo_rd_pvld) //|> w
  ,.intr_fifo_rd_pd (intr_fifo_rd_pd) //|> w
  ,.pwrbus_ram_pd (pwrbus_ram_pd[31:0]) //|< i
  );
assign intr_fifo_rd_prdy = dma_wr_rsp_complete;
assign intr0_internal = cfg_mode_quite & intr_req_pvld & (intr_req_ptr==0);
assign intr0_wr = dma_wr_rsp_complete & (intr_fifo_rd_pd==0);
always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin
  if (!nvdla_core_rstn) begin
    sdp2glb_done_intr_pd[0] <= 1'b0;
  end else begin
  sdp2glb_done_intr_pd[0] <= intr0_wr | intr0_internal;
  end
end
assign intr1_internal = cfg_mode_quite & intr_req_pvld & (intr_req_ptr==1);
assign intr1_wr = dma_wr_rsp_complete & (intr_fifo_rd_pd==1);
always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin
  if (!nvdla_core_rstn) begin
    sdp2glb_done_intr_pd[1] <= 1'b0;
  end else begin
  sdp2glb_done_intr_pd[1] <= intr1_wr | intr1_internal;
  end
end
assign mon_intr_fifo_rd_pvld = intr_fifo_rd_pvld;
`ifdef SPYGLASS_ASSERT_ON
`else
// spyglass disable_block NoWidthInBasedNum-ML
// spyglass disable_block STARC-2.10.3.2a
// spyglass disable_block STARC05-2.1.3.1
// spyglass disable_block STARC-2.1.4.6
// spyglass disable_block W116
// spyglass disable_block W154
// spyglass disable_block W239
// spyglass disable_block W362
// spyglass disable_block WRN_58
// spyglass disable_block WRN_61
`endif // SPYGLASS_ASSERT_ON
`ifdef ASSERT_ON
`ifdef FV_ASSERT_ON
`define ASSERT_RESET nvdla_core_rstn
`else
`ifdef SYNTHESIS
`define ASSERT_RESET nvdla_core_rstn
`else
`ifdef ASSERT_OFF_RESET_IS_X
`define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b0 : nvdla_core_rstn)
`else
`define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b1 : nvdla_core_rstn)
`endif // ASSERT_OFF_RESET_IS_X
`endif // SYNTHESIS
`endif // FV_ASSERT_ON
// VCS coverage off
  nv_assert_never #(0,0,"when write complete, intr_ptr should be already in the head of intr_fifo read side") zzz_assert_never_1x (nvdla_core_clk, `ASSERT_RESET, !mon_intr_fifo_rd_pvld & intr_fifo_rd_prdy); // spyglass disable W504 SelfDeterminedExpr-ML 
// VCS coverage on
`undef ASSERT_RESET
`endif // ASSERT_ON
`ifdef SPYGLASS_ASSERT_ON
`else
// spyglass enable_block NoWidthInBasedNum-ML
// spyglass enable_block STARC-2.10.3.2a
// spyglass enable_block STARC05-2.1.3.1
// spyglass enable_block STARC-2.1.4.6
// spyglass enable_block W116
// spyglass enable_block W154
// spyglass enable_block W239
// spyglass enable_block W362
// spyglass enable_block WRN_58
// spyglass enable_block WRN_61
`endif // SPYGLASS_ASSERT_ON
`ifdef SPYGLASS_ASSERT_ON
`else
// spyglass disable_block NoWidthInBasedNum-ML
// spyglass disable_block STARC-2.10.3.2a
// spyglass disable_block STARC05-2.1.3.1
// spyglass disable_block STARC-2.1.4.6
// spyglass disable_block W116
// spyglass disable_block W154
// spyglass disable_block W239
// spyglass disable_block W362
// spyglass disable_block WRN_58
// spyglass disable_block WRN_61
`endif // SPYGLASS_ASSERT_ON
`ifdef ASSERT_ON
`ifdef FV_ASSERT_ON
`define ASSERT_RESET nvdla_core_rstn
`else
`ifdef SYNTHESIS
`define ASSERT_RESET nvdla_core_rstn
`else
`ifdef ASSERT_OFF_RESET_IS_X
`define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b0 : nvdla_core_rstn)
`else
`define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b1 : nvdla_core_rstn)
`endif // ASSERT_OFF_RESET_IS_X
`endif // SYNTHESIS
`endif // FV_ASSERT_ON
// VCS coverage off
  nv_assert_never #(0,0,"write intr0 and eql intr0 never happen in the same layer") zzz_assert_never_2x (nvdla_core_clk, `ASSERT_RESET, intr0_wr & intr0_internal); // spyglass disable W504 SelfDeterminedExpr-ML 
// VCS coverage on
`undef ASSERT_RESET
`endif // ASSERT_ON
`ifdef SPYGLASS_ASSERT_ON
`else
// spyglass enable_block NoWidthInBasedNum-ML
// spyglass enable_block STARC-2.10.3.2a
// spyglass enable_block STARC05-2.1.3.1
// spyglass enable_block STARC-2.1.4.6
// spyglass enable_block W116
// spyglass enable_block W154
// spyglass enable_block W239
// spyglass enable_block W362
// spyglass enable_block WRN_58
// spyglass enable_block WRN_61
`endif // SPYGLASS_ASSERT_ON
`ifdef SPYGLASS_ASSERT_ON
`else
// spyglass disable_block NoWidthInBasedNum-ML
// spyglass disable_block STARC-2.10.3.2a
// spyglass disable_block STARC05-2.1.3.1
// spyglass disable_block STARC-2.1.4.6
// spyglass disable_block W116
// spyglass disable_block W154
// spyglass disable_block W239
// spyglass disable_block W362
// spyglass disable_block WRN_58
// spyglass disable_block WRN_61
`endif // SPYGLASS_ASSERT_ON
`ifdef ASSERT_ON
`ifdef FV_ASSERT_ON
`define ASSERT_RESET nvdla_core_rstn
`else
`ifdef SYNTHESIS
`define ASSERT_RESET nvdla_core_rstn
`else
`ifdef ASSERT_OFF_RESET_IS_X
`define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b0 : nvdla_core_rstn)
`else
`define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b1 : nvdla_core_rstn)
`endif // ASSERT_OFF_RESET_IS_X
`endif // SYNTHESIS
`endif // FV_ASSERT_ON
// VCS coverage off
  nv_assert_never #(0,0,"write intr1 and eql intr1 never happen in the same layer") zzz_assert_never_3x (nvdla_core_clk, `ASSERT_RESET, intr1_wr & intr1_internal); // spyglass disable W504 SelfDeterminedExpr-ML 
// VCS coverage on
`undef ASSERT_RESET
`endif // ASSERT_ON
`ifdef SPYGLASS_ASSERT_ON
`else
// spyglass enable_block NoWidthInBasedNum-ML
// spyglass enable_block STARC-2.10.3.2a
// spyglass enable_block STARC05-2.1.3.1
// spyglass enable_block STARC-2.1.4.6
// spyglass enable_block W116
// spyglass enable_block W154
// spyglass enable_block W239
// spyglass enable_block W362
// spyglass enable_block WRN_58
// spyglass enable_block WRN_61
`endif // SPYGLASS_ASSERT_ON
//==============
// PERF STATISTIC
assign wdma_stall_cnt_inc = dma_wr_req_vld & !dma_wr_req_rdy;
assign wdma_stall_cnt_clr = op_load;
assign wdma_stall_cnt_cen = reg2dp_op_en & reg2dp_perf_dma_en;
    assign dp2reg_wdma_stall_dec = 1'b0;
    always @(
      wdma_stall_cnt_inc
      or dp2reg_wdma_stall_dec
      ) begin
      stl_adv = wdma_stall_cnt_inc ^ dp2reg_wdma_stall_dec;
    end
    always @(
      stl_cnt_cur
      or wdma_stall_cnt_inc
      or dp2reg_wdma_stall_dec
      or stl_adv
      or wdma_stall_cnt_clr
      ) begin
      stl_cnt_ext[33:0] = {1'b0, 1'b0, stl_cnt_cur};
      stl_cnt_inc[33:0] = stl_cnt_cur + 1'b1; // spyglass disable W164b
      stl_cnt_dec[33:0] = stl_cnt_cur - 1'b1; // spyglass disable W164b
      stl_cnt_mod[33:0] = (wdma_stall_cnt_inc && !dp2reg_wdma_stall_dec)? stl_cnt_inc : (!wdma_stall_cnt_inc && dp2reg_wdma_stall_dec)? stl_cnt_dec : stl_cnt_ext;
      stl_cnt_new[33:0] = (stl_adv)? stl_cnt_mod[33:0] : stl_cnt_ext[33:0];
      stl_cnt_nxt[33:0] = (wdma_stall_cnt_clr)? 34'd0 : stl_cnt_new[33:0];
    end
    always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin
      if (!nvdla_core_rstn) begin
        stl_cnt_cur[31:0] <= 0;
      end else begin
      if (wdma_stall_cnt_cen) begin
      stl_cnt_cur[31:0] <= stl_cnt_nxt[31:0];
      end
      end
    end
    always @(
      stl_cnt_cur
      ) begin
      dp2reg_wdma_stall[31:0] = stl_cnt_cur[31:0];
    end
endmodule // NV_NVDLA_SDP_WDMA_intr