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

Subversion Repositories thor

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

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

powered by: WebSVN 2.1.0

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