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

Subversion Repositories scarm

[/] [scarm/] [trunk/] [src/] [scBooth.cpp] - Blame information for rev 10

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

Line No. Rev Author Line
1 5 zhong
///////////////////////////////////////////////////////////////////////////////
2
// This program is free software; you can redistribute it and/or
3
// modify it under the terms of the GNU General Public License
4
// as published by the Free Software Foundation; either version 2
5
// of the License, or (at your option) any later version.
6
//
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
// GNU General Public License for more details.
11
//
12
// You should have received a copy of the GNU General Public License
13
// along with this program; if not, write to the Free Software
14
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15
//////////////////////////////////////////////////////////////////////
16
 
17
///////////////////////////////////////////////////////////////////              
18
//          
19
//  Original Author: Allen Tao Zhong,
20
//  University of Electronic Science and Technology in China
21
//  email: zhong@opencores.org
22
//  info   This is a SystemC ARM model,I "stole" some codes from 
23
//       "swarm" , author Michael Dales (michael@dcs.gla.ac.uk)
24
// scBooth.cpp: implementation of the scBooth class.
25
//
26
//////////////////////////////////////////////////////////////////////
27
 
28
#include "scBooth.h"
29
 
30
//////////////////////////////////////////////////////////////////////
31
// Construction/Destruction
32
//////////////////////////////////////////////////////////////////////
33
 
34
 
35
 
36
scBooth::~scBooth()
37
{
38
 
39
}
40
///////////////////////////////////////////////////////////////////////////////
41
// carry_save_adder_32 - 32 bit carry save adder (well, what did you expect?).
42
//
43
void scBooth::carry_save_adder_32(uint32_t a, uint32_t b, uint32_t cin,
44
                         uint32_t *res, uint32_t *cout)
45
{
46
  uint32_t ps, t1, t2;
47
 
48
  ps = a ^ b;
49
  *res = ps ^ cin;
50
 
51
  t1 = b & ~ps;
52
  t2 = cin & ps;
53
  *cout = t1 | t2;
54
 
55
  /*fprintf(stdout, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
56
    a, b, cin, *res, *cout);
57
    fflush(stdout);*/
58
}
59
 
60
 
61
#define SHIFT_LEFT(_x,_y)  ((_y >= 32) ? 0 : _x << _y)
62
#define SHIFT_RIGHT(_x,_y) ((_y >= 32) ? 0 : _x >> _y)
63
#define SIGNED_SHIFT_RIGHT(_x,_y) ((_y >= 32) ? ((_x >> 31) * 0xFFFFFFFF) : ((int32_t)_x) >> _y)
64
 
65
///////////////////////////////////////////////////////////////////////////////
66
// booth_stage_one - Does a single round of booths multiply algorithm. Note
67
//                   this works on 64 bits.
68
//
69
void scBooth::booth_one_stage(uint32_t* part_sum_hi, uint32_t* part_sum_lo,
70
                     uint32_t* part_carry_hi, uint32_t* part_carry_lo,
71
                     uint32_t mult, uint32_t N, bool_t* carry,
72
                     uint32_t multiplier, bool_t bSign)
73
{
74
  uint32_t temp;
75
  uint32_t srt;
76
 
77
  temp = multiplier & 0x3;
78
  temp |= (*carry == 1) ? 4 : 0;
79
 
80
  switch (temp)
81
    {
82
    case 0:
83
      carry_save_adder_32(*part_sum_lo, 0, *part_carry_lo,
84
                          part_sum_lo, part_carry_lo);
85
      carry_save_adder_32(*part_sum_hi, 0, *part_carry_hi,
86
                          part_sum_hi, part_carry_hi);
87
      break;
88
    case 1:
89
      carry_save_adder_32(*part_sum_lo, SHIFT_LEFT(mult,(2 * N)),
90
                          *part_carry_lo,
91
                          part_sum_lo, part_carry_lo);
92
      srt = bSign == 0 ? SHIFT_RIGHT(mult,(32 - (2 * N))) :
93
        SIGNED_SHIFT_RIGHT(mult,(32 - (2 * N)));
94
      carry_save_adder_32(*part_sum_hi, srt, *part_carry_hi,
95
                          part_sum_hi, part_carry_hi);
96
      break;
97
    case 2:
98
      carry_save_adder_32(*part_sum_lo, ~(SHIFT_LEFT(mult,((2 * N) + 1))),
99
                          (*part_carry_lo) | 0x1 , part_sum_lo, part_carry_lo);
100
      srt = bSign == 0 ? SHIFT_RIGHT(mult,(32 - ((2 * N) + 1))) :
101
        SIGNED_SHIFT_RIGHT(mult,(32 - ((2 * N) + 1)));
102
      carry_save_adder_32(*part_sum_hi, ~(srt),
103
                          *part_carry_hi, part_sum_hi, part_carry_hi);
104
      break;
105
    case 3:
106
      carry_save_adder_32(*part_sum_lo, ~(SHIFT_LEFT(mult, (2 * N))),
107
                          (*part_carry_lo) | 0x1 , part_sum_lo, part_carry_lo);
108
      srt = bSign == 0 ? SHIFT_RIGHT(mult, (32 - (2 * N))) :
109
        SIGNED_SHIFT_RIGHT(mult, (32 - (2 * N)));
110
      carry_save_adder_32(*part_sum_hi, ~(srt),
111
                          *part_carry_hi, part_sum_hi, part_carry_hi);
112
      break;
113
    case 4:
114
      carry_save_adder_32(*part_sum_lo, SHIFT_LEFT(mult, (2 * N)),
115
                          *part_carry_lo,
116
                          part_sum_lo, part_carry_lo);
117
      srt = bSign == 0 ? SHIFT_RIGHT(mult, (32 - (2 * N))) :
118
        SIGNED_SHIFT_RIGHT(mult, (32 - (2 * N)));
119
      carry_save_adder_32(*part_sum_hi, srt,
120
                          *part_carry_hi,
121
                          part_sum_hi, part_carry_hi);
122
      break;
123
    case 5:
124
      carry_save_adder_32(*part_sum_lo, SHIFT_LEFT(mult, ((2 * N) + 1)),
125
                          *part_carry_lo,
126
                          part_sum_lo, part_carry_lo);
127
      srt = bSign == 0 ? SHIFT_RIGHT(mult, (32 - ((2 * N) + 1))) :
128
        SIGNED_SHIFT_RIGHT(mult, (32 - ((2 * N) + 1)));
129
      carry_save_adder_32(*part_sum_hi,
130
                          srt,
131
                          *part_carry_hi, part_sum_hi, part_carry_hi);
132
      break;
133
    case 6:
134
      carry_save_adder_32(*part_sum_lo, ~(SHIFT_LEFT(mult,(2 * N))),
135
                          (*part_carry_lo) | 0x1 , part_sum_lo, part_carry_lo);
136
      srt = bSign == 0 ? SHIFT_RIGHT(mult,(32 - (2 * N))) :
137
        SIGNED_SHIFT_RIGHT(mult,(32 - (2 * N)));
138
      carry_save_adder_32(*part_sum_hi,
139
                          ~(srt),
140
                          *part_carry_hi, part_sum_hi, part_carry_hi);
141
      break;
142
    case 7:
143
      carry_save_adder_32(*part_sum_lo, 0, *part_carry_lo,
144
                          part_sum_lo, part_carry_lo);
145
      carry_save_adder_32(*part_sum_hi, 0, *part_carry_hi,
146
                          part_sum_hi, part_carry_hi);
147
      break;
148
    }
149
 
150
#if 0
151
  if (N < 15)
152
    *carry = (temp >> 1) & 0x1;
153
  else
154
    *carry = 0;
155
#else
156
    *carry = (temp >> 1) & 0x1;
157
#endif
158
}
159
 
160
 
161
///////////////////////////////////////////////////////////////////////////////
162
// four_stage_booth - Does four rounds of booths alg at once
163
//
164
void scBooth::four_stage_booth(uint32_t* part_sum_hi, uint32_t* part_sum_lo,
165
                      uint32_t* part_carry_hi, uint32_t* part_carry_lo,
166
                      uint32_t mult, uint32_t N, bool_t* carry,
167
                      uint32_t* multiplier, bool_t bSign)
168
{
169
  for (int i = 0; i < 4; i++)
170
    {
171
      booth_one_stage(part_sum_hi, part_sum_lo,
172
                      part_carry_hi, part_carry_lo,
173
                      mult, (N * 4) + i,
174
                      carry, *multiplier, bSign);
175
 
176
      *part_carry_hi = (*part_carry_hi << 1) | (*part_carry_lo >> 31);
177
      *part_carry_lo = *part_carry_lo << 1;
178
      *multiplier = *multiplier >> 2;
179
    }
180
}
181
 
182
 
183
 
184
void scBooth::entry()
185
{
186
  out=a*b;
187
}

powered by: WebSVN 2.1.0

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