Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—el2_pic_ctrl.sv Coverage Hit Total
Test Date: 03-01-2025 Toggle 97.1% 101 104
Test: all Branch 100.0% 24 24

            Line data    Source code
       1              : //********************************************************************************
       2              : // SPDX-License-Identifier: Apache-2.0
       3              : // Copyright 2020 Western Digital Corporation or its affiliates.
       4              : //
       5              : // Licensed under the Apache License, Version 2.0 (the "License");
       6              : // you may not use this file except in compliance with the License.
       7              : // You may obtain a copy of the License at
       8              : //
       9              : // http://www.apache.org/licenses/LICENSE-2.0
      10              : //
      11              : // Unless required by applicable law or agreed to in writing, software
      12              : // distributed under the License is distributed on an "AS IS" BASIS,
      13              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              : // See the License for the specific language governing permissions and
      15              : // limitations under the License.
      16              : //********************************************************************************
      17              : 
      18              : //********************************************************************************
      19              : // Function: Programmable Interrupt Controller
      20              : // Comments:
      21              : //********************************************************************************
      22              : 
      23              : module el2_pic_ctrl 
      24              : import el2_pkg::*;
      25              : #(
      26              : `include "el2_param.vh"
      27              :  )
      28              :                   (
      29              : 
      30     67357489 :                      input  logic                   clk,                  // Core clock
      31     67357489 :                      input  logic                   free_clk,             // free clock
      32          505 :                      input  logic                   rst_l,                // Reset for all flops
      33            4 :                      input  logic                   clk_override,         // Clock over-ride for gating
      34          302 :                      input  logic                   io_clk_override,      // PIC IO  Clock over-ride for gating
      35          269 :                      input  logic [pt.PIC_TOTAL_INT_PLUS1-1:0]   extintsrc_req,  // Interrupt requests
      36      1694287 :                      input  logic [31:0]            picm_rdaddr,          // Address of the register
      37      1710005 :                      input  logic [31:0]            picm_wraddr,          // Address of the register
      38       712136 :                      input  logic [31:0]            picm_wr_data,         // Data to be written to the register
      39        42900 :                      input  logic                   picm_wren,            // Write enable to the register
      40         9602 :                      input  logic                   picm_rden,            // Read enable for the register
      41           10 :                      input  logic                   picm_mken,            // Read the Mask for the register
      42         1216 :                      input  logic [3:0]             meicurpl,             // Current Priority Level
      43           57 :                      input  logic [3:0]             meipt,                // Current Priority Threshold
      44              : 
      45         1133 :                      output logic                   mexintpend,           // External Inerrupt request to the core
      46          834 :                      output logic [7:0]             claimid,              // Claim Id of the requested interrupt
      47          716 :                      output logic [3:0]             pl,                   // Priority level of the requested interrupt
      48         4770 :                      output logic [31:0]            picm_rd_data,         // Read data of the register
      49          159 :                      output logic                   mhwakeup,             // Wake-up interrupt request
      50              :                      // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
      51              :                      /*pragma coverage off*/
      52              :                      input  logic                   scan_mode             // scan mode
      53              :                      /*pragma coverage on*/
      54              : 
      55              : );
      56              : 
      57              : localparam NUM_LEVELS            = $clog2(pt.PIC_TOTAL_INT_PLUS1);
      58              : localparam INTPRIORITY_BASE_ADDR = pt.PIC_BASE_ADDR ;
      59              : localparam INTPEND_BASE_ADDR     = pt.PIC_BASE_ADDR + 32'h00001000 ;
      60              : localparam INTENABLE_BASE_ADDR   = pt.PIC_BASE_ADDR + 32'h00002000 ;
      61              : localparam EXT_INTR_PIC_CONFIG   = pt.PIC_BASE_ADDR + 32'h00003000 ;
      62              : localparam EXT_INTR_GW_CONFIG    = pt.PIC_BASE_ADDR + 32'h00004000 ;
      63              : localparam EXT_INTR_GW_CLEAR     = pt.PIC_BASE_ADDR + 32'h00005000 ;
      64              : 
      65              : 
      66              : localparam INTPEND_SIZE          = (pt.PIC_TOTAL_INT_PLUS1 <= 32)  ? 32  :
      67              :                                    (pt.PIC_TOTAL_INT_PLUS1 <= 64)  ? 64  :
      68              :                                    (pt.PIC_TOTAL_INT_PLUS1 <= 128) ? 128 :
      69              :                                    (pt.PIC_TOTAL_INT_PLUS1 <= 256) ? 256 :
      70              :                                    (pt.PIC_TOTAL_INT_PLUS1 <= 512) ? 512 :  1024 ;
      71              : 
      72              : localparam INT_GRPS              =  INTPEND_SIZE / 32 ;
      73              : localparam INTPRIORITY_BITS      =  4 ;
      74              : localparam ID_BITS               =  8 ;
      75              : localparam int GW_CONFIG[pt.PIC_TOTAL_INT_PLUS1-1:0] = '{default:0} ;
      76              : 
      77              : localparam INT_ENABLE_GRPS       =   (pt.PIC_TOTAL_INT_PLUS1 - 1)  / 4 ;
      78              : 
      79          474 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]           intenable_clk_enable ;
      80              : //logic [INT_ENABLE_GRPS:0]                    intenable_clk_enable_grp ;
      81            0 : logic [INT_ENABLE_GRPS:0]                    gw_clk ;
      82              : 
      83         1580 : logic  addr_intpend_base_match;
      84              : 
      85          634 : logic  raddr_config_pic_match ;
      86         4234 : logic  raddr_intenable_base_match;
      87      1965591 : logic  raddr_intpriority_base_match;
      88        11881 : logic  raddr_config_gw_base_match ;
      89              : 
      90          638 : logic  waddr_config_pic_match ;
      91      1965822 : logic  waddr_intpriority_base_match;
      92         4618 : logic  waddr_intenable_base_match;
      93        12260 : logic  waddr_config_gw_base_match ;
      94         1514 : logic  addr_clear_gw_base_match ;
      95              : 
      96         1133 : logic  mexintpend_in;
      97          159 : logic  mhwakeup_in ;
      98          200 : logic  intpend_reg_read ;
      99              : 
     100         4770 : logic [31:0]                                 picm_rd_data_in, intpend_rd_out;
     101         1464 : logic                                        intenable_rd_out ;
     102         1560 : logic [INTPRIORITY_BITS-1:0]                 intpriority_rd_out;
     103         1572 : logic [1:0]                                  gw_config_rd_out;
     104              : 
     105          106 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [INTPRIORITY_BITS-1:0] intpriority_reg;
     106          127 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [INTPRIORITY_BITS-1:0] intpriority_reg_inv;
     107          302 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        intpriority_reg_we;
     108          100 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        intpriority_reg_re;
     109          236 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [1:0]                  gw_config_reg;
     110              : 
     111           85 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        intenable_reg;
     112          502 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        intenable_reg_we;
     113          100 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        intenable_reg_re;
     114          502 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        gw_config_reg_we;
     115          100 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        gw_config_reg_re;
     116          106 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        gw_clear_reg_we;
     117              : 
     118          279 : logic [INTPEND_SIZE-1:0]                     intpend_reg_extended;
     119              : 
     120          106 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [INTPRIORITY_BITS-1:0] intpend_w_prior_en;
     121          304 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [ID_BITS-1:0]          intpend_id;
     122          325 : logic [INTPRIORITY_BITS-1:0]                 maxint;
     123          713 : logic [INTPRIORITY_BITS-1:0]                 selected_int_priority;
     124          132 : logic [INT_GRPS-1:0] [31:0]                  intpend_rd_part_out ;
     125              : 
     126           21 : logic                                        config_reg;
     127           21 : logic                                        intpriord;
     128          104 : logic                                        config_reg_we ;
     129          100 : logic                                        config_reg_re ;
     130       556657 : logic                                        config_reg_in ;
     131         3102 : logic                                        intpriority_reg_read ;
     132         3100 : logic                                        intenable_reg_read   ;
     133         3100 : logic                                        gw_config_reg_read   ;
     134        42902 : logic                                        picm_wren_ff , picm_rden_ff ;
     135      1694254 : logic [31:0]                                 picm_raddr_ff;
     136      1710004 : logic [31:0]                                 picm_waddr_ff;
     137       712123 : logic [31:0]                                 picm_wr_data_ff;
     138        19247 : logic [3:0]                                  mask;
     139           10 : logic                                        picm_mken_ff;
     140          834 : logic [ID_BITS-1:0]                          claimid_in ;
     141          713 : logic [INTPRIORITY_BITS-1:0]                 pl_in ;
     142          734 : logic [INTPRIORITY_BITS-1:0]                 pl_in_q ;
     143              : 
     144              : //logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        extintsrc_req_sync;
     145          279 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        extintsrc_req_gw;
     146            0 :    logic                                                  picm_bypass_ff;
     147              : 
     148              : // clkens
     149         9616 :    logic                                     pic_raddr_c1_clken;
     150            0 :    logic                                     pic_waddr_c1_clken;
     151        42904 :    logic                                     pic_data_c1_clken;
     152        12408 :    logic                                     pic_pri_c1_clken;
     153        18606 :    logic                                     pic_int_c1_clken;
     154        18606 :    logic                                     gw_config_c1_clken;
     155              : 
     156              : // clocks
     157     67238537 :    logic                                     pic_raddr_c1_clk;
     158     67271829 :    logic                                     pic_data_c1_clk;
     159     67241337 :    logic                                     pic_pri_c1_clk;
     160     67247537 :    logic                                     pic_int_c1_clk;
     161     67247537 :    logic                                     gw_config_c1_clk;
     162              : 
     163              : // ---- Clock gating section ------
     164              : // c1 clock enables
     165              :    assign pic_raddr_c1_clken  = picm_mken | picm_rden | clk_override;
     166              :    assign pic_data_c1_clken   = picm_wren | clk_override;
     167              :    assign pic_pri_c1_clken    = (waddr_intpriority_base_match & picm_wren_ff)  | (raddr_intpriority_base_match & picm_rden_ff) | clk_override;
     168              :    assign pic_int_c1_clken    = (waddr_intenable_base_match   & picm_wren_ff)  | (raddr_intenable_base_match   & picm_rden_ff) | clk_override;
     169              :    assign gw_config_c1_clken  = (waddr_config_gw_base_match   & picm_wren_ff)  | (raddr_config_gw_base_match   & picm_rden_ff) | clk_override;
     170              : 
     171              :    // C1 - 1 clock pulse for data
     172              :    rvoclkhdr pic_addr_c1_cgc   ( .en(pic_raddr_c1_clken),  .l1clk(pic_raddr_c1_clk), .* );
     173              :    rvoclkhdr pic_data_c1_cgc   ( .en(pic_data_c1_clken),   .l1clk(pic_data_c1_clk), .* );
     174              :    rvoclkhdr pic_pri_c1_cgc    ( .en(pic_pri_c1_clken),    .l1clk(pic_pri_c1_clk),  .* );
     175              :    rvoclkhdr pic_int_c1_cgc    ( .en(pic_int_c1_clken),    .l1clk(pic_int_c1_clk),  .* );
     176              :    rvoclkhdr gw_config_c1_cgc  ( .en(gw_config_c1_clken),  .l1clk(gw_config_c1_clk),  .* );
     177              : 
     178              : // ------ end clock gating section ------------------------
     179              : 
     180              : assign raddr_intenable_base_match   = (picm_raddr_ff[31:NUM_LEVELS+2] == INTENABLE_BASE_ADDR[31:NUM_LEVELS+2]) ;
     181              : assign raddr_intpriority_base_match = (picm_raddr_ff[31:NUM_LEVELS+2] == INTPRIORITY_BASE_ADDR[31:NUM_LEVELS+2]) ;
     182              : assign raddr_config_gw_base_match   = (picm_raddr_ff[31:NUM_LEVELS+2] == EXT_INTR_GW_CONFIG[31:NUM_LEVELS+2]) ;
     183              : assign raddr_config_pic_match       = (picm_raddr_ff[31:0]            == EXT_INTR_PIC_CONFIG[31:0]) ;
     184              : 
     185              : assign addr_intpend_base_match      = (picm_raddr_ff[31:6]            == INTPEND_BASE_ADDR[31:6]) ;
     186              : 
     187              : assign waddr_config_pic_match       = (picm_waddr_ff[31:0]            == EXT_INTR_PIC_CONFIG[31:0]) ;
     188              : assign addr_clear_gw_base_match     = (picm_waddr_ff[31:NUM_LEVELS+2] == EXT_INTR_GW_CLEAR[31:NUM_LEVELS+2]) ;
     189              : assign waddr_intpriority_base_match = (picm_waddr_ff[31:NUM_LEVELS+2] == INTPRIORITY_BASE_ADDR[31:NUM_LEVELS+2]) ;
     190              : assign waddr_intenable_base_match   = (picm_waddr_ff[31:NUM_LEVELS+2] == INTENABLE_BASE_ADDR[31:NUM_LEVELS+2]) ;
     191              : assign waddr_config_gw_base_match   = (picm_waddr_ff[31:NUM_LEVELS+2] == EXT_INTR_GW_CONFIG[31:NUM_LEVELS+2]) ;
     192              : 
     193              :    assign picm_bypass_ff = picm_rden_ff & picm_wren_ff & ( picm_raddr_ff[31:0] == picm_waddr_ff[31:0] );    // pic writes and reads to same address together
     194              : 
     195              : 
     196              : rvdff #(32) picm_radd_flop  (.*, .din (picm_rdaddr),        .dout(picm_raddr_ff),         .clk(pic_raddr_c1_clk));
     197              : rvdff #(32) picm_wadd_flop  (.*, .din (picm_wraddr),        .dout(picm_waddr_ff),         .clk(pic_data_c1_clk));
     198              : rvdff  #(1) picm_wre_flop   (.*, .din (picm_wren),          .dout(picm_wren_ff),          .clk(free_clk));
     199              : rvdff  #(1) picm_rde_flop   (.*, .din (picm_rden),          .dout(picm_rden_ff),          .clk(free_clk));
     200              : rvdff  #(1) picm_mke_flop   (.*, .din (picm_mken),          .dout(picm_mken_ff),          .clk(free_clk));
     201              : rvdff #(32) picm_dat_flop   (.*, .din (picm_wr_data[31:0]), .dout(picm_wr_data_ff[31:0]), .clk(pic_data_c1_clk));
     202              : 
     203              : //rvsyncss  #(pt.PIC_TOTAL_INT_PLUS1-1) sync_inst
     204              : //(
     205              : // .clk (free_clk),
     206              : // .dout(extintsrc_req_sync[pt.PIC_TOTAL_INT_PLUS1-1:1]),
     207              : // .din (extintsrc_req[pt.PIC_TOTAL_INT_PLUS1-1:1]),
     208              : // .*) ;
     209              : //
     210              : //assign extintsrc_req_sync[0] = extintsrc_req[0];
     211              : /*
     212              : genvar p ;
     213              : for (p=0; p<=INT_ENABLE_GRPS ; p++) begin  : IO_CLK_GRP
     214              :    if (p==INT_ENABLE_GRPS) begin : LAST_GRP
     215              :        assign intenable_clk_enable_grp[p] = |intenable_clk_enable[pt.PIC_TOTAL_INT_PLUS1-1 : p*4] | io_clk_override;
     216              :        rvoclkhdr intenable_c1_cgc   ( .en(intenable_clk_enable_grp[p]),  .l1clk(gw_clk[p]), .* );
     217              :    end else begin :  CLK_GRPS
     218              :        assign intenable_clk_enable_grp[p] = |intenable_clk_enable[p*4+3 : p*4] | io_clk_override;
     219              :        rvoclkhdr intenable_c1_cgc   ( .en(intenable_clk_enable_grp[p]),  .l1clk(gw_clk[p]), .* );
     220              :    end
     221              : end
     222              : */
     223              : 
     224              : 
     225              : 
     226              : genvar i ;
     227              : genvar p ;
     228              : for (p=0; p<=INT_ENABLE_GRPS ; p++) begin  : IO_CLK_GRP
     229              : wire grp_clk, grp_clken;
     230              : 
     231              :     assign grp_clken = |intenable_clk_enable[(p==INT_ENABLE_GRPS?pt.PIC_TOTAL_INT_PLUS1-1:p*4+3) : p*4] | io_clk_override;
     232              : 
     233              :   `ifndef RV_FPGA_OPTIMIZE
     234              :     rvclkhdr intenable_c1_cgc( .en(grp_clken),  .l1clk(grp_clk), .* );
     235              :   `else
     236              : /*pragma coverage off*/
     237              :     assign gw_clk[p] = 1'b0 ;
     238              : /*pragma coverage on*/
     239              :   `endif
     240              : 
     241              :     for(genvar i= (p==0 ? 1: 0); i< (p==INT_ENABLE_GRPS ? pt.PIC_TOTAL_INT_PLUS1-p*4 :4); i++) begin : GW
     242              :         el2_configurable_gw gw_inst(
     243              :              .*,
     244              :             .gw_clk(grp_clk),
     245              :             .rawclk(clk),
     246              :             .clken (grp_clken),
     247              :             .extintsrc_req(extintsrc_req[i+p*4]) ,
     248              :             .meigwctrl_polarity(gw_config_reg[i+p*4][0]) ,
     249              :             .meigwctrl_type(gw_config_reg[i+p*4][1]) ,
     250              :             .meigwclr(gw_clear_reg_we[i+p*4]) ,
     251              :             .extintsrc_req_config(extintsrc_req_gw[i+p*4])
     252              :         );
     253              :     end
     254              : end
     255              : 
     256              : 
     257              : 
     258              : 
     259              : 
     260              : 
     261              : 
     262              : 
     263              : for (i=0; i<pt.PIC_TOTAL_INT_PLUS1 ; i++) begin  : SETREG
     264              : 
     265              :  if (i > 0 ) begin : NON_ZERO_INT
     266              :      assign intpriority_reg_we[i] =  waddr_intpriority_base_match & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff;
     267              :      assign intpriority_reg_re[i] =  raddr_intpriority_base_match & (picm_raddr_ff[NUM_LEVELS+1:2] == i) & picm_rden_ff;
     268              : 
     269              :      assign intenable_reg_we[i]   =  waddr_intenable_base_match   & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff;
     270              :      assign intenable_reg_re[i]   =  raddr_intenable_base_match   & (picm_raddr_ff[NUM_LEVELS+1:2] == i) & picm_rden_ff;
     271              : 
     272              :      assign gw_config_reg_we[i]   =  waddr_config_gw_base_match   & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff;
     273              :      assign gw_config_reg_re[i]   =  raddr_config_gw_base_match   & (picm_raddr_ff[NUM_LEVELS+1:2] == i) & picm_rden_ff;
     274              : 
     275              :      assign gw_clear_reg_we[i]    =  addr_clear_gw_base_match     & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff ;
     276              : 
     277              :      rvdffs #(INTPRIORITY_BITS) intpriority_ff  (.*, .en( intpriority_reg_we[i]), .din (picm_wr_data_ff[INTPRIORITY_BITS-1:0]), .dout(intpriority_reg[i]), .clk(pic_pri_c1_clk));
     278              :      rvdffs #(1)                 intenable_ff   (.*, .en( intenable_reg_we[i]),   .din (picm_wr_data_ff[0]),                    .dout(intenable_reg[i]),   .clk(pic_int_c1_clk));
     279              :      rvdffs #(2)                 gw_config_ff   (.*, .en( gw_config_reg_we[i]),   .din (picm_wr_data_ff[1:0]),                  .dout(gw_config_reg[i]),   .clk(gw_config_c1_clk));
     280              : 
     281              :      assign intenable_clk_enable[i]  =  gw_config_reg[i][1] | intenable_reg_we[i] | intenable_reg[i] | gw_clear_reg_we[i] ;
     282              : 
     283              : /*
     284              :      rvsyncss_fpga  #(1) sync_inst
     285              :      (
     286              :       .gw_clk      (gw_clk[i/4]),
     287              :       .rawclk      (clk),
     288              :       .clken       (intenable_clk_enable_grp[i/4]),
     289              :       .dout        (extintsrc_req_sync[i]),
     290              :       .din         (extintsrc_req[i]),
     291              :       .*) ;
     292              : 
     293              : 
     294              : 
     295              : 
     296              : 
     297              :         el2_configurable_gw config_gw_inst(.*,
     298              :                                             .gw_clk(gw_clk[i/4]),
     299              :                                             .rawclk(clk),
     300              :                                             .clken (intenable_clk_enable_grp[i/4]),
     301              :                                             .extintsrc_req_sync(extintsrc_req_sync[i]) ,
     302              :                                             .meigwctrl_polarity(gw_config_reg[i][0]) ,
     303              :                                             .meigwctrl_type(gw_config_reg[i][1]) ,
     304              :                                             .meigwclr(gw_clear_reg_we[i]) ,
     305              :                                             .extintsrc_req_config(extintsrc_req_gw[i])
     306              :                                             );
     307              :              */
     308              : 
     309              :  end else begin : INT_ZERO
     310              :      assign intpriority_reg_we[i] =  1'b0 ;
     311              :      assign intpriority_reg_re[i] =  1'b0 ;
     312              :      assign intenable_reg_we[i]   =  1'b0 ;
     313              :      assign intenable_reg_re[i]   =  1'b0 ;
     314              : 
     315              :      assign gw_config_reg_we[i]   =  1'b0 ;
     316              :      assign gw_config_reg_re[i]   =  1'b0 ;
     317              :      assign gw_clear_reg_we[i]    =  1'b0 ;
     318              : 
     319              :      assign gw_config_reg[i]    = '0 ;
     320              : 
     321              :      assign intpriority_reg[i] = {INTPRIORITY_BITS{1'b0}} ;
     322              :      assign intenable_reg[i]   = 1'b0 ;
     323              :      assign extintsrc_req_gw[i] = 1'b0 ;
     324              : //     assign extintsrc_req_sync[i]    = 1'b0 ;
     325              :      assign intenable_clk_enable[i] = 1'b0;
     326              :  end
     327              : 
     328              : 
     329    873824832 :     assign intpriority_reg_inv[i] =  intpriord ? ~intpriority_reg[i] : intpriority_reg[i] ;
     330              : 
     331              :     assign intpend_w_prior_en[i]  =  {INTPRIORITY_BITS{(extintsrc_req_gw[i] & intenable_reg[i])}} & intpriority_reg_inv[i] ;
     332              :     assign intpend_id[i]          =  i ;
     333              : end
     334              : 
     335              : 
     336              :         assign pl_in[INTPRIORITY_BITS-1:0]                  =      selected_int_priority[INTPRIORITY_BITS-1:0] ;
     337              : 
     338              : //if (pt.PIC_2CYCLE == 1) begin : genblock
     339              : //end
     340              : //else begin : genblock
     341              : //end
     342              : 
     343              :  genvar l, m , j, k;
     344              : 
     345              : if (pt.PIC_2CYCLE == 1) begin : genblock
     346              :         logic [NUM_LEVELS/2:0] [pt.PIC_TOTAL_INT_PLUS1+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
     347              :         logic [NUM_LEVELS/2:0] [pt.PIC_TOTAL_INT_PLUS1+2:0] [ID_BITS-1:0]          level_intpend_id;
     348              :         logic [NUM_LEVELS:NUM_LEVELS/2] [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] [INTPRIORITY_BITS-1:0] levelx_intpend_w_prior_en;
     349              :         logic [NUM_LEVELS:NUM_LEVELS/2] [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] [ID_BITS-1:0]          levelx_intpend_id;
     350              : 
     351              :         assign level_intpend_w_prior_en[0][pt.PIC_TOTAL_INT_PLUS1+2:0] = {4'b0,4'b0,4'b0,intpend_w_prior_en[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
     352              :         assign level_intpend_id[0][pt.PIC_TOTAL_INT_PLUS1+2:0]         = {8'b0,8'b0,8'b0,intpend_id[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
     353              : 
     354              :         logic [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0] [INTPRIORITY_BITS-1:0] l2_intpend_w_prior_en_ff;
     355              :         logic [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0] [ID_BITS-1:0]          l2_intpend_id_ff;
     356              : 
     357              :         assign levelx_intpend_w_prior_en[NUM_LEVELS/2][(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] = {{1*INTPRIORITY_BITS{1'b0}},l2_intpend_w_prior_en_ff[(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0]} ;
     358              :         assign levelx_intpend_id[NUM_LEVELS/2][(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0]         = {{1*ID_BITS{1'b1}},l2_intpend_id_ff[(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0]} ;
     359              : ///  Do the prioritization of the interrupts here  ////////////
     360              :  for (l=0; l<NUM_LEVELS/2 ; l++) begin : TOP_LEVEL
     361              :     for (m=0; m<=(pt.PIC_TOTAL_INT_PLUS1)/(2**(l+1)) ; m++) begin : COMPARE
     362              :        if ( m == (pt.PIC_TOTAL_INT_PLUS1)/(2**(l+1))) begin
     363              :             assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
     364              :             assign level_intpend_id[l+1][m+1]         = '0 ;
     365              :        end
     366              :        el2_cmp_and_mux  #(.ID_BITS(ID_BITS),
     367              :                       .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
     368              :                       .a_id(level_intpend_id[l][2*m]),
     369              :                       .a_priority(level_intpend_w_prior_en[l][2*m]),
     370              :                       .b_id(level_intpend_id[l][2*m+1]),
     371              :                       .b_priority(level_intpend_w_prior_en[l][2*m+1]),
     372              :                       .out_id(level_intpend_id[l+1][m]),
     373              :                       .out_priority(level_intpend_w_prior_en[l+1][m])) ;
     374              : 
     375              :     end
     376              :  end
     377              : 
     378              :         for (i=0; i<=pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2) ; i++) begin : MIDDLE_FLOPS
     379              :           rvdff #(INTPRIORITY_BITS) level2_intpend_prior_reg  (.*, .din (level_intpend_w_prior_en[NUM_LEVELS/2][i]), .dout(l2_intpend_w_prior_en_ff[i]),  .clk(free_clk));
     380              :           rvdff #(ID_BITS)          level2_intpend_id_reg     (.*, .din (level_intpend_id[NUM_LEVELS/2][i]),         .dout(l2_intpend_id_ff[i]),          .clk(free_clk));
     381              :         end
     382              : 
     383              :  for (j=NUM_LEVELS/2; j<NUM_LEVELS ; j++) begin : BOT_LEVELS
     384              :     for (k=0; k<=(pt.PIC_TOTAL_INT_PLUS1)/(2**(j+1)) ; k++) begin : COMPARE
     385              :        if ( k == (pt.PIC_TOTAL_INT_PLUS1)/(2**(j+1))) begin
     386              :             assign levelx_intpend_w_prior_en[j+1][k+1] = '0 ;
     387              :             assign levelx_intpend_id[j+1][k+1]         = '0 ;
     388              :        end
     389              :             el2_cmp_and_mux  #(.ID_BITS(ID_BITS),
     390              :                         .INTPRIORITY_BITS(INTPRIORITY_BITS))
     391              :                  cmp_l1 (
     392              :                         .a_id(levelx_intpend_id[j][2*k]),
     393              :                         .a_priority(levelx_intpend_w_prior_en[j][2*k]),
     394              :                         .b_id(levelx_intpend_id[j][2*k+1]),
     395              :                         .b_priority(levelx_intpend_w_prior_en[j][2*k+1]),
     396              :                         .out_id(levelx_intpend_id[j+1][k]),
     397              :                         .out_priority(levelx_intpend_w_prior_en[j+1][k])) ;
     398              :     end
     399              :   end
     400              :         assign claimid_in[ID_BITS-1:0]                      =      levelx_intpend_id[NUM_LEVELS][0] ;   // This is the last level output
     401              :         assign selected_int_priority[INTPRIORITY_BITS-1:0]  =      levelx_intpend_w_prior_en[NUM_LEVELS][0] ;
     402              : end
     403              : else begin : genblock
     404              : 
     405              :         logic [NUM_LEVELS:0] [pt.PIC_TOTAL_INT_PLUS1+1:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
     406              :         logic [NUM_LEVELS:0] [pt.PIC_TOTAL_INT_PLUS1+1:0] [ID_BITS-1:0]          level_intpend_id;
     407              : 
     408              :         assign level_intpend_w_prior_en[0][pt.PIC_TOTAL_INT_PLUS1+1:0] = {{2*INTPRIORITY_BITS{1'b0}},intpend_w_prior_en[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
     409              :         assign level_intpend_id[0][pt.PIC_TOTAL_INT_PLUS1+1:0] = {{2*ID_BITS{1'b1}},intpend_id[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
     410              : 
     411              : ///  Do the prioritization of the interrupts here  ////////////
     412              : // genvar l, m , j, k;  already declared outside ifdef
     413              :  for (l=0; l<NUM_LEVELS ; l++) begin : LEVEL
     414              :     for (m=0; m<=(pt.PIC_TOTAL_INT_PLUS1)/(2**(l+1)) ; m++) begin : COMPARE
     415              :        if ( m == (pt.PIC_TOTAL_INT_PLUS1)/(2**(l+1))) begin
     416              :             assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
     417              :             assign level_intpend_id[l+1][m+1]         = '0 ;
     418              :        end
     419              :        el2_cmp_and_mux  #(.ID_BITS(ID_BITS),
     420              :                       .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
     421              :                       .a_id(level_intpend_id[l][2*m]),
     422              :                       .a_priority(level_intpend_w_prior_en[l][2*m]),
     423              :                       .b_id(level_intpend_id[l][2*m+1]),
     424              :                       .b_priority(level_intpend_w_prior_en[l][2*m+1]),
     425              :                       .out_id(level_intpend_id[l+1][m]),
     426              :                       .out_priority(level_intpend_w_prior_en[l+1][m])) ;
     427              : 
     428              :     end
     429              :  end
     430              :         assign claimid_in[ID_BITS-1:0]                      =      level_intpend_id[NUM_LEVELS][0] ;   // This is the last level output
     431              :         assign selected_int_priority[INTPRIORITY_BITS-1:0]  =      level_intpend_w_prior_en[NUM_LEVELS][0] ;
     432              : 
     433              : end
     434              : 
     435              : 
     436              : 
     437              : ///////////////////////////////////////////////////////////////////////
     438              : // Config Reg`
     439              : ///////////////////////////////////////////////////////////////////////
     440              : assign config_reg_we               =  waddr_config_pic_match & picm_wren_ff;
     441              : assign config_reg_re               =  raddr_config_pic_match & picm_rden_ff;
     442              : 
     443              : assign config_reg_in  =  picm_wr_data_ff[0] ;   //
     444              : rvdffs #(1) config_reg_ff  (.*, .clk(free_clk), .en(config_reg_we), .din (config_reg_in), .dout(config_reg));
     445              : 
     446              : assign intpriord  = config_reg ;
     447              : 
     448              : 
     449              : 
     450              : //////////////////////////////////////////////////////////////////////////
     451              : // Send the interrupt to the core if it is above the thresh-hold
     452              : //////////////////////////////////////////////////////////////////////////
     453              : ///////////////////////////////////////////////////////////
     454              : /// ClaimId  Reg and Corresponding PL
     455              : ///////////////////////////////////////////////////////////
     456              : //
     457     27307026 : assign pl_in_q[INTPRIORITY_BITS-1:0] = intpriord ? ~pl_in : pl_in ;
     458              : rvdff #(ID_BITS)          claimid_ff  (.*,  .din (claimid_in[ID_BITS-1:00]),     .dout(claimid[ID_BITS-1:00]),    .clk(free_clk));
     459              : rvdff  #(INTPRIORITY_BITS) pl_ff      (.*, .din (pl_in_q[INTPRIORITY_BITS-1:0]), .dout(pl[INTPRIORITY_BITS-1:0]), .clk(free_clk));
     460              : 
     461         1237 : logic [INTPRIORITY_BITS-1:0] meipt_inv , meicurpl_inv ;
     462     27307026 : assign meipt_inv[INTPRIORITY_BITS-1:0]    = intpriord ? ~meipt[INTPRIORITY_BITS-1:0]    : meipt[INTPRIORITY_BITS-1:0] ;
     463     27307026 : assign meicurpl_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meicurpl[INTPRIORITY_BITS-1:0] : meicurpl[INTPRIORITY_BITS-1:0] ;
     464              : assign mexintpend_in = (( selected_int_priority[INTPRIORITY_BITS-1:0] > meipt_inv[INTPRIORITY_BITS-1:0]) &
     465              :                         ( selected_int_priority[INTPRIORITY_BITS-1:0] > meicurpl_inv[INTPRIORITY_BITS-1:0]) );
     466              : rvdff #(1) mexintpend_ff  (.*, .clk(free_clk), .din (mexintpend_in), .dout(mexintpend));
     467              : 
     468     27307026 : assign maxint[INTPRIORITY_BITS-1:0]      =  intpriord ? 0 : 15 ;
     469              : assign mhwakeup_in = ( pl_in_q[INTPRIORITY_BITS-1:0] == maxint) ;
     470              : rvdff #(1) wake_up_ff  (.*, .clk(free_clk), .din (mhwakeup_in), .dout(mhwakeup));
     471              : 
     472              : 
     473              : 
     474              : 
     475              : 
     476              : //////////////////////////////////////////////////////////////////////////
     477              : //  Reads of register.
     478              : //  1- intpending
     479              : //////////////////////////////////////////////////////////////////////////
     480              : 
     481              : assign intpend_reg_read     =  addr_intpend_base_match      & picm_rden_ff ;
     482              : assign intpriority_reg_read =  raddr_intpriority_base_match & picm_rden_ff;
     483              : assign intenable_reg_read   =  raddr_intenable_base_match   & picm_rden_ff;
     484              : assign gw_config_reg_read   =  raddr_config_gw_base_match   & picm_rden_ff;
     485              : 
     486              : assign intpend_reg_extended[INTPEND_SIZE-1:0]  = {{INTPEND_SIZE-pt.PIC_TOTAL_INT_PLUS1{1'b0}},extintsrc_req_gw[pt.PIC_TOTAL_INT_PLUS1-1:0]} ;
     487              : 
     488              :    for (i=0; i<(INT_GRPS); i++) begin
     489              :             assign intpend_rd_part_out[i] =  (({32{intpend_reg_read & picm_raddr_ff[5:2] == i}}) & intpend_reg_extended[((32*i)+31):(32*i)]) ;
     490              :    end
     491              : 
     492          304 :    always_comb begin : INTPEND_RD
     493          304 :          intpend_rd_out =  '0 ;
     494          304 :          for (int i=0; i<INT_GRPS; i++) begin
     495          304 :                intpend_rd_out |=  intpend_rd_part_out[i] ;
     496              :          end
     497              :    end
     498              : 
     499     27354860 :    always_comb begin : INTEN_RD
     500     27354860 :          intenable_rd_out =  '0 ;
     501     27354860 :          intpriority_rd_out =  '0 ;
     502     27354860 :          gw_config_rd_out =  '0 ;
     503    875355520 :          for (int i=0; i<pt.PIC_TOTAL_INT_PLUS1; i++) begin
     504    875346220 :               if (intenable_reg_re[i]) begin
     505         9300 :                intenable_rd_out    =  intenable_reg[i]  ;
     506              :               end
     507    875346220 :               if (intpriority_reg_re[i]) begin
     508         9300 :                intpriority_rd_out  =  intpriority_reg[i] ;
     509              :               end
     510    875346220 :               if (gw_config_reg_re[i]) begin
     511         9300 :                gw_config_rd_out  =  gw_config_reg[i] ;
     512              :               end
     513              :          end
     514              :    end
     515              : 
     516              : 
     517              :  assign picm_rd_data_in[31:0] = ({32{intpend_reg_read      }} &   intpend_rd_out                                                    ) |
     518              :                                 ({32{intpriority_reg_read  }} &  {{32-INTPRIORITY_BITS{1'b0}}, intpriority_rd_out                 } ) |
     519              :                                 ({32{intenable_reg_read    }} &  {31'b0 , intenable_rd_out                                        } ) |
     520              :                                 ({32{gw_config_reg_read    }} &  {30'b0 , gw_config_rd_out                                        } ) |
     521              :                                 ({32{config_reg_re         }} &  {31'b0 , config_reg                                              } ) |
     522              :                                 ({32{picm_mken_ff & mask[3]}} &  {30'b0 , 2'b11                                                   } ) |
     523              :                                 ({32{picm_mken_ff & mask[2]}} &  {31'b0 , 1'b1                                                    } ) |
     524              :                                 ({32{picm_mken_ff & mask[1]}} &  {28'b0 , 4'b1111                                                 } ) |
     525              :                                 ({32{picm_mken_ff & mask[0]}} &   32'b0                                                             ) ;
     526              : 
     527              : 
     528     27354860 : assign picm_rd_data[31:0] = picm_bypass_ff ? picm_wr_data_ff[31:0] : picm_rd_data_in[31:0] ;
     529              : 
     530      1694236 : logic [14:0] address;
     531              : 
     532              : assign address[14:0] = picm_raddr_ff[14:0];
     533              : 
     534              : `include "pic_map_auto.h"
     535              : 
     536              : endmodule
     537              : 
     538              : 
     539              : module el2_cmp_and_mux #(parameter ID_BITS=8,
     540              :                                INTPRIORITY_BITS = 4)
     541              :                     (
     542         8750 :                         input  logic [ID_BITS-1:0]       a_id,
     543         3816 :                         input  logic [INTPRIORITY_BITS-1:0] a_priority,
     544              : 
     545         7965 :                         input  logic [ID_BITS-1:0]       b_id,
     546         3952 :                         input  logic [INTPRIORITY_BITS-1:0] b_priority,
     547              : 
     548        12332 :                         output logic [ID_BITS-1:0]       out_id,
     549         6272 :                         output logic [INTPRIORITY_BITS-1:0] out_priority
     550              : 
     551              :                     );
     552              : 
     553         6207 : logic   a_is_lt_b ;
     554              : 
     555              : assign  a_is_lt_b  = ( a_priority[INTPRIORITY_BITS-1:0] < b_priority[INTPRIORITY_BITS-1:0] ) ;
     556              : 
     557    983016770 : assign  out_id[ID_BITS-1:0]                = a_is_lt_b ? b_id[ID_BITS-1:0] :
     558              :                                                          a_id[ID_BITS-1:0] ;
     559    983016770 : assign  out_priority[INTPRIORITY_BITS-1:0] = a_is_lt_b ? b_priority[INTPRIORITY_BITS-1:0] :
     560              :                                                          a_priority[INTPRIORITY_BITS-1:0] ;
     561              : endmodule // cmp_and_mux
     562              : 
     563              : 
     564              : module el2_configurable_gw (
     565      3397872 :                              input logic gw_clk,
     566   1671817307 :                              input logic rawclk,
     567        39994 :                              input logic clken,
     568        15664 :                              input logic rst_l,
     569         6615 :                              input logic extintsrc_req ,
     570          748 :                              input logic meigwctrl_polarity ,
     571         7064 :                              input logic meigwctrl_type ,
     572         2500 :                              input logic meigwclr ,
     573              : 
     574         6290 :                              output logic extintsrc_req_config
     575              :                             );
     576              : 
     577              : 
     578         6645 :   logic  gw_int_pending_in, gw_int_pending, extintsrc_req_sync;
     579              : 
     580              :   rvsyncss_fpga  #(1) sync_inst (
     581              :       .dout        (extintsrc_req_sync),
     582              :       .din         (extintsrc_req),
     583              :       .*) ;
     584              : 
     585              : 
     586              :   assign gw_int_pending_in =  (extintsrc_req_sync ^ meigwctrl_polarity) | (gw_int_pending & ~meigwclr) ;
     587              :   rvdff_fpga #(1) int_pend_ff        (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (gw_int_pending_in),     .dout(gw_int_pending));
     588              : 
     589              : 
     590    844158418 :   assign extintsrc_req_config =  meigwctrl_type ? ((extintsrc_req_sync ^  meigwctrl_polarity) | gw_int_pending) : (extintsrc_req_sync ^  meigwctrl_polarity) ;
     591              : 
     592              : endmodule // configurable_gw
     593              : 
     594              : 
     595              : 
     596              : 
     597              : 
     598              : 
     599              : 
     600              : 
     601              :