Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / spc / tlu / rtl / tlu_cxi_ctl.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: tlu_cxi_ctl.v
4// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
5// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
6//
7// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8//
9// This program is free software; you can redistribute it and/or modify
10// it under the terms of the GNU General Public License as published by
11// the Free Software Foundation; version 2 of the License.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17//
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21//
22// For the avoidance of doubt, and except that if any non-GPL license
23// choice is available it will apply instead, Sun elects to use only
24// the General Public License version 2 (GPLv2) at this time for any
25// software where a choice of GPL license versions is made
26// available with the language indicating that GPLv2 or any later version
27// may be used, or where a choice of which version of the GPL is applied is
28// otherwise unspecified.
29//
30// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31// CA 95054 USA or visit www.sun.com if you need additional information or
32// have any questions.
33//
34// ========== Copyright Header End ============================================
35module tlu_cxi_ctl (
36 l2clk,
37 scan_in,
38 tcu_pce_ov,
39 spc_aclk,
40 spc_bclk,
41 tcu_scan_en,
42 fls_core_running,
43 fls_ss_request,
44 lsu_cpx_req,
45 lsu_cpx_err,
46 lsu_cpx_sre,
47 lsu_cpx_err_thread_id,
48 lsu_cpx_thread_id,
49 lsu_cpx_valid,
50 lsu_cpx_type,
51 lsu_cpx_vector,
52 lsu_cpx_prefetch,
53 lsu_ext_interrupt,
54 lsu_ext_int_type,
55 lsu_ext_int_vec,
56 lsu_ext_int_tid,
57 trl_ss_complete,
58 asi_irl_cleared,
59 cth_irl_cleared,
60 tlu_cerer_l2c_socc,
61 tlu_cerer_l2u_socu,
62 tlu_cerer_l2nd,
63 scan_out,
64 cxi_xir,
65 cxi_ivt,
66 cxi_wr_int_dis,
67 cxi_int_dis_vec,
68 cxi_l2_soc_sre,
69 cxi_l2_soc_err_type,
70 cxi_l2_soc_tid,
71 cxi_l2_err,
72 cxi_soc_err,
73 spc_ss_complete);
74wire pce_ov;
75wire stop;
76wire siclk;
77wire soclk;
78wire se;
79wire l1clk;
80wire request_lat_scanin;
81wire request_lat_scanout;
82wire [1:0] cpx_err;
83wire cpx_sre;
84wire [2:0] cpx_err_thr_id;
85wire [2:0] cpx_thr_id;
86wire [3:0] cpx_req;
87wire cpx_valid;
88wire [1:0] cpx_type;
89wire [5:0] cpx_vector;
90wire cpx_prefetch;
91wire valid_req;
92wire [7:0] id_decode;
93wire reset_type;
94wire xir_excp;
95wire ivd_lat_scanin;
96wire ivd_lat_scanout;
97wire l_ext_interrupt;
98wire [1:0] l_ext_int_type;
99wire [5:0] l_ext_int_vec;
100wire [2:0] l_ext_int_tid;
101wire [7:0] ivd_decode;
102wire irr_ne_0;
103wire hwint_type;
104wire ivt_excp;
105wire cerer_lat_scanin;
106wire cerer_lat_scanout;
107wire cerer_l2c_socc;
108wire cerer_l2u_socu;
109wire cerer_l2nd;
110wire valid_l2_err;
111wire valid_soc_err;
112wire valid_prefetch_err;
113wire [7:0] step_pending_in;
114wire [7:0] step_pending;
115wire step_pending_lat_scanin;
116wire step_pending_lat_scanout;
117wire ss_complete_in;
118wire ss_complete_lat_scanin;
119wire ss_complete_lat_scanout;
120wire ss_complete;
121wire spares_scanin;
122wire spares_scanout;
123
124
125
126input l2clk;
127input scan_in;
128input tcu_pce_ov;
129input spc_aclk;
130input spc_bclk;
131input tcu_scan_en;
132
133input [7:0] fls_core_running;
134input fls_ss_request;
135
136input [3:0] lsu_cpx_req; // Same as "rtntype" in CPX chapter
137input [1:0] lsu_cpx_err; // Error type for errors
138input lsu_cpx_sre; // software_recoverable_error
139input [2:0] lsu_cpx_err_thread_id; // Thread ID from CPX control
140input [2:0] lsu_cpx_thread_id; // Thread ID from CPX data
141input lsu_cpx_valid; // Valid for CPX packet
142input [1:0] lsu_cpx_type; // Interrupt type
143input [5:0] lsu_cpx_vector; // Trap requests from crossbar
144input lsu_cpx_prefetch; // Prefetch response (not load)
145
146input lsu_ext_interrupt; // Write to interrupt vector dispatch
147input [1:0] lsu_ext_int_type; // Type for CPX packet
148input [5:0] lsu_ext_int_vec; // Interrupt vector
149input [2:0] lsu_ext_int_tid;
150
151input [7:0] trl_ss_complete; // Single step is complete
152
153input [7:0] asi_irl_cleared; // Int_Received Reg had bits cleared
154input [63:0] cth_irl_cleared; // Copy of IRR after clearing operations
155
156input tlu_cerer_l2c_socc;
157input tlu_cerer_l2u_socu;
158input tlu_cerer_l2nd;
159
160
161
162output scan_out;
163
164output [7:0] cxi_xir; // External Interrupt Request
165output [7:0] cxi_ivt; // Interrupt Vector Trap Request
166
167output [7:0] cxi_wr_int_dis; // Interrupt Vector Dispatch packet
168output [5:0] cxi_int_dis_vec; // from gasket
169
170output cxi_l2_soc_sre; // software_recoverable_error
171output [1:0] cxi_l2_soc_err_type; // C=01, UC=10, ND=11
172output [2:0] cxi_l2_soc_tid;
173output cxi_l2_err; // L2 error reported
174output cxi_soc_err; // SOC error reported
175
176output spc_ss_complete; // Single step complete for all threads
177
178
179
180////////////////////////////////////////////////////////////////////////////////
181
182assign pce_ov = tcu_pce_ov;
183assign stop = 1'b0;
184assign siclk = spc_aclk;
185assign soclk = spc_bclk;
186assign se = tcu_scan_en;
187
188
189
190////////////////////////////////////////////////////////////////////////////////
191// Clock header
192
193tlu_cxi_ctl_l1clkhdr_ctl_macro clkgen (
194 .l2clk (l2clk ),
195 .l1en (1'b1 ),
196 .l1clk (l1clk ),
197 .pce_ov(pce_ov),
198 .stop(stop),
199 .se(se)
200);
201
202
203
204// Latch the request
205
206tlu_cxi_ctl_msff_ctl_macro__width_23 request_lat (
207 .scan_in(request_lat_scanin),
208 .scan_out(request_lat_scanout),
209 .din ({lsu_cpx_err [1:0],
210 lsu_cpx_sre ,
211 lsu_cpx_err_thread_id [2:0],
212 lsu_cpx_thread_id [2:0],
213 lsu_cpx_req [3:0],
214 lsu_cpx_valid ,
215 lsu_cpx_type [1:0],
216 lsu_cpx_vector [5:0],
217 lsu_cpx_prefetch }),
218 .dout ({cpx_err [1:0],
219 cpx_sre ,
220 cpx_err_thr_id [2:0],
221 cpx_thr_id [2:0],
222 cpx_req [3:0],
223 cpx_valid ,
224 cpx_type [1:0],
225 cpx_vector [5:0],
226 cpx_prefetch }),
227 .l1clk(l1clk),
228 .siclk(siclk),
229 .soclk(soclk)
230);
231
232
233
234//////////////////////////////////////////////////////////////////////////////
235//
236// XIR decode
237//
238// decode thread_id
239
240assign valid_req = cpx_valid & (cpx_req[3:0] == 4'b0111);
241
242assign id_decode[7:0] =
243 {cpx_thr_id[2:0] == 3'b111,
244 cpx_thr_id[2:0] == 3'b110,
245 cpx_thr_id[2:0] == 3'b101,
246 cpx_thr_id[2:0] == 3'b100,
247 cpx_thr_id[2:0] == 3'b011,
248 cpx_thr_id[2:0] == 3'b010,
249 cpx_thr_id[2:0] == 3'b001,
250 cpx_thr_id[2:0] == 3'b000};
251
252
253// process CPX interrupt type
254
255assign reset_type = (cpx_type[1:0] == 2'b01);
256
257assign xir_excp = valid_req & reset_type & (cpx_vector[5:0] == 6'b000011);
258
259assign cxi_xir[7:0] = {8 {xir_excp}} & id_decode[7:0];
260
261
262
263//////////////////////////////////////////////////////////////////////////////
264//
265// Interrupt Vector Dispatch decode
266//
267
268tlu_cxi_ctl_msff_ctl_macro__width_12 ivd_lat (
269 .scan_in(ivd_lat_scanin),
270 .scan_out(ivd_lat_scanout),
271 .din ({lsu_ext_interrupt ,
272 lsu_ext_int_type [1:0],
273 lsu_ext_int_vec [5:0],
274 lsu_ext_int_tid [2:0]}),
275 .dout ({l_ext_interrupt ,
276 l_ext_int_type [1:0],
277 l_ext_int_vec [5:0],
278 l_ext_int_tid [2:0]}),
279 .l1clk(l1clk),
280 .siclk(siclk),
281 .soclk(soclk)
282);
283
284assign ivd_decode[7:0] =
285 {l_ext_int_tid[2:0] == 3'b111,
286 l_ext_int_tid[2:0] == 3'b110,
287 l_ext_int_tid[2:0] == 3'b101,
288 l_ext_int_tid[2:0] == 3'b100,
289 l_ext_int_tid[2:0] == 3'b011,
290 l_ext_int_tid[2:0] == 3'b010,
291 l_ext_int_tid[2:0] == 3'b001,
292 l_ext_int_tid[2:0] == 3'b000};
293
294
295// Check if Interrupt Receive Register is zero
296
297assign irr_ne_0 =
298 (| cth_irl_cleared[63:0]);
299
300
301// process interrupt type
302
303assign hwint_type = (l_ext_int_type[1:0] == 2'b00);
304
305assign ivt_excp = l_ext_interrupt & hwint_type;
306
307assign cxi_ivt[7:0] =
308 ({8 {ivt_excp}} & ivd_decode[7:0]) |
309 ({8 {irr_ne_0}} & asi_irl_cleared[7:0]) ;
310
311assign cxi_wr_int_dis[7:0] = {8 {ivt_excp}} & ivd_decode[7:0];
312
313assign cxi_int_dis_vec[5:0] = l_ext_int_vec[5:0];
314
315
316
317//////////////////////////////////////////////////////////////////////////////
318//
319// L2 and SOC error decode
320//
321
322tlu_cxi_ctl_msff_ctl_macro__width_3 cerer_lat (
323 .scan_in(cerer_lat_scanin),
324 .scan_out(cerer_lat_scanout),
325 .din ({tlu_cerer_l2c_socc ,
326 tlu_cerer_l2u_socu ,
327 tlu_cerer_l2nd }),
328 .dout ({cerer_l2c_socc ,
329 cerer_l2u_socu ,
330 cerer_l2nd }),
331 .l1clk(l1clk),
332 .siclk(siclk),
333 .soclk(soclk)
334);
335
336
337assign valid_l2_err =
338 cpx_valid & (cpx_req[3:0] == 4'b1100) &
339 ((cpx_err[1:0] == 2'b01 & cerer_l2c_socc) |
340 (cpx_err[1:0] == 2'b10 & cerer_l2u_socu) |
341 (cpx_err[1:0] == 2'b11 & cerer_l2nd ) ) ;
342assign valid_soc_err =
343 cpx_valid & (cpx_req[3:0] == 4'b1101) &
344 ((cpx_err[1:0] == 2'b01 & cerer_l2c_socc) |
345 (cpx_err[1:0] == 2'b10 & cerer_l2u_socu) ) ;
346assign valid_prefetch_err =
347 cpx_valid & (cpx_req[3:0] == 4'b0000) & cpx_prefetch &
348 ((cpx_err[1:0] == 2'b01 & cerer_l2c_socc) |
349 (cpx_err[1:0] == 2'b10 & cerer_l2u_socu) |
350 (cpx_err[1:0] == 2'b11 & cerer_l2nd ) ) ;
351
352assign cxi_l2_soc_sre =
353 ((cpx_sre | (cpx_req[3:0] == 4'b0000 & cpx_prefetch)) &
354 (cpx_err[1:0] == 2'b01)) |
355 ((cpx_req[3:0] == 4'b1101) &
356 (cpx_err[1:0] == 2'b10)) ;
357assign cxi_l2_soc_err_type[1:0] =
358 cpx_err[1:0];
359assign cxi_l2_err =
360 valid_l2_err | valid_prefetch_err;
361assign cxi_soc_err =
362 valid_soc_err;
363
364assign cxi_l2_soc_tid[2:0] =
365 cpx_err_thr_id[2:0];
366
367
368
369//////////////////////////////////////////////////////////////////////////////
370//
371// Figure out when all threads have stepped
372//
373
374assign step_pending_in[7:0] =
375 ((fls_core_running[7:0] & {8 {fls_ss_request}}) |
376 step_pending[7:0]) & ~trl_ss_complete[7:0];
377
378tlu_cxi_ctl_msff_ctl_macro__width_8 step_pending_lat (
379 .scan_in(step_pending_lat_scanin),
380 .scan_out(step_pending_lat_scanout),
381 .din (step_pending_in [7:0] ),
382 .dout (step_pending [7:0] ),
383 .l1clk(l1clk),
384 .siclk(siclk),
385 .soclk(soclk)
386);
387
388assign ss_complete_in =
389 (| step_pending[7:0]) & ~(| step_pending_in[7:0]);
390
391tlu_cxi_ctl_msff_ctl_macro__width_1 ss_complete_lat (
392 .scan_in(ss_complete_lat_scanin),
393 .scan_out(ss_complete_lat_scanout),
394 .din (ss_complete_in ),
395 .dout (ss_complete ),
396 .l1clk(l1clk),
397 .siclk(siclk),
398 .soclk(soclk)
399);
400
401assign spc_ss_complete =
402 ss_complete;
403
404
405
406//////////////////////////////////////////////////////////////////////////////
407//
408// Spares
409//
410
411tlu_cxi_ctl_spare_ctl_macro__num_1 spares (
412 .scan_in(spares_scanin),
413 .scan_out(spares_scanout),
414 .l1clk (l1clk ),
415 .siclk(siclk),
416 .soclk(soclk)
417);
418
419
420
421supply0 vss; // <- port for ground
422supply1 vdd; // <- port for power
423// fixscan start:
424assign request_lat_scanin = scan_in ;
425assign ivd_lat_scanin = request_lat_scanout ;
426assign cerer_lat_scanin = ivd_lat_scanout ;
427assign step_pending_lat_scanin = cerer_lat_scanout ;
428assign ss_complete_lat_scanin = step_pending_lat_scanout ;
429assign spares_scanin = ss_complete_lat_scanout ;
430assign scan_out = spares_scanout ;
431// fixscan end:
432endmodule
433
434
435
436
437
438
439// any PARAMS parms go into naming of macro
440
441module tlu_cxi_ctl_l1clkhdr_ctl_macro (
442 l2clk,
443 l1en,
444 pce_ov,
445 stop,
446 se,
447 l1clk);
448
449
450 input l2clk;
451 input l1en;
452 input pce_ov;
453 input stop;
454 input se;
455 output l1clk;
456
457
458
459
460
461cl_sc1_l1hdr_8x c_0 (
462
463
464 .l2clk(l2clk),
465 .pce(l1en),
466 .l1clk(l1clk),
467 .se(se),
468 .pce_ov(pce_ov),
469 .stop(stop)
470);
471
472
473
474endmodule
475
476
477
478
479
480
481
482
483
484
485
486
487
488// any PARAMS parms go into naming of macro
489
490module tlu_cxi_ctl_msff_ctl_macro__width_23 (
491 din,
492 l1clk,
493 scan_in,
494 siclk,
495 soclk,
496 dout,
497 scan_out);
498wire [22:0] fdin;
499wire [21:0] so;
500
501 input [22:0] din;
502 input l1clk;
503 input scan_in;
504
505
506 input siclk;
507 input soclk;
508
509 output [22:0] dout;
510 output scan_out;
511assign fdin[22:0] = din[22:0];
512
513
514
515
516
517
518dff #(23) d0_0 (
519.l1clk(l1clk),
520.siclk(siclk),
521.soclk(soclk),
522.d(fdin[22:0]),
523.si({scan_in,so[21:0]}),
524.so({so[21:0],scan_out}),
525.q(dout[22:0])
526);
527
528
529
530
531
532
533
534
535
536
537
538
539endmodule
540
541
542
543
544
545
546
547
548
549
550
551
552
553// any PARAMS parms go into naming of macro
554
555module tlu_cxi_ctl_msff_ctl_macro__width_12 (
556 din,
557 l1clk,
558 scan_in,
559 siclk,
560 soclk,
561 dout,
562 scan_out);
563wire [11:0] fdin;
564wire [10:0] so;
565
566 input [11:0] din;
567 input l1clk;
568 input scan_in;
569
570
571 input siclk;
572 input soclk;
573
574 output [11:0] dout;
575 output scan_out;
576assign fdin[11:0] = din[11:0];
577
578
579
580
581
582
583dff #(12) d0_0 (
584.l1clk(l1clk),
585.siclk(siclk),
586.soclk(soclk),
587.d(fdin[11:0]),
588.si({scan_in,so[10:0]}),
589.so({so[10:0],scan_out}),
590.q(dout[11:0])
591);
592
593
594
595
596
597
598
599
600
601
602
603
604endmodule
605
606
607
608
609
610
611
612
613
614
615
616
617
618// any PARAMS parms go into naming of macro
619
620module tlu_cxi_ctl_msff_ctl_macro__width_3 (
621 din,
622 l1clk,
623 scan_in,
624 siclk,
625 soclk,
626 dout,
627 scan_out);
628wire [2:0] fdin;
629wire [1:0] so;
630
631 input [2:0] din;
632 input l1clk;
633 input scan_in;
634
635
636 input siclk;
637 input soclk;
638
639 output [2:0] dout;
640 output scan_out;
641assign fdin[2:0] = din[2:0];
642
643
644
645
646
647
648dff #(3) d0_0 (
649.l1clk(l1clk),
650.siclk(siclk),
651.soclk(soclk),
652.d(fdin[2:0]),
653.si({scan_in,so[1:0]}),
654.so({so[1:0],scan_out}),
655.q(dout[2:0])
656);
657
658
659
660
661
662
663
664
665
666
667
668
669endmodule
670
671
672
673
674
675
676
677
678
679
680
681
682
683// any PARAMS parms go into naming of macro
684
685module tlu_cxi_ctl_msff_ctl_macro__width_8 (
686 din,
687 l1clk,
688 scan_in,
689 siclk,
690 soclk,
691 dout,
692 scan_out);
693wire [7:0] fdin;
694wire [6:0] so;
695
696 input [7:0] din;
697 input l1clk;
698 input scan_in;
699
700
701 input siclk;
702 input soclk;
703
704 output [7:0] dout;
705 output scan_out;
706assign fdin[7:0] = din[7:0];
707
708
709
710
711
712
713dff #(8) d0_0 (
714.l1clk(l1clk),
715.siclk(siclk),
716.soclk(soclk),
717.d(fdin[7:0]),
718.si({scan_in,so[6:0]}),
719.so({so[6:0],scan_out}),
720.q(dout[7:0])
721);
722
723
724
725
726
727
728
729
730
731
732
733
734endmodule
735
736
737
738
739
740
741
742
743
744
745
746
747
748// any PARAMS parms go into naming of macro
749
750module tlu_cxi_ctl_msff_ctl_macro__width_1 (
751 din,
752 l1clk,
753 scan_in,
754 siclk,
755 soclk,
756 dout,
757 scan_out);
758wire [0:0] fdin;
759
760 input [0:0] din;
761 input l1clk;
762 input scan_in;
763
764
765 input siclk;
766 input soclk;
767
768 output [0:0] dout;
769 output scan_out;
770assign fdin[0:0] = din[0:0];
771
772
773
774
775
776
777dff #(1) d0_0 (
778.l1clk(l1clk),
779.siclk(siclk),
780.soclk(soclk),
781.d(fdin[0:0]),
782.si(scan_in),
783.so(scan_out),
784.q(dout[0:0])
785);
786
787
788
789
790
791
792
793
794
795
796
797
798endmodule
799
800
801
802
803
804
805
806
807
808// Description: Spare gate macro for control blocks
809//
810// Param num controls the number of times the macro is added
811// flops=0 can be used to use only combination spare logic
812
813
814module tlu_cxi_ctl_spare_ctl_macro__num_1 (
815 l1clk,
816 scan_in,
817 siclk,
818 soclk,
819 scan_out);
820wire si_0;
821wire so_0;
822wire spare0_flop_unused;
823wire spare0_buf_32x_unused;
824wire spare0_nand3_8x_unused;
825wire spare0_inv_8x_unused;
826wire spare0_aoi22_4x_unused;
827wire spare0_buf_8x_unused;
828wire spare0_oai22_4x_unused;
829wire spare0_inv_16x_unused;
830wire spare0_nand2_16x_unused;
831wire spare0_nor3_4x_unused;
832wire spare0_nand2_8x_unused;
833wire spare0_buf_16x_unused;
834wire spare0_nor2_16x_unused;
835wire spare0_inv_32x_unused;
836
837
838input l1clk;
839input scan_in;
840input siclk;
841input soclk;
842output scan_out;
843
844cl_sc1_msff_8x spare0_flop (.l1clk(l1clk),
845 .siclk(siclk),
846 .soclk(soclk),
847 .si(si_0),
848 .so(so_0),
849 .d(1'b0),
850 .q(spare0_flop_unused));
851assign si_0 = scan_in;
852
853cl_u1_buf_32x spare0_buf_32x (.in(1'b1),
854 .out(spare0_buf_32x_unused));
855cl_u1_nand3_8x spare0_nand3_8x (.in0(1'b1),
856 .in1(1'b1),
857 .in2(1'b1),
858 .out(spare0_nand3_8x_unused));
859cl_u1_inv_8x spare0_inv_8x (.in(1'b1),
860 .out(spare0_inv_8x_unused));
861cl_u1_aoi22_4x spare0_aoi22_4x (.in00(1'b1),
862 .in01(1'b1),
863 .in10(1'b1),
864 .in11(1'b1),
865 .out(spare0_aoi22_4x_unused));
866cl_u1_buf_8x spare0_buf_8x (.in(1'b1),
867 .out(spare0_buf_8x_unused));
868cl_u1_oai22_4x spare0_oai22_4x (.in00(1'b1),
869 .in01(1'b1),
870 .in10(1'b1),
871 .in11(1'b1),
872 .out(spare0_oai22_4x_unused));
873cl_u1_inv_16x spare0_inv_16x (.in(1'b1),
874 .out(spare0_inv_16x_unused));
875cl_u1_nand2_16x spare0_nand2_16x (.in0(1'b1),
876 .in1(1'b1),
877 .out(spare0_nand2_16x_unused));
878cl_u1_nor3_4x spare0_nor3_4x (.in0(1'b0),
879 .in1(1'b0),
880 .in2(1'b0),
881 .out(spare0_nor3_4x_unused));
882cl_u1_nand2_8x spare0_nand2_8x (.in0(1'b1),
883 .in1(1'b1),
884 .out(spare0_nand2_8x_unused));
885cl_u1_buf_16x spare0_buf_16x (.in(1'b1),
886 .out(spare0_buf_16x_unused));
887cl_u1_nor2_16x spare0_nor2_16x (.in0(1'b0),
888 .in1(1'b0),
889 .out(spare0_nor2_16x_unused));
890cl_u1_inv_32x spare0_inv_32x (.in(1'b1),
891 .out(spare0_inv_32x_unused));
892assign scan_out = so_0;
893
894
895
896endmodule
897