Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—lib—beh_lib.sv Coverage Hit Total
Test Date: 27-12-2024 Toggle 94.5% 137 145
Test: all Branch 100.0% 7 7

            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              : // all flops call the rvdff flop
      17              : 
      18              : 
      19              : module rvdff #( parameter WIDTH=1, SHORT=0 )
      20              :    (
      21    975881385 :      input logic [WIDTH-1:0] din,
      22  59966394116 :      input logic           clk,
      23       181870 :      input logic                   rst_l,
      24              : 
      25    226964313 :      output logic [WIDTH-1:0] dout
      26              :      );
      27              : 
      28              : if (SHORT == 1) begin
      29              :    assign dout = din;
      30              : end
      31              : else begin
      32              : `ifdef RV_CLOCKGATE
      33              :    always @(posedge tb_top.clk) begin
      34              :       #0 $strobe("CG: %0t %m din %x dout %x clk %b width %d",$time,din,dout,clk,WIDTH);
      35              :    end
      36              : `endif
      37              : 
      38  27060071642 :    always_ff @(posedge clk or negedge rst_l) begin
      39  26686803952 :       if (rst_l == 0)
      40    373274974 :         dout[WIDTH-1:0] <= 0;
      41              :       else
      42  26686796668 :         dout[WIDTH-1:0] <= din[WIDTH-1:0];
      43              :    end
      44              : 
      45              : end
      46              : endmodule
      47              : 
      48              : // rvdff with 2:1 input mux to flop din iff sel==1
      49              : module rvdffs #( parameter WIDTH=1, SHORT=0 )
      50              :    (
      51   2170675966 :      input logic [WIDTH-1:0] din,
      52   1712408709 :      input logic             en,
      53  49886542697 :      input logic           clk,
      54       167145 :      input logic                   rst_l,
      55    212764134 :      output logic [WIDTH-1:0] dout
      56              :      );
      57              : 
      58              : if (SHORT == 1) begin : genblock
      59              :    assign dout = din;
      60              : end
      61              : else begin : genblock
      62              :    rvdff #(WIDTH) dffs (.din((en) ? din[WIDTH-1:0] : dout[WIDTH-1:0]), .*);
      63              : end
      64              : 
      65              : endmodule
      66              : 
      67              : // rvdff with en and clear
      68              : module rvdffsc #( parameter WIDTH=1, SHORT=0 )
      69              :    (
      70      1229507 :      input logic [WIDTH-1:0] din,
      71      2932533 :      input logic             en,
      72      4735671 :      input logic             clear,
      73   3298181698 :      input logic           clk,
      74        12359 :      input logic                   rst_l,
      75      2907229 :      output logic [WIDTH-1:0] dout
      76              :      );
      77              : 
      78      2908966 :    logic [WIDTH-1:0]          din_new;
      79              : if (SHORT == 1) begin : genblock
      80              :    assign dout = din;
      81              : end
      82              : else begin : genblock
      83              :    assign din_new = {WIDTH{~clear}} & (en ? din[WIDTH-1:0] : dout[WIDTH-1:0]);
      84              :    rvdff #(WIDTH) dffsc (.din(din_new[WIDTH-1:0]), .*);
      85              : end
      86              : endmodule
      87              : 
      88              : // _fpga versions
      89              : module rvdff_fpga #( parameter WIDTH=1, SHORT=0 )
      90              :    (
      91    125989446 :      input logic [WIDTH-1:0] din,
      92     66887160 :      input logic           clk,
      93     19775868 :      input logic           clken,
      94  10783835316 :      input logic           rawclk,
      95        36011 :      input logic           rst_l,
      96              : 
      97     68585694 :      output logic [WIDTH-1:0] dout
      98              :      );
      99              : 
     100              : if (SHORT == 1) begin : genblock
     101              :    assign dout = din;
     102              : end
     103              : else begin : genblock
     104              :    `ifdef RV_FPGA_OPTIMIZE
     105              :     rvdffs #(WIDTH) dffs (.clk(rawclk), .en(clken), .*);
     106              : `else
     107              :     rvdff #(WIDTH)  dff (.*);
     108              : `endif
     109              : end
     110              : endmodule
     111              : 
     112              : // rvdff with 2:1 input mux to flop din iff sel==1
     113              : module rvdffs_fpga #( parameter WIDTH=1, SHORT=0 )
     114              :    (
     115    986558122 :      input logic [WIDTH-1:0] din,
     116     83315680 :      input logic             en,
     117     83981765 :      input logic           clk,
     118     87204337 :      input logic           clken,
     119  59990112110 :      input logic           rawclk,
     120       153659 :      input logic           rst_l,
     121              : 
     122     22582562 :      output logic [WIDTH-1:0] dout
     123              :      );
     124              : 
     125              : if (SHORT == 1) begin : genblock
     126              :    assign dout = din;
     127              : end
     128              : else begin : genblock
     129              : `ifdef RV_FPGA_OPTIMIZE
     130              :    rvdffs #(WIDTH)   dffs (.clk(rawclk), .en(clken & en), .*);
     131              : `else
     132              :    rvdffs #(WIDTH)   dffs (.*);
     133              : `endif
     134              : end
     135              : 
     136              : endmodule
     137              : 
     138              : // rvdff with en and clear
     139              : module rvdffsc_fpga #( parameter WIDTH=1, SHORT=0 )
     140              :    (
     141     11226184 :      input logic [WIDTH-1:0] din,
     142     11593484 :      input logic             en,
     143     24471739 :      input logic             clear,
     144      8308922 :      input logic             clk,
     145         1286 :      input logic             clken,
     146    871519856 :      input logic             rawclk,
     147         1289 :      input logic             rst_l,
     148              : 
     149     11228666 :      output logic [WIDTH-1:0] dout
     150              :      );
     151              : 
     152            0 :    logic [WIDTH-1:0]          din_new;
     153              : if (SHORT == 1) begin : genblock
     154              :    assign dout = din;
     155              : end
     156              : else begin : genblock
     157              : `ifdef RV_FPGA_OPTIMIZE
     158              :    rvdffs  #(WIDTH)   dffs  (.clk(rawclk), .din(din[WIDTH-1:0] & {WIDTH{~clear}}),.en((en | clear) & clken), .*);
     159              : `else
     160              :    rvdffsc #(WIDTH)   dffsc (.*);
     161              : `endif
     162              : end
     163              : endmodule
     164              : 
     165              : 
     166              : module rvdffe #( parameter WIDTH=1, SHORT=0, OVERRIDE=0 )
     167              :    (
     168   2032865403 :      input  logic [WIDTH-1:0] din,
     169   1672734479 :      input  logic           en,
     170  43371865616 :      input  logic           clk,
     171       153637 :      input  logic           rst_l,
     172              :      // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     173              :      /*pragma coverage off*/
     174              :      input  logic             scan_mode,
     175              :      /*pragma coverage on*/
     176    128437278 :      output logic [WIDTH-1:0] dout
     177              :      );
     178              : 
     179        16226 :    logic                      l1clk;
     180              : 
     181              : if (SHORT == 1) begin : genblock
     182              :    if (1) begin : genblock
     183              :       assign dout = din;
     184              :    end
     185              : end
     186              : else begin : genblock
     187              : 
     188              : `ifndef RV_PHYSICAL
     189              :    if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
     190              : `endif
     191              : 
     192              : `ifdef RV_FPGA_OPTIMIZE
     193              :       rvdffs #(WIDTH) dff ( .* );
     194              : `else
     195              :       rvclkhdr clkhdr ( .* );
     196              :       rvdff #(WIDTH) dff (.*, .clk(l1clk));
     197              : `endif
     198              : 
     199              : `ifndef RV_PHYSICAL
     200              :    end
     201              :    else
     202              :       $error("%m: rvdffe must be WIDTH >= 8");
     203              : `endif
     204              : end // else: !if(SHORT == 1)
     205              : 
     206              : endmodule // rvdffe
     207              : 
     208              : 
     209              : module rvdffpcie #( parameter WIDTH=31 )
     210              :    (
     211     81852567 :      input  logic [WIDTH-1:0] din,
     212   1014544758 :      input  logic             clk,
     213         3636 :      input  logic             rst_l,
     214     74462173 :      input  logic             en,
     215              :      // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     216              :      /*pragma coverage off*/
     217              :      input  logic             scan_mode,
     218              :      /*pragma coverage on*/
     219     78032790 :      output logic [WIDTH-1:0] dout
     220              :      );
     221              : 
     222              : 
     223              : 
     224              : `ifndef RV_PHYSICAL
     225              :    if (WIDTH == 31) begin: genblock
     226              : `endif
     227              : 
     228              : `ifdef RV_FPGA_OPTIMIZE
     229              :       rvdffs #(WIDTH) dff ( .* );
     230              : `else
     231              : 
     232              :       rvdfflie #(.WIDTH(WIDTH), .LEFT(19)) dff (.*);
     233              : 
     234              : `endif
     235              : 
     236              : `ifndef RV_PHYSICAL
     237              :    end
     238              :    else
     239              :       $error("%m: rvdffpcie width must be 31");
     240              : `endif
     241              : endmodule
     242              : 
     243              : // format: { LEFT, EXTRA }
     244              : // LEFT # of bits will be done with rvdffie, all else EXTRA with rvdffe
     245              : module rvdfflie #( parameter WIDTH=16, LEFT=8 )
     246              :    (
     247     34920928 :      input  logic [WIDTH-1:0] din,
     248    347660790 :      input  logic             clk,
     249          945 :      input  logic             rst_l,
     250     29920247 :      input  logic             en,
     251              :      // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     252              :      /*pragma coverage off*/
     253              :      input  logic             scan_mode,
     254              :      /*pragma coverage on*/
     255     34920435 :      output logic [WIDTH-1:0] dout
     256              :      );
     257              : 
     258              :    localparam EXTRA = WIDTH-LEFT;
     259              : 
     260              : 
     261              : 
     262              : 
     263              : 
     264              : 
     265              : 
     266              :    localparam LMSB = WIDTH-1;
     267              :    localparam LLSB = LMSB-LEFT+1;
     268              :    localparam XMSB = LLSB-1;
     269              :    localparam XLSB = LLSB-EXTRA;
     270              : 
     271              : 
     272              : `ifndef RV_PHYSICAL
     273              :    if (WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8) begin: genblock
     274              : `endif
     275              : 
     276              : `ifdef RV_FPGA_OPTIMIZE
     277              :       rvdffs #(WIDTH) dff ( .* );
     278              : `else
     279              : 
     280              :       rvdffiee #(LEFT)  dff_left  (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
     281              : 
     282              : 
     283              :       rvdffe  #(EXTRA)  dff_extra (.*, .din(din[XMSB:XLSB]), .dout(dout[XMSB:XLSB]));
     284              : 
     285              : 
     286              : 
     287              : 
     288              : `endif
     289              : 
     290              : `ifndef RV_PHYSICAL
     291              :    end
     292              :    else
     293              :       $error("%m: rvdfflie musb be WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8");
     294              : `endif
     295              : endmodule
     296              : 
     297              : 
     298              : 
     299              : 
     300              : // special power flop for predict packet
     301              : // format: { LEFT, RIGHT==31 }
     302              : // LEFT # of bits will be done with rvdffe; RIGHT is enabled by LEFT[LSB] & en
     303              : module rvdffppe #( parameter integer WIDTH = 39 )
     304              :    (
     305      9850994 :      input  logic [WIDTH-1:0] din,
     306    115884880 :      input  logic             clk,
     307          299 :      input  logic             rst_l,
     308      9565153 :      input  logic             en,
     309              :      // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     310              :      /*pragma coverage off*/
     311              :      input  logic             scan_mode,
     312              :      /*pragma coverage on*/
     313      5773261 :      output logic [WIDTH-1:0] dout
     314              :      );
     315              : 
     316              :    localparam integer RIGHT = 31;
     317              :    localparam integer LEFT  = WIDTH - RIGHT;
     318              : 
     319              :    localparam integer LMSB  = WIDTH-1;
     320              :    localparam integer LLSB  = LMSB-LEFT+1;
     321              :    localparam integer RMSB  = LLSB-1;
     322              :    localparam integer RLSB  = LLSB-RIGHT;
     323              : 
     324              : 
     325              : `ifndef RV_PHYSICAL
     326              :    if (WIDTH>=32 && LEFT>=8 && RIGHT>=8) begin: genblock
     327              : `endif
     328              : 
     329              : `ifdef RV_FPGA_OPTIMIZE
     330              :       rvdffs #(WIDTH) dff ( .* );
     331              : `else
     332              :       rvdffe #(LEFT)     dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
     333              : 
     334              :       rvdffe #(RIGHT)   dff_right (.*, .din(din[RMSB:RLSB]), .dout(dout[RMSB:RLSB]), .en(en & din[LLSB]));  // qualify with pret
     335              : 
     336              : 
     337              : `endif
     338              : 
     339              : `ifndef RV_PHYSICAL
     340              :    end
     341              :    else
     342              :       $error("%m: must be WIDTH>=32 && LEFT>=8 && RIGHT>=8");
     343              : `endif
     344              : endmodule
     345              : 
     346              : 
     347              : 
     348              : 
     349              : module rvdffie #( parameter WIDTH=1, OVERRIDE=0 )
     350              :    (
     351     23753302 :      input  logic [WIDTH-1:0] din,
     352              : 
     353    676359072 :      input  logic           clk,
     354         2392 :      input  logic           rst_l,
     355              :      // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     356              :      /*pragma coverage off*/
     357              :      input  logic             scan_mode,
     358              :      /*pragma coverage on*/
     359     23686634 :      output logic [WIDTH-1:0] dout
     360              :      );
     361              : 
     362            0 :    logic                      l1clk;
     363     34726581 :    logic                      en;
     364              : 
     365              : 
     366              : 
     367              : 
     368              : 
     369              : 
     370              : 
     371              : 
     372              : `ifndef RV_PHYSICAL
     373              :    if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
     374              : `endif
     375              : 
     376              :       assign en = |(din ^ dout);
     377              : 
     378              : `ifdef RV_FPGA_OPTIMIZE
     379              :       rvdffs #(WIDTH) dff ( .* );
     380              : `else
     381              :       rvclkhdr clkhdr ( .* );
     382              :       rvdff #(WIDTH) dff (.*, .clk(l1clk));
     383              : `endif
     384              : 
     385              : `ifndef RV_PHYSICAL
     386              :    end
     387              :    else
     388              :      $error("%m: rvdffie must be WIDTH >= 8");
     389              : `endif
     390              : 
     391              : 
     392              : endmodule
     393              : 
     394              : // ie flop but it has an .en input
     395              : module rvdffiee #( parameter WIDTH=1, OVERRIDE=0 )
     396              :    (
     397            0 :      input  logic [WIDTH-1:0] din,
     398              : 
     399         6150 :      input  logic           clk,
     400           48 :      input  logic           rst_l,
     401              :      // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     402              :      /*pragma coverage off*/
     403              :      input  logic           scan_mode,
     404              :      /*pragma coverage on*/
     405           48 :      input  logic           en,
     406            0 :      output logic [WIDTH-1:0] dout
     407              :      );
     408              : 
     409            0 :    logic                      l1clk;
     410            0 :    logic                      final_en;
     411              : 
     412              : `ifndef RV_PHYSICAL
     413              :    if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
     414              : `endif
     415              : 
     416              :       assign final_en = (|(din ^ dout)) & en;
     417              : 
     418              : `ifdef RV_FPGA_OPTIMIZE
     419              :       rvdffs #(WIDTH) dff ( .*, .en(final_en) );
     420              : `else
     421              :       rvdffe #(WIDTH) dff (.*,  .en(final_en));
     422              : `endif
     423              : 
     424              : `ifndef RV_PHYSICAL
     425              :    end
     426              :    else
     427              :       $error("%m: rvdffie width must be >= 8");
     428              : `endif
     429              : 
     430              : endmodule
     431              : 
     432              : 
     433              : 
     434              : module rvsyncss #(parameter WIDTH = 251)
     435              :    (
     436    115884880 :      input  logic                 clk,
     437          299 :      input  logic                 rst_l,
     438          359 :      input  logic [WIDTH-1:0]     din,
     439          355 :      output logic [WIDTH-1:0]     dout
     440              :      );
     441              : 
     442          355 :    logic [WIDTH-1:0]              din_ff1;
     443              : 
     444              :    rvdff #(WIDTH) sync_ff1  (.*, .din (din[WIDTH-1:0]),     .dout(din_ff1[WIDTH-1:0]));
     445              :    rvdff #(WIDTH) sync_ff2  (.*, .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
     446              : 
     447              : endmodule // rvsyncss
     448              : 
     449              : module rvsyncss_fpga #(parameter WIDTH = 251)
     450              :    (
     451      3127890 :      input  logic                 gw_clk,
     452   2624046322 :      input  logic                 rawclk,
     453         9536 :      input  logic                 clken,
     454         9433 :      input  logic                 rst_l,
     455         3439 :      input  logic [WIDTH-1:0]     din,
     456         3436 :      output logic [WIDTH-1:0]     dout
     457              :      );
     458              : 
     459         3436 :    logic [WIDTH-1:0]              din_ff1;
     460              : 
     461              :    rvdff_fpga #(WIDTH) sync_ff1  (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din[WIDTH-1:0]),     .dout(din_ff1[WIDTH-1:0]));
     462              :    rvdff_fpga #(WIDTH) sync_ff2  (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
     463              : 
     464              : endmodule // rvsyncss
     465              : 
     466              : module rvlsadder
     467              :   (
     468      2795547 :     input logic [31:0] rs1,
     469      1154729 :     input logic [11:0] offset,
     470              : 
     471      2795565 :     output logic [31:0] dout
     472              :     );
     473              : 
     474       266872 :    logic                cout;
     475       345822 :    logic                sign;
     476              : 
     477      2793494 :    logic [31:12]        rs1_inc;
     478      2491891 :    logic [31:12]        rs1_dec;
     479              : 
     480              :    assign {cout,dout[11:0]} = {1'b0,rs1[11:0]} + {1'b0,offset[11:0]};
     481              : 
     482              :    assign rs1_inc[31:12] = rs1[31:12] + 1;
     483              : 
     484              :    assign rs1_dec[31:12] = rs1[31:12] - 1;
     485              : 
     486              :    assign sign = offset[11];
     487              : 
     488              :    assign dout[31:12] = ({20{  sign ^~  cout}} &     rs1[31:12]) |
     489              :                         ({20{ ~sign &   cout}}  & rs1_inc[31:12]) |
     490              :                         ({20{  sign &  ~cout}}  & rs1_dec[31:12]);
     491              : 
     492              : endmodule // rvlsadder
     493              : 
     494              : // assume we only maintain pc[31:1] in the pipe
     495              : 
     496              : module rvbradder
     497              :   (
     498     27862542 :     input [31:1] pc,
     499     17189145 :     input [12:1] offset,
     500              : 
     501     28176752 :     output [31:1] dout
     502              :     );
     503              : 
     504      4353973 :    logic          cout;
     505      4496538 :    logic          sign;
     506              : 
     507       110892 :    logic [31:13]  pc_inc;
     508       110618 :    logic [31:13]  pc_dec;
     509              : 
     510              :    assign {cout,dout[12:1]} = {1'b0,pc[12:1]} + {1'b0,offset[12:1]};
     511              : 
     512              :    assign pc_inc[31:13] = pc[31:13] + 1;
     513              : 
     514              :    assign pc_dec[31:13] = pc[31:13] - 1;
     515              : 
     516              :    assign sign = offset[12];
     517              : 
     518              : 
     519              :    assign dout[31:13] = ({19{  sign ^~  cout}} &     pc[31:13]) |
     520              :                         ({19{ ~sign &   cout}}  & pc_inc[31:13]) |
     521              :                         ({19{  sign &  ~cout}}  & pc_dec[31:13]);
     522              : 
     523              : 
     524              : endmodule // rvbradder
     525              : 
     526              : 
     527              : // 2s complement circuit
     528              : module rvtwoscomp #( parameter WIDTH=32 )
     529              :    (
     530        61382 :      input logic [WIDTH-1:0] din,
     531              : 
     532        73114 :      output logic [WIDTH-1:0] dout
     533              :      );
     534              : 
     535        73114 :    logic [WIDTH-1:1]          dout_temp;   // holding for all other bits except for the lsb. LSB is always din
     536              : 
     537              :    genvar                     i;
     538              : 
     539              :    for ( i = 1; i < WIDTH; i++ )  begin : flip_after_first_one
     540              :       assign dout_temp[i] = (|din[i-1:0]) ? ~din[i] : din[i];
     541              :    end : flip_after_first_one
     542              : 
     543              :    assign dout[WIDTH-1:0]  = { dout_temp[WIDTH-1:1], din[0] };
     544              : 
     545              : endmodule  // 2'scomp
     546              : 
     547              : // find first
     548              : module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) )
     549              :    (
     550              :      input logic [WIDTH-1:0] din,
     551              : 
     552              :      output logic [SHIFT-1:0] dout
     553              :      );
     554              :    logic                      done;
     555              : 
     556              :    always_comb begin
     557              :       dout[SHIFT-1:0] = {SHIFT{1'b0}};
     558              :       done    = 1'b0;
     559              : 
     560              :       for ( int i = WIDTH-1; i > 0; i-- )  begin : find_first_one
     561              :          done |= din[i];
     562              :          dout[SHIFT-1:0] += done ? 1'b0 : 1'b1;
     563              :       end : find_first_one
     564              :    end
     565              : endmodule // rvfindfirst1
     566              : 
     567              : module rvfindfirst1hot #( parameter WIDTH=32 )
     568              :    (
     569              :      input logic [WIDTH-1:0] din,
     570              : 
     571              :      output logic [WIDTH-1:0] dout
     572              :      );
     573              :    logic                      done;
     574              : 
     575              :    always_comb begin
     576              :       dout[WIDTH-1:0] = {WIDTH{1'b0}};
     577              :       done    = 1'b0;
     578              :       for ( int i = 0; i < WIDTH; i++ )  begin : find_first_one
     579              :          dout[i] = ~done & din[i];
     580              :          done   |= din[i];
     581              :       end : find_first_one
     582              :    end
     583              : endmodule // rvfindfirst1hot
     584              : 
     585              : // mask and match function matches bits after finding the first 0 position
     586              : // find first starting from LSB. Skip that location and match the rest of the bits
     587              : module rvmaskandmatch #( parameter WIDTH=32 )
     588              :    (
     589        20201 :      input  logic [WIDTH-1:0] mask,     // this will have the mask in the lower bit positions
     590        21080 :      input  logic [WIDTH-1:0] data,     // this is what needs to be matched on the upper bits with the mask's upper bits
     591         1258 :      input  logic             masken,   // when 1 : do mask. 0 : full match
     592        22682 :      output logic             match
     593              :      );
     594              : 
     595        18917 :    logic [WIDTH-1:0]          matchvec;
     596         1258 :    logic                      masken_or_fullmask;
     597              : 
     598              :    assign masken_or_fullmask = masken &  ~(&mask[WIDTH-1:0]);
     599              : 
     600              :    assign matchvec[0]        = masken_or_fullmask | (mask[0] == data[0]);
     601              :    genvar                     i;
     602              : 
     603              :    for ( i = 1; i < WIDTH; i++ )  begin : match_after_first_zero
     604              :       assign matchvec[i] = (&mask[i-1:0] & masken_or_fullmask) ? 1'b1 : (mask[i] == data[i]);
     605              :    end : match_after_first_zero
     606              : 
     607              :    assign match  = &matchvec[WIDTH-1:0];    // all bits either matched or were masked off
     608              : 
     609              : endmodule // rvmaskandmatch
     610              : 
     611              : 
     612              : 
     613              : 
     614              : // Check if the S_ADDR <= addr < E_ADDR
     615              : module rvrangecheck  #(CCM_SADR = 32'h0,
     616              :                        CCM_SIZE  = 128) (
     617     10238197 :    input  logic [31:0]   addr,                             // Address to be checked for range
     618      1400507 :    output logic          in_range,                            // S_ADDR <= start_addr < E_ADDR
     619      1856327 :    output logic          in_region
     620              : );
     621              : 
     622              :    localparam REGION_BITS = 4;
     623              :    localparam MASK_BITS = 10 + $clog2(CCM_SIZE);
     624              : 
     625          925 :    logic [31:0]          start_addr;
     626          925 :    logic [3:0]           region;
     627              : 
     628              :    assign start_addr[31:0]        = CCM_SADR;
     629              :    assign region[REGION_BITS-1:0] = start_addr[31:(32-REGION_BITS)];
     630              : 
     631              :    assign in_region = (addr[31:(32-REGION_BITS)] == region[REGION_BITS-1:0]);
     632              :    if (CCM_SIZE  == 48)
     633              :     assign in_range  = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]) & ~(&addr[MASK_BITS-1 : MASK_BITS-2]);
     634              :    else
     635              :     assign in_range  = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]);
     636              : 
     637              : endmodule  // rvrangechecker
     638              : 
     639              : // 16 bit even parity generator
     640              : module rveven_paritygen #(WIDTH = 16)  (
     641              :                                          input  logic [WIDTH-1:0]  data_in,         // Data
     642              :                                          output logic              parity_out       // generated even parity
     643              :                                          );
     644              : 
     645              :    assign  parity_out =  ^(data_in[WIDTH-1:0]) ;
     646              : 
     647              : endmodule  // rveven_paritygen
     648              : 
     649              : module rveven_paritycheck #(WIDTH = 16)  (
     650              :                                            input  logic [WIDTH-1:0]  data_in,         // Data
     651              :                                            input  logic              parity_in,
     652              :                                            output logic              parity_err       // Parity error
     653              :                                            );
     654              : 
     655              :    assign  parity_err =  ^(data_in[WIDTH-1:0]) ^ parity_in ;
     656              : 
     657              : endmodule  // rveven_paritycheck
     658              : 
     659              : module rvecc_encode  (
     660       186950 :                       input [31:0] din,
     661       216601 :                       output [6:0] ecc_out
     662              :                       );
     663       216340 : logic [5:0] ecc_out_temp;
     664              : 
     665              :    assign ecc_out_temp[0] = din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30];
     666              :    assign ecc_out_temp[1] = din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31];
     667              :    assign ecc_out_temp[2] = din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31];
     668              :    assign ecc_out_temp[3] = din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25];
     669              :    assign ecc_out_temp[4] = din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25];
     670              :    assign ecc_out_temp[5] = din[26]^din[27]^din[28]^din[29]^din[30]^din[31];
     671              : 
     672              :    assign ecc_out[6:0] = {(^din[31:0])^(^ecc_out_temp[5:0]),ecc_out_temp[5:0]};
     673              : 
     674              : endmodule // rvecc_encode
     675              : 
     676              : module rvecc_decode  (
     677      4408660 :                       input         en,
     678      1345612 :                       input [31:0]  din,
     679      1473932 :                       input [6:0]   ecc_in,
     680          596 :                       input         sed_ded,    // only do detection and no correction. Used for the I$
     681      1345612 :                       output [31:0] dout,
     682      1473932 :                       output [6:0]  ecc_out,
     683           20 :                       output        single_ecc_error,
     684            8 :                       output        double_ecc_error
     685              : 
     686              :                       );
     687              : 
     688         2240 :    logic [6:0]                      ecc_check;
     689         2150 :    logic [38:0]                     error_mask;
     690      2981320 :    logic [38:0]                     din_plus_parity, dout_plus_parity;
     691              : 
     692              :    // Generate the ecc bits
     693              :    assign ecc_check[0] = ecc_in[0]^din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30];
     694              :    assign ecc_check[1] = ecc_in[1]^din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31];
     695              :    assign ecc_check[2] = ecc_in[2]^din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31];
     696              :    assign ecc_check[3] = ecc_in[3]^din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25];
     697              :    assign ecc_check[4] = ecc_in[4]^din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25];
     698              :    assign ecc_check[5] = ecc_in[5]^din[26]^din[27]^din[28]^din[29]^din[30]^din[31];
     699              : 
     700              :    // This is the parity bit
     701              :    assign ecc_check[6] = ((^din[31:0])^(^ecc_in[6:0])) & ~sed_ded;
     702              : 
     703              :    assign single_ecc_error = en & (ecc_check[6:0] != 0) & ecc_check[6];   // this will never be on for sed_ded
     704              :    assign double_ecc_error = en & (ecc_check[6:0] != 0) & ~ecc_check[6];  // all errors in the sed_ded case will be recorded as DE
     705              : 
     706              :    // Generate the mask for error correctiong
     707              :    for (genvar i=1; i<40; i++) begin
     708              :       assign error_mask[i-1] = (ecc_check[5:0] == i);
     709              :    end
     710              : 
     711              :    // Generate the corrected data
     712              :    assign din_plus_parity[38:0] = {ecc_in[6], din[31:26], ecc_in[5], din[25:11], ecc_in[4], din[10:4], ecc_in[3], din[3:1], ecc_in[2], din[0], ecc_in[1:0]};
     713              : 
     714              :    assign dout_plus_parity[38:0] = single_ecc_error ? (error_mask[38:0] ^ din_plus_parity[38:0]) : din_plus_parity[38:0];
     715              :    assign dout[31:0]             = {dout_plus_parity[37:32], dout_plus_parity[30:16], dout_plus_parity[14:8], dout_plus_parity[6:4], dout_plus_parity[2]};
     716              :    assign ecc_out[6:0]           = {(dout_plus_parity[38] ^ (ecc_check[6:0] == 7'b1000000)), dout_plus_parity[31], dout_plus_parity[15], dout_plus_parity[7], dout_plus_parity[3], dout_plus_parity[1:0]};
     717              : 
     718              : endmodule // rvecc_decode
     719              : 
     720              : module rvecc_encode_64  (
     721     11278398 :                       input [63:0] din,
     722     11881471 :                       output [6:0] ecc_out
     723              :                       );
     724              :   assign ecc_out[0] = din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]^din[32]^din[34]^din[36]^din[38]^din[40]^din[42]^din[44]^din[46]^din[48]^din[50]^din[52]^din[54]^din[56]^din[57]^din[59]^din[61]^din[63];
     725              : 
     726              :    assign ecc_out[1] = din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31]^din[32]^din[35]^din[36]^din[39]^din[40]^din[43]^din[44]^din[47]^din[48]^din[51]^din[52]^din[55]^din[56]^din[58]^din[59]^din[62]^din[63];
     727              : 
     728              :    assign ecc_out[2] = din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31]^din[32]^din[37]^din[38]^din[39]^din[40]^din[45]^din[46]^din[47]^din[48]^din[53]^din[54]^din[55]^din[56]^din[60]^din[61]^din[62]^din[63];
     729              : 
     730              :    assign ecc_out[3] = din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]^din[33]^din[34]^din[35]^din[36]^din[37]^din[38]^din[39]^din[40]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56];
     731              : 
     732              :    assign ecc_out[4] = din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]^din[41]^din[42]^din[43]^din[44]^din[45]^din[46]^din[47]^din[48]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56];
     733              : 
     734              :    assign ecc_out[5] = din[26]^din[27]^din[28]^din[29]^din[30]^din[31]^din[32]^din[33]^din[34]^din[35]^din[36]^din[37]^din[38]^din[39]^din[40]^din[41]^din[42]^din[43]^din[44]^din[45]^din[46]^din[47]^din[48]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56];
     735              : 
     736              :    assign ecc_out[6] = din[57]^din[58]^din[59]^din[60]^din[61]^din[62]^din[63];
     737              : 
     738              : endmodule // rvecc_encode_64
     739              : 
     740              : 
     741              : module rvecc_decode_64  (
     742      1602122 :                       input         en,
     743      1626771 :                       input [63:0]  din,
     744      1626394 :                       input [6:0]   ecc_in,
     745           10 :                       output        ecc_error
     746              :                       );
     747              : 
     748           28 :    logic [6:0]                      ecc_check;
     749              : 
     750              :    // Generate the ecc bits
     751              :    assign ecc_check[0] = ecc_in[0]^din[0]^din[1]^din[3]^din[4]^din[6]^din[8]^din[10]^din[11]^din[13]^din[15]^din[17]^din[19]^din[21]^din[23]^din[25]^din[26]^din[28]^din[30]^din[32]^din[34]^din[36]^din[38]^din[40]^din[42]^din[44]^din[46]^din[48]^din[50]^din[52]^din[54]^din[56]^din[57]^din[59]^din[61]^din[63];
     752              : 
     753              :    assign ecc_check[1] = ecc_in[1]^din[0]^din[2]^din[3]^din[5]^din[6]^din[9]^din[10]^din[12]^din[13]^din[16]^din[17]^din[20]^din[21]^din[24]^din[25]^din[27]^din[28]^din[31]^din[32]^din[35]^din[36]^din[39]^din[40]^din[43]^din[44]^din[47]^din[48]^din[51]^din[52]^din[55]^din[56]^din[58]^din[59]^din[62]^din[63];
     754              : 
     755              :    assign ecc_check[2] = ecc_in[2]^din[1]^din[2]^din[3]^din[7]^din[8]^din[9]^din[10]^din[14]^din[15]^din[16]^din[17]^din[22]^din[23]^din[24]^din[25]^din[29]^din[30]^din[31]^din[32]^din[37]^din[38]^din[39]^din[40]^din[45]^din[46]^din[47]^din[48]^din[53]^din[54]^din[55]^din[56]^din[60]^din[61]^din[62]^din[63];
     756              : 
     757              :    assign ecc_check[3] = ecc_in[3]^din[4]^din[5]^din[6]^din[7]^din[8]^din[9]^din[10]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]^din[33]^din[34]^din[35]^din[36]^din[37]^din[38]^din[39]^din[40]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56];
     758              : 
     759              :    assign ecc_check[4] = ecc_in[4]^din[11]^din[12]^din[13]^din[14]^din[15]^din[16]^din[17]^din[18]^din[19]^din[20]^din[21]^din[22]^din[23]^din[24]^din[25]^din[41]^din[42]^din[43]^din[44]^din[45]^din[46]^din[47]^din[48]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56];
     760              : 
     761              :    assign ecc_check[5] = ecc_in[5]^din[26]^din[27]^din[28]^din[29]^din[30]^din[31]^din[32]^din[33]^din[34]^din[35]^din[36]^din[37]^din[38]^din[39]^din[40]^din[41]^din[42]^din[43]^din[44]^din[45]^din[46]^din[47]^din[48]^din[49]^din[50]^din[51]^din[52]^din[53]^din[54]^din[55]^din[56];
     762              : 
     763              :    assign ecc_check[6] = ecc_in[6]^din[57]^din[58]^din[59]^din[60]^din[61]^din[62]^din[63];
     764              : 
     765              :    assign ecc_error = en & (ecc_check[6:0] != 0);  // all errors in the sed_ded case will be recorded as DE
     766              : 
     767              :  endmodule // rvecc_decode_64
     768              : 
     769              : `ifndef TECH_SPECIFIC_EC_RV_ICG
     770              : module `TEC_RV_ICG
     771              :   (
     772      2148771 :    input logic SE, EN, CK,
     773      1019989 :    output Q
     774              :    );
     775              : 
     776        98129 :    logic  en_ff;
     777       101147 :    logic  enable;
     778              : 
     779              :    assign      enable = EN | SE;
     780              : 
     781      2250128 :    always @(CK, enable) begin
     782      1175574 :       if(!CK)
     783      1074555 :         en_ff = enable;
     784              :    end
     785              :    assign Q = CK & en_ff;
     786              : 
     787              : endmodule
     788              : `endif
     789              : 
     790              : `ifndef RV_FPGA_OPTIMIZE
     791              : module rvclkhdr
     792              :   (
     793        18437 :    input  logic en,
     794      1552222 :    input  logic clk,
     795              :    // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     796              :    /*pragma coverage off*/
     797              :    input  logic scan_mode,
     798              :    /*pragma coverage on*/
     799       899391 :    output logic l1clk
     800              :    );
     801              : 
     802            0 :    logic   SE;
     803              :    assign       SE = 0;
     804              : 
     805              : `ifdef TECH_SPECIFIC_EC_RV_ICG
     806              :    `USER_EC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
     807              : `else
     808              :    `TEC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
     809              : `endif
     810              : 
     811              : endmodule // rvclkhdr
     812              : `endif
     813              : 
     814              : module rvoclkhdr
     815              :   (
     816     37094524 :    input  logic en,
     817   3129488309 :    input  logic clk,
     818              :    // Excluding scan_mode from coverage as its usage is determined by the integrator of the VeeR core.
     819              :    /*pragma coverage off*/
     820              :    input  logic scan_mode,
     821              :    /*pragma coverage on*/
     822   3129012358 :    output logic l1clk
     823              :    );
     824              : 
     825            0 :    logic   SE;
     826              :    assign       SE = 0;
     827              : 
     828              : `ifdef RV_FPGA_OPTIMIZE
     829              :    assign l1clk = clk;
     830              : `else
     831              :    `ifdef TECH_SPECIFIC_EC_RV_ICG
     832              :       `USER_EC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
     833              :    `else
     834              :       `TEC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
     835              :     `endif
     836              : `endif
     837              : 
     838              : endmodule
     839              : 
     840              : 
     841              :