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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [trunk/] [rtl/] [Module_VectorALU.v] - Blame information for rev 180

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

Line No. Rev Author Line
1 152 diegovalve
`timescale 1ns / 1ps
2
`include "aDefinitions.v"
3
/**********************************************************************************
4
Theia, Ray Cast Programable graphic Processing Unit.
5
Copyright (C) 2010  Diego Valverde (diego.valverde.g@gmail.com)
6
 
7
This program is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License
9
as published by the Free Software Foundation; either version 2
10
of the License, or (at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
 
21
***********************************************************************************/
22
 
23
 
24
 
25
//--------------------------------------------------------------
26
module VectorALU
27
(
28
        input wire                                              Clock,
29
        input wire                                              Reset,
30
        input  wire[`INSTRUCTION_OP_LENGTH-1:0]          iOperation,
31
        input  wire[`WIDTH-1:0]                                                          iChannel_Ax,
32
        input  wire[`WIDTH-1:0]                                                          iChannel_Bx,
33
        input  wire[`WIDTH-1:0]                                                          iChannel_Ay,
34
        input  wire[`WIDTH-1:0]                                                          iChannel_By,
35
        input  wire[`WIDTH-1:0]                                                          iChannel_Az,
36
        input  wire[`WIDTH-1:0]                                                          iChannel_Bz,
37
        output wire [`WIDTH-1:0]                                                 oResultA,
38
        output wire [`WIDTH-1:0]                                                 oResultB,
39
        output wire [`WIDTH-1:0]                                                 oResultC,
40
        input    wire                                                                                           iInputReady,
41
        output reg                                                                                              oBranchTaken,
42
        output reg                                                                                              oBranchNotTaken,
43
        output reg                                   oReturnFromSub,
44
        input wire [`ROM_ADDRESS_WIDTH-1:0]          iCurrentIP,
45
 
46
        //Connections to the O Memory
47
        output wire [`DATA_ROW_WIDTH-1:0]    oOMEMWriteAddress,
48
        output wire [`DATA_ROW_WIDTH-1:0]    oOMEMWriteData,
49
        output wire                          oOMEM_WriteEnable,
50
        //Connections to the R Memory
51
        output wire [`DATA_ROW_WIDTH-1:0]    oTMEMReadAddress,
52
        input wire [`DATA_ROW_WIDTH-1:0]     iTMEMReadData,
53
        input wire                           iTMEMDataAvailable,
54
        output wire                          oTMEMDataRequest,
55
 
56
        output reg                                                                                              OutputReady
57
 
58
);
59
 
60
 
61
 
62
 
63
 
64
wire wMultiplcationUnscaled;
65
assign wMultiplcationUnscaled = (iOperation == `IMUL) ? 1'b1 : 1'b0;
66
 
67
//--------------------------------------------------------------
68
 
69
reg [7:0]         InputReadyA,InputReadyB,InputReadyC;
70
 
71
//------------------------------------------------------
72
/*
73
        This is the block that takes care of all tha arithmetic
74
        comparisons. Supported operations are <,>,<=,>=,==,!=
75
 
76
*/
77
//------------------------------------------------------
78
reg [`WIDTH-1:0] wMultiplicationA_Ax;
79
reg  [`WIDTH-1:0] wMultiplicationA_Bx;
80
wire [`LONG_WIDTH-1:0] wMultiplicationA_Result;
81
wire  wMultiplicationA_InputReady;
82
wire wMultiplicationA_OutputReady;
83
wire wMultiplicationOutputReady, wMultiplicationOutputReadyA,
84
wMultiplicationOutputReadyB,wMultiplicationOutputReadyC,wMultiplicationOutputReadyD;
85
 
86
wire wAddSubAOutputReady,wAddSubBOutputReady,wAddSubCOutputReady;
87
wire [`INSTRUCTION_OP_LENGTH-1:0] wOperation;
88
wire [`WIDTH-1:0] wSwizzleOutputX,wSwizzleOutputY,wSwizzleOutputZ;
89
 
90
//--------------------------------------------------------------------
91
reg [`WIDTH-1:0] ResultA,ResultB,ResultC;
92
 
93
//Output Flip Flops,
94
//This flip flop will control the outputs so that the
95
//values of the outputs change ONLY when when there is 
96
//a positive edge of OutputReady
97
 
98
FFD32_POSEDGE ResultAFFD
99
(
100
        .Clock( OutputReady ),
101
        .D( ResultA ),
102
        .Q( oResultA )
103
);
104
 
105
FFD32_POSEDGE ResultBFFD
106
(
107
        .Clock( OutputReady ),
108
        .D( ResultB ),
109
        .Q( oResultB )
110
);
111
 
112
FFD32_POSEDGE ResultCFFD
113
(
114
        .Clock( OutputReady ),
115
        .D( ResultC ),
116
        .Q( oResultC )
117
);
118
//--------------------------------------------------------------------
119
 
120
 
121
 
122
Swizzle3D Swizzle1
123
(
124
        .Source0_X( iChannel_Bx ),
125
        .Source0_Y( iChannel_By ),
126
        .Source0_Z( iChannel_Bz ),
127
        .iOperation( iChannel_Ax ),
128
 
129
        .SwizzleX( wSwizzleOutputX ),
130
        .SwizzleY( wSwizzleOutputY ),
131
        .SwizzleZ( wSwizzleOutputZ )
132
);
133
//---------------------------------------------------------------------
134
wire [`LONG_WIDTH-1:0] wModulus2N_ResultA,wModulus2N_ResultB,wModulus2N_ResultC;
135
 
136
//---------------------------------------------------------------------(
137
 
138
wire IOW_Operation,wOMEM_We;
139
assign IOW_Operation = (iOperation == `OMWRITE);
140
 
141
always @ ( * )
142
begin
143
        if (iOperation == `RET)
144
                oReturnFromSub <= OutputReady;
145
        else
146
                oReturnFromSub <= 1'b0;
147
 
148
end
149
 
150
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD1_AWE
151
(
152
        .Clock( Clock ),
153
        .Reset( Reset),
154
        .Enable( 1'b1 ),
155
        .D( IOW_Operation ),
156
        .Q( wOMEM_We )
157
);
158
 
159
assign oOMEM_WriteEnable = wOMEM_We & IOW_Operation;
160
 
161
FFD_POSEDGE_SYNCRONOUS_RESET # ( `DATA_ROW_WIDTH ) FFD1_A
162
(
163
        .Clock( Clock ),
164
        .Reset( Reset),
165
        .Enable( iInputReady ),
166
        .D( {iChannel_Ax,iChannel_Ay,iChannel_Az} ),
167
        .Q( oOMEMWriteAddress)
168
);
169
FFD_POSEDGE_SYNCRONOUS_RESET # ( `DATA_ROW_WIDTH ) FFD2_B
170
(
171
        .Clock( Clock ),
172
        .Reset( Reset),
173
        .Enable( iInputReady ),
174
        .D( {iChannel_Bx,iChannel_By,iChannel_Bz} ),
175
        .Q( oOMEMWriteData )
176
);
177
 
178
 
179
 
180
wire wTMReadOutputReady;
181
assign wTMReadOutputReady = iTMEMDataAvailable;
182
/*
183
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD1_ARE
184
(
185
        .Clock( Clock ),
186
        .Reset( Reset),
187
        .Enable( 1'b1 ),
188
        .D( iTMEMDataAvailable ),
189
        .Q( wTMReadOutputReady )
190
);
191
*/
192
//assign oTMEMReadAddress = {iChannel_Ax,iChannel_Ay,iChannel_Az};
193
 
194
//We wait 1 clock cycle before be send the data read request, because
195
//we need to lathc the values at the output
196
 
197
wire wOpTRead;
198
assign wOpTRead = ( iOperation == `TMREAD ) ? 1'b1 : 1'b0;
199
wire wTMEMRequest;
200
FFD_POSEDGE_SYNCRONOUS_RESET # ( 1 ) FFD1_ARE123
201
(
202
        .Clock( Clock ),
203
        .Reset( Reset),
204
        .Enable( 1'b1 ),
205
        .D( wOpTRead ),
206
        .Q( wTMEMRequest )
207
);
208
assign oTMEMDataRequest = wTMEMRequest & wOpTRead;
209
FFD_POSEDGE_SYNCRONOUS_RESET # ( `DATA_ROW_WIDTH ) FFD2_B445
210
(
211
        .Clock( Clock ),
212
        .Reset( Reset),
213
        .Enable( iInputReady & wOpTRead ),
214
        .D( {iChannel_Ax,iChannel_Ay,iChannel_Az} ),
215
        .Q( oTMEMReadAddress )
216
);
217
 
218
/*
219
        This MUX will select the apropiated X,Y or Z depending on
220
        wheter it is XYZ iOperation. This gets defined by the bits 3 and 4
221
        of iOperation, and only applies for oBranchTaken and Store operations.
222
*/
223
 
224
wire                                    wArithmeticComparison_Result;
225
wire                                    ArithmeticComparison_InputReady;
226
wire                                    ArithmeticComparison_OutputReady;
227
reg[`WIDTH-1:0]  ArithmeticComparison_A,ArithmeticComparison_B;
228
 
229
 
230
always @ ( * )
231
begin
232
        case ( {iOperation[4],iOperation[3]} )
233
                2'b01:          ArithmeticComparison_A = iChannel_Ax;
234
                2'b10:          ArithmeticComparison_A = iChannel_Ay;
235
                2'b11:          ArithmeticComparison_A = iChannel_Az;
236
                default: ArithmeticComparison_A = 0;     //Should never happen
237
        endcase
238
end
239
//---------------------------------------------------------------------
240
always @ ( * )
241
begin
242
        case ( {iOperation[4],iOperation[3]} )
243
                2'b01:          ArithmeticComparison_B = iChannel_Bx;
244
                2'b10:          ArithmeticComparison_B = iChannel_By;
245
                2'b11:          ArithmeticComparison_B = iChannel_Bz;
246
                default: ArithmeticComparison_B = 0;     //Should never happen
247
        endcase
248
end
249
 
250
//---------------------------------------------------------------------
251
/*
252
        The onbly instance of Aritmetic comparison in the ALU,
253
        ArithmeticComparison operations matches the 3 LSB of
254
        Global ALU iOperation for oBranchTaken Instruction family
255
*/
256
 
257
assign ArithmeticComparison_InputReady = iInputReady;
258
 
259
wire wArithmeticComparisonResult;
260
 
261
ArithmeticComparison ArithmeticComparison_1
262
(
263
        .Clock( Clock ),
264
        .X( ArithmeticComparison_A ),
265
        .Y( ArithmeticComparison_B ),
266
        .iOperation( iOperation[2:0] ),
267
        .iInputReady( ArithmeticComparison_InputReady ),
268
        .OutputReady( ArithmeticComparison_OutputReady ),
269
        .Result( wArithmeticComparisonResult )
270
);
271
 
272
 
273
assign  wArithmeticComparison_Result = wArithmeticComparisonResult && OutputReady;
274
//--------------------------------------------------------------------
275
 RADIX_R_MUL_32_FULL_PARALLEL MultiplicationChannel_A
276
(
277
 
278
        .Clock( Clock ),
279
        .Reset( Reset ),
280
        .A( wMultiplicationA_Ax ),
281
        .B( wMultiplicationA_Bx ),
282
        .R( wMultiplicationA_Result ),
283
        .iUnscaled( wMultiplcationUnscaled ),
284
        .iInputReady( wMultiplicationA_InputReady ),
285
        .OutputReady( wMultiplicationA_OutputReady )
286
);
287
 
288
//--------------------------------------------------------------------
289
always @ ( * )
290
begin
291
        case (iOperation)
292
        `CROSS:                 wMultiplicationA_Ax = iChannel_Ay;      // Ay * Bz
293
        `MAG:                   wMultiplicationA_Ax = iChannel_Ax;
294
        `MULP:          wMultiplicationA_Ax = iChannel_Ax;      //Az = Ax * Ay
295
        default:        wMultiplicationA_Ax = iChannel_Ax;      // Ax * Bx
296
        endcase
297
end
298
//--------------------------------------------------------------------
299
 
300
//assign wMultiplicationA_Ax = iChannel_Ax;
301
 
302
assign wMultiplicationA_InputReady
303
        = (iOperation == `CROSS ||
304
                iOperation == `DOT      ||
305
                iOperation == `MUL      ||
306
                iOperation == `IMUL     ||
307
                iOperation == `MAG      ||
308
                iOperation == `MULP
309
                ) ? iInputReady : 0;
310
 
311
//--------------------------------------------------------------------
312
always @ ( * )
313
begin
314
        case (iOperation)
315
        `MUL,`IMUL:                     wMultiplicationA_Bx = iChannel_Bx;      //Ax*Bx
316
        `MAG:                   wMultiplicationA_Bx = iChannel_Ax;      //Ax^2
317
        `DOT:                   wMultiplicationA_Bx = iChannel_Bx;      //Ax*Bx
318
        `CROSS:         wMultiplicationA_Bx = iChannel_Bz;      // Ay * Bz
319
        `MULP:          wMultiplicationA_Bx = iChannel_Ay;  //Az = Ax * Ay
320
        default:                wMultiplicationA_Bx = 32'b0;
321
        endcase
322
end
323
//--------------------------------------------------------------------
324
 
325
//------------------------------------------------------
326
 
327
reg [`WIDTH-1:0] wMultiplicationB_Ay;
328
reg [`WIDTH-1:0]  wMultiplicationB_By;
329
wire [`LONG_WIDTH-1:0] wMultiplicationB_Result;
330
wire wMultiplicationB_InputReady;
331
wire wMultiplicationB_OutputReady;
332
 
333
 
334
RADIX_R_MUL_32_FULL_PARALLEL MultiplicationChannel_B
335
(
336
 
337
        .Clock( Clock ),
338
        .Reset( Reset ),
339
        .A( wMultiplicationB_Ay ),
340
        .B( wMultiplicationB_By ),
341
        .R( wMultiplicationB_Result ),
342
        .iUnscaled( wMultiplcationUnscaled ),
343
        .iInputReady( wMultiplicationB_InputReady ),
344
        .OutputReady( wMultiplicationB_OutputReady )
345
);
346
 
347
 
348
//----------------------------------------------------
349
 
350
always @ ( * )
351
begin
352
        case (iOperation)
353
                `CROSS:         wMultiplicationB_Ay = iChannel_Az;      // Az * By
354
                `MAG:   wMultiplicationB_Ay = iChannel_Ay;
355
                default: wMultiplicationB_Ay = iChannel_Ay;     // Ay * By
356
        endcase
357
end
358
//----------------------------------------------------
359
assign wMultiplicationB_InputReady
360
        = (iOperation == `CROSS                         ||
361
                iOperation == `DOT      ||
362
                iOperation == `MUL              ||
363
                iOperation == `IMUL             ||
364
                iOperation == `MAG ) ? iInputReady : 0;
365
 
366
//----------------------------------------------------
367
always @ ( * )
368
begin
369
        case (iOperation)
370
        `MUL,`IMUL:                     wMultiplicationB_By = iChannel_By;      //Ay*By
371
        `MAG:                   wMultiplicationB_By = iChannel_Ay;      //Ay^2
372
        `DOT:                   wMultiplicationB_By = iChannel_By;      //Ay*By
373
        `CROSS:         wMultiplicationB_By = iChannel_By;      // Az * By
374
        default:                wMultiplicationB_By = 32'b0;
375
        endcase
376
end
377
//----------------------------------------------------
378
 
379
//------------------------------------------------------
380
reg [`WIDTH-1:0] wMultiplicationC_Az;
381
reg  [`WIDTH-1:0] wMultiplicationC_Bz;
382
wire [`LONG_WIDTH-1:0] wMultiplicationC_Result;
383
wire wMultiplicationC_InputReady;
384
wire wMultiplicationC_OutputReady;
385
 
386
 
387
RADIX_R_MUL_32_FULL_PARALLEL MultiplicationChannel_C
388
(
389
 
390
        .Clock( Clock ),
391
        .Reset( Reset ),
392
        .A( wMultiplicationC_Az ),
393
        .B( wMultiplicationC_Bz ),
394
        .R( wMultiplicationC_Result ),
395
        .iUnscaled( wMultiplcationUnscaled ),
396
        .iInputReady( wMultiplicationC_InputReady ),
397
        .OutputReady( wMultiplicationC_OutputReady )
398
);
399
 
400
 
401
//----------------------------------------------------
402
always @ ( * )
403
begin
404
        case (iOperation)
405
                `CROSS:         wMultiplicationC_Az = iChannel_Az;      //Az*Bx
406
                `MAG:   wMultiplicationC_Az = iChannel_Az;
407
                default:                                wMultiplicationC_Az = iChannel_Az;      //Az*Bz
408
        endcase
409
end
410
//----------------------------------------------------
411
 
412
assign wMultiplicationC_InputReady
413
        = (
414
                iOperation == `CROSS                    ||
415
                iOperation == `DOT      ||
416
                iOperation == `MUL              ||
417
                iOperation == `IMUL             ||
418
                iOperation == `MAG
419
                ) ? iInputReady : 0;
420
 
421
//----------------------------------------------------
422
always @ ( * )
423
begin
424
        case (iOperation)
425
        `MUL,`IMUL:                     wMultiplicationC_Bz = iChannel_Bz;      //Az*Bz
426
        `MAG:                   wMultiplicationC_Bz = iChannel_Az;      //Ay^2
427
        `DOT:                   wMultiplicationC_Bz = iChannel_Bz;      //Az*Bz
428
        `CROSS:         wMultiplicationC_Bz = iChannel_Bx;      //Az*Bx
429
        default:                wMultiplicationC_Bz = 32'b0;
430
        endcase
431
end
432
//----------------------------------------------------  
433
 
434
reg [`WIDTH-1:0] wMultiplicationD_Aw;
435
reg  [`WIDTH-1:0] wMultiplicationD_Bw;
436
wire [`LONG_WIDTH-1:0] wMultiplicationD_Result;
437
wire wMultiplicationD_InputReady;
438
wire wMultiplicationD_OutputReady;
439
 
440
 
441
RADIX_R_MUL_32_FULL_PARALLEL MultiplicationChannel_D
442
(
443
 
444
        .Clock( Clock ),
445
        .Reset( Reset ),
446
        .A( wMultiplicationD_Aw ),
447
        .B( wMultiplicationD_Bw ),
448
        .R( wMultiplicationD_Result ),
449
        .iUnscaled( wMultiplcationUnscaled ),
450
        .iInputReady( wMultiplicationD_InputReady ),
451
        .OutputReady( wMultiplicationD_OutputReady )
452
);
453
 
454
assign wMultiplicationD_InputReady
455
        = (iOperation == `CROSS ) ? iInputReady : 0;
456
 
457
 
458
//----------------------------------------------------  
459
always @ ( * )
460
begin
461
        case (iOperation)
462
        `CROSS:                 wMultiplicationD_Aw = iChannel_Ax;      //Ax*Bz
463
        default:                                                        wMultiplicationD_Aw = 32'b0;
464
        endcase
465
end
466
//----------------------------------------------------  
467
always @ ( * )
468
begin
469
        case (iOperation)
470
        `CROSS:                 wMultiplicationD_Bw = iChannel_Bz;      //Ax*Bz
471
        default:                                                        wMultiplicationD_Bw = 32'b0;
472
        endcase
473
end
474
//----------------------------------------------------  
475
reg [`WIDTH-1:0] wMultiplicationE_Ak;
476
reg  [`WIDTH-1:0] wMultiplicationE_Bk;
477
wire [`LONG_WIDTH-1:0] wMultiplicationE_Result;
478
wire wMultiplicationE_InputReady;
479
wire wMultiplicationE_OutputReady;
480
 
481
 
482
RADIX_R_MUL_32_FULL_PARALLEL MultiplicationChannel_E
483
(
484
 
485
        .Clock( Clock ),
486
        .Reset( Reset ),
487
        .A( wMultiplicationE_Ak ),
488
        .B( wMultiplicationE_Bk ),
489
        .R( wMultiplicationE_Result ),
490
        .iUnscaled( wMultiplcationUnscaled ),
491
        .iInputReady( wMultiplicationE_InputReady ),
492
        .OutputReady( wMultiplicationE_OutputReady )
493
);
494
 
495
assign wMultiplicationE_InputReady
496
        = (iOperation == `CROSS ) ? iInputReady : 0;
497
 
498
 
499
//----------------------------------------------------  
500
always @ ( * )
501
begin
502
        case (iOperation)
503
        `CROSS:                 wMultiplicationE_Ak = iChannel_Ax;      //Ax*By
504
        default:                        wMultiplicationE_Ak = 32'b0;
505
        endcase
506
end
507
//----------------------------------------------------  
508
always @ ( * )
509
begin
510
        case (iOperation)
511
        `CROSS:                 wMultiplicationE_Bk = iChannel_By;      //Ax*By
512
        default:                        wMultiplicationE_Bk = 32'b0;
513
        endcase
514
end
515
 
516
//----------------------------------------------------          
517
reg [`WIDTH-1:0] wMultiplicationF_Al;
518
reg  [`WIDTH-1:0] wMultiplicationF_Bl;
519
wire [`LONG_WIDTH-1:0] wMultiplicationF_Result;
520
wire wMultiplicationF_InputReady;
521
wire wMultiplicationF_OutputReady;
522
 
523
 
524
RADIX_R_MUL_32_FULL_PARALLEL MultiplicationChannel_F
525
(
526
 
527
        .Clock( Clock ),
528
        .Reset( Reset ),
529
        .A( wMultiplicationF_Al ),
530
        .B( wMultiplicationF_Bl ),
531
        .R( wMultiplicationF_Result ),
532
        .iUnscaled( wMultiplcationUnscaled ),
533
        .iInputReady( wMultiplicationF_InputReady ),
534
        .OutputReady( wMultiplicationF_OutputReady )
535
);
536
assign wMultiplicationF_InputReady
537
        = (iOperation == `CROSS ) ? iInputReady : 0;
538
 
539
 
540
//----------------------------------------------------  
541
always @ ( * )
542
begin
543
        case (iOperation)
544
        `CROSS:                 wMultiplicationF_Al = iChannel_Ay;      //Ay*Bx
545
        default:                        wMultiplicationF_Al = 32'b0;
546
        endcase
547
end
548
//----------------------------------------------------  
549
always @ ( * )
550
begin
551
        case (iOperation)
552
        `CROSS:                 wMultiplicationF_Bl = iChannel_Bx;      //Ay*Bx
553
        default:                        wMultiplicationF_Bl = 32'b0;
554
        endcase
555
end
556
//------------------------------------------------------
557
wire [`WIDTH-1:0] wDivisionA_Result;
558
wire wDivisionA_OutputReady;
559
wire wDivisionA_InputReady;
560
 
561
assign wDivisionA_InputReady =
562
        ( iOperation == `DIV) ? iInputReady : 0;
563
 
564
SignedIntegerDivision DivisionChannel_A
565
(
566
.Clock( Clock ),
567
.Reset( Reset ),
568
.iDividend( iChannel_Ax ),
569
.iDivisor(      iChannel_Bx ),
570
.xQuotient( wDivisionA_Result ),
571
.iInputReady( wDivisionA_InputReady ),
572
.OutputReady( wDivisionA_OutputReady )
573
 
574
);
575
//------------------------------------------------------
576
wire [`WIDTH-1:0] wDivisionB_Result;
577
wire wDivisionB_OutputReady;
578
wire wDivisionB_InputReady;
579
 
580
assign wDivisionB_InputReady =
581
        ( iOperation == `DIV) ? iInputReady : 0;
582
 
583
SignedIntegerDivision DivisionChannel_B
584
(
585
.Clock( Clock ),
586
.Reset( Reset ),
587
.iDividend( iChannel_Ay ),
588
.iDivisor( iChannel_By ),
589
.xQuotient( wDivisionB_Result ),
590
.iInputReady( wDivisionB_InputReady ),
591
.OutputReady( wDivisionB_OutputReady )
592
 
593
);
594
//------------------------------------------------------
595
wire [`WIDTH-1:0] wDivisionC_Result;
596
wire wDivisionC_OutputReady;
597
wire wDivisionC_InputReady;
598
 
599
 
600
assign wDivisionC_InputReady =
601
        ( iOperation == `DIV) ? iInputReady : 0;
602
 
603
SignedIntegerDivision DivisionChannel_C
604
(
605
.Clock( Clock ),
606
.Reset( Reset ),
607
.iDividend( iChannel_Az ),
608
.iDivisor( iChannel_Bz ),
609
.xQuotient( wDivisionC_Result ),
610
.iInputReady( wDivisionC_InputReady ),
611
.OutputReady( wDivisionC_OutputReady )
612
 
613
);
614
//--------------------------------------------------------------
615
/*
616
        First addtion block instance goes here.
617
        Note that all inputs/outputs to the block
618
        are wires. It has two MUXES one for each entry.
619
*/
620
reg [`LONG_WIDTH-1:0] wAddSubA_Ax,wAddSubA_Bx;
621
wire [`LONG_WIDTH-1:0] wAddSubA_Result;
622
wire wAddSubA_Operation; //Either addition or substraction
623
reg wAddSubA_InputReady;
624
wire wAddSubA_OutputReady;
625
 
626
assign wAddSubA_Operation
627
        = (
628
                iOperation == `SUB
629
                || iOperation == `CROSS
630
                || iOperation == `DEC
631
                || iOperation == `MOD
632
        ) ? 1 : 0;
633
 
634
FixedAddSub AddSubChannel_A
635
(
636
.Clock( Clock ),
637
.Reset( Reset ),
638
.A( wAddSubA_Ax ),
639
.B( wAddSubA_Bx ),
640
.R( wAddSubA_Result ),
641
.iOperation( wAddSubA_Operation ),
642
.iInputReady( wAddSubA_InputReady ),
643
.OutputReady( wAddSubA_OutputReady )
644
);
645
//Diego
646
 
647
 
648
//----------------------------
649
 
650
//InpuReady Mux A
651
always @ ( * )
652
begin
653
        case (iOperation)
654
        `ADD:           wAddSubA_InputReady = iInputReady;
655
        `SUB:           wAddSubA_InputReady = iInputReady;
656
        `INC,`INCX,`INCY,`INCZ:         wAddSubA_InputReady = iInputReady;
657
        `DEC:           wAddSubA_InputReady = iInputReady;
658
        `MOD:           wAddSubA_InputReady = iInputReady;
659
 
660
        `MAG:           wAddSubA_InputReady = wMultiplicationOutputReadyA &&
661
                                                                                                wMultiplicationOutputReadyB;
662
                                                                                //wMultiplicationA_OutputReady 
663
                                                                                //&& wMultiplicationB_OutputReady;
664
 
665
        `DOT:           wAddSubA_InputReady =
666
                                                                                        wMultiplicationOutputReadyA &&
667
                                                                                        wMultiplicationOutputReadyB;
668
                                                                                //wMultiplicationA_OutputReady 
669
                                                                                //&& wMultiplicationB_OutputReady;
670
 
671
        `CROSS: wAddSubA_InputReady =
672
                                                                                wMultiplicationOutputReadyA &&
673
                                                                                wMultiplicationOutputReadyB;
674
                                                                                // wMultiplicationA_OutputReady
675
                                                                                //&& wMultiplicationB_OutputReady;
676
 
677
        default:        wAddSubA_InputReady = 1'b0;
678
        endcase
679
end
680
//----------------------------
681
 
682
//wAddSubA_Bx 2:1 input Mux
683
always @ ( * )
684
begin
685
        case (iOperation)
686
 
687
        `ADD:           wAddSubA_Ax = ( iChannel_Ax[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ax } : { 32'b0, iChannel_Ax };
688
        `SUB:   wAddSubA_Ax = ( iChannel_Ax[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ax } : { 32'b0, iChannel_Ax };
689
        `INC,`INCX,`INCY,`INCZ:         wAddSubA_Ax = ( iChannel_Ax[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ax } : { 32'b0, iChannel_Ax };
690
        `DEC:           wAddSubA_Ax = ( iChannel_Ax[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ax } : { 32'b0, iChannel_Ax };
691
        `MOD:           wAddSubA_Ax = ( iChannel_Bx[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Bx } : { 32'b0, iChannel_Bx };
692
 
693
        `MAG:           wAddSubA_Ax = wMultiplicationA_Result;
694
        `DOT:           wAddSubA_Ax = wMultiplicationA_Result;
695
        `CROSS: wAddSubA_Ax = wMultiplicationA_Result;
696
        default:        wAddSubA_Ax = 64'b0;
697
        endcase
698
end
699
//----------------------------
700
//wAddSubA_Bx 2:1 input Mux
701
always @ ( * )
702
begin
703
        case (iOperation)
704
        `ADD: wAddSubA_Bx = ( iChannel_Bx[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Bx } : { 32'b0, iChannel_Bx };
705
        `SUB: wAddSubA_Bx = ( iChannel_Bx[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Bx } : { 32'b0, iChannel_Bx };
706
        `INC,`INCX: wAddSubA_Bx = (`LONG_WIDTH'd1 << `SCALE);
707
        `INCY,`INCZ: wAddSubA_Bx = `LONG_WIDTH'd0;
708
        `DEC: wAddSubA_Bx = (`LONG_WIDTH'd1 << `SCALE);
709
        `MOD: wAddSubA_Bx = (`LONG_WIDTH'd1 << `SCALE);
710
 
711
        `MAG:           wAddSubA_Bx = wMultiplicationB_Result;
712
        `DOT:           wAddSubA_Bx = wMultiplicationB_Result;
713
        `CROSS: wAddSubA_Bx = wMultiplicationB_Result;
714
        default:        wAddSubA_Bx = 64'b0;
715
        endcase
716
end
717
//--------------------------------------------------------------
718
/*
719
        Second addtion block instance goes here.
720
        Note that all inputs/outputs to the block
721
        are wires. It has two MUXES one for each entry.
722
*/
723
 
724
wire [`LONG_WIDTH-1:0] wAddSubB_Result;
725
 
726
 
727
wire wAddSubB_Operation; //Either addition or substraction
728
reg  wAddSubB_InputReady;
729
wire wAddSubB_OutputReady;
730
 
731
reg [`LONG_WIDTH-1:0] wAddSubB_Ay,wAddSubB_By;
732
 
733
assign wAddSubB_Operation =
734
        ( iOperation == `SUB
735
          || iOperation == `CROSS
736
          || iOperation == `DEC
737
          || iOperation == `MOD
738
          ) ? 1 : 0;
739
 
740
FixedAddSub AddSubChannel_B
741
(
742
.Clock( Clock ),
743
.Reset( Reset ),
744
.A( wAddSubB_Ay ),
745
.B( wAddSubB_By ),
746
.R( wAddSubB_Result ),
747
.iOperation( wAddSubB_Operation ),
748
.iInputReady( wAddSubB_InputReady ),
749
.OutputReady( wAddSubB_OutputReady )
750
);
751
//----------------------------
752
wire wMultiplicationOutputReadyC_Dealy1;
753
FFD_POSEDGE_ASYNC_RESET # (1) FFwMultiplicationOutputReadyC_Dealy1
754
(
755
        .Clock( Clock ),
756
        .Clear( Reset ),
757
        .D( wMultiplicationOutputReadyC ),
758
        .Q( wMultiplicationOutputReadyC_Dealy1 )
759
);
760
 
761
 
762
 
763
 
764
 
765
//InpuReady Mux B
766
always @ ( * )
767
begin
768
        case (iOperation)
769
        `ADD:           wAddSubB_InputReady = iInputReady;
770
        `SUB:           wAddSubB_InputReady = iInputReady;
771
        `INC,`INCX,`INCY,`INCZ:         wAddSubB_InputReady = iInputReady;
772
        `DEC:           wAddSubB_InputReady = iInputReady;
773
        `MOD:           wAddSubB_InputReady = iInputReady;
774
 
775
        `MAG:           wAddSubB_InputReady = wAddSubAOutputReady
776
                                                                                        && wMultiplicationOutputReadyC_Dealy1;
777
                                                                                //&& wMultiplicationC_OutputReady;
778
 
779
        `DOT:           wAddSubB_InputReady = wAddSubAOutputReady
780
                                                                                && wMultiplicationOutputReadyC_Dealy1;
781
                                                                                //&& wMultiplicationC_OutputReady;
782
 
783
        `CROSS: wAddSubB_InputReady = wMultiplicationOutputReadyC &&
784
                                                                                         wMultiplicationOutputReadyD;
785
                                                                                //      wMultiplicationC_OutputReady
786
                                                                                //&& wMultiplicationD_OutputReady;
787
 
788
        default:        wAddSubB_InputReady = 1'b0;
789
 
790
        endcase
791
end
792
//----------------------------
793
// wAddSubB_Ay 2:1 input Mux
794
// If the iOperation is ADD or SUB, it will simply take the inputs from
795
// ALU Channels. If it is a VECTOR_MAGNITUDE, it take the input from the
796
// previus ADDER_A, same for dot product.
797
always @ ( * )
798
begin
799
        case (iOperation)
800
        `ADD:   wAddSubB_Ay = (iChannel_Ay[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ay} : {32'b0,iChannel_Ay};            //Ay
801
        `SUB:   wAddSubB_Ay = (iChannel_Ay[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ay} : {32'b0,iChannel_Ay};            //Ay
802
        `INC,`INCX,`INCY,`INCZ:         wAddSubB_Ay = (iChannel_Ay[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ay} : {32'b0,iChannel_Ay};            //Ay
803
        `DEC:           wAddSubB_Ay = (iChannel_Ay[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ay} : {32'b0,iChannel_Ay};            //Ay
804
        `MOD:           wAddSubB_Ay = (iChannel_By[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_By} : {32'b0,iChannel_By};            //Ay
805
        `MAG:           wAddSubB_Ay = wAddSubA_Result;  //A^2+B^2
806
        `DOT:           wAddSubB_Ay = wAddSubA_Result;   //Ax*Bx + Ay*By
807
        `CROSS: wAddSubB_Ay     = wMultiplicationC_Result;
808
        default:        wAddSubB_Ay = 64'b0;
809
        endcase
810
end
811
//----------------------------
812
//wAddSubB_By 2:1 input Mux
813
always @ ( * )
814
begin
815
        case (iOperation)
816
        `ADD:   wAddSubB_By = (iChannel_By[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_By } : {32'b0,iChannel_By};                            //By
817
        `SUB:   wAddSubB_By = (iChannel_By[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_By } : {32'b0,iChannel_By}; //{32'b0,iChannel_By};                             //By
818
        `INC,`INCY:             wAddSubB_By = (`LONG_WIDTH'd1 << `SCALE);
819
        `INCX,`INCZ:   wAddSubB_By = `LONG_WIDTH'd0;
820
        `DEC:           wAddSubB_By = (`LONG_WIDTH'd1 << `SCALE);
821
        `MOD:           wAddSubB_By = (`LONG_WIDTH'd1 << `SCALE);
822
        `MAG:           wAddSubB_By = wMultiplicationC_Result;  //C^2
823
        `DOT:           wAddSubB_By = wMultiplicationC_Result;  //Az * Bz
824
        `CROSS: wAddSubB_By     = wMultiplicationD_Result;
825
        default:        wAddSubB_By = 32'b0;
826
        endcase
827
end
828
//--------------------------------------------------------------
829
wire [`LONG_WIDTH-1:0] wAddSubC_Result;
830
reg [`LONG_WIDTH-1:0] wAddSubC_Az,wAddSubC_Bz;
831
 
832
wire wAddSubC_Operation; //Either addition or substraction
833
reg wAddSubC_InputReady;
834
wire wAddSubC_OutputReady;
835
 
836
reg [`LONG_WIDTH-1:0] AddSubC_Az,AddSubB_Bz;
837
 
838
//-----------------------------------------
839
always @ ( * )
840
begin
841
        case (iOperation)
842
                `CROSS:         wAddSubC_Az = wMultiplicationE_Result;
843
                `MOD: wAddSubC_Az = (iChannel_Bz[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_Bz} : {32'b0,iChannel_Bz};
844
                default:                                wAddSubC_Az = (iChannel_Az[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_Az} : {32'b0,iChannel_Az};
845
        endcase
846
end
847
//-----------------------------------------
848
always @ ( * )
849
begin
850
        case (iOperation)
851
                `CROSS:         wAddSubC_Bz = wMultiplicationF_Result;
852
                `INC,`INCZ:             wAddSubC_Bz = (`LONG_WIDTH'd1 << `SCALE);
853
                `INCX,`INCY:   wAddSubC_Bz = `LONG_WIDTH'd0;
854
                `DEC:           wAddSubC_Bz = (`LONG_WIDTH'd1 << `SCALE);
855
                `MOD:           wAddSubC_Bz = (`LONG_WIDTH'd1 << `SCALE);
856
                default:                                wAddSubC_Bz = (iChannel_Bz[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_Bz} : {32'b0,iChannel_Bz};
857
        endcase
858
end
859
//-----------------------------------------
860
 
861
assign wAddSubC_Operation
862
        = (
863
                iOperation == `SUB
864
                || iOperation == `CROSS
865
                || iOperation == `DEC
866
                || iOperation == `MOD
867
                ) ? 1 : 0;
868
 
869
FixedAddSub AddSubChannel_C
870
(
871
.Clock( Clock ),
872
.Reset( Reset ),
873
.A( wAddSubC_Az ),
874
.B( wAddSubC_Bz ),
875
.R( wAddSubC_Result ),
876
.iOperation( wAddSubC_Operation ),
877
.iInputReady( wAddSubC_InputReady ),
878
.OutputReady( wAddSubC_OutputReady )
879
);
880
 
881
 
882
always @ ( * )
883
begin
884
        case (iOperation)
885
        `CROSS: wAddSubC_InputReady = wMultiplicationE_OutputReady &&
886
                wMultiplicationF_OutputReady;
887
 
888
        default: wAddSubC_InputReady = iInputReady;
889
        endcase
890
end
891
 
892
//------------------------------------------------------
893
wire [`WIDTH-1:0] wSquareRoot_Result;
894
wire wSquareRoot_OutputReady;
895
 
896
 
897
FixedPointSquareRoot SQROOT1
898
(
899
        .Clock( Clock ),
900
        .Reset( Reset ),
901
        .Operand( wAddSubB_Result ),
902
        .iInputReady( wAddSubBOutputReady && iOperation == `MAG),
903
        .OutputReady( wSquareRoot_OutputReady ),
904
        .Result( wSquareRoot_Result )
905
);
906
//------------------------------------------------------
907
 
908
assign wModulus2N_ResultA =  (iChannel_Ax  & wAddSubA_Result );
909
assign wModulus2N_ResultB =  (iChannel_Ay  & wAddSubB_Result );
910
assign wModulus2N_ResultC =  (iChannel_Az  & wAddSubC_Result );
911
 
912
 
913
 
914
 
915
 
916
 
917
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//
918
//****Mux for ResultA***
919
// Notice that the Dot Product or the Magnitud Result will
920
// output in ResultA.
921
 
922
always @ ( *  )
923
begin
924
        case ( iOperation )
925
        `RETURN:                                ResultA = iChannel_Ax;
926
        `ADD:                                   ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};// & 32'h7FFFFFFF;
927
        `SUB:                                   ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};//wAddSubA_Result[31:0];
928
        `CROSS:                         ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};//wAddSubA_Result[31:0];
929
        `DIV:                                   ResultA = wDivisionA_Result;
930
        `MUL:                                   ResultA = wMultiplicationA_Result[31:0];
931
        `IMUL:            ResultA = wMultiplicationA_Result[31:0];
932
        `DOT:                                   ResultA = (wAddSubB_Result[63] == 1'b1) ? { 1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]};//wAddSubB_Result[31:0];
933
        `MAG:                                   ResultA = wSquareRoot_Result;
934
        `ZERO:                          ResultA = 32'b0;
935
        `COPY:                          ResultA = iChannel_Ax;
936
        `TMREAD:          ResultA = iTMEMReadData[95:64];
937
        `LEA:             ResultA = {16'b0,iCurrentIP};
938
 
939
        `SWIZZLE3D: ResultA  = wSwizzleOutputX;
940
 
941
        //Set Operations
942
        `UNSCALE:                       ResultA  = iChannel_Ax >> `SCALE;
943
        `SETX,`RET:     ResultA  = iChannel_Ax;
944
   `SETY:                               ResultA  = iChannel_Bx;
945
        `SETZ:                          ResultA  = iChannel_Bx;
946
        `INC,`INCX,`INCY,`INCZ:                                 ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};
947
        `DEC:                                   ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};
948
        `MOD:                                   ResultA =  wModulus2N_ResultA;
949
        `FRAC:                          ResultA = iChannel_Ax & (`WIDTH'hFFFFFFFF >> (`WIDTH - `SCALE));
950
        `MULP:                     ResultA = iChannel_Ax;
951
        `NEG:                                   ResultA = ~iChannel_Ax + 1'b1;
952
        `XCHANGEX:                      ResultA  = iChannel_Bx;
953
 
954
        default:
955
        begin
956
        `ifdef DEBUG
957
//      $display("%dns ALU: Error Unknown Operation: %d",$time,iOperation);
958
//      $stop();
959
        `endif
960
        ResultA =  32'b0;
961
        end
962
        endcase
963
end
964
//------------------------------------------------------
965
//****Mux for RB***
966
always @ ( * )
967
begin
968
        case ( iOperation )
969
        `RETURN:                                ResultB = iChannel_Ax;
970
        `ADD:                                   ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]}; // & 32'h7FFFFFFF;
971
        `SUB:                                   ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]}; //wAddSubB_Result[31:0];
972
        `CROSS:                         ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]};//wAddSubB_Result[31:0];
973
        `DIV:                                   ResultB = wDivisionB_Result;
974
        `MUL:                                   ResultB = wMultiplicationB_Result[31:0];
975
        `IMUL:            ResultB = wMultiplicationB_Result[31:0];
976
        `DOT:                                   ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]};//wAddSubB_Result[31:0];
977
        `MAG:                                   ResultB = wSquareRoot_Result;
978
        `ZERO:                          ResultB = 32'b0;
979
        `COPY:                          ResultB = iChannel_Ay;
980
        `TMREAD:          ResultB = iTMEMReadData[63:32];
981
        `LEA:             ResultB = {16'b0,iCurrentIP};
982
 
983
        //Set Operations
984
        `UNSCALE:                       ResultB  = iChannel_Ay >> `SCALE;
985
        `SETX,`RET:             ResultB  = iChannel_By;         // {Source1[95:64],Source0[63:32],Source0[31:0]}; 
986
        `SETY:                          ResultB  = iChannel_Ax;         // {Source0[95:64],Source1[95:64],Source0[31:0]}; 
987
        `SETZ:                          ResultB  = iChannel_By;  // {Source0[95:64],Source0[63:32],Source1[95:64]}; 
988
 
989
        `SWIZZLE3D:             ResultB  = wSwizzleOutputY;
990
 
991
        `INC,`INCX,`INCY,`INCZ:                                 ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]}; // & 32'h7FFFFFFF;
992
        `DEC:                                   ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]}; // & 32'h7FFFFFFF;
993
        `MOD:                                   ResultB =  wModulus2N_ResultB;
994
        `FRAC:                          ResultB = iChannel_Ay & (`WIDTH'hFFFFFFFF >> (`WIDTH - `SCALE));
995
        `MULP:                          ResultB = iChannel_Ay;
996
        `NEG:                                   ResultB = ~iChannel_Ay + 1'b1;
997
        `XCHANGEX:                      ResultB = iChannel_Ay;
998
 
999
        default:
1000
        begin
1001
        `ifdef DEBUG
1002
        //$display("%dns ALU: Error Unknown Operation: %d",$time,iOperation);
1003
        //$stop();
1004
        `endif
1005
        ResultB =  32'b0;
1006
        end
1007
        endcase
1008
end
1009
//------------------------------------------------------
1010
//****Mux for RC***
1011
always @ ( * )
1012
begin
1013
        case ( iOperation )
1014
        `RETURN:                                ResultC = iChannel_Ax;
1015
        `ADD:                                   ResultC = (wAddSubC_Result[63] == 1'b1) ? {1'b1,wAddSubC_Result[30:0]} : {1'b0,wAddSubC_Result[30:0]}; //wAddSubC_Result[31:0];// & 32'h7FFFFFFF;
1016
        `SUB:                                   ResultC = (wAddSubC_Result[63] == 1'b1) ? {1'b1,wAddSubC_Result[30:0]} : {1'b0,wAddSubC_Result[30:0]}; //wAddSubC_Result[31:0];
1017
        `CROSS:                         ResultC = (wAddSubC_Result[63] == 1'b1) ? {1'b1,wAddSubC_Result[30:0]} : {1'b0,wAddSubC_Result[30:0]};//wAddSubC_Result[31:0];
1018
        `DIV:                                   ResultC = wDivisionC_Result;
1019
        `MUL:                                   ResultC = wMultiplicationC_Result[31:0];
1020
        `IMUL:            ResultC = wMultiplicationC_Result[31:0];
1021
        `DOT:                                   ResultC = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]};//wAddSubB_Result[31:0];
1022
        `MAG:                                   ResultC = wSquareRoot_Result;
1023
        `ZERO:                          ResultC = 32'b0;
1024
        `COPY:                          ResultC = iChannel_Az;
1025
        `TMREAD:          ResultC = iTMEMReadData[31:0];
1026
        `LEA:             ResultC = {16'b0,iCurrentIP};
1027
 
1028
        `SWIZZLE3D: ResultC  = wSwizzleOutputZ;
1029
 
1030
        //Set Operations
1031
        `UNSCALE:                       ResultC  = iChannel_Az >> `SCALE;
1032
        `SETX,`RET:             ResultC  = iChannel_Bz;         // {Source1[95:64],Source0[63:32],Source0[31:0]}; 
1033
        `SETY:                          ResultC  = iChannel_Bz;         // {Source0[95:64],Source1[95:64],Source0[31:0]}; 
1034
        `SETZ:                          ResultC  = iChannel_Ax;  // {Source0[95:64],Source0[63:32],Source1[95:64]}; 
1035
 
1036
        `INC,`INCX,`INCY,`INCZ:                                 ResultC = (wAddSubC_Result[63] == 1'b1) ? {1'b1,wAddSubC_Result[30:0]} : {1'b0,wAddSubC_Result[30:0]}; //wAddSubC_Result[31:0];// & 32'h7FFFFFFF;
1037
        `DEC:                                   ResultC = (wAddSubC_Result[63] == 1'b1) ? {1'b1,wAddSubC_Result[30:0]} : {1'b0,wAddSubC_Result[30:0]}; //wAddSubC_Result[31:0];// & 32'h7FFFFFFF;
1038
        `MOD:                                   ResultC =  wModulus2N_ResultC;
1039
        `FRAC:                          ResultC = iChannel_Az & (`WIDTH'hFFFFFFFF >> (`WIDTH - `SCALE));
1040
        `MULP:                          ResultC = wMultiplicationA_Result[31:0];
1041
        `NEG:                                   ResultC = ~iChannel_Az + 1'b1;
1042
        `XCHANGEX:                      ResultC = iChannel_Az;
1043
        default:
1044
        begin
1045
        `ifdef DEBUG
1046
        //$display("%dns ALU: Error Unknown Operation: %d",$time,iOperation);
1047
        //$stop();
1048
        `endif
1049
        ResultC =  32'b0;
1050
        end
1051
        endcase
1052
end
1053
//------------------------------------------------------------------------
1054
 
1055
 
1056
always @ ( * )
1057
begin
1058
        case (iOperation)
1059
        `JMP,`CALL,`RET: oBranchTaken = OutputReady;
1060
        `JGX:   oBranchTaken = wArithmeticComparison_Result;
1061
        `JGY:   oBranchTaken = wArithmeticComparison_Result;
1062
        `JGZ:   oBranchTaken = wArithmeticComparison_Result;
1063
 
1064
        `JLX:   oBranchTaken = wArithmeticComparison_Result;
1065
        `JLY:   oBranchTaken = wArithmeticComparison_Result;
1066
        `JLZ:   oBranchTaken = wArithmeticComparison_Result;
1067
 
1068
        `JEQX:  oBranchTaken = wArithmeticComparison_Result;
1069
        `JEQY:  oBranchTaken = wArithmeticComparison_Result;
1070
        `JEQZ:  oBranchTaken = wArithmeticComparison_Result;
1071
 
1072
        `JNEX:  oBranchTaken = wArithmeticComparison_Result;
1073
        `JNEY:  oBranchTaken = wArithmeticComparison_Result;
1074
        `JNEZ:  oBranchTaken = wArithmeticComparison_Result;
1075
 
1076
        `JGEX:  oBranchTaken = wArithmeticComparison_Result;
1077
        `JGEY:  oBranchTaken = wArithmeticComparison_Result;
1078
        `JGEZ:  oBranchTaken = wArithmeticComparison_Result;
1079
 
1080
        `JLEX:  oBranchTaken = wArithmeticComparison_Result;
1081
        `JLEY:  oBranchTaken = wArithmeticComparison_Result;
1082
        `JLEZ:  oBranchTaken = wArithmeticComparison_Result;
1083
 
1084
        default: oBranchTaken = 0;
1085
        endcase
1086
 
1087
end
1088
 
1089
always @ ( * )
1090
begin
1091
        case (iOperation)
1092
 
1093
                `JMP,`CALL,`RET,`JGX,`JGY,`JGZ,`JLX,`JLY,`JLZ,`JEQX,`JEQY,`JEQZ,
1094
                `JNEX,`JNEY,`JNEZ,`JGEX,`JGEY,`JGEZ: oBranchNotTaken = !oBranchTaken && OutputReady;
1095
                `JLEX: oBranchNotTaken = !oBranchTaken && OutputReady;
1096
                `JLEY: oBranchNotTaken = !oBranchTaken && OutputReady;
1097
                `JLEZ: oBranchNotTaken = !oBranchTaken && OutputReady;
1098
        default:
1099
                oBranchNotTaken = 0;
1100
        endcase
1101
end
1102
//------------------------------------------------------------------------
1103
//Output ready logic Stuff for Division...
1104
//Some FFT will hopefully do the trick
1105
 
1106
wire wDivisionOutputReadyA,wDivisionOutputReadyB,wDivisionOutputReadyC;
1107
wire wDivisionOutputReady;
1108
 
1109
 
1110
assign wAddSubAOutputReady = wAddSubA_OutputReady;
1111
assign wAddSubBOutputReady = wAddSubB_OutputReady;
1112
assign wAddSubCOutputReady = wAddSubC_OutputReady;
1113
 
1114
 
1115
FFT1 FFT_DivisionA
1116
  (
1117
   .D(1'b1),
1118
   .Clock( wDivisionA_OutputReady ),
1119
   .Reset( iInputReady ),
1120
   .Q( wDivisionOutputReadyA )
1121
 );
1122
 
1123
FFT1 FFT_DivisionB
1124
  (
1125
   .D(1'b1),
1126
   .Clock( wDivisionB_OutputReady ),
1127
   .Reset( iInputReady ),
1128
   .Q( wDivisionOutputReadyB )
1129
 );
1130
 
1131
 FFT1 FFT_DivisionC
1132
  (
1133
   .D(1'b1),
1134
   .Clock( wDivisionC_OutputReady ),
1135
   .Reset( iInputReady ),
1136
   .Q( wDivisionOutputReadyC )
1137
 );
1138
 
1139
 assign wDivisionOutputReady =
1140
 ( wDivisionOutputReadyA && wDivisionOutputReadyB && wDivisionOutputReadyC );
1141
 
1142
assign wMultiplicationOutputReadyA = wMultiplicationA_OutputReady;
1143
assign wMultiplicationOutputReadyB = wMultiplicationB_OutputReady;
1144
assign wMultiplicationOutputReadyC = wMultiplicationC_OutputReady;
1145
assign wMultiplicationOutputReadyD = wMultiplicationD_OutputReady;
1146
 
1147
 assign wMultiplicationOutputReady =
1148
 ( wMultiplicationOutputReadyA && wMultiplicationOutputReadyB && wMultiplicationOutputReadyC );
1149
 
1150
 wire wSquareRootOutputReady;
1151
 FFT1 FFT_Sqrt
1152
  (
1153
   .D(1'b1),
1154
   .Clock( wSquareRoot_OutputReady ),
1155
   .Reset( iInputReady ),
1156
   .Q( wSquareRootOutputReady )
1157
 );
1158
 
1159
 
1160
//------------------------------------------------------------------------
1161
wire wOutputDelay1Cycle,wOutputDelay2Cycle,wOutputDelay3Cycle;
1162
 
1163
 
1164
FFD_POSEDGE_ASYNC_RESET # (1) FFOutputReadyDelay2
1165
(
1166
        .Clock( Clock ),
1167
        .Clear( Reset ),
1168
        .D( iInputReady ),
1169
        .Q( wOutputDelay1Cycle )
1170
);
1171
 
1172
FFD_POSEDGE_ASYNC_RESET # (1) FFOutputReadyDelay22
1173
(
1174
        .Clock( Clock  ),
1175
        .Clear( Reset ),
1176
        .D( wOutputDelay1Cycle ),
1177
        .Q( wOutputDelay2Cycle )
1178
);
1179
 
1180
 
1181
FFD_POSEDGE_ASYNC_RESET # (1) FFOutputReadyDelay222
1182
(
1183
        .Clock( Clock &&  wOperation == `OMWRITE),
1184
        .Clear( Reset ),
1185
        .D( wOutputDelay2Cycle ),
1186
        .Q( wOutputDelay3Cycle )
1187
);
1188
 
1189
 
1190
 
1191
 
1192
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_OP_LENGTH ) SourceZ2
1193
(
1194
        .Clock( Clock ),
1195
        .Reset( Reset ),
1196
        .Enable( iInputReady ),
1197
        .D( iOperation ),
1198
        .Q(wOperation)
1199
);
1200
 
1201
 
1202
//Mux for output ready signal
1203
always @ ( * )
1204
begin
1205
        case ( wOperation )
1206
        `UNSCALE:                       OutputReady  = wOutputDelay1Cycle;
1207
        `RETURN: OutputReady = wOutputDelay1Cycle;
1208
 
1209
        `NOP: OutputReady = wOutputDelay1Cycle;
1210
        `FRAC: OutputReady = wOutputDelay1Cycle;
1211
        `NEG: OutputReady = wOutputDelay1Cycle;
1212
        `OMWRITE: OutputReady = wOutputDelay3Cycle;
1213
        `TMREAD:  OutputReady = wTMReadOutputReady;  //One cycle after TMEM data availale asserted
1214
 
1215
        `ifdef DEBUG
1216
        //Debug Print behaves as a NOP in terms of ALU...
1217
        `DEBUG_PRINT: OutputReady = wOutputDelay1Cycle;
1218
        `endif
1219
 
1220
        `ADD,`INC,`INCX,`INCY,`INCZ:            OutputReady =   wAddSubAOutputReady &&
1221
                                                                        wAddSubBOutputReady &&
1222
                                                                        wAddSubCOutputReady;
1223
 
1224
        `SUB,`DEC:              OutputReady =   wAddSubAOutputReady &&
1225
                                                                        wAddSubBOutputReady &&
1226
                                                                        wAddSubCOutputReady;
1227
 
1228
        `DIV:           OutputReady =   wDivisionOutputReady;
1229
 
1230
 
1231
        `MUL,`IMUL:     OutputReady =   wMultiplicationOutputReady;
1232
        `MULP:  OutputReady =  wMultiplicationOutputReadyA;
1233
 
1234
        `DOT:           OutputReady = wAddSubBOutputReady;
1235
 
1236
        `CROSS: OutputReady =   wAddSubAOutputReady &&
1237
                                                                        wAddSubBOutputReady &&
1238
                                                                        wAddSubCOutputReady;
1239
 
1240
        `MAG:           OutputReady = wSquareRootOutputReady;
1241
 
1242
        `ZERO:  OutputReady = wOutputDelay1Cycle;
1243
 
1244
        `COPY:  OutputReady = wOutputDelay1Cycle;
1245
 
1246
        `SWIZZLE3D: OutputReady = wOutputDelay1Cycle;
1247
 
1248
        `SETX,`SETY,`SETZ,`JMP,`LEA,`CALL,`RET:         OutputReady = wOutputDelay1Cycle;
1249
 
1250
 
1251
 
1252
        `JGX,`JGY,`JGZ:                         OutputReady = ArithmeticComparison_OutputReady;
1253
        `JLX,`JLY,`JLZ:                         OutputReady = ArithmeticComparison_OutputReady;
1254
        `JEQX,`JEQY,`JEQZ:                      OutputReady = ArithmeticComparison_OutputReady;
1255
        `JNEX,`JNEY,`JNEZ:                      OutputReady = ArithmeticComparison_OutputReady;
1256
        `JGEX,`JGEY,`JGEZ:                      OutputReady = ArithmeticComparison_OutputReady;
1257
        `JLEX,`JLEY,`JLEZ:                      OutputReady = ArithmeticComparison_OutputReady;
1258
 
1259
        `MOD: OutputReady = wAddSubAOutputReady &&                              //TODO: wait 1 more cycle
1260
                                                                        wAddSubBOutputReady &&
1261
                                                                        wAddSubCOutputReady;
1262
 
1263
        `XCHANGEX: OutputReady = wOutputDelay1Cycle;
1264
 
1265
 
1266
        default:
1267
        begin
1268
                OutputReady =  32'b0;
1269
                //`ifdef DEBUG
1270
                //$display("*** ALU ERROR: iOperation = %d ***",iOperation);
1271
                //`endif
1272
        end
1273
 
1274
        endcase
1275
end
1276
 
1277
endmodule
1278
//------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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