OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v7/] [rtl/] [common/] [FT64_alu.v] - Blame information for rev 60

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 60 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
//      FT64_alu.v
9
//
10
// This source file is free software: you can redistribute it and/or modify 
11
// it under the terms of the GNU Lesser General Public License as published 
12
// by the Free Software Foundation, either version 3 of the License, or     
13
// (at your option) any later version.                                      
14
//                                                                          
15
// This source file is distributed in the hope that it will be useful,      
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
18
// GNU General Public License for more details.                             
19
//                                                                          
20
// You should have received a copy of the GNU General Public License        
21
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
22
//
23
// ============================================================================
24
//
25
`include "FT64_defines.vh"
26
`include "FT64_config.vh"
27
 
28
module FT64_alu(rst, clk, ld, abort, instr, sz, tlb, store, a, b, c, pc, Ra, tgt, tgt2, ven, vm,
29
    csr, o, ob, done, idle, excen, exc, thrd, ptrmask, state, mem, shift,
30
    ol, dl, ASID, icl_i, cyc_i, we_i, vadr_i, cyc_o, we_o, padr_o, uncached, tlb_miss,
31
    exv_o, rdv_o, wrv_o
32
`ifdef SUPPORT_SEGMENTATION
33
                , zs_base, ds_base, es_base, fs_base, gs_base, hs_base, ss_base, cs_base,
34
                zsub, dsub, esub, fsub, gsub, hsub, ssub, csub,
35
                zslb, dslb, eslb, fslb, gslb, hslb, sslb, cslb
36
`endif
37
`ifdef SUPPORT_BBMS
38
    , pb, cbl, cbu, ro, dbl, dbu, sbl, sbu, en
39
`endif
40
    );
41
parameter DBW = 64;
42
parameter ABW = 64;
43
parameter BIG = 1'b1;
44
parameter SUP_VECTOR = 1;
45
parameter TRUE = 1'b1;
46
parameter FALSE = 1'b0;
47
parameter PTR = 20'hFFF01;
48
input rst;
49
input clk;
50
input ld;
51
input abort;
52
input [47:0] instr;
53
input [2:0] sz;
54
input tlb;
55
input store;
56
input [63:0] a;
57
input [63:0] b;
58
input [63:0] c;
59
input [31:0] pc;
60
input [11:0] Ra;
61
input [11:0] tgt;
62
input [7:0] tgt2;
63
input [5:0] ven;
64
input [15:0] vm;
65
input [63:0] csr;
66
output reg [63:0] o;
67
output reg [63:0] ob;
68
output reg done;
69
output reg idle;
70
input [4:0] excen;
71
output reg [8:0] exc;
72
input thrd;
73
input [63:0] ptrmask;
74
input [1:0] state;
75
input mem;
76
input shift;
77
input [1:0] ol;
78
input [1:0] dl;
79
input [7:0] ASID;
80
input icl_i;
81
input cyc_i;
82
input we_i;
83
input [ABW-1:0] vadr_i;
84
output cyc_o;
85
output we_o;
86
output [ABW-1:0] padr_o;
87
output uncached;
88
output tlb_miss;
89
output wrv_o;
90
output rdv_o;
91
output exv_o;
92
`ifdef SUPPORT_SEGMENTATION
93
input [63:0] zs_base;
94
input [63:0] ds_base;
95
input [63:0] es_base;
96
input [63:0] fs_base;
97
input [63:0] gs_base;
98
input [63:0] hs_base;
99
input [63:0] ss_base;
100
input [63:0] cs_base;
101
input [63:0] zslb;
102
input [63:0] dslb;
103
input [63:0] eslb;
104
input [63:0] fslb;
105
input [63:0] gslb;
106
input [63:0] hslb;
107
input [63:0] sslb;
108
input [63:0] cslb;
109
input [63:0] zsub;
110
input [63:0] dsub;
111
input [63:0] esub;
112
input [63:0] fsub;
113
input [63:0] gsub;
114
input [63:0] hsub;
115
input [63:0] ssub;
116
input [63:0] csub;
117
`endif
118
`ifdef SUPPORT_BBMS
119
input [63:0] pb;
120
input [63:0] cbl;
121
input [63:0] cbu;
122
input [63:0] ro;
123
input [63:0] dbl;
124
input [63:0] dbu;
125
input [63:0] sbl;
126
input [63:0] sbu;
127
input [63:0] en;
128
`endif
129
 
130
parameter byt = 3'd0;
131
parameter char = 3'd1;
132
parameter half = 3'd2;
133
parameter word = 3'd3;
134
parameter byt_para = 3'd4;
135
parameter char_para = 3'd5;
136
parameter half_para = 3'd6;
137
parameter word_para = 3'd7;
138
 
139
integer n;
140
 
141
reg adrDone, adrIdle;
142
reg [63:0] usa;                  // unsegmented address
143
`ifdef SUPPORT_SEGMENTATION
144
reg [63:0] pb;
145
reg [63:0] ub;
146
reg [63:0] lb;
147
always @*
148
case(usa[63:61])
149
3'd0:   pb <= zs_base;
150
3'd1: pb <= ds_base;
151
3'd2: pb <= es_base;
152
3'd3: pb <= fs_base;
153
3'd4: pb <= gs_base;
154
3'd5: pb <= hs_base;
155
3'd6: pb <= ss_base;
156
3'd7: pb <= cs_base;
157
endcase
158
always @*
159
case(usa[63:61])
160
3'd0:   ub <= zsub;
161
3'd1: ub <= dsub;
162
3'd2: ub <= esub;
163
3'd3: ub <= fsub;
164
3'd4: ub <= gsub;
165
3'd5: ub <= hsub;
166
3'd6: ub <= ssub;
167
3'd7: ub <= csub;
168
endcase
169
always @*
170
case(usa[63:61])
171
3'd0:   lb <= zslb;
172
3'd1: lb <= dslb;
173
3'd2: lb <= eslb;
174
3'd3: lb <= fslb;
175
3'd4: lb <= gslb;
176
3'd5: lb <= hslb;
177
3'd6: lb <= sslb;
178
3'd7: lb <= cslb;
179
endcase
180
`else
181
`ifndef SUPPORT_BBMS
182
reg [63:0] pb = 64'h0;
183
`endif
184
`endif
185
reg [63:0] addro;
186
reg [63:0] adr;                  // load / store address
187
reg [63:0] shift8;
188
 
189
wire [7:0] a8 = a[7:0];
190
wire [15:0] a16 = a[15:0];
191
wire [31:0] a32 = a[31:0];
192
wire [7:0] b8 = b[7:0];
193
wire [15:0] b16 = b[15:0];
194
wire [31:0] b32 = b[31:0];
195
wire [63:0] orb = instr[6] ? {34'd0,b[29:0]} : {50'd0,b[13:0]};
196
wire [63:0] andb = b;//((instr[6]==1'b1) ? {34'h3FFFFFFFF,b[29:0]} : {50'h3FFFFFFFFFFFF,b[13:0]});
197
 
198
wire [21:0] qimm = instr[39:18];
199
wire [63:0] imm = {{45{instr[39]}},instr[39:21]};
200
wire [DBW-1:0] divq, rem;
201
wire divByZero;
202
wire [15:0] prod80, prod81, prod82, prod83, prod84, prod85, prod86, prod87;
203
wire [31:0] prod160, prod161, prod162, prod163;
204
wire [63:0] prod320, prod321;
205
wire [DBW*2-1:0] prod;
206
wire mult_done8, mult_idle8, div_done8, div_idle8;
207
wire mult_done80, mult_idle80, div_done80, div_idle80;
208
wire mult_done81, mult_idle81, div_done81, div_idle81;
209
wire mult_done82, mult_idle82, div_done82, div_idle82;
210
wire mult_done83, mult_idle83, div_done83, div_idle83;
211
wire mult_done84, mult_idle84, div_done84, div_idle84;
212
wire mult_done85, mult_idle85, div_done85, div_idle85;
213
wire mult_done86, mult_idle86, div_done86, div_idle86;
214
wire mult_done87, mult_idle87, div_done87, div_idle87;
215
wire mult_done16, mult_idle16, div_done16, div_idle16;
216
wire mult_done160, mult_idle160, div_done160, div_idle160;
217
wire mult_done161, mult_idle161, div_done161, div_idle161;
218
wire mult_done162, mult_idle162, div_done162, div_idle162;
219
wire mult_done163, mult_idle163, div_done163, div_idle163;
220
wire mult_done320, mult_idle320, div_done320, div_idle320;
221
wire mult_done321, mult_idle321, div_done321, div_idle321;
222
wire mult_done, mult_idle, div_done, div_idle;
223
wire aslo;
224
wire [6:0] clzo,cloo,cpopo;
225
wire [63:0] shftho;
226
reg [63:0] shift9;
227
 
228
function IsLoad;
229
input [47:0] isn;
230
case(isn[`INSTRUCTION_OP])
231
`MEMNDX:
232
        if (isn[`INSTRUCTION_L2]==2'b00)
233
                IsLoad = !isn[31];
234
        else
235
                IsLoad = FALSE;
236
`LB:    IsLoad = TRUE;
237
`LBU:   IsLoad = TRUE;
238
`Lx:    IsLoad = TRUE;
239
`LxU:   IsLoad = TRUE;
240
`LWR:   IsLoad = TRUE;
241
`LV:    IsLoad = TRUE;
242
`LVx:   IsLoad = TRUE;
243
`LVxU:  IsLoad = TRUE;
244
default:    IsLoad = FALSE;
245
endcase
246
endfunction
247
 
248
function IsMul;
249
input [47:0] isn;
250
case(isn[`INSTRUCTION_OP])
251
`IVECTOR:
252
  case(isn[`INSTRUCTION_S2])
253
  `VMUL,`VMULS:   IsMul = TRUE;
254
  default:    IsMul = FALSE;
255
  endcase
256
`R2:
257
  case(isn[`INSTRUCTION_S2])
258
  `MULU,`MULSU,`MUL: IsMul = TRUE;
259
  `MULUH,`MULSUH,`MULH: IsMul = TRUE;
260
  `FXMUL: IsMul = TRUE;
261
  default:    IsMul = FALSE;
262
  endcase
263
`MULUI,`MULI:  IsMul = TRUE;
264
default:    IsMul = FALSE;
265
endcase
266
endfunction
267
 
268
function IsDivmod;
269
input [47:0] isn;
270
case(isn[`INSTRUCTION_OP])
271
`IVECTOR:
272
  case(isn[`INSTRUCTION_S2])
273
  `VDIV,`VDIVS:   IsDivmod = TRUE;
274
  default:    IsDivmod = FALSE;
275
  endcase
276
`R2:
277
  case(isn[`INSTRUCTION_S2])
278
  `DIVU,`DIVSU,`DIV: IsDivmod = TRUE;
279
  `MODU,`MODSU,`MOD: IsDivmod = TRUE;
280
  default:    IsDivmod = FALSE;
281
  endcase
282
`DIVUI,`DIVI,`MODI:  IsDivmod = TRUE;
283
default:    IsDivmod = FALSE;
284
endcase
285
endfunction
286
 
287
function IsSgn;
288
input [47:0] isn;
289
case(isn[`INSTRUCTION_OP])
290
`IVECTOR:
291
    case(isn[`INSTRUCTION_S2])
292
    `VMUL,`VMULS,`VDIV,`VDIVS:    IsSgn = TRUE;
293
    default:    IsSgn = FALSE;
294
    endcase
295
`R2:
296
  case(isn[`INSTRUCTION_S2])
297
  `MUL,`DIV,`MOD,`MULH:   IsSgn = TRUE;
298
  `FXMUL: IsSgn = TRUE;
299
  default:    IsSgn = FALSE;
300
  endcase
301
`MULI,`DIVI,`MODI:    IsSgn = TRUE;
302
default:    IsSgn = FALSE;
303
endcase
304
endfunction
305
 
306
function IsSgnus;
307
input [47:0] isn;
308
case(isn[`INSTRUCTION_OP])
309
`R2:
310
  case(isn[`INSTRUCTION_S2])
311
  `MULSU,`MULSUH,`DIVSU,`MODSU:   IsSgnus = TRUE;
312
  default:    IsSgnus = FALSE;
313
  endcase
314
default:    IsSgnus = FALSE;
315
endcase
316
endfunction
317
 
318
function IsShiftAndOp;
319
input [47:0] isn;
320
IsShiftAndOp = FALSE;
321
endfunction
322
 
323
wire [63:0] bfout,shfto;
324
wire [63:0] shftob;
325
wire [63:0] shftco;
326
 
327
always @(posedge clk)
328
        shift9 <= shift8;
329
 
330
wire tlb_done, tlb_idle;
331
wire [DBW-1:0] tlbo;
332
 
333
`ifdef SUPPORT_TLB
334
FT64_TLB utlb1 (
335
        .rst(rst),
336
        .clk(clk),
337
        .ld(ld & tlb),
338
        .done(tlb_done),
339
        .idle(tlb_idle),
340
        .ol(ol),
341
        .ASID(ASID),
342
        .op(instr[25:22]),
343
        .regno(instr[21:18]),
344
        .dati(a),
345
        .dato(tlbo),
346
        .uncached(uncached),
347
        .icl_i(icl_i),
348
        .cyc_i(cyc_i),
349
        .we_i(we_i),
350
        .vadr_i(vadr_i),
351
        .cyc_o(cyc_o),
352
        .we_o(we_o),
353
        .padr_o(padr_o),
354
        .TLBMiss(tlb_miss),
355
        .wrv_o(wrv_o),
356
        .rdv_o(rdv_o),
357
        .exv_o(exv_o),
358
        .HTLBVirtPageo()
359
);
360
`else
361
assign tlbo = 64'hDEADDEADDEADDEAD;
362
assign uncached = 1'b0;
363
assign padr_o = vadr_i;
364
assign cyc_o = cyc_i;
365
assign we_o = we_i;
366
assign tlb_miss = 1'b0;
367
assign wrv_o = 1'b0;
368
assign rdv_o = 1'b0;
369
assign exv_o = 1'b0;
370
`endif
371
 
372
FT64_bitfield #(DBW) ubf1
373
(
374
    .inst(instr),
375
    .a(a),
376
    .b(b),
377
    .c(c),
378
    .o(bfout),
379
    .masko()
380
);
381
 
382
FT64_multiplier #(DBW) umult1
383
(
384
        .rst(rst),
385
        .clk(clk),
386
        .ld(ld && IsMul(instr)&& (sz==word || sz==word_para)),
387
        .abort(abort),
388
        .sgn(IsSgn(instr)),
389
        .sgnus(IsSgnus(instr)),
390
        .a(a),
391
        .b(b),
392
        .o(prod),
393
        .done(mult_done),
394
        .idle(mult_idle)
395
);
396
 
397
FT64_multiplier #(32) umulth0
398
(
399
        .rst(rst),
400
        .clk(clk),
401
        .ld(ld && IsMul(instr) && (sz==half || sz==half_para)),
402
        .abort(abort),
403
        .sgn(IsSgn(instr)),
404
        .sgnus(IsSgnus(instr)),
405
        .a(a[31:0]),
406
        .b(b[31:0]),
407
        .o(prod320),
408
        .done(mult_done320),
409
        .idle(mult_idle320)
410
);
411
 
412
FT64_multiplier #(16) umultc0
413
(
414
        .rst(rst),
415
        .clk(clk),
416
        .ld(ld && IsMul(instr) && (sz==char || sz==char_para)),
417
        .abort(abort),
418
        .sgn(IsSgn(instr)),
419
        .sgnus(IsSgnus(instr)),
420
        .a(a[15:0]),
421
        .b(b[15:0]),
422
        .o(prod160),
423
        .done(mult_done160),
424
        .idle(mult_idle160)
425
);
426
 
427
FT64_multiplier #(8) umultb0
428
(
429
        .rst(rst),
430
        .clk(clk),
431
        .ld(ld && IsMul(instr) && (sz==byt || sz==byt_para)),
432
        .abort(abort),
433
        .sgn(IsSgn(instr)),
434
        .sgnus(IsSgnus(instr)),
435
        .a(a[7:0]),
436
        .b(b[7:0]),
437
        .o(prod80),
438
        .done(mult_done80),
439
        .idle(mult_idle80)
440
);
441
 
442
`ifdef SIMD
443
FT64_multiplier #(32) umulth1
444
(
445
        .rst(rst),
446
        .clk(clk),
447
        .ld(ld && IsMul(instr) && (sz==half || sz==half_para)),
448
        .abort(abort),
449
        .sgn(IsSgn(instr)),
450
        .sgnus(IsSgnus(instr)),
451
        .a(a[63:32]),
452
        .b(b[63:32]),
453
        .o(prod321),
454
        .done(mult_done321),
455
        .idle(mult_idle321)
456
);
457
 
458
FT64_multiplier #(16) umultc1
459
(
460
        .rst(rst),
461
        .clk(clk),
462
        .ld(ld && IsMul(instr) && (sz==char_para)),
463
        .abort(abort),
464
        .sgn(IsSgn(instr)),
465
        .sgnus(IsSgnus(instr)),
466
        .a(a[31:16]),
467
        .b(b[31:16]),
468
        .o(prod161),
469
        .done(mult_done161),
470
        .idle(mult_idle161)
471
);
472
 
473
FT64_multiplier #(16) umultc2
474
(
475
        .rst(rst),
476
        .clk(clk),
477
        .ld(ld && IsMul(instr) && (sz==char_para)),
478
        .abort(abort),
479
        .sgn(IsSgn(instr)),
480
        .sgnus(IsSgnus(instr)),
481
        .a(a[47:32]),
482
        .b(b[47:32]),
483
        .o(prod162),
484
        .done(mult_done162),
485
        .idle(mult_idle162)
486
);
487
 
488
FT64_multiplier #(16) umultc3
489
(
490
        .rst(rst),
491
        .clk(clk),
492
        .ld(ld && IsMul(instr) && (sz==char_para)),
493
        .abort(abort),
494
        .sgn(IsSgn(instr)),
495
        .sgnus(IsSgnus(instr)),
496
        .a(a[63:48]),
497
        .b(b[63:48]),
498
        .o(prod163),
499
        .done(mult_done163),
500
        .idle(mult_idle163)
501
);
502
 
503
FT64_multiplier #(8) umultb1
504
(
505
        .rst(rst),
506
        .clk(clk),
507
        .ld(ld && IsMul(instr) && (sz==byt_para)),
508
        .abort(abort),
509
        .sgn(IsSgn(instr)),
510
        .sgnus(IsSgnus(instr)),
511
        .a(a[15:8]),
512
        .b(b[15:8]),
513
        .o(prod81),
514
        .done(mult_done81),
515
        .idle(mult_idle81)
516
);
517
 
518
FT64_multiplier #(8) umultb2
519
(
520
        .rst(rst),
521
        .clk(clk),
522
        .ld(ld && IsMul(instr) && (sz==byt_para)),
523
        .abort(abort),
524
        .sgn(IsSgn(instr)),
525
        .sgnus(IsSgnus(instr)),
526
        .a(a[23:16]),
527
        .b(b[23:16]),
528
        .o(prod82),
529
        .done(mult_done82),
530
        .idle(mult_idle82)
531
);
532
 
533
FT64_multiplier #(8) umultb3
534
(
535
        .rst(rst),
536
        .clk(clk),
537
        .ld(ld && IsMul(instr) && (sz==byt_para)),
538
        .abort(abort),
539
        .sgn(IsSgn(instr)),
540
        .sgnus(IsSgnus(instr)),
541
        .a(a[31:24]),
542
        .b(b[31:24]),
543
        .o(prod83),
544
        .done(mult_done83),
545
        .idle(mult_idle83)
546
);
547
 
548
FT64_multiplier #(8) umultb4
549
(
550
        .rst(rst),
551
        .clk(clk),
552
        .ld(ld && IsMul(instr) && (sz==byt_para)),
553
        .abort(abort),
554
        .sgn(IsSgn(instr)),
555
        .sgnus(IsSgnus(instr)),
556
        .a(a[39:32]),
557
        .b(b[39:32]),
558
        .o(prod84),
559
        .done(mult_done84),
560
        .idle(mult_idle84)
561
);
562
 
563
FT64_multiplier #(8) umultb5
564
(
565
        .rst(rst),
566
        .clk(clk),
567
        .ld(ld && IsMul(instr) && (sz==byt_para)),
568
        .abort(abort),
569
        .sgn(IsSgn(instr)),
570
        .sgnus(IsSgnus(instr)),
571
        .a(a[47:40]),
572
        .b(b[47:40]),
573
        .o(prod85),
574
        .done(mult_done85),
575
        .idle(mult_idle85)
576
);
577
 
578
FT64_multiplier #(8) umultb6
579
(
580
        .rst(rst),
581
        .clk(clk),
582
        .ld(ld && IsMul(instr) && (sz==byt_para)),
583
        .abort(abort),
584
        .sgn(IsSgn(instr)),
585
        .sgnus(IsSgnus(instr)),
586
        .a(a[55:48]),
587
        .b(b[55:48]),
588
        .o(prod86),
589
        .done(mult_done86),
590
        .idle(mult_idle86)
591
);
592
 
593
FT64_multiplier #(8) umultb7
594
(
595
        .rst(rst),
596
        .clk(clk),
597
        .ld(ld && IsMul(instr) && (sz==byt_para)),
598
        .abort(abort),
599
        .sgn(IsSgn(instr)),
600
        .sgnus(IsSgnus(instr)),
601
        .a(a[63:56]),
602
        .b(b[63:56]),
603
        .o(prod87),
604
        .done(mult_done87),
605
        .idle(mult_idle87)
606
);
607
`endif
608
 
609
FT64_divider #(DBW) udiv1
610
(
611
        .rst(rst),
612
        .clk(clk),
613
        .ld(ld && IsDivmod(instr) && (sz==word || sz==word_para)),
614
        .abort(abort),
615
        .sgn(IsSgn(instr)),
616
        .sgnus(IsSgnus(instr)),
617
        .a(a),
618
        .b(b),
619
        .qo(divq),
620
        .ro(rem),
621
        .dvByZr(divByZero),
622
        .done(div_done),
623
        .idle(div_idle)
624
);
625
 
626
wire [5:0] bshift = instr[31:26]==`SHIFTR ? b[5:0] : {instr[30],instr[22:18]};
627
 
628
FT64_shift ushft1
629
(
630
    .instr(instr),
631
    .a(a),
632
    .b(bshift),
633
    .res(shfto),
634
    .ov(aslo)
635
);
636
 
637
FT64_shifth ushfthL
638
(
639
    .instr(instr),
640
    .a(a[31:0]),
641
    .b(bshift),
642
    .res(shftho[31:0]),
643
    .ov()
644
);
645
 
646
FT64_shifth ushfthH
647
(
648
    .instr(instr),
649
    .a(a[63:32]),
650
    .b(b[63:32]),
651
    .res(shftho[63:32]),
652
    .ov()
653
);
654
 
655
FT64_shiftc ushftc0
656
(
657
    .instr(instr),
658
    .a(a[15:0]),
659
    .b(bshift),
660
    .res(shftco[15:0]),
661
    .ov()
662
);
663
 
664
FT64_shiftc ushftc1
665
(
666
    .instr(instr),
667
    .a(a[31:16]),
668
    .b(b[31:16]),
669
    .res(shftco[31:16]),
670
    .ov()
671
);
672
 
673
FT64_shiftc ushftc2
674
(
675
    .instr(instr),
676
    .a(a[47:32]),
677
    .b(b[47:32]),
678
    .res(shftco[47:32]),
679
    .ov()
680
);
681
 
682
FT64_shiftc ushftc3
683
(
684
    .instr(instr),
685
    .a(a[63:48]),
686
    .b(b[63:48]),
687
    .res(shftco[63:48]),
688
    .ov()
689
);
690
 
691
FT64_shiftb ushftb0
692
(
693
    .instr(instr),
694
    .a(a[7:0]),
695
    .b(bshift),
696
    .res(shftob[7:0]),
697
    .ov()
698
);
699
 
700
FT64_shiftb ushftb1
701
(
702
    .instr(instr),
703
    .a(a[15:8]),
704
    .b(b[15:8]),
705
    .res(shftob[15:8]),
706
    .ov()
707
);
708
 
709
FT64_shiftb ushftb2
710
(
711
    .instr(instr),
712
    .a(a[23:16]),
713
    .b(b[23:16]),
714
    .res(shftob[23:16]),
715
    .ov()
716
);
717
 
718
FT64_shiftb ushftb3
719
(
720
    .instr(instr),
721
    .a(a[31:24]),
722
    .b(b[31:24]),
723
    .res(shftob[31:24]),
724
    .ov()
725
);
726
 
727
FT64_shiftb ushftb4
728
(
729
    .instr(instr),
730
    .a(a[39:32]),
731
    .b(b[39:32]),
732
    .res(shftob[39:32]),
733
    .ov()
734
);
735
 
736
FT64_shiftb ushftb5
737
(
738
    .instr(instr),
739
    .a(a[47:40]),
740
    .b(b[47:40]),
741
    .res(shftob[47:40]),
742
    .ov()
743
);
744
 
745
FT64_shiftb ushftb6
746
(
747
    .instr(instr),
748
    .a(a[55:48]),
749
    .b(b[55:48]),
750
    .res(shftob[55:48]),
751
    .ov()
752
);
753
 
754
FT64_shiftb ushftb7
755
(
756
    .instr(instr),
757
    .a(a[63:56]),
758
    .b(b[63:56]),
759
    .res(shftob[63:56]),
760
    .ov()
761
);
762
 
763
cntlz64 uclz1
764
(
765
        .i(sz==2'd0 ? {56'hFFFFFFFFFFFFFF,a[7:0]} :
766
           sz==2'd1 ? {48'hFFFFFFFFFFFF,a[15:0]} :
767
           sz==2'd2 ? {32'hFFFFFFFF,a[31:0]} : a),
768
        .o(clzo)
769
);
770
 
771
cntlo64 uclo1
772
(
773
        .i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
774
        .o(cloo)
775
);
776
 
777
cntpop64 ucpop1
778
(
779
        .i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
780
        .o(cpopo)
781
);
782
 
783
wire [7:0] bcdaddo,bcdsubo;
784
wire [15:0] bcdmulo;
785
BCDAdd ubcd1 (1'b0,a,b,bcdaddo);
786
BCDSub ubcd2 (1'b0,a,b,bcdsubo);
787
BCDMul2 ubcd3 (a,b,bcdmulo);
788
 
789
wire [7:0] s8 = a[7:0] + b[7:0];
790
wire [15:0] s16 = a[15:0] + b[15:0];
791
wire [31:0] s32 = a[31:0] + b[31:0];
792
wire [7:0] d8 = a[7:0] - b[7:0];
793
wire [15:0] d16 = a[15:0] - b[15:0];
794
wire [31:0] d32 = a[31:0] - b[31:0];
795
wire [63:0] and64 = a & b;
796
wire [63:0] or64 = a | b;
797
wire [63:0] xor64 = a ^ b;
798
wire [63:0] redor64 = {63'd0,|a};
799
wire [63:0] redor32 = {31'd0,|a[63:32],31'd0,|a[31:0]};
800
wire [63:0] redor16 = {15'd0,|a[63:48],15'd0,|a[47:32],15'd0,|a[31:16],15'd0,|a[15:0]};
801
wire [63:0] redor8 = {7'b0,|a[63:56],6'b0,|a[55:48],7'd0,|a[47:40],7'd0,|a[39:32],7'd0,
802
                                                                                                         |a[31:24],7'd0,|a[23:16],7'd0,|a[15:8],7'd0,|a[7:0]};
803
wire [63:0] zxb10 = {54'd0,b[9:0]};
804
wire [63:0] sxb10 = {{54{b[9]}},b[9:0]};
805
wire [63:0] zxb26 = {38'd0,instr[47:32],instr[27:18]};
806
wire [63:0] sxb26 = {{38{instr[47]}},instr[47:32],instr[27:18]};
807
reg [15:0] mask;
808
wire [4:0] cpopom;
809
wire signed [63:0] as = a;
810
wire signed [63:0] bs = b;
811
wire signed [63:0] cs = c;
812
 
813
always @*
814
for (n = 0; n < 16; n = n + 1)
815
    if (n <= ven)
816
        mask[n] = 1'b1;
817
    else
818
        mask[n] = 1'b0;
819
 
820
cntpop16 ucpop2
821
(
822
        .i(vm & mask),
823
        .o(cpopom)
824
);
825
 
826
wire [5:0] lsto, fsto;
827
ffz24 uffo1
828
(
829
    .i(~{8'h00,a[15:0]}),
830
    .o(lsto)
831
);
832
 
833
flz24 uflo1
834
(
835
    .i(~{8'h00,a[15:0]}),
836
    .o(fsto)
837
);
838
 
839
wire [DBW-1:0] bmmo;
840
FT64_BMM ubmm1
841
(
842
        .op(1'b0),
843
        .a(a),
844
        .b(b),
845
        .o(bmmo)
846
);
847
 
848
always @*
849
begin
850
case(instr[`INSTRUCTION_OP])
851
`IVECTOR:
852
    if (SUP_VECTOR)
853
    case(instr[`INSTRUCTION_S2])
854
    `VABS:         o[63:0] = a[63] ? -a : a;
855
    `VSIGN:        o[63:0] = a[63] ? 64'hFFFFFFFFFFFFFFFF : a==64'd0 ? 64'd0 : 64'd1;
856
    `VMxx:
857
        case(instr[25:23])
858
            `VMAND:        o[63:0] = and64;
859
            `VMOR:         o[63:0] = or64;
860
            `VMXOR:        o[63:0] = xor64;
861
            `VMXNOR:       o[63:0] = ~(xor64);
862
            `VMPOP:        o[63:0] = {57'd0,cpopo};
863
            `VMFILL:       for (n = 0; n < 64; n = n + 1)
864
                               o[n] = (n < a);
865
                               // Change the following when VL > 16
866
            `VMFIRST:      o[63:0] = fsto==5'd31 ? 64'd64 : fsto;
867
            `VMLAST:       o[63:0] = lsto==5'd31 ? 64'd64 : lsto;
868
                endcase
869
    `VADD,`VADDS:  o[63:0] = vm[ven] ? a + b : c;
870
    `VSUB,`VSUBS:  o[63:0] = vm[ven] ? a - b : c;
871
    `VMUL,`VMULS:  o[63:0] = vm[ven] ? prod[DBW-1:0] : c;
872
    `VDIV,`VDIVS:  o[63:0] = BIG ? (vm[ven] ? divq : c) : 64'hCCCCCCCCCCCCCCCC;
873
    `VAND,`VANDS:  o[63:0] = vm[ven] ? a & b : c;
874
    `VOR,`VORS:    o[63:0] = vm[ven] ? a | b : c;
875
    `VXOR,`VXORS:  o[63:0] = vm[ven] ? a ^ b : c;
876
    `VCNTPOP:      o[63:0] = {57'd0,cpopo};
877
    `VSHLV:        o[63:0] = a;   // no masking here
878
    `VSHRV:        o[63:0] = a;
879
    `VCMPRSS:      o[63:0] = a;
880
    `VCIDX:        o[63:0] = a * ven;
881
    `VSCAN:        o[63:0] = a * (cpopom==0 ? 0 : cpopom-1);
882
    `VSxx,`VSxxS,
883
    `VSxxb,`VSxxSb:
884
        case({instr[26],instr[20:19]})
885
        `VSEQ:     begin
886
                       o[63:0] = c;
887
                       o[ven] = vm[ven] ? a==b : c[ven];
888
                   end
889
        `VSNE:     begin
890
                       o[63:0] = c;
891
                       o[ven] = vm[ven] ? a!=b : c[ven];
892
                   end
893
        `VSLT:      begin
894
                         o[63:0] = c;
895
                         o[ven] = vm[ven] ? $signed(a) < $signed(b) : c[ven];
896
                    end
897
        `VSGE:      begin
898
                         o[63:0] = c;
899
                         o[ven] = vm[ven] ? $signed(a) >= $signed(b) : c[ven];
900
                    end
901
        `VSLE:      begin
902
                          o[63:0] = c;
903
                          o[ven] = vm[ven] ? $signed(a) <= $signed(b) : c[ven];
904
                    end
905
        `VSGT:      begin
906
                         o[63:0] = c;
907
                         o[ven] = vm[ven] ? $signed(a) > $signed(b) : c[ven];
908
                    end
909
        default:        o[63:0] = 64'hCCCCCCCCCCCCCCCC;
910
        endcase
911
    `VSxxU,`VSxxSU,
912
    `VSxxUb,`VSxxSUb:
913
        case({instr[26],instr[20:19]})
914
        `VSEQ:     begin
915
                       o[63:0] = c;
916
                       o[ven] = vm[ven] ? a==b : c[ven];
917
                   end
918
        `VSNE:     begin
919
                       o[63:0] = c;
920
                       o[ven] = vm[ven] ? a!=b : c[ven];
921
                   end
922
        `VSLT:      begin
923
                         o[63:0] = c;
924
                         o[ven] = vm[ven] ? a < b : c[ven];
925
                    end
926
        `VSGE:      begin
927
                         o[63:0] = c;
928
                         o[ven] = vm[ven] ? a >= b : c[ven];
929
                    end
930
        `VSLE:      begin
931
                          o[63:0] = c;
932
                          o[ven] = vm[ven] ? a <= b : c[ven];
933
                    end
934
        `VSGT:      begin
935
                         o[63:0] = c;
936
                         o[ven] = vm[ven] ? a > b : c[ven];
937
                    end
938
        default:        o[63:0] = 64'hCCCCCCCCCCCCCCCC;
939
        endcase
940
    `VBITS2V:   o[63:0] = vm[ven] ? a[ven] : c;
941
    `V2BITS:    begin
942
                o[63:0] = b;
943
                o[ven] = vm[ven] ? a[0] : b[ven];
944
                end
945
    `VSHL,`VSHR,`VASR:  o[63:0] = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
946
    `VXCHG:     o[63:0] = vm[ven] ? b : a;
947
    default:    o[63:0] = 64'hCCCCCCCCCCCCCCCC;
948
    endcase
949
    else
950
        o[63:0] <= 64'hCCCCCCCCCCCCCCCC;
951
`R2:
952
        if (instr[6])
953
                case(instr[47:42])
954
                `SHIFTR:
955
                        begin
956
                        case(instr[35:33])
957
                        `ASL,`ASR,`ROL,`ROR:
958
                                case(instr[32:30])      // size
959
                                3'd0:   shift8 = {{56{shftob[7]}},shftob[7:0]};
960
                                3'd1:   shift8 = {{48{shftob[15]}},shftco[15:0]};
961
                                3'd2:   shift8 = {{32{shftho[31]}},shftho[31:0]};
962
                                3'd3,3'd7:      shift8 = shfto;
963
                                3'd4:   shift8 = shftob;
964
                                3'd5:   shift8 = shftco;
965
                                3'd6:   shift8 = shftho;
966
                                endcase
967
                        `SHL,`SHR:
968
                                case(instr[32:30])      // size
969
                                3'd0:   shift8 = {56'd0,shftob[7:0]};
970
                                3'd1:   shift8 = {48'd0,shftco[15:0]};
971
                                3'd2:   shift8 = {32'd0,shftho[31:0]};
972
                                3'd3,3'd7:      shift8 = shfto;
973
                                3'd4:   shift8 = shftob;
974
                                3'd5:   shift8 = shftco;
975
                                3'd6:   shift8 = shftho;
976
                                endcase
977
                        default:        o[63:0] = 64'hDCDCDCDCDCDCDCDC;
978
                        endcase
979
                        case(instr[35:33])
980
                        `ASL,`ASR,`SHL,`SHR,`ROL,`ROR:
981
                                o[63:0] = shift9;
982
                        default:        o[63:0] = 64'hDCDCDCDCDCDCDCDC;
983
                        endcase
984
                        end
985
                `MIN:
986
                        case(instr[30:28])
987
                        3'd3:
988
                                if (as < bs && as < cs)
989
                                        o[63:0] = as;
990
                                else if (bs < cs)
991
                                        o[63:0] = bs;
992
                                else
993
                                        o[63:0] = cs;
994
            default:    o = 64'hDEADDEADDEADDEAD;
995
                        endcase
996
    `CMOVEZ:    begin
997
                        o = (a==64'd0) ? b : c;
998
                        end
999
    `CMOVNZ:    if (instr[41:39]==3'd4)
1000
                                o = (a!=64'd0) ? b : {{48{instr[38]}},instr[38:23]};
1001
                        else
1002
                                o = (a!=64'd0) ? b : c;
1003
    default:    o = 64'hDEADDEADDEADDEAD;
1004
                endcase
1005
        else
1006
            casez(instr[`INSTRUCTION_S2])
1007
            `BCD:
1008
                case(instr[`INSTRUCTION_S1])
1009
                `BCDADD:    o[63:0] = BIG ? bcdaddo :  64'hCCCCCCCCCCCCCCCC;
1010
                `BCDSUB:    o[63:0] = BIG ? bcdsubo :  64'hCCCCCCCCCCCCCCCC;
1011
                `BCDMUL:    o[63:0] = BIG ? bcdmulo :  64'hCCCCCCCCCCCCCCCC;
1012
                default:    o[63:0] = 64'hDEADDEADDEADDEAD;
1013
                endcase
1014
            `MOV:       begin
1015
                        o[63:0] = a;
1016
                        end
1017
            `VMOV:              o[63:0] = a;
1018
            `R1:
1019
                case(instr[`INSTRUCTION_S1])
1020
                `CNTLZ:     o[63:0] = BIG ? {57'd0,clzo} : 64'hCCCCCCCCCCCCCCCC;
1021
                `CNTLO:     o[63:0] = BIG ? {57'd0,cloo} : 64'hCCCCCCCCCCCCCCCC;
1022
                `CNTPOP:    o[63:0] = BIG ? {57'd0,cpopo} : 64'hCCCCCCCCCCCCCCCC;
1023
                `ABS:       case(sz[1:0])
1024
                            2'd0:   o[63:0] = BIG ? (a[7] ? -a[7:0] : a[7:0]) : 64'hCCCCCCCCCCCCCCCC;
1025
                            2'd1:   o[63:0] = BIG ? (a[15] ? -a[15:0] : a[15:0]) : 64'hCCCCCCCCCCCCCCCC;
1026
                            2'd2:   o[63:0] = BIG ? (a[31] ? -a[31:0] : a[31:0]) : 64'hCCCCCCCCCCCCCCCC;
1027
                            2'd3:   o[63:0] = BIG ? (a[63] ? -a : a) : 64'hCCCCCCCCCCCCCCCC;
1028
                            endcase
1029
                `NOT:   case(sz[1:0])
1030
                        2'd0:   o = {~|a[63:56],~|a[55:48],~|a[47:40],~|a[39:32],~|a[31:24],~|a[23:16],~|a[15:8],~|a[7:0]};
1031
                        2'd1:   o = {~|a[63:48],~|a[47:32],~|a[31:16],~|a[15:0]};
1032
                        2'd2:   o = {~|a[63:32],~|a[31:0]};
1033
                        2'd3:   o = ~|a[63:0];
1034
                        endcase
1035
                `NEG:
1036
                                                case(sz[1:0])
1037
                                                2'd0:   o = {-a[63:56],-a[55:48],-a[47:40],-a[39:32],-a[31:24],-a[23:16],-a[15:8],-a[7:0]};
1038
                                                2'd1: o = {-a[63:48],-a[47:32],-a[31:16],-a[15:0]};
1039
                                                2'd2:   o = {-a[63:32],-a[31:0]};
1040
                                                2'd3:   o = -a;
1041
                                                endcase
1042
                `REDOR: case(sz[1:0])
1043
                        2'd0:   o = redor8;
1044
                        2'd1:   o = redor16;
1045
                        2'd2:   o = redor32;
1046
                        2'd3:   o = redor64;
1047
                        endcase
1048
                `ZXH:           o[63:0] = {32'd0,a[31:0]};
1049
                `ZXC:           o[63:0] = {48'd0,a[15:0]};
1050
                `ZXB:           o[63:0] = {56'd0,a[7:0]};
1051
                `SXH:           o[63:0] = {{32{a[31]}},a[31:0]};
1052
                `SXC:           o[63:0] = {{48{a[15]}},a[15:0]};
1053
                `SXB:           o[63:0] = {{56{a[7]}},a[7:0]};
1054
//              5'h1C:          o[63:0] = tmem[a[9:0]];
1055
                default:    o = 64'hDEADDEADDEADDEAD;
1056
                endcase
1057
            `BMM:               o[63:0] = BIG ? bmmo : 64'hCCCCCCCCCCCCCCCC;
1058
            `SHIFT31,
1059
            `SHIFT63,
1060
            `SHIFTR:
1061
                begin
1062
                        if (instr[25:23]==`SHL || instr[25:23]==`ASL)
1063
                                o[63:0] = shfto;
1064
                        else
1065
                                o[63:0] = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
1066
                        $display("BIG=%d",BIG);
1067
                        if(!BIG)
1068
                                $stop;
1069
                end
1070
            `ADD:
1071
`ifdef SIMD
1072
                case(sz)
1073
                        3'd0,3'd4:
1074
                                begin
1075
                                        o[7:0] = a[7:0] + b[7:0];
1076
                                        o[15:8] = a[15:8] + b[15:8];
1077
                                        o[23:16] = a[23:16] + b[23:16];
1078
                                        o[31:24] = a[31:24] + b[31:24];
1079
                                        o[39:32] = a[39:32] + b[39:32];
1080
                                        o[47:40] = a[47:40] + b[47:40];
1081
                                        o[55:48] = a[55:48] + b[55:48];
1082
                                        o[63:56] = a[63:56] + b[63:56];
1083
                                end
1084
                        3'd1,3'd5:
1085
                                begin
1086
                                        o[15:0] = a[15:0] + b[15:0];
1087
                                        o[31:16] = a[31:16] + b[31:16];
1088
                                        o[47:32] = a[47:32] + b[47:32];
1089
                                        o[63:48] = a[63:48] + b[63:48];
1090
                                end
1091
                        3'd2,3'd6:
1092
                                begin
1093
                                        o[31:0] = a[31:0] + b[31:0];
1094
                                        o[63:32] = a[63:32] + b[63:32];
1095
                                end
1096
                    default:
1097
                        begin
1098
                                o[63:0] = a + b;
1099
                        end
1100
                    endcase
1101
`else
1102
                        o = a + b;
1103
`endif
1104
            `SUB:
1105
`ifdef SIMD
1106
                case(sz)
1107
                        3'd0,3'd4:
1108
                                begin
1109
                                        o[7:0] = a[7:0] - b[7:0];
1110
                                        o[15:8] = a[15:8] - b[15:8];
1111
                                        o[23:16] = a[23:16] - b[23:16];
1112
                                        o[31:24] = a[31:24] - b[31:24];
1113
                                        o[39:32] = a[39:32] - b[39:32];
1114
                                        o[47:40] = a[47:40] - b[47:40];
1115
                                        o[55:48] = a[55:48] - b[55:48];
1116
                                        o[63:56] = a[63:56] - b[63:56];
1117
                                end
1118
                        3'd1,3'd5:
1119
                                begin
1120
                                        o[15:0] = a[15:0] - b[15:0];
1121
                                        o[31:16] = a[31:16] - b[31:16];
1122
                                        o[47:32] = a[47:32] - b[47:32];
1123
                                        o[63:48] = a[63:48] - b[63:48];
1124
                                end
1125
                        3'd2,3'd6:
1126
                                begin
1127
                                        o[31:0] = a[31:0] - b[31:0];
1128
                                        o[63:32] = a[63:32] - b[63:32];
1129
                                end
1130
                    default:
1131
                        begin
1132
                                o[63:0] = a - b;
1133
                        end
1134
                    endcase
1135
`else
1136
                        o = a - b;
1137
`endif
1138
            `SLT:   tskSlt(instr,instr[25:23],a,b,o);
1139
            `SLTU:  tskSltu(instr,instr[25:23],a,b,o);
1140
            `SLE:   tskSle(instr,instr[25:23],a,b,o);
1141
            `SLEU:  tskSleu(instr,instr[25:23],a,b,o);
1142
            `AND:   o = and64;
1143
            `OR:    o = or64;
1144
            `XOR:   o = xor64;
1145
            `NAND:  o = ~and64;
1146
            `NOR:   o = ~or64;
1147
            `XNOR:  o = ~xor64;
1148
            `SEI:   o = a | instr[21:16];
1149
            `RTI:   o = a | instr[21:16];
1150
            `MUX:       for (n = 0; n < 64; n = n + 1)
1151
                            o[n] <= a[n] ? b[n] : c[n];
1152
            `MULU,`MULSU,`MUL:
1153
        case(sz)
1154
        byt_para:               o[63:0] = {prod87[7:0],prod86[7:0],prod85[7:0],prod84[7:0],prod83[7:0],prod82[7:0],prod81[7:0],prod80[7:0]};
1155
        char_para:      o[63:0] = {prod163[15:0],prod162[15:0],prod161[15:0],prod160[15:0]};
1156
                                half_para:      o[63:0] = {prod321[31:0],prod320[31:0]};
1157
                                default:                o[63:0] = prod[DBW-1:0];
1158
                                endcase
1159
                        `FXMUL:
1160
                                case(sz)
1161
                                half_para:      o = {prod321[47:16] + prod321[15],prod320[47:16] + prod320[15]};
1162
                                default:                o = prod[95:32] + prod[31];
1163
                                endcase
1164
                        `MULF:  o = a[23:0] * b[15:0];
1165
            `DIVU:   o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
1166
            `DIVSU:  o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
1167
            `DIV:    o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
1168
            `MODU:   o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
1169
            `MODSU:  o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
1170
            `MOD:    o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
1171
                        `LEAX:
1172
                                        begin
1173
                                        o[63:0] = BIG ? a + (b << instr[22:21]) : 64'hCCCCCCCCEEEEEEEE;
1174
                                        //o[63:44] = PTR;
1175
                                        end
1176
            `MIN:
1177
`ifdef SIMD
1178
                  case(sz)
1179
                                3'd0,3'd4:
1180
                                        begin
1181
                                        o[7:0] = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0]) : 8'hCC;
1182
                                        o[15:8] = BIG ? ($signed(a[15:8]) < $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
1183
                                        o[23:16] = BIG ? ($signed(a[23:16]) < $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
1184
                                        o[31:24] = BIG ? ($signed(a[31:24]) < $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
1185
                                        o[39:32] = BIG ? ($signed(a[39:32]) < $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
1186
                                        o[47:40] = BIG ? ($signed(a[47:40]) < $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
1187
                                        o[55:48] = BIG ? ($signed(a[55:48]) < $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
1188
                                        o[63:56] = BIG ? ($signed(a[63:56]) < $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
1189
                                        end
1190
                                3'd1,3'd5:
1191
                                        begin
1192
                                        o[15:0] = BIG ? ($signed(a[15:0]) < $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
1193
                                        o[32:16] = BIG ? ($signed(a[32:16]) < $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
1194
                                        o[47:32] = BIG ? ($signed(a[47:32]) < $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
1195
                                        o[63:48] = BIG ? ($signed(a[63:48]) < $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
1196
                                        end
1197
                                3'd2,3'd6:
1198
                                        begin
1199
                                        o[31:0] = BIG ? ($signed(a[31:0]) < $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
1200
                                        o[63:32] = BIG ? ($signed(a[63:32]) < $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
1201
                                        end
1202
                                        3'd3,3'd7:
1203
                                                begin
1204
                                        o[63:0] = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
1205
                                        end
1206
                                endcase
1207
`else
1208
                        o[63:0] = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
1209
`endif
1210
            `MAX:
1211
`ifdef SIMD
1212
                                case(sz)
1213
                                3'd0,3'd4:
1214
                                        begin
1215
                                        o[7:0] = BIG ? ($signed(a[7:0]) > $signed(b[7:0]) ? a[7:0] : b[7:0]) : 64'hCCCCCCCCCCCCCCCC;
1216
                                        o[15:8] = BIG ? ($signed(a[15:8]) > $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
1217
                                        o[23:16] = BIG ? ($signed(a[23:16]) > $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
1218
                                        o[31:24] = BIG ? ($signed(a[31:24]) > $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
1219
                                        o[39:32] = BIG ? ($signed(a[39:32]) > $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
1220
                                        o[47:40] = BIG ? ($signed(a[47:40]) > $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
1221
                                        o[55:48] = BIG ? ($signed(a[55:48]) > $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
1222
                                        o[63:56] = BIG ? ($signed(a[63:56]) > $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
1223
                                        end
1224
                                3'd1,3'd5:
1225
                                        begin
1226
                                        o[15:0] = BIG ? ($signed(a[15:0]) > $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
1227
                                        o[32:16] = BIG ? ($signed(a[32:16]) > $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
1228
                                        o[47:32] = BIG ? ($signed(a[47:32]) > $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
1229
                                        o[63:48] = BIG ? ($signed(a[63:48]) > $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
1230
                                        end
1231
                                3'd2,3'd6:
1232
                                        begin
1233
                                        o[31:0] = BIG ? ($signed(a[31:0]) > $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
1234
                                        o[63:32] = BIG ? ($signed(a[63:32]) > $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
1235
                                        end
1236
                                        3'd3,3'd7:
1237
                                                begin
1238
                                        o[63:0] = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
1239
                                        end
1240
                                endcase
1241
`else
1242
                        o[63:0] = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
1243
`endif
1244
            `MAJ:               o = (a & b) | (a & c) | (b & c);
1245
            `CHK:       o[63:0] = (a >= b && a < c);
1246
            /*
1247
            `RTOP:              case(c[5:0])
1248
                                `RTADD: o = a + b;
1249
                                `RTSUB: o = a - b;
1250
                                `RTAND: o = and64;
1251
                                `RTOR:  o = or64;
1252
                                `RTXOR: o = xor64;
1253
                                `RTNAND:        o = ~and64;
1254
                                `RTNOR: o = ~or64;
1255
                                `RTXNOR:        o = ~xor64;
1256
                                `RTSLT: o = as < bs;
1257
                                `RTSGE: o = as >= bs;
1258
                                `RTSLE: o = as <= bs;
1259
                                `RTSGT: o = as > bs;
1260
                                `RTSEQ: o = as==bs;
1261
                                `RTSNE: o = as!=bs;
1262
                                endcase
1263
            */
1264
            `TLB:               o = BIG ? tlbo : 64'hDEADDEADDEADDEAD;
1265
            default:    o[63:0] = 64'hDEADDEADDEADDEAD;
1266
            endcase
1267
`MEMNDX:
1268
        if (instr[7:6]==2'b10) begin
1269
                if (instr[31])
1270
                        case({instr[31:28],instr[17:16]})
1271
                        `PUSH:
1272
                                begin
1273
                                        usa = a - 4'd8;
1274
                                        o = {pb[50:0],13'd0} + usa;
1275
                                end
1276
            default:    o = 64'hDEADDEADDEADDEAD;
1277
                        endcase
1278
                else
1279
                        o = 64'hDEADDEADDEADDEAD;
1280
        end
1281
        else if (instr[7:6]==2'b00) begin
1282
                if (!instr[31])
1283
                        case({instr[31:28],instr[22:21]})
1284
                        `CACHEX,`LVX,
1285
            `LBX,`LBUX,`LCX,`LCUX,
1286
            `LVBX,`LVBUX,`LVCX,`LVCUX,`LVHX,`LVHUX,`LVWX,
1287
            `LHX,`LHUX,`LWX,`LWRX:
1288
                                        if (BIG) begin
1289
                                                usa = a + (c << instr[19:18]);
1290
                                                o = {pb[50:0],13'd0} + usa;
1291
                                        end
1292
                                        else
1293
                                                o = 64'hCCCCCCCCEEEEEEEE;
1294
            `LVX,`SVX:
1295
                if (BIG) begin
1296
                        usa = a + (c << 2'd3);
1297
                        o = {pb[50:0],13'd0} + usa;
1298
                end
1299
                else
1300
                        o = 64'hCCCCCCCCCCCCCCCC;
1301
            `LVWS,`SVWS:
1302
                                if (BIG) begin
1303
                                        usa = a + ({c * ven,3'b000});
1304
                                        o = {pb[50:0],13'd0} + usa;
1305
                                end
1306
                                else
1307
                                        o = 64'hCCCCCCCCCCCCCCCC;
1308
            default:    o = 64'hDEADDEADDEADDEAD;
1309
                        endcase
1310
                else
1311
                        case({instr[31:28],instr[17:16]})
1312
                        `PUSH:
1313
                                begin
1314
                                        usa = a - 4'd8;
1315
                                        o = {pb[50:0],13'd0} + usa;
1316
                                end
1317
            `SBX,`SCX,`SHX,`SWX,`SWCX:
1318
                                        if (BIG) begin
1319
                                                usa = a + (c << instr[14:13]);
1320
                                                o = {pb[50:0],13'd0} + usa;
1321
                                        end
1322
                                        else
1323
                                                o = 64'hCCCCCCCCEEEEEEEE;
1324
            `SVX:  if (BIG) begin
1325
                                        usa = a + (c << 2'd3);
1326
                                        o = {pb[50:0],13'd0} + usa;
1327
                                end
1328
                                else
1329
                                        o = 64'hCCCCCCCCCCCCCCCC;
1330
            `SVWS:
1331
                                if (BIG) begin
1332
                                        usa = a + ({c * ven,3'b000});
1333
                                        o = {pb[50:0],13'd0} + usa;
1334
                                end
1335
                                else
1336
                                        o = 64'hCCCCCCCCCCCCCCCC;
1337
            default:    o = 64'hDEADDEADDEADDEAD;
1338
                        endcase
1339
        end
1340
        else
1341
                o[63:0] = 64'hDEADDEADDEADDEAD;
1342
`AUIPC:
1343
        begin
1344
                if (instr[7:6]==2'b01)
1345
                        o[63:0] = pc + {instr[47:18],instr[12:8],30'd0};
1346
                else
1347
                        o[63:0] = pc + {{15{instr[31]}},instr[31:18],instr[12:8],30'd0};
1348
                o[29:0] = 30'd0;
1349
//              o[63:44] = PTR;
1350
        end
1351
`LUI:
1352
        begin
1353
                if (instr[7:6]==2'b01)
1354
                        o = {instr[47:18],instr[12:8],30'd0};
1355
                else
1356
                        o = {{15{instr[31]}},instr[31:18],instr[12:8],30'd0};
1357
        end
1358
`ADDI:  o = a + b;
1359
`SLTI:  o = $signed(a) < $signed(b);
1360
`SLTUI: o = a < b;
1361
`SGTI:  o = $signed(a) > $signed(b);
1362
`SGTUI: o = a > b;
1363
`ANDI:  o = a & andb;
1364
`ORI:           o = a | orb;
1365
`XORI:  o = a ^ orb;
1366
`XNORI: o = ~(a ^ orb);
1367
`MULUI: o = prod[DBW-1:0];
1368
`MULI:  o = prod[DBW-1:0];
1369
`MULFI: o = a[23:0] * b[15:0];
1370
`DIVUI:         o = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
1371
`DIVI:          o = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
1372
`MODI:          o = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
1373
`LB,`LBU,`SB:
1374
        begin
1375
                usa = a + b;
1376
                o = {pb[50:0],13'd0} + usa;
1377
        end
1378
`Lx,`LxU,`Sx,`LVx,`LVxU:
1379
                        begin
1380
                                casez(b[2:0])
1381
                                3'b100:
1382
                                        begin
1383
                                                usa = a + {b[63:3],3'b0};       // LW / SW
1384
                                                o = {pb[50:0],13'd0} + usa;
1385
                                        end
1386
                                3'b?10:
1387
                                        begin
1388
                                                usa = a + {b[63:2],2'b0};       // LH / LHU / SH
1389
                                                o = {pb[50:0],13'd0} + usa;
1390
                                        end
1391
                                default:
1392
                                        begin
1393
                                                usa = a + {b[63:1],1'b0};       // LC / LCU / SC
1394
                                                o = {pb[50:0],13'd0} + usa;
1395
                                        end
1396
                                endcase
1397
                        end
1398
`LWR,`SWC,`CAS,`CACHE:
1399
                        begin
1400
                                usa = a + b;
1401
                                o = {pb[50:0],13'd0} + usa;
1402
                        end
1403
`LV,`SV:
1404
                        begin
1405
                                usa = a + b + {ven,3'b0};
1406
                                o = {pb[50:0],13'd0} + usa;
1407
                        end
1408
`CSRRW:
1409
                        case(instr[27:18])
1410
                        10'h044: o = BIG ? (csr | {39'd0,thrd,24'h0}) : 64'hDDDDDDDDDDDDDDDD;
1411
                        default:        o = BIG ? csr : 64'hDDDDDDDDDDDDDDDD;
1412
                        endcase
1413
`BITFIELD:  o = BIG ? bfout : 64'hCCCCCCCCCCCCCCCC;
1414
default:    o = 64'hDEADDEADDEADDEAD;
1415
endcase
1416
end
1417
 
1418
always @(posedge clk)
1419
if (rst)
1420
        adrDone <= TRUE;
1421
else begin
1422
        if (ld)
1423
                adrDone <= FALSE;
1424
        else if (mem|shift)
1425
                adrDone <= TRUE;
1426
end
1427
 
1428
always @(posedge clk)
1429
if (rst)
1430
        adrIdle <= TRUE;
1431
else begin
1432
        if (ld)
1433
                adrIdle <= FALSE;
1434
        else if (mem|shift)
1435
                adrIdle <= TRUE;
1436
end
1437
 
1438
always @(posedge clk)
1439
case(instr[`INSTRUCTION_OP])
1440
`R2:
1441
        if (instr[`INSTRUCTION_L2]==2'b01)
1442
                case(instr[47:42])
1443
                `ADD,`SUB,
1444
                `AND,`OR,`XOR,`NAND,`NOR,`XNOR,
1445
                `SHIFTR:
1446
                        case(instr[41:36])
1447
                        `R1:
1448
                                case(instr[22:18])
1449
                                `COM:   addro[63:0] = ~shift8;
1450
                                `NOT:   addro[63:0] = ~|shift8;
1451
                                `NEG:   addro[63:0] = -shift8;
1452
                                default:        addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
1453
                                endcase
1454
                        `ADD:   addro[63:0] = shift8 + c;
1455
                        `SUB:   addro[63:0] = shift8 - c;
1456
                        `AND:   addro[63:0] = shift8 & c;
1457
                        `OR:    addro[63:0] = shift8 | c;
1458
                        `XOR:   addro[63:0] = shift8 ^ c;
1459
                        default:        addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
1460
                        endcase
1461
                default:        addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
1462
                endcase
1463
        else
1464
           addro = 64'hCCCCCCCCCCCCCCCE;
1465
default:        addro = 64'hCCCCCCCCCCCCCCCE;
1466
endcase
1467
 
1468
reg sao_done, sao_idle;
1469
always @(posedge clk)
1470
if (rst) begin
1471
        sao_done <= 1'b1;
1472
        sao_idle <= 1'b1;
1473
end
1474
else begin
1475
if (ld & IsShiftAndOp(instr) & BIG) begin
1476
        sao_done <= 1'b0;
1477
        sao_idle <= 1'b0;
1478
end
1479
else begin
1480
        if (IsShiftAndOp(instr) & BIG) begin
1481
                sao_done <= 1'b1;
1482
                sao_idle <= 1'b1;
1483
        end
1484
end
1485
end
1486
 
1487
// Generate done signal
1488
always @*
1489
if (rst)
1490
        done <= TRUE;
1491
else begin
1492
        if (IsMul(instr)) begin
1493
                case(sz)
1494
                byt,byt_para:   done <= mult_done80;
1495
                char,char_para: done <= mult_done160;
1496
                half,half_para: done <= mult_done320;
1497
                default:        done <= mult_done;
1498
                endcase
1499
        end
1500
        else if (IsDivmod(instr) & BIG)
1501
                done <= div_done;
1502
        else if (IsShiftAndOp(instr) & BIG)
1503
                done <= sao_done;
1504
        else if (shift)
1505
                done <= adrDone;
1506
        else if (tlb & BIG)
1507
                done <= tlb_done;
1508
        else
1509
                done <= TRUE;
1510
end
1511
 
1512
// Generate idle signal
1513
always @*
1514
if (rst)
1515
        idle <= TRUE;
1516
else begin
1517
        if (IsMul(instr)) begin
1518
                case(sz)
1519
                byt,byt_para:   idle <= mult_idle80;
1520
                char,char_para: idle <= mult_idle160;
1521
                half,half_para: idle <= mult_idle320;
1522
                default:        idle <= mult_idle;
1523
                endcase
1524
        end
1525
        else if (IsDivmod(instr) & BIG)
1526
                idle <= div_idle;
1527
        else if (IsShiftAndOp(instr) & BIG)
1528
                idle <= sao_idle;
1529
        else if (shift)
1530
                idle <= adrIdle;
1531
        else if (tlb & BIG)
1532
                idle <= tlb_idle;
1533
        else
1534
                idle <= TRUE;
1535
end
1536
 
1537
function fnOverflow;
1538
input op;   // 0 = add, 1=sub
1539
input a;
1540
input b;
1541
input s;
1542
fnOverflow = (op ^ s ^ b) & (~op ^ a ^ b);
1543
endfunction
1544
 
1545
always @*
1546
begin
1547
//if ((tgt[4:0]==5'd31 || tgt[4:0]==5'd30) && (o[ABW-1:0] < {sbl[50:13],13'd0} || o[ABW-1:0] > {pl[50:0],13'h1FFF}))
1548
//    exc <= `FLT_STK;
1549
//else
1550
case(instr[`INSTRUCTION_OP])
1551
`R2:
1552
    case(instr[`INSTRUCTION_S2])
1553
    `ADD:   exc <= (fnOverflow(0,a[63],b[63],o[63]) & excen[0] & instr[24]) ? `FLT_OFL : `FLT_NONE;
1554
    `SUB:   exc <= (fnOverflow(1,a[63],b[63],o[63]) & excen[1] & instr[24]) ? `FLT_OFL : `FLT_NONE;
1555
//    `ASL,`ASLI:     exc <= (BIG & aslo & excen[2]) ? `FLT_OFL : `FLT_NONE;
1556
    `MUL,`MULSU:    exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF && excen[3] ? `FLT_OFL : `FLT_NONE ):
1557
                           (prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE);
1558
    `FXMUL:     exc <= prod[95] ? (prod[127:96] != 32'hFFFFFFFF && excen[3] ? `FLT_OFL : `FLT_NONE ):
1559
                           (prod[127:96] != 32'd0 && excen[3] ? `FLT_OFL : `FLT_NONE);
1560
    `MULU:      exc <= prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE;
1561
    `DIV,`DIVSU,`DIVU: exc <= BIG && excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
1562
    `MOD,`MODSU,`MODU: exc <= BIG && excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
1563
    default:    exc <= `FLT_NONE;
1564
    endcase
1565
`MULI:    exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF & excen[3] ? `FLT_OFL : `FLT_NONE):
1566
                                    (prod[127:64] != 64'd0 & excen[3] ? `FLT_OFL : `FLT_NONE);
1567
`DIVI: exc <= BIG & excen[4] & divByZero & instr[27] ? `FLT_DBZ : `FLT_NONE;
1568
`MODI: exc <= BIG & excen[4] & divByZero & instr[27] ? `FLT_DBZ : `FLT_NONE;
1569
`CSRRW: exc <= (instr[27:21]==7'b0011011) ? `FLT_SEG : `FLT_NONE;
1570
`MEMNDX:
1571
        begin
1572
`ifdef SUPPORT_SEGMENTATION
1573
                if (usa < {lb[50:0],13'h0000} && usa > {ub[50:0],13'h1fff} && dl!=2'b00)
1574
                        exc <= (Ra[4:0]==5'd30 || Ra[4:0]==5'd31) ? `FLT_STK : `FLT_SGB;
1575
                else
1576
`endif
1577
`ifdef SUPPORT_BBMS
1578
                if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
1579
                        exc <= `FLT_STK;
1580
                else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
1581
                        exc <= `FLT_SGB;
1582
                else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
1583
                        exc <= `FLT_SGB;
1584
                else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
1585
                        exc <= `FLT_SGB;
1586
                else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
1587
                        exc <= `FLT_WRV;
1588
                else
1589
`endif
1590
                begin
1591
                        if (instr[7:6]==2'b10) begin
1592
                                if (instr[31])
1593
                                        case({instr[31:28],instr[17:16]})
1594
                                        `PUSH:          exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1595
                            default:    exc <= `FLT_UNIMP;
1596
                                        endcase
1597
                                else
1598
                                        exc <= `FLT_UNIMP;
1599
                        end
1600
                        else if (instr[7:6]==2'b00) begin
1601
                                if (!instr[31]) begin
1602
                                        if (BIG) begin
1603
                                                case({instr[31:28],instr[22:21]})
1604
                                                `LBX,`LBUX,`LVBX,`LVBUX:        exc <= `FLT_NONE;
1605
                                    `LCX,`LCUX,`LVCX,`LVCUX:    exc <= |o[  0] ? `FLT_ALN : `FLT_NONE;
1606
                                    `LVHX,`LVHUX,`LHX,`LHUX:    exc <= |o[1:0] ? `FLT_ALN : `FLT_NONE;
1607
                                    `LWX,`LVWX,`LWRX,
1608
                                                `CACHEX,`LVX:                                                   exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1609
                                    `LVX,`SVX,`LVWS,`SVWS:              exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1610
                                    default:    exc <= `FLT_UNIMP;
1611
                                                endcase
1612
                                        end
1613
                                        else
1614
                                                exc <= `FLT_UNIMP;
1615
                                end
1616
                                else begin
1617
                                        if (BIG) begin
1618
                                                case({instr[31:28],instr[17:16]})
1619
                                                `PUSH:  exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1620
                                                `SBX:           exc <= `FLT_NONE;
1621
                                    `SCX:               exc <= |o[  0] ? `FLT_ALN : `FLT_NONE;
1622
                                    `SHX:               exc <= |o[1:0] ? `FLT_ALN : `FLT_NONE;
1623
                                    `SWX,`SWCX: exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1624
                                    `SVX:       exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1625
                                    `SVWS:      exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1626
                                    default:    exc <= `FLT_UNIMP;
1627
                                                endcase
1628
                                        end
1629
                                        else
1630
                                                exc <= `FLT_UNIMP;
1631
                                end
1632
                        end
1633
                        else
1634
                                exc <= `FLT_UNIMP;
1635
                end
1636
        end
1637
`ifdef SUPPORT_SEGMENTATION
1638
`LB,`LBU,`SB:
1639
                if (usa < {lb[50:0],13'h0000} && usa > {ub[50:0],13'h1fff} && dl!=2'b00)
1640
                        exc <= (Ra[4:0]==5'd30 || Ra[4:0]==5'd31) ? `FLT_STK : `FLT_SGB;
1641
`endif
1642
`ifdef SUPPORT_BBMS
1643
`LB,`LBU,`SB:
1644
                if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
1645
                        exc <= `FLT_STK;
1646
                else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
1647
                        exc <= `FLT_SGB;
1648
                else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
1649
                        exc <= `FLT_SGB;
1650
                else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
1651
                        exc <= `FLT_SGB;
1652
                else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
1653
                        exc <= `FLT_WRV;
1654
`endif
1655
`Lx,`Sx,`LxU,`LVx,`LVxU:
1656
        begin
1657
`ifdef SUPPORT_SEGMENTATION
1658
                if (usa < {lb[50:0],13'h0000} && usa > {ub[50:0],13'h1fff} && dl!=2'b00)
1659
                        exc <= (Ra[4:0]==5'd30 || Ra[4:0]==5'd31) ? `FLT_STK : `FLT_SGB;
1660
                else
1661
`endif
1662
`ifdef SUPPORT_BBMS
1663
                if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
1664
                        exc <= `FLT_STK;
1665
                else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
1666
                        exc <= `FLT_SGB;
1667
                else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
1668
                        exc <= `FLT_SGB;
1669
                else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
1670
                        exc <= `FLT_SGB;
1671
                else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
1672
                        exc <= `FLT_WRV;
1673
                else
1674
`endif
1675
                        casez(b[2:0])
1676
                        3'b100:         exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;   // LW / SW
1677
                        3'b?10:         exc <= |o[1:0] ? `FLT_ALN : `FLT_NONE;   // LH / LHU / SH
1678
                        default:        exc <= |o[  0] ? `FLT_ALN : `FLT_NONE;   // LC / LCU / SC
1679
                        endcase
1680
        end
1681
`LWR,`SWC,`CAS,`CACHE:
1682
        begin
1683
`ifdef SUPPORT_SEGMENTATION
1684
                if (usa < {lb[50:0],13'h0000} && usa > {ub[50:0],13'h1fff} && dl!=2'b00)
1685
                        exc <= (Ra[4:0]==5'd30 || Ra[4:0]==5'd31) ? `FLT_STK : `FLT_SGB;
1686
                else
1687
`endif
1688
`ifdef SUPPORT_BBMS
1689
                if ((Ra[4:0]==5'd30 || Ra[4:0]==5'd31) && (usa < {sbl[50:0],13'd0} || usa > {sbu[50:0],13'h1FF8}) && dl!=2'b00)
1690
                        exc <= `FLT_STK;
1691
                else if (usa > {sbu[50:0],13'h1FFF} && dl!=2'b00)
1692
                        exc <= `FLT_SGB;
1693
                else if (usa < {sbl[50:0],13'h0000} && usa > {dbu[50:0],13'h1fff} && dl!=2'b00)
1694
                        exc <= `FLT_SGB;
1695
                else if (usa > {en[50:0],13'h1fff} && usa < {dbl[50:0],13'd0} && dl!=2'b00)
1696
                        exc <= `FLT_SGB;
1697
                else if (usa < {ro[50:0],13'd0} && store && dl!=2'b00)
1698
                        exc <= `FLT_WRV;
1699
                else
1700
`endif
1701
                        exc <= |o[2:0] ? `FLT_ALN : `FLT_NONE;
1702
        end
1703
default:    exc <= `FLT_NONE;
1704
endcase
1705
end
1706
 
1707
reg [63:0] aa, bb;
1708
 
1709
always @(posedge clk)
1710
begin
1711
        aa <= shfto;
1712
        bb <= c;
1713
end
1714
 
1715
task tskSlt;
1716
input [47:0] instr;
1717
input [2:0] sz;
1718
input [63:0] a;
1719
input [63:0] b;
1720
output [63:0] o;
1721
begin
1722
`ifdef SIMD
1723
        case(sz[2:0])
1724
  3'd0:   o[63:0] = $signed(a[7:0]) < $signed(b[7:0]);
1725
  3'd1:   o[63:0] = $signed(a[15:0]) < $signed(b[15:0]);
1726
  3'd2:   o[63:0] = $signed(a[31:0]) < $signed(b[31:0]);
1727
  3'd3:   o[63:0] = $signed(a) < $signed(b);
1728
  3'd4:         o[63:0] = {
1729
                                                        7'h0,$signed(a[7:0]) < $signed(b[7:0]),
1730
                                                        7'h0,$signed(a[15:8]) < $signed(b[15:8]),
1731
                                                        7'h0,$signed(a[23:16]) < $signed(b[23:16]),
1732
                                                        7'h0,$signed(a[31:24]) < $signed(b[31:24]),
1733
                                                        7'h0,$signed(a[39:32]) < $signed(b[39:32]),
1734
                                                        7'h0,$signed(a[47:40]) < $signed(b[47:40]),
1735
                                                        7'h0,$signed(a[55:48]) < $signed(b[55:48]),
1736
                                                        7'h0,$signed(a[63:56]) < $signed(b[63:56])
1737
                                                        };
1738
  3'd5:         o[63:0] = {
1739
                                                        15'h0,$signed(a[15:0]) < $signed(b[15:0]),
1740
                                                        15'h0,$signed(a[31:16]) < $signed(b[31:16]),
1741
                                                        15'h0,$signed(a[47:32]) < $signed(b[47:32]),
1742
                                                        15'h0,$signed(a[63:48]) < $signed(b[63:48])
1743
                                                        };
1744
  3'd6:         o[63:0] = {
1745
                                                        31'h0,$signed(a[31:0]) < $signed(b[31:0]),
1746
                                                        31'h0,$signed(a[63:32]) < $signed(b[63:32])
1747
                                                        };
1748
        3'd7:           o[63:0] = $signed(a[63:0]) < $signed(b[63:0]);
1749
  endcase
1750
`else
1751
        o[63:0] = $signed(a[63:0]) < $signed(b[63:0]);
1752
`endif
1753
end
1754
endtask
1755
 
1756
task tskSle;
1757
input [47:0] instr;
1758
input [2:0] sz;
1759
input [63:0] a;
1760
input [63:0] b;
1761
output [63:0] o;
1762
begin
1763
`ifdef SIMD
1764
        case(sz[2:0])
1765
  3'd0:   o[63:0] = $signed(a[7:0]) <= $signed(b[7:0]);
1766
  3'd1:   o[63:0] = $signed(a[15:0]) <= $signed(b[15:0]);
1767
  3'd2:   o[63:0] = $signed(a[31:0]) <= $signed(b[31:0]);
1768
  3'd3:   o[63:0] = $signed(a) <= $signed(b);
1769
  3'd4:         o[63:0] = {
1770
                                                        7'h0,$signed(a[7:0]) <= $signed(b[7:0]),
1771
                                                        7'h0,$signed(a[15:8]) <= $signed(b[15:8]),
1772
                                                        7'h0,$signed(a[23:16]) <= $signed(b[23:16]),
1773
                                                        7'h0,$signed(a[31:24]) <= $signed(b[31:24]),
1774
                                                        7'h0,$signed(a[39:32]) <= $signed(b[39:32]),
1775
                                                        7'h0,$signed(a[47:40]) <= $signed(b[47:40]),
1776
                                                        7'h0,$signed(a[55:48]) <= $signed(b[55:48]),
1777
                                                        7'h0,$signed(a[63:56]) <= $signed(b[63:56])
1778
                                                        };
1779
  3'd5:         o[63:0] = {
1780
                                                        15'h0,$signed(a[15:0]) <= $signed(b[15:0]),
1781
                                                        15'h0,$signed(a[31:16]) <= $signed(b[31:16]),
1782
                                                        15'h0,$signed(a[47:32]) <= $signed(b[47:32]),
1783
                                                        15'h0,$signed(a[63:48]) <= $signed(b[63:48])
1784
                                                        };
1785
  3'd6:         o[63:0] = {
1786
                                                        31'h0,$signed(a[31:0]) <= $signed(b[31:0]),
1787
                                                        31'h0,$signed(a[63:32]) <= $signed(b[63:32])
1788
                                                        };
1789
        3'd7:           o[63:0] = $signed(a[63:0]) <= $signed(b[63:0]);
1790
  endcase
1791
`else
1792
        o[63:0] = $signed(a[63:0]) <= $signed(b[63:0]);
1793
`endif
1794
end
1795
endtask
1796
 
1797
task tskSltu;
1798
input [47:0] instr;
1799
input [2:0] sz;
1800
input [63:0] a;
1801
input [63:0] b;
1802
output [63:0] o;
1803
begin
1804
`ifdef SIMD
1805
        case(sz[2:0])
1806
  3'd4,3'd0:            o = {
1807
                                                        7'h0,(a[7:0]) < (b[7:0]),
1808
                                                        7'h0,(a[15:8]) < (b[15:8]),
1809
                                                        7'h0,(a[23:16]) < (b[23:16]),
1810
                                                        7'h0,(a[31:24]) < (b[31:24]),
1811
                                                        7'h0,(a[39:32]) < (b[39:32]),
1812
                                                        7'h0,(a[47:40]) < (b[47:40]),
1813
                                                        7'h0,(a[55:48]) < (b[55:48]),
1814
                                                        7'h0,(a[63:56]) < (b[63:56])
1815
                                                        };
1816
  3'd5,3'd1:            o = {
1817
                                                        15'h0,(a[15:0]) < (b[15:0]),
1818
                                                        15'h0,(a[31:16]) < (b[31:16]),
1819
                                                        15'h0,(a[47:32]) < (b[47:32]),
1820
                                                        15'h0,(a[63:48]) < (b[63:48])
1821
                                                        };
1822
  3'd6,3'd2:            o = {
1823
                                                        31'h0,(a[31:0]) < (b[31:0]),
1824
                                                        31'h0,(a[63:32]) < (b[63:32])
1825
                                                        };
1826
        3'd7,3'd3:              o = (a[63:0]) < (b[63:0]);
1827
  endcase
1828
`else
1829
        o = (a) < (b);
1830
`endif
1831
end
1832
endtask
1833
 
1834
task tskSleu;
1835
input [47:0] instr;
1836
input [2:0] sz;
1837
input [63:0] a;
1838
input [63:0] b;
1839
output [63:0] o;
1840
begin
1841
`ifdef SIMD
1842
        case(sz[2:0])
1843
  3'd0:   o[63:0] = (a[7:0]) <= (b[7:0]);
1844
  3'd1:   o[63:0] = (a[15:0]) <= (b[15:0]);
1845
  3'd2:   o[63:0] = (a[31:0]) <= (b[31:0]);
1846
  3'd3:   o[63:0] = (a) <= (b);
1847
  3'd4:         o[63:0] = {
1848
                                                        7'h0,(a[7:0]) <= (b[7:0]),
1849
                                                        7'h0,(a[15:8]) <= (b[15:8]),
1850
                                                        7'h0,(a[23:16]) <= (b[23:16]),
1851
                                                        7'h0,(a[31:24]) <= (b[31:24]),
1852
                                                        7'h0,(a[39:32]) <= (b[39:32]),
1853
                                                        7'h0,(a[47:40]) <= (b[47:40]),
1854
                                                        7'h0,(a[55:48]) <= (b[55:48]),
1855
                                                        7'h0,(a[63:56]) <= (b[63:56])
1856
                                                        };
1857
  3'd5:         o[63:0] = {
1858
                                                        15'h0,(a[15:0]) <= (b[15:0]),
1859
                                                        15'h0,(a[31:16]) <= (b[31:16]),
1860
                                                        15'h0,(a[47:32]) <= (b[47:32]),
1861
                                                        15'h0,(a[63:48]) <= (b[63:48])
1862
                                                        };
1863
  3'd6:         o[63:0] = {
1864
                                                        31'h0,(a[31:0]) <= (b[31:0]),
1865
                                                        31'h0,(a[63:32]) <= (b[63:32])
1866
                                                        };
1867
        3'd7:           o[63:0] = (a[63:0]) <= (b[63:0]);
1868
  endcase
1869
`else
1870
        o[63:0] = (a[63:0]) <= (b[63:0]);
1871
`endif
1872
end
1873
endtask
1874
 
1875
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.