Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—el2_pic_ctrl.sv Coverage Hit Total
Test Date: 14-11-2024 Toggle 86.9% 93 107
Test: all Branch 100.0% 15 15

            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     69932226 :                      input  logic                   clk,                  // Core clock
      31     69932226 :                      input  logic                   free_clk,             // free clock
      32          343 :                      input  logic                   rst_l,                // Reset for all flops
      33            4 :                      input  logic                   clk_override,         // Clock over-ride for gating
      34          343 :                      input  logic                   io_clk_override,      // PIC IO  Clock over-ride for gating
      35          100 :                      input  logic [pt.PIC_TOTAL_INT_PLUS1-1:0]   extintsrc_req,  // Interrupt requests
      36          435 :                      input  logic [31:0]            picm_rdaddr,          // Address of the register
      37          435 :                      input  logic [31:0]            picm_wraddr,          // Address of the register
      38        92722 :                      input  logic [31:0]            picm_wr_data,         // Data to be written to the register
      39        30400 :                      input  logic                   picm_wren,            // Write enable to the register
      40         9302 :                      input  logic                   picm_rden,            // Read enable for the register
      41           10 :                      input  logic                   picm_mken,            // Read the Mask for the register
      42         1170 :                      input  logic [3:0]             meicurpl,             // Current Priority Level
      43           38 :                      input  logic [3:0]             meipt,                // Current Priority Threshold
      44              : 
      45         1115 :                      output logic                   mexintpend,           // External Inerrupt request to the core
      46            0 :                      output logic [7:0]             claimid,              // Claim Id of the requested interrupt
      47          172 :                      output logic [3:0]             pl,                   // Priority level of the requested interrupt
      48            0 :                      output logic [31:0]            picm_rd_data,         // Read data of the register
      49          149 :                      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              :                      /*verilator coverage_off*/
      52              :                      input  logic                   scan_mode             // scan mode
      53              :                      /*verilator 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           27 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]           intenable_clk_enable ;
      80            0 : logic [INT_ENABLE_GRPS:0]                    intenable_clk_enable_grp ;
      81            0 : logic [INT_ENABLE_GRPS:0]                    gw_clk ;
      82              : 
      83         1368 : logic  addr_intpend_base_match;
      84              : 
      85          520 : logic  raddr_config_pic_match ;
      86         4654 : logic  raddr_intenable_base_match;
      87      2109853 : logic  raddr_intpriority_base_match;
      88        11744 : logic  raddr_config_gw_base_match ;
      89              : 
      90          524 : logic  waddr_config_pic_match ;
      91      2110096 : logic  waddr_intpriority_base_match;
      92         4846 : logic  waddr_intenable_base_match;
      93        11915 : logic  waddr_config_gw_base_match ;
      94         2420 : logic  addr_clear_gw_base_match ;
      95              : 
      96         1115 : logic  mexintpend_in;
      97          149 : logic  mhwakeup_in ;
      98            0 : logic  intpend_reg_read ;
      99              : 
     100            0 : logic [31:0]                                 picm_rd_data_in, intpend_rd_out;
     101         1418 : logic                                        intenable_rd_out ;
     102         1522 : logic [INTPRIORITY_BITS-1:0]                 intpriority_rd_out;
     103         1554 : logic [1:0]                                  gw_config_rd_out;
     104              : 
     105           47 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [INTPRIORITY_BITS-1:0] intpriority_reg;
     106           32 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [INTPRIORITY_BITS-1:0] intpriority_reg_inv;
     107          300 : 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           18 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [1:0]                  gw_config_reg;
     110              : 
     111           38 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        intenable_reg;
     112          300 : 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          300 : 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           60 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        gw_clear_reg_we;
     117              : 
     118           84 : logic [INTPEND_SIZE-1:0]                     intpend_reg_extended;
     119              : 
     120           27 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [INTPRIORITY_BITS-1:0] intpend_w_prior_en;
     121            0 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0] [ID_BITS-1:0]          intpend_id;
     122          345 : logic [INTPRIORITY_BITS-1:0]                 maxint;
     123          171 : logic [INTPRIORITY_BITS-1:0]                 selected_int_priority;
     124            0 : logic [INT_GRPS-1:0] [31:0]                  intpend_rd_part_out ;
     125              : 
     126            1 : logic                                        config_reg;
     127            1 : logic                                        intpriord;
     128            4 : logic                                        config_reg_we ;
     129            0 : logic                                        config_reg_re ;
     130       579751 : logic                                        config_reg_in ;
     131            0 : logic                                        prithresh_reg_write , prithresh_reg_read;
     132         3102 : logic                                        intpriority_reg_read ;
     133         3100 : logic                                        intenable_reg_read   ;
     134         3100 : logic                                        gw_config_reg_read   ;
     135         9302 : logic                                        picm_wren_ff , picm_rden_ff ;
     136          435 : logic [31:0]                                 picm_raddr_ff;
     137          435 : logic [31:0]                                 picm_waddr_ff;
     138        92722 : logic [31:0]                                 picm_wr_data_ff;
     139          570 : logic [3:0]                                  mask;
     140           10 : logic                                        picm_mken_ff;
     141            0 : logic [ID_BITS-1:0]                          claimid_in ;
     142          171 : logic [INTPRIORITY_BITS-1:0]                 pl_in ;
     143          172 : logic [INTPRIORITY_BITS-1:0]                 pl_in_q ;
     144              : 
     145            0 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        extintsrc_req_sync;
     146           72 : logic [pt.PIC_TOTAL_INT_PLUS1-1:0]                        extintsrc_req_gw;
     147            0 :    logic                                                  picm_bypass_ff;
     148              : 
     149              : // clkens
     150         9316 :    logic                                     pic_raddr_c1_clken;
     151            0 :    logic                                     pic_waddr_c1_clken;
     152        30404 :    logic                                     pic_data_c1_clken;
     153        12408 :    logic                                     pic_pri_c1_clken;
     154        12406 :    logic                                     pic_int_c1_clken;
     155        12406 :    logic                                     gw_config_c1_clken;
     156              : 
     157              : // clocks
     158     69839801 :    logic                                     pic_raddr_c1_clk;
     159     69860893 :    logic                                     pic_data_c1_clk;
     160     69842901 :    logic                                     pic_pri_c1_clk;
     161     69842901 :    logic                                     pic_int_c1_clk;
     162     69842901 :    logic                                     gw_config_c1_clk;
     163              : 
     164              : // ---- Clock gating section ------
     165              : // c1 clock enables
     166              :    assign pic_raddr_c1_clken  = picm_mken | picm_rden | clk_override;
     167              :    assign pic_data_c1_clken   = picm_wren | clk_override;
     168              :    assign pic_pri_c1_clken    = (waddr_intpriority_base_match & picm_wren_ff)  | (raddr_intpriority_base_match & picm_rden_ff) | clk_override;
     169              :    assign pic_int_c1_clken    = (waddr_intenable_base_match   & picm_wren_ff)  | (raddr_intenable_base_match   & picm_rden_ff) | clk_override;
     170              :    assign gw_config_c1_clken  = (waddr_config_gw_base_match   & picm_wren_ff)  | (raddr_config_gw_base_match   & picm_rden_ff) | clk_override;
     171              : 
     172              :    // C1 - 1 clock pulse for data
     173              :    rvoclkhdr pic_addr_c1_cgc   ( .en(pic_raddr_c1_clken),  .l1clk(pic_raddr_c1_clk), .* );
     174              :    rvoclkhdr pic_data_c1_cgc   ( .en(pic_data_c1_clken),   .l1clk(pic_data_c1_clk), .* );
     175              :    rvoclkhdr pic_pri_c1_cgc    ( .en(pic_pri_c1_clken),    .l1clk(pic_pri_c1_clk),  .* );
     176              :    rvoclkhdr pic_int_c1_cgc    ( .en(pic_int_c1_clken),    .l1clk(pic_int_c1_clk),  .* );
     177              :    rvoclkhdr gw_config_c1_cgc  ( .en(gw_config_c1_clken),  .l1clk(gw_config_c1_clk),  .* );
     178              : 
     179              : // ------ end clock gating section ------------------------
     180              : 
     181              : assign raddr_intenable_base_match   = (picm_raddr_ff[31:NUM_LEVELS+2] == INTENABLE_BASE_ADDR[31:NUM_LEVELS+2]) ;
     182              : assign raddr_intpriority_base_match = (picm_raddr_ff[31:NUM_LEVELS+2] == INTPRIORITY_BASE_ADDR[31:NUM_LEVELS+2]) ;
     183              : assign raddr_config_gw_base_match   = (picm_raddr_ff[31:NUM_LEVELS+2] == EXT_INTR_GW_CONFIG[31:NUM_LEVELS+2]) ;
     184              : assign raddr_config_pic_match       = (picm_raddr_ff[31:0]            == EXT_INTR_PIC_CONFIG[31:0]) ;
     185              : 
     186              : assign addr_intpend_base_match      = (picm_raddr_ff[31:6]            == INTPEND_BASE_ADDR[31:6]) ;
     187              : 
     188              : assign waddr_config_pic_match       = (picm_waddr_ff[31:0]            == EXT_INTR_PIC_CONFIG[31:0]) ;
     189              : assign addr_clear_gw_base_match     = (picm_waddr_ff[31:NUM_LEVELS+2] == EXT_INTR_GW_CLEAR[31:NUM_LEVELS+2]) ;
     190              : assign waddr_intpriority_base_match = (picm_waddr_ff[31:NUM_LEVELS+2] == INTPRIORITY_BASE_ADDR[31:NUM_LEVELS+2]) ;
     191              : assign waddr_intenable_base_match   = (picm_waddr_ff[31:NUM_LEVELS+2] == INTENABLE_BASE_ADDR[31:NUM_LEVELS+2]) ;
     192              : assign waddr_config_gw_base_match   = (picm_waddr_ff[31:NUM_LEVELS+2] == EXT_INTR_GW_CONFIG[31:NUM_LEVELS+2]) ;
     193              : 
     194              :    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
     195              : 
     196              : 
     197              : rvdff #(32) picm_radd_flop  (.*, .din (picm_rdaddr),        .dout(picm_raddr_ff),         .clk(pic_raddr_c1_clk));
     198              : rvdff #(32) picm_wadd_flop  (.*, .din (picm_wraddr),        .dout(picm_waddr_ff),         .clk(pic_data_c1_clk));
     199              : rvdff  #(1) picm_wre_flop   (.*, .din (picm_wren),          .dout(picm_wren_ff),          .clk(free_clk));
     200              : rvdff  #(1) picm_rde_flop   (.*, .din (picm_rden),          .dout(picm_rden_ff),          .clk(free_clk));
     201              : rvdff  #(1) picm_mke_flop   (.*, .din (picm_mken),          .dout(picm_mken_ff),          .clk(free_clk));
     202              : rvdff #(32) picm_dat_flop   (.*, .din (picm_wr_data[31:0]), .dout(picm_wr_data_ff[31:0]), .clk(pic_data_c1_clk));
     203              : 
     204              : //rvsyncss  #(pt.PIC_TOTAL_INT_PLUS1-1) sync_inst
     205              : //(
     206              : // .clk (free_clk),
     207              : // .dout(extintsrc_req_sync[pt.PIC_TOTAL_INT_PLUS1-1:1]),
     208              : // .din (extintsrc_req[pt.PIC_TOTAL_INT_PLUS1-1:1]),
     209              : // .*) ;
     210              : //
     211              : //assign extintsrc_req_sync[0] = extintsrc_req[0];
     212              : /*
     213              : genvar p ;
     214              : for (p=0; p<=INT_ENABLE_GRPS ; p++) begin  : IO_CLK_GRP
     215              :    if (p==INT_ENABLE_GRPS) begin : LAST_GRP
     216              :        assign intenable_clk_enable_grp[p] = |intenable_clk_enable[pt.PIC_TOTAL_INT_PLUS1-1 : p*4] | io_clk_override;
     217              :        rvoclkhdr intenable_c1_cgc   ( .en(intenable_clk_enable_grp[p]),  .l1clk(gw_clk[p]), .* );
     218              :    end else begin :  CLK_GRPS
     219              :        assign intenable_clk_enable_grp[p] = |intenable_clk_enable[p*4+3 : p*4] | io_clk_override;
     220              :        rvoclkhdr intenable_c1_cgc   ( .en(intenable_clk_enable_grp[p]),  .l1clk(gw_clk[p]), .* );
     221              :    end
     222              : end
     223              : */
     224              : 
     225              : 
     226              : 
     227              : genvar i ;
     228              : genvar p ;
     229              : for (p=0; p<=INT_ENABLE_GRPS ; p++) begin  : IO_CLK_GRP
     230              : wire grp_clk, grp_clken;
     231              : 
     232              :     assign grp_clken = |intenable_clk_enable[(p==INT_ENABLE_GRPS?pt.PIC_TOTAL_INT_PLUS1-1:p*4+3) : p*4] | io_clk_override;
     233              : 
     234              :   `ifndef RV_FPGA_OPTIMIZE
     235              :     rvclkhdr intenable_c1_cgc( .en(grp_clken),  .l1clk(grp_clk), .* );
     236              :   `else
     237              :     assign gw_clk[p] = 1'b0 ;
     238              :   `endif
     239              : 
     240              :     for(genvar i= (p==0 ? 1: 0); i< (p==INT_ENABLE_GRPS ? pt.PIC_TOTAL_INT_PLUS1-p*4 :4); i++) begin : GW
     241              :         el2_configurable_gw gw_inst(
     242              :              .*,
     243              :             .gw_clk(grp_clk),
     244              :             .rawclk(clk),
     245              :             .clken (grp_clken),
     246              :             .extintsrc_req(extintsrc_req[i+p*4]) ,
     247              :             .meigwctrl_polarity(gw_config_reg[i+p*4][0]) ,
     248              :             .meigwctrl_type(gw_config_reg[i+p*4][1]) ,
     249              :             .meigwclr(gw_clear_reg_we[i+p*4]) ,
     250              :             .extintsrc_req_config(extintsrc_req_gw[i+p*4])
     251              :         );
     252              :     end
     253              : end
     254              : 
     255              : 
     256              : 
     257              : 
     258              : 
     259              : 
     260              : 
     261              : 
     262              : for (i=0; i<pt.PIC_TOTAL_INT_PLUS1 ; i++) begin  : SETREG
     263              : 
     264              :  if (i > 0 ) begin : NON_ZERO_INT
     265              :      assign intpriority_reg_we[i] =  waddr_intpriority_base_match & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff;
     266              :      assign intpriority_reg_re[i] =  raddr_intpriority_base_match & (picm_raddr_ff[NUM_LEVELS+1:2] == i) & picm_rden_ff;
     267              : 
     268              :      assign intenable_reg_we[i]   =  waddr_intenable_base_match   & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff;
     269              :      assign intenable_reg_re[i]   =  raddr_intenable_base_match   & (picm_raddr_ff[NUM_LEVELS+1:2] == i) & picm_rden_ff;
     270              : 
     271              :      assign gw_config_reg_we[i]   =  waddr_config_gw_base_match   & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff;
     272              :      assign gw_config_reg_re[i]   =  raddr_config_gw_base_match   & (picm_raddr_ff[NUM_LEVELS+1:2] == i) & picm_rden_ff;
     273              : 
     274              :      assign gw_clear_reg_we[i]    =  addr_clear_gw_base_match     & (picm_waddr_ff[NUM_LEVELS+1:2] == i) & picm_wren_ff ;
     275              : 
     276              :      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));
     277              :      rvdffs #(1)                 intenable_ff   (.*, .en( intenable_reg_we[i]),   .din (picm_wr_data_ff[0]),                    .dout(intenable_reg[i]),   .clk(pic_int_c1_clk));
     278              :      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));
     279              : 
     280              :      assign intenable_clk_enable[i]  =  gw_config_reg[i][1] | intenable_reg_we[i] | intenable_reg[i] | gw_clear_reg_we[i] ;
     281              : 
     282              : /*
     283              :      rvsyncss_fpga  #(1) sync_inst
     284              :      (
     285              :       .gw_clk      (gw_clk[i/4]),
     286              :       .rawclk      (clk),
     287              :       .clken       (intenable_clk_enable_grp[i/4]),
     288              :       .dout        (extintsrc_req_sync[i]),
     289              :       .din         (extintsrc_req[i]),
     290              :       .*) ;
     291              : 
     292              : 
     293              : 
     294              : 
     295              : 
     296              :         el2_configurable_gw config_gw_inst(.*,
     297              :                                             .gw_clk(gw_clk[i/4]),
     298              :                                             .rawclk(clk),
     299              :                                             .clken (intenable_clk_enable_grp[i/4]),
     300              :                                             .extintsrc_req_sync(extintsrc_req_sync[i]) ,
     301              :                                             .meigwctrl_polarity(gw_config_reg[i][0]) ,
     302              :                                             .meigwctrl_type(gw_config_reg[i][1]) ,
     303              :                                             .meigwclr(gw_clear_reg_we[i]) ,
     304              :                                             .extintsrc_req_config(extintsrc_req_gw[i])
     305              :                                             );
     306              :              */
     307              : 
     308              :  end else begin : INT_ZERO
     309              :      assign intpriority_reg_we[i] =  1'b0 ;
     310              :      assign intpriority_reg_re[i] =  1'b0 ;
     311              :      assign intenable_reg_we[i]   =  1'b0 ;
     312              :      assign intenable_reg_re[i]   =  1'b0 ;
     313              : 
     314              :      assign gw_config_reg_we[i]   =  1'b0 ;
     315              :      assign gw_config_reg_re[i]   =  1'b0 ;
     316              :      assign gw_clear_reg_we[i]    =  1'b0 ;
     317              : 
     318              :      assign gw_config_reg[i]    = '0 ;
     319              : 
     320              :      assign intpriority_reg[i] = {INTPRIORITY_BITS{1'b0}} ;
     321              :      assign intenable_reg[i]   = 1'b0 ;
     322              :      assign extintsrc_req_gw[i] = 1'b0 ;
     323              :      assign extintsrc_req_sync[i]    = 1'b0 ;
     324              :      assign intenable_clk_enable[i] = 1'b0;
     325              :  end
     326              : 
     327              : 
     328              :     assign intpriority_reg_inv[i] =  intpriord ? ~intpriority_reg[i] : intpriority_reg[i] ;
     329              : 
     330              :     assign intpend_w_prior_en[i]  =  {INTPRIORITY_BITS{(extintsrc_req_gw[i] & intenable_reg[i])}} & intpriority_reg_inv[i] ;
     331              :     assign intpend_id[i]          =  i ;
     332              : end
     333              : 
     334              : 
     335              :         assign pl_in[INTPRIORITY_BITS-1:0]                  =      selected_int_priority[INTPRIORITY_BITS-1:0] ;
     336              : 
     337              : //if (pt.PIC_2CYCLE == 1) begin : genblock
     338              : //end
     339              : //else begin : genblock
     340              : //end
     341              : 
     342              :  genvar l, m , j, k;
     343              : 
     344              : if (pt.PIC_2CYCLE == 1) begin : genblock
     345              :         logic [NUM_LEVELS/2:0] [pt.PIC_TOTAL_INT_PLUS1+2:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
     346              :         logic [NUM_LEVELS/2:0] [pt.PIC_TOTAL_INT_PLUS1+2:0] [ID_BITS-1:0]          level_intpend_id;
     347              :         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;
     348              :         logic [NUM_LEVELS:NUM_LEVELS/2] [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2))+1:0] [ID_BITS-1:0]          levelx_intpend_id;
     349              : 
     350              :         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]} ;
     351              :         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]} ;
     352              : 
     353              :         logic [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0] [INTPRIORITY_BITS-1:0] l2_intpend_w_prior_en_ff;
     354              :         logic [(pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2)):0] [ID_BITS-1:0]          l2_intpend_id_ff;
     355              : 
     356              :         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]} ;
     357              :         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]} ;
     358              : ///  Do the prioritization of the interrupts here  ////////////
     359              :  for (l=0; l<NUM_LEVELS/2 ; l++) begin : TOP_LEVEL
     360              :     for (m=0; m<=(pt.PIC_TOTAL_INT_PLUS1)/(2**(l+1)) ; m++) begin : COMPARE
     361              :        if ( m == (pt.PIC_TOTAL_INT_PLUS1)/(2**(l+1))) begin
     362              :             assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
     363              :             assign level_intpend_id[l+1][m+1]         = '0 ;
     364              :        end
     365              :        el2_cmp_and_mux  #(.ID_BITS(ID_BITS),
     366              :                       .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
     367              :                       .a_id(level_intpend_id[l][2*m]),
     368              :                       .a_priority(level_intpend_w_prior_en[l][2*m]),
     369              :                       .b_id(level_intpend_id[l][2*m+1]),
     370              :                       .b_priority(level_intpend_w_prior_en[l][2*m+1]),
     371              :                       .out_id(level_intpend_id[l+1][m]),
     372              :                       .out_priority(level_intpend_w_prior_en[l+1][m])) ;
     373              : 
     374              :     end
     375              :  end
     376              : 
     377              :         for (i=0; i<=pt.PIC_TOTAL_INT_PLUS1/2**(NUM_LEVELS/2) ; i++) begin : MIDDLE_FLOPS
     378              :           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));
     379              :           rvdff #(ID_BITS)          level2_intpend_id_reg     (.*, .din (level_intpend_id[NUM_LEVELS/2][i]),         .dout(l2_intpend_id_ff[i]),          .clk(free_clk));
     380              :         end
     381              : 
     382              :  for (j=NUM_LEVELS/2; j<NUM_LEVELS ; j++) begin : BOT_LEVELS
     383              :     for (k=0; k<=(pt.PIC_TOTAL_INT_PLUS1)/(2**(j+1)) ; k++) begin : COMPARE
     384              :        if ( k == (pt.PIC_TOTAL_INT_PLUS1)/(2**(j+1))) begin
     385              :             assign levelx_intpend_w_prior_en[j+1][k+1] = '0 ;
     386              :             assign levelx_intpend_id[j+1][k+1]         = '0 ;
     387              :        end
     388              :             el2_cmp_and_mux  #(.ID_BITS(ID_BITS),
     389              :                         .INTPRIORITY_BITS(INTPRIORITY_BITS))
     390              :                  cmp_l1 (
     391              :                         .a_id(levelx_intpend_id[j][2*k]),
     392              :                         .a_priority(levelx_intpend_w_prior_en[j][2*k]),
     393              :                         .b_id(levelx_intpend_id[j][2*k+1]),
     394              :                         .b_priority(levelx_intpend_w_prior_en[j][2*k+1]),
     395              :                         .out_id(levelx_intpend_id[j+1][k]),
     396              :                         .out_priority(levelx_intpend_w_prior_en[j+1][k])) ;
     397              :     end
     398              :   end
     399              :         assign claimid_in[ID_BITS-1:0]                      =      levelx_intpend_id[NUM_LEVELS][0] ;   // This is the last level output
     400              :         assign selected_int_priority[INTPRIORITY_BITS-1:0]  =      levelx_intpend_w_prior_en[NUM_LEVELS][0] ;
     401              : end
     402              : else begin : genblock
     403              : 
     404              :         logic [NUM_LEVELS:0] [pt.PIC_TOTAL_INT_PLUS1+1:0] [INTPRIORITY_BITS-1:0] level_intpend_w_prior_en;
     405              :         logic [NUM_LEVELS:0] [pt.PIC_TOTAL_INT_PLUS1+1:0] [ID_BITS-1:0]          level_intpend_id;
     406              : 
     407              :         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]} ;
     408              :         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]} ;
     409              : 
     410              : ///  Do the prioritization of the interrupts here  ////////////
     411              : // genvar l, m , j, k;  already declared outside ifdef
     412              :  for (l=0; l<NUM_LEVELS ; l++) begin : LEVEL
     413              :     for (m=0; m<=(pt.PIC_TOTAL_INT_PLUS1)/(2**(l+1)) ; m++) begin : COMPARE
     414              :        if ( m == (pt.PIC_TOTAL_INT_PLUS1)/(2**(l+1))) begin
     415              :             assign level_intpend_w_prior_en[l+1][m+1] = '0 ;
     416              :             assign level_intpend_id[l+1][m+1]         = '0 ;
     417              :        end
     418              :        el2_cmp_and_mux  #(.ID_BITS(ID_BITS),
     419              :                       .INTPRIORITY_BITS(INTPRIORITY_BITS)) cmp_l1 (
     420              :                       .a_id(level_intpend_id[l][2*m]),
     421              :                       .a_priority(level_intpend_w_prior_en[l][2*m]),
     422              :                       .b_id(level_intpend_id[l][2*m+1]),
     423              :                       .b_priority(level_intpend_w_prior_en[l][2*m+1]),
     424              :                       .out_id(level_intpend_id[l+1][m]),
     425              :                       .out_priority(level_intpend_w_prior_en[l+1][m])) ;
     426              : 
     427              :     end
     428              :  end
     429              :         assign claimid_in[ID_BITS-1:0]                      =      level_intpend_id[NUM_LEVELS][0] ;   // This is the last level output
     430              :         assign selected_int_priority[INTPRIORITY_BITS-1:0]  =      level_intpend_w_prior_en[NUM_LEVELS][0] ;
     431              : 
     432              : end
     433              : 
     434              : 
     435              : 
     436              : ///////////////////////////////////////////////////////////////////////
     437              : // Config Reg`
     438              : ///////////////////////////////////////////////////////////////////////
     439              : assign config_reg_we               =  waddr_config_pic_match & picm_wren_ff;
     440              : assign config_reg_re               =  raddr_config_pic_match & picm_rden_ff;
     441              : 
     442              : assign config_reg_in  =  picm_wr_data_ff[0] ;   //
     443              : rvdffs #(1) config_reg_ff  (.*, .clk(free_clk), .en(config_reg_we), .din (config_reg_in), .dout(config_reg));
     444              : 
     445              : assign intpriord  = config_reg ;
     446              : 
     447              : 
     448              : 
     449              : //////////////////////////////////////////////////////////////////////////
     450              : // Send the interrupt to the core if it is above the thresh-hold
     451              : //////////////////////////////////////////////////////////////////////////
     452              : ///////////////////////////////////////////////////////////
     453              : /// ClaimId  Reg and Corresponding PL
     454              : ///////////////////////////////////////////////////////////
     455              : //
     456              : assign pl_in_q[INTPRIORITY_BITS-1:0] = intpriord ? ~pl_in : pl_in ;
     457              : rvdff #(ID_BITS)          claimid_ff  (.*,  .din (claimid_in[ID_BITS-1:00]),     .dout(claimid[ID_BITS-1:00]),    .clk(free_clk));
     458              : rvdff  #(INTPRIORITY_BITS) pl_ff      (.*, .din (pl_in_q[INTPRIORITY_BITS-1:0]), .dout(pl[INTPRIORITY_BITS-1:0]), .clk(free_clk));
     459              : 
     460           39 : logic [INTPRIORITY_BITS-1:0] meipt_inv , meicurpl_inv ;
     461              : assign meipt_inv[INTPRIORITY_BITS-1:0]    = intpriord ? ~meipt[INTPRIORITY_BITS-1:0]    : meipt[INTPRIORITY_BITS-1:0] ;
     462              : assign meicurpl_inv[INTPRIORITY_BITS-1:0] = intpriord ? ~meicurpl[INTPRIORITY_BITS-1:0] : meicurpl[INTPRIORITY_BITS-1:0] ;
     463              : assign mexintpend_in = (( selected_int_priority[INTPRIORITY_BITS-1:0] > meipt_inv[INTPRIORITY_BITS-1:0]) &
     464              :                         ( selected_int_priority[INTPRIORITY_BITS-1:0] > meicurpl_inv[INTPRIORITY_BITS-1:0]) );
     465              : rvdff #(1) mexintpend_ff  (.*, .clk(free_clk), .din (mexintpend_in), .dout(mexintpend));
     466              : 
     467              : assign maxint[INTPRIORITY_BITS-1:0]      =  intpriord ? 0 : 15 ;
     468              : assign mhwakeup_in = ( pl_in_q[INTPRIORITY_BITS-1:0] == maxint) ;
     469              : rvdff #(1) wake_up_ff  (.*, .clk(free_clk), .din (mhwakeup_in), .dout(mhwakeup));
     470              : 
     471              : 
     472              : 
     473              : 
     474              : 
     475              : //////////////////////////////////////////////////////////////////////////
     476              : //  Reads of register.
     477              : //  1- intpending
     478              : //////////////////////////////////////////////////////////////////////////
     479              : 
     480              : assign intpend_reg_read     =  addr_intpend_base_match      & picm_rden_ff ;
     481              : assign intpriority_reg_read =  raddr_intpriority_base_match & picm_rden_ff;
     482              : assign intenable_reg_read   =  raddr_intenable_base_match   & picm_rden_ff;
     483              : assign gw_config_reg_read   =  raddr_config_gw_base_match   & picm_rden_ff;
     484              : 
     485              : 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]} ;
     486              : 
     487              :    for (i=0; i<(INT_GRPS); i++) begin
     488              :             assign intpend_rd_part_out[i] =  (({32{intpend_reg_read & picm_raddr_ff[5:2] == i}}) & intpend_reg_extended[((32*i)+31):(32*i)]) ;
     489              :    end
     490              : 
     491          344 :    always_comb begin : INTPEND_RD
     492          344 :          intpend_rd_out =  '0 ;
     493          344 :          for (int i=0; i<INT_GRPS; i++) begin
     494          688 :                intpend_rd_out |=  intpend_rd_part_out[i] ;
     495              :          end
     496              :    end
     497              : 
     498          344 :    always_comb begin : INTEN_RD
     499          344 :          intenable_rd_out =  '0 ;
     500          344 :          intpriority_rd_out =  '0 ;
     501          344 :          gw_config_rd_out =  '0 ;
     502          344 :          for (int i=0; i<pt.PIC_TOTAL_INT_PLUS1; i++) begin
     503    910261268 :               if (intenable_reg_re[i]) begin
     504         9300 :                intenable_rd_out    =  intenable_reg[i]  ;
     505              :               end
     506    910261268 :               if (intpriority_reg_re[i]) begin
     507         9300 :                intpriority_rd_out  =  intpriority_reg[i] ;
     508              :               end
     509    910261268 :               if (gw_config_reg_re[i]) begin
     510         9300 :                gw_config_rd_out  =  gw_config_reg[i] ;
     511              :               end
     512              :          end
     513              :    end
     514              : 
     515              : 
     516              :  assign picm_rd_data_in[31:0] = ({32{intpend_reg_read      }} &   intpend_rd_out                                                    ) |
     517              :                                 ({32{intpriority_reg_read  }} &  {{32-INTPRIORITY_BITS{1'b0}}, intpriority_rd_out                 } ) |
     518              :                                 ({32{intenable_reg_read    }} &  {31'b0 , intenable_rd_out                                        } ) |
     519              :                                 ({32{gw_config_reg_read    }} &  {30'b0 , gw_config_rd_out                                        } ) |
     520              :                                 ({32{config_reg_re         }} &  {31'b0 , config_reg                                              } ) |
     521              :                                 ({32{picm_mken_ff & mask[3]}} &  {30'b0 , 2'b11                                                   } ) |
     522              :                                 ({32{picm_mken_ff & mask[2]}} &  {31'b0 , 1'b1                                                    } ) |
     523              :                                 ({32{picm_mken_ff & mask[1]}} &  {28'b0 , 4'b1111                                                 } ) |
     524              :                                 ({32{picm_mken_ff & mask[0]}} &   32'b0                                                             ) ;
     525              : 
     526              : 
     527              : assign picm_rd_data[31:0] = picm_bypass_ff ? picm_wr_data_ff[31:0] : picm_rd_data_in[31:0] ;
     528              : 
     529       479502 : logic [14:0] address;
     530              : 
     531              : assign address[14:0] = picm_raddr_ff[14:0];
     532              : 
     533              : `include "pic_map_auto.h"
     534              : 
     535              : endmodule
     536              : 
     537              : 
     538              : module el2_cmp_and_mux #(parameter ID_BITS=8,
     539              :                                INTPRIORITY_BITS = 4)
     540              :                     (
     541         1720 :                         input  logic [ID_BITS-1:0]       a_id,
     542         2823 :                         input  logic [INTPRIORITY_BITS-1:0] a_priority,
     543              : 
     544          344 :                         input  logic [ID_BITS-1:0]       b_id,
     545         2934 :                         input  logic [INTPRIORITY_BITS-1:0] b_priority,
     546              : 
     547         1720 :                         output logic [ID_BITS-1:0]       out_id,
     548         3983 :                         output logic [INTPRIORITY_BITS-1:0] out_priority
     549              : 
     550              :                     );
     551              : 
     552         5981 : logic   a_is_lt_b ;
     553              : 
     554              : assign  a_is_lt_b  = ( a_priority[INTPRIORITY_BITS-1:0] < b_priority[INTPRIORITY_BITS-1:0] ) ;
     555              : 
     556              : assign  out_id[ID_BITS-1:0]                = a_is_lt_b ? b_id[ID_BITS-1:0] :
     557              :                                                          a_id[ID_BITS-1:0] ;
     558              : assign  out_priority[INTPRIORITY_BITS-1:0] = a_is_lt_b ? b_priority[INTPRIORITY_BITS-1:0] :
     559              :                                                          a_priority[INTPRIORITY_BITS-1:0] ;
     560              : endmodule // cmp_and_mux
     561              : 
     562              : 
     563              : module el2_configurable_gw (
     564      3127890 :                              input logic gw_clk,
     565   1751516106 :                              input logic rawclk,
     566        10807 :                              input logic clken,
     567        10642 :                              input logic rst_l,
     568         3441 :                              input logic extintsrc_req ,
     569          763 :                              input logic meigwctrl_polarity ,
     570          842 :                              input logic meigwctrl_type ,
     571         2500 :                              input logic meigwclr ,
     572              : 
     573         3085 :                              output logic extintsrc_req_config
     574              :                             );
     575              : 
     576              : 
     577         2524 :   logic  gw_int_pending_in, gw_int_pending, extintsrc_req_sync;
     578              : 
     579              :   rvsyncss_fpga  #(1) sync_inst (
     580              :       .dout        (extintsrc_req_sync),
     581              :       .din         (extintsrc_req),
     582              :       .*) ;
     583              : 
     584              : 
     585              :   assign gw_int_pending_in =  (extintsrc_req_sync ^ meigwctrl_polarity) | (gw_int_pending & ~meigwclr) ;
     586              :   rvdff_fpga #(1) int_pend_ff        (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (gw_int_pending_in),     .dout(gw_int_pending));
     587              : 
     588              : 
     589              :   assign extintsrc_req_config =  meigwctrl_type ? ((extintsrc_req_sync ^  meigwctrl_polarity) | gw_int_pending) : (extintsrc_req_sync ^  meigwctrl_polarity) ;
     590              : 
     591              : endmodule // configurable_gw
     592              : 
     593              : 
     594              : 
     595              : 
     596              : 
     597              : 
     598              : 
     599              : 
     600              :