Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—ifu—el2_ifu_aln_ctl.sv Coverage Hit Total
Test Date: 21-11-2024 Toggle 96.8% 120 124
Test: all Branch 96.0% 24 25

            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: Instruction aligner
      20              : //********************************************************************************
      21              : module el2_ifu_aln_ctl
      22              : import el2_pkg::*;
      23              : #(
      24              : `include "el2_param.vh"
      25              :  )
      26              :   (
      27              : 
      28              :    // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
      29              :    /*verilator coverage_off*/
      30              :    input logic                                    scan_mode,                // Flop scan mode control
      31              :    /*verilator coverage_on*/
      32          338 :    input logic                                    rst_l,                    // reset, active low
      33     69840565 :    input logic                                    clk,                      // Clock only while core active.  Through one clock header.  For flops with    second clock header built in.  Connected to ACTIVE_L2CLK.
      34     69840565 :    input logic                                    active_clk,               // Clock only while core active.  Through two clock headers. For flops without second clock header built in.
      35              : 
      36            8 :    input logic                                    ifu_async_error_start,    // ecc/parity related errors with current fetch - not sent down the pipe
      37              : 
      38            4 :    input logic [1:0]                              iccm_rd_ecc_double_err,   // This fetch has a double ICCM ecc  error.
      39              : 
      40          180 :    input logic [1:0]                              ic_access_fault_f,        // Instruction access fault for the current fetch.
      41          172 :    input logic [1:0]                              ic_access_fault_type_f,   // Instruction access fault types
      42              : 
      43       673974 :    input logic                                    exu_flush_final,          // Flush from the pipeline.
      44              : 
      45      6195679 :    input logic                                    dec_i0_decode_d,          // Valid instruction at D-stage and not blocked
      46              : 
      47      2166762 :    input logic [31:0]                             ifu_fetch_data_f,         // fetch data in memory format - not right justified
      48              : 
      49      6333593 :    input logic [1:0]                              ifu_fetch_val,            // valids on a 2B boundary, right justified
      50          443 :    input logic [31:1]                             ifu_fetch_pc,             // starting pc of fetch
      51              : 
      52              : 
      53              : 
      54      6010401 :    output logic                                   ifu_i0_valid,             // Instruction 0 is valid
      55          206 :    output logic                                   ifu_i0_icaf,              // Instruction 0 has access fault
      56          274 :    output logic [1:0]                             ifu_i0_icaf_type,         // Instruction 0 access fault type
      57           86 :    output logic                                   ifu_i0_icaf_second,       // Instruction 0 has access fault on second 2B of 4B inst
      58              : 
      59            2 :    output logic                                   ifu_i0_dbecc,             // Instruction 0 has double bit ecc error
      60       468702 :    output logic [31:0]                            ifu_i0_instr,             // Instruction 0
      61         1321 :    output logic [31:1]                            ifu_i0_pc,                // Instruction 0 PC
      62      5770511 :    output logic                                   ifu_i0_pc4,
      63              : 
      64      5986539 :    output logic                                   ifu_fb_consume1,          // Consumed one buffer. To fetch control fetch for buffer mass balance
      65      1761739 :    output logic                                   ifu_fb_consume2,          // Consumed two buffers.To fetch control fetch for buffer mass balance
      66              : 
      67              : 
      68       376431 :    input logic [pt.BHT_GHR_SIZE-1:0]              ifu_bp_fghr_f,            // fetch GHR
      69       518479 :    input logic [31:1]                             ifu_bp_btb_target_f,      // predicted RET target
      70      2176718 :    input logic [11:0]                             ifu_bp_poffset_f,         // predicted target offset
      71            0 :    input logic [1:0] [$clog2(pt.BTB_SIZE)-1:0]    ifu_bp_fa_index_f,        // predicted branch index (fully associative option)
      72              : 
      73      1823494 :    input logic [1:0]                              ifu_bp_hist0_f,           // history counters for all 4 potential branches, bit 1, right justified
      74      2024478 :    input logic [1:0]                              ifu_bp_hist1_f,           // history counters for all 4 potential branches, bit 1, right justified
      75       408365 :    input logic [1:0]                              ifu_bp_pc4_f,             // pc4 indication, right justified
      76      2374031 :    input logic [1:0]                              ifu_bp_way_f,             // way indication, right justified
      77       956919 :    input logic [1:0]                              ifu_bp_valid_f,           // branch valid, right justified
      78        70446 :    input logic [1:0]                              ifu_bp_ret_f,             // predicted ret indication, right justified
      79              : 
      80              : 
      81       206055 :    output el2_br_pkt_t                           i0_brp,                   // Branch packet for I0.
      82       651059 :    output logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]   ifu_i0_bp_index,          // BP index
      83       628591 :    output logic [pt.BHT_GHR_SIZE-1:0]             ifu_i0_bp_fghr,           // BP FGHR
      84        21223 :    output logic [pt.BTB_BTAG_SIZE-1:0]            ifu_i0_bp_btag,           // BP tag
      85              : 
      86            0 :    output logic [$clog2(pt.BTB_SIZE)-1:0]         ifu_i0_fa_index,          // Fully associt btb index
      87              : 
      88      6195679 :    output logic                                   ifu_pmu_instr_aligned,    // number of inst aligned this cycle
      89              : 
      90      1427480 :    output logic [15:0]                            ifu_i0_cinst              // 16b compress inst for i0
      91              :    );
      92              : 
      93              : 
      94              : 
      95      6782653 :    logic                                          ifvalid;
      96        51594 :    logic                                          shift_f1_f0, shift_f2_f0, shift_f2_f1;
      97       271300 :    logic                                          fetch_to_f0, fetch_to_f1, fetch_to_f2;
      98              : 
      99       686016 :    logic [1:0]                                    f2val_in, f2val;
     100      1522402 :    logic [1:0]                                    f1val_in, f1val;
     101      4310909 :    logic [1:0]                                    f0val_in, f0val;
     102        77535 :    logic [1:0]                                    sf1val, sf0val;
     103              : 
     104      1361254 :    logic [31:0]                                   aligndata;
     105      5770512 :    logic                                          first4B, first2B;
     106              : 
     107       241378 :    logic [31:0]                                   uncompress0;
     108      6195679 :    logic                                          i0_shift;
     109      4372102 :    logic                                          shift_2B, shift_4B;
     110      3312033 :    logic                                          f1_shift_2B;
     111       578883 :    logic                                          f2_valid, sf1_valid, sf0_valid;
     112              : 
     113      1361254 :    logic [31:0]                                   ifirst;
     114      4646540 :    logic [1:0]                                    alignval;
     115      2130775 :    logic [31:1]                                   firstpc, secondpc;
     116              : 
     117      2077583 :    logic [11:0]                                   f1poffset;
     118       554300 :    logic [11:0]                                   f0poffset;
     119       395019 :    logic [pt.BHT_GHR_SIZE-1:0]                    f1fghr;
     120       603477 :    logic [pt.BHT_GHR_SIZE-1:0]                    f0fghr;
     121      1872690 :    logic [1:0]                                    f1hist1;
     122      2524577 :    logic [1:0]                                    f0hist1;
     123      1629731 :    logic [1:0]                                    f1hist0;
     124      2343603 :    logic [1:0]                                    f0hist0;
     125              : 
     126            0 :    logic [1:0][$clog2(pt.BTB_SIZE)-1:0]           f0index, f1index, alignindex;
     127              : 
     128          126 :    logic [1:0]                                    f1ictype;
     129          188 :    logic [1:0]                                    f0ictype;
     130              : 
     131       310624 :    logic [1:0]                                    f1pc4;
     132       476060 :    logic [1:0]                                    f0pc4;
     133              : 
     134        13698 :    logic [1:0]                                    f1ret;
     135        79380 :    logic [1:0]                                    f0ret;
     136      3407588 :    logic [1:0]                                    f1way;
     137      3984021 :    logic [1:0]                                    f0way;
     138              : 
     139       513326 :    logic [1:0]                                    f1brend;
     140       803785 :    logic [1:0]                                    f0brend;
     141              : 
     142      2271543 :    logic [1:0]                                    alignbrend;
     143      2125415 :    logic [1:0]                                    alignpc4;
     144              : 
     145        81894 :    logic [1:0]                                    alignret;
     146      4381218 :    logic [1:0]                                    alignway;
     147      4644199 :    logic [1:0]                                    alignhist1;
     148      4153481 :    logic [1:0]                                    alignhist0;
     149      4112425 :    logic [1:1]                                    alignfromf1;
     150      2365947 :    logic                                          i0_ends_f1;
     151         9628 :    logic                                          i0_br_start_error;
     152              : 
     153       381470 :    logic [31:1]                                   f1prett;
     154       439415 :    logic [31:1]                                   f0prett;
     155            2 :    logic [1:0]                                    f1dbecc;
     156            2 :    logic [1:0]                                    f0dbecc;
     157          132 :    logic [1:0]                                    f1icaf;
     158          200 :    logic [1:0]                                    f0icaf;
     159              : 
     160            2 :    logic [1:0]                                    aligndbecc;
     161          118 :    logic [1:0]                                    alignicaf;
     162      2550497 :    logic                                          i0_brp_pc4;
     163              : 
     164       611525 :    logic [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]          firstpc_hash, secondpc_hash;
     165              : 
     166            0 :    logic                                          first_legal;
     167              : 
     168      4430856 :    logic [1:0]                                    wrptr, wrptr_in;
     169      3625701 :    logic [1:0]                                    rdptr, rdptr_in;
     170      4275505 :    logic [2:0]                                    qwen;
     171       321444 :    logic [31:0]                                   q2,q1,q0;
     172      2750383 :    logic                                          q2off_in, q2off;
     173      2743805 :    logic                                          q1off_in, q1off;
     174      2775229 :    logic                                          q0off_in, q0off;
     175      3735880 :    logic                                          f0_shift_2B;
     176              : 
     177      1289961 :    logic [31:0]                                   q0eff;
     178       899020 :    logic [31:0]                                   q0final;
     179      4904978 :    logic                                          q0ptr;
     180      4904978 :    logic [1:0]                                    q0sel;
     181              : 
     182      1133585 :    logic [31:0]                                   q1eff;
     183      1320997 :    logic [15:0]                                   q1final;
     184      3425636 :    logic                                          q1ptr;
     185      3425636 :    logic [1:0]                                    q1sel;
     186              : 
     187      3625693 :    logic [2:0]                                    qren;
     188              : 
     189      1888526 :    logic                                          consume_fb1, consume_fb0;
     190          120 :    logic [1:0]                                    icaf_eff;
     191              : 
     192              :    localparam                                     BRDATA_SIZE  = pt.BTB_ENABLE ? 16+($clog2(pt.BTB_SIZE)*2*pt.BTB_FULLYA) : 4;
     193              :    localparam                                     BRDATA_WIDTH = pt.BTB_ENABLE ? 8+($clog2(pt.BTB_SIZE)*pt.BTB_FULLYA) : 2;
     194        60904 :    logic [BRDATA_SIZE-1:0]                        brdata_in, brdata2, brdata1, brdata0;
     195       193629 :    logic [BRDATA_SIZE-1:0]                        brdata1eff, brdata0eff;
     196       179151 :    logic [BRDATA_SIZE-1:0]                        brdata1final, brdata0final;
     197              : 
     198              :    localparam                                     MHI   = 1+(pt.BTB_ENABLE * (43+pt.BHT_GHR_SIZE));
     199              :    localparam                                     MSIZE = 2+(pt.BTB_ENABLE * (43+pt.BHT_GHR_SIZE));
     200              : 
     201       144293 :    logic [MHI:0]                                  misc_data_in, misc2, misc1, misc0;
     202       512941 :    logic [MHI:0]                                  misc1eff, misc0eff;
     203              : 
     204        16657 :    logic [pt.BTB_BTAG_SIZE-1:0]                  firstbrtag_hash, secondbrtag_hash;
     205              : 
     206            8 :    logic                                         error_stall_in, error_stall;
     207              : 
     208              :    assign error_stall_in = (error_stall | ifu_async_error_start) & ~exu_flush_final;
     209              : 
     210              :    rvdff #(.WIDTH(7))  bundle1ff (.*,
     211              :                                   .clk(active_clk),
     212              :                                   .din ({wrptr_in[1:0],rdptr_in[1:0],q2off_in,q1off_in,q0off_in}),
     213              :                                   .dout({wrptr[1:0],   rdptr[1:0],   q2off,   q1off,   q0off})
     214              :                                   );
     215              : 
     216              :    rvdffie #(.WIDTH(7),.OVERRIDE(1))  bundle2ff (.*,
     217              :                                                  .din ({error_stall_in,f2val_in[1:0],f1val_in[1:0],f0val_in[1:0]}),
     218              :                                                  .dout({error_stall,   f2val[1:0],   f1val[1:0],   f0val[1:0]   })
     219              :                                                  );
     220              : 
     221              : if(pt.BTB_ENABLE==1) begin : genblock1
     222              :    rvdffe #(BRDATA_SIZE)  brdata2ff   (.*, .clk(clk), .en(qwen[2]),        .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata2[BRDATA_SIZE-1:0]));
     223              :    rvdffe #(BRDATA_SIZE)  brdata1ff   (.*, .clk(clk), .en(qwen[1]),        .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata1[BRDATA_SIZE-1:0]));
     224              :    rvdffe #(BRDATA_SIZE)  brdata0ff   (.*, .clk(clk), .en(qwen[0]),        .din(brdata_in[BRDATA_SIZE-1:0]), .dout(brdata0[BRDATA_SIZE-1:0]));
     225              :    rvdffe #(MSIZE)        misc2ff     (.*, .clk(clk), .en(qwen[2]),        .din(misc_data_in[MHI:0]),        .dout(misc2[MHI:0]));
     226              :    rvdffe #(MSIZE)        misc1ff     (.*, .clk(clk), .en(qwen[1]),        .din(misc_data_in[MHI:0]),        .dout(misc1[MHI:0]));
     227              :    rvdffe #(MSIZE)        misc0ff     (.*, .clk(clk), .en(qwen[0]),        .din(misc_data_in[MHI:0]),        .dout(misc0[MHI:0]));
     228              : end
     229              : else begin : genblock1
     230              : 
     231              :    rvdffie #((MSIZE*3)+(BRDATA_SIZE*3))    miscff      (.*,
     232              :                                                         .din({qwen[2] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc2[MHI:0], brdata2[BRDATA_SIZE-1:0]},
     233              :                                                               qwen[1] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc1[MHI:0], brdata1[BRDATA_SIZE-1:0]},
     234              :                                                               qwen[0] ? {misc_data_in[MHI:0], brdata_in[BRDATA_SIZE-1:0]} : {misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]}}),
     235              :                                                         .dout({misc2[MHI:0], brdata2[BRDATA_SIZE-1:0],
     236              :                                                                misc1[MHI:0], brdata1[BRDATA_SIZE-1:0],
     237              :                                                                misc0[MHI:0], brdata0[BRDATA_SIZE-1:0]})
     238              :                                                         );
     239              : end
     240              : 
     241          337 :   logic [31:1] q2pc, q1pc, q0pc;
     242              : 
     243              :    rvdffe #(31)           q2pcff        (.*, .clk(clk), .en(qwen[2]),        .din(ifu_fetch_pc[31:1]),     .dout(q2pc[31:1]));
     244              :    rvdffe #(31)           q1pcff        (.*, .clk(clk), .en(qwen[1]),        .din(ifu_fetch_pc[31:1]),     .dout(q1pc[31:1]));
     245              :    rvdffe #(31)           q0pcff        (.*, .clk(clk), .en(qwen[0]),        .din(ifu_fetch_pc[31:1]),     .dout(q0pc[31:1]));
     246              : 
     247              :    rvdffe #(32)           q2ff        (.*, .clk(clk), .en(qwen[2]),        .din(ifu_fetch_data_f[31:0]),     .dout(q2[31:0]));
     248              :    rvdffe #(32)           q1ff        (.*, .clk(clk), .en(qwen[1]),        .din(ifu_fetch_data_f[31:0]),     .dout(q1[31:0]));
     249              :    rvdffe #(32)           q0ff        (.*, .clk(clk), .en(qwen[0]),        .din(ifu_fetch_data_f[31:0]),     .dout(q0[31:0]));
     250              : 
     251              : 
     252              :    // new queue control logic
     253              : 
     254              :    assign qren[2:0]          = {  rdptr[1:0] == 2'b10,
     255              :                                   rdptr[1:0] == 2'b01,
     256              :                                   rdptr[1:0] == 2'b00 };
     257              : 
     258              :    assign qwen[2:0]          = { (wrptr[1:0] == 2'b10) & ifvalid,
     259              :                                  (wrptr[1:0] == 2'b01) & ifvalid,
     260              :                                  (wrptr[1:0] == 2'b00) & ifvalid };
     261              : 
     262              : 
     263              :    assign rdptr_in[1:0]      = ({2{ qren[0]         &  ifu_fb_consume1 & ~exu_flush_final}} & 2'b01     ) |
     264              :                                ({2{ qren[1]         &  ifu_fb_consume1 & ~exu_flush_final}} & 2'b10     ) |
     265              :                                ({2{ qren[2]         &  ifu_fb_consume1 & ~exu_flush_final}} & 2'b00     ) |
     266              :                                ({2{ qren[0]         &  ifu_fb_consume2 & ~exu_flush_final}} & 2'b10     ) |
     267              :                                ({2{ qren[1]         &  ifu_fb_consume2 & ~exu_flush_final}} & 2'b00     ) |
     268              :                                ({2{ qren[2]         &  ifu_fb_consume2 & ~exu_flush_final}} & 2'b01     ) |
     269              :                                ({2{~ifu_fb_consume1 & ~ifu_fb_consume2 & ~exu_flush_final}} & rdptr[1:0]);
     270              : 
     271              :    assign wrptr_in[1:0]      = ({2{ qwen[0] & ~exu_flush_final}} & 2'b01     ) |
     272              :                                ({2{ qwen[1] & ~exu_flush_final}} & 2'b10     ) |
     273              :                                ({2{ qwen[2] & ~exu_flush_final}} & 2'b00     ) |
     274              :                                ({2{~ifvalid & ~exu_flush_final}} & wrptr[1:0]);
     275              : 
     276              : 
     277              : 
     278              :    assign q2off_in          = ( ~qwen[2] & (rdptr[1:0]==2'd2)  &  (q2off | f0_shift_2B) ) |
     279              :                               ( ~qwen[2] & (rdptr[1:0]==2'd1)  &  (q2off | f1_shift_2B) ) |
     280              :                               ( ~qwen[2] & (rdptr[1:0]==2'd0)  &   q2off                );
     281              : 
     282              :    assign q1off_in          = ( ~qwen[1] & (rdptr[1:0]==2'd1)  &  (q1off | f0_shift_2B) ) |
     283              :                               ( ~qwen[1] & (rdptr[1:0]==2'd0)  &  (q1off | f1_shift_2B) ) |
     284              :                               ( ~qwen[1] & (rdptr[1:0]==2'd2)  &   q1off                );
     285              : 
     286              :    assign q0off_in          = ( ~qwen[0] & (rdptr[1:0]==2'd0)  &  (q0off | f0_shift_2B) ) |
     287              :                               ( ~qwen[0] & (rdptr[1:0]==2'd2)  &  (q0off | f1_shift_2B) ) |
     288              :                               ( ~qwen[0] & (rdptr[1:0]==2'd1)  &   q0off                );
     289              : 
     290              : 
     291              : 
     292              :    assign q0ptr              = ( (rdptr[1:0]==2'b00) & q0off ) |
     293              :                                ( (rdptr[1:0]==2'b01) & q1off ) |
     294              :                                ( (rdptr[1:0]==2'b10) & q2off );
     295              : 
     296              :    assign q1ptr              = ( (rdptr[1:0]==2'b00) & q1off ) |
     297              :                                ( (rdptr[1:0]==2'b01) & q2off ) |
     298              :                                ( (rdptr[1:0]==2'b10) & q0off );
     299              : 
     300              :    assign q0sel[1:0]         = {q0ptr,~q0ptr};
     301              : 
     302              :    assign q1sel[1:0]         = {q1ptr,~q1ptr};
     303              : 
     304              :    // end new queue control logic
     305              : 
     306              : 
     307              :    // misc data that is associated with each fetch buffer
     308              : 
     309              :    if(pt.BTB_ENABLE==1)
     310              :      assign misc_data_in[MHI:0] = {
     311              : 
     312              :                                     ic_access_fault_type_f[1:0],
     313              :                                     ifu_bp_btb_target_f[31:1],
     314              :                                     ifu_bp_poffset_f[11:0],
     315              :                                     ifu_bp_fghr_f[pt.BHT_GHR_SIZE-1:0]
     316              :                                     };
     317              :    else
     318              :      assign misc_data_in[MHI:0] = {
     319              :                                     ic_access_fault_type_f[1:0]
     320              :                                     };
     321              : 
     322              : 
     323              :    assign {misc1eff[MHI:0],misc0eff[MHI:0]} = (({MSIZE*2{qren[0]}} & {misc1[MHI:0],misc0[MHI:0]}) |
     324              :                                                ({MSIZE*2{qren[1]}} & {misc2[MHI:0],misc1[MHI:0]}) |
     325              :                                                ({MSIZE*2{qren[2]}} & {misc0[MHI:0],misc2[MHI:0]}));
     326              : 
     327              :    if(pt.BTB_ENABLE==1) begin
     328              :    assign {
     329              :             f1ictype[1:0],
     330              :             f1prett[31:1],
     331              :             f1poffset[11:0],
     332              :             f1fghr[pt.BHT_GHR_SIZE-1:0]
     333              :             } = misc1eff[MHI:0];
     334              : 
     335              :    assign {
     336              :             f0ictype[1:0],
     337              :             f0prett[31:1],
     338              :             f0poffset[11:0],
     339              :             f0fghr[pt.BHT_GHR_SIZE-1:0]
     340              :             } = misc0eff[MHI:0];
     341              : 
     342              :       if(pt.BTB_FULLYA) begin
     343              :          assign brdata_in[BRDATA_SIZE-1:0] = {
     344              :                                                ifu_bp_fa_index_f[1], iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1],
     345              :                                                ifu_bp_fa_index_f[0], iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0]
     346              :                                                };
     347              :          assign {f0index[1],f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1],
     348              :                  f0index[0],f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0];
     349              : 
     350              :          assign {f1index[1],f1dbecc[1],f1icaf[1],f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1],
     351              :                  f1index[0],f1dbecc[0],f1icaf[0],f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0]} = brdata1final[BRDATA_SIZE-1:0];
     352              : 
     353              :       end
     354              :       else begin
     355              :          assign brdata_in[BRDATA_SIZE-1:0] = {
     356              :                                                iccm_rd_ecc_double_err[1],ic_access_fault_f[1],ifu_bp_hist1_f[1],ifu_bp_hist0_f[1],ifu_bp_pc4_f[1],ifu_bp_way_f[1],ifu_bp_valid_f[1],ifu_bp_ret_f[1],
     357              :                                                iccm_rd_ecc_double_err[0],ic_access_fault_f[0],ifu_bp_hist1_f[0],ifu_bp_hist0_f[0],ifu_bp_pc4_f[0],ifu_bp_way_f[0],ifu_bp_valid_f[0],ifu_bp_ret_f[0]
     358              :                                                };
     359              :          assign {f0dbecc[1],f0icaf[1],f0hist1[1],f0hist0[1],f0pc4[1],f0way[1],f0brend[1],f0ret[1],
     360              :                  f0dbecc[0],f0icaf[0],f0hist1[0],f0hist0[0],f0pc4[0],f0way[0],f0brend[0],f0ret[0]} = brdata0final[BRDATA_SIZE-1:0];
     361              : 
     362              :          assign {f1dbecc[1],f1icaf[1],f1hist1[1],f1hist0[1],f1pc4[1],f1way[1],f1brend[1],f1ret[1],
     363              :                  f1dbecc[0],f1icaf[0],f1hist1[0],f1hist0[0],f1pc4[0],f1way[0],f1brend[0],f1ret[0]} = brdata1final[BRDATA_SIZE-1:0];
     364              : 
     365              :       end
     366              : 
     367              : 
     368              : 
     369              : 
     370              :    assign {brdata1eff[BRDATA_SIZE-1:0],brdata0eff[BRDATA_SIZE-1:0]} = (({BRDATA_SIZE*2{qren[0]}} & {brdata1[BRDATA_SIZE-1:0],brdata0[BRDATA_SIZE-1:0]}) |
     371              :                                                                        ({BRDATA_SIZE*2{qren[1]}} & {brdata2[BRDATA_SIZE-1:0],brdata1[BRDATA_SIZE-1:0]}) |
     372              :                                                                        ({BRDATA_SIZE*2{qren[2]}} & {brdata0[BRDATA_SIZE-1:0],brdata2[BRDATA_SIZE-1:0]}));
     373              : 
     374              :    assign brdata0final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q0sel[0]}} & {                     brdata0eff[2*BRDATA_WIDTH-1:0]}) |
     375              :                                            ({BRDATA_SIZE{q0sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
     376              : 
     377              :    assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & {                     brdata1eff[2*BRDATA_WIDTH-1:0]}) |
     378              :                                            ({BRDATA_SIZE{q1sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
     379              : 
     380              :    end // if (pt.BTB_ENABLE==1)
     381              :    else begin
     382              :       assign {
     383              :                f1ictype[1:0]
     384              :                } = misc1eff[MHI:0];
     385              : 
     386              :       assign {
     387              :                f0ictype[1:0]
     388              :                } = misc0eff[MHI:0];
     389              : 
     390              :       assign brdata_in[BRDATA_SIZE-1:0] = {
     391              :                                             iccm_rd_ecc_double_err[1],ic_access_fault_f[1],
     392              :                                             iccm_rd_ecc_double_err[0],ic_access_fault_f[0]
     393              :                                             };
     394              :       assign {f0dbecc[1],f0icaf[1],
     395              :               f0dbecc[0],f0icaf[0]} = brdata0final[BRDATA_SIZE-1:0];
     396              : 
     397              :       assign {f1dbecc[1],f1icaf[1],
     398              :               f1dbecc[0],f1icaf[0]} = brdata1final[BRDATA_SIZE-1:0];
     399              : 
     400              :       assign {brdata1eff[BRDATA_SIZE-1:0],brdata0eff[BRDATA_SIZE-1:0]} = (({BRDATA_SIZE*2{qren[0]}} & {brdata1[BRDATA_SIZE-1:0],brdata0[BRDATA_SIZE-1:0]}) |
     401              :                                                                           ({BRDATA_SIZE*2{qren[1]}} & {brdata2[BRDATA_SIZE-1:0],brdata1[BRDATA_SIZE-1:0]}) |
     402              :                                                                           ({BRDATA_SIZE*2{qren[2]}} & {brdata0[BRDATA_SIZE-1:0],brdata2[BRDATA_SIZE-1:0]}));
     403              : 
     404              :       assign brdata0final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q0sel[0]}} & {                     brdata0eff[2*BRDATA_WIDTH-1:0]}) |
     405              :                                               ({BRDATA_SIZE{q0sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata0eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
     406              : 
     407              :       assign brdata1final[BRDATA_SIZE-1:0] = (({BRDATA_SIZE{q1sel[0]}} & {                     brdata1eff[2*BRDATA_WIDTH-1:0]}) |
     408              :                                               ({BRDATA_SIZE{q1sel[1]}} & {{BRDATA_WIDTH{1'b0}},brdata1eff[BRDATA_SIZE-1:BRDATA_WIDTH]}));
     409              : 
     410              :    end // else: !if(pt.BTB_ENABLE==1)
     411              : 
     412              : 
     413              :    // possible states of { sf0_valid, sf1_valid, f2_valid }
     414              :    //
     415              :    // 000    if->f0
     416              :    // 100    if->f1
     417              :    // 101    illegal
     418              :    // 010    if->f1, f1->f0
     419              :    // 110    if->f2
     420              :    // 001    if->f1, f2->f0
     421              :    // 011    if->f2, f2->f1, f1->f0
     422              :    // 111   !if,     no shift
     423              : 
     424              :    assign f2_valid           =  f2val[0];
     425              :    assign sf1_valid          =  sf1val[0];
     426              :    assign sf0_valid          =  sf0val[0];
     427              : 
     428              :    // interface to fetch
     429              : 
     430              :    assign consume_fb0        = ~sf0val[0] & f0val[0];
     431              : 
     432              :    assign consume_fb1        = ~sf1val[0] & f1val[0];
     433              : 
     434              :    assign ifu_fb_consume1    =  consume_fb0 & ~consume_fb1 & ~exu_flush_final;
     435              :    assign ifu_fb_consume2    =  consume_fb0 &  consume_fb1 & ~exu_flush_final;
     436              : 
     437              :    assign ifvalid            =  ifu_fetch_val[0];
     438              : 
     439              :    assign shift_f1_f0        =  ~sf0_valid &  sf1_valid;
     440              :    assign shift_f2_f0        =  ~sf0_valid & ~sf1_valid &  f2_valid;
     441              :    assign shift_f2_f1        =  ~sf0_valid &  sf1_valid &  f2_valid;
     442              : 
     443              :    assign fetch_to_f0        =  ~sf0_valid & ~sf1_valid & ~f2_valid & ifvalid;
     444              : 
     445              :    assign fetch_to_f1        = (~sf0_valid & ~sf1_valid &  f2_valid & ifvalid)  |
     446              :                                (~sf0_valid &  sf1_valid & ~f2_valid & ifvalid)  |
     447              :                                ( sf0_valid & ~sf1_valid & ~f2_valid & ifvalid);
     448              : 
     449              :    assign fetch_to_f2        = (~sf0_valid &  sf1_valid &  f2_valid & ifvalid)  |
     450              :                                ( sf0_valid &  sf1_valid & ~f2_valid & ifvalid);
     451              : 
     452              : 
     453              :    assign f2val_in[1:0]      = ({2{ fetch_to_f2 &                               ~exu_flush_final}} & ifu_fetch_val[1:0]) |
     454              :                                ({2{~fetch_to_f2 & ~shift_f2_f1 & ~shift_f2_f0 & ~exu_flush_final}} & f2val[1:0]        );
     455              : 
     456              : 
     457              :    assign sf1val[1:0]        = ({2{ f1_shift_2B}} & {1'b0,f1val[1]}) |
     458              :                                ({2{~f1_shift_2B}} & f1val[1:0]     );
     459              : 
     460              :    assign f1val_in[1:0]      = ({2{ fetch_to_f1                               & ~exu_flush_final}} & ifu_fetch_val[1:0]) |
     461              :                                ({2{                shift_f2_f1                & ~exu_flush_final}} & f2val[1:0]        ) |
     462              :                                ({2{~fetch_to_f1 & ~shift_f2_f1 & ~shift_f1_f0 & ~exu_flush_final}} & sf1val[1:0]       );
     463              : 
     464              : 
     465              : 
     466              :    assign sf0val[1:0]        = ({2{ shift_2B            }} & {1'b0,f0val[1]}) |
     467              :                                ({2{~shift_2B & ~shift_4B}} & f0val[1:0]);
     468              : 
     469              :    assign f0val_in[1:0]      = ({2{fetch_to_f0                                & ~exu_flush_final}} & ifu_fetch_val[1:0]) |
     470              :                                ({2{                shift_f2_f0                & ~exu_flush_final}} & f2val[1:0]        ) |
     471              :                                ({2{                               shift_f1_f0 & ~exu_flush_final}} & sf1val[1:0]       ) |
     472              :                                ({2{~fetch_to_f0 & ~shift_f2_f0 & ~shift_f1_f0 & ~exu_flush_final}} & sf0val[1:0]       );
     473              : 
     474              :    assign {q1eff[31:0],q0eff[31:0]} = (({64{qren[0]}} & {q1[31:0],q0[31:0]}) |
     475              :                                        ({64{qren[1]}} & {q2[31:0],q1[31:0]}) |
     476              :                                        ({64{qren[2]}} & {q0[31:0],q2[31:0]}));
     477              : 
     478              :    assign q0final[31:0]      = ({32{q0sel[0]}} & {      q0eff[31:0]}) |
     479              :                                ({32{q0sel[1]}} & {16'b0,q0eff[31:16]});
     480              : 
     481              :    assign q1final[15:0]      = ({16{q1sel[0]}} & q1eff[15:0] ) |
     482              :                                ({16{q1sel[1]}} & q1eff[31:16]);
     483         1321 :    logic [31:1] q0pceff, q0pcfinal;
     484          341 :    logic [31:1] q1pceff;
     485              : 
     486              :    assign {q1pceff[31:1],q0pceff[31:1]} = (({62{qren[0]}} & {q1pc[31:1],q0pc[31:1]}) |
     487              :                                            ({62{qren[1]}} & {q2pc[31:1],q1pc[31:1]}) |
     488              :                                            ({62{qren[2]}} & {q0pc[31:1],q2pc[31:1]}));
     489              : 
     490              : 
     491              :    assign q0pcfinal[31:1]      = ({31{q0sel[0]}} & ( q0pceff[31:1])) |
     492              :                                  ({31{q0sel[1]}} & ( q0pceff[31:1] + 31'd1));
     493              : 
     494              :    assign aligndata[31:0]    = ({32{ f0val[1]           }} & {q0final[31:0]}) |
     495              :                                ({32{~f0val[1] & f0val[0]}} & {q1final[15:0],q0final[15:0]});
     496              : 
     497              :    assign alignval[1:0]      = ({ 2{ f0val[1]           }} & {2'b11}) |
     498              :                                ({ 2{~f0val[1] & f0val[0]}} & {f1val[0],1'b1});
     499              : 
     500              :    assign alignicaf[1:0]    = ({ 2{ f0val[1]           }} &  f0icaf[1:0]          ) |
     501              :                               ({ 2{~f0val[1] & f0val[0]}} & {f1icaf[0],f0icaf[0]});
     502              : 
     503              :    assign aligndbecc[1:0]    = ({ 2{ f0val[1]           }} &  f0dbecc[1:0]          ) |
     504              :                               ({ 2{~f0val[1] & f0val[0]}} & {f1dbecc[0],f0dbecc[0]});
     505              : 
     506              :    if (pt.BTB_ENABLE==1) begin
     507              : 
     508              :    // for branch prediction
     509              : 
     510              :    assign alignbrend[1:0]    = ({ 2{ f0val[1]           }} &  f0brend[1:0]          ) |
     511              :                                ({ 2{~f0val[1] & f0val[0]}} & {f1brend[0],f0brend[0]});
     512              : 
     513              :    assign alignpc4[1:0]      = ({ 2{ f0val[1]           }} &  f0pc4[1:0]        ) |
     514              :                                ({ 2{~f0val[1] & f0val[0]}} & {f1pc4[0],f0pc4[0]});
     515              : 
     516              :       if(pt.BTB_FULLYA) begin
     517              :          assign alignindex[0]      = f0index[0];
     518              :          assign alignindex[1]      = f0val[1] ? f0index[1] : f1index[0];
     519              :       end
     520              : 
     521              :    assign alignret[1:0]      = ({ 2{ f0val[1]           }} &  f0ret[1:0]        ) |
     522              :                                ({ 2{~f0val[1] & f0val[0]}} & {f1ret[0],f0ret[0]});
     523              : 
     524              :    assign alignway[1:0]      = ({ 2{ f0val[1]           }} &  f0way[1:0]        ) |
     525              :                                ({ 2{~f0val[1] & f0val[0]}} & {f1way[0],f0way[0]});
     526              : 
     527              :    assign alignhist1[1:0]    = ({ 2{ f0val[1]           }} &  f0hist1[1:0]          ) |
     528              :                                ({ 2{~f0val[1] & f0val[0]}} & {f1hist1[0],f0hist1[0]});
     529              : 
     530              :    assign alignhist0[1:0]    = ({ 2{ f0val[1]           }} &  f0hist0[1:0]          ) |
     531              :                                ({ 2{~f0val[1] & f0val[0]}} & {f1hist0[0],f0hist0[0]});
     532              : 
     533              :    assign secondpc[31:1]     = ({31{ f0val[1]           }} &  (q0pceff[31:1] + 31'd1)) |
     534              :                                // you need the base pc for 2nd one only (4B max, 2B for the 1st and 2B for the 2nd)
     535              :                                ({31{~f0val[1] & f0val[0]}} &   q1pceff[31:1]      );
     536              : 
     537              : 
     538              :    assign firstpc[31:1]      =  q0pcfinal[31:1];
     539              :       end // if (pt.BTB_ENABLE==1)
     540              : 
     541              :    assign alignfromf1[1]     =      ~f0val[1] & f0val[0];
     542              : 
     543              : 
     544              :    assign ifu_i0_pc[31:1]    =  q0pcfinal[31:1];
     545              : 
     546              : 
     547              :    assign ifu_i0_pc4         =  first4B;
     548              : 
     549              : 
     550              :    assign ifu_i0_cinst[15:0] = aligndata[15:0];
     551              : 
     552              :    assign first4B            = (aligndata[1:0] == 2'b11);
     553              :    assign first2B            = ~first4B;
     554              : 
     555              :    assign ifu_i0_valid       = (first4B & alignval[1]) |
     556              :                                (first2B & alignval[0]);
     557              : 
     558              :    // inst access fault on any byte of inst results in access fault for the inst
     559              :    assign ifu_i0_icaf        = (first4B & (|alignicaf[1:0])) |
     560              :                                (first2B &   alignicaf[0]   );
     561              : 
     562              :    assign ifu_i0_icaf_type[1:0] = (first4B & ~f0val[1] & f0val[0] & ~alignicaf[0] & ~aligndbecc[0]) ? f1ictype[1:0] : f0ictype[1:0];
     563              : 
     564              : 
     565              :    assign icaf_eff[1:0] = alignicaf[1:0] | aligndbecc[1:0];
     566              : 
     567              :    assign ifu_i0_icaf_second = first4B & ~icaf_eff[0] & icaf_eff[1];
     568              : 
     569              :    assign ifu_i0_dbecc       = (first4B & (|aligndbecc[1:0])) |
     570              :                                (first2B &   aligndbecc[0]   );
     571              : 
     572              : 
     573              :    assign ifirst[31:0]       =  aligndata[31:0];
     574              : 
     575              : 
     576              :    assign ifu_i0_instr[31:0] = ({32{first4B & alignval[1]}} & ifirst[31:0]) |
     577              :                                ({32{first2B & alignval[0]}} & uncompress0[31:0]);
     578              : 
     579              : if(pt.BTB_ENABLE==1) begin : genblock2
     580              : 
     581              :    // if you detect br does not start on instruction boundary
     582              : 
     583              :    el2_btb_addr_hash #(.pt(pt)) firsthash (.pc(firstpc [pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
     584              :                                             .hash(firstpc_hash [pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
     585              :    el2_btb_addr_hash #(.pt(pt)) secondhash(.pc(secondpc[pt.BTB_INDEX3_HI:pt.BTB_INDEX1_LO]),
     586              :                                             .hash(secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]));
     587              : 
     588              :    if(pt.BTB_FULLYA) begin
     589              :       assign firstbrtag_hash = firstpc;
     590              :       assign secondbrtag_hash = secondpc;
     591              :    end
     592              :    else begin
     593              :       if(pt.BTB_BTAG_FOLD) begin : btbfold
     594              :          el2_btb_tag_hash_fold #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
     595              :                                                          .hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0]));
     596              :          el2_btb_tag_hash_fold #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
     597              :                                                          .hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0]));
     598              :       end
     599              :       else begin : btbfold
     600              :          el2_btb_tag_hash #(.pt(pt)) first_brhash (.pc(firstpc [pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
     601              :                                                     .hash(firstbrtag_hash [pt.BTB_BTAG_SIZE-1:0]));
     602              :          el2_btb_tag_hash #(.pt(pt)) second_brhash(.pc(secondpc[pt.BTB_ADDR_HI+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE+pt.BTB_BTAG_SIZE:pt.BTB_ADDR_HI+1]),
     603              :                                                     .hash(secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0]));
     604              :       end
     605              :    end // else: !if(pt.BTB_FULLYA)
     606              : 
     607              : 
     608              :    // start_indexing - you want pc to be based on where the end of branch is prediction
     609              :    // normal indexing pc based that's incorrect now for pc4 cases it's pc4 + 2
     610              : 
     611          339 :    always_comb begin
     612              : 
     613          339 :       i0_brp                 = '0;
     614              : 
     615          339 :       i0_br_start_error      = (first4B & alignval[1] & alignbrend[0]);
     616              : 
     617          339 :       i0_brp.valid           = (first2B & alignbrend[0]) |
     618          339 :                                (first4B & alignbrend[1]) |
     619          339 :                                 i0_br_start_error;
     620              : 
     621          339 :       i0_brp_pc4             = (first2B & alignpc4[0]) |
     622          339 :                                (first4B & alignpc4[1]);
     623              : 
     624          339 :       i0_brp.ret             = (first2B & alignret[0]) |
     625          339 :                                (first4B & alignret[1]);
     626              : 
     627          339 :       i0_brp.way             = (first2B | alignbrend[0])  ?  alignway[0]  :  alignway[1];
     628              : 
     629          339 :       i0_brp.hist[1]         = (first2B & alignhist1[0]) |
     630          339 :                                (first4B & alignhist1[1]);
     631              : 
     632          339 :       i0_brp.hist[0]         = (first2B & alignhist0[0]) |
     633          339 :                                (first4B & alignhist0[1]);
     634              : 
     635          339 :       i0_ends_f1             =  first4B & alignfromf1[1];
     636              : 
     637          339 :       i0_brp.toffset[11:0]   = (i0_ends_f1)  ?  f1poffset[11:0]  :  f0poffset[11:0];
     638              : 
     639          339 :       i0_brp.prett[31:1]     = (i0_ends_f1)  ?  f1prett[31:1]    :  f0prett[31:1];
     640              : 
     641          339 :       i0_brp.br_start_error  = i0_br_start_error;
     642              : 
     643          339 :       i0_brp.bank            = (first2B | alignbrend[0])  ?  firstpc[1]  :  secondpc[1];
     644              : 
     645          339 :       i0_brp.br_error        = (i0_brp.valid &  i0_brp_pc4 &  first2B) |
     646          339 :                                (i0_brp.valid & ~i0_brp_pc4 &  first4B);
     647              : 
     648          339 :       if(pt.BTB_FULLYA)
     649            0 :         ifu_i0_fa_index = (first2B | alignbrend[0])  ?  alignindex[0]  :  alignindex[1];
     650              :       else
     651          339 :         ifu_i0_fa_index = '0;
     652              : 
     653              :  end
     654              : 
     655              : 
     656              :    assign ifu_i0_bp_index[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO] = (first2B | alignbrend[0])  ?  firstpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO]  :
     657              :                                                                                          secondpc_hash[pt.BTB_ADDR_HI:pt.BTB_ADDR_LO];
     658              : 
     659              :    assign ifu_i0_bp_fghr[pt.BHT_GHR_SIZE-1:0]            = (i0_ends_f1)               ?  f1fghr[pt.BHT_GHR_SIZE-1:0]  :
     660              :                                                                                          f0fghr[pt.BHT_GHR_SIZE-1:0];
     661              : 
     662              :    assign ifu_i0_bp_btag[pt.BTB_BTAG_SIZE-1:0]           = (first2B | alignbrend[0])  ?  firstbrtag_hash[pt.BTB_BTAG_SIZE-1:0]  :
     663              :                                                                                          secondbrtag_hash[pt.BTB_BTAG_SIZE-1:0];
     664              : end
     665              : else begin
     666              :    assign i0_brp = '0;
     667              :    assign ifu_i0_bp_index = '0;
     668              :    assign ifu_i0_bp_fghr = '0;
     669              :    assign ifu_i0_bp_btag = '0;
     670              : end // else: !if(pt.BTB_ENABLE==1)
     671              : 
     672              :    // decompress
     673              : 
     674              :    // quiet inputs for 4B inst
     675              :    el2_ifu_compress_ctl compress0 (.din((first2B) ? aligndata[15:0] : '0), .dout(uncompress0[31:0]));
     676              : 
     677              : 
     678              : 
     679              :    assign i0_shift           =  dec_i0_decode_d & ~error_stall;
     680              : 
     681              :    assign ifu_pmu_instr_aligned = i0_shift;
     682              : 
     683              : 
     684              :    // compute how many bytes are being shifted from f0
     685              : 
     686              :    assign shift_2B           =  i0_shift & first2B;
     687              : 
     688              :    assign shift_4B           =  i0_shift & first4B;
     689              : 
     690              :    // exact equations for the queue logic
     691              :    assign f0_shift_2B        = (shift_2B & f0val[0]            ) |
     692              :                                (shift_4B & f0val[0] & ~f0val[1]);
     693              : 
     694              : 
     695              :    // f0 valid states
     696              :    //     11
     697              :    //     10
     698              :    //     00
     699              : 
     700              :    assign f1_shift_2B        =  f0val[0] & ~f0val[1] & shift_4B;
     701              : 
     702              : 
     703              : 
     704              : endmodule