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

Subversion Repositories Aquarius

[/] [Aquarius/] [trunk/] [verilog/] [mult.v] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 thorn_aitc
//======================================================
2
// Aquarius Project
3
//    SuperH-2 ISA Compatible RISC CPU
4
//------------------------------------------------------
5
// Module      : Multiplier Unit
6
//------------------------------------------------------
7
// File        : mult.v
8
// Library     : none
9
// Description : Multiplier Unit in CPU.
10
// Simulator   : Icarus Verilog (Cygwin)
11
// Synthesizer : Xilinx XST (Windows XP)
12
// Author      : Thorn Aitch
13
//------------------------------------------------------
14
// Revision Number : 1
15
// Date of Change  : 19th August 2002
16
// Creator         : Thorn Aitch
17
// Description     : Initial Design                               
18
//------------------------------------------------------
19
// Revision Number : 2
20
// Date of Change  : 30th April 2003
21
// Modifier        : Thorn Aitch
22
// Description     : Release Version 1.0
23
//======================================================
24
// Copyright (C) 2002-2003, Thorn Aitch
25
//
26
// Designs can be altered while keeping list of
27
// modifications "the same as in GNU" No money can
28
// be earned by selling the designs themselves, but
29
// anyone can get money by selling the implementation
30
// of the design, such as ICs based on some cores, 
31
// boards based on some schematics or Layouts, and
32
// even GUI interfaces to text mode drivers.
33
// "The same as GPL SW" Any update to the design
34
// should be documented and returned to the design. 
35
// Any derivative work based on the IP should be free
36
// under OpenIP License. Derivative work means any
37
// update, change or improvement on the design. 
38
// Any work based on the design can be either made
39
// free under OpenIP license or protected by any other
40
// license. Work based on the design means any work uses
41
// the OpenIP Licensed core as a building black without
42
// changing anything on it with any other blocks to
43
// produce larger design.  There is NO WARRANTY on the
44
// functionality or performance of the design on the
45
// real hardware implementation.
46
// On the other hand, the SuperH-2 ISA (Instruction Set
47
// Architecture) executed by Aquarius is rigidly
48
// the property of Renesas Corp. Then you have all 
49
// responsibility to judge if there are not any 
50
// infringements to Renesas's rights regarding your 
51
// Aquarius adoption into your design. 
52
// By adopting Aquarius, the user assumes all 
53
// responsibility for its use.
54
// This project may cause any damages around you, for 
55
// example, loss of properties, data, money, profits,
56
// life, or business etc. By adopting this source, 
57
// the user assumes all responsibility for its use.
58
//======================================================
59
 
60
`include "timescale.v"
61
`include "defines.v"
62
 
63
//****************************
64
// Multiply Unit Specification
65
//****************************
66
// This unit handles following multiplier related operations. 
67
//   DMULS.L
68
//   DMULU.L
69
//   MAC.L
70
//   MAC.W
71
//   MUL.L
72
//   MULS.W
73
//   MULU.W
74
// Physical multiplier size is 32bit*16bit->48bit.
75
// Then, 32x32 operations are executed in 2 cycles.
76
 
77
//*************************************************
78
// Module Definition
79
//*************************************************
80
module mult(
81
    // system signal
82
    CLK, RST,
83
    // command
84
    SLOT, MULCOM1, MULCOM2, MAC_S, WRMACH, WRMACL,
85
    // input data
86
    MACIN1, MACIN2,
87
    // output data
88
    MACH, MACL,
89
    // busy signal
90
    MAC_BUSY
91
    );
92
 
93
//-------------------
94
// Module I/O Signals
95
//-------------------
96
    input  CLK;           // clock
97
    input  RST;           // reset
98
    input  SLOT;          // cpu pipe slot
99
    input  MULCOM1;       // M1 latch command
100
    input  [7:0] MULCOM2; // M2 latch and mult engage command
101
                          // NOP      0 0000000 00
102
                          // DMULS.L  1 0111101 BD
103
                          // DMULU.L  1 0110101 B5
104
                          // MAC.L    1 0001111 8F
105
                          // MAC.W    1 1001111 CF
106
                          // MUL.L    1 0000111 87
107
                          // MULS.W   1 0101111 AF
108
                          // MULU.W   1 0101110 AE
109
    input  MAC_S;         // S-bit in SR
110
    input  WRMACH, WRMACL;// write MACH and MACL directly from data path
111
    input  [31:0] MACIN1; // input data 1
112
    input  [31:0] MACIN2; // input data 2
113
    output [31:0] MACH;   // output MACH
114
    output [31:0] MACL;   // output MACL
115
    output MAC_BUSY;      // busy signal (negate at final operation state)
116
 
117
//-----------------
118
// Internal Signals
119
//-----------------
120
    reg  [31:0] M1;   // input data1 latch
121
    reg  [31:0] M2;   // input data2 latch
122
    reg  [31:0] MB;   // input data 2 buffer to implement continuous MAC.L instruction
123
    reg  SELA;        // 0:A=M1, 1:A=MB
124
    reg  [31:0] A;    // A=M1 or A=MB (selected by SELA)
125
    reg  [31:0] B;    // B=M2
126
    reg  SHIFT;       // use lower(0)/upper(1) 16bit of B; use unshifted(0)/16bit-shifted(1) PM
127
    reg  SIGN;        // 0:unsigned, 1:signed (multipier operation)
128
    reg  SIZE;        // if 32*32 then 1, 16*16 then 0
129
    reg  [30:0] AH;   // lower 31bit of A
130
    reg  [15:0] BH;   // upper 16bit of B(0) or lower 16bit of B(1)
131
    reg  [46:0] ABH;  // output of Multiplier(31x16) (=A * BH) (calculated as unsigned)
132
    reg  [32:0] ABH2; // modified ABH
133
    reg  [31:0] P2;   // if signed32*32, ~SHIFT&A[31]&B[31:0], if signed16*16, ~SHIFT&A[31]&{B[15:0]:16'h0000}
134
    reg  [31:0] P3;   // if signed32*32, ~SHIFT&B[31]&A[31:0], if signed16*16, ~SHIFT&B[15]&A[31:0]
135
    reg  [31:0] P23;  // P2 + P3
136
    reg  [32:0] P23S; // if SIGN, ~P23, else P23
137
    reg  [47:0] PM;   // multiplier output (partial result) with sign
138
    reg  [63:0] C;    // one of the adder inputs
139
    reg  ZH;          // if final result is 16bit, adder input from MACH is forced to zero 
140
    reg  [1:0] ADD;   // 00:ADD, 10:ADDS48, 11:ADDS32 (adder functions regarding saturation)
141
    reg  [63:0] ADDRESULT;  // pure adder result
142
    reg  [63:0] ADDRESULT2; // saturated result
143
    reg  SAT;         // whether saturation has occured or not (to or 0001 to MACH)
144
    reg  LATMACH;     // latch signal of MACH by state machine
145
    reg  LATMACL;     // latch signal of MACL by state machine
146
    reg  [31:0] MACH; // actual MACH
147
    reg  [31:0] MACL; // actual MACL
148
    reg  MAC_BUSY;    // busy signal (negate at final operation state)
149
    reg  [3:0] STATE;     // control state
150
    reg  [3:0] NEXTSTATE; // next state
151
    reg  MAC_DISPATCH;    // mult can accept next new operation
152
 
153
//-------------------
154
// Main State Machine
155
//-------------------
156
    // state machine F/F
157
    always @(posedge CLK or posedge RST)
158
    begin
159
        if (RST == 1'b1)
160
            STATE <= `NOP;
161
        else if (MAC_DISPATCH & SLOT)
162
            begin
163
                case(MULCOM2)
164
                    8'h00   : STATE <= `NOP;
165
                    8'hBD   : STATE <= `DMULSL;
166
                    8'hB5   : STATE <= `DMULUL;
167
                    8'h8F   : if (MAC_S == 1'b0)
168
                                  STATE <= `MACL0;
169
                              else
170
                                  STATE <= `MACLS;
171
                    8'hCF   : if (MAC_S == 1'b0)
172
                                  STATE <= `MACW;
173
                              else
174
                                  STATE <= `MACWS;
175
                    8'h87   : STATE <= `MULL;
176
                    8'hAF   : STATE <= `MULSW;
177
                    8'hAE   : STATE <= `MULUW;
178
                    default : STATE <= `NOP;
179
                endcase
180
            end
181
        else if (MAC_DISPATCH & ~SLOT)
182
            STATE <= `NOP;
183
        else if (~MAC_DISPATCH)
184
            STATE <= NEXTSTATE;
185
    end
186
 
187
//------------------
188
// State Transistion
189
//------------------
190
// NOP     : A=M1, BH=LowerB, unsign MULT, C=PM,                > NOP
191
//
192
// DMULSL  : A=M1, BH=LowerB, signed MULT, C=PM,       MAC<=ADD > DMULSL2
193
// DMULSL2 : A=M1, BH=upperB, signed MULT, C=(PM<<16), MAC<=ADD > NOP
194
//
195
// DMULUL  : A=M1, BH=LowerB, unsign MULT, C=PM,       MAC<=ADD > DMULUL2
196
// DMULUL2 : A=M1, BH=upperB, unsign MULT, C=(PM<<16), MAC<=ADD > NOP
197
//
198
// MACL0   : A=MB, BH=LowerB, signed MULT, C=PM,       MAC<=ADD > MACL2
199
// MACL2   : A=MB, BH=upperB, signed MULT, C=(PM<<16), MAC<=ADD > NOP
200
 
201
// MACLS   : A=MB, BH=LowerB, signed MULT, C=PM,       MAC<=ADDS48 > MACL2
202
// MACLS2  : A=MB, BH=upperB, signed MULT, C=(PM<<16), MAC<=ADDS48 > NOP
203
 
204
// MACW    : A=M1, BH=LowerB, signed MULT, C=PM,       MAC<=ADD > NOP
205
 
206
// MACWS   : A=M1, BH=LowerB, signed MULT, C=PM,       MACL<=ADDS32 > NOP
207
//                                                               if saturate, MACH|=0001
208
 
209
// MULL    : A=M1, BH=LowerB, signed MULT, C=PM,       MACL<=ADD > MULL2
210
// MULL2   : A=M1, BH=upperB, signed MULT, C=(PM<<16), MACL<=ADD > NOP
211
 
212
// MULSW   : A=M1, BH=LowerB, signed MULT, C=PM,       MACL<=ADD > NOP
213
 
214
// MULUW   : A=M1, BH=LowerB, unsign MULT, C=PM,       MACL<=ADD > NOP
215
 
216
    always @(STATE or SLOT or MULCOM2 or MAC_S)
217
    begin
218
        case (STATE)
219
            `NOP    :begin
220
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_000_00_000;
221
                      MAC_BUSY <= 1'b0;
222
                      MAC_DISPATCH <= 1'b1;
223
                      NEXTSTATE <= `NOP;
224
                     end
225
            `DMULSL :begin
226
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_011_00_110;
227
                      MAC_BUSY <= 1'b1;
228
                      MAC_DISPATCH <= 1'b0;
229
                      NEXTSTATE <= `DMULSL2;
230
                     end
231
            `DMULSL2:begin
232
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_111_00_110;
233
                      MAC_BUSY <= 1'b0;
234
                      MAC_DISPATCH <= 1'b1;
235
                      NEXTSTATE <= `NOP;
236
                     end
237
            `DMULUL :begin
238
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_001_00_110;
239
                      MAC_BUSY <= 1'b1;
240
                      MAC_DISPATCH <= 1'b0;
241
                      NEXTSTATE <= `DMULUL2;
242
                     end
243
            `DMULUL2:begin
244
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_101_00_110;
245
                      MAC_BUSY <= 1'b0;
246
                      MAC_DISPATCH <= 1'b1;
247
                      NEXTSTATE <= `NOP;
248
                     end
249
            `MACL0  :begin
250
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_011_00_110;
251
                      MAC_BUSY <= 1'b1;
252
                      MAC_DISPATCH <= 1'b0;
253
                      NEXTSTATE <= `MACL2;
254
                     end
255
            `MACL2  :begin
256
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_111_00_110;
257
                      MAC_BUSY <= 1'b0;
258
                      MAC_DISPATCH <= 1'b1;
259
                      NEXTSTATE <= `NOP;
260
                     end
261
            `MACLS  :begin
262
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_011_10_110;
263
                      MAC_BUSY <= 1'b1;
264
                      MAC_DISPATCH <= 1'b0;
265
                      NEXTSTATE <= `MACLS2;
266
                     end
267
            `MACLS2 :begin
268
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b1_111_10_110;
269
                      MAC_BUSY <= 1'b0;
270
                      MAC_DISPATCH <= 1'b1;
271
                      NEXTSTATE <= `NOP;
272
                     end
273
            `MACW   :begin
274
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_010_00_110;
275
                      MAC_BUSY <= 1'b1;
276
                      MAC_DISPATCH <= 1'b1;
277
                      NEXTSTATE <= `NOP;
278
                     end
279
            `MACWS  :begin
280
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_010_11_011;
281
                      MAC_BUSY <= 1'b0;
282
                      MAC_DISPATCH <= 1'b1;
283
                      NEXTSTATE <= `NOP;
284
                     end
285
            `MULL   :begin
286
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_011_00_011;
287
                      MAC_BUSY <= 1'b1;
288
                      MAC_DISPATCH <= 1'b0;
289
                      NEXTSTATE <= `MULL2;
290
                     end
291
            `MULL2  :begin
292
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_111_00_011;
293
                      MAC_BUSY <= 1'b0;
294
                      MAC_DISPATCH <= 1'b1;
295
                      NEXTSTATE <= `NOP;
296
                     end
297
            `MULSW  :begin
298
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_010_00_011;
299
                      MAC_BUSY <= 1'b0;
300
                      MAC_DISPATCH <= 1'b1;
301
                      NEXTSTATE <= `NOP;
302
                     end
303
            `MULUW  :begin
304
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_000_00_011;
305
                      MAC_BUSY <= 1'b0;
306
                      MAC_DISPATCH <= 1'b1;
307
                      NEXTSTATE <= `NOP;
308
                     end
309
            default : begin
310
                      {SELA,SHIFT,SIGN,SIZE,ADD,LATMACH,LATMACL,ZH}<=9'b0_000_00_000;
311
                      MAC_BUSY <= 1'b0;
312
                      MAC_DISPATCH <= 1'b1;
313
                      NEXTSTATE <= `NOP;
314
                     end
315
        endcase
316
    end
317
 
318
//-----------------------------------------
319
// Data Path
320
//-----------------------------------------
321
 
322
//---
323
// M1
324
//---
325
    always @(posedge CLK)
326
    begin
327
        if (SLOT & MULCOM1)
328
           begin
329
            M1 <= MACIN1;
330
        end
331
    end
332
 
333
//-------
334
// M2
335
// B (=M2)
336
//-------
337
    always @(posedge CLK)
338
    begin
339
        if (SLOT & MULCOM2[7])
340
           begin
341
            M2 <= MACIN2;
342
        end
343
    end
344
 
345
    always @(M2) B <= M2;
346
 
347
//---
348
// MB
349
//---
350
// if SLOT and MULCOM2=MACL, do latch M1.
351
    always @(posedge CLK)
352
    begin
353
        if (SLOT & MULCOM2[7] & (MULCOM2[5:0] == 6'b001111))
354
           begin
355
            MB <= M1;
356
        end
357
    end
358
 
359
//--------
360
//Select A
361
//--------
362
    always @(SELA or M1 or MB)
363
    begin
364
        if (SELA)
365
            A <= MB;
366
         else
367
            A <= M1;
368
    end
369
 
370
//---------------------------------------
371
// lower 31bit of A     (input to Multiplier)
372
//---------------------------------------
373
    always @(A or SIZE)
374
    begin
375
           if (SIZE == 1'b0)
376
               AH <= {16'h0000,A[14:0]};
377
           else
378
               AH <= A[30:0];
379
    end
380
 
381
//---------------------------------------
382
// upper/lower of B (input to Multiplier)
383
//---------------------------------------
384
    always @(B or SHIFT or SIZE)
385
    begin
386
        if (SIZE == 1'b0)
387
                  BH <= {1'b0,B[14:0]};
388
        else if (SHIFT == 1'b0)
389
            BH <= B[15:0];
390
        else
391
            BH <= {1'b0,B[30:16]};
392
    end
393
 
394
//-----------
395
// Multiplier
396
//----------
397
    always @(AH or BH)
398
    begin
399
        ABH[46:0] <= AH[30:0] * BH[15:0]; // 31bit * 16bit -> 47bit
400
    end
401
 
402
//---
403
// PM
404
//---
405
    always @(SHIFT or SIZE or A or B)
406
    begin
407
        if (SHIFT)
408
               begin
409
                         P2 <= {1'b0, (A[31])? B[30:0]:31'h00000000};
410
                         P3 <= {1'b0, (B[31])? A[30:0]:31'h00000000};
411
                  end
412
           else if(~SIZE)
413
               begin
414
                         P2 <= {17'h00000, (A[15])? B[14:0]:15'h0000};
415
                         P3 <= {17'h00000, (B[15])? A[14:0]:15'h0000};
416
                  end
417
           else
418
               begin
419
                         P2 <= 32'h00000000;
420
                         P3 <= 32'h00000000;
421
                  end
422
    end
423
 
424
    always @(P2 or P3)
425
    begin
426
        P23 <= P2 + P3;
427
    end
428
 
429
    always @(ABH or SHIFT or SIZE or A or B)
430
    begin
431
        if (SIZE == 1'b0)
432
               ABH2 <= {17'h00000,(A[15] & B[15]),ABH[29:15]};
433
        else if (SHIFT == 1'b0)
434
            ABH2 <= {1'b0, ABH[46:15]};
435
           else
436
               ABH2 <= {1'b0,(A[31] & B[31]),ABH[45:15]};
437
    end
438
 
439
    always @(P23 or SIGN)
440
    begin
441
        if (SIGN == 1'b0)
442
               P23S <= {1'b0, P23};
443
           else
444
               P23S <= {1'b1,~P23};
445
    end
446
 
447
    always @(P23S or ABH or ABH2 or SIGN)
448
    begin
449
           PM[47:15] <= ABH2[32:0] + P23S + SIGN;
450
           PM[14: 0] <= ABH[14: 0];
451
    end
452
 
453
//---------
454
// Select C
455
//---------
456
    always @(PM or SHIFT or SIZE)
457
    begin
458
        if (SHIFT == 1'b0)
459
            if (~SIZE & PM[47])
460
                C <= {16'hffff, PM};
461
            else
462
                C <= {16'h0000, PM};
463
        else
464
            C <= {PM, 16'h0000};
465
    end
466
 
467
//-------------------------------------
468
// 64bit ADDER with Satulating function
469
//-------------------------------------
470
//
471
// Essential of Saturate Operation [ MAC[64] + C[64] ]
472
//
473
//   +S     |             Left plane shows value of MAC.
474
//     \    |             "+S" is + side saturate value (ex.00007FFF).
475
//      \  <P>            "-S" is - side saturate value (ex.FFFF8000).
476
//  <P'> \  |             Addition of plus C rotates MAC value counterclockwise.
477
//        \ |             Addition of minus C rotates MAC value clockwise.                                                     
478
// 7F..    \|     00..
479
// -------------------    Region<M'> : MAC=80000000~FFFF7FFF
480
// 80..    /|     FF..    Region<M > : MAC=FFFF8000~FFFFFFFF
481
//        / |             Region<P > : MAC=00000000~00007FFF
482
//  <M'> /  |             Region<P'> : MAC=00008000~7FFFFFFF
483
//      /  <M>  
484
//     /    |             Note that initial MAC value may be in any region.
485
//   -S     |             And value C may also be 00000000~FFFFFFFF.
486
//                                            
487
// ===========================================
488
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
489
// ===========================================
490
//     P            +          P     OK      
491
//     P            +          P'    00007FFF
492
//     P            +          M'    00007FFF
493
//     P            +          M     00007FFF 
494
// -------------------------------------------
495
//     P'           +          P     00007FFF Impossible      
496
//     P'           +          P'    00007FFF
497
//     P'           +          M'    00007FFF
498
//     P'           +          M     00007FFF 
499
// -------------------------------------------
500
//     M'           +          P     OK      
501
//     M'           +          P'    00007FFF Imposible
502
//     M'           +          M'    FFFF8000
503
//     M'           +          M     OK       
504
// -------------------------------------------
505
//     M            +          P     OK      
506
//     M            +          P'    00007FFF
507
//     M            +          M'    00007FFF Impossible
508
//     M            +          M     OK       
509
// ===========================================
510
//     P            -          P     OK      
511
//     P            -          P'    FFFF8000 Impossible
512
//     P            -          M'    FFFF8000
513
//     P            -          M     OK 
514
// -------------------------------------------
515
//     P'           -          P     OK      
516
//     P'           -          P'    00007FFF
517
//     P'           -          M'    FFFF8000 Impossible
518
//     P'           -          M     OK 
519
// -------------------------------------------
520
//     M'           -          P     FFFF8000      
521
//     M'           -          P'    FFFF8000
522
//     M'           -          M'    FFFF8000
523
//     M'           -          M     FFFF8000 Impossible       
524
// -------------------------------------------
525
//     M            -          P     FFFF8000      
526
//     M            -          P'    FFFF8000
527
//     M            -          M'    FFFF8000
528
//     M            -          M     OK       
529
// ===========================================
530
 
531
// Again, Compactly...                               
532
// ===========================================
533
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
534
// ===========================================
535
//     P /M        +/-        P /M  OK      
536
//     P /M        +/-        P'/M' 00007FFF/FFFF8000
537
//     P /M        +/-        M'/P' 00007FFF/FFFF8000
538
//     P /M        +/-        M /P  00007FFF/FFFF8000
539
// -------------------------------------------
540
//     P'/M'       +/-        P /M  Impossible = Don't care      
541
//     P'/M'       +/-        P'/M' 00007FFF/FFFF8000
542
//     P'/M'       +/-        M'/P' 00007FFF/FFFF8000
543
//     P'/M'       +/-        M /P  00007FFF/FFFF8000
544
// -------------------------------------------
545
//     M'/P'       +/-        P /M  OK      
546
//     M'/P'       +/-        P'/M' Impossible = Don't care
547
//     M'/P'       +/-        M'/P' FFFF8000/00007FFF <--caution !
548
//     M'/P'       +/-        M /P  OK       
549
// -------------------------------------------
550
//     M /P        +/-        P /M  OK      
551
//     M /P        +/-        P'/M' 00007FFF/FFFF8000
552
//     M /P        +/-        M'/P' Impossible = Don't care
553
//     M /P        +/-        M /P  OK       
554
// ===========================================
555
 
556
// Again, Much Compactly...                                  
557
// ===========================================
558
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
559
// ===========================================
560
//     P /M        +/-        P /M  OK      
561
//     P /M        +/-        P'/M' 00007FFF/FFFF8000
562
//     P /M        +/-        - /+  00007FFF/FFFF8000
563
// -------------------------------------------
564
//     P'/M'       +/-        P /M  Impossible = Don't care      
565
//     P'/M'       +/-        P'/M' 00007FFF/FFFF8000
566
//     P'/M'       +/-        - /+  00007FFF/FFFF8000
567
// -------------------------------------------
568
//     M'/P'       +/-        P /M  OK 
569
//     - /+        +/-        M'/P' FFFF8000/00007FFF <--caution !
570
//     M'/P'       +/-        M /P  OK       
571
// -------------------------------------------
572
//     M /P        +/-        P /M  OK      
573
//     - /+        +/-        P'/M' 00007FFF/FFFF8000
574
//     M /P        +/-        M /P  OK       
575
// ===========================================
576
 
577
// Again, Much Compactly...                                  
578
// ===========================================
579
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
580
// ===========================================
581
//     + /-        +/-        P /M  OK      
582
//     + /-        +/-        P'/M' 00007FFF/FFFF8000
583
//     + /-        +/-        - /+  00007FFF/FFFF8000
584
// -------------------------------------------
585
//     - /+        +/-        P /M  OK 
586
//     - /+        +/-        M'/P' FFFF8000/00007FFF <--caution !
587
//     - /+        +/-        M /P  OK       
588
//     - /+        +/-        P'/M' 00007FFF/FFFF8000
589
// ===========================================
590
 
591
// Again, Much Compactly...                                  
592
// ===========================================
593
// Initial_MAC  Rotation(C)  MAC+C  Result_MAC
594
// ===========================================
595
//     * /*        +/-        P /M  OK      
596
//     * /*        +/-        P'/M' 00007FFF/FFFF8000
597
//     + /-        +/-        - /+  00007FFF/FFFF8000
598
//     - /+        +/-        M'/P' FFFF8000/00007FFF <--caution !
599
//     - /+        +/-        M /P  OK       
600
// ===========================================
601
 
602
    always @(C or MACH or MACL or ZH)
603
    begin
604
        ADDRESULT <= C + {((ZH == 1'b0) ? MACH : 32'h00000000), MACL};
605
    end
606
 
607
    reg [1:0] RESULT_REGION48; //00:P, 01:P', 10:M, 11:M'
608
    reg       RESULT_REGION32; //0:P, 1:M, No P'/M' region in case of 32bit saturation.
609
    always @(ADDRESULT)
610
    begin
611
        RESULT_REGION48[1] <=  ADDRESULT[63];
612
        RESULT_REGION32    <=  ADDRESULT[31];
613
        if (ADDRESULT[63] == 1'b0)
614
          //RESULT_REGION48[0] <= (ADDRESULT[63:47] >= 17'h00001);
615
                  RESULT_REGION48[0] <= (ADDRESULT[63:47] != 17'h00000);
616
        else
617
          //RESULT_REGION48[0] <= (ADDRESULT[63:47] <= 17'hFFFFE);
618
                  RESULT_REGION48[0] <= (ADDRESULT[63:47] != 17'hFFFFF);
619
    end
620
 
621
    always @(ADDRESULT or C or MACH or MACL or ADD or RESULT_REGION48 or RESULT_REGION32)
622
    begin
623
        case(ADD)
624
            2'b00   : begin // ADD
625
                          ADDRESULT2 <= ADDRESULT;
626
                          SAT <= 1'b0;
627
                      end
628
            2'b10   : begin // ADDS48
629
                          if (~C[63]) // + rotation
630
                              case ({MACH[31], RESULT_REGION48})
631
                                  3'b000 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,P
632
                                  3'b001 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,P'
633
                                  3'b010 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,M
634
                                  3'b011 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,M'
635
                                  3'b100 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,P
636
                                  3'b101 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //-,P'
637
                                  3'b110 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,M
638
                                  3'b111 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,M'
639
                                  default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
640
                              endcase
641
                          else        // - rotation
642
                              case ({MACH[31], RESULT_REGION48})
643
                                  3'b000 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,P
644
                                  3'b001 : {ADDRESULT2,SAT} <= {64'h00007FFFFFFFFFFF,1'b1}; //+,P'
645
                                  3'b010 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,M
646
                                  3'b011 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //+,M'
647
                                  3'b100 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,P
648
                                  3'b101 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,P'
649
                                  3'b110 : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,M
650
                                  3'b111 : {ADDRESULT2,SAT} <= {64'hFFFF800000000000,1'b1}; //-,M'
651
                                  default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
652
                              endcase
653
                      end
654
            2'b11   : begin // ADDS32
655
                          if (~C[31]) // + rotation
656
                              case ({MACL[31], RESULT_REGION32})
657
                                  2'b00  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,P
658
                                  2'b01  : {ADDRESULT2,SAT} <= {64'h000000007FFFFFFF,1'b1}; //+,M
659
                                  2'b10  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,P
660
                                  2'b11  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,M
661
                                  default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
662
                              endcase
663
                          else        // - rotation
664
                              case ({MACL[31], RESULT_REGION32})
665
                                  2'b00  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,P
666
                                  2'b01  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //+,M
667
                                  2'b10  : {ADDRESULT2,SAT} <= {64'hFFFFFFFF80000000,1'b1}; //-,P
668
                                  2'b11  : {ADDRESULT2,SAT} <= {ADDRESULT,1'b0};            //-,M
669
                                  default: {ADDRESULT2,SAT} <= {64'hxxxxxxxxxxxxxxxx,1'bx};
670
                              endcase
671
                      end
672
            default : begin
673
                          ADDRESULT2 <= 64'hxxxxxxxxxxxxxxxx;
674
                          SAT <= 1'b0;
675
                      end
676
        endcase
677
    end
678
 
679
//-----
680
// MACH
681
//-----
682
// Clear condition of MACH: following command do not clear MACH
683
                          // MAC.L    1 0001111 8F
684
                          // MAC.W    1 1001111 CF
685
                          // MUL.L    1 0000111 87
686
                          // MULS.W   1 0101111 AF
687
                          // MULU.W   1 0101110 AE
688
// Should do saturating operation 
689
    always @(posedge CLK)
690
    begin
691
        if (SLOT & WRMACH)
692
            MACH <= MACIN1;
693
        else if (SLOT & MULCOM2[7]
694
                 & (MULCOM2[5:0] != 6'b001111)
695
                 & (MULCOM2[6:0] != 7'b0000111)
696
                 & (MULCOM2[6:0] != 7'b0101111)
697
                 & (MULCOM2[6:0] != 7'b0101110)
698
           )
699
            begin
700
                MACH <= 32'h00000000;
701
            end
702
        else if ((STATE == `MACWS) && (SAT == 1'b1))
703
            begin
704
                MACH <= MACH | 32'h00000001;
705
            end
706
        else if (LATMACH == 1'b1)
707
            begin
708
                MACH <= ADDRESULT2[63:32];
709
            end
710
    end
711
 
712
//-----
713
// MACL
714
//-----
715
// Clear condition of MACL: following command do not clear MACL
716
                          // MAC.L    1 0001111 8F
717
                          // MAC.W    1 1001111 CF
718
    always @(posedge CLK)
719
    begin
720
        if (SLOT & WRMACL)
721
            MACL <= MACIN2;
722
        else if (SLOT & MULCOM2[7] & (MULCOM2[5:0] != 6'b001111))
723
            begin
724
                MACL <= 32'h00000000;
725
            end
726
        else if (LATMACL == 1'b1)
727
            begin
728
                MACL <= ADDRESULT2[31:0];
729
            end
730
    end
731
 
732
//======================================================
733
  endmodule
734
//======================================================

powered by: WebSVN 2.1.0

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