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

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64/] [rtl/] [common/] [FT64alu.v] - Blame information for rev 43

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 43 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
//      FT64alu.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 FT64alu(rst, clk, ld, abort, instr, a, b, c, imm, tgt, tgt2, ven, vm, sbl, sbu,
28
    csr, o, ob, done, idle, excen, exc, thrd);
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
input rst;
35
input clk;
36
input ld;
37
input abort;
38
input [31:0] instr;
39
input [63:0] a;
40
input [63:0] b;
41
input [63:0] c;
42
input [63:0] imm;
43
input [7:0] tgt;
44
input [7:0] tgt2;
45
input [5:0] ven;
46
input [15:0] vm;
47
input [31:0] sbl;
48
input [31:0] sbu;
49
input [63:0] csr;
50
output reg [63:0] o;
51
output reg [63:0] ob;
52
output reg done;
53
output reg idle;
54
input [4:0] excen;
55
output reg [8:0] exc;
56
input thrd;
57
integer n;
58
 
59
wire [DBW-1:0] divq, rem;
60
wire divByZero;
61
wire [DBW*2-1:0] prod;
62
wire mult_done, mult_idle, div_done, div_idle;
63
wire aslo;
64
wire [6:0] clzo,cloo,cpopo;
65
wire [63:0] shftho;
66
 
67
function IsMul;
68
input [31:0] isn;
69
case(isn[`INSTRUCTION_OP])
70
`VECTOR:
71
    case(isn[`INSTRUCTION_S2])
72
    `VMUL,`VMULS:   IsMul = TRUE;
73
    default:    IsMul = FALSE;
74
    endcase
75
`RR:
76
    case(isn[`INSTRUCTION_S2])
77
    `MULU,`MULSU,`MUL: IsMul = TRUE;
78
    default:    IsMul = FALSE;
79
    endcase
80
`MULUI,`MULSUI,`MULI:  IsMul = TRUE;
81
default:    IsMul = FALSE;
82
endcase
83
endfunction
84
 
85
function IsDivmod;
86
input [31:0] isn;
87
case(isn[`INSTRUCTION_OP])
88
`VECTOR:
89
    case(isn[`INSTRUCTION_S2])
90
    `VDIV,`VDIVS:   IsDivmod = TRUE;
91
    default:    IsDivmod = FALSE;
92
    endcase
93
`RR:
94
    case(isn[`INSTRUCTION_S2])
95
    `DIVMODU,`DIVMODSU,`DIVMOD: IsDivmod = TRUE;
96
    default:    IsDivmod = FALSE;
97
    endcase
98
`DIVUI,`DIVSUI,`DIVI,`MODUI,`MODSUI,`MODI:  IsDivmod = TRUE;
99
default:    IsDivmod = FALSE;
100
endcase
101
endfunction
102
 
103
function IsSgn;
104
input [31:0] isn;
105
case(isn[`INSTRUCTION_OP])
106
`VECTOR:
107
    case(isn[`INSTRUCTION_S2])
108
    `VMUL,`VMULS,`VDIV,`VDIVS:    IsSgn = TRUE;
109
    default:    IsSgn = FALSE;
110
    endcase
111
`RR:
112
    case(isn[`INSTRUCTION_S2])
113
    `MUL,`DIVMOD:   IsSgn = TRUE;
114
    default:    IsSgn = FALSE;
115
    endcase
116
`MULI,`DIVI,`MODI:    IsSgn = TRUE;
117
default:    IsSgn = FALSE;
118
endcase
119
endfunction
120
 
121
function IsSgnus;
122
input [31:0] isn;
123
case(isn[`INSTRUCTION_OP])
124
`RR:
125
    case(isn[`INSTRUCTION_S2])
126
    `MULSU,`DIVMODSU:   IsSgnus = TRUE;
127
    default:    IsSgnus = FALSE;
128
    endcase
129
`MULSUI,`DIVSUI,`MODSUI:    IsSgnus = TRUE;
130
default:    IsSgnus = FALSE;
131
endcase
132
endfunction
133
 
134
wire [2:0] sz =
135
    instr[`INSTRUCTION_OP]==`VECTOR ? 2'd3 :
136
    instr[`INSTRUCTION_S2]==`R1 ? instr[18:16] : instr[23:21];
137
 
138
wire [63:0] bfout,shfto;
139
wire [63:0] shftob;
140
wire [63:0] shftco;
141
 
142
FT64_bitfield #(DBW) ubf1
143
(
144
    .inst(instr),
145
    .a(a),
146
    .b(b),
147
    .o(bfout),
148
    .masko()
149
);
150
 
151
FT64_multiplier #(DBW) umult1
152
(
153
        .rst(rst),
154
        .clk(clk),
155
        .ld(ld && IsMul(instr)),
156
        .abort(abort),
157
        .sgn(IsSgn(instr)),
158
        .sgnus(IsSgnus(instr)),
159
        .a(a),
160
        .b(b),
161
        .o(prod),
162
        .done(mult_done),
163
        .idle(mult_idle)
164
);
165
 
166
FT64_divider #(DBW) udiv1
167
(
168
        .rst(rst),
169
        .clk(clk),
170
        .ld(ld && IsDivmod(instr)),
171
        .abort(abort),
172
        .sgn(IsSgn(instr)),
173
        .sgnus(IsSgnus(instr)),
174
        .a(a),
175
        .b(b),
176
        .qo(divq),
177
        .ro(rem),
178
        .dvByZr(divByZero),
179
        .done(div_done),
180
        .idle(div_idle)
181
);
182
 
183
FT64_shift ushft1
184
(
185
    .instr(instr),
186
    .a(a),
187
    .b(b),
188
    .res(shfto),
189
    .ov(aslo)
190
);
191
 
192
FT64_shifth ushfthL
193
(
194
    .instr(instr),
195
    .a(a[31:0]),
196
    .b(b[31:0]),
197
    .res(shftho[31:0]),
198
    .ov()
199
);
200
 
201
FT64_shifth ushfthH
202
(
203
    .instr(instr),
204
    .a(a[63:32]),
205
    .b(b[63:32]),
206
    .res(shftho[63:32]),
207
    .ov()
208
);
209
 
210
FT64_shiftc ushftc0
211
(
212
    .instr(instr),
213
    .a(a[15:0]),
214
    .b(b[15:0]),
215
    .res(shftco[15:0]),
216
    .ov()
217
);
218
 
219
FT64_shiftc ushftc1
220
(
221
    .instr(instr),
222
    .a(a[31:16]),
223
    .b(b[31:16]),
224
    .res(shftco[31:16]),
225
    .ov()
226
);
227
 
228
FT64_shiftc ushftc2
229
(
230
    .instr(instr),
231
    .a(a[47:32]),
232
    .b(b[47:32]),
233
    .res(shftco[47:32]),
234
    .ov()
235
);
236
 
237
FT64_shiftc ushftc3
238
(
239
    .instr(instr),
240
    .a(a[63:48]),
241
    .b(b[63:48]),
242
    .res(shftco[63:48]),
243
    .ov()
244
);
245
 
246
FT64_shiftb ushftb0
247
(
248
    .instr(instr),
249
    .a(a[7:0]),
250
    .b(b[7:0]),
251
    .res(shftob[7:0]),
252
    .ov()
253
);
254
 
255
FT64_shiftb ushftb1
256
(
257
    .instr(instr),
258
    .a(a[15:8]),
259
    .b(b[15:8]),
260
    .res(shftob[15:8]),
261
    .ov()
262
);
263
 
264
FT64_shiftb ushftb2
265
(
266
    .instr(instr),
267
    .a(a[23:16]),
268
    .b(b[23:16]),
269
    .res(shftob[23:16]),
270
    .ov()
271
);
272
 
273
FT64_shiftb ushftb3
274
(
275
    .instr(instr),
276
    .a(a[31:24]),
277
    .b(b[31:24]),
278
    .res(shftob[31:24]),
279
    .ov()
280
);
281
 
282
FT64_shiftb ushftb4
283
(
284
    .instr(instr),
285
    .a(a[39:32]),
286
    .b(b[39:32]),
287
    .res(shftob[39:32]),
288
    .ov()
289
);
290
 
291
FT64_shiftb ushftb5
292
(
293
    .instr(instr),
294
    .a(a[47:40]),
295
    .b(b[47:40]),
296
    .res(shftob[47:40]),
297
    .ov()
298
);
299
 
300
FT64_shiftb ushftb6
301
(
302
    .instr(instr),
303
    .a(a[55:48]),
304
    .b(b[55:48]),
305
    .res(shftob[55:48]),
306
    .ov()
307
);
308
 
309
FT64_shiftb ushftb7
310
(
311
    .instr(instr),
312
    .a(a[63:56]),
313
    .b(b[63:56]),
314
    .res(shftob[63:56]),
315
    .ov()
316
);
317
 
318
cntlz64 uclz1
319
(
320
        .i(sz==2'd0 ? {56'hFFFFFFFFFFFFFF,a[7:0]} :
321
           sz==2'd1 ? {48'hFFFFFFFFFFFF,a[15:0]} :
322
           sz==2'd2 ? {32'hFFFFFFFF,a[31:0]} : a),
323
        .o(clzo)
324
);
325
 
326
cntlo64 uclo1
327
(
328
        .i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
329
        .o(cloo)
330
);
331
 
332
cntpop64 ucpop1
333
(
334
        .i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
335
        .o(cpopo)
336
);
337
 
338
wire [7:0] bcdaddo,bcdsubo;
339
wire [15:0] bcdmulo;
340
BCDAdd ubcd1 (1'b0,a,b,bcdaddo);
341
BCDSub ubcd2 (1'b0,a,b,bcdsubo);
342
BCDMul2 ubcd3 (a,b,bcdmulo);
343
 
344
wire [7:0] s8 = a[7:0] + b[7:0];
345
wire [15:0] s16 = a[15:0] + b[15:0];
346
wire [31:0] s32 = a[31:0] + b[31:0];
347
wire [7:0] d8 = a[7:0] - b[7:0];
348
wire [15:0] d16 = a[15:0] - b[15:0];
349
wire [31:0] d32 = a[31:0] - b[31:0];
350
wire [63:0] and64 = a & b;
351
wire [63:0] or64 = a | b;
352
wire [63:0] xor64 = a ^ b;
353
wire [63:0] redor64 = {63'd0,|a};
354
wire [63:0] redor32 = {63'd0,|a[31:0]};
355
wire [63:0] redor16 = {63'd0,|a[15:0]};
356
wire [63:0] redor8 = {63'd0,|a[7:0]};
357
wire [63:0] zxb12 = {52'd0,b[11:0]};
358
wire [63:0] sxb12 = {{52{b[11]}},b[11:0]};
359
reg [15:0] mask;
360
wire [4:0] cpopom;
361
 
362
always @*
363
for (n = 0; n < 16; n = n + 1)
364
    if (n <= ven)
365
        mask[n] = 1'b1;
366
    else
367
        mask[n] = 1'b0;
368
 
369
cntpop16 ucpop2
370
(
371
        .i(vm & mask),
372
        .o(cpopom)
373
);
374
 
375
wire [5:0] lsto, fsto;
376
ffz24 uffo1
377
(
378
    .i(~{8'h00,a[15:0]}),
379
    .o(lsto)
380
);
381
 
382
flz24 uflo1
383
(
384
    .i(~{8'h00,a[15:0]}),
385
    .o(fsto)
386
);
387
 
388
wire [DBW-1:0] bmmo;
389
FT64_BMM ubmm1
390
(
391
        .op(1'b0),
392
        .a(a),
393
        .b(b),
394
        .o(bmmo)
395
);
396
 
397
always @*
398
case(instr[`INSTRUCTION_OP])
399
`VECTOR:
400
    if (SUP_VECTOR)
401
    case(instr[`INSTRUCTION_S2])
402
    `VABS:         o = a[63] ? -a : a;
403
    `VSIGN:        o = a[63] ? 64'hFFFFFFFFFFFFFFFF : a==64'd0 ? 64'd0 : 64'd1;
404
    `VMxx:
405
        case(instr[25:23])
406
            `VMAND:        o = and64;
407
            `VMOR:         o = or64;
408
            `VMXOR:        o = xor64;
409
            `VMXNOR:       o = ~(xor64);
410
            `VMPOP:        o = {57'd0,cpopo};
411
            `VMFILL:       for (n = 0; n < 64; n = n + 1)
412
                               o[n] = (n < a);
413
                               // Change the following when VL > 16
414
            `VMFIRST:      o = fsto==5'd31 ? 64'd64 : fsto;
415
            `VMLAST:       o = lsto==5'd31 ? 64'd64 : lsto;
416
                endcase
417
    `VADD,`VADDS:  o = vm[ven] ? a + b : c;
418
    `VSUB,`VSUBS:  o = vm[ven] ? a - b : c;
419
    `VMUL,`VMULS:  o = vm[ven] ? prod[DBW-1:0] : c;
420
    `VDIV,`VDIVS:  o = BIG ? (vm[ven] ? divq : c) : 64'hCCCCCCCCCCCCCCCC;
421
    `VAND,`VANDS:  o = vm[ven] ? a & b : c;
422
    `VOR,`VORS:    o = vm[ven] ? a | b : c;
423
    `VXOR,`VXORS:  o = vm[ven] ? a ^ b : c;
424
    `VCNTPOP:      o = {57'd0,cpopo};
425
    `VSHLV:        o = a;   // no masking here
426
    `VSHRV:        o = a;
427
    `VCMPRSS:      o = a;
428
    `VCIDX:        o = a * ven;
429
    `VSCAN:        o = a * (cpopom==0 ? 0 : cpopom-1);
430
    `VSxx,`VSxxS,
431
    `VSxxb,`VSxxSb:
432
        case({instr[26],instr[20:19]})
433
        `VSEQ:     begin
434
                       o = c;
435
                       o[ven] = vm[ven] ? a==b : c[ven];
436
                   end
437
        `VSNE:     begin
438
                       o = c;
439
                       o[ven] = vm[ven] ? a!=b : c[ven];
440
                   end
441
        `VSLT:      begin
442
                         o = c;
443
                         o[ven] = vm[ven] ? $signed(a) < $signed(b) : c[ven];
444
                    end
445
        `VSGE:      begin
446
                         o = c;
447
                         o[ven] = vm[ven] ? $signed(a) >= $signed(b) : c[ven];
448
                    end
449
        `VSLE:      begin
450
                          o = c;
451
                          o[ven] = vm[ven] ? $signed(a) <= $signed(b) : c[ven];
452
                    end
453
        `VSGT:      begin
454
                         o = c;
455
                         o[ven] = vm[ven] ? $signed(a) > $signed(b) : c[ven];
456
                    end
457
        endcase
458
    `VSxxU,`VSxxSU,
459
    `VSxxUb,`VSxxSUb:
460
        case({instr[26],instr[20:19]})
461
        `VSEQ:     begin
462
                       o = c;
463
                       o[ven] = vm[ven] ? a==b : c[ven];
464
                   end
465
        `VSNE:     begin
466
                       o = c;
467
                       o[ven] = vm[ven] ? a!=b : c[ven];
468
                   end
469
        `VSLT:      begin
470
                         o = c;
471
                         o[ven] = vm[ven] ? a < b : c[ven];
472
                    end
473
        `VSGE:      begin
474
                         o = c;
475
                         o[ven] = vm[ven] ? a >= b : c[ven];
476
                    end
477
        `VSLE:      begin
478
                          o = c;
479
                          o[ven] = vm[ven] ? a <= b : c[ven];
480
                    end
481
        `VSGT:      begin
482
                         o = c;
483
                         o[ven] = vm[ven] ? a > b : c[ven];
484
                    end
485
        endcase
486
    `VBITS2V:   o = vm[ven] ? a[ven] : c;
487
    `V2BITS:    begin
488
                o = b;
489
                o[ven] = vm[ven] ? a[0] : b[ven];
490
                end
491
    `VSHL,`VSHR,`VASR:  o = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
492
    `VXCHG:     o = vm[ven] ? b : a;
493
    endcase
494
    else
495
        o <= 64'hCCCCCCCCCCCCCCCC;
496
`RR:
497
    case(instr[`INSTRUCTION_S2])
498
    `BCD:
499
        case(instr[`INSTRUCTION_S1])
500
        `BCDADD:    o = BIG ? bcdaddo :  64'hCCCCCCCCCCCCCCCC;
501
        `BCDSUB:    o = BIG ? bcdsubo :  64'hCCCCCCCCCCCCCCCC;
502
        `BCDMUL:    o = BIG ? bcdmulo :  64'hCCCCCCCCCCCCCCCC;
503
        default:    o = 64'hDEADDEADDEADDEAD;
504
        endcase
505
    `MOV:               o = a;
506
    `VMOV:              o = a;
507
    `R1:
508
        case(instr[`INSTRUCTION_S1])
509
        `CNTLZ:     o = BIG ? {57'd0,clzo} : 64'hCCCCCCCCCCCCCCCC;
510
        `CNTLO:     o = BIG ? {57'd0,cloo} : 64'hCCCCCCCCCCCCCCCC;
511
        `CNTPOP:    o = BIG ? {57'd0,cpopo} : 64'hCCCCCCCCCCCCCCCC;
512
        `ABS:       case(sz)
513
                    2'd0:   o = BIG ? (a[7] ? -a[7:0] : a[7:0]) : 64'hCCCCCCCCCCCCCCCC;
514
                    2'd1:   o = BIG ? (a[15] ? -a[15:0] : a[15:0]) : 64'hCCCCCCCCCCCCCCCC;
515
                    2'd2:   o = BIG ? (a[31] ? -a[31:0] : a[31:0]) : 64'hCCCCCCCCCCCCCCCC;
516
                    2'd3:   o = BIG ? (a[63] ? -a : a) : 64'hCCCCCCCCCCCCCCCC;
517
                    endcase
518
        `NOT:   case(sz)
519
                2'd0:   o = ~|a[7:0];
520
                2'd1:   o = ~|a[15:0];
521
                2'd2:   o = ~|a[31:0];
522
                2'd3:   o = ~|a[63:0];
523
                endcase
524
        `REDOR: case(sz)
525
                2'd0:   o = redor8;
526
                2'd1:   o = redor16;
527
                2'd2:   o = redor32;
528
                2'd3:   o = redor64;
529
                endcase
530
        default:    o = 64'hDEADDEADDEADDEAD;
531
        endcase
532
    `BMM:               o = BIG ? bmmo : 64'hCCCCCCCCCCCCCCCC;
533
    `SHIFT:     o = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
534
    `SHIFTB:    o = BIG ? shftob : 64'hCCCCCCCCCCCCCCCC;
535
    `SHIFTC:    o = BIG ? shftco : 64'hCCCCCCCCCCCCCCCC;
536
    `SHIFTH:    o = BIG ? shftho : 64'hCCCCCCCCCCCCCCCC;
537
    `ADD:   case(sz)
538
                3'd0,3'd4:
539
                        begin
540
                                o[7:0] <= a[7:0] + b[7:0];
541
                                o[15:8] <= a[15:8] + b[15:8];
542
                                o[23:16] <= a[23:16] + b[23:16];
543
                                o[31:24] <= a[31:24] + b[31:24];
544
                                o[39:32] <= a[39:32] + b[39:32];
545
                                o[47:40] <= a[47:40] + b[47:40];
546
                                o[55:48] <= a[55:48] + b[55:48];
547
                                o[63:56] <= a[63:56] + b[63:56];
548
                        end
549
                3'd1,3'd5:
550
                        begin
551
                                o[15:0] <= a[15:0] + b[15:0];
552
                                o[31:16] <= a[31:16] + b[31:16];
553
                                o[47:32] <= a[47:32] + b[47:32];
554
                                o[63:48] <= a[63:48] + b[63:48];
555
                        end
556
                3'd2,3'd6:
557
                        begin
558
                                o[31:0] <= a[31:0] + b[31:0];
559
                                o[63:32] <= a[63:32] + b[63:32];
560
                        end
561
            3'd3,3'd7:
562
                        o = a + b;
563
            endcase
564
    `SUB:   case(sz)
565
                3'd0,3'd4:
566
                        begin
567
                                o[7:0] <= a[7:0] - b[7:0];
568
                                o[15:8] <= a[15:8] - b[15:8];
569
                                o[23:16] <= a[23:16] - b[23:16];
570
                                o[31:24] <= a[31:24] - b[31:24];
571
                                o[39:32] <= a[39:32] - b[39:32];
572
                                o[47:40] <= a[47:40] - b[47:40];
573
                                o[55:48] <= a[55:48] - b[55:48];
574
                                o[63:56] <= a[63:56] - b[63:56];
575
                        end
576
                3'd1,3'd5:
577
                        begin
578
                                o[15:0] <= a[15:0] - b[15:0];
579
                                o[31:16] <= a[31:16] - b[31:16];
580
                                o[47:32] <= a[47:32] - b[47:32];
581
                                o[63:48] <= a[63:48] - b[63:48];
582
                        end
583
                3'd2,3'd6:
584
                        begin
585
                                o[31:0] <= a[31:0] - b[31:0];
586
                                o[63:32] <= a[63:32] - b[63:32];
587
                        end
588
            3'd3,3'd7:
589
                        o = a - b;
590
            endcase
591
    `CMP:   case(instr[25:23])
592
                3'd0,3'd1:      // CMP
593
                        case(sz[1:0])
594
                    2'd0:   o = $signed(a[7:0]) < $signed(b[7:0]) ? 64'hFFFFFFFFFFFFFFFF : a[7:0]==b[7:0] ? 64'd0 : 64'd1;
595
                    2'd1:   o = $signed(a[15:0]) < $signed(b[15:0]) ? 64'hFFFFFFFFFFFFFFFF : a[15:0]==b[15:0] ? 64'd0 : 64'd1;
596
                    2'd2:   o = $signed(a[31:0]) < $signed(b[31:0]) ? 64'hFFFFFFFFFFFFFFFF : a[31:0]==b[31:0] ? 64'd0 : 64'd1;
597
                    2'd3:   o = $signed(a) < $signed(b) ? 64'hFFFFFFFFFFFFFFFF : a==b ? 64'd0 : 64'd1;
598
                    endcase
599
                3'd2:   // SEQ
600
                        case(sz[1:0])
601
                        2'd0:   o = a[7:0]==b[7:0];
602
                        2'd1:   o = a[15:0]==b[15:0];
603
                        2'd2:   o = a[31:0]==b[31:0];
604
                        2'd3:   o = a==b;
605
                        endcase
606
                3'd3:   // SNE
607
                        case(sz[1:0])
608
                        2'd0:   o = a[7:0]!=b[7:0];
609
                        2'd1:   o = a[15:0]!=b[15:0];
610
                        2'd2:   o = a[31:0]!=b[31:0];
611
                        2'd3:   o = a!=b;
612
                        endcase
613
                3'd4:   // SLT
614
                        case(sz[1:0])
615
                    2'd0:   o = $signed(a[7:0]) < $signed(b[7:0]);
616
                    2'd1:   o = $signed(a[15:0]) < $signed(b[15:0]);
617
                    2'd2:   o = $signed(a[31:0]) < $signed(b[31:0]);
618
                    2'd3:   o = $signed(a) < $signed(b);
619
                    endcase
620
                3'd5:   // SGE
621
                        case(sz[1:0])
622
                    2'd0:   o = $signed(a[7:0]) >= $signed(b[7:0]);
623
                    2'd1:   o = $signed(a[15:0]) >= $signed(b[15:0]);
624
                    2'd2:   o = $signed(a[31:0]) >= $signed(b[31:0]);
625
                    2'd3:   o = $signed(a) >= $signed(b);
626
                    endcase
627
                3'd6:   // SLE
628
                        case(sz[1:0])
629
                    2'd0:   o = $signed(a[7:0]) <= $signed(b[7:0]);
630
                    2'd1:   o = $signed(a[15:0]) <= $signed(b[15:0]);
631
                    2'd2:   o = $signed(a[31:0]) <= $signed(b[31:0]);
632
                    2'd3:   o = $signed(a) <= $signed(b);
633
                    endcase
634
                3'd7:   // SGT
635
                        case(sz[1:0])
636
                    2'd0:   o = $signed(a[7:0]) > $signed(b[7:0]);
637
                    2'd1:   o = $signed(a[15:0]) > $signed(b[15:0]);
638
                    2'd2:   o = $signed(a[31:0]) > $signed(b[31:0]);
639
                    2'd3:   o = $signed(a) > $signed(b);
640
                    endcase
641
                endcase
642
    `CMPU:  case(instr[25:23])
643
                3'd0,3'd1:      // CMPU
644
                        case(sz[1:0])
645
                    2'd0:   o = a[7:0] < b[7:0] ? 64'hFFFFFFFFFFFFFFFF : a[7:0]==b[7:0] ? 64'd0 : 64'd1;
646
                    2'd1:   o = a[15:0] < b[15:0] ? 64'hFFFFFFFFFFFFFFFF : a[15:0]==b[15:0] ? 64'd0 : 64'd1;
647
                    2'd2:   o = a[31:0] < b[31:0] ? 64'hFFFFFFFFFFFFFFFF : a[31:0]==b[31:0] ? 64'd0 : 64'd1;
648
                    2'd3:   o = a < b ? 64'hFFFFFFFFFFFFFFFF : a==b ? 64'd0 : 64'd1;
649
                    endcase
650
                3'd2:   // SEQ
651
                        case(sz[1:0])
652
                        2'd0:   o = a[7:0]==b[7:0];
653
                        2'd1:   o = a[15:0]==b[15:0];
654
                        2'd2:   o = a[31:0]==b[31:0];
655
                        2'd3:   o = a==b;
656
                        endcase
657
                3'd3:   // SNE
658
                        case(sz[1:0])
659
                        2'd0:   o = a[7:0]!=b[7:0];
660
                        2'd1:   o = a[15:0]!=b[15:0];
661
                        2'd2:   o = a[31:0]!=b[31:0];
662
                        2'd3:   o = a!=b;
663
                        endcase
664
                3'd4:   // SLTU
665
                        case(sz[1:0])
666
                    2'd0:   o = a[7:0] < b[7:0];
667
                    2'd1:   o = a[15:0] < b[15:0];
668
                    2'd2:   o = a[31:0] < b[31:0];
669
                    2'd3:   o = a < b;
670
                    endcase
671
                3'd5:   // SGEU
672
                        case(sz[1:0])
673
                    2'd0:   o = a[7:0] >= b[7:0];
674
                    2'd1:   o = a[15:0] >= b[15:0];
675
                    2'd2:   o = a[31:0] >= b[31:0];
676
                    2'd3:   o = a >= b;
677
                    endcase
678
                3'd6:   // SLEU
679
                        case(sz[1:0])
680
                    2'd0:   o = a[7:0] <= b[7:0];
681
                    2'd1:   o = a[15:0] <= b[15:0];
682
                    2'd2:   o = a[31:0] <= b[31:0];
683
                    2'd3:   o = a <= b;
684
                    endcase
685
                3'd7:   // SGTU
686
                        case(sz[1:0])
687
                    2'd0:   o = a[7:0] > b[7:0];
688
                    2'd1:   o = a[15:0] > b[15:0];
689
                    2'd2:   o = a[31:0] > b[31:0];
690
                    2'd3:   o = a > b;
691
                    endcase
692
                endcase
693
    `AND:   o = and64;
694
    `OR:    o = or64;
695
    `XOR:   o = xor64;
696
    `NAND:  o = ~and64;
697
    `NOR:   o = ~or64;
698
    `XNOR:  o = ~xor64;
699
    `SEI:       o = a | instr[21:16];
700
    `RTI:       o = a | instr[21:16];
701
    `CMOVEQ:    o = (a==64'd0) ? b : c;
702
    `CMOVNE:    o = (a!=64'd0) ? b : c;
703
    `MUX:       for (n = 0; n < 64; n = n + 1)
704
                    o[n] <= a[n] ? b[n] : c[n];
705
    `MULU:      o = instr[25:24]==2'b00 ? prod[DBW-1:0] : prod[DBW*2-1:DBW];
706
    `MULSU:     o = instr[25:24]==2'b00 ? prod[DBW-1:0] : prod[DBW*2-1:DBW];
707
    `MUL:       o = instr[25:24]==2'b00 ? prod[DBW-1:0] : prod[DBW*2-1:DBW];
708
    `DIVMODU:   o = BIG ? (instr[25:24]==2'b00 ? divq : rem) : 64'hCCCCCCCCCCCCCCCC;
709
    `DIVMODSU:  o = BIG ? (instr[25:24]==2'b00 ? divq : rem) : 64'hCCCCCCCCCCCCCCCC;
710
    `DIVMOD:    o = BIG ? (instr[25:24]==2'b00 ? divq : rem) : 64'hCCCCCCCCCCCCCCCC;
711
    `LBX,`LBOX,`LBUX,`LCX,`LCOX,`LCUX,
712
    `LHX,`LHOX,`LHUX,`LWX,`LWRX,`SBX,`SCX,`SHX,`SWX,`SWCX:
713
                        o = BIG ? a + (b << instr[22:21]) : 64'hCCCCCCCCEEEEEEEE;
714
    `LVx:               o = BIG ? a + (b << instr[22:21]) : 64'hCCCCCCCCCCCCCCCC;
715
    `LVX,`SVX:  o = BIG ? a + (b << 2'd3) : 64'hCCCCCCCCCCCCCCCC;
716
    `LVWS,`SVWS:    o = BIG ? a + ({b * ven,3'b000}) : 64'hCCCCCCCCCCCCCCCC;
717
    `MIN:       case(sz)
718
                        3'd0,3'd4:
719
                                begin
720
                                o[7:0] = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0]) : 8'hCC;
721
                                o[15:8] = BIG ? ($signed(a[15:8]) < $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
722
                                o[23:16] = BIG ? ($signed(a[23:16]) < $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
723
                                o[31:24] = BIG ? ($signed(a[31:24]) < $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
724
                                o[39:32] = BIG ? ($signed(a[39:32]) < $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
725
                                o[47:40] = BIG ? ($signed(a[47:40]) < $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
726
                                o[55:48] = BIG ? ($signed(a[55:48]) < $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
727
                                o[63:56] = BIG ? ($signed(a[63:56]) < $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
728
                                end
729
                        3'd1,3'd5:
730
                                begin
731
                                o[15:0] = BIG ? ($signed(a[15:0]) < $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
732
                                o[32:16] = BIG ? ($signed(a[32:16]) < $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
733
                                o[47:32] = BIG ? ($signed(a[47:32]) < $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
734
                                o[63:48] = BIG ? ($signed(a[63:48]) < $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
735
                                end
736
                        3'd2,3'd6:
737
                                begin
738
                                o[31:0] = BIG ? ($signed(a[31:0]) < $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
739
                                o[63:32] = BIG ? ($signed(a[63:32]) < $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
740
                                end
741
                                3'd3,3'd7:
742
                                o = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
743
                        endcase
744
    `MAX:       case(sz)
745
                        3'd0,3'd4:
746
                                begin
747
                                o[7:0] = BIG ? ($signed(a[7:0]) > $signed(b[7:0]) ? a[7:0] : b[7:0]) : 64'hCCCCCCCCCCCCCCCC;
748
                                o[15:8] = BIG ? ($signed(a[15:8]) > $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
749
                                o[23:16] = BIG ? ($signed(a[23:16]) > $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
750
                                o[31:24] = BIG ? ($signed(a[31:24]) > $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
751
                                o[39:32] = BIG ? ($signed(a[39:32]) > $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
752
                                o[47:40] = BIG ? ($signed(a[47:40]) > $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
753
                                o[55:48] = BIG ? ($signed(a[55:48]) > $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
754
                                o[63:56] = BIG ? ($signed(a[63:56]) > $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
755
                                end
756
                        3'd1,3'd5:
757
                                begin
758
                                o[15:0] = BIG ? ($signed(a[15:0]) > $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
759
                                o[32:16] = BIG ? ($signed(a[32:16]) > $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
760
                                o[47:32] = BIG ? ($signed(a[47:32]) > $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
761
                                o[63:48] = BIG ? ($signed(a[63:48]) > $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
762
                                end
763
                        3'd2,3'd6:
764
                                begin
765
                                o[31:0] = BIG ? ($signed(a[31:0]) > $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
766
                                o[63:32] = BIG ? ($signed(a[63:32]) > $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
767
                                end
768
                                3'd3,3'd7:
769
                                o = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
770
                        endcase
771
    `MAJ:               o = (a & b) | (a & c) | (b & c);
772
    `CHK:       o = (a >= b && a < c);
773
    default:    o = 64'hDEADDEADDEADDEAD;
774
    endcase
775
 `ADDI: o = a + b;
776
 `CMPI: o = $signed(a) < $signed(b) ? 64'hFFFFFFFFFFFFFFFF : a==b ? 64'd0 : 64'd1;
777
 `CMPUI: o = a < b ? 64'hFFFFFFFFFFFFFFFF : a==b ? 64'd0 : 64'd1;
778
 `ANDI:  o = a & b;
779
 `ORI:   o = a | b;
780
 `XORI:  o = a ^ b;
781
 `QOPI:     case(instr[10:8])
782
            `QORI:
783
                case(instr[7:6])
784
                2'd0:   o = b | {48'h000000000000,imm[15:0]};
785
                2'd1:   o = b | {32'h00000000,imm[15:0],16'h0000};
786
                2'd2:   o = b | {16'h0000,imm[15:0],32'h00000000};
787
                2'd3:   o = b | {imm[15:0],48'h000000000000};
788
                endcase
789
            `QXORI:
790
                case(instr[7:6])
791
                2'd0:   o = b ^ {48'h000000000000,imm[15:0]};
792
                2'd1:   o = b ^ {32'h00000000,imm[15:0],16'h0000};
793
                2'd2:   o = b ^ {16'h0000,imm[15:0],32'h00000000};
794
                2'd3:   o = b ^ {imm[15:0],48'h000000000000};
795
                endcase
796
            `QANDI:
797
                case(instr[7:6])
798
                2'd0:   o = b & {48'hFFFFFFFFFFFF,imm[15:0]};
799
                2'd1:   o = b & {32'hFFFFFFFF,imm[15:0],16'hFFFF};
800
                2'd2:   o = b & {16'hFFFF,imm[15:0],32'hFFFFFFFF};
801
                2'd3:   o = b & {imm[15:0],48'hFFFFFFFFFFFF};
802
                endcase
803
             `QADDI:
804
                case(instr[7:6])
805
                2'd0:   o = b + imm;
806
                2'd1:   o = b + {imm,16'h0};
807
                2'd2:   o = b + {imm,32'h0};
808
                2'd3:   o = b + {imm,48'h0};
809
                endcase
810
            default:    o = 64'hDEADDEADDEADDEAD;
811
            endcase
812
 `SccI:
813
            case(instr[31:28])
814
            `SEQ:   o = a == sxb12;
815
            `SNE:   o = a != sxb12;
816
            `SLT:   o = $signed(a) < $signed(sxb12);
817
            `SGE:   o = $signed(a) >= $signed(sxb12);
818
            `SLE:   o = $signed(a) <= $signed(sxb12);
819
            `SGT:   o = $signed(a) > $signed(sxb12);
820
            `SLTU:  o = a < zxb12;
821
            `SGEU:  o = a >= zxb12;
822
            `SLEU:  o = a <= zxb12;
823
            `SGTU:  o = a > zxb12;
824
            default:    o = 64'hDEADDEADDEADDEAD;
825
            endcase
826
 `MULUI:     o = prod[DBW-1:0];
827
 `MULSUI:    o = prod[DBW-1:0];
828
 `MULI:      o = prod[DBW-1:0];
829
 `DIVUI:     o = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
830
 `DIVSUI:    o = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
831
 `DIVI:      o = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
832
 `MODUI:     o = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
833
 `MODSUI:    o = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
834
 `MODI:      o = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
835
 `LB,`LBO,`LBU,`LC,`LCO,`LCU,`LH,`LHO,`LHU,`LW,`LWR,
836
 `SB,`SC,`SH,`SW,`SWC,`CAS:  o = a + b;
837
 `LVx:           o = a + sxb12;
838
 `LV,`SV:    o = a + b + {ven,3'b0};
839
 `CSRRW:     o = BIG ? csr | {thrd,24'h0} : 64'hDDDDDDDDDDDDDDDD;
840
 `BITFIELD:   o = BIG ? bfout : 64'hCCCCCCCCCCCCCCCC;
841
  default:    o = 64'hDEADDEADDEADDEAD;
842
endcase
843
 
844
// Generate done signal
845
always @*
846
begin
847
    if (IsMul(instr))
848
        done <= mult_done;
849
    else if (IsDivmod(instr) & BIG)
850
        done <= div_done;
851
    else
852
        done <= TRUE;
853
end
854
 
855
// Generate idle signal
856
always @*
857
begin
858
    if (IsMul(instr))
859
        idle <= mult_idle;
860
    else if (IsDivmod(instr) & BIG)
861
        idle <= div_idle;
862
    else
863
        idle <= TRUE;
864
end
865
 
866
function fnOverflow;
867
input op;   // 0 = add, 1=sub
868
input a;
869
input b;
870
input s;
871
fnOverflow = (op ^ s ^ b) & (~op ^ a ^ b);
872
endfunction
873
 
874
always @*
875
begin
876
if ((tgt==6'd31 || tgt==6'd30) && (o[31:0] < sbl || o[31:0] > sbu))
877
    exc <= `FLT_STK;
878
else
879
case(instr[`INSTRUCTION_OP])
880
`RR:
881
    case(instr[`INSTRUCTION_S2])
882
    `ADD:   exc <= (fnOverflow(0,a[63],b[63],o[63]) & excen[0] & instr[24]) ? `FLT_OFL : `FLT_NONE;
883
    `SUB:   exc <= (fnOverflow(1,a[63],b[63],o[63]) & excen[1] & instr[24]) ? `FLT_OFL : `FLT_NONE;
884
    `ASL,`ASLI:     exc <= (BIG & aslo & excen[2]) ? `FLT_OFL : `FLT_NONE;
885
    `MUL,`MULSU:    exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF && excen[3] ? `FLT_OFL : `FLT_NONE ):
886
                           (prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE);
887
    `MULU:      exc <= prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE;
888
    `DIVMOD,`DIVMODSU,`DIVMODU: exc <= BIG && excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
889
    default:    exc <= `FLT_NONE;
890
    endcase
891
`MULI,`MULSUI:    exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF & excen[3] ? `FLT_OFL : `FLT_NONE):
892
                                    (prod[127:64] != 64'd0 & excen[3] ? `FLT_OFL : `FLT_NONE);
893
`DIVI,`DIVSUI: exc <= BIG & excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
894
`MODI,`MODSUI: exc <= BIG & excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
895
default:    exc <= `FLT_NONE;
896
endcase
897
end
898
 
899
endmodule

powered by: WebSVN 2.1.0

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