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

Subversion Repositories thor

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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