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

Subversion Repositories thor

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

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

Line No. Rev Author Line
1 48 robfinch
// ============================================================================
2
//        __
3
//   \\__/ o\    (C) 2017-2018  Robert Finch, Waterloo
4
//    \  __ /    All rights reserved.
5
//     \/_//     robfinch<remove>@finitron.ca
6
//       ||
7
//
8
//      FT64_alu.v
9
//
10
// This source file is free software: you can redistribute it and/or modify 
11
// it under the terms of the GNU Lesser General Public License as published 
12
// by the Free Software Foundation, either version 3 of the License, or     
13
// (at your option) any later version.                                      
14
//                                                                          
15
// This source file is distributed in the hope that it will be useful,      
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
18
// GNU General Public License for more details.                             
19
//                                                                          
20
// You should have received a copy of the GNU General Public License        
21
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
22
//
23
// ============================================================================
24
//
25
`include "FT64_defines.vh"
26
 
27
module FT64_alu(rst, clk, ld, abort, instr, a, b, c, pc, tgt, tgt2, ven, vm, sbl, sbu,
28
    csr, o, ob, done, idle, excen, exc, thrd, ptrmask, state, mem, shift48);
29
parameter DBW = 64;
30
parameter BIG = 1'b1;
31
parameter SUP_VECTOR = 1;
32
parameter TRUE = 1'b1;
33
parameter FALSE = 1'b0;
34
parameter PTR = 20'hFFF01;
35
input rst;
36
input clk;
37
input ld;
38
input abort;
39
input [47:0] instr;
40
input [63:0] a;
41
input [63:0] b;
42
input [63:0] c;
43
input [31:0] pc;
44
input [11:0] tgt;
45
input [7:0] tgt2;
46
input [5:0] ven;
47
input [15:0] vm;
48
input [31:0] sbl;
49
input [31:0] sbu;
50
input [63:0] csr;
51
output reg [63:0] o;
52
output reg [63:0] ob;
53
output reg done;
54
output reg idle;
55
input [4:0] excen;
56
output reg [8:0] exc;
57
input thrd;
58
input [63:0] ptrmask;
59
input [1:0] state;
60
input mem;
61
input shift48;
62
 
63
integer n;
64
 
65
reg adrDone, adrIdle;
66
reg [63:0] addro;
67
reg [63:0] addr8;
68
 
69
wire [7:0] a8 = a[7:0];
70
wire [15:0] a16 = a[15:0];
71
wire [31:0] a32 = a[31:0];
72
wire [7:0] b8 = b[7:0];
73
wire [15:0] b16 = b[15:0];
74
wire [31:0] b32 = b[31:0];
75
wire [63:0] orb = instr[6] ? {34'd0,b[29:0]} : {50'd0,b[13:0]};
76
wire [63:0] andb = b;//((instr[6]==1'b1) ? {34'h3FFFFFFFF,b[29:0]} : {50'h3FFFFFFFFFFFF,b[13:0]});
77
 
78
wire [21:0] qimm = instr[39:18];
79
wire [63:0] imm = {{45{instr[39]}},instr[39:21]};
80
wire [DBW-1:0] divq, rem;
81
wire divByZero;
82
wire [15:0] prod8;
83
wire [31:0] prod16;
84
wire [63:0] prod32;
85
wire [DBW*2-1:0] prod;
86
wire mult_done8, mult_idle8, div_done8, div_idle8;
87
wire mult_done16, mult_idle16, div_done16, div_idle16;
88
wire mult_done32, mult_idle32, div_done32, div_idle32;
89
wire mult_done, mult_idle, div_done, div_idle;
90
wire aslo;
91
wire [6:0] clzo,cloo,cpopo;
92
wire [63:0] shftho;
93
reg [34:0] addr9;
94
 
95
function IsMul;
96
input [47:0] isn;
97
case(isn[`INSTRUCTION_OP])
98
`IVECTOR:
99
    case(isn[`INSTRUCTION_S2])
100
    `VMUL,`VMULS:   IsMul = TRUE;
101
    default:    IsMul = FALSE;
102
    endcase
103
`RR:
104
    case(isn[`INSTRUCTION_S2])
105
    `MULU,`MULSU,`MUL: IsMul = TRUE;
106
    default:    IsMul = FALSE;
107
    endcase
108
`MULUI,`MULSUI,`MULI:  IsMul = TRUE;
109
default:    IsMul = FALSE;
110
endcase
111
endfunction
112
 
113
function IsDivmod;
114
input [47:0] isn;
115
case(isn[`INSTRUCTION_OP])
116
`IVECTOR:
117
    case(isn[`INSTRUCTION_S2])
118
    `VDIV,`VDIVS:   IsDivmod = TRUE;
119
    default:    IsDivmod = FALSE;
120
    endcase
121
`RR:
122
    case(isn[`INSTRUCTION_S2])
123
    `DIVMODU,`DIVMODSU,`DIVMOD: IsDivmod = TRUE;
124
    default:    IsDivmod = FALSE;
125
    endcase
126
`DIVUI,`DIVI,`MODI:  IsDivmod = TRUE;
127
default:    IsDivmod = FALSE;
128
endcase
129
endfunction
130
 
131
function IsSgn;
132
input [47:0] isn;
133
case(isn[`INSTRUCTION_OP])
134
`IVECTOR:
135
    case(isn[`INSTRUCTION_S2])
136
    `VMUL,`VMULS,`VDIV,`VDIVS:    IsSgn = TRUE;
137
    default:    IsSgn = FALSE;
138
    endcase
139
`RR:
140
    case(isn[`INSTRUCTION_S2])
141
    `MUL,`DIVMOD:   IsSgn = TRUE;
142
    default:    IsSgn = FALSE;
143
    endcase
144
`MULI,`DIVI,`MODI:    IsSgn = TRUE;
145
default:    IsSgn = FALSE;
146
endcase
147
endfunction
148
 
149
function IsSgnus;
150
input [47:0] isn;
151
case(isn[`INSTRUCTION_OP])
152
`RR:
153
    case(isn[`INSTRUCTION_S2])
154
    `MULSU,`DIVMODSU:   IsSgnus = TRUE;
155
    default:    IsSgnus = FALSE;
156
    endcase
157
default:    IsSgnus = FALSE;
158
endcase
159
endfunction
160
 
161
function IsShiftAndOp;
162
input [47:0] isn;
163
IsShiftAndOp = FALSE;
164
endfunction
165
 
166
wire [2:0] sz =
167
    instr[`INSTRUCTION_OP]==`IVECTOR ? 2'd3 :
168
    instr[`INSTRUCTION_S2]==`R1 ? instr[18:16] : instr[23:21];
169
 
170
wire [63:0] bfout,shfto;
171
wire [63:0] shftob;
172
wire [63:0] shftco;
173
 
174
FT64_bitfield #(DBW) ubf1
175
(
176
    .inst(instr),
177
    .a(a),
178
    .b(b),
179
    .c(c),
180
    .o(bfout),
181
    .masko()
182
);
183
 
184
FT64_multiplier #(DBW) umult1
185
(
186
        .rst(rst),
187
        .clk(clk),
188
        .ld(ld && IsMul(instr)),
189
        .abort(abort),
190
        .sgn(IsSgn(instr)),
191
        .sgnus(IsSgnus(instr)),
192
        .a(a),
193
        .b(b),
194
        .o(prod),
195
        .done(mult_done),
196
        .idle(mult_idle)
197
);
198
 
199
FT64_divider #(DBW) udiv1
200
(
201
        .rst(rst),
202
        .clk(clk),
203
        .ld(ld && IsDivmod(instr)),
204
        .abort(abort),
205
        .sgn(IsSgn(instr)),
206
        .sgnus(IsSgnus(instr)),
207
        .a(a),
208
        .b(b),
209
        .qo(divq),
210
        .ro(rem),
211
        .dvByZr(divByZero),
212
        .done(div_done),
213
        .idle(div_idle)
214
);
215
 
216
wire [5:0] bshift = instr[31:26]==`SHIFTR ? b : {instr[30],instr[17:13]};
217
 
218
FT64_shift ushft1
219
(
220
    .instr(instr),
221
    .a(a),
222
    .b(bshift),
223
    .res(shfto),
224
    .ov(aslo)
225
);
226
 
227
FT64_shifth ushfthL
228
(
229
    .instr(instr),
230
    .a(a[31:0]),
231
    .b(bshift),
232
    .res(shftho[31:0]),
233
    .ov()
234
);
235
 
236
FT64_shifth ushfthH
237
(
238
    .instr(instr),
239
    .a(a[63:32]),
240
    .b(b[63:32]),
241
    .res(shftho[63:32]),
242
    .ov()
243
);
244
 
245
FT64_shiftc ushftc0
246
(
247
    .instr(instr),
248
    .a(a[15:0]),
249
    .b(bshift),
250
    .res(shftco[15:0]),
251
    .ov()
252
);
253
 
254
FT64_shiftc ushftc1
255
(
256
    .instr(instr),
257
    .a(a[31:16]),
258
    .b(b[31:16]),
259
    .res(shftco[31:16]),
260
    .ov()
261
);
262
 
263
FT64_shiftc ushftc2
264
(
265
    .instr(instr),
266
    .a(a[47:32]),
267
    .b(b[47:32]),
268
    .res(shftco[47:32]),
269
    .ov()
270
);
271
 
272
FT64_shiftc ushftc3
273
(
274
    .instr(instr),
275
    .a(a[63:48]),
276
    .b(b[63:48]),
277
    .res(shftco[63:48]),
278
    .ov()
279
);
280
 
281
FT64_shiftb ushftb0
282
(
283
    .instr(instr),
284
    .a(a[7:0]),
285
    .b(bshift),
286
    .res(shftob[7:0]),
287
    .ov()
288
);
289
 
290
FT64_shiftb ushftb1
291
(
292
    .instr(instr),
293
    .a(a[15:8]),
294
    .b(b[15:8]),
295
    .res(shftob[15:8]),
296
    .ov()
297
);
298
 
299
FT64_shiftb ushftb2
300
(
301
    .instr(instr),
302
    .a(a[23:16]),
303
    .b(b[23:16]),
304
    .res(shftob[23:16]),
305
    .ov()
306
);
307
 
308
FT64_shiftb ushftb3
309
(
310
    .instr(instr),
311
    .a(a[31:24]),
312
    .b(b[31:24]),
313
    .res(shftob[31:24]),
314
    .ov()
315
);
316
 
317
FT64_shiftb ushftb4
318
(
319
    .instr(instr),
320
    .a(a[39:32]),
321
    .b(b[39:32]),
322
    .res(shftob[39:32]),
323
    .ov()
324
);
325
 
326
FT64_shiftb ushftb5
327
(
328
    .instr(instr),
329
    .a(a[47:40]),
330
    .b(b[47:40]),
331
    .res(shftob[47:40]),
332
    .ov()
333
);
334
 
335
FT64_shiftb ushftb6
336
(
337
    .instr(instr),
338
    .a(a[55:48]),
339
    .b(b[55:48]),
340
    .res(shftob[55:48]),
341
    .ov()
342
);
343
 
344
FT64_shiftb ushftb7
345
(
346
    .instr(instr),
347
    .a(a[63:56]),
348
    .b(b[63:56]),
349
    .res(shftob[63:56]),
350
    .ov()
351
);
352
 
353
cntlz64 uclz1
354
(
355
        .i(sz==2'd0 ? {56'hFFFFFFFFFFFFFF,a[7:0]} :
356
           sz==2'd1 ? {48'hFFFFFFFFFFFF,a[15:0]} :
357
           sz==2'd2 ? {32'hFFFFFFFF,a[31:0]} : a),
358
        .o(clzo)
359
);
360
 
361
cntlo64 uclo1
362
(
363
        .i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
364
        .o(cloo)
365
);
366
 
367
cntpop64 ucpop1
368
(
369
        .i(sz==2'd0 ? a[7:0] : sz==2'd1 ? a[15:0] : sz==2'd2 ? a[31:0] : a),
370
        .o(cpopo)
371
);
372
 
373
wire [7:0] bcdaddo,bcdsubo;
374
wire [15:0] bcdmulo;
375
BCDAdd ubcd1 (1'b0,a,b,bcdaddo);
376
BCDSub ubcd2 (1'b0,a,b,bcdsubo);
377
BCDMul2 ubcd3 (a,b,bcdmulo);
378
 
379
wire [7:0] s8 = a[7:0] + b[7:0];
380
wire [15:0] s16 = a[15:0] + b[15:0];
381
wire [31:0] s32 = a[31:0] + b[31:0];
382
wire [7:0] d8 = a[7:0] - b[7:0];
383
wire [15:0] d16 = a[15:0] - b[15:0];
384
wire [31:0] d32 = a[31:0] - b[31:0];
385
wire [63:0] and64 = a & b;
386
wire [63:0] or64 = a | b;
387
wire [63:0] xor64 = a ^ b;
388
wire [63:0] redor64 = {63'd0,|a};
389
wire [63:0] redor32 = {63'd0,|a[31:0]};
390
wire [63:0] redor16 = {63'd0,|a[15:0]};
391
wire [63:0] redor8 = {63'd0,|a[7:0]};
392
wire [63:0] zxb10 = {54'd0,b[9:0]};
393
wire [63:0] sxb10 = {{54{b[9]}},b[9:0]};
394
wire [63:0] zxb26 = {38'd0,instr[47:32],instr[27:18]};
395
wire [63:0] sxb26 = {{38{instr[47]}},instr[47:32],instr[27:18]};
396
reg [15:0] mask;
397
wire [4:0] cpopom;
398
wire signed [63:0] as = a;
399
wire signed [63:0] bs = b;
400
wire signed [63:0] cs = c;
401
 
402
always @*
403
for (n = 0; n < 16; n = n + 1)
404
    if (n <= ven)
405
        mask[n] = 1'b1;
406
    else
407
        mask[n] = 1'b0;
408
 
409
cntpop16 ucpop2
410
(
411
        .i(vm & mask),
412
        .o(cpopom)
413
);
414
 
415
wire [5:0] lsto, fsto;
416
ffz24 uffo1
417
(
418
    .i(~{8'h00,a[15:0]}),
419
    .o(lsto)
420
);
421
 
422
flz24 uflo1
423
(
424
    .i(~{8'h00,a[15:0]}),
425
    .o(fsto)
426
);
427
 
428
wire [DBW-1:0] bmmo;
429
FT64_BMM ubmm1
430
(
431
        .op(1'b0),
432
        .a(a),
433
        .b(b),
434
        .o(bmmo)
435
);
436
 
437
always @*
438
begin
439
case(instr[`INSTRUCTION_OP])
440
`IVECTOR:
441
    if (SUP_VECTOR)
442
    case(instr[`INSTRUCTION_S2])
443
    `VABS:         o[63:0] = a[63] ? -a : a;
444
    `VSIGN:        o[63:0] = a[63] ? 64'hFFFFFFFFFFFFFFFF : a==64'd0 ? 64'd0 : 64'd1;
445
    `VMxx:
446
        case(instr[25:23])
447
            `VMAND:        o[63:0] = and64;
448
            `VMOR:         o[63:0] = or64;
449
            `VMXOR:        o[63:0] = xor64;
450
            `VMXNOR:       o[63:0] = ~(xor64);
451
            `VMPOP:        o[63:0] = {57'd0,cpopo};
452
            `VMFILL:       for (n = 0; n < 64; n = n + 1)
453
                               o[n] = (n < a);
454
                               // Change the following when VL > 16
455
            `VMFIRST:      o[63:0] = fsto==5'd31 ? 64'd64 : fsto;
456
            `VMLAST:       o[63:0] = lsto==5'd31 ? 64'd64 : lsto;
457
                endcase
458
    `VADD,`VADDS:  o[63:0] = vm[ven] ? a + b : c;
459
    `VSUB,`VSUBS:  o[63:0] = vm[ven] ? a - b : c;
460
    `VMUL,`VMULS:  o[63:0] = vm[ven] ? prod[DBW-1:0] : c;
461
    `VDIV,`VDIVS:  o[63:0] = BIG ? (vm[ven] ? divq : c) : 64'hCCCCCCCCCCCCCCCC;
462
    `VAND,`VANDS:  o[63:0] = vm[ven] ? a & b : c;
463
    `VOR,`VORS:    o[63:0] = vm[ven] ? a | b : c;
464
    `VXOR,`VXORS:  o[63:0] = vm[ven] ? a ^ b : c;
465
    `VCNTPOP:      o[63:0] = {57'd0,cpopo};
466
    `VSHLV:        o[63:0] = a;   // no masking here
467
    `VSHRV:        o[63:0] = a;
468
    `VCMPRSS:      o[63:0] = a;
469
    `VCIDX:        o[63:0] = a * ven;
470
    `VSCAN:        o[63:0] = a * (cpopom==0 ? 0 : cpopom-1);
471
    `VSxx,`VSxxS,
472
    `VSxxb,`VSxxSb:
473
        case({instr[26],instr[20:19]})
474
        `VSEQ:     begin
475
                       o[63:0] = c;
476
                       o[ven] = vm[ven] ? a==b : c[ven];
477
                   end
478
        `VSNE:     begin
479
                       o[63:0] = c;
480
                       o[ven] = vm[ven] ? a!=b : c[ven];
481
                   end
482
        `VSLT:      begin
483
                         o[63:0] = c;
484
                         o[ven] = vm[ven] ? $signed(a) < $signed(b) : c[ven];
485
                    end
486
        `VSGE:      begin
487
                         o[63:0] = c;
488
                         o[ven] = vm[ven] ? $signed(a) >= $signed(b) : c[ven];
489
                    end
490
        `VSLE:      begin
491
                          o[63:0] = c;
492
                          o[ven] = vm[ven] ? $signed(a) <= $signed(b) : c[ven];
493
                    end
494
        `VSGT:      begin
495
                         o[63:0] = c;
496
                         o[ven] = vm[ven] ? $signed(a) > $signed(b) : c[ven];
497
                    end
498
        default:        o[63:0] = 64'hCCCCCCCCCCCCCCCC;
499
        endcase
500
    `VSxxU,`VSxxSU,
501
    `VSxxUb,`VSxxSUb:
502
        case({instr[26],instr[20:19]})
503
        `VSEQ:     begin
504
                       o[63:0] = c;
505
                       o[ven] = vm[ven] ? a==b : c[ven];
506
                   end
507
        `VSNE:     begin
508
                       o[63:0] = c;
509
                       o[ven] = vm[ven] ? a!=b : c[ven];
510
                   end
511
        `VSLT:      begin
512
                         o[63:0] = c;
513
                         o[ven] = vm[ven] ? a < b : c[ven];
514
                    end
515
        `VSGE:      begin
516
                         o[63:0] = c;
517
                         o[ven] = vm[ven] ? a >= b : c[ven];
518
                    end
519
        `VSLE:      begin
520
                          o[63:0] = c;
521
                          o[ven] = vm[ven] ? a <= b : c[ven];
522
                    end
523
        `VSGT:      begin
524
                         o[63:0] = c;
525
                         o[ven] = vm[ven] ? a > b : c[ven];
526
                    end
527
        default:        o[63:0] = 64'hCCCCCCCCCCCCCCCC;
528
        endcase
529
    `VBITS2V:   o[63:0] = vm[ven] ? a[ven] : c;
530
    `V2BITS:    begin
531
                o[63:0] = b;
532
                o[ven] = vm[ven] ? a[0] : b[ven];
533
                end
534
    `VSHL,`VSHR,`VASR:  o[63:0] = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
535
    `VXCHG:     o[63:0] = vm[ven] ? b : a;
536
    default:    o[63:0] = 64'hCCCCCCCCCCCCCCCC;
537
    endcase
538
    else
539
        o[63:0] <= 64'hCCCCCCCCCCCCCCCC;
540
`R2:
541
        if (instr[6])
542
                case(instr[47:42])
543
                `SHIFTR:
544
                        begin
545
                        case(instr[35:33])
546
                        `ASL,`ASR,`ROL,`ROR:
547
                                case(instr[32:30])      // size
548
                                3'd0:   addr8 = {{56{shftob[7]}},shftob[7:0]};
549
                                3'd1:   addr8 = {{48{shftob[15]}},shftco[15:0]};
550
                                3'd2:   addr8 = {{32{shftho[31]}},shftho[31:0]};
551
                                3'd3,3'd7:      addr8 = shfto;
552
                                3'd4:   addr8 = shftob;
553
                                3'd5:   addr8 = shftco;
554
                                3'd6:   addr8 = shftho;
555
                                endcase
556
                        `SHL,`SHR:
557
                                case(instr[32:30])      // size
558
                                3'd0:   addr8 = {56'd0,shftob[7:0]};
559
                                3'd1:   addr8 = {48'd0,shftco[15:0]};
560
                                3'd2:   addr8 = {32'd0,shftho[31:0]};
561
                                3'd3,3'd7:      addr8 = shfto;
562
                                3'd4:   addr8 = shftob;
563
                                3'd5:   addr8 = shftco;
564
                                3'd6:   addr8 = shftho;
565
                                endcase
566
                        default:        o[63:0] = 64'hDCDCDCDCDCDCDCDC;
567
                        endcase
568
                        case(instr[35:33])
569
                        `ASL,`ASR,`SHL,`SHR,`ROL,`ROR:
570
                                o[63:0] = addr9;
571
                        default:        o[63:0] = 64'hDCDCDCDCDCDCDCDC;
572
                        endcase
573
                        end
574
                `MIN:
575
                        case(instr[30:28])
576
                        3'd3:
577
                                if (as < bs && as < cs)
578
                                        o[63:0] = as;
579
                                else if (bs < cs)
580
                                        o[63:0] = bs;
581
                                else
582
                                        o[63:0] = cs;
583
                        endcase
584
                endcase
585
        else
586
            case(instr[`INSTRUCTION_S2])
587
            `BCD:
588
                case(instr[`INSTRUCTION_S1])
589
                `BCDADD:    o[63:0] = BIG ? bcdaddo :  64'hCCCCCCCCCCCCCCCC;
590
                `BCDSUB:    o[63:0] = BIG ? bcdsubo :  64'hCCCCCCCCCCCCCCCC;
591
                `BCDMUL:    o[63:0] = BIG ? bcdmulo :  64'hCCCCCCCCCCCCCCCC;
592
                default:    o[63:0] = 64'hDEADDEADDEADDEAD;
593
                endcase
594
            `MOV:       begin
595
                        o[63:0] = a;
596
                        end
597
            `VMOV:              o[63:0] = a;
598
            `R1:
599
                case(instr[`INSTRUCTION_S1])
600
                `CNTLZ:     o[63:0] = BIG ? {57'd0,clzo} : 64'hCCCCCCCCCCCCCCCC;
601
                `CNTLO:     o[63:0] = BIG ? {57'd0,cloo} : 64'hCCCCCCCCCCCCCCCC;
602
                `CNTPOP:    o[63:0] = BIG ? {57'd0,cpopo} : 64'hCCCCCCCCCCCCCCCC;
603
                `ABS:       case(sz)
604
                            2'd0:   o[63:0] = BIG ? (a[7] ? -a[7:0] : a[7:0]) : 64'hCCCCCCCCCCCCCCCC;
605
                            2'd1:   o[63:0] = BIG ? (a[15] ? -a[15:0] : a[15:0]) : 64'hCCCCCCCCCCCCCCCC;
606
                            2'd2:   o[63:0] = BIG ? (a[31] ? -a[31:0] : a[31:0]) : 64'hCCCCCCCCCCCCCCCC;
607
                            2'd3:   o[63:0] = BIG ? (a[63] ? -a : a) : 64'hCCCCCCCCCCCCCCCC;
608
                            endcase
609
                `NOT:   case(sz)
610
                        2'd0:   o[63:0] = ~|a[7:0];
611
                        2'd1:   o[63:0] = ~|a[15:0];
612
                        2'd2:   o[63:0] = ~|a[31:0];
613
                        2'd3:   o[63:0] = ~|a[63:0];
614
                        endcase
615
                `REDOR: case(sz)
616
                        2'd0:   o[63:0] = redor8;
617
                        2'd1:   o[63:0] = redor16;
618
                        2'd2:   o[63:0] = redor32;
619
                        2'd3:   o[63:0] = redor64;
620
                        endcase
621
                `ZXH:           o[63:0] = {32'd0,a[31:0]};
622
                `ZXC:           o[63:0] = {48'd0,a[15:0]};
623
                `ZXB:           o[63:0] = {56'd0,a[7:0]};
624
                `SXH:           o[63:0] = {{32{a[31]}},a[31:0]};
625
                `SXC:           o[63:0] = {{48{a[15]}},a[15:0]};
626
                `SXB:           o[63:0] = {{56{a[7]}},a[7:0]};
627
//              5'h1C:          o[63:0] = tmem[a[9:0]];
628
                default:    o = 64'hDEADDEADDEADDEAD;
629
                endcase
630
            `BMM:               o[63:0] = BIG ? bmmo : 64'hCCCCCCCCCCCCCCCC;
631
            `SHIFT31,
632
            `SHIFT63,
633
            `SHIFTR:
634
                begin
635
                        if (instr[25:23]==`SHL)
636
                                o[63:0] = shfto;
637
                        else
638
                                o[63:0] = BIG ? shfto : 64'hCCCCCCCCCCCCCCCC;
639
                        $display("BIG=%d",BIG);
640
                        if(!BIG)
641
                                $stop;
642
                end
643
            `ADD:   case(sz)
644
                        3'd0,3'd4:
645
                                begin
646
                                        o[7:0] = a[7:0] + b[7:0];
647
                                        o[15:8] = a[15:8] + b[15:8];
648
                                        o[23:16] = a[23:16] + b[23:16];
649
                                        o[31:24] = a[31:24] + b[31:24];
650
                                        o[39:32] = a[39:32] + b[39:32];
651
                                        o[47:40] = a[47:40] + b[47:40];
652
                                        o[55:48] = a[55:48] + b[55:48];
653
                                        o[63:56] = a[63:56] + b[63:56];
654
                                end
655
                        3'd1,3'd5:
656
                                begin
657
                                        o[15:0] = a[15:0] + b[15:0];
658
                                        o[31:16] = a[31:16] + b[31:16];
659
                                        o[47:32] = a[47:32] + b[47:32];
660
                                        o[63:48] = a[63:48] + b[63:48];
661
                                end
662
                        3'd2,3'd6:
663
                                begin
664
                                        o[31:0] = a[31:0] + b[31:0];
665
                                        o[63:32] = a[63:32] + b[63:32];
666
                                end
667
                    3'd3,3'd7:
668
                        begin
669
                                o[63:0] = a + b;
670
                        end
671
                    endcase
672
            `SUB:   case(sz)
673
                        3'd0,3'd4:
674
                                begin
675
                                        o[7:0] = a[7:0] - b[7:0];
676
                                        o[15:8] = a[15:8] - b[15:8];
677
                                        o[23:16] = a[23:16] - b[23:16];
678
                                        o[31:24] = a[31:24] - b[31:24];
679
                                        o[39:32] = a[39:32] - b[39:32];
680
                                        o[47:40] = a[47:40] - b[47:40];
681
                                        o[55:48] = a[55:48] - b[55:48];
682
                                        o[63:56] = a[63:56] - b[63:56];
683
                                end
684
                        3'd1,3'd5:
685
                                begin
686
                                        o[15:0] = a[15:0] - b[15:0];
687
                                        o[31:16] = a[31:16] - b[31:16];
688
                                        o[47:32] = a[47:32] - b[47:32];
689
                                        o[63:48] = a[63:48] - b[63:48];
690
                                end
691
                        3'd2,3'd6:
692
                                begin
693
                                        o[31:0] = a[31:0] - b[31:0];
694
                                        o[63:32] = a[63:32] - b[63:32];
695
                                end
696
                    3'd3,3'd7:
697
                        begin
698
                                o[63:0] = a - b;
699
                        end
700
                    endcase
701
            `SLT:   tskSlt(instr,instr[25:23],a,b,o);
702
            `SLTU:  tskSltu(instr,instr[25:23],a,b,o);
703
            `SLE:   tskSle(instr,instr[25:23],a,b,o);
704
            `SLEU:  tskSleu(instr,instr[25:23],a,b,o);
705
            `AND:   o[63:0] = and64;
706
            `OR:    o[63:0] = or64;
707
            `XOR:   o[63:0] = xor64;
708
            `NAND:  o[63:0] = ~and64;
709
            `NOR:   o[63:0] = ~or64;
710
            `XNOR:  o[63:0] = ~xor64;
711
            `SEI:       o[63:0] = a | instr[21:16];
712
            `RTI:       o[63:0] = a | instr[21:16];
713
            `CMOVEZ:    begin
714
                                o[63:0] = (a==64'd0) ? b : c;
715
                                end
716
            `CMOVNZ:    if (instr[41])
717
                                        o[63:0] = (a!=64'd0) ? b : {{48{instr[38]}},instr[38:28],instr[22:18]};
718
                                else
719
                                        o[63:0] = (a!=64'd0) ? b : c;
720
            `MUX:       for (n = 0; n < 64; n = n + 1)
721
                            o[n] <= a[n] ? b[n] : c[n];
722
            `MULU:      o[63:0] = instr[25:24]==2'b00 ? prod[DBW-1:0] : prod[DBW*2-1:DBW];
723
            `MULSU:     o[63:0] = instr[25:24]==2'b00 ? prod[DBW-1:0] : prod[DBW*2-1:DBW];
724
            `MUL:       o[63:0] = instr[25:24]==2'b00 ? prod[DBW-1:0] : prod[DBW*2-1:DBW];
725
            `DIVMODU:   o[63:0] = BIG ? (instr[25:24]==2'b00 ? divq : rem) : 64'hCCCCCCCCCCCCCCCC;
726
            `DIVMODSU:  o[63:0] = BIG ? (instr[25:24]==2'b00 ? divq : rem) : 64'hCCCCCCCCCCCCCCCC;
727
            `DIVMOD:    o[63:0] = BIG ? (instr[25:24]==2'b00 ? divq : rem) : 64'hCCCCCCCCCCCCCCCC;
728
                        `LEAX:
729
                                        begin
730
                                        o[63:0] = BIG ? a + (b << instr[22:21]) : 64'hCCCCCCCCEEEEEEEE;
731
                                        o[63:44] = PTR;
732
                                        end
733
            `MIN:       case(sz)
734
                                3'd0,3'd4:
735
                                        begin
736
                                        o[7:0] = BIG ? ($signed(a[7:0]) < $signed(b[7:0]) ? a[7:0] : b[7:0]) : 8'hCC;
737
                                        o[15:8] = BIG ? ($signed(a[15:8]) < $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
738
                                        o[23:16] = BIG ? ($signed(a[23:16]) < $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
739
                                        o[31:24] = BIG ? ($signed(a[31:24]) < $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
740
                                        o[39:32] = BIG ? ($signed(a[39:32]) < $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
741
                                        o[47:40] = BIG ? ($signed(a[47:40]) < $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
742
                                        o[55:48] = BIG ? ($signed(a[55:48]) < $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
743
                                        o[63:56] = BIG ? ($signed(a[63:56]) < $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
744
                                        end
745
                                3'd1,3'd5:
746
                                        begin
747
                                        o[15:0] = BIG ? ($signed(a[15:0]) < $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
748
                                        o[32:16] = BIG ? ($signed(a[32:16]) < $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
749
                                        o[47:32] = BIG ? ($signed(a[47:32]) < $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
750
                                        o[63:48] = BIG ? ($signed(a[63:48]) < $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
751
                                        end
752
                                3'd2,3'd6:
753
                                        begin
754
                                        o[31:0] = BIG ? ($signed(a[31:0]) < $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
755
                                        o[63:32] = BIG ? ($signed(a[63:32]) < $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
756
                                        end
757
                                        3'd3,3'd7:
758
                                                begin
759
                                        o[63:0] = BIG ? ($signed(a) < $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
760
                                        end
761
                                endcase
762
            `MAX:       case(sz)
763
                                3'd0,3'd4:
764
                                        begin
765
                                        o[7:0] = BIG ? ($signed(a[7:0]) > $signed(b[7:0]) ? a[7:0] : b[7:0]) : 64'hCCCCCCCCCCCCCCCC;
766
                                        o[15:8] = BIG ? ($signed(a[15:8]) > $signed(b[15:8]) ? a[15:8] : b[15:8]) : 64'hCCCCCCCCCCCCCCCC;
767
                                        o[23:16] = BIG ? ($signed(a[23:16]) > $signed(b[23:16]) ? a[23:16] : b[23:16]) : 64'hCCCCCCCCCCCCCCCC;
768
                                        o[31:24] = BIG ? ($signed(a[31:24]) > $signed(b[31:24]) ? a[31:24] : b[31:24]) : 64'hCCCCCCCCCCCCCCCC;
769
                                        o[39:32] = BIG ? ($signed(a[39:32]) > $signed(b[39:32]) ? a[39:32] : b[39:32]) : 64'hCCCCCCCCCCCCCCCC;
770
                                        o[47:40] = BIG ? ($signed(a[47:40]) > $signed(b[47:40]) ? a[47:40] : b[47:40]) : 64'hCCCCCCCCCCCCCCCC;
771
                                        o[55:48] = BIG ? ($signed(a[55:48]) > $signed(b[55:48]) ? a[55:48] : b[55:48]) : 64'hCCCCCCCCCCCCCCCC;
772
                                        o[63:56] = BIG ? ($signed(a[63:56]) > $signed(b[63:56]) ? a[63:56] : b[63:56]) : 64'hCCCCCCCCCCCCCCCC;
773
                                        end
774
                                3'd1,3'd5:
775
                                        begin
776
                                        o[15:0] = BIG ? ($signed(a[15:0]) > $signed(b[15:0]) ? a[15:0] : b[15:0]) : 64'hCCCCCCCCCCCCCCCC;
777
                                        o[32:16] = BIG ? ($signed(a[32:16]) > $signed(b[32:16]) ? a[32:16] : b[32:16]) : 64'hCCCCCCCCCCCCCCCC;
778
                                        o[47:32] = BIG ? ($signed(a[47:32]) > $signed(b[47:32]) ? a[47:32] : b[47:32]) : 64'hCCCCCCCCCCCCCCCC;
779
                                        o[63:48] = BIG ? ($signed(a[63:48]) > $signed(b[63:48]) ? a[63:48] : b[63:48]) : 64'hCCCCCCCCCCCCCCCC;
780
                                        end
781
                                3'd2,3'd6:
782
                                        begin
783
                                        o[31:0] = BIG ? ($signed(a[31:0]) > $signed(b[31:0]) ? a[31:0] : b[31:0]) : 64'hCCCCCCCCCCCCCCCC;
784
                                        o[63:32] = BIG ? ($signed(a[63:32]) > $signed(b[63:32]) ? a[63:32] : b[63:32]) : 64'hCCCCCCCCCCCCCCCC;
785
                                        end
786
                                        3'd3,3'd7:
787
                                                begin
788
                                        o[63:0] = BIG ? ($signed(a) > $signed(b) ? a : b) : 64'hCCCCCCCCCCCCCCCC;
789
                                        end
790
                                endcase
791
            `MAJ:               o = (a & b) | (a & c) | (b & c);
792
            `CHK:       o[63:0] = (a >= b && a < c);
793
            /*
794
            `RTOP:              case(c[5:0])
795
                                `RTADD: o = a + b;
796
                                `RTSUB: o = a - b;
797
                                `RTAND: o = and64;
798
                                `RTOR:  o = or64;
799
                                `RTXOR: o = xor64;
800
                                `RTNAND:        o = ~and64;
801
                                `RTNOR: o = ~or64;
802
                                `RTXNOR:        o = ~xor64;
803
                                `RTSLT: o = as < bs;
804
                                `RTSGE: o = as >= bs;
805
                                `RTSLE: o = as <= bs;
806
                                `RTSGT: o = as > bs;
807
                                `RTSEQ: o = as==bs;
808
                                `RTSNE: o = as!=bs;
809
                                endcase
810
            */
811
            default:    o[63:0] = 64'hDEADDEADDEADDEAD;
812
            endcase
813
`MEMNDX:
814
        if (instr[7:6]==2'b00)
815
                case(instr[`INSTRUCTION_S2])
816
                `LVX,
817
    `LBX,`LBUX,`LCX,`LCUX,
818
    `LHX,`LHUX,`LWX,`LWRX,`SBX,`SCX,`SHX,`SWX,`SWCX:
819
                                if (BIG) begin
820
                                        o[63:0] = a + (b << instr[24:23]);
821
                                end
822
                                else
823
                                        o[63:0] = 64'hCCCCCCCCEEEEEEEE;
824
    `LVX,`SVX:  if (BIG) begin
825
                                o[63:0] = a + (b << 2'd3);
826
                        end
827
                        else
828
                                o[63:0] = 64'hCCCCCCCCCCCCCCCC;
829
    `LVWS,`SVWS:
830
                        if (BIG) begin
831
                                o[63:0] = a + ({b * ven,3'b000});
832
                        end
833
                        else
834
                                o[63:0] = 64'hCCCCCCCCCCCCCCCC;
835
                endcase
836
        else
837
                o[63:0] = 64'hDEADDEADDEADDEAD;
838
`AUIPC:
839
        begin
840
                if (instr[7:6]==2'b01)
841
                        o[63:0] = pc + {instr[47:13],30'd0};
842
                else
843
                        o[63:0] = pc + {{15{instr[31]}},instr[31:13],30'd0};
844
                o[29:0] = 30'd0;
845
//              o[63:44] = PTR;
846
        end
847
`LUI:
848
        begin
849
                if (instr[7:6]==2'b01)
850
                        o[63:0] = {instr[47:13],30'd0};
851
                else
852
                        o[63:0] = {{15{instr[31]}},instr[31:13],30'd0};
853
        end
854
`ADDI:  o[63:0] = a + b;
855
`SLTI:  o[63:0] = $signed(a) < $signed(b);
856
`SLTUI: o[63:0] = a < b;
857
`SGTI:  o[63:0] = $signed(a) > $signed(b);
858
`SGTUI: o[63:0] = a > b;
859
`ANDI:  o[63:0] = a & andb;
860
`ORI:           o[63:0] = a | orb;
861
`XORI:  o[63:0] = a ^ orb;
862
`XNORI: o[63:0] = ~(a ^ orb);
863
`MULUI:         o[63:0] = prod[DBW-1:0];
864
`MULI:          o[63:0] = prod[DBW-1:0];
865
`DIVUI:         o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
866
`DIVI:          o[63:0] = BIG ? divq : 64'hCCCCCCCCCCCCCCCC;
867
`MODI:          o[63:0] = BIG ? rem : 64'hCCCCCCCCCCCCCCCC;
868
`LB,`LBU,`SB:   o[63:0] = a + b;
869
`Lx,`LxU,`Sx:
870
                        begin
871
                                o[63:0] = a + b;
872
                                casez(b[2:0])
873
                                3'b100: o[2:0] = 3'd0;   // LW / SW
874
                                3'b?10: o[1:0] = 2'd0;   // LH / LHU / SH
875
                                3'b??1: o[0] = 1'd0;             // LC / LCU / SC
876
                                endcase
877
                        end
878
`LWR,`SWC,`CAS:
879
                        begin
880
                                o[63:0] = a + b;
881
                        end
882
`LVx:           begin
883
                                o[63:0] = a + (instr[6] ? sxb26 : sxb10);
884
                        end
885
`LV,`SV:    begin
886
                                o[63:0] = a + b + {ven,3'b0};
887
                        end
888
`CSRRW:     case(instr[27:18])
889
                        10'h044: o[63:0] = BIG ? csr | {thrd,24'h0} : 64'hDDDDDDDDDDDDDDDD;
890
                        default:        o[63:0] = BIG ? csr : 64'hDDDDDDDDDDDDDDDD;
891
                        endcase
892
`BITFIELD:  o[63:0] = BIG ? bfout : 64'hCCCCCCCCCCCCCCCC;
893
default:    o[63:0] = 64'hDEADDEADDEADDEAD;
894
endcase
895
end
896
 
897
always @(posedge clk)
898
        if (ld)
899
                adrDone <= FALSE;
900
        else if (mem|shift48)
901
                adrDone <= TRUE;
902
 
903
always @(posedge clk)
904
case(instr[`INSTRUCTION_OP])
905
`R2:
906
        if (instr[`INSTRUCTION_L2]==2'b01)
907
                case(instr[47:42])
908
                `ADD,`SUB,
909
                `AND,`OR,`XOR,`NAND,`NOR,`XNOR,
910
                `SHIFTR:
911
                        case(instr[41:36])
912
                        `R1:
913
                                case(instr[22:18])
914
                                `COM:   addro[63:0] = ~addr8;
915
                                `NOT:   addro[63:0] = ~|addr8;
916
                                `NEG:   addro[63:0] = -addr8;
917
                                default:        addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
918
                                endcase
919
                        `ADD:   addro[63:0] = addr8 + c;
920
                        `SUB:   addro[63:0] = addr8 - c;
921
                        `AND:   addro[63:0] = addr8 & c;
922
                        `OR:    addro[63:0] = addr8 | c;
923
                        `XOR:   addro[63:0] = addr8 ^ c;
924
                        default:        addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
925
                        endcase
926
                default:        addro[63:0] = 64'hDCDCDCDCDCDCDCDC;
927
                endcase
928
        else
929
           addro = 64'hCCCCCCCCCCCCCCCE;
930
default:        addro = 64'hCCCCCCCCCCCCCCCE;
931
endcase
932
 
933
reg sao_done, sao_idle;
934
 
935
// Generate done signal
936
always @*
937
if (rst)
938
        done <= TRUE;
939
else begin
940
        if (IsMul(instr))
941
                done <= mult_done;
942
        else if (IsDivmod(instr) & BIG)
943
                done <= div_done;
944
        else if (IsShiftAndOp(instr) & BIG)
945
                done <= sao_done;
946
        else if (shift48)
947
                done <= adrDone;
948
        else
949
                done <= TRUE;
950
end
951
 
952
// Generate idle signal
953
always @*
954
if (rst)
955
        idle <= TRUE;
956
else begin
957
        if (IsMul(instr))
958
                idle <= mult_idle;
959
        else if (IsDivmod(instr) & BIG)
960
                idle <= div_idle;
961
        else if (IsShiftAndOp(instr) & BIG)
962
                idle <= sao_idle;
963
        else if (shift48)
964
                idle <= adrIdle;
965
        else
966
                idle <= TRUE;
967
end
968
 
969
function fnOverflow;
970
input op;   // 0 = add, 1=sub
971
input a;
972
input b;
973
input s;
974
fnOverflow = (op ^ s ^ b) & (~op ^ a ^ b);
975
endfunction
976
 
977
always @*
978
begin
979
if ((tgt[4:0]==5'd31 || tgt[4:0]==5'd30) && (o[31:0] < sbl || o[31:0] > sbu))
980
    exc <= `FLT_STK;
981
else
982
case(instr[`INSTRUCTION_OP])
983
`R2:
984
    case(instr[`INSTRUCTION_S2])
985
    `ADD:   exc <= (fnOverflow(0,a[63],b[63],o[63]) & excen[0] & instr[24]) ? `FLT_OFL : `FLT_NONE;
986
    `SUB:   exc <= (fnOverflow(1,a[63],b[63],o[63]) & excen[1] & instr[24]) ? `FLT_OFL : `FLT_NONE;
987
    `ASL,`ASLI:     exc <= (BIG & aslo & excen[2]) ? `FLT_OFL : `FLT_NONE;
988
    `MUL,`MULSU:    exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF && excen[3] ? `FLT_OFL : `FLT_NONE ):
989
                           (prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE);
990
    `MULU:      exc <= prod[127:64] != 64'd0 && excen[3] ? `FLT_OFL : `FLT_NONE;
991
    `DIVMOD,`DIVMODSU,`DIVMODU: exc <= BIG && excen[4] & divByZero ? `FLT_DBZ : `FLT_NONE;
992
    default:    exc <= `FLT_NONE;
993
    endcase
994
`MULI:    exc <= prod[63] ? (prod[127:64] != 64'hFFFFFFFFFFFFFFFF & excen[3] ? `FLT_OFL : `FLT_NONE):
995
                                    (prod[127:64] != 64'd0 & excen[3] ? `FLT_OFL : `FLT_NONE);
996
`DIVI: exc <= BIG & excen[4] & divByZero & instr[27] ? `FLT_DBZ : `FLT_NONE;
997
`MODI: exc <= BIG & excen[4] & divByZero & instr[27] ? `FLT_DBZ : `FLT_NONE;
998
default:    exc <= `FLT_NONE;
999
endcase
1000
end
1001
 
1002
reg [63:0] aa, bb;
1003
 
1004
always @(posedge clk)
1005
begin
1006
        aa <= shfto;
1007
        bb <= c;
1008
end
1009
 
1010
task tskSlt;
1011
input [47:0] instr;
1012
input [2:0] sz;
1013
input [63:0] a;
1014
input [63:0] b;
1015
output [63:0] o;
1016
begin
1017
        case(sz[2:0])
1018
  3'd0:   o[63:0] = $signed(a[7:0]) < $signed(b[7:0]);
1019
  3'd1:   o[63:0] = $signed(a[15:0]) < $signed(b[15:0]);
1020
  3'd2:   o[63:0] = $signed(a[31:0]) < $signed(b[31:0]);
1021
  3'd3:   o[63:0] = $signed(a) < $signed(b);
1022
  3'd4:         o[63:0] = {
1023
                                                        7'h0,$signed(a[7:0]) < $signed(b[7:0]),
1024
                                                        7'h0,$signed(a[15:8]) < $signed(b[15:8]),
1025
                                                        7'h0,$signed(a[23:16]) < $signed(b[23:16]),
1026
                                                        7'h0,$signed(a[31:24]) < $signed(b[31:24]),
1027
                                                        7'h0,$signed(a[39:32]) < $signed(b[39:32]),
1028
                                                        7'h0,$signed(a[47:40]) < $signed(b[47:40]),
1029
                                                        7'h0,$signed(a[55:48]) < $signed(b[55:48]),
1030
                                                        7'h0,$signed(a[63:56]) < $signed(b[63:56])
1031
                                                        };
1032
  3'd5:         o[63:0] = {
1033
                                                        15'h0,$signed(a[15:0]) < $signed(b[15:0]),
1034
                                                        15'h0,$signed(a[31:16]) < $signed(b[31:16]),
1035
                                                        15'h0,$signed(a[47:32]) < $signed(b[47:32]),
1036
                                                        15'h0,$signed(a[63:48]) < $signed(b[63:48])
1037
                                                        };
1038
  3'd6:         o[63:0] = {
1039
                                                        31'h0,$signed(a[31:0]) < $signed(b[31:0]),
1040
                                                        31'h0,$signed(a[63:32]) < $signed(b[63:32])
1041
                                                        };
1042
        3'd7:           o[63:0] = $signed(a[63:0]) < $signed(b[63:0]);
1043
  endcase
1044
end
1045
endtask
1046
 
1047
task tskSle;
1048
input [47:0] instr;
1049
input [2:0] sz;
1050
input [63:0] a;
1051
input [63:0] b;
1052
output [63:0] o;
1053
begin
1054
        case(sz[2:0])
1055
  3'd0:   o[63:0] = $signed(a[7:0]) <= $signed(b[7:0]);
1056
  3'd1:   o[63:0] = $signed(a[15:0]) <= $signed(b[15:0]);
1057
  3'd2:   o[63:0] = $signed(a[31:0]) <= $signed(b[31:0]);
1058
  3'd3:   o[63:0] = $signed(a) <= $signed(b);
1059
  3'd4:         o[63:0] = {
1060
                                                        7'h0,$signed(a[7:0]) <= $signed(b[7:0]),
1061
                                                        7'h0,$signed(a[15:8]) <= $signed(b[15:8]),
1062
                                                        7'h0,$signed(a[23:16]) <= $signed(b[23:16]),
1063
                                                        7'h0,$signed(a[31:24]) <= $signed(b[31:24]),
1064
                                                        7'h0,$signed(a[39:32]) <= $signed(b[39:32]),
1065
                                                        7'h0,$signed(a[47:40]) <= $signed(b[47:40]),
1066
                                                        7'h0,$signed(a[55:48]) <= $signed(b[55:48]),
1067
                                                        7'h0,$signed(a[63:56]) <= $signed(b[63:56])
1068
                                                        };
1069
  3'd5:         o[63:0] = {
1070
                                                        15'h0,$signed(a[15:0]) <= $signed(b[15:0]),
1071
                                                        15'h0,$signed(a[31:16]) <= $signed(b[31:16]),
1072
                                                        15'h0,$signed(a[47:32]) <= $signed(b[47:32]),
1073
                                                        15'h0,$signed(a[63:48]) <= $signed(b[63:48])
1074
                                                        };
1075
  3'd6:         o[63:0] = {
1076
                                                        31'h0,$signed(a[31:0]) <= $signed(b[31:0]),
1077
                                                        31'h0,$signed(a[63:32]) <= $signed(b[63:32])
1078
                                                        };
1079
        3'd7:           o[63:0] = $signed(a[63:0]) <= $signed(b[63:0]);
1080
  endcase
1081
end
1082
endtask
1083
 
1084
task tskSltu;
1085
input [47:0] instr;
1086
input [2:0] sz;
1087
input [63:0] a;
1088
input [63:0] b;
1089
output [63:0] o;
1090
begin
1091
        case(sz[2:0])
1092
  3'd0:   o[63:0] = (a[7:0]) < (b[7:0]);
1093
  3'd1:   o[63:0] = (a[15:0]) < (b[15:0]);
1094
  3'd2:   o[63:0] = (a[31:0]) < (b[31:0]);
1095
  3'd3:   o[63:0] = (a) < (b);
1096
  3'd4:         o[63:0] = {
1097
                                                        7'h0,(a[7:0]) < (b[7:0]),
1098
                                                        7'h0,(a[15:8]) < (b[15:8]),
1099
                                                        7'h0,(a[23:16]) < (b[23:16]),
1100
                                                        7'h0,(a[31:24]) < (b[31:24]),
1101
                                                        7'h0,(a[39:32]) < (b[39:32]),
1102
                                                        7'h0,(a[47:40]) < (b[47:40]),
1103
                                                        7'h0,(a[55:48]) < (b[55:48]),
1104
                                                        7'h0,(a[63:56]) < (b[63:56])
1105
                                                        };
1106
  3'd5:         o[63:0] = {
1107
                                                        15'h0,(a[15:0]) < (b[15:0]),
1108
                                                        15'h0,(a[31:16]) < (b[31:16]),
1109
                                                        15'h0,(a[47:32]) < (b[47:32]),
1110
                                                        15'h0,(a[63:48]) < (b[63:48])
1111
                                                        };
1112
  3'd6:         o[63:0] = {
1113
                                                        31'h0,(a[31:0]) < (b[31:0]),
1114
                                                        31'h0,(a[63:32]) < (b[63:32])
1115
                                                        };
1116
        3'd7:           o[63:0] = (a[63:0]) < (b[63:0]);
1117
  endcase
1118
end
1119
endtask
1120
 
1121
task tskSleu;
1122
input [47:0] instr;
1123
input [2:0] sz;
1124
input [63:0] a;
1125
input [63:0] b;
1126
output [63:0] o;
1127
begin
1128
        case(sz[2:0])
1129
  3'd0:   o[63:0] = (a[7:0]) <= (b[7:0]);
1130
  3'd1:   o[63:0] = (a[15:0]) <= (b[15:0]);
1131
  3'd2:   o[63:0] = (a[31:0]) <= (b[31:0]);
1132
  3'd3:   o[63:0] = (a) <= (b);
1133
  3'd4:         o[63:0] = {
1134
                                                        7'h0,(a[7:0]) <= (b[7:0]),
1135
                                                        7'h0,(a[15:8]) <= (b[15:8]),
1136
                                                        7'h0,(a[23:16]) <= (b[23:16]),
1137
                                                        7'h0,(a[31:24]) <= (b[31:24]),
1138
                                                        7'h0,(a[39:32]) <= (b[39:32]),
1139
                                                        7'h0,(a[47:40]) <= (b[47:40]),
1140
                                                        7'h0,(a[55:48]) <= (b[55:48]),
1141
                                                        7'h0,(a[63:56]) <= (b[63:56])
1142
                                                        };
1143
  3'd5:         o[63:0] = {
1144
                                                        15'h0,(a[15:0]) <= (b[15:0]),
1145
                                                        15'h0,(a[31:16]) <= (b[31:16]),
1146
                                                        15'h0,(a[47:32]) <= (b[47:32]),
1147
                                                        15'h0,(a[63:48]) <= (b[63:48])
1148
                                                        };
1149
  3'd6:         o[63:0] = {
1150
                                                        31'h0,(a[31:0]) <= (b[31:0]),
1151
                                                        31'h0,(a[63:32]) <= (b[63:32])
1152
                                                        };
1153
        3'd7:           o[63:0] = (a[63:0]) <= (b[63:0]);
1154
  endcase
1155
end
1156
endtask
1157
 
1158
endmodule

powered by: WebSVN 2.1.0

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