Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—exu—el2_exu_alu_ctl.sv Coverage Hit Total
Test Date: 19-09-2024 Toggle 96.6% 85 88
Test: all Branch 100.0% 22 22

            Line data    Source code
       1              : // SPDX-License-Identifier: Apache-2.0
       2              : // Copyright 2020 Western Digital Corporation or its affiliates.
       3              : //
       4              : // Licensed under the Apache License, Version 2.0 (the "License");
       5              : // you may not use this file except in compliance with the License.
       6              : // You may obtain a copy of the License at
       7              : //
       8              : // http://www.apache.org/licenses/LICENSE-2.0
       9              : //
      10              : // Unless required by applicable law or agreed to in writing, software
      11              : // distributed under the License is distributed on an "AS IS" BASIS,
      12              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13              : // See the License for the specific language governing permissions and
      14              : // limitations under the License.
      15              : 
      16              : 
      17              : module el2_exu_alu_ctl
      18              : import el2_pkg::*;
      19              : #(
      20              : `include "el2_param.vh"
      21              : )
      22              :   (
      23     61849896 :    input  logic                  clk,                // Top level clock
      24          364 :    input  logic                  rst_l,              // Reset
      25            0 :    input  logic                  scan_mode,          // Scan control
      26              : 
      27       613954 :    input  logic                  flush_upper_x,      // Branch flush from previous cycle
      28        58638 :    input  logic                  flush_lower_r,      // Master flush of entire pipeline
      29      6190093 :    input  logic                  enable,             // Clock enable
      30      5396604 :    input  logic                  valid_in,           // Valid
      31         1460 :    input  el2_alu_pkt_t         ap,                 // predecodes
      32        75092 :    input  logic                  csr_ren_in,         // CSR select
      33         6941 :    input  logic        [31:0]    csr_rddata_in,      // CSR data
      34       359544 :    input  logic signed [31:0]    a_in,               // A operand
      35      2494553 :    input  logic        [31:0]    b_in,               // B operand
      36         1288 :    input  logic        [31:1]    pc_in,              // for pc=pc+2,4 calculations
      37       506364 :    input  el2_predict_pkt_t     pp_in,              // Predicted branch structure
      38       123446 :    input  logic        [12:1]    brimm_in,           // Branch offset
      39              : 
      40              : 
      41       568818 :    output logic        [31:0]    result_ff,          // final result
      42       613955 :    output logic                  flush_upper_out,    // Branch flush
      43       672565 :    output logic                  flush_final_out,    // Branch flush or flush entire pipeline
      44         2370 :    output logic        [31:1]    flush_path_out,     // Branch flush PC
      45          308 :    output logic        [31:1]    pc_ff,              // flopped PC
      46      2921809 :    output logic                  pred_correct_out,   // NPC control
      47       506364 :    output el2_predict_pkt_t     predict_p_out       // Predicted branch structure
      48              :   );
      49              : 
      50              : 
      51       359552 :    logic               [31:0]    zba_a_in;
      52       878911 :    logic               [31:0]    aout;
      53       277648 :    logic                         cout,ov,neg;
      54       121745 :    logic               [31:0]    lout;
      55       343325 :    logic               [31:0]    sout;
      56       648649 :    logic                         sel_shift;
      57      3894049 :    logic                         sel_adder;
      58        59366 :    logic                         slt_one;
      59      3083810 :    logic                         actual_taken;
      60         1288 :    logic               [31:1]    pcout;
      61       391957 :    logic                         cond_mispredict;
      62       148978 :    logic                         target_mispredict;
      63      3858410 :    logic                         eq, ne, lt, ge;
      64       707268 :    logic                         any_jal;
      65      2893552 :    logic               [1:0]     newhist;
      66       707268 :    logic                         sel_pc;
      67       357190 :    logic               [31:0]    csr_write_data;
      68       726161 :    logic               [31:0]    result;
      69              : 
      70              : 
      71              : 
      72              : 
      73              :    // *** Start - BitManip ***
      74              : 
      75              :    // Zbb
      76           14 :    logic                  ap_clz;
      77         1896 :    logic                  ap_ctz;
      78         1888 :    logic                  ap_cpop;
      79         1832 :    logic                  ap_sext_b;
      80         1854 :    logic                  ap_sext_h;
      81         3366 :    logic                  ap_min;
      82         3326 :    logic                  ap_max;
      83         1793 :    logic                  ap_rol;
      84         3374 :    logic                  ap_ror;
      85         1916 :    logic                  ap_rev8;
      86         1892 :    logic                  ap_orc_b;
      87        29748 :    logic                  ap_zbb;
      88              : 
      89              :    // Zbs
      90         3527 :    logic                  ap_bset;
      91         3414 :    logic                  ap_bclr;
      92         3554 :    logic                  ap_binv;
      93         3322 :    logic                  ap_bext;
      94              : 
      95              :    // Zbp
      96         1656 :    logic                  ap_pack;
      97            0 :    logic                  ap_packu;
      98           25 :    logic                  ap_packh;
      99              : 
     100              :    // Zba
     101         1810 :    logic                  ap_sh1add;
     102         1855 :    logic                  ap_sh2add;
     103         1604 :    logic                  ap_sh3add;
     104         5187 :    logic                  ap_zba;
     105              : 
     106              : 
     107              : 
     108              :    if (pt.BITMANIP_ZBB == 1)
     109              :      begin
     110              :        assign ap_clz          =  ap.clz;
     111              :        assign ap_ctz          =  ap.ctz;
     112              :        assign ap_cpop         =  ap.cpop;
     113              :        assign ap_sext_b       =  ap.sext_b;
     114              :        assign ap_sext_h       =  ap.sext_h;
     115              :        assign ap_min          =  ap.min;
     116              :        assign ap_max          =  ap.max;
     117              :      end
     118              :    else
     119              :      begin
     120              :        assign ap_clz          =  1'b0;
     121              :        assign ap_ctz          =  1'b0;
     122              :        assign ap_cpop         =  1'b0;
     123              :        assign ap_sext_b       =  1'b0;
     124              :        assign ap_sext_h       =  1'b0;
     125              :        assign ap_min          =  1'b0;
     126              :        assign ap_max          =  1'b0;
     127              :      end
     128              : 
     129              : 
     130              :    if ( (pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1) )
     131              :      begin
     132              :        assign ap_rol          =  ap.rol;
     133              :        assign ap_ror          =  ap.ror;
     134              :        assign ap_rev8         =  ap.grev & (b_in[4:0] == 5'b11000);
     135              :        assign ap_orc_b        =  ap.gorc & (b_in[4:0] == 5'b00111);
     136              :        assign ap_zbb          =  ap.zbb;
     137              :      end
     138              :    else
     139              :      begin
     140              :        assign ap_rol          =  1'b0;
     141              :        assign ap_ror          =  1'b0;
     142              :        assign ap_rev8         =  1'b0;
     143              :        assign ap_orc_b        =  1'b0;
     144              :        assign ap_zbb          =  1'b0;
     145              :      end
     146              : 
     147              : 
     148              :    if (pt.BITMANIP_ZBS == 1)
     149              :      begin
     150              :        assign ap_bset         =  ap.bset;
     151              :        assign ap_bclr         =  ap.bclr;
     152              :        assign ap_binv         =  ap.binv;
     153              :        assign ap_bext         =  ap.bext;
     154              :      end
     155              :    else
     156              :      begin
     157              :        assign ap_bset         =  1'b0;
     158              :        assign ap_bclr         =  1'b0;
     159              :        assign ap_binv         =  1'b0;
     160              :        assign ap_bext         =  1'b0;
     161              :      end
     162              : 
     163              : 
     164              :    if (pt.BITMANIP_ZBP == 1)
     165              :      begin
     166              :        assign ap_packu        =  ap.packu;
     167              :      end
     168              :    else
     169              :      begin
     170              :        assign ap_packu        =  1'b0;
     171              :      end
     172              : 
     173              : 
     174              :    if ( (pt.BITMANIP_ZBB == 1) | (pt.BITMANIP_ZBP == 1) | (pt.BITMANIP_ZBE == 1) | (pt.BITMANIP_ZBF == 1) )
     175              :      begin
     176              :        assign ap_pack         =  ap.pack;
     177              :        assign ap_packh        =  ap.packh;
     178              :      end
     179              :    else
     180              :      begin
     181              :        assign ap_pack         =  1'b0;
     182              :        assign ap_packh        =  1'b0;
     183              :      end
     184              : 
     185              : 
     186              :    if (pt.BITMANIP_ZBA == 1)
     187              :      begin
     188              :        assign ap_sh1add       =  ap.sh1add;
     189              :        assign ap_sh2add       =  ap.sh2add;
     190              :        assign ap_sh3add       =  ap.sh3add;
     191              :        assign ap_zba          =  ap.zba;
     192              :      end
     193              :    else
     194              :      begin
     195              :        assign ap_sh1add       =  1'b0;
     196              :        assign ap_sh2add       =  1'b0;
     197              :        assign ap_sh3add       =  1'b0;
     198              :        assign ap_zba          =  1'b0;
     199              :      end
     200              : 
     201              : 
     202              : 
     203              : 
     204              :    // *** End   - BitManip ***
     205              : 
     206              : 
     207              : 
     208              : 
     209              :    rvdffpcie #(31) i_pc_ff      (.*, .clk(clk), .en(enable),              .din(pc_in[31:1]),    .dout(pc_ff[31:1]));   // any PC is run through here - doesn't have to be alu
     210              :    rvdffe    #(32) i_result_ff  (.*, .clk(clk), .en(enable & valid_in),   .din(result[31:0]),   .dout(result_ff[31:0]));
     211              : 
     212              : 
     213              : 
     214              :    // immediates are just muxed into rs2
     215              : 
     216              :    // add    =>  add=1;
     217              :    // sub    =>  add=1; sub=1;
     218              : 
     219              :    // and    =>  lctl=3
     220              :    // or     =>  lctl=2
     221              :    // xor    =>  lctl=1
     222              : 
     223              :    // sll    =>  sctl=3
     224              :    // srl    =>  sctl=2
     225              :    // sra    =>  sctl=1
     226              : 
     227              :    // slt    =>  slt
     228              : 
     229              :    // lui    =>  lctl=2; or x0, imm20 previously << 12
     230              :    // auipc  =>  add;   add pc, imm20 previously << 12
     231              : 
     232              :    // beq    =>  bctl=4; add; add x0, pc, sext(offset[12:1])
     233              :    // bne    =>  bctl=3; add; add x0, pc, sext(offset[12:1])
     234              :    // blt    =>  bctl=2; add; add x0, pc, sext(offset[12:1])
     235              :    // bge    =>  bctl=1; add; add x0, pc, sext(offset[12:1])
     236              : 
     237              :    // jal    =>  rs1=pc {pc[31:1],1'b0},  rs2=sext(offset20:1]);   rd=pc+[2,4]
     238              :    // jalr   =>  rs1=rs1,                 rs2=sext(offset20:1]);   rd=pc+[2,4]
     239              : 
     240              : 
     241              : 
     242              :    assign zba_a_in[31:0]      = ( {32{ ap_sh1add}} & {a_in[30:0],1'b0} ) |
     243              :                                 ( {32{ ap_sh2add}} & {a_in[29:0],2'b0} ) |
     244              :                                 ( {32{ ap_sh3add}} & {a_in[28:0],3'b0} ) |
     245              :                                 ( {32{~ap_zba   }} &  a_in[31:0]       );
     246              : 
     247      2574746 :    logic        [31:0]    bm;
     248              : 
     249              :    assign bm[31:0]            = ( ap.sub )  ?  ~b_in[31:0]  :  b_in[31:0];
     250              : 
     251              :    assign {cout, aout[31:0]}  = {1'b0, zba_a_in[31:0]} + {1'b0, bm[31:0]} + {32'b0, ap.sub};
     252              : 
     253              :    assign ov                  = (~a_in[31] & ~bm[31] &  aout[31]) |
     254              :                                 ( a_in[31] &  bm[31] & ~aout[31] );
     255              : 
     256              :    assign lt                  = (~ap.unsign & (neg ^ ov)) |
     257              :                                 ( ap.unsign & ~cout);
     258              : 
     259              :    assign eq                  = (a_in[31:0] == b_in[31:0]);
     260              :    assign ne                  = ~eq;
     261              :    assign neg                 =  aout[31];
     262              :    assign ge                  = ~lt;
     263              : 
     264              : 
     265              : 
     266              :    assign lout[31:0]          =  ( {32{csr_ren_in       }} &  csr_rddata_in[31:0]       ) |
     267              :                                  ( {32{ap.land & ~ap_zbb}} &  a_in[31:0] &  b_in[31:0]  ) |
     268              :                                  ( {32{ap.lor  & ~ap_zbb}} & (a_in[31:0] |  b_in[31:0]) ) |
     269              :                                  ( {32{ap.lxor & ~ap_zbb}} & (a_in[31:0] ^  b_in[31:0]) ) |
     270              :                                  ( {32{ap.land &  ap_zbb}} &  a_in[31:0] & ~b_in[31:0]  ) |
     271              :                                  ( {32{ap.lor  &  ap_zbb}} & (a_in[31:0] | ~b_in[31:0]) ) |
     272              :                                  ( {32{ap.lxor &  ap_zbb}} & (a_in[31:0] ^ ~b_in[31:0]) );
     273              : 
     274              : 
     275              : 
     276              : 
     277              :    // * * * * * * * * * * * * * * * * * *  BitManip  :  ROL,ROR      * * * * * * * * * * * * * * * * * *
     278              :    // * * * * * * * * * * * * * * * * * *  BitManip  :  ZBEXT        * * * * * * * * * * * * * * * * * *
     279              : 
     280        11014 :    logic        [5:0]     shift_amount;
     281          323 :    logic        [31:0]    shift_mask;
     282       155951 :    logic        [62:0]    shift_extend;
     283      1097270 :    logic        [62:0]    shift_long;
     284              : 
     285              : 
     286              :    assign shift_amount[5:0]            = ( { 6{ap.sll}}   & (6'd32 - {1'b0,b_in[4:0]}) ) |   // [5] unused
     287              :                                          ( { 6{ap.srl}}   &          {1'b0,b_in[4:0]}  ) |
     288              :                                          ( { 6{ap.sra}}   &          {1'b0,b_in[4:0]}  ) |
     289              :                                          ( { 6{ap_rol}}   & (6'd32 - {1'b0,b_in[4:0]}) ) |
     290              :                                          ( { 6{ap_ror}}   &          {1'b0,b_in[4:0]}  ) |
     291              :                                          ( { 6{ap_bext}}  &          {1'b0,b_in[4:0]}  );
     292              : 
     293              : 
     294              :    assign shift_mask[31:0]             = ( 32'hffffffff << ({5{ap.sll}} & b_in[4:0]) );
     295              : 
     296              : 
     297              :    assign shift_extend[31:0]           =  a_in[31:0];
     298              : 
     299              :    assign shift_extend[62:32]          = ( {31{ap.sra}} & {31{a_in[31]}} ) |
     300              :                                          ( {31{ap.sll}} &     a_in[30:0] ) |
     301              :                                          ( {31{ap_rol}} &     a_in[30:0] ) |
     302              :                                          ( {31{ap_ror}} &     a_in[30:0] );
     303              : 
     304              : 
     305              :    assign shift_long[62:0]    = 63'( shift_extend[62:0] >> shift_amount[4:0] );   // 62-32 unused
     306              : 
     307              :    assign sout[31:0]          =   shift_long[31:0] & shift_mask[31:0];
     308              : 
     309              : 
     310              : 
     311              : 
     312              :    // * * * * * * * * * * * * * * * * * *  BitManip  :  CLZ,CTZ      * * * * * * * * * * * * * * * * * *
     313              : 
     314         1906 :    logic                  bitmanip_clz_ctz_sel;
     315       360108 :    logic        [31:0]    bitmanip_a_reverse_ff;
     316          416 :    logic        [31:0]    bitmanip_lzd_in;
     317          425 :    logic        [5:0]     bitmanip_dw_lzd_enc;
     318           90 :    logic        [5:0]     bitmanip_clz_ctz_result;
     319              : 
     320              :    assign bitmanip_clz_ctz_sel         =  ap_clz | ap_ctz;
     321              : 
     322              :    assign bitmanip_a_reverse_ff[31:0]  = {a_in[0],  a_in[1],  a_in[2],  a_in[3],  a_in[4],  a_in[5],  a_in[6],  a_in[7],
     323              :                                           a_in[8],  a_in[9],  a_in[10], a_in[11], a_in[12], a_in[13], a_in[14], a_in[15],
     324              :                                           a_in[16], a_in[17], a_in[18], a_in[19], a_in[20], a_in[21], a_in[22], a_in[23],
     325              :                                           a_in[24], a_in[25], a_in[26], a_in[27], a_in[28], a_in[29], a_in[30], a_in[31]};
     326              : 
     327              :    assign bitmanip_lzd_in[31:0]        = ( {32{ap_clz}} & a_in[31:0]                 ) |
     328              :                                          ( {32{ap_ctz}} & bitmanip_a_reverse_ff[31:0]);
     329              : 
     330          334 :    logic        [31:0]    bitmanip_lzd_os;
     331              :    integer                i;
     332         1398 :    logic                  found;
     333              : 
     334          323 :    always_comb
     335          323 :      begin
     336          323 :         bitmanip_lzd_os[31:0]   =  bitmanip_lzd_in[31:0];
     337          323 :         bitmanip_dw_lzd_enc[5:0]=  6'b0;
     338          323 :         found = 1'b0;
     339              : 
     340          323 :         for (int i=0; i<32; i++) begin
     341        62496 :           if (bitmanip_lzd_os[31] == 1'b0 && found == 0) begin
     342    865145792 :               bitmanip_dw_lzd_enc[5:0]=  bitmanip_dw_lzd_enc[5:0] + 6'b00_0001;
     343    865145792 :               bitmanip_lzd_os[31:0]   =  bitmanip_lzd_os[31:0] << 1;
     344              :            end
     345              :            else
     346        62496 :               found=1'b1;
     347              :         end
     348              :      end
     349              : 
     350              : 
     351              : 
     352              :    assign bitmanip_clz_ctz_result[5:0] = {6{bitmanip_clz_ctz_sel}} & {bitmanip_dw_lzd_enc[5],( {5{~bitmanip_dw_lzd_enc[5]}} & bitmanip_dw_lzd_enc[4:0] )};
     353              : 
     354              : 
     355              : 
     356              : 
     357              :    // * * * * * * * * * * * * * * * * * *  BitManip  :  CPOP         * * * * * * * * * * * * * * * * * *
     358              : 
     359        46630 :    logic        [5:0]     bitmanip_cpop;
     360          104 :    logic        [5:0]     bitmanip_cpop_result;
     361              : 
     362              : 
     363              :    integer                bitmanip_cpop_i;
     364              : 
     365          323 :    always_comb
     366          323 :      begin
     367          323 :        bitmanip_cpop[5:0]               =  6'b0;
     368              : 
     369          323 :        for (bitmanip_cpop_i=0; bitmanip_cpop_i<32; bitmanip_cpop_i++)
     370        10336 :          begin
     371        10336 :             bitmanip_cpop[5:0]          =  bitmanip_cpop[5:0] + {5'b0,a_in[bitmanip_cpop_i]};
     372              :          end      // FOR    bitmanip_cpop_i
     373              :      end          // ALWAYS_COMB
     374              : 
     375              : 
     376              :    assign bitmanip_cpop_result[5:0]    =  {6{ap_cpop}} & bitmanip_cpop[5:0];
     377              : 
     378              : 
     379              : 
     380              : 
     381              :    // * * * * * * * * * * * * * * * * * *  BitManip  :  SEXT_B,SEXT_H  * * * * * * * * * * * * * * * * *
     382              : 
     383          914 :    logic       [31:0]     bitmanip_sext_result;
     384              : 
     385              :    assign bitmanip_sext_result[31:0]   = ( {32{ap_sext_b}} & { {24{a_in[7]}} ,a_in[7:0]  } ) |
     386              :                                          ( {32{ap_sext_h}} & { {16{a_in[15]}},a_in[15:0] } );
     387              : 
     388              : 
     389              : 
     390              : 
     391              :    // * * * * * * * * * * * * * * * * * *  BitManip  :  MIN,MAX,MINU,MAXU  * * * * * * * * * * * * * * *
     392              : 
     393         6692 :    logic                  bitmanip_minmax_sel;
     394         1312 :    logic        [31:0]    bitmanip_minmax_result;
     395              : 
     396              :    assign bitmanip_minmax_sel          =  ap_min | ap_max;
     397              : 
     398      4293403 :    logic                  bitmanip_minmax_sel_a;
     399              : 
     400              :    assign bitmanip_minmax_sel_a        =  ge  ^ ap_min;
     401              : 
     402              :    assign bitmanip_minmax_result[31:0] = ({32{bitmanip_minmax_sel &  bitmanip_minmax_sel_a}}  &  a_in[31:0]) |
     403              :                                          ({32{bitmanip_minmax_sel & ~bitmanip_minmax_sel_a}}  &  b_in[31:0]);
     404              : 
     405              : 
     406              : 
     407              : 
     408              :    // * * * * * * * * * * * * * * * * * *  BitManip  :  PACK, PACKU, PACKH * * * * * * * * * * * * * * *
     409              : 
     410          382 :    logic        [31:0]    bitmanip_pack_result;
     411            0 :    logic        [31:0]    bitmanip_packu_result;
     412           36 :    logic        [31:0]    bitmanip_packh_result;
     413              : 
     414              :    assign bitmanip_pack_result[31:0]   = {32{ap_pack}}  & {b_in[15:0], a_in[15:0]};
     415              :    assign bitmanip_packu_result[31:0]  = {32{ap_packu}} & {b_in[31:16],a_in[31:16]};
     416              :    assign bitmanip_packh_result[31:0]  = {32{ap_packh}} & {16'b0,b_in[7:0],a_in[7:0]};
     417              : 
     418              : 
     419              : 
     420              :    // * * * * * * * * * * * * * * * * * *  BitManip  :  REV, ORC_B   * * * * * * * * * * * * * * * * * *
     421              : 
     422          266 :    logic        [31:0]    bitmanip_rev8_result;
     423          720 :    logic        [31:0]    bitmanip_orc_b_result;
     424              : 
     425              :    assign bitmanip_rev8_result[31:0]   = {32{ap_rev8}}  & {a_in[7:0],a_in[15:8],a_in[23:16],a_in[31:24]};
     426              : 
     427              : 
     428              : // uint32_t gorc32(uint32_t rs1, uint32_t rs2)
     429              : // {
     430              : //      uint32_t x = rs1;
     431              : //      int shamt = rs2 & 31;                                                        ORC.B  ORC16
     432              : //      if (shamt &  1) x |= ((x & 0x55555555) <<  1) | ((x & 0xAAAAAAAA) >>  1);      1      0
     433              : //      if (shamt &  2) x |= ((x & 0x33333333) <<  2) | ((x & 0xCCCCCCCC) >>  2);      1      0
     434              : //      if (shamt &  4) x |= ((x & 0x0F0F0F0F) <<  4) | ((x & 0xF0F0F0F0) >>  4);      1      0
     435              : //      if (shamt &  8) x |= ((x & 0x00FF00FF) <<  8) | ((x & 0xFF00FF00) >>  8);      0      0
     436              : //      if (shamt & 16) x |= ((x & 0x0000FFFF) << 16) | ((x & 0xFFFF0000) >> 16);      0      1
     437              : //      return x;
     438              : // }
     439              : 
     440              : 
     441              : // BEFORE              31  ,   30  ,   29  ,   28  ,    27  ,   26,     25,     24
     442              : // shamt[0]  b =    a31|a30,a31|a30,a29|a28,a29|a28, a27|a26,a27|a26,a25|a24,a25|a24
     443              : // shamt[1]  c =    b31|b29,b30|b28,b31|b29,b30|b28, b27|b25,b26|b24,b27|b25,b26|b24
     444              : // shamt[2]  d =    c31|c27,c30|c26,c29|c25,c28|c24, c31|c27,c30|c26,c29|c25,c28|c24
     445              : //
     446              : // Expand d31 =        c31         |         c27;
     447              : //            =   b31   |   b29    |    b27   |   b25;
     448              : //            = a31|a30 | a29|a28  |  a27|a26 | a25|a24
     449              : 
     450              :    assign bitmanip_orc_b_result[31:0]  = {32{ap_orc_b}} & { {8{| a_in[31:24]}}, {8{| a_in[23:16]}}, {8{| a_in[15:8]}}, {8{| a_in[7:0]}} };
     451              : 
     452              : 
     453              : 
     454              :    // * * * * * * * * * * * * * * * * * *  BitManip  :  ZBSET, ZBCLR, ZBINV  * * * * * * * * * * * * * *
     455              : 
     456        39756 :    logic        [31:0]    bitmanip_sb_1hot;
     457         1983 :    logic        [31:0]    bitmanip_sb_data;
     458              : 
     459              :    assign bitmanip_sb_1hot[31:0]       = ( 32'h00000001 << b_in[4:0] );
     460              : 
     461              :    assign bitmanip_sb_data[31:0]       = ( {32{ap_bset}} & ( a_in[31:0] |  bitmanip_sb_1hot[31:0]) ) |
     462              :                                          ( {32{ap_bclr}} & ( a_in[31:0] & ~bitmanip_sb_1hot[31:0]) ) |
     463              :                                          ( {32{ap_binv}} & ( a_in[31:0] ^  bitmanip_sb_1hot[31:0]) );
     464              : 
     465              : 
     466              : 
     467              : 
     468              : 
     469              : 
     470              :    assign sel_shift           =  ap.sll  | ap.srl | ap.sra | ap_rol | ap_ror;
     471              :    assign sel_adder           = (ap.add  | ap.sub | ap_zba) & ~ap.slt & ~ap_min & ~ap_max;
     472              :    assign sel_pc              =  ap.jal  | pp_in.pcall | pp_in.pja | pp_in.pret;
     473              :    assign csr_write_data[31:0]= (ap.csr_imm)  ?  b_in[31:0]  :  a_in[31:0];
     474              : 
     475              :    assign slt_one             =  ap.slt & lt;
     476              : 
     477              : 
     478              : 
     479              :    assign result[31:0]        =                        lout[31:0]             |
     480              :                                 ({32{sel_shift}}    &  sout[31:0]           ) |
     481              :                                 ({32{sel_adder}}    &  aout[31:0]           ) |
     482              :                                 ({32{sel_pc}}       & {pcout[31:1],1'b0}    ) |
     483              :                                 ({32{ap.csr_write}} &  csr_write_data[31:0] ) |
     484              :                                                       {31'b0, slt_one}        |
     485              :                                 ({32{ap_bext}}      & {31'b0, sout[0]}      ) |
     486              :                                                       {26'b0, bitmanip_clz_ctz_result[5:0]} |
     487              :                                                       {26'b0, bitmanip_cpop_result[5:0]}    |
     488              :                                                        bitmanip_sext_result[31:0]    |
     489              :                                                        bitmanip_minmax_result[31:0]  |
     490              :                                                        bitmanip_pack_result[31:0]    |
     491              :                                                        bitmanip_packu_result[31:0]   |
     492              :                                                        bitmanip_packh_result[31:0]   |
     493              :                                                        bitmanip_rev8_result[31:0]    |
     494              :                                                        bitmanip_orc_b_result[31:0]   |
     495              :                                                        bitmanip_sb_data[31:0];
     496              : 
     497              : 
     498              : 
     499              :    // *** branch handling ***
     500              : 
     501              :    assign any_jal             =  ap.jal      |
     502              :                                  pp_in.pcall |
     503              :                                  pp_in.pja   |
     504              :                                  pp_in.pret;
     505              : 
     506              :    assign actual_taken        = (ap.beq & eq) |
     507              :                                 (ap.bne & ne) |
     508              :                                 (ap.blt & lt) |
     509              :                                 (ap.bge & ge) |
     510              :                                  any_jal;
     511              : 
     512              :    // for a conditional br pcout[] will be the opposite of the branch prediction
     513              :    // for jal or pcall, it will be the link address pc+2 or pc+4
     514              : 
     515              :    rvbradder ibradder (
     516              :                      .pc     ( pc_in[31:1]    ),
     517              :                      .offset ( brimm_in[12:1] ),
     518              :                      .dout   ( pcout[31:1]    ));
     519              : 
     520              : 
     521              :    // pred_correct is for the npc logic
     522              :    // pred_correct indicates not to use the flush_path
     523              :    // for any_jal pred_correct==0
     524              : 
     525              :    assign pred_correct_out    = (valid_in & ap.predict_nt & ~actual_taken & ~any_jal) |
     526              :                                 (valid_in & ap.predict_t  &  actual_taken & ~any_jal);
     527              : 
     528              : 
     529              :    // for any_jal adder output is the flush path
     530              :    assign flush_path_out[31:1]= (any_jal) ? aout[31:1] : pcout[31:1];
     531              : 
     532              : 
     533              :    // pcall and pret are included here
     534              :    assign cond_mispredict     = (ap.predict_t  & ~actual_taken) |
     535              :                                 (ap.predict_nt &  actual_taken);
     536              : 
     537              : 
     538              :    // target mispredicts on ret's
     539              : 
     540              :    assign target_mispredict   =  pp_in.pret & (pp_in.prett[31:1] != aout[31:1]);
     541              : 
     542              :    assign flush_upper_out     =   (ap.jal | cond_mispredict | target_mispredict) & valid_in & ~flush_upper_x   & ~flush_lower_r;
     543              :    assign flush_final_out     = ( (ap.jal | cond_mispredict | target_mispredict) & valid_in & ~flush_upper_x ) |  flush_lower_r;
     544              : 
     545              : 
     546              :    // .i 3
     547              :    // .o 2
     548              :    // .ilb hist[1] hist[0] taken
     549              :    // .ob newhist[1] newhist[0]
     550              :    // .type fd
     551              :    //
     552              :    // 00 0 01
     553              :    // 01 0 01
     554              :    // 10 0 00
     555              :    // 11 0 10
     556              :    // 00 1 10
     557              :    // 01 1 00
     558              :    // 10 1 11
     559              :    // 11 1 11
     560              : 
     561              :    assign newhist[1]          = ( pp_in.hist[1] &  pp_in.hist[0]) | (~pp_in.hist[0] & actual_taken);
     562              :    assign newhist[0]          = (~pp_in.hist[1] & ~actual_taken)  | ( pp_in.hist[1] & actual_taken);
     563              : 
     564          323 :    always_comb begin
     565          323 :       predict_p_out           =  pp_in;
     566              : 
     567          323 :       predict_p_out.misp      = ~flush_upper_x & ~flush_lower_r & (cond_mispredict | target_mispredict);
     568          323 :       predict_p_out.ataken    =  actual_taken;
     569          323 :       predict_p_out.hist[1]   =  newhist[1];
     570          323 :       predict_p_out.hist[0]   =  newhist[0];
     571              : 
     572              :    end
     573              : 
     574              : 
     575              : 
     576              : endmodule // el2_exu_alu_ctl