suctl.v
38.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
/**************************************************************************
* *
* Copyright (C) 1994, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
*************************************************************************/
// $Id: suctl.v,v 1.1.1.1 2002/05/17 06:07:48 blythe Exp $
// suctl.v: RSP scalar unit control with calls to VU control and issue logic
`timescale 1ns / 10ps
`include "sopcodes.h"
module suctl (clk, reset_l,
halt, single_step, pc_in_wr_en, pc_data_in,
dma_dm_to_rd, dma_rd_to_dm, dma_imem_select,
br_addr, rd_inst,
sushvamt, sualu_cout_l, sualu_ovr, sualumsb,
suexasign, suexbsign, suonesdet_z,
su_inst,
surfile_ra_t, surfile_ra_f, surfile_rb_t, surfile_rb_f,
surdamux, surdbmux, suimmmux, suvulsoffsetmux, suimmlsmux,
set_broke, break_inst_debug,
sualuamux, sualubmux, sushamux, sushbmux,
suslten, susltlt, sualuen, sualu, sualu_cin, sudrivels,
sushen, shiftamt, sushift_s,
su_ex_store, su_ex_load, vu_ex_store, vu_ex_load,
ex_mfc2, ex_mtc2, ex_cfc2, ex_su_byte_ls, ex_su_half_ls, ex_su_uns_ls,
elem_num, chip_sel, rd_base, rd_offset, rd_elem_num,
vu_rd_ld_dec_k, vu_rd_st_dec_k,
df_ls_drive_ls_in_wb, df_pass_thru,
surfile_w_t, surfile_w_f, su_mem_wen, suwben,
vu_comp_k, vu_func, vs_eq_one, vu_elem, vs,
ex_ctc2_vc0, ex_ctc2_vc1, ex_ctc2_vc2,
vu_rd_store_type_k, vu_rd_storecfc2_k,
rd_cfvc0_k, rd_cfvc1_k, rd_cfvc2_k,
acc_wr_reg, acc_wr_en,
vu_ld_addr, vu_st_addr, vu_st_xpose_addr, xpose,
cp0_address, cp0_write, cp0_enable, ex_mfc0,
imem_chip_sel_l, imem_dma_cycle, rd_pre_vt, vt_sel,
su_nop_debug, vu_nop_debug,
link_pc_delay_pc, pc, su_rd_pc_debug, vu_rd_pc_debug);
input clk;
input reset_l;
input halt;
input single_step;
input pc_in_wr_en;
input [11:2] pc_data_in;
input dma_dm_to_rd;
input dma_rd_to_dm;
input dma_imem_select;
input [11:2] br_addr;
input [63:0] rd_inst; // imem out. [63:32] is low order inst
input [4:0] sushvamt;
// EX stage from SU DP
input sualu_cout_l; // active low
input sualu_ovr;
input sualumsb;
input suexasign;
input suexbsign;
input suonesdet_z;
// RD stage to SU DP
output [31:0] su_inst;
output [31:0] surfile_ra_t; // decoded ra addr
output [31:0] surfile_ra_f; // decoded ra addr, complement
output [31:0] surfile_rb_t; // decoded rb addr
output [31:0] surfile_rb_f; // decoded rb addr, complement
output [4:0] surdamux;
output [5:0] surdbmux;
output [3:0] suimmmux; // imm sxt, zxt, lui
output [1:0] suimmlsmux;
output [4:0] suvulsoffsetmux; // vu l/s offset generation
// RD stage to LS
output [3:0] rd_base;
output [3:0] rd_offset;
output [3:0] rd_elem_num;
output [11:0] vu_rd_ld_dec_k; // type of vu ld data
output [11:0] vu_rd_st_dec_k; // type of vu st data
// RD stage to DMA
output set_broke;
// RD stage to nowhere
output break_inst_debug;
output [1:0] sualuamux; // EX stage to SU DP
output [1:0] sualubmux;
output [3:0] sushamux;
output [2:0] sushbmux;
output sudrivels;
output suslten; // enable slt result
output susltlt; // set, lt true
output sualuen;
output [4:0] sualu;
output sualu_cin;
output sushen;
output [31:0] shiftamt;
output sushift_s;
// EX stage to LS
output su_ex_store;
output su_ex_load;
output vu_ex_store;
output vu_ex_load;
output ex_mfc2;
output ex_mtc2;
output ex_cfc2;
output ex_su_byte_ls;
output ex_su_half_ls;
output ex_su_uns_ls;
output [3:0] elem_num;
output chip_sel; // dmem chip select
// DF stage to LS
output df_ls_drive_ls_in_wb;
output df_pass_thru; // df_inst is MT, MF, CT, CF
// WB stage to SU DP
output [31:0] surfile_w_t; // decoded rf write en
output [31:0] surfile_w_f; // decoded rf write en, comp
output su_mem_wen; // en load data into SU RFile
output suwben; // en wb_data into SU RFile
// Controls for VU
// RD stage to VU
output vu_comp_k;
output [5:0] vu_func;
output vs_eq_one;
output [3:0] vu_elem;
output [4:0] vs; // RD: reg num for vs read
output vu_rd_store_type_k;
output vu_rd_storecfc2_k;
output rd_cfvc0_k;
output rd_cfvc1_k;
output rd_cfvc2_k;
// EX/ACC stage to VU
output ex_ctc2_vc0;
output ex_ctc2_vc1;
output ex_ctc2_vc2;
// DF stage to VU
output [4:0] acc_wr_reg;
output acc_wr_en;
output [4:0] vu_ld_addr;
output [4:0] vu_st_addr;
output [4:0] vu_st_xpose_addr;
output xpose; // ld xpose in ACC or st xpose in RD
// EX stage to CP0
output [3:0] cp0_address;
output cp0_write; // CTC0
output cp0_enable; // !CTC0
output ex_mfc0;
output imem_chip_sel_l; // pre-IF stage to IMem
output imem_dma_cycle; // IF stage to BIST
output su_nop_debug; // RD stage to nowhere
output vu_nop_debug; // RD stage to nowhere
output [23:0] link_pc_delay_pc; // EX stage to LS
output [11:2] pc;
output [11:0] su_rd_pc_debug;
output [11:0] vu_rd_pc_debug;
// Controls for VT
output [4:0] rd_pre_vt;
output [1:0] vt_sel;
wire imem_chip_sel;
wire wr_br_addr;
wire [4:0] pc_sel;
wire pc_wr_en;
wire rd_broke_k;
wire single_step_halt;
wire start_ext_halt;
wire adv_ir;
wire halting;
wire prev_halt;
wire imem_stall;
wire imem_dma_ppif;
wire imem_dma_pif;
wire imem_dma_if;
wire imem_dma_rd;
wire start_imem_dma;
wire [31:0] su_inst; // RD stage
wire [31:0] su_inst_a;
wire [31:0] vu_inst_a;
wire [31:0] su_inst_b;
wire [31:0] vu_inst_b;
wire choose_su_inst_b;
wire choose_vu_inst_b;
wire set_taken;
wire clear_taken;
wire [5:0] opc;
wire [5:0] func;
wire [4:0] rs;
wire [4:0] rt;
wire [4:0] rd;
wire [4:0] lsopc;
wire kill_re; // kill inst entering EX
wire kill_su_issue;
wire kill_vu_issue;
wire vu_comp;
wire rd_bubble;
wire ex_break;
wire load_use_stall;
wire load_store_stall;
wire vu_reg_hazard_comp;
wire vu_reg_hazard_ls;
wire rd_dma_cycle;
wire ex_dma_cycle;
wire df_dma_cycle;
wire dmem_dma_stall;
wire [4:0] rd_wr_reg;
wire [4:0] ex_wr_reg;
wire [4:0] df_wr_reg;
wire [4:0] wb_wr_reg;
wire rd_wr_en;
wire rd_wr_en_k;
wire ex_wr_en;
wire df_wr_en;
wire wb_wr_en;
wire [31:0] surfile_nobar; // decoded RF write enable
wire [31:0] surfile_bar; // decoded RF write enable
wire [31:0] surfile_w_bar; // decoded RF write enable
wire use_a;
wire use_b;
wire rs_zero;
wire rt_zero;
wire a_gets_0;
wire a_ex_byp;
wire a_df_byp;
wire a_wb_byp;
wire b_ex_byp;
wire b_df_byp;
wire b_wb_byp;
wire rd_sh_en; // shifter drives ex_out
wire rd_sh_l; // left shift
wire ex_sh_l;
wire rd_sh_r; // logical right shift
wire ex_sh_r;
wire rd_sh_ra; // arithmetic right shift
wire ex_sh_ra;
wire rd_mfc2;
wire rd_mfc2_k;
wire rd_mtc2;
wire rd_mtc2_k;
wire rd_cfc2;
wire rd_cfc2_k;
wire rd_alubmux_1;
wire ex_alubmux_1;
wire [4:0] rd_sh_amt; // encoded right shift amount
wire [4:0] ex_sh_amt; // encoded shift amount
wire [31:0] shiftamt_b;
wire rd_sslt_en; // slt signed
wire rd_uslt_en; // slt unsigned
wire ex_sslt_en; // slt signed drives ex_out
wire ex_uslt_en; // slt unsigned drives ex_out
wire rd_alu_en; // alu drives ex_out
wire [4:0] rd_alu; // alu function control
wire rd_alu_cin;
wire rd_imm; // inst has imm operand
wire rd_branch;
wire rd_branch_k;
wire rd_branch1; // 1-source branches
wire rd_br_al; // branch and link
wire rd_br_al_k;
wire ex_br_al;
wire ex_branch;
wire [5:0] rd_br_type;
wire [5:0] rd_br_type_k;
wire [5:0] ex_br_type;
wire rd_jump_imm;
wire rd_jump;
wire rd_jump_k;
wire ex_jump;
wire taken;
wire wr_taken;
wire old_taken;
wire rd_broke;
wire rd_su_load; // dmem load
wire rd_su_load_k;
wire su_df_load;
wire su_wb_load_type;
wire su_rd_load_type; // dmem load or MFCx or CFCx
wire su_rd_load_type_k;
wire su_ex_load_type;
wire su_df_load_type;
wire vu_rd_load;
wire vu_rd_load_k;
wire vu_rd_ls;
wire vu_df_load;
wire vu_byte_ls;
wire vu_short_ls;
wire vu_word_ls;
wire vu_double_ls;
wire vu_quad_ls;
wire vu_rest_ls;
wire vu_pack_ls;
wire vu_upack_ls;
wire vu_half_ls;
wire vu_fourth_ls;
wire vu_trans_ls;
wire vu_wrap_ls;
wire su_rd_store; // dmem store
wire su_rd_store_k;
wire vu_rd_store; // dmem store
wire vu_rd_store_k;
wire rd_su_byte_ls;
wire rd_su_half_ls;
wire rd_su_uns_ls;
wire rd_su_byte_ls_k;
wire rd_su_half_ls_k;
wire rd_su_uns_ls_k;
wire rd_pass_thru;
wire rd_pass_thru_k;
wire ex_pass_thru;
wire rd_ls_drive_ls_in_wb;
wire rd_ls_drive_ls_in_wb_k;
wire ex_ls_drive_ls_in_wb;
// CP0 Signals:
wire rd_mtc0;
wire rd_mtc0_k;
wire ex_mtc0;
wire rd_mfc0;
wire rd_mfc0_k;
wire [4:0] ex_wr_reg_n;
wire ex_wr_en_n;
wire ex_sslt_en_n;
wire ex_uslt_en_n;
wire sualuen_n;
wire sualu_cin_n;
wire [4:0] sualu_n;
wire ex_alubmux_1_n;
wire sushen_n;
wire ex_sh_l_n;
wire ex_sh_r_n;
wire ex_sh_ra_n;
wire [4:0] ex_sh_amt_n;
wire [3:0] elem_num_n;
wire su_ex_load_n;
wire su_ex_load_type_n;
wire vu_ex_load_n;
wire ex_mfc2_n;
wire ex_mtc2_n;
wire ex_cfc2_n;
wire ex_ls_drive_ls_in_wb_n;
wire ex_pass_thru_n;
wire ex_dma_cycle_n;
wire su_ex_store_n;
wire vu_ex_store_n;
wire ex_su_byte_ls_n;
wire ex_su_half_ls_n;
wire ex_su_uns_ls_n;
wire ex_branch_n;
wire ex_br_al_n;
wire [5:0] ex_br_type_n;
wire ex_jump_n;
wire prev_halt_n;
wire imem_dma_pif_n;
wire imem_dma_if_n;
wire imem_dma_rd_n;
wire old_taken_n;
wire old_delay_pending_n;
wire old_target_pending_n;
wire [4:0] df_wr_reg_n;
wire df_wr_en_n;
wire su_df_load_n;
wire su_df_load_type_n;
wire vu_df_load_n;
wire df_ls_drive_ls_in_wb_n;
wire df_pass_thru_n;
wire df_dma_cycle_n;
wire [4:0] wb_wr_reg_n;
wire wb_wr_en_n;
wire su_wb_load_type_n;
wire ex_mtc0_n;
wire [3:0] cp0_address_n;
wire ex_mfc0_n;
wire reset_l_lat;
wire reset_l_lat_n;
//
// RD stage signals: instruction decode, bypasses
//
assign su_inst = choose_su_inst_b ? su_inst_b : su_inst_a;
assign opc = su_inst[31:26];
assign func = su_inst[5:0];
assign rs = su_inst[25:21];
assign rt = su_inst[20:16];
assign rd = su_inst[15:11];
assign lsopc = su_inst[15:11];
assign rd_elem_num = su_inst[10:7];
// Note that rd_su_load and rd_su_store are *not* mutually exclusive
// with VU load/store decodes:
assign rd_offset =
(rd_su_load || su_rd_store) ? su_inst[3:0] :
(vu_quad_ls || vu_rest_ls || vu_half_ls ||
vu_fourth_ls || vu_trans_ls || vu_wrap_ls) ? 4'b0 :
(vu_double_ls || vu_pack_ls || vu_upack_ls) ? {su_inst[0], 3'b0} :
vu_word_ls ? {su_inst[1:0], 2'b0} :
vu_short_ls ? {su_inst[2:0], 1'b0} :
/* vu_byte_ls or su ?*/ su_inst[3:0];
assign rd_base = sushvamt[3:0];
regfile_decode regfile_decode_rs(rs, surfile_ra_t, surfile_ra_f);
regfile_decode regfile_decode_rt(rt, surfile_rb_t, surfile_rb_f);
assign rd_wr_reg =
(su_rd_load_type || rd_imm) ? rt : // su loads, MFCx, CFCx, imm
(`JAL || `REGIMM) ? 31 : // (`JAL || rd_br_al)
rd;
assign rd_wr_en = !(
(rd_wr_reg==5'b0) || // write to R0
(rd_branch && !rd_br_al) || // non-link branches
`LWC2 || `SB || `SH || `SW || `SWC2 || // stores, vu load
`J || (`SPECIAL && (`JR || `BREAK)) || // non-link jumps, break
((opc[5:4]==2'b01) && (rs[4:2]!=3'b000))); // VU, MTCx, CTCx
assign rd_mfc2 = (opc[5:4]==2'b01) && (opc[1]==1'b1) &&
(rs[4]==0) && (rs[2:1]==2'b00);
assign rd_mtc2 = (opc[5:4]==2'b01) && (opc[1]==1'b1) &&
(rs[4]==0) && (rs[2:1]==2'b10);
assign rd_cfc2 = (opc[5:4]==2'b01) && (opc[1]==1'b1) &&
(rs[4]==0) && (rs[2:1]==2'b01);
assign rd_sslt_en = `SLTI || (`SPECIAL && `SLT);
assign rd_uslt_en = `SLTIU || (`SPECIAL && `SLTU);
assign rd_alu_en = `ADDI || `ADDIU || `ANDI || `ORI || `XORI || `LUI ||
(`SPECIAL &&
(`ADD || `ADDU || `SUB || `SUBU || `AND || `OR || `XOR || `NOR));
assign rd_alu_cin = `SLTI || `SLTIU ||
`SPECIAL && (`SLT || `SLTU || `SUB || `SUBU);
assign rd_alu[4] = `ANDI || `ORI || `XORI || `LUI ||
(`SPECIAL && (`AND || `OR || `XOR || `NOR)); // logical ops
assign rd_alu[3] = `ORI || `LUI || (`SPECIAL && (`OR)); // NAND, OR, LUI
assign rd_alu[2] = `ANDI || `ORI || `LUI ||
(`SPECIAL && (`AND || `OR || `NOR)); // AND, NAND, OR, NOR, LUI
assign rd_alu[1] = `ORI || `XORI || `LUI || `SLTI || `SLTIU ||
(`SPECIAL && (`OR || `NOR || `XOR || `SLT || `SLTU || `SUB || `SUBU));
// OR, NOR, XOR, LUI, SUB, SLT
assign rd_alu[0] = `ORI || `LUI || (`SPECIAL && (`OR || `NOR));
// OR, NOR, LUI
assign rd_sh_l = `SPECIAL && (`SLL || `SLLV);
assign rd_sh_r = `SPECIAL && (`SRL || `SRLV);
assign rd_sh_ra = `SPECIAL && (`SRA || `SRAV);
assign rd_sh_en = rd_br_al || `JAL || (`SPECIAL && (`JALR)) ||
rd_sh_l || rd_sh_r || rd_sh_ra;
// Left shifts are converted to right shifts, because that's the kind of
// shifter we have. Data to be shifted is preshifted right by one bit,
// and put in the high order half of the 64-bit shift input. It's then
// right shifted by the inverse of the left shift amount. This results
// in a right shift of 32-(left shift amount), which is equivalent to the
// desired left shift.
// *** This may take too long in RD:
assign rd_sh_amt = rd_br_al || rd_jump ? 5'b01100 :
(`SPECIAL && `SLL) ? ~su_inst[10:6] :
(`SPECIAL && (`SRL || `SRA)) ? su_inst[10:6] :
(`SPECIAL && `SLLV) ? ~sushvamt :
/* (`SPECIAL && (`SRLV || `SRAV)) */ sushvamt;
assign rd_imm = (opc[5:3] == 3'b001);
assign suimmlsmux[0] = !vu_rd_ls;
assign suimmlsmux[1] = vu_rd_ls;
assign suimmmux[3] = rd_branch || `J || `JAL; // br, J, JAL
assign suimmmux[2] = `LUI || (`SPECIAL && (`JR || `JALR)); // lui,JxxR(0)
assign suimmmux[1] = `LB || `LBU || `LH || `LHU || `LW ||
`SB || `SH || `SW ||
`ADDI || `ADDIU || `SLTI || `SLTIU; // sxt
assign suimmmux[0] = `ANDI || `ORI || `XORI; // zxt
assign suvulsoffsetmux =
{vu_quad_ls || vu_rest_ls || vu_half_ls || vu_fourth_ls ||
vu_trans_ls || vu_wrap_ls,
vu_double_ls || vu_pack_ls || vu_upack_ls,
vu_word_ls,
vu_short_ls,
vu_byte_ls};
assign rd_jump = `J || `JAL || (`SPECIAL && (`JR || `JALR));
assign rd_jump_imm = `J || `JAL;
assign rd_branch = `BEQ || `BNE || `BLEZ || `BGTZ ||
(`REGIMM && (`BLTZ || `BGEZ || `BLTZAL || `BGEZAL));
// *** really any REGIMM
assign rd_branch1 = `BLEZ || `BGTZ ||
(`REGIMM && (`BLTZ || `BGEZ || `BLTZAL || `BGEZAL));
// *** really any REGIMM
assign rd_br_al = `REGIMM && (`BLTZAL || `BGEZAL);
assign rd_br_type[0] = `BEQ;
assign rd_br_type[1] = `BNE;
assign rd_br_type[2] = `BLEZ || (`REGIMM && (`BLTZ || `BLTZAL)); // < 0
assign rd_br_type[3] = `BLEZ || (`REGIMM && (`BGEZ || `BGEZAL)); // = 0
assign rd_br_type[4] = `BGTZ || (`REGIMM && (`BGEZ || `BGEZAL)); // > 0
assign rd_br_type[5] = rd_br_al; // link
assign rd_su_load = (opc[5:3] == 3'b100); // LB, LBU, LH, LHU, LW
assign su_rd_load_type =
(opc[5:3] == 3'b100) || (opc[5:3]==3'b010 && rs[4:2]==3'b000);
// loads or MFCx or CFCx
assign vu_byte_ls = (lsopc==5'h0);
assign vu_short_ls = (lsopc==5'h1);
assign vu_word_ls = (lsopc==5'h2);
assign vu_double_ls = (lsopc==5'h3);
assign vu_quad_ls = (lsopc==5'h4);
assign vu_rest_ls = (lsopc==5'h5);
assign vu_pack_ls = (lsopc==5'h6);
assign vu_upack_ls = (lsopc==5'h7);
assign vu_half_ls = (lsopc==5'h8);
assign vu_fourth_ls = (lsopc==5'h9);
assign vu_wrap_ls = (lsopc==5'ha); // does not include lwt
assign vu_trans_ls = (lsopc==5'hb); // includes lwt
assign vu_rd_ld_dec_k[0] = vu_byte_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[1] = vu_short_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[2] = vu_word_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[3] = vu_double_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[4] = vu_quad_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[5] = vu_rest_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[6] = vu_pack_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[7] = vu_upack_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[8] = vu_half_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[9] = vu_fourth_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[10] = vu_trans_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_ld_dec_k[11] = vu_wrap_ls && vu_rd_load && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[0] = vu_byte_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[1] = vu_short_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[2] = vu_word_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[3] = vu_double_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[4] = vu_quad_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[5] = vu_rest_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[6] = vu_pack_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[7] = vu_upack_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[8] = vu_half_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[9] = vu_fourth_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[10] = vu_trans_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_st_dec_k[11] = vu_wrap_ls && vu_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_load = (opc[5:3]==3'b110);
assign rd_pass_thru = ((`COP2 || `COP0) && (rs[4:3] == 2'b00)); // MT/F,CT/F
assign rd_ls_drive_ls_in_wb = `LWC2 || rd_su_load || rd_pass_thru;
// *** Optimization: combine vu_xx_store and su_xx_store? Check load, too.
assign su_rd_store = (opc[5:3] == 3'b101);
assign vu_rd_store = (opc[5:3] == 3'b111);
assign rd_su_byte_ls = (opc[5:4] == 3'b10) && (opc[1:0] == 2'b00);
assign rd_su_half_ls = (opc[5:4] == 3'b10) && (opc[1:0] == 2'b01);
assign rd_su_uns_ls = (opc[5:4] == 3'b10) && (opc[2] == 1'b1);
assign rd_alubmux_1 = (vu_rd_load || rd_su_load || // imm_data for l/s/br
vu_rd_store || su_rd_store ||
rd_branch || rd_jump);
// Bypasses // *** try all x==y in one level, then do combinations in next
// *** Based on QTV, instantiate XORS in wr_reg comparisons:
/* suRdAMux: suRdBMux:
0 rFile A src 0 rFile B src
1 EX bypass 1 EX bypass
2 DF bypass 2 DF bypass
3 WB bypass 3 WB bypass
4 zeros (J, JAL, R0) 4 imm_data
5 zeros (R0)
*/
assign rs_zero = use_a && (rs==5'b0);
assign rt_zero = use_b && (rt==5'b0);
assign a_ex_byp = ({rs, 1'b1} == {ex_wr_reg, ex_wr_en});
assign a_df_byp = ({rs, 1'b1} == {df_wr_reg, df_wr_en});
assign a_wb_byp = ({rs, 1'b1} == {wb_wr_reg, wb_wr_en});
assign a_gets_0 = rd_jump_imm || rs_zero || `LUI;
assign surdamux[0] =
!a_wb_byp && !a_df_byp && !a_ex_byp && !a_gets_0;
assign surdamux[1] = // ex byp
a_ex_byp && !a_gets_0;
assign surdamux[2] = // df byp
a_df_byp && !a_ex_byp && !a_gets_0;
assign surdamux[3] = // wb byp
a_wb_byp && !a_df_byp && !a_ex_byp && !a_gets_0;
assign surdamux[4] = a_gets_0; // zeroes
assign b_ex_byp = ({rt, 1'b1} == {ex_wr_reg, ex_wr_en});
assign b_df_byp = ({rt, 1'b1} == {df_wr_reg, df_wr_en});
assign b_wb_byp = ({rt, 1'b1} == {wb_wr_reg, wb_wr_en});
assign vu_rd_ls = `LWC2 || `SWC2;
// Note offsets for loads and stores (and branches?) do not go through
// surdbmux, but through a FF then sualubmux.
assign surdbmux[0] = !b_wb_byp && !b_df_byp && !b_ex_byp &&
!rd_imm && !rd_branch1 && !rt_zero;
assign surdbmux[1] = b_ex_byp && // ex byp
!rd_imm && !rd_branch1 && !rt_zero;
assign surdbmux[2] = b_df_byp && !b_ex_byp && // df byp
!rd_imm && !rd_branch1 && !rt_zero;
assign surdbmux[3] = b_wb_byp && !b_df_byp && !b_ex_byp && // wb_byp
!rd_imm && !rd_branch1 && !rt_zero;
assign surdbmux[4] = rd_imm; // inst_data
assign surdbmux[5] = rd_branch1 || rt_zero; // 0's
// Pipe Control
assign rd_broke = `SPECIAL && `BREAK;
// Instruction in RD uses as a souce a register that is the destination
// of a load in progress. Hold RD, kill EX, advance DF and WB.
assign use_a = !(`J || `JAL || `COP0 || `COP2 ||
(`SPECIAL && (func[5:2] == 4'b0000))); // non-variable shifts
assign use_b =
`SPECIAL ||
(opc[5:2] == 4'b0001) || // branches
(opc[5:3]== 3'b101) || // su stores
((opc[5:4] == 2'b01) && rs[2]); // MT, CT
assign load_use_stall = !kill_su_issue && (
(use_a && a_ex_byp && su_ex_load_type) ||
(use_a && a_df_byp && su_df_load_type) ||
(use_b && b_ex_byp && su_ex_load_type) ||
(use_b && b_df_byp && su_df_load_type));
assign load_store_stall = !kill_su_issue &&
(su_rd_store || vu_rd_store || rd_pass_thru) && // store or mf/mt/cf/ct
(su_df_load || vu_df_load || df_pass_thru); // load or mf/mt/cf/ct
assign rd_dma_cycle = (dma_dm_to_rd || dma_rd_to_dm) && !dma_imem_select;
assign dmem_dma_stall = !kill_su_issue && (rd_dma_cycle || df_dma_cycle) &&
(su_rd_store || vu_rd_store || rd_pass_thru || rd_su_load || vu_rd_load);
// Adv_ir causes the RD stage latches to be held if deasserted.
// Kill_re causes the EX stage signals to be deasserted.
// To stall the pipe, adv_ir = 0 and kill_re = 1.
// To restart execution after a halt, for one cycle adv_ir = 1 and kill_re = 0.
assign adv_ir = !(vu_reg_hazard_comp && !kill_vu_issue) &&
!(vu_reg_hazard_ls && !kill_su_issue) && !load_use_stall &&
!load_store_stall && !dmem_dma_stall;
// When halt is deasserted the first non-halt cycle is valid in IF but not
// RD. The use of prev_halt in kill_re prevents issue of an RD instruction
// before a valid instruction has reached RD.
assign kill_re = (vu_reg_hazard_comp && !kill_vu_issue) ||
(vu_reg_hazard_ls && !kill_su_issue) ||
load_use_stall || load_store_stall ||
dmem_dma_stall || imem_dma_rd || halt || prev_halt;
wire kill_re_non_vu; // for suvuctl, which generates vu_reg_hazard
assign kill_re_non_vu = load_use_stall || load_store_stall ||
dmem_dma_stall || imem_dma_rd || halt || prev_halt;
assign vu_comp_k = vu_comp && !(kill_vu_issue || kill_re_non_vu || vu_reg_hazard_comp || (vu_reg_hazard_ls && !kill_su_issue));
/*
// Logically this is correct, but reset_l, adv_ir and pc_sel are too late to
// be used by imem_chip_sel.
assign imem_chip_sel =
!reset_l ||
imem_dma_if || // dma access to imem
(!halt && adv_ir && !imem_stall) || // more to execute in IR FF
(!halt && adv_ir && (pc_sel[2] || pc_sel[3])); // take a branch
*/
spasdff_1_0 su_reset_ff (reset_l_lat, reset_l_lat_n, reset_l, clk, 1'b1);
assign imem_chip_sel = !reset_l_lat || imem_dma_if || !halt;
wire should_have_stalled;
assign should_have_stalled =
(imem_chip_sel && !imem_dma_if && !adv_ir) ||
(imem_chip_sel && !imem_dma_if && imem_stall &&
!(pc_sel[2] || pc_sel[3])) ;
assign imem_chip_sel_l = !imem_chip_sel;
assign single_step_halt = single_step && !prev_halt && !halt;
// *** In single step mode, halt is deasserted in 2-cycle quanta. During the
// *** first cycle rd_bubble is set, so no instruction is issued. During the
// *** second cycle an instruction is issued and rd_broke_k is asserted.
assign set_broke = single_step_halt || rd_broke_k;
// Kill: optionally kill EX stage signals
assign rd_wr_en_k = rd_wr_en && !(kill_su_issue || kill_re);
assign rd_su_load_k = rd_su_load && !(kill_su_issue || kill_re);
assign rd_su_byte_ls_k = rd_su_byte_ls && !(kill_su_issue || kill_re);
assign rd_su_half_ls_k = rd_su_half_ls && !(kill_su_issue || kill_re);
assign rd_su_uns_ls_k = rd_su_uns_ls && !(kill_su_issue || kill_re);
assign su_rd_load_type_k = su_rd_load_type && !(kill_su_issue || kill_re);
assign vu_rd_load_k = vu_rd_load && !(kill_su_issue || kill_re);
assign rd_mfc2_k = rd_mfc2 && !(kill_su_issue || kill_re);
assign rd_mtc2_k = rd_mtc2 && !(kill_su_issue || kill_re);
assign rd_cfc2_k = rd_cfc2 && !(kill_su_issue || kill_re);
assign rd_ls_drive_ls_in_wb_k = rd_ls_drive_ls_in_wb && !(kill_su_issue || kill_re);
assign rd_pass_thru_k = rd_pass_thru && !(kill_su_issue || kill_re);
assign su_rd_store_k = su_rd_store && !(kill_su_issue || kill_re);
assign vu_rd_store_k = vu_rd_store && !(kill_su_issue || kill_re);
assign rd_branch_k = rd_branch && !(kill_su_issue || kill_re);
assign rd_br_al_k = rd_br_al && !(kill_su_issue || kill_re);
assign rd_br_type_k = rd_br_type & {6{!(kill_su_issue || kill_re)}};
assign rd_jump_k = rd_jump && !(kill_su_issue || kill_re);
assign rd_broke_k = rd_broke && !(kill_su_issue || kill_re);
assign break_inst_debug = rd_broke_k;
//
// EX stage signals
//
// *** How should functional enables be set at reset? Currently all 0's.
// *** What uses of reset_l can be eliminated?
spasdff_1_0 su_re_break_ff (ex_break, ex_break_n, set_broke, clk, reset_l);
spasdff_5_0 su_re_wr_reg_ff (ex_wr_reg,ex_wr_reg_n, rd_wr_reg, clk,1'b1);
spasdff_1_0 su_re_wr_en_ff (ex_wr_en,ex_wr_en_n, rd_wr_en_k, clk, reset_l);
spasdff_1_0 su_re_sslt_en_ff (ex_sslt_en,ex_sslt_en_n,rd_sslt_en,clk,reset_l);
spasdff_1_0 su_re_uslt_en_ff (ex_uslt_en,ex_uslt_en_n,rd_uslt_en,clk,reset_l);
spasdff_1_0 su_re_alu_en_ff (sualuen,sualuen_n, rd_alu_en, clk, reset_l);
spasdff_1_0 su_re_alu_cin_ff (sualu_cin,sualu_cin_n, rd_alu_cin,clk,reset_l);
spasdff_5_0 su_re_alu_ff (sualu,sualu_n, rd_alu, clk, reset_l);
spasdff_1_0 su_re_alubmux_ff (ex_alubmux_1,ex_alubmux_1_n, rd_alubmux_1, clk, reset_l);
spasdff_1_0 su_re_sh_en_ff (sushen,sushen_n, rd_sh_en, clk, reset_l);
spasdff_1_0 su_re_sh_l_ff (ex_sh_l,ex_sh_l_n, rd_sh_l, clk, reset_l);
spasdff_1_0 su_re_sh_r_ff (ex_sh_r,ex_sh_r_n, rd_sh_r, clk, reset_l);
spasdff_1_0 su_re_sh_ra_ff (ex_sh_ra,ex_sh_ra_n, rd_sh_ra, clk, reset_l);
spasdff_5_0 su_re_sh_amt_ff (ex_sh_amt,ex_sh_amt_n, rd_sh_amt, clk,reset_l);
spasdff_4_0 su_re_elem_ff(elem_num,elem_num_n, su_inst[10:7], clk,reset_l);
spasdff_1_0 su_re_load_ff(su_ex_load,su_ex_load_n, rd_su_load_k, clk,reset_l);
spasdff_1_0 su_re_ldty_ff(su_ex_load_type,su_ex_load_type_n, su_rd_load_type_k,clk,reset_l);
spasdff_1_0 su_re_vu_load_ff(vu_ex_load,vu_ex_load_n,vu_rd_load_k,clk,reset_l);
spasdff_1_0 su_re_mfc2_ff(ex_mfc2,ex_mfc2_n, rd_mfc2_k, clk, reset_l);
spasdff_1_0 su_re_mtc2_ff(ex_mtc2,ex_mtc2_n, rd_mtc2_k, clk, reset_l);
spasdff_1_0 su_re_cfc2_ff(ex_cfc2,ex_cfc2_n, rd_cfc2_k, clk, reset_l);
spasdff_1_0 su_re_lsls_ff(ex_ls_drive_ls_in_wb,ex_ls_drive_ls_in_wb_n, rd_ls_drive_ls_in_wb_k, clk, reset_l);
spasdff_1_0 su_re_pss_ff(ex_pass_thru,ex_pass_thru_n,rd_pass_thru_k,clk,reset_l);
spasdff_1_0 su_re_dma_ff(ex_dma_cycle,ex_dma_cycle_n, rd_dma_cycle, clk, reset_l);
spasdff_1_0 su_re_store_ff(su_ex_store,su_ex_store_n,su_rd_store_k,clk,reset_l);
spasdff_1_0 su_re_vu_st_ff(vu_ex_store,vu_ex_store_n,vu_rd_store_k,clk,reset_l);
spasdff_1_0 su_re_byte_ff(ex_su_byte_ls,ex_su_byte_ls_n,rd_su_byte_ls_k,clk,reset_l);
spasdff_1_0 su_re_half_ff(ex_su_half_ls,ex_su_half_ls_n, rd_su_half_ls_k,clk,reset_l);
spasdff_1_0 su_re_uns_ff(ex_su_uns_ls,ex_su_uns_ls_n,rd_su_uns_ls_k,clk,reset_l);
spasdff_1_0 su_re_branch_ff(ex_branch,ex_branch_n,rd_branch_k,clk, reset_l);
spasdff_1_0 su_re_br_al_ff(ex_br_al,ex_br_al_n, rd_br_al_k, clk, reset_l);
spasdff_6_0 su_re_br_type_ff(ex_br_type,ex_br_type_n,rd_br_type_k,clk,reset_l);
spasdff_1_0 su_re_jump_ff(ex_jump,ex_jump_n, rd_jump_k, clk, reset_l);
assign sualuamux[0] = !ex_branch; // next_pc for br
assign sualuamux[1] = ex_branch;
assign sualubmux[0] = !ex_alubmux_1; // imm_data for l/s/br
assign sualubmux[1] = ex_alubmux_1;
assign sushamux = (ex_jump || ex_br_al) ? 4'b1000 : // link_pc
(ex_sh_r || ex_sh_ra) ? 4'b0100 : // b src
ex_sh_l ? 4'b0010 : // b<0>, zeroes
4'b0001; // a src
assign sushbmux = (ex_sh_ra && suexbsign) ? 3'b100 : // ones
ex_sh_l ? 3'b001 : // b src >> 1
3'b010; // zeroes
assign sushift_s = 1'b0; // 32 bit shift
sp_5_32_decode shift_decode(shiftamt_b, ex_sh_amt);
assign shiftamt = ~shiftamt_b;
// Branch checks
assign taken = ex_jump ||
(ex_br_type[0] && suonesdet_z) || // BEQ
(ex_br_type[1] && !suonesdet_z) || // BNE
(ex_br_type[2] && suexasign) || // < 0
(ex_br_type[3] && suonesdet_z) || // = 0
(ex_br_type[4] && !suexasign && !suonesdet_z); // > 0
// If there's a taken branch in EX, but no adv_ir (or we are halting),
// we need to save the information that there has been a branch and the
// target must be fetched.
spasdff_1_1 su_halt_ff (prev_halt,prev_halt_n, halt, clk, reset_l);
assign imem_dma_ppif = (dma_dm_to_rd || dma_rd_to_dm) && dma_imem_select;
spasdff_1_0 su_pif_idma_ff (imem_dma_pif,imem_dma_pif_n, imem_dma_ppif, clk, reset_l);
spasdff_1_0 su_if_idma_ff (imem_dma_if,imem_dma_if_n, imem_dma_pif, clk, reset_l);
spasdff_1_0 su_idma_ff (imem_dma_rd,imem_dma_rd_n, imem_dma_if, clk, reset_l);
assign imem_dma_cycle = imem_dma_if;
assign start_imem_dma = imem_dma_if && !imem_dma_rd;
assign halting =
(halt && !prev_halt && !ex_break) || // external halt
(!halt && start_imem_dma) || // imem dma starting
rd_broke_k || // break inst encountered
single_step_halt; // single instruction issued
wire delay_slot;
wire set_target_pending;
wire clear_target_pending;
wire wr_target_pending;
wire br_target;
wire old_target_pending;
// This addresses the situation where (following a halted state) a delay
// slot instruction is in RD but is unable to issue, the branch target is
// in IF, and halting is asserted again.
wire if_taken_target;
wire if_taken_target_n;
wire reset_taken;
spasdffen_1_0 su_clr_taken_ff (if_taken_target, if_taken_target_n, clear_taken, pc_wr_en, clk, reset_l);
assign reset_taken = delay_slot && kill_re && if_taken_target && halting;
// Set a flag indicating that a branch condition has been met but the
// pc hasn't yet been loaded with the target pc, because there's a halt
// condition or no pc write enable.
// !clear_taken is because the halt pc can be loaded with the target
// address in the "taken" cycle.
assign set_taken = (taken && !clear_taken && (!pc_wr_en || halting)) || reset_taken;
// Clear old_taken when the target pc gets loaded into the pc:
// pc <- taken || pc <- old_taken || pc <- halt_pc && halt_pc = target addr
// pc_sel[2] || pc_sel[3] || (pc_sel[1] && )
assign clear_taken = !reset_taken && pc_wr_en && // reset_taken should be impossible here
(pc_sel[2] || pc_sel[3] ||
(pc_sel[1] && (
(!(delay_slot && kill_re) && (rd_bubble || (old_target_pending && !br_target))) ||
(delay_slot && !kill_re && taken) ||
(delay_slot && !kill_re && old_taken)
)));
assign wr_taken = set_taken || clear_taken;
spasdffen_1_0 su_taken_ff (old_taken,old_taken_n, set_taken, wr_taken, clk, reset_l);
assign wr_br_addr = taken && (!pc_wr_en || halting);
// Set a flag indicating that the next instruction to be executed is
// a delay slot instruction.
wire set_delay_pending;
wire clear_delay_pending;
wire wr_delay_pending;
// Don't need rd_bubble, because it can't be a branch bubble *and* delay slot:
assign set_delay_pending = delay_slot && kill_re;
// Clear delay_pending when the delay slot instruction gets *issued*
assign clear_delay_pending = !kill_re;
assign wr_delay_pending = set_delay_pending || clear_delay_pending;
spasdffen_1_0 su_delpnd_ff (old_delay_pending,old_delay_pending_n, set_delay_pending, wr_delay_pending, clk, reset_l);
// Set a flag indicating that the next instruction to be issued is a branch
// target.
assign set_target_pending = (br_target || rd_bubble) && kill_re;
assign clear_target_pending = !kill_re;
assign wr_target_pending = set_target_pending || clear_target_pending;
spasdffen_1_0 su_tarpnd_ff (old_target_pending,old_target_pending_n, set_target_pending, wr_target_pending, clk, reset_l);
// Next PC Selection
assign pc_sel[0] = pc_in_wr_en; // pc gets pc_data_in
assign pc_sel[1] = !pc_in_wr_en && halting; // pc gets int_halt_pc
assign pc_sel[2] = !pc_in_wr_en && !halting && taken;
assign pc_sel[3] = !pc_in_wr_en && !halting && !taken && old_taken;
assign pc_sel[4] = !pc_in_wr_en && !halting && !taken && !old_taken;
// SLT checks
// Note, sualu_cout_l is active low.
assign susltlt = (ex_uslt_en && sualu_cout_l) ||
(ex_sslt_en && ((!sualu_ovr && !sualu_cout_l) ||
(!(sualu_ovr ^ !sualu_cout_l) && sualumsb)));
assign suslten = ex_sslt_en || ex_uslt_en;
assign chip_sel = vu_ex_load || su_ex_load || vu_ex_store || su_ex_store;
// *** Move sudrivels computation to RD then delay to EX:
assign sudrivels = su_ex_store || ex_mtc0 || ex_mtc2 ||
ex_ctc2_vc0 || ex_ctc2_vc1 || ex_ctc2_vc2;
//
// DF stage signals
//
spasdff_5_0 su_ed_wr_reg_ff(df_wr_reg,df_wr_reg_n, ex_wr_reg, clk, reset_l);
spasdff_1_0 su_ed_wr_en_ff(df_wr_en,df_wr_en_n, ex_wr_en, clk, reset_l);
spasdff_1_0 su_ed_load_ff(su_df_load,su_df_load_n, su_ex_load, clk, reset_l);
spasdff_1_0 su_ed_ld_ty_ff(su_df_load_type,su_df_load_type_n, su_ex_load_type, clk,reset_l);
spasdff_1_0 vu_ed_load_ff(vu_df_load,vu_df_load_n, vu_ex_load, clk, reset_l);
spasdff_1_0 su_ed_lsls_ff(df_ls_drive_ls_in_wb,df_ls_drive_ls_in_wb_n, ex_ls_drive_ls_in_wb, clk, reset_l);
spasdff_1_0 su_ed_pass_ff(df_pass_thru,df_pass_thru_n,ex_pass_thru,clk,reset_l);
spasdff_1_0 su_ed_dma_ff(df_dma_cycle,df_dma_cycle_n, ex_dma_cycle, clk, reset_l);
//
// WB stage signals
//
spasdff_5_0 su_dw_wr_reg_ff(wb_wr_reg,wb_wr_reg_n, df_wr_reg, clk, reset_l);
// Write to R0 during reset. Purpose is to eliminate x's from QSim log.
wire df_wr_en_r;
assign df_wr_en_r = df_wr_en || !reset_l;
spasdff_1_0 su_dw_wr_en_ff(wb_wr_en,wb_wr_en_n, df_wr_en_r, clk, 1'b1);
spasdff_1_0 su_dw_ld_type_ff(su_wb_load_type,su_wb_load_type_n,su_df_load_type,clk,reset_l);
assign su_mem_wen = su_wb_load_type;
assign suwben = !su_wb_load_type;
regfile_decode regfile_decode_w(wb_wr_reg, surfile_nobar, surfile_bar);
assign surfile_w_bar = ~(surfile_nobar & {32{wb_wr_en}});
rsp_lden32_t surfile_wen_t(
.en_t (surfile_w_t),
.ld_bar (surfile_w_bar),
.clk (clk)
);
rsp_lden32_f surfile_wen_f(
.en_f (surfile_w_f),
.ld_bar (surfile_w_bar),
.clk (clk)
);
/* ********************************************************************** */
suvuctl suvuctl (
.clk (clk),
.reset_l (reset_l),
.su_inst_a (su_inst_a),
.su_inst_b (su_inst_b),
.vu_inst_a (vu_inst_a),
.vu_inst_b (vu_inst_b),
.choose_su_inst_b (choose_su_inst_b),
.choose_vu_inst_b (choose_vu_inst_b),
.kill_re_non_vu (kill_re_non_vu),
.kill_su_issue (kill_su_issue),
.kill_vu_issue (kill_vu_issue),
.elem_num (elem_num),
.vu_comp_k (vu_comp_k),
.vu_reg_hazard_comp (vu_reg_hazard_comp),
.vu_reg_hazard_ls (vu_reg_hazard_ls),
.vu_func (vu_func),
.vu_elem (vu_elem),
.vu_ld_addr (vu_ld_addr),
.vu_st_addr (vu_st_addr),
.vu_st_xpose_addr (vu_st_xpose_addr),
.ex_ctc2_vc0 (ex_ctc2_vc0),
.ex_ctc2_vc1 (ex_ctc2_vc1),
.ex_ctc2_vc2 (ex_ctc2_vc2),
.vu_rd_store_type_k (vu_rd_store_type_k),
.vu_rd_storecfc2_k (vu_rd_storecfc2_k),
.rd_cfvc0_k (rd_cfvc0_k),
.rd_cfvc1_k (rd_cfvc1_k),
.rd_cfvc2_k (rd_cfvc2_k),
.acc_wr_reg (acc_wr_reg),
.acc_wr_en (acc_wr_en),
.xpose (xpose)
);
issue issue (
.clk (clk),
.reset_l (reset_l),
.halt (halt),
.single_step (single_step),
.pc_in_wr_en (pc_in_wr_en),
.pc_data_in (pc_data_in),
.pc_sel (pc_sel),
.halting (halting),
.br_addr (br_addr),
.rd_inst (rd_inst),
.set_broke (set_broke),
.wr_br_addr (wr_br_addr),
.imem_dma_pif (imem_dma_pif),
.taken (taken),
.old_taken (old_taken),
.adv_ir (adv_ir),
.kill_re (kill_re),
.should_have_stalled (should_have_stalled),
.old_delay_pending (old_delay_pending),
.clear_target_pending (clear_target_pending),
.old_target_pending (old_target_pending),
.su_inst_a (su_inst_a),
.su_inst_b (su_inst_b),
.vu_inst_a (vu_inst_a),
.vu_inst_b (vu_inst_b),
.choose_su_inst_b (choose_su_inst_b),
.choose_vu_inst_b (choose_vu_inst_b),
.su_nop_debug (su_nop_debug),
.vu_nop_debug (vu_nop_debug),
.link_pc_delay_pc (link_pc_delay_pc),
.pc (pc),
.pc_wr_en (pc_wr_en),
.rd_bubble (rd_bubble),
.br_target (br_target),
.delay_slot (delay_slot),
.imem_stall (imem_stall),
.start_ext_halt (start_ext_halt),
.kill_su_issue (kill_su_issue),
.kill_vu_issue (kill_vu_issue),
.vu_comp (vu_comp),
.vs (vs),
.vs_eq_one (vs_eq_one),
.rd_pre_vt (rd_pre_vt),
.vt_sel (vt_sel),
.su_rd_pc_debug (su_rd_pc_debug),
.vu_rd_pc_debug (vu_rd_pc_debug)
);
/* ********************************************************************** */
// CP0 Control
assign rd_mtc0 = (opc[5:4]==2'b01) && (opc[1]==1'b0) &&
(rs[4]==0) && (rs[2:1]==2'b10);
assign rd_mtc0_k = rd_mtc0 && !(kill_su_issue || kill_re);
spasdff_1_0 su_re_mtc0_ff(ex_mtc0,ex_mtc0_n, rd_mtc0_k, clk, reset_l);
spasdff_4_0 su_re_c0_addr_ff(cp0_address,cp0_address_n, rd[3:0], clk, reset_l);
assign cp0_write = ex_mtc0;
assign cp0_enable = !ex_mtc0 && !halt;
assign rd_mfc0 = (opc[5:4]==2'b01) && (opc[1]==1'b0) &&
(rs[4]==0) && (rs[2:1]==2'b00);
assign rd_mfc0_k = rd_mfc0 && !(kill_su_issue || kill_re);
spasdff_1_0 su_re_mfc0_ff(ex_mfc0,ex_mfc0_n, rd_mfc0_k, clk, reset_l);
/* ********************************************************************** */
endmodule