/
FISA64.v
3560 lines (3378 loc) · 90.6 KB
/
FISA64.v
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
// ============================================================================
// FISA64.v
// __
// \\__/ o\ (C) 2015 Robert Finch, Stratford
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// 106MHz without multiply (include as a multi-cycle path)
// ============================================================================
//
`define TRUE 1'b1
`define FALSE 1'b0
//`define DEBUG_COP 1'b1
//`define FLOAT 1'b1
`define RR 7'h02
`define BTFLD 7'h03
`define BFSET 3'd0
`define BFCLR 3'd1
`define BFCHG 3'd2
`define BFINS 3'd3
`define BFINSI 3'd4
`define BFEXT 3'd5
`define BFEXTU 3'd6
`define NAND 7'h00
`define NOR 7'h01
`define ENOR 7'h02
`define ADD 7'h04
`define SUB 7'h05
`define CMP 7'h06
`define MUL 7'h07
`define DIV 7'h08
`define MOD 7'h09
`define LDI 7'h0A
`define NOT 7'h0A
`define MOV 7'h0B
`define CHKI 7'h0B
`define AND 7'h0C
`define OR 7'h0D
`define EOR 7'h0E
`define SXB 7'h10
`define SXC 7'h11
`define SXH 7'h12
`define IMM41 7'h13
`define ADDU 7'h14
`define SUBU 7'h15
`define CMPU 7'h16
`define MULU 7'h17
`define DIVU 7'h18
`define MODU 7'h19
`define LDFI 7'h1A
`define CHK 7'h1A
`define MTFP 7'h1C
`define MV2FLT 7'h1D
`define MTSPR 7'h1E
`define MFSPR 7'h1F
`define IMM10 7'b001000x
`define MOV2 7'b010000x
`define ADDQ 7'h22
`define BRAS 7'h23
`define MYST 7'h24
`define RTL 7'h27
`define FADD 7'h28
`define FSUB 7'h29
`define FCMP 7'h2A
`define FMUL 7'h2B
`define FDIV 7'h2C
`define RTS2 7'h30
`define PUSHPOP 7'h31
`define BEQS 7'h32
`define BNES 7'h33
`define LDIQ 7'h34
`define SYS 7'h35
`define PCTRL2 7'h36
`define NOP2 9'd0
`define STP2 9'd1
`define WAI2 9'd2
`define INT3 9'd3
`define CLI2 9'd4
`define SEI2 9'd5
`define RTI2 9'd6
`define RTE2 9'd7
`define RTD2 9'd8
`define RTL2 7'h37
`define BRK 7'h38
`define BSR 7'h39
`define BRA 7'h3A
`define RTS 7'h3B
`define JAL 7'h3C
`define Bcc 7'h3D
`define BEQ 3'h0
`define BNE 3'h1
`define BGT 3'h2
`define BGE 3'h3
`define BLT 3'h4
`define BLE 3'h5
`define BUN 3'h6
`define JALI 7'h3E
`define NOP 7'h3F
`define SLL 7'h30
`define SRL 7'h31
`define ROL 7'h32
`define ROR 7'h33
`define SRA 7'h34
`define CPUID 7'h36
`define PCTRL 7'h37
`define CLI 5'd0
`define SEI 5'd1
`define STP 5'd2
`define WAI 5'd3
`define EIC 5'd4
`define DIC 5'd5
`define SRI 5'd8
`define FIP 5'd10
`define RTD 5'd29
`define RTE 5'd30
`define RTI 5'd31
`define SLLI 7'h38
`define SRLI 7'h39
`define ROLI 7'h3A
`define RORI 7'h3B
`define SRAI 7'h3C
`define FENCE 7'h40
`define LB 7'h40
`define LBU 7'h41
`define LC 7'h42
`define LCU 7'h43
`define LH 7'h44
`define LHU 7'h45
`define LW 7'h46
`define LEA 7'h47
`define LBX 7'h48
`define LBUX 7'h49
`define LCX 7'h4A
`define LCUX 7'h4B
`define LHX 7'h4C
`define LHUX 7'h4D
`define LWX 7'h4E
`define LEAX 7'h4F
`define LFD 7'h51
`define LFDX 7'h59
`define LWAR 7'h5C
`define SUI 7'h5F
`define SB 7'h60
`define SC 7'h61
`define SH 7'h62
`define SW 7'h63
`define INC 7'h64
`define PEA 7'h65
`define PMW 7'h66
`define SBX 7'h68
`define SCX 7'h69
`define SHX 7'h6A
`define SWX 7'h6B
`define CAS 7'h6C
`define SWCR 7'h6E
`define INCX 7'h6F
`define SFD 7'h71
`define SFDX 7'h75
`define FIX2FLT 7'h60
`define FLT2FIX 7'h61
`define FMOV 7'h62
`define FNEG 7'h63
`define FABS 7'h64
`define MFFP 7'h65
`define MV2FIX 7'h66
`define IMM 7'b1111xxx
`define CR0 8'd00
`define CR3 8'd03
`define TICK 8'd04
`define CLK 8'd06
`define DBPC 8'd07
`define IPC 8'd08
`define EPC 8'd09
`define VBR 8'd10
`define BEAR 8'd11
`define VECNO 8'd12
`define SR 8'd13
`define MULH 8'd14
`define ISP 8'd15
`define DSP 8'd16
`define ESP 8'd17
`define FPSCR 8'd20
`define EA 8'd40
`define TAGS 8'd41
`define LOTGRP 8'd42
`define CASREG 8'd44
`define MYSTREG 8'd45
`define DBAD0 8'd50
`define DBAD1 8'd51
`define DBAD2 8'd52
`define DBAD3 8'd53
`define DBCTRL 8'd54
`define DBSTAT 8'd55
//0000_0011_1100_1110_00001111_00111000;
//03cc0f38
`define BRK_BND {6'd0,9'd487,5'd0,5'h1E,`BRK}
`define BRK_DBZ {6'd0,9'd488,5'd0,5'h1E,`BRK}
`define BRK_OFL {6'd0,9'd489,5'd0,5'h1E,`BRK}
`define BRK_FLT {6'd0,9'd493,5'd0,5'h1E,`BRK}
`define BRK_TAP {2'b01,4'd0,9'd494,5'd0,5'h1E,`BRK}
`define BRK_SSM {2'b01,4'd0,9'd495,5'd0,5'h1E,`BRK}
`define BRK_BPT {2'b01,4'd0,9'd496,5'd0,5'h1E,`BRK}
`define BRK_EXF {6'd0,9'd497,5'd0,5'h1E,`BRK}
`define BRK_DWF {6'd0,9'd498,5'd0,5'h1E,`BRK}
`define BRK_DRF {6'd0,9'd499,5'd0,5'h1E,`BRK}
`define BRK_PRV {6'd0,9'd501,5'd0,5'h1E,`BRK}
`define BRK_DBE {1'b1,5'd0,9'd508,5'd0,5'h1E,`BRK}
`define BRK_IBE {1'b1,5'd0,9'd509,5'd0,5'h1E,`BRK}
`define BRK_NMI {1'b1,5'd0,9'd510,5'd0,5'h1E,`BRK}
`define BRK_IRQ {1'b1,5'd0,vect_i,5'd0,5'h1E,`BRK}
module FISA64(rack_num,box_num,board_num,chip_num,core_num,
rst_i, clk_i, clk3x_i, clk_o, nmi_i, irq_i, vect_i, sri_o, bte_o, cti_o, bl_o,
cyc_o, stb_o, ack_i, err_i, we_o, sel_o, adr_o, dat_i, dat_o, sr_o, cr_o, rb_i,
tap_i, tap_o);
parameter AMSB = 31; // most significant address bit
input [15:0] rack_num;
input [7:0] box_num;
input [7:0] board_num;
input [7:0] chip_num;
input [15:0] core_num;
input rst_i;
input clk_i;
input clk3x_i;
output clk_o; // gated clock output
input nmi_i;
input irq_i;
input [8:0] vect_i;
output reg sri_o;
output reg [1:0] bte_o;
output reg [2:0] cti_o;
output reg [5:0] bl_o;
output reg cyc_o;
output reg stb_o;
input ack_i;
input err_i;
output reg we_o;
output reg [7:0] sel_o;
output reg [AMSB:0] adr_o;
input [63:0] dat_i;
output reg [63:0] dat_o;
output reg sr_o;
output reg cr_o;
input rb_i;
input tap_i;
output tap_o;
parameter TRUE = 1'b1;
parameter FALSE = 1'b0;
parameter RESET = 6'd1;
parameter IFETCH1 = 6'd2;
parameter IFETCH2 = 6'd3;
parameter DECODE = 6'd4;
parameter EXECUTE = 6'd5;
parameter LOAD0 = 6'd7;
parameter LOAD1 = 6'd8;
parameter LOAD2 = 6'd9;
parameter LOAD3 = 6'd10;
parameter LOAD4 = 6'd11;
parameter LOAD5 = 6'd12;
parameter INC = 6'd16;
parameter STORE1 = 6'd17;
parameter STORE2 = 6'd18;
parameter STORE3 = 6'd19;
parameter STORE4 = 6'd20;
parameter STORE5 = 6'd21;
parameter LOAD_ICACHE = 6'd22;
parameter LOAD_ICACHE2 = 6'd23;
parameter LOAD_ICACHE3 = 6'd24;
parameter LOAD_ICACHE4 = 6'd25;
parameter RUN = 6'd26;
parameter PEA = 6'd27;
parameter PMW = 6'd28;
parameter CAS = 6'd29;
parameter MULDIV = 6'd32;
parameter MULT1 = 6'd33;
parameter MULT2 = 6'd34;
parameter MULT3 = 6'd35;
parameter DIV = 6'd36;
parameter FIX_SIGN = 6'd37;
parameter MD_RES = 6'd38;
parameter FLT1 = 6'd39;
parameter FLT2 = 6'd40;
parameter FLT3 = 6'd41;
parameter LOAD_ICACHE5 = 6'd42;
parameter LOAD_ICACHE6 = 6'd43;
parameter LOAD_ICACHE7 = 6'd44;
parameter LOAD_ICACHE8 = 6'd45;
parameter byt = 2'd0;
parameter half = 2'd1;
parameter char = 2'd2;
parameter word = 2'd3;
parameter regTR = 6'd24;
parameter regSP = 6'd30;
parameter regLR = 6'd31;
wire clk;
reg [5:0] state;
reg [63:0] tick; // tick counter
reg [AMSB:0] vbr; // vector base register
reg [63:0] casreg; // compare-and-swap compare register
reg [6:0] mystreg;
reg [49:0] clk_throttle_new;
reg [63:0] dbctrl,dbstat; // debug control, debug status
reg [AMSB:0] dbad0,dbad1,dbad2,dbad3; // debug address
reg [AMSB:0] bear; // bus error address register
reg ssm; // single step mode
reg km; // kernel mode
wire im = status_reg[16];
reg [63:0] status_reg;
reg [63:0] cr0;
wire pe = cr0[0]; // protected mode enabled
wire bpe = cr0[32]; // branch predictor enable
wire ice = cr0[30]; // instruction cache enable
wire rb = cr0[36];
wire ovf_xe = cr0[40]; // overflow exception enable
wire dbz_xe = cr0[41]; // divide by zero exception enable
reg [2:0] imcd; // interrupt enable count down
reg [1:0] sscd; // single step count down
reg [8:0] vecno;
reg tapi1;
reg tap_nmi_edge;
reg tam; // test access mode
reg [AMSB:0] pc,dpc,xpc,wpc;
reg [AMSB:0] epc,ipc,dbpc; // exception, interrupt PC's, debug PC
reg [AMSB:0] isp,dsp,esp; // stack pointer save areas
reg gie; // global interrupt enable
reg StatusHWI;
reg [AMSB:0] ibufadr;
reg [31:0] ibuf;
wire ibufhit = pc[AMSB:1]==ibufadr[AMSB:1];
reg [63:0] regfile [63:0];
reg [63:0] sp,usp;
reg [63:0] sp_inc;
reg [31:0] ir,xir,mir,wir;
wire [95:0] insn96;
reg [31:0] insn;
reg [3:0] pc_inc,dpc_inc,xpc_inc;
reg [63:0] imm64,imm64a;
function [3:0] insnsz;
input [31:0] insn;
insnsz = ((insn[6:3]==4'd6 || insn[6:1]==6'b010000 || insn[6:0]==`ADDQ || insn[6:0]==`BRAS || insn[6:1]==6'b001000) ? 64'd2 : 64'd4);
endfunction
always @(insn96)
casex(insn96[6:0])
7'b001000x:
begin // IMM10
insn <= insn96[47:16];
pc_inc <= 4'd6;
imm64 <= {{39{insn96[15]}},insn96[15:7],insn96[0],insn96[47:33]};
end
`IMM41:
begin // IMM41
insn <= insn96[79:48];
pc_inc <= 4'd10;
imm64 <= {{8{insn96[47]}},insn96[47:7],insn96[79:65]};
end
7'b1111xxx:
if (insn96[38:35]==4'hF) begin // double prefix
insn <= insn96[95:64];
pc_inc <= 4'd12;
imm64 <= {insn96[31:7],insn96[2:0],insn96[63:39],insn96[34:32],insn96[95:81]};
end
else begin // IMM28
insn <= insn96[63:32];
pc_inc <= 4'd8;
imm64 <= {{21{insn96[31]}},insn96[31:7],insn96[2:0],insn96[63:49]};
end
default:
begin
insn <= insn96[31:0];
pc_inc <= insnsz(insn96[31:0]);
imm64 <= {{49{insn96[31]}},insn96[31:17]};
end
endcase
wire [31:0] iir = ice ? insn : ibuf;
wire [6:0] iopcode = iir[6:0];
wire [6:0] opcode = ir[6:0];
wire [6:0] ifunct = iir[31:25];
wire [6:0] funct = ir[31:25];
reg [6:0] xfunct,mfunct,mdfunct,x1funct;
reg [6:0] xopcode,mopcode,wopcode,mdopcode,x1opcode;
wire fltRega = (opcode==`RR && funct[6:4]==3'd6) ||
opcode==`FADD || opcode==`FSUB || opcode==`FCMP || opcode==`FMUL || opcode==`FDIV ||
(opcode==`PUSHPOP && ir[12]==1'b1);
wire fltRegb = (opcode==`RR && funct[6:4]==3'd6) || opcode==`FADD || opcode==`FSUB || opcode==`FCMP || opcode==`FMUL || opcode==`FDIV;
wire fltRegc = (opcode==`RR && funct[6:4]==3'd6) || opcode==`SFD || opcode==`SFDX;
wire isPush = (opcode==`PUSHPOP && ir[15:13]==3'd0)||opcode==`PEA||opcode==`PMW;
wire isPop = (opcode==`PUSHPOP && ir[15:13]==3'd1);
wire isRts = opcode==`RTS2 || opcode==`RTS;
wire isRtl = opcode==`RTL2 || opcode==`RTL;
wire [5:0] Ra = (isPop|isRts|isRtl) ? regSP : {fltRega,ir[11:7]};
wire [5:0] Rb = {fltRegb,ir[21:17]};
wire [5:0] Rc = isPush ? regSP : isRtl ? regLR : {fltRegc,ir[16:12]};
reg [5:0] xRt,mRt,wRt,tRt,uRt;
reg xRt2,wRt2,tRt2;
reg [63:0] rfoa,rfob,rfoc;
reg [63:0] res,res2,ea,xres,mres,wres,lres,md_res,wres2,tres,tres2,ures;
reg mc_done;
always @*
case(Ra)
6'd0: rfoa <= 64'd0;
xRt: rfoa <= res;
wRt: rfoa <= wres;
tRt: rfoa <= tres;
uRt: rfoa <= ures;
regSP: if (xRt2)
rfoa <= res2;
else if (wRt2)
rfoa <= wres2;
else if (tRt2)
rfoa <= tres2;
else
rfoa <= sp;
default: rfoa <= regfile[Ra];
endcase
always @*
case(Rb)
6'd0: rfob <= 64'd0;
xRt: rfob <= res;
wRt: rfob <= wres;
tRt: rfob <= tres;
uRt: rfob <= ures;
regSP: if (xRt2)
rfob <= res2;
else if (wRt2)
rfob <= wres2;
else if (tRt2)
rfob <= tres2;
else
rfob <= sp;
default: rfob <= regfile[Rb];
endcase
always @*
case(Rc)
6'd0: rfoc <= 64'd0;
xRt: rfoc <= res;
wRt: rfoc <= wres;
tRt: rfoc <= tres;
uRt: rfoc <= ures;
regSP: if (xRt2)
rfoc <= res2;
else if (wRt2)
rfoc <= wres2;
else if (tRt2)
rfoc <= tres2;
else
rfoc <= sp;
default: rfoc <= regfile[Rc];
endcase
reg [63:0] a,b,c,imm,xb;
wire [63:0] pa = a[63] ? -a : a;
reg [63:0] aa,bb;
reg [63:0] q,r;
reg [127:0] p;
wire [127:0] p1 = aa * bb;
wire [63:0] diff = r - bb;
reg [6:0] cnt;
reg res_sgn;
reg [1:0] ld_size, st_size;
reg [31:0] insncnt;
reg [3:0] sri_cnt;
// Detect multi-cycle operation.
function fnIsMC;
input [31:0] ir;
input [6:0] opcode;
input [6:0] funct;
case(opcode)
`RR:
case(funct)
`MUL,`MULU,`DIV,`DIVU,`MOD,`MODU: fnIsMC = TRUE;
`FIX2FLT,`FLT2FIX,`MV2FIX,`MV2FLT: fnIsMC = TRUE;
default: fnIsMC = FALSE;
endcase
`PCTRL2:
case(ir[15:7])
`INT3: fnIsMC = TRUE;
default: fnIsMC = FALSE;
endcase
`BRK,`SYS,
`MUL,`MULU,`DIV,`DIVU,`MOD,`MODU,
`PUSHPOP,
`PMW,`PEA,`RTS,`RTS2,
`LB,`LBU,`LC,`LCU,`LH,`LHU,`LW,`LWAR,`INC,`CAS,`JALI,`INCX,
`LBX,`LBUX,`LCX,`LCUX,`LHX,`LHUX,`LWX,
`SB,`SC,`SH,`SW,`SWCR,`SBX,`SCX,`SHX,`SWX,
`FADD,`FSUB,`FMUL,`FDIV,`FCMP,
`LFD,`LFDX,`SFD,`SFDX
:
fnIsMC = TRUE;
default: fnIsMC = FALSE;
endcase
endfunction
wire iihit;
wire advanceEX = !fnIsMC(xir,xopcode,xfunct);
wire advanceWB = (xRt!=6'd0 || xRt2) && advanceEX;
wire advanceTL = advanceWB;
wire advanceRF = advanceEX;
wire advanceIF = advanceRF & iihit;
//-----------------------------------------------------------------------------
// Instruction Cache
//-----------------------------------------------------------------------------
reg isICacheReset;
reg isICacheLoad;
wire [31:0] dbg_insn;
wire ihit,ihit2;
assign iihit = (ice ? ihit&ihit2 : ibufhit);
reg utg; // update cache tag
reg [AMSB:0] tagadr;
FISA64_icache_ram u1
(
.wclk(clk),
.wa(adr_o[12:0]),
.wr(isICacheLoad & (ack_i|err_i)),
.i(err_i ? {2{`BRK_IBE}} : dat_i),
.rclk(~clk),
.pc(pc[12:0]),
.insn(insn96)
);
FISA64_itag_ram u2
(
.wclk(clk),
.wa(tagadr),
.v(!isICacheReset),
.wr(utg|isICacheReset),
.rclk(~clk),
.pc(pc),
.hit(ihit),
.hit2(ihit2)
);
//-----------------------------------------------------------------------------
// Debug (not working yet)
// The debug system is a processor on it's own.
// It's capable of loading a program via the test access point port into the
// debug sandbox. It can then generate a tap interrupt to the cpu. The master
// cpu will then execute the code in the debug sandbox. The sandbox is
// exited with a RTD instruction.
// ToDo: add a PIO port so the debug processor can control things.
//-----------------------------------------------------------------------------
reg d63,x63,w63;
reg tap_nmi;
`ifdef DEBUG_COP
reg dbg_ram_ack,dbg_rom_ack,dbg_ser_ack;
wire dbg16_cyc,dbg16_stb,dbg16_we;
wire [23:0] dbg16_adr;
wire [15:0] dbg16_dato;
reg [15:0] dbg16_dati;
wire [15:0] dbg_ramoL,dbg_ramoH,dbg16_insn,dr16_dato;
wire [7:0] dbg_ser_dato;
wire cs_dbg_iram = dbg16_cyc && dbg16_stb && dbg16_adr[23:12]==12'h00F; // places ram at $F000
wire cs_dbg_irom = dbg16_cyc && dbg16_stb && dbg16_adr[23:16]==8'h1; // places rom at $10000
wire cs_dbg_pio = dbg16_cyc && dbg16_stb && dbg16_adr[23:8]==16'h00D0; // Uart is at $E000
wire cs_dbg_dram = dbg16_cyc && dbg16_stb && dbg16_adr[23:15]==9'h000; // readback ram at $0000 to $3FFF
wire cs_cpu_dram = cyc_o && stb_o && adr_o[AMSB:16]==16'hFFE0;
always @(posedge clk_i)
if (rst)
dbg_ram_ack <= 1'b0;
else
dbg_ram_ack <= cs_dbg_iram & ~dbg_ram_ack;
always @(posedge clk_i)
if (rst)
dbg_rom_ack <= 1'b0;
else
dbg_rom_ack <= cs_dbg_irom & ~dbg_rom_ack;
always @*
if (cs_dbg_iram && ~dbg16_adr[1])
dbg16_dati <= dbg_ramoL;
else if (cs_dbg_iram && dbg16_adr[1])
dbg16_dati <= dbg_ramoH;
else if (cs_dbg_irom)
dbg16_dati <= dbg16_insn;
else if (cs_dbg_dram)
dbg16_dati <= dr16_dato;
else
dbg16_dati <= dbg_ser_dato;
always @(posedge clk_i)
if (rst)
tap_nmi <= FALSE;
else begin
if (cs_dbg_pio) begin
tap_nmi <= dbg16_dato[0];
end
end
assign dbg16_acki = dbg_ram_ack|dbg_rom_ack|dbg_ser_ack|cs_dbg_dram;
FISA64_debug_iram u8
(
.wclk(clk_i),
.rwa(dbg16_adr[11:0]),
.wr(cs_dbg_ram && dbg16_we && ~dbg16_adr[1]),
.i(dbg16_dato),
.o(dbg_ramoL),
.rclk(clk3x_i),
.pc(pc),
.insn(dbg_insn[15:0])
);
FISA64_debug_iram u9
(
.wclk(clk_i),
.rwa(dbg16_adr[11:0]),
.wr(cs_dbg_ram && dbg16_we && dbg16_adr[1]),
.i(dbg16_dato),
.o(dbg_ramoH),
.rclk(clk3x_i),
.pc(pc),
.insn(dbg_insn[31:16])
);
FISA64_debug_dram
(
.wclk(clk),
.rwa(adr_o[13:0]),
.wr(we_o && cs_cpu_dram),
.sel(sel_o),
.i(dat_o),
.o(),
.rclk(clk3x_i),
.ea(dbg16_adr[13:0]),
.dat(dr16_dato)
);
FISA64_debug_rom u10
(
.clk(clk3x_i),
.pc(dbg16_adr[11:0]),
.insn(dbg16_insn)
);
dbg16 u11
(
.rst_i(rst),
.clk_i(clk_i),
.cyc_o(dbg16_cyc),
.stb_o(dbg16_stb),
.ack_i(dbg16_acki),
.we_o(dbg16_we),
.adr_o(dbg16_adr),
.dat_i(dbg16_dati),
.dat_o(dbg16_dato)
);
rtfSimpleUart #(.pIOAddress(32'hFFDCE000)) u12
(
.rst_i(rst), // reset
.clk_i(clk_i), // eg 100.7MHz
.cyc_i(dbg16_cyc), // cycle valid
.stb_i(dbg16_stb), // strobe
.we_i(dbg16_we), // 1 = write
.adr_i({16'hFFDC,dbg16_adr[15:0]}), // register address
.dat_i(dbg16_dato[7:0]), // data input bus
.dat_o(dbg_ser_dato), // data output bus
.ack_o(dbg_ser_ack), // transfer acknowledge
.vol_o(), // volatile register selected
.irq_o(), // interrupt request
//----------------
.cts_ni(), // clear to send - active low - (flow control)
.rts_no(), // request to send - active low - (flow control)
.dsr_ni(), // data set ready - active low
.dcd_ni(), // data carrier detect - active low
.dtr_no(), // data terminal ready - active low
.rxd_i(tap_i), // serial data in
.txd_o(tap_o), // serial data out
.data_present_o()
);
`endif
//-----------------------------------------------------------------------------
// Memory management stuff.
//-----------------------------------------------------------------------------
reg [AMSB:0] rpc; // registered PC value
always @(negedge clk)
rpc <= pc;
reg [15:0] lottags [2047:0];
always @(posedge clk)
if (advanceEX && xopcode==`RR && xfunct==`MTSPR && xir[24:17]==`TAGS)
lottags[ea[26:16]] <= a[15:0];
wire [15:0] lottag = (ea[31:20]==12'hFFD) ? 16'h0006 : lottags[ea[26:16]]; // allow for I/O
wire [15:0] lottagX = (ea[31:20]==12'hFFD) ? 16'h0000 : lottags[rpc[26:16]];
reg [9:0] lotgrp [5:0];
wire isLotOwner = km | (((lotgrp[0]==lottag[15:6]) ||
(lotgrp[1]==lottag[15:6]) ||
(lotgrp[2]==lottag[15:6]) ||
(lotgrp[3]==lottag[15:6]) ||
(lotgrp[4]==lottag[15:6]) ||
(lotgrp[5]==lottag[15:6])))
;
wire isLotOwnerX = km | (((lotgrp[0]==lottagX[15:6]) ||
(lotgrp[1]==lottagX[15:6]) ||
(lotgrp[2]==lottagX[15:6]) ||
(lotgrp[3]==lottagX[15:6]) ||
(lotgrp[4]==lottagX[15:6]) ||
(lotgrp[5]==lottagX[15:6])))
;
//-----------------------------------------------------------------------------
// Debug
//-----------------------------------------------------------------------------
wire db_imatch0 = (dbctrl[0] && dbctrl[17:16]==2'b00 && pc[AMSB:1]==dbad0[AMSB:1]);
wire db_imatch1 = (dbctrl[1] && dbctrl[21:20]==2'b00 && pc[AMSB:1]==dbad1[AMSB:1]);
wire db_imatch2 = (dbctrl[2] && dbctrl[25:24]==2'b00 && pc[AMSB:1]==dbad2[AMSB:1]);
wire db_imatch3 = (dbctrl[3] && dbctrl[29:28]==2'b00 && pc[AMSB:1]==dbad3[AMSB:1]);
wire db_imatch = db_imatch0|db_imatch1|db_imatch2|db_imatch3;
wire db_lmatch0 =
dbctrl[0] && dbctrl[17:16]==2'b11 && ea[AMSB:3]==dbad0[AMSB:3] &&
((dbctrl[19:18]==2'b00 && ea[2:0]==dbad0[2:0]) ||
(dbctrl[19:18]==2'b01 && ea[2:1]==dbad0[2:1]) ||
(dbctrl[19:18]==2'b10 && ea[2]==dbad0[2]) ||
dbctrl[19:18]==2'b11)
;
wire db_lmatch1 =
dbctrl[1] && dbctrl[21:20]==2'b11 && ea[AMSB:3]==dbad1[AMSB:3] &&
((dbctrl[23:22]==2'b00 && ea[2:0]==dbad1[2:0]) ||
(dbctrl[23:22]==2'b01 && ea[2:1]==dbad1[2:1]) ||
(dbctrl[23:22]==2'b10 && ea[2]==dbad1[2]) ||
dbctrl[23:22]==2'b11)
;
wire db_lmatch2 =
dbctrl[2] && dbctrl[25:24]==2'b11 && ea[AMSB:3]==dbad2[AMSB:3] &&
((dbctrl[27:26]==2'b00 && ea[2:0]==dbad2[2:0]) ||
(dbctrl[27:26]==2'b01 && ea[2:1]==dbad2[2:1]) ||
(dbctrl[27:26]==2'b10 && ea[2]==dbad2[2]) ||
dbctrl[27:26]==2'b11)
;
wire db_lmatch3 =
dbctrl[3] && dbctrl[29:28]==2'b11 && ea[AMSB:3]==dbad3[AMSB:3] &&
((dbctrl[31:30]==2'b00 && ea[2:0]==dbad3[2:0]) ||
(dbctrl[31:30]==2'b01 && ea[2:1]==dbad3[2:1]) ||
(dbctrl[31:30]==2'b10 && ea[2]==dbad3[2]) ||
dbctrl[31:30]==2'b11)
;
wire db_lmatch = db_lmatch0|db_lmatch1|db_lmatch2|db_lmatch3;
wire db_smatch0 =
dbctrl[0] && dbctrl[17:16]==2'b01 && ea[AMSB:3]==dbad0[AMSB:3] &&
((dbctrl[19:18]==2'b00 && ea[2:0]==dbad0[2:0]) ||
(dbctrl[19:18]==2'b01 && ea[2:1]==dbad0[2:1]) ||
(dbctrl[19:18]==2'b10 && ea[2]==dbad0[2]) ||
dbctrl[19:18]==2'b11)
;
wire db_smatch1 =
dbctrl[1] && dbctrl[21:20]==2'b01 && ea[AMSB:3]==dbad1[AMSB:3] &&
((dbctrl[23:22]==2'b00 && ea[2:0]==dbad1[2:0]) ||
(dbctrl[23:22]==2'b01 && ea[2:1]==dbad1[2:1]) ||
(dbctrl[23:22]==2'b10 && ea[2]==dbad1[2]) ||
dbctrl[23:22]==2'b11)
;
wire db_smatch2 =
dbctrl[2] && dbctrl[25:24]==2'b01 && ea[AMSB:3]==dbad2[AMSB:3] &&
((dbctrl[27:26]==2'b00 && ea[2:0]==dbad2[2:0]) ||
(dbctrl[27:26]==2'b01 && ea[2:1]==dbad2[2:1]) ||
(dbctrl[27:26]==2'b10 && ea[2]==dbad2[2]) ||
dbctrl[27:26]==2'b11)
;
wire db_smatch3 =
dbctrl[3] && dbctrl[29:28]==2'b01 && ea[AMSB:3]==dbad3[AMSB:3] &&
((dbctrl[31:30]==2'b00 && ea[2:0]==dbad3[2:0]) ||
(dbctrl[31:30]==2'b01 && ea[2:1]==dbad3[2:1]) ||
(dbctrl[31:30]==2'b10 && ea[2]==dbad3[2]) ||
dbctrl[31:30]==2'b11)
;
wire db_smatch = db_smatch0|db_smatch1|db_smatch2|db_smatch3;
wire db_stat0 = db_imatch0 | db_lmatch0 | db_smatch0;
wire db_stat1 = db_imatch1 | db_lmatch1 | db_smatch1;
wire db_stat2 = db_imatch2 | db_lmatch2 | db_smatch2;
wire db_stat3 = db_imatch3 | db_lmatch3 | db_smatch3;
//-----------------------------------------------------------------------------
// Floating point modules.
//-----------------------------------------------------------------------------
reg dbl_overflow_xe;
reg dbl_underflow_xe;
reg dbl_invalid_op_xe;
reg dbl_divide_by_zero_xe;
reg dbl_overflow_xo;
reg dbl_underflow_xo;
reg dbl_invalid_op_xo;
reg dbl_divide_by_zero_xo;
reg dbl_g_xo;
reg dbl_overflow;
reg dbl_underflow;
reg dbl_invalid_op;
reg dbl_divide_by_zero;
reg dbl_zerozero;
reg dbl_infdiv;
wire d_zero = lres[62:0]==63'd0;
wire d_neg = lres[63] & ~d_zero;
wire d_pos = ~lres[63] & ~d_zero;
wire d_nan = lres[62:52]==11'h7FF;
reg dbl_neg;
reg dbl_pos;
reg dbl_zero;
reg dbl_nan;
reg faddsub_operation_nd;
wire [63:0] faddsub_result;
wire faddsub_operation_rfd;
wire faddsub_invalid_op;
wire faddsub_rdy;
reg fmul_operation_nd;
wire [63:0] fmul_result;
wire fmul_operation_rfd;
wire fmul_invalid_op;
wire fmul_rdy;
reg fdiv_operation_nd;
wire [63:0] fdiv_result;
wire fdiv_operation_rfd;
wire fdiv_invalid_op;
wire fdiv_rdy;
reg fix2flt_operation_nd;
wire [63:0] fix2flt_result;
wire fix2flt_operation_rfd;
wire fix2flt_rdy;
reg flt2fix_operation_nd;
wire [63:0] flt2fix_result;
wire flt2fix_operation_rfd;
wire flt2fix_invalid_op;
wire flt2fix_rdy;
reg fcmp_operation_nd;
wire [3:0] fcmp_result;
wire fcmp_operation_rfd;
wire fcmp_invalid_op;
wire fcmp_rdy;
`ifdef FLOAT
FISA64_dblAddsub udbladdsub (
.a(a), // input [63 : 0] a
.b(b), // input [63 : 0] b
.operation({5'd0,x1opcode[0]}), // input [5 : 0] operation
.operation_nd(faddsub_operation_nd), // input operation_nd
.operation_rfd(faddsub_operation_rfd), // output operation_rfd
.clk(clk), // input clk
.result(faddsub_result), // output [63 : 0] result
.underflow(faddsub_underflow), // output underflow
.overflow(faddsub_overflow), // output overflow
.invalid_op(faddsub_invalid_op), // output invalid_op
.rdy(faddsub_rdy) // output rdy
);
FISA64_dblMul udblmul (
.a(a), // input [63 : 0] a
.b(b), // input [63 : 0] b
.operation_nd(fmul_operation_nd), // input operation_nd
.operation_rfd(fmul_operation_rfd), // output operation_rfd
.clk(clk), // input clk
.result(fmul_result), // output [63 : 0] result
.underflow(fmul_underflow), // output underflow
.overflow(fmul_overflow), // output overflow
.invalid_op(fmul_invalid_op), // output invalid_op
.rdy(fmul_rdy) // output rdy
);
FISA64_dblDiv udbldiv (
.a(a), // input [63 : 0] a
.b(b), // input [63 : 0] b
.operation_nd(fdiv_operation_nd), // input operation_nd
.operation_rfd(fdiv_operation_rfd), // output operation_rfd
.clk(clk), // input clk
.result(fdiv_result), // output [63 : 0] result
.underflow(fdiv_underflow), // output underflow
.overflow(fdiv_overflow), // output overflow
.invalid_op(fdiv_invalid_op), // output invalid_op
.divide_by_zero(fdiv_divide_by_zero), // output divide_by_zero
.rdy(fdiv_rdy) // output rdy
);
FISA64_dblFix2Flt udblfix2flt (
.a(a), // input [63 : 0] a
.operation_nd(fix2flt_operation_nd), // input operation_nd
.operation_rfd(fix2flt_operation_rfd), // output operation_rfd
.clk(clk), // input clk
.result(fix2flt_result), // output [63 : 0] result
.rdy(fix2flt_rdy) // output rdy
);
FISA64_dblFlt2Fix udblflt2fix (
.a(a), // input [63 : 0] a
.operation_nd(flt2fix_operation_nd), // input operation_nd
.operation_rfd(flt2fix_operation_rfd), // output operation_rfd
.clk(clk), // input clk
.result(flt2fix_result), // output [63 : 0] result
.overflow(flt2fix_overflow), // output overflow
.invalid_op(flt2fix_invalid_op), // output invalid_op
.rdy(flt2fix_rdy) // output rdy
);
FISA64_dblCmp udblcmp (
.a(a), // input [63 : 0] a
.b(b), // input [63 : 0] b
.operation_nd(fcmp_operation_nd), // input operation_nd
.operation_rfd(fcmp_operation_rfd), // output operation_rfd
.clk(clk), // input clk
.result(fcmp_result), // output [3 : 0] result
.invalid_op(fcmp_invalid_op), // output invalid_op
.rdy(fcmp_rdy) // output rdy
);
`else
assign faddsub_operation_rfd = 1'b1;
assign fmul_operation_rfd = 1'b1;
assign fdiv_operation_rfd = 1'b1;
assign fix2flt_operation_rfd = 1'b1;
assign flt2fix_operation_rfd = 1'b1;
assign fcmp_operation_rfd = 1'b1;
assign faddsub_result = 64'd0;
assign fmul_result = 64'd0;
assign fdiv_result = 64'd0;
assign flt2fix_result = 64'd0;
assign fix2flt_result = 64'd0;
assign fcmp_result = 64'd0;
assign faddsub_overflow = 1'b0;
assign fmul_overflow = 1'b0;
assign fdiv_overflow = 1'b0;
assign flt2fix_overflow = 1'b0;
assign faddsub_underflow = 1'b0;
assign fmul_underflow = 1'b0;
assign fdiv_underflow = 1'b0;
assign faddsub_invalid_op = 1'b0;
assign fmul_invalid_op = 1'b0;
assign fdiv_invalid_op = 1'b0;
assign fcmp_invalid_op = 1'b0;
assign flt2fix_invalid_op = 1'b0;
assign fdiv_divide_by_zero = 1'b0;
assign faddsub_rdy = 1'b1;
assign fmul_rdy = 1'b1;
assign fdiv_rdy = 1'b1;
assign fix2flt_rdy = 1'b1;
assign flt2fix_rdy = 1'b1;
assign fcmp_rdy = 1'b1;
`endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Overflow:
// Add: the signs of the inputs are the same, and the sign of the
// sum is different
// Sub: the signs of the inputs are different, and the sign of
// the sum is the same as B
function fnASOverflow;
input op;
input a;
input b;
input s;
begin