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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [branches/] [icarus_version/] [rtl/] [Module_VectorALU.v] - Blame information for rev 169

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

Line No. Rev Author Line
1 158 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 164 diegovalve
.oQuotient( wDivisionA_Result[`WIDTH-1:0] ),
571 158 diegovalve
.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 164 diegovalve
.oQuotient( wDivisionB_Result[`WIDTH-1:0] ),
590 158 diegovalve
.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 164 diegovalve
.oQuotient( wDivisionC_Result[`WIDTH-1:0] ),
610 158 diegovalve
.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_SYNCRONOUS_RESET # (1) FFwMultiplicationOutputReadyC_Dealy1
754
(
755
        .Clock( Clock ),
756
        .Reset( Reset ),
757
        .Enable(1'b1 ),
758
        .D( wMultiplicationOutputReadyC ),
759
        .Q( wMultiplicationOutputReadyC_Dealy1 )
760
);
761
 
762
 
763
 
764
 
765
 
766
//InpuReady Mux B
767
always @ ( * )
768
begin
769
        case (iOperation)
770
        `ADD:           wAddSubB_InputReady = iInputReady;
771
        `SUB:           wAddSubB_InputReady = iInputReady;
772
        `INC,`INCX,`INCY,`INCZ:         wAddSubB_InputReady = iInputReady;
773
        `DEC:           wAddSubB_InputReady = iInputReady;
774
        `MOD:           wAddSubB_InputReady = iInputReady;
775
 
776
        `MAG:           wAddSubB_InputReady = wAddSubAOutputReady
777
                                                                                        && wMultiplicationOutputReadyC_Dealy1;
778
                                                                                //&& wMultiplicationC_OutputReady;
779
 
780
        `DOT:           wAddSubB_InputReady = wAddSubAOutputReady
781
                                                                                && wMultiplicationOutputReadyC_Dealy1;
782
                                                                                //&& wMultiplicationC_OutputReady;
783
 
784
        `CROSS: wAddSubB_InputReady = wMultiplicationOutputReadyC &&
785
                                                                                         wMultiplicationOutputReadyD;
786
                                                                                //      wMultiplicationC_OutputReady
787
                                                                                //&& wMultiplicationD_OutputReady;
788
 
789
        default:        wAddSubB_InputReady = 1'b0;
790
 
791
        endcase
792
end
793
//----------------------------
794
// wAddSubB_Ay 2:1 input Mux
795
// If the iOperation is ADD or SUB, it will simply take the inputs from
796
// ALU Channels. If it is a VECTOR_MAGNITUDE, it take the input from the
797
// previus ADDER_A, same for dot product.
798
always @ ( * )
799
begin
800
        case (iOperation)
801
        `ADD:   wAddSubB_Ay = (iChannel_Ay[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ay} : {32'b0,iChannel_Ay};            //Ay
802
        `SUB:   wAddSubB_Ay = (iChannel_Ay[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ay} : {32'b0,iChannel_Ay};            //Ay
803
        `INC,`INCX,`INCY,`INCZ:         wAddSubB_Ay = (iChannel_Ay[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ay} : {32'b0,iChannel_Ay};            //Ay
804
        `DEC:           wAddSubB_Ay = (iChannel_Ay[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_Ay} : {32'b0,iChannel_Ay};            //Ay
805
        `MOD:           wAddSubB_Ay = (iChannel_By[31] == 1'b1) ? {32'hFFFFFFFF, iChannel_By} : {32'b0,iChannel_By};            //Ay
806
        `MAG:           wAddSubB_Ay = wAddSubA_Result;  //A^2+B^2
807
        `DOT:           wAddSubB_Ay = wAddSubA_Result;   //Ax*Bx + Ay*By
808
        `CROSS: wAddSubB_Ay     = wMultiplicationC_Result;
809
        default:        wAddSubB_Ay = 64'b0;
810
        endcase
811
end
812
//----------------------------
813
//wAddSubB_By 2:1 input Mux
814
always @ ( * )
815
begin
816
        case (iOperation)
817
        `ADD:   wAddSubB_By = (iChannel_By[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_By } : {32'b0,iChannel_By};                            //By
818
        `SUB:   wAddSubB_By = (iChannel_By[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_By } : {32'b0,iChannel_By}; //{32'b0,iChannel_By};                             //By
819
        `INC,`INCY:             wAddSubB_By = (`LONG_WIDTH'd1 << `SCALE);
820
        `INCX,`INCZ:   wAddSubB_By = `LONG_WIDTH'd0;
821
        `DEC:           wAddSubB_By = (`LONG_WIDTH'd1 << `SCALE);
822
        `MOD:           wAddSubB_By = (`LONG_WIDTH'd1 << `SCALE);
823
        `MAG:           wAddSubB_By = wMultiplicationC_Result;  //C^2
824
        `DOT:           wAddSubB_By = wMultiplicationC_Result;  //Az * Bz
825
        `CROSS: wAddSubB_By     = wMultiplicationD_Result;
826
        default:        wAddSubB_By = 32'b0;
827
        endcase
828
end
829
//--------------------------------------------------------------
830
wire [`LONG_WIDTH-1:0] wAddSubC_Result;
831
reg [`LONG_WIDTH-1:0] wAddSubC_Az,wAddSubC_Bz;
832
 
833
wire wAddSubC_Operation; //Either addition or substraction
834
reg wAddSubC_InputReady;
835
wire wAddSubC_OutputReady;
836
 
837
reg [`LONG_WIDTH-1:0] AddSubC_Az,AddSubB_Bz;
838
 
839
//-----------------------------------------
840
always @ ( * )
841
begin
842
        case (iOperation)
843
                `CROSS:         wAddSubC_Az = wMultiplicationE_Result;
844
                `MOD: wAddSubC_Az = (iChannel_Bz[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_Bz} : {32'b0,iChannel_Bz};
845
                default:                                wAddSubC_Az = (iChannel_Az[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_Az} : {32'b0,iChannel_Az};
846
        endcase
847
end
848
//-----------------------------------------
849
always @ ( * )
850
begin
851
        case (iOperation)
852
                `CROSS:         wAddSubC_Bz = wMultiplicationF_Result;
853
                `INC,`INCZ:             wAddSubC_Bz = (`LONG_WIDTH'd1 << `SCALE);
854
                `INCX,`INCY:   wAddSubC_Bz = `LONG_WIDTH'd0;
855
                `DEC:           wAddSubC_Bz = (`LONG_WIDTH'd1 << `SCALE);
856
                `MOD:           wAddSubC_Bz = (`LONG_WIDTH'd1 << `SCALE);
857
                default:                                wAddSubC_Bz = (iChannel_Bz[31] == 1'b1) ? {32'hFFFFFFFF,iChannel_Bz} : {32'b0,iChannel_Bz};
858
        endcase
859
end
860
//-----------------------------------------
861
 
862
assign wAddSubC_Operation
863
        = (
864
                iOperation == `SUB
865
                || iOperation == `CROSS
866
                || iOperation == `DEC
867
                || iOperation == `MOD
868
                ) ? 1 : 0;
869
 
870
FixedAddSub AddSubChannel_C
871
(
872
.Clock( Clock ),
873
.Reset( Reset ),
874
.A( wAddSubC_Az ),
875
.B( wAddSubC_Bz ),
876
.R( wAddSubC_Result ),
877
.iOperation( wAddSubC_Operation ),
878
.iInputReady( wAddSubC_InputReady ),
879
.OutputReady( wAddSubC_OutputReady )
880
);
881
 
882
 
883
always @ ( * )
884
begin
885
        case (iOperation)
886
        `CROSS: wAddSubC_InputReady = wMultiplicationE_OutputReady &&
887
                wMultiplicationF_OutputReady;
888
 
889
        default: wAddSubC_InputReady = iInputReady;
890
        endcase
891
end
892
 
893
//------------------------------------------------------
894
wire [`WIDTH-1:0] wSquareRoot_Result;
895
wire wSquareRoot_OutputReady;
896
 
897
 
898
FixedPointSquareRoot SQROOT1
899
(
900
        .Clock( Clock ),
901
        .Reset( Reset ),
902
        .Operand( wAddSubB_Result ),
903
        .iInputReady( wAddSubBOutputReady && iOperation == `MAG),
904
        .OutputReady( wSquareRoot_OutputReady ),
905
        .Result( wSquareRoot_Result )
906
);
907
//------------------------------------------------------
908
 
909
assign wModulus2N_ResultA =  (iChannel_Ax  & wAddSubA_Result );
910
assign wModulus2N_ResultB =  (iChannel_Ay  & wAddSubB_Result );
911
assign wModulus2N_ResultC =  (iChannel_Az  & wAddSubC_Result );
912
 
913
 
914
 
915
 
916
 
917
 
918
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//
919
//****Mux for ResultA***
920
// Notice that the Dot Product or the Magnitud Result will
921
// output in ResultA.
922
 
923
always @ ( *  )
924
begin
925
        case ( iOperation )
926
        `RETURN:                                ResultA = iChannel_Ax;
927
        `ADD:                                   ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};// & 32'h7FFFFFFF;
928
        `SUB:                                   ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};//wAddSubA_Result[31:0];
929
        `CROSS:                         ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};//wAddSubA_Result[31:0];
930
        `DIV:                                   ResultA = wDivisionA_Result;
931
        `MUL:                                   ResultA = wMultiplicationA_Result[31:0];
932
        `IMUL:            ResultA = wMultiplicationA_Result[31:0];
933
        `DOT:                                   ResultA = (wAddSubB_Result[63] == 1'b1) ? { 1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]};//wAddSubB_Result[31:0];
934
        `MAG:                                   ResultA = wSquareRoot_Result;
935
        `ZERO:                          ResultA = 32'b0;
936
        `COPY:                          ResultA = iChannel_Ax;
937
        `TMREAD:          ResultA = iTMEMReadData[95:64];
938
        `LEA:             ResultA = {16'b0,iCurrentIP};
939
 
940
        `SWIZZLE3D: ResultA  = wSwizzleOutputX;
941
 
942
        //Set Operations
943
        `UNSCALE:                       ResultA  = iChannel_Ax >> `SCALE;
944
        `SETX,`RET:     ResultA  = iChannel_Ax;
945
   `SETY:                               ResultA  = iChannel_Bx;
946
        `SETZ:                          ResultA  = iChannel_Bx;
947
        `INC,`INCX,`INCY,`INCZ:                                 ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};
948
        `DEC:                                   ResultA = (wAddSubA_Result[63] == 1'b1) ? { 1'b1,wAddSubA_Result[30:0]} : {1'b0,wAddSubA_Result[30:0]};
949
        `MOD:                                   ResultA =  wModulus2N_ResultA;
950
        `FRAC:                          ResultA = iChannel_Ax & (`WIDTH'hFFFFFFFF >> (`WIDTH - `SCALE));
951
        `MULP:                     ResultA = iChannel_Ax;
952
        `NEG:                                   ResultA = ~iChannel_Ax + 1'b1;
953
        `XCHANGEX:                      ResultA  = iChannel_Bx;
954
 
955
        default:
956
        begin
957
        `ifdef DEBUG
958
//      $display("%dns ALU: Error Unknown Operation: %d",$time,iOperation);
959
//      $stop();
960
        `endif
961
        ResultA =  32'b0;
962
        end
963
        endcase
964
end
965
//------------------------------------------------------
966
//****Mux for RB***
967
always @ ( * )
968
begin
969
        case ( iOperation )
970
        `RETURN:                                ResultB = iChannel_Ax;
971
        `ADD:                                   ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]}; // & 32'h7FFFFFFF;
972
        `SUB:                                   ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]}; //wAddSubB_Result[31:0];
973
        `CROSS:                         ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]};//wAddSubB_Result[31:0];
974
        `DIV:                                   ResultB = wDivisionB_Result;
975
        `MUL:                                   ResultB = wMultiplicationB_Result[31:0];
976
        `IMUL:            ResultB = wMultiplicationB_Result[31:0];
977
        `DOT:                                   ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]};//wAddSubB_Result[31:0];
978
        `MAG:                                   ResultB = wSquareRoot_Result;
979
        `ZERO:                          ResultB = 32'b0;
980
        `COPY:                          ResultB = iChannel_Ay;
981
        `TMREAD:          ResultB = iTMEMReadData[63:32];
982
        `LEA:             ResultB = {16'b0,iCurrentIP};
983
 
984
        //Set Operations
985
        `UNSCALE:                       ResultB  = iChannel_Ay >> `SCALE;
986
        `SETX,`RET:             ResultB  = iChannel_By;         // {Source1[95:64],Source0[63:32],Source0[31:0]}; 
987
        `SETY:                          ResultB  = iChannel_Ax;         // {Source0[95:64],Source1[95:64],Source0[31:0]}; 
988
        `SETZ:                          ResultB  = iChannel_By;  // {Source0[95:64],Source0[63:32],Source1[95:64]}; 
989
 
990
        `SWIZZLE3D:             ResultB  = wSwizzleOutputY;
991
 
992
        `INC,`INCX,`INCY,`INCZ:                                 ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]}; // & 32'h7FFFFFFF;
993
        `DEC:                                   ResultB = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]}; // & 32'h7FFFFFFF;
994
        `MOD:                                   ResultB =  wModulus2N_ResultB;
995
        `FRAC:                          ResultB = iChannel_Ay & (`WIDTH'hFFFFFFFF >> (`WIDTH - `SCALE));
996
        `MULP:                          ResultB = iChannel_Ay;
997
        `NEG:                                   ResultB = ~iChannel_Ay + 1'b1;
998
        `XCHANGEX:                      ResultB = iChannel_Ay;
999
 
1000
        default:
1001
        begin
1002
        `ifdef DEBUG
1003
        //$display("%dns ALU: Error Unknown Operation: %d",$time,iOperation);
1004
        //$stop();
1005
        `endif
1006
        ResultB =  32'b0;
1007
        end
1008
        endcase
1009
end
1010
//------------------------------------------------------
1011
//****Mux for RC***
1012
always @ ( * )
1013
begin
1014
        case ( iOperation )
1015
        `RETURN:                                ResultC = iChannel_Ax;
1016
        `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;
1017
        `SUB:                                   ResultC = (wAddSubC_Result[63] == 1'b1) ? {1'b1,wAddSubC_Result[30:0]} : {1'b0,wAddSubC_Result[30:0]}; //wAddSubC_Result[31:0];
1018
        `CROSS:                         ResultC = (wAddSubC_Result[63] == 1'b1) ? {1'b1,wAddSubC_Result[30:0]} : {1'b0,wAddSubC_Result[30:0]};//wAddSubC_Result[31:0];
1019
        `DIV:                                   ResultC = wDivisionC_Result;
1020
        `MUL:                                   ResultC = wMultiplicationC_Result[31:0];
1021
        `IMUL:            ResultC = wMultiplicationC_Result[31:0];
1022
        `DOT:                                   ResultC = (wAddSubB_Result[63] == 1'b1) ? {1'b1,wAddSubB_Result[30:0]} : {1'b0,wAddSubB_Result[30:0]};//wAddSubB_Result[31:0];
1023
        `MAG:                                   ResultC = wSquareRoot_Result;
1024
        `ZERO:                          ResultC = 32'b0;
1025
        `COPY:                          ResultC = iChannel_Az;
1026
        `TMREAD:          ResultC = iTMEMReadData[31:0];
1027
        `LEA:             ResultC = {16'b0,iCurrentIP};
1028
 
1029
        `SWIZZLE3D: ResultC  = wSwizzleOutputZ;
1030
 
1031
        //Set Operations
1032
        `UNSCALE:                       ResultC  = iChannel_Az >> `SCALE;
1033
        `SETX,`RET:             ResultC  = iChannel_Bz;         // {Source1[95:64],Source0[63:32],Source0[31:0]}; 
1034
        `SETY:                          ResultC  = iChannel_Bz;         // {Source0[95:64],Source1[95:64],Source0[31:0]}; 
1035
        `SETZ:                          ResultC  = iChannel_Ax;  // {Source0[95:64],Source0[63:32],Source1[95:64]}; 
1036
 
1037
        `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;
1038
        `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;
1039
        `MOD:                                   ResultC =  wModulus2N_ResultC;
1040
        `FRAC:                          ResultC = iChannel_Az & (`WIDTH'hFFFFFFFF >> (`WIDTH - `SCALE));
1041
        `MULP:                          ResultC = wMultiplicationA_Result[31:0];
1042
        `NEG:                                   ResultC = ~iChannel_Az + 1'b1;
1043
        `XCHANGEX:                      ResultC = iChannel_Az;
1044
        default:
1045
        begin
1046
        `ifdef DEBUG
1047
        //$display("%dns ALU: Error Unknown Operation: %d",$time,iOperation);
1048
        //$stop();
1049
        `endif
1050
        ResultC =  32'b0;
1051
        end
1052
        endcase
1053
end
1054
//------------------------------------------------------------------------
1055
 
1056
 
1057
always @ ( * )
1058
begin
1059
        case (iOperation)
1060
        `JMP,`CALL,`RET: oBranchTaken = OutputReady;
1061
        `JGX:   oBranchTaken = wArithmeticComparison_Result;
1062
        `JGY:   oBranchTaken = wArithmeticComparison_Result;
1063
        `JGZ:   oBranchTaken = wArithmeticComparison_Result;
1064
 
1065
        `JLX:   oBranchTaken = wArithmeticComparison_Result;
1066
        `JLY:   oBranchTaken = wArithmeticComparison_Result;
1067
        `JLZ:   oBranchTaken = wArithmeticComparison_Result;
1068
 
1069
        `JEQX:  oBranchTaken = wArithmeticComparison_Result;
1070
        `JEQY:  oBranchTaken = wArithmeticComparison_Result;
1071
        `JEQZ:  oBranchTaken = wArithmeticComparison_Result;
1072
 
1073
        `JNEX:  oBranchTaken = wArithmeticComparison_Result;
1074
        `JNEY:  oBranchTaken = wArithmeticComparison_Result;
1075
        `JNEZ:  oBranchTaken = wArithmeticComparison_Result;
1076
 
1077
        `JGEX:  oBranchTaken = wArithmeticComparison_Result;
1078
        `JGEY:  oBranchTaken = wArithmeticComparison_Result;
1079
        `JGEZ:  oBranchTaken = wArithmeticComparison_Result;
1080
 
1081
        `JLEX:  oBranchTaken = wArithmeticComparison_Result;
1082
        `JLEY:  oBranchTaken = wArithmeticComparison_Result;
1083
        `JLEZ:  oBranchTaken = wArithmeticComparison_Result;
1084
 
1085
        default: oBranchTaken = 0;
1086
        endcase
1087
 
1088
end
1089
 
1090
always @ ( * )
1091
begin
1092
        case (iOperation)
1093
 
1094
                `JMP,`CALL,`RET,`JGX,`JGY,`JGZ,`JLX,`JLY,`JLZ,`JEQX,`JEQY,`JEQZ,
1095
                `JNEX,`JNEY,`JNEZ,`JGEX,`JGEY,`JGEZ: oBranchNotTaken = !oBranchTaken && OutputReady;
1096
                `JLEX: oBranchNotTaken = !oBranchTaken && OutputReady;
1097
                `JLEY: oBranchNotTaken = !oBranchTaken && OutputReady;
1098
                `JLEZ: oBranchNotTaken = !oBranchTaken && OutputReady;
1099
        default:
1100
                oBranchNotTaken = 0;
1101
        endcase
1102
end
1103
//------------------------------------------------------------------------
1104
//Output ready logic Stuff for Division...
1105
//Some FFT will hopefully do the trick
1106
 
1107
wire wDivisionOutputReadyA,wDivisionOutputReadyB,wDivisionOutputReadyC;
1108
wire wDivisionOutputReady;
1109
 
1110
 
1111
assign wAddSubAOutputReady = wAddSubA_OutputReady;
1112
assign wAddSubBOutputReady = wAddSubB_OutputReady;
1113
assign wAddSubCOutputReady = wAddSubC_OutputReady;
1114
 
1115
 
1116
FFT1 FFT_DivisionA
1117
  (
1118
   .D(1'b1),
1119
   .Clock( wDivisionA_OutputReady ),
1120
   .Reset( iInputReady ),
1121
   .Q( wDivisionOutputReadyA )
1122
 );
1123
 
1124
FFT1 FFT_DivisionB
1125
  (
1126
   .D(1'b1),
1127
   .Clock( wDivisionB_OutputReady ),
1128
   .Reset( iInputReady ),
1129
   .Q( wDivisionOutputReadyB )
1130
 );
1131
 
1132
 FFT1 FFT_DivisionC
1133
  (
1134
   .D(1'b1),
1135
   .Clock( wDivisionC_OutputReady ),
1136
   .Reset( iInputReady ),
1137
   .Q( wDivisionOutputReadyC )
1138
 );
1139
 
1140
 assign wDivisionOutputReady =
1141
 ( wDivisionOutputReadyA && wDivisionOutputReadyB && wDivisionOutputReadyC );
1142
 
1143
assign wMultiplicationOutputReadyA = wMultiplicationA_OutputReady;
1144
assign wMultiplicationOutputReadyB = wMultiplicationB_OutputReady;
1145
assign wMultiplicationOutputReadyC = wMultiplicationC_OutputReady;
1146
assign wMultiplicationOutputReadyD = wMultiplicationD_OutputReady;
1147
 
1148
 assign wMultiplicationOutputReady =
1149
 ( wMultiplicationOutputReadyA && wMultiplicationOutputReadyB && wMultiplicationOutputReadyC );
1150
 
1151
 wire wSquareRootOutputReady;
1152
 FFT1 FFT_Sqrt
1153
  (
1154
   .D(1'b1),
1155
   .Clock( wSquareRoot_OutputReady ),
1156
   .Reset( iInputReady ),
1157
   .Q( wSquareRootOutputReady )
1158
 );
1159
 
1160
 
1161
//------------------------------------------------------------------------
1162
wire wOutputDelay1Cycle,wOutputDelay2Cycle,wOutputDelay3Cycle;
1163
 
1164
 
1165
 
1166
FFD_POSEDGE_SYNCRONOUS_RESET # (1) FFOutputReadyDelay2
1167
(
1168
        .Clock( Clock ),
1169
        .Reset( Reset ),
1170
        .Enable(1'b1),
1171
        .D( iInputReady ),
1172
        .Q( wOutputDelay1Cycle )
1173
);
1174
 
1175
FFD_POSEDGE_SYNCRONOUS_RESET # (1) FFOutputReadyDelay22
1176
(
1177
        .Clock( Clock  ),
1178
        .Reset( Reset ),
1179
        .Enable(1'b1),
1180
        .D( wOutputDelay1Cycle ),
1181
        .Q( wOutputDelay2Cycle )
1182
);
1183
wire wIsOMWRITE;
1184
assign wIsOMWRITE = (wOperation == `OMWRITE) ? 1'b1: 1'b0;
1185
 
1186
FFD_POSEDGE_SYNCRONOUS_RESET # (1) FFOutputReadyDelay222
1187
(
1188
        .Clock( Clock ),
1189
        .Reset( Reset ),
1190
        .Enable(wIsOMWRITE),
1191
        .D( wOutputDelay2Cycle ),
1192
        .Q( wOutputDelay3Cycle )
1193
);
1194
 
1195
FFD_POSEDGE_SYNCRONOUS_RESET # ( `INSTRUCTION_OP_LENGTH ) SourceZ2
1196
(
1197
        .Clock( Clock ),
1198
        .Reset( Reset ),
1199
        .Enable( iInputReady ),
1200
        .D( iOperation ),
1201
        .Q(wOperation)
1202
);
1203
 
1204
 
1205
//Mux for output ready signal
1206
always @ ( * )
1207
begin
1208
        case ( wOperation )
1209
        `UNSCALE:                       OutputReady  = wOutputDelay1Cycle;
1210
        `RETURN: OutputReady = wOutputDelay1Cycle;
1211
 
1212
        `NOP: OutputReady = wOutputDelay1Cycle;
1213
        `FRAC: OutputReady = wOutputDelay1Cycle;
1214
        `NEG: OutputReady = wOutputDelay1Cycle;
1215
        `OMWRITE: OutputReady = wOutputDelay3Cycle;
1216
        `TMREAD:  OutputReady = wTMReadOutputReady;  //One cycle after TMEM data availale asserted
1217
 
1218
        `ifdef DEBUG
1219
        //Debug Print behaves as a NOP in terms of ALU...
1220
        `DEBUG_PRINT: OutputReady = wOutputDelay1Cycle;
1221
        `endif
1222
 
1223
        `ADD,`INC,`INCX,`INCY,`INCZ:            OutputReady =   wAddSubAOutputReady &&
1224
                                                                        wAddSubBOutputReady &&
1225
                                                                        wAddSubCOutputReady;
1226
 
1227
        `SUB,`DEC:              OutputReady =   wAddSubAOutputReady &&
1228
                                                                        wAddSubBOutputReady &&
1229
                                                                        wAddSubCOutputReady;
1230
 
1231
        `DIV:           OutputReady =   wDivisionOutputReady;
1232
 
1233
 
1234
        `MUL,`IMUL:     OutputReady =   wMultiplicationOutputReady;
1235
        `MULP:  OutputReady =  wMultiplicationOutputReadyA;
1236
 
1237
        `DOT:           OutputReady = wAddSubBOutputReady;
1238
 
1239
        `CROSS: OutputReady =   wAddSubAOutputReady &&
1240
                                                                        wAddSubBOutputReady &&
1241
                                                                        wAddSubCOutputReady;
1242
 
1243
        `MAG:           OutputReady = wSquareRootOutputReady;
1244
 
1245
        `ZERO:  OutputReady = wOutputDelay1Cycle;
1246
 
1247
        `COPY:  OutputReady = wOutputDelay1Cycle;
1248
 
1249
        `SWIZZLE3D: OutputReady = wOutputDelay1Cycle;
1250
 
1251
        `SETX,`SETY,`SETZ,`JMP,`LEA,`CALL,`RET:         OutputReady = wOutputDelay1Cycle;
1252
 
1253
 
1254
 
1255
        `JGX,`JGY,`JGZ:                         OutputReady = ArithmeticComparison_OutputReady;
1256
        `JLX,`JLY,`JLZ:                         OutputReady = ArithmeticComparison_OutputReady;
1257
        `JEQX,`JEQY,`JEQZ:                      OutputReady = ArithmeticComparison_OutputReady;
1258
        `JNEX,`JNEY,`JNEZ:                      OutputReady = ArithmeticComparison_OutputReady;
1259
        `JGEX,`JGEY,`JGEZ:                      OutputReady = ArithmeticComparison_OutputReady;
1260
        `JLEX,`JLEY,`JLEZ:                      OutputReady = ArithmeticComparison_OutputReady;
1261
 
1262
        `MOD: OutputReady = wAddSubAOutputReady &&                              //TODO: wait 1 more cycle
1263
                                                                        wAddSubBOutputReady &&
1264
                                                                        wAddSubCOutputReady;
1265
 
1266
        `XCHANGEX: OutputReady = wOutputDelay1Cycle;
1267
 
1268
 
1269
        default:
1270
        begin
1271
                OutputReady =  32'b0;
1272
                //`ifdef DEBUG
1273
                //$display("*** ALU ERROR: iOperation = %d ***",iOperation);
1274
                //`endif
1275
        end
1276
 
1277
        endcase
1278
end
1279
 
1280
endmodule
1281
//------------------------------------------------------------------------

powered by: WebSVN 2.1.0

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