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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v5/] [rtl/] [common/] [FT64_alu.v] - Blame information for rev 51

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

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

powered by: WebSVN 2.1.0

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