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 :
|