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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [tags/] [latest_stable/] [rtl/] [GPU/] [CORES/] [EXE/] [Module_VectorALU.v] - Blame information for rev 105

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

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

powered by: WebSVN 2.1.0

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