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