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