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