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

Subversion Repositories theia_gpu

[/] [theia_gpu/] [tags/] [Beta_0.2/] [rtl/] [EXE/] [Module_VectorALU.v] - Blame information for rev 200

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

powered by: WebSVN 2.1.0

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