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 178

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

powered by: WebSVN 2.1.0

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