Project Full coverage report
Current view: Cores-VeeR-EL2—Cores-VeeR-EL2—design—lib—beh_lib.sv Coverage Hit Total
Test Date: 19-09-2024 Toggle 86.3% 132 153
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          742 :      input logic [WIDTH-1:0] din,
      22     59264685 :      input logic           clk,
      23          542 :      input logic                   rst_l,
      24              : 
      25          745 :      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     24308894 :    always_ff @(posedge clk or negedge rst_l) begin
      39         3466 :       if (rst_l == 0)
      40         1740 :         dout[WIDTH-1:0] <= 0;
      41              :       else
      42     24308533 :         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        87916 :      input logic [WIDTH-1:0] din,
      52        14508 :      input logic             en,
      53     59635290 :      input logic           clk,
      54          609 :      input logic                   rst_l,
      55          834 :      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       778501 :      input logic [WIDTH-1:0] din,
      71       343374 :      input logic             en,
      72       343558 :      input logic             clear,
      73    247548826 :      input logic           clk,
      74         1401 :      input logic                   rst_l,
      75       295188 :      output logic [WIDTH-1:0] dout
      76              :      );
      77              : 
      78       295188 :    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      3729097 :      input logic [WIDTH-1:0] din,
      92      9473980 :      input logic           clk,
      93         1360 :      input logic           clken,
      94    106036643 :      input logic           rawclk,
      95         1171 :      input logic           rst_l,
      96              : 
      97      3729026 :      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          326 :      input logic [WIDTH-1:0] din,
     116         2374 :      input logic             en,
     117        57008 :      input logic           clk,
     118          662 :      input logic           clken,
     119    124009391 :      input logic           rawclk,
     120          691 :      input logic           rst_l,
     121              : 
     122           31 :      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         1221 :      input logic [WIDTH-1:0] din,
     142      3543250 :      input logic             en,
     143         3024 :      input logic             clear,
     144      3411859 :      input logic             clk,
     145          977 :      input logic             clken,
     146    158721159 :      input logic             rawclk,
     147         1037 :      input logic             rst_l,
     148              : 
     149       177398 :      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      3121522 :      input  logic [WIDTH-1:0] din,
     169       347562 :      input  logic           en,
     170     59466018 :      input  logic           clk,
     171          534 :      input  logic           rst_l,
     172            0 :      input  logic             scan_mode,
     173         6731 :      output logic [WIDTH-1:0] dout
     174              :      );
     175              : 
     176        10084 :    logic                      l1clk;
     177              : 
     178              : if (SHORT == 1) begin : genblock
     179              :    if (1) begin : genblock
     180              :       assign dout = din;
     181              :    end
     182              : end
     183              : else begin : genblock
     184              : 
     185              : `ifndef RV_PHYSICAL
     186              :    if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
     187              : `endif
     188              : 
     189              : `ifdef RV_FPGA_OPTIMIZE
     190              :       rvdffs #(WIDTH) dff ( .* );
     191              : `else
     192              :       rvclkhdr clkhdr ( .* );
     193              :       rvdff #(WIDTH) dff (.*, .clk(l1clk));
     194              : `endif
     195              : 
     196              : `ifndef RV_PHYSICAL
     197              :    end
     198              :    else
     199              :       $error("%m: rvdffe must be WIDTH >= 8");
     200              : `endif
     201              : end // else: !if(SHORT == 1)
     202              : 
     203              : endmodule // rvdffe
     204              : 
     205              : 
     206              : module rvdffpcie #( parameter WIDTH=31 )
     207              :    (
     208       140094 :      input  logic [WIDTH-1:0] din,
     209    580374798 :      input  logic             clk,
     210         3840 :      input  logic             rst_l,
     211     47050225 :      input  logic             en,
     212            0 :      input  logic             scan_mode,
     213       139867 :      output logic [WIDTH-1:0] dout
     214              :      );
     215              : 
     216              : 
     217              : 
     218              : `ifndef RV_PHYSICAL
     219              :    if (WIDTH == 31) begin: genblock
     220              : `endif
     221              : 
     222              : `ifdef RV_FPGA_OPTIMIZE
     223              :       rvdffs #(WIDTH) dff ( .* );
     224              : `else
     225              : 
     226              :       rvdfflie #(.WIDTH(WIDTH), .LEFT(19)) dff (.*);
     227              : 
     228              : `endif
     229              : 
     230              : `ifndef RV_PHYSICAL
     231              :    end
     232              :    else
     233              :       $error("%m: rvdffpcie width must be 31");
     234              : `endif
     235              : endmodule
     236              : 
     237              : // format: { LEFT, EXTRA }
     238              : // LEFT # of bits will be done with rvdffie, all else EXTRA with rvdffe
     239              : module rvdfflie #( parameter WIDTH=16, LEFT=8 )
     240              :    (
     241          300 :      input  logic [WIDTH-1:0] din,
     242     59176340 :      input  logic             clk,
     243          364 :      input  logic             rst_l,
     244          322 :      input  logic             en,
     245            0 :      input  logic             scan_mode,
     246          299 :      output logic [WIDTH-1:0] dout
     247              :      );
     248              : 
     249              :    localparam EXTRA = WIDTH-LEFT;
     250              : 
     251              : 
     252              : 
     253              : 
     254              : 
     255              : 
     256              : 
     257              :    localparam LMSB = WIDTH-1;
     258              :    localparam LLSB = LMSB-LEFT+1;
     259              :    localparam XMSB = LLSB-1;
     260              :    localparam XLSB = LLSB-EXTRA;
     261              : 
     262              : 
     263              : `ifndef RV_PHYSICAL
     264              :    if (WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8) begin: genblock
     265              : `endif
     266              : 
     267              : `ifdef RV_FPGA_OPTIMIZE
     268              :       rvdffs #(WIDTH) dff ( .* );
     269              : `else
     270              : 
     271              :       rvdffiee #(LEFT)  dff_left  (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
     272              : 
     273              : 
     274              :       rvdffe  #(EXTRA)  dff_extra (.*, .din(din[XMSB:XLSB]), .dout(dout[XMSB:XLSB]));
     275              : 
     276              : 
     277              : 
     278              : 
     279              : `endif
     280              : 
     281              : `ifndef RV_PHYSICAL
     282              :    end
     283              :    else
     284              :       $error("%m: rvdfflie musb be WIDTH >= 16 && LEFT >= 8 && EXTRA >= 8");
     285              : `endif
     286              : endmodule
     287              : 
     288              : 
     289              : 
     290              : 
     291              : // special power flop for predict packet
     292              : // format: { LEFT, RIGHT==31 }
     293              : // LEFT # of bits will be done with rvdffe; RIGHT is enabled by LEFT[LSB] & en
     294              : module rvdffppe #( parameter integer WIDTH = 39 )
     295              :    (
     296       219944 :      input  logic [WIDTH-1:0] din,
     297     61843746 :      input  logic             clk,
     298          316 :      input  logic             rst_l,
     299      5991939 :      input  logic             en,
     300            0 :      input  logic             scan_mode,
     301       219944 :      output logic [WIDTH-1:0] dout
     302              :      );
     303              : 
     304              :    localparam integer RIGHT = 31;
     305              :    localparam integer LEFT  = WIDTH - RIGHT;
     306              : 
     307              :    localparam integer LMSB  = WIDTH-1;
     308              :    localparam integer LLSB  = LMSB-LEFT+1;
     309              :    localparam integer RMSB  = LLSB-1;
     310              :    localparam integer RLSB  = LLSB-RIGHT;
     311              : 
     312              : 
     313              : `ifndef RV_PHYSICAL
     314              :    if (WIDTH>=32 && LEFT>=8 && RIGHT>=8) begin: genblock
     315              : `endif
     316              : 
     317              : `ifdef RV_FPGA_OPTIMIZE
     318              :       rvdffs #(WIDTH) dff ( .* );
     319              : `else
     320              :       rvdffe #(LEFT)     dff_left (.*, .din(din[LMSB:LLSB]), .dout(dout[LMSB:LLSB]));
     321              : 
     322              :       rvdffe #(RIGHT)   dff_right (.*, .din(din[RMSB:RLSB]), .dout(dout[RMSB:RLSB]), .en(en & din[LLSB]));  // qualify with pret
     323              : 
     324              : 
     325              : `endif
     326              : 
     327              : `ifndef RV_PHYSICAL
     328              :    end
     329              :    else
     330              :       $error("%m: must be WIDTH>=32 && LEFT>=8 && RIGHT>=8");
     331              : `endif
     332              : endmodule
     333              : 
     334              : 
     335              : 
     336              : 
     337              : module rvdffie #( parameter WIDTH=1, OVERRIDE=0 )
     338              :    (
     339       149724 :      input  logic [WIDTH-1:0] din,
     340              : 
     341     61843746 :      input  logic           clk,
     342          316 :      input  logic           rst_l,
     343            0 :      input  logic             scan_mode,
     344       149724 :      output logic [WIDTH-1:0] dout
     345              :      );
     346              : 
     347            0 :    logic                      l1clk;
     348        78293 :    logic                      en;
     349              : 
     350              : 
     351              : 
     352              : 
     353              : 
     354              : 
     355              : 
     356              : 
     357              : `ifndef RV_PHYSICAL
     358              :    if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
     359              : `endif
     360              : 
     361              :       assign en = |(din ^ dout);
     362              : 
     363              : `ifdef RV_FPGA_OPTIMIZE
     364              :       rvdffs #(WIDTH) dff ( .* );
     365              : `else
     366              :       rvclkhdr clkhdr ( .* );
     367              :       rvdff #(WIDTH) dff (.*, .clk(l1clk));
     368              : `endif
     369              : 
     370              : `ifndef RV_PHYSICAL
     371              :    end
     372              :    else
     373              :      $error("%m: rvdffie must be WIDTH >= 8");
     374              : `endif
     375              : 
     376              : 
     377              : endmodule
     378              : 
     379              : // ie flop but it has an .en input
     380              : module rvdffiee #( parameter WIDTH=1, OVERRIDE=0 )
     381              :    (
     382            0 :      input  logic [WIDTH-1:0] din,
     383              : 
     384         6150 :      input  logic           clk,
     385           48 :      input  logic           rst_l,
     386            0 :      input  logic           scan_mode,
     387            6 :      input  logic           en,
     388            0 :      output logic [WIDTH-1:0] dout
     389              :      );
     390              : 
     391            0 :    logic                      l1clk;
     392            0 :    logic                      final_en;
     393              : 
     394              : `ifndef RV_PHYSICAL
     395              :    if (WIDTH >= 8 || OVERRIDE==1) begin: genblock
     396              : `endif
     397              : 
     398              :       assign final_en = (|(din ^ dout)) & en;
     399              : 
     400              : `ifdef RV_FPGA_OPTIMIZE
     401              :       rvdffs #(WIDTH) dff ( .*, .en(final_en) );
     402              : `else
     403              :       rvdffe #(WIDTH) dff (.*,  .en(final_en));
     404              : `endif
     405              : 
     406              : `ifndef RV_PHYSICAL
     407              :    end
     408              :    else
     409              :       $error("%m: rvdffie width must be >= 8");
     410              : `endif
     411              : 
     412              : endmodule
     413              : 
     414              : 
     415              : 
     416              : module rvsyncss #(parameter WIDTH = 251)
     417              :    (
     418     61843746 :      input  logic                 clk,
     419          316 :      input  logic                 rst_l,
     420           17 :      input  logic [WIDTH-1:0]     din,
     421           12 :      output logic [WIDTH-1:0]     dout
     422              :      );
     423              : 
     424           12 :    logic [WIDTH-1:0]              din_ff1;
     425              : 
     426              :    rvdff #(WIDTH) sync_ff1  (.*, .din (din[WIDTH-1:0]),     .dout(din_ff1[WIDTH-1:0]));
     427              :    rvdff #(WIDTH) sync_ff2  (.*, .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
     428              : 
     429              : endmodule // rvsyncss
     430              : 
     431              : module rvsyncss_fpga #(parameter WIDTH = 251)
     432              :    (
     433      3127890 :      input  logic                 gw_clk,
     434   1502440592 :      input  logic                 rawclk,
     435        10063 :      input  logic                 clken,
     436         9960 :      input  logic                 rst_l,
     437         3421 :      input  logic [WIDTH-1:0]     din,
     438         3420 :      output logic [WIDTH-1:0]     dout
     439              :      );
     440              : 
     441         3420 :    logic [WIDTH-1:0]              din_ff1;
     442              : 
     443              :    rvdff_fpga #(WIDTH) sync_ff1  (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din[WIDTH-1:0]),     .dout(din_ff1[WIDTH-1:0]));
     444              :    rvdff_fpga #(WIDTH) sync_ff2  (.*, .clk(gw_clk), .rawclk(rawclk), .clken(clken), .din (din_ff1[WIDTH-1:0]), .dout(dout[WIDTH-1:0]));
     445              : 
     446              : endmodule // rvsyncss
     447              : 
     448              : module rvlsadder
     449              :   (
     450       476238 :     input logic [31:0] rs1,
     451       270136 :     input logic [11:0] offset,
     452              : 
     453       594111 :     output logic [31:0] dout
     454              :     );
     455              : 
     456       281606 :    logic                cout;
     457       368726 :    logic                sign;
     458              : 
     459      1464889 :    logic [31:12]        rs1_inc;
     460        17884 :    logic [31:12]        rs1_dec;
     461              : 
     462              :    assign {cout,dout[11:0]} = {1'b0,rs1[11:0]} + {1'b0,offset[11:0]};
     463              : 
     464              :    assign rs1_inc[31:12] = rs1[31:12] + 1;
     465              : 
     466              :    assign rs1_dec[31:12] = rs1[31:12] - 1;
     467              : 
     468              :    assign sign = offset[11];
     469              : 
     470              :    assign dout[31:12] = ({20{  sign ^~  cout}} &     rs1[31:12]) |
     471              :                         ({20{ ~sign &   cout}}  & rs1_inc[31:12]) |
     472              :                         ({20{  sign &  ~cout}}  & rs1_dec[31:12]);
     473              : 
     474              : endmodule // rvlsadder
     475              : 
     476              : // assume we only maintain pc[31:1] in the pipe
     477              : 
     478              : module rvbradder
     479              :   (
     480         2210 :     input [31:1] pc,
     481      3642214 :     input [12:1] offset,
     482              : 
     483       139780 :     output [31:1] dout
     484              :     );
     485              : 
     486      4180298 :    logic          cout;
     487      3834276 :    logic          sign;
     488              : 
     489         2280 :    logic [31:13]  pc_inc;
     490       106032 :    logic [31:13]  pc_dec;
     491              : 
     492              :    assign {cout,dout[12:1]} = {1'b0,pc[12:1]} + {1'b0,offset[12:1]};
     493              : 
     494              :    assign pc_inc[31:13] = pc[31:13] + 1;
     495              : 
     496              :    assign pc_dec[31:13] = pc[31:13] - 1;
     497              : 
     498              :    assign sign = offset[12];
     499              : 
     500              : 
     501              :    assign dout[31:13] = ({19{  sign ^~  cout}} &     pc[31:13]) |
     502              :                         ({19{ ~sign &   cout}}  & pc_inc[31:13]) |
     503              :                         ({19{  sign &  ~cout}}  & pc_dec[31:13]);
     504              : 
     505              : 
     506              : endmodule // rvbradder
     507              : 
     508              : 
     509              : // 2s complement circuit
     510              : module rvtwoscomp #( parameter WIDTH=32 )
     511              :    (
     512        16813 :      input logic [WIDTH-1:0] din,
     513              : 
     514        26587 :      output logic [WIDTH-1:0] dout
     515              :      );
     516              : 
     517        27432 :    logic [WIDTH-1:1]          dout_temp;   // holding for all other bits except for the lsb. LSB is always din
     518              : 
     519              :    genvar                     i;
     520              : 
     521              :    for ( i = 1; i < WIDTH; i++ )  begin : flip_after_first_one
     522              :       assign dout_temp[i] = (|din[i-1:0]) ? ~din[i] : din[i];
     523              :    end : flip_after_first_one
     524              : 
     525              :    assign dout[WIDTH-1:0]  = { dout_temp[WIDTH-1:1], din[0] };
     526              : 
     527              : endmodule  // 2'scomp
     528              : 
     529              : // find first
     530              : module rvfindfirst1 #( parameter WIDTH=32, SHIFT=$clog2(WIDTH) )
     531              :    (
     532              :      input logic [WIDTH-1:0] din,
     533              : 
     534              :      output logic [SHIFT-1:0] dout
     535              :      );
     536              :    logic                      done;
     537              : 
     538              :    always_comb begin
     539              :       dout[SHIFT-1:0] = {SHIFT{1'b0}};
     540              :       done    = 1'b0;
     541              : 
     542              :       for ( int i = WIDTH-1; i > 0; i-- )  begin : find_first_one
     543              :          done |= din[i];
     544              :          dout[SHIFT-1:0] += done ? 1'b0 : 1'b1;
     545              :       end : find_first_one
     546              :    end
     547              : endmodule // rvfindfirst1
     548              : 
     549              : module rvfindfirst1hot #( parameter WIDTH=32 )
     550              :    (
     551              :      input logic [WIDTH-1:0] din,
     552              : 
     553              :      output logic [WIDTH-1:0] dout
     554              :      );
     555              :    logic                      done;
     556              : 
     557              :    always_comb begin
     558              :       dout[WIDTH-1:0] = {WIDTH{1'b0}};
     559              :       done    = 1'b0;
     560              :       for ( int i = 0; i < WIDTH; i++ )  begin : find_first_one
     561              :          dout[i] = ~done & din[i];
     562              :          done   |= din[i];
     563              :       end : find_first_one
     564              :    end
     565              : endmodule // rvfindfirst1hot
     566              : 
     567              : // mask and match function matches bits after finding the first 0 position
     568              : // find first starting from LSB. Skip that location and match the rest of the bits
     569              : module rvmaskandmatch #( parameter WIDTH=32 )
     570              :    (
     571         3586 :      input  logic [WIDTH-1:0] mask,     // this will have the mask in the lower bit positions
     572        11552 :      input  logic [WIDTH-1:0] data,     // this is what needs to be matched on the upper bits with the mask's upper bits
     573         1258 :      input  logic             masken,   // when 1 : do mask. 0 : full match
     574        22538 :      output logic             match
     575              :      );
     576              : 
     577         2544 :    logic [WIDTH-1:0]          matchvec;
     578         1258 :    logic                      masken_or_fullmask;
     579              : 
     580              :    assign masken_or_fullmask = masken &  ~(&mask[WIDTH-1:0]);
     581              : 
     582              :    assign matchvec[0]        = masken_or_fullmask | (mask[0] == data[0]);
     583              :    genvar                     i;
     584              : 
     585              :    for ( i = 1; i < WIDTH; i++ )  begin : match_after_first_zero
     586              :       assign matchvec[i] = (&mask[i-1:0] & masken_or_fullmask) ? 1'b1 : (mask[i] == data[i]);
     587              :    end : match_after_first_zero
     588              : 
     589              :    assign match  = &matchvec[WIDTH-1:0];    // all bits either matched or were masked off
     590              : 
     591              : endmodule // rvmaskandmatch
     592              : 
     593              : 
     594              : 
     595              : 
     596              : // Check if the S_ADDR <= addr < E_ADDR
     597              : module rvrangecheck  #(CCM_SADR = 32'h0,
     598              :                        CCM_SIZE  = 128) (
     599      1188555 :    input  logic [31:0]   addr,                             // Address to be checked for range
     600            0 :    output logic          in_range,                            // S_ADDR <= start_addr < E_ADDR
     601       828482 :    output logic          in_region
     602              : );
     603              : 
     604              :    localparam REGION_BITS = 4;
     605              :    localparam MASK_BITS = 10 + $clog2(CCM_SIZE);
     606              : 
     607            0 :    logic [31:0]          start_addr;
     608          662 :    logic [3:0]           region;
     609              : 
     610              :    assign start_addr[31:0]        = CCM_SADR;
     611              :    assign region[REGION_BITS-1:0] = start_addr[31:(32-REGION_BITS)];
     612              : 
     613              :    assign in_region = (addr[31:(32-REGION_BITS)] == region[REGION_BITS-1:0]);
     614              :    if (CCM_SIZE  == 48)
     615              :     assign in_range  = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]) & ~(&addr[MASK_BITS-1 : MASK_BITS-2]);
     616              :    else
     617              :     assign in_range  = (addr[31:MASK_BITS] == start_addr[31:MASK_BITS]);
     618              : 
     619              : endmodule  // rvrangechecker
     620              : 
     621              : // 16 bit even parity generator
     622              : module rveven_paritygen #(WIDTH = 16)  (
     623              :                                          input  logic [WIDTH-1:0]  data_in,         // Data
     624              :                                          output logic              parity_out       // generated even parity
     625              :                                          );
     626              : 
     627              :    assign  parity_out =  ^(data_in[WIDTH-1:0]) ;
     628              : 
     629              : endmodule  // rveven_paritygen
     630              : 
     631              : module rveven_paritycheck #(WIDTH = 16)  (
     632              :                                            input  logic [WIDTH-1:0]  data_in,         // Data
     633              :                                            input  logic              parity_in,
     634              :                                            output logic              parity_err       // Parity error
     635              :                                            );
     636              : 
     637              :    assign  parity_err =  ^(data_in[WIDTH-1:0]) ^ parity_in ;
     638              : 
     639              : endmodule  // rveven_paritycheck
     640              : 
     641              : module rvecc_encode  (
     642         7578 :                       input [31:0] din,
     643        67266 :                       output [6:0] ecc_out
     644              :                       );
     645        50887 : logic [5:0] ecc_out_temp;
     646              : 
     647              :    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];
     648              :    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];
     649              :    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];
     650              :    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];
     651              :    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];
     652              :    assign ecc_out_temp[5] = din[26]^din[27]^din[28]^din[29]^din[30]^din[31];
     653              : 
     654              :    assign ecc_out[6:0] = {(^din[31:0])^(^ecc_out_temp[5:0]),ecc_out_temp[5:0]};
     655              : 
     656              : endmodule // rvecc_encode
     657              : 
     658              : module rvecc_decode  (
     659      2127952 :                       input         en,
     660       505562 :                       input [31:0]  din,
     661       839208 :                       input [6:0]   ecc_in,
     662          634 :                       input         sed_ded,    // only do detection and no correction. Used for the I$
     663       505562 :                       output [31:0] dout,
     664       839208 :                       output [6:0]  ecc_out,
     665           12 :                       output        single_ecc_error,
     666            8 :                       output        double_ecc_error
     667              : 
     668              :                       );
     669              : 
     670         1140 :    logic [6:0]                      ecc_check;
     671            0 :    logic [38:0]                     error_mask;
     672      1009341 :    logic [38:0]                     din_plus_parity, dout_plus_parity;
     673              : 
     674              :    // Generate the ecc bits
     675              :    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];
     676              :    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];
     677              :    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];
     678              :    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];
     679              :    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];
     680              :    assign ecc_check[5] = ecc_in[5]^din[26]^din[27]^din[28]^din[29]^din[30]^din[31];
     681              : 
     682              :    // This is the parity bit
     683              :    assign ecc_check[6] = ((^din[31:0])^(^ecc_in[6:0])) & ~sed_ded;
     684              : 
     685              :    assign single_ecc_error = en & (ecc_check[6:0] != 0) & ecc_check[6];   // this will never be on for sed_ded
     686              :    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
     687              : 
     688              :    // Generate the mask for error correctiong
     689              :    for (genvar i=1; i<40; i++) begin
     690              :       assign error_mask[i-1] = (ecc_check[5:0] == i);
     691              :    end
     692              : 
     693              :    // Generate the corrected data
     694              :    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]};
     695              : 
     696              :    assign dout_plus_parity[38:0] = single_ecc_error ? (error_mask[38:0] ^ din_plus_parity[38:0]) : din_plus_parity[38:0];
     697              :    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]};
     698              :    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]};
     699              : 
     700              : endmodule // rvecc_decode
     701              : 
     702              : module rvecc_encode_64  (
     703      2037611 :                       input [63:0] din,
     704      4245520 :                       output [6:0] ecc_out
     705              :                       );
     706              :   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];
     707              : 
     708              :    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];
     709              : 
     710              :    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];
     711              : 
     712              :    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];
     713              : 
     714              :    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];
     715              : 
     716              :    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];
     717              : 
     718              :    assign ecc_out[6] = din[57]^din[58]^din[59]^din[60]^din[61]^din[62]^din[63];
     719              : 
     720              : endmodule // rvecc_encode_64
     721              : 
     722              : 
     723              : module rvecc_decode_64  (
     724      2629384 :                       input         en,
     725       446297 :                       input [63:0]  din,
     726      1164725 :                       input [6:0]   ecc_in,
     727            0 :                       output        ecc_error
     728              :                       );
     729              : 
     730            0 :    logic [6:0]                      ecc_check;
     731              : 
     732              :    // Generate the ecc bits
     733              :    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];
     734              : 
     735              :    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];
     736              : 
     737              :    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];
     738              : 
     739              :    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];
     740              : 
     741              :    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];
     742              : 
     743              :    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];
     744              : 
     745              :    assign ecc_check[6] = ecc_in[6]^din[57]^din[58]^din[59]^din[60]^din[61]^din[62]^din[63];
     746              : 
     747              :    assign ecc_error = en & (ecc_check[6:0] != 0);  // all errors in the sed_ded case will be recorded as DE
     748              : 
     749              :  endmodule // rvecc_decode_64
     750              : 
     751              : `ifndef TECH_SPECIFIC_EC_RV_ICG
     752              : module `TEC_RV_ICG
     753              :   (
     754       101426 :    input logic SE, EN, CK,
     755      1021173 :    output Q
     756              :    );
     757              : 
     758        98075 :    logic  en_ff;
     759       101075 :    logic  enable;
     760              : 
     761              :    assign      enable = EN | SE;
     762              : 
     763          250 :    always @(CK, enable) begin
     764      2158198 :       if(!CK)
     765      2158263 :         en_ff = enable;
     766              :    end
     767              :    assign Q = CK & en_ff;
     768              : 
     769              : endmodule
     770              : `endif
     771              : 
     772              : `ifndef RV_FPGA_OPTIMIZE
     773              : module rvclkhdr
     774              :   (
     775        18367 :    input  logic en,
     776      1559117 :    input  logic clk,
     777            0 :    input  logic scan_mode,
     778       900039 :    output logic l1clk
     779              :    );
     780              : 
     781            0 :    logic   SE;
     782              :    assign       SE = 0;
     783              : 
     784              : `ifdef TECH_SPECIFIC_EC_RV_ICG
     785              :    `USER_EC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
     786              : `else
     787              :    `TEC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
     788              : `endif
     789              : 
     790              : endmodule // rvclkhdr
     791              : `endif
     792              : 
     793              : module rvoclkhdr
     794              :   (
     795     26675376 :    input  logic en,
     796   1670378587 :    input  logic clk,
     797            0 :    input  logic scan_mode,
     798   1669902276 :    output logic l1clk
     799              :    );
     800              : 
     801            0 :    logic   SE;
     802              :    assign       SE = 0;
     803              : 
     804              : `ifdef RV_FPGA_OPTIMIZE
     805              :    assign l1clk = clk;
     806              : `else
     807              :    `ifdef TECH_SPECIFIC_EC_RV_ICG
     808              :       `USER_EC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
     809              :    `else
     810              :       `TEC_RV_ICG clkhdr ( .*, .EN(en), .CK(clk), .Q(l1clk));
     811              :     `endif
     812              : `endif
     813              : 
     814              : endmodule
     815              : 
     816              : 
     817              :