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

Subversion Repositories theia_gpu

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

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

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

powered by: WebSVN 2.1.0

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