CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CordicXilinx.cc
Go to the documentation of this file.
1 
26 
27 #include <vector>
28 #include <iostream>
29 #include <iomanip>
30 #include <cassert>
31 #include <math.h>
32 
33 CordicXilinx::CordicXilinx(int inputBits, int outputBits, bool debug) :
34  inputBits_(inputBits),
35  outputBits_(outputBits),
36  debug_(debug)
37 {
38  // Coarse rotation lowers necessary iterations by 2
39  iterations_ = outputBits-2;
40  // Internal precision is by default this value (when set to 0 in xilinx config)
41  internalBits_ = outputBits+ceil(log((float) iterations_)/log(2.));
42 
43  double scaleFactor = 1.;
44  for(int i=1; i<=iterations_; ++i)
45  {
46  int rotation = encodeAngle(atan(pow(2.,-i)));
47  rotations_.push_back(rotation);
48  scaleFactor *= pow(1+pow(2.,-2*i), -0.5);
49  }
50  scaleFactor_ = scaleFactor*pow(2., internalBits_-1)+0.5;
51 
52  // Precompute angles table for speed
56 
57  if ( debug_ ) printf("Cordic setup: %d iterations, %d internal bits, scale factor = %d\n", iterations_, internalBits_, scaleFactor_);
58 }
59 
60 int CordicXilinx::encodeAngle(const double angleFloat) const
61 {
62  assert(abs(angleFloat)<=M_PI);
63  // Xilinx seems to store rounded rotation table
64  return angleFloat*pow(2., internalBits_-3)+0.5;
65 }
66 
67 void CordicXilinx::operator() ( int32_t xInput , int32_t yInput , int32_t& aPhi , uint32_t& aMagnitude ) const
68 {
69  // Assumption in algorithm is that arithmetic shifts are used for ints (as opposed to logical shifts)
70  static_assert( ((int) -1)>>3 == (int) -1 , "Signed ints need to use arithmetic shifts for this algorithm to work properly!");
71 
72  // Input checks
73  // Input is in 2QN format, and for xilinx
74  // the max is +- 1.0000...
75  assert(abs(xInput) <= (1<<(inputBits_-1)));
76  assert(abs(yInput) <= (1<<(inputBits_-1)));
77 
78  // Rotation to get from current vector to origin
79  // must invert to get aPhi
80  int rotation(0);
81  int x,y;
82 
83  // Debug tool
84  auto printVals = [&x,&y,&rotation,this]
85  {
86  printf("x: % 8d y: % 8d phi: % 8d outphi: % 8d float phi = % f\n",
87  x,
88  y,
89  rotation,
90  (abs(rotation)>>(internalBits_-outputBits_)) * ((rotation>0) ? -1:1),
91  rotation/pow(2., internalBits_-3)
92  );
93  };
94 
95  // Convert to internal precision
96  if ( internalBits_ > inputBits_ )
97  {
98  x = xInput << (internalBits_-inputBits_);
99  y = yInput << (internalBits_-inputBits_);
100  }
101  else
102  {
103  x = xInput >> (inputBits_-internalBits_);
104  y = yInput >> (inputBits_-internalBits_);
105  }
106  if ( debug_ ) printVals();
107 
108  // Coarse rotate to [-pi/4,pi/4)
109  if ( x-y >= 0 )
110  {
111  if ( x+y >= 0 )
112  {
113  // East (Correct) quadrant
114  }
115  else
116  {
117  // South, rotate by +pi/2
118  int xtmp = -y;
119  int ytmp = x;
120  x = xtmp;
121  y = ytmp;
122  rotation += encodedAngles_[HalfPi];
123  }
124  }
125  else
126  {
127  if ( x+y >= 0 )
128  {
129  // North, rotate by -pi/2
130  int xtmp = y;
131  int ytmp = -x;
132  x = xtmp;
133  y = ytmp;
134  rotation += encodedAngles_[NHalfPi];
135  }
136  else
137  {
138  // West, rotate by pi
139  x = -x;
140  y = -y;
141  rotation += encodedAngles_[Pi];
142  }
143  }
144  if ( debug_ ) std::cout << "Coarse rotate" << std::endl;
145  if ( debug_ ) printVals();
146 
147  if ( debug_ ) std::cout << "Starting iterations" << std::endl;
148  for ( int i=1; i<=iterations_; ++i )
149  {
150  int sign = (y>=0) ? -1:1;
151  int xtmp = x - sign*(y>>i);
152  int ytmp = y + sign*(x>>i);
153  x = xtmp;
154  y = ytmp;
155  rotation += sign*rotations_[i-1];
156  if ( debug_ ) printVals();
157  }
158 
159  // need a little extra room for the last multiplication
160  aMagnitude = ((long) x * (long) scaleFactor_)>>(2*internalBits_-outputBits_-1);
161 
162  // Xilinx seems to just mod to [-pi,pi]
163  if ( rotation > encodedAngles_[Pi] ) rotation -= 2*encodedAngles_[Pi]+1;
164  aPhi = (-rotation)>>(internalBits_-outputBits_);
165 }
int i
Definition: DBlmapReader.cc:9
std::vector< int > rotations_
Definition: CordicXilinx.h:27
double sign(double x)
assert(m_qm.get())
const int inputBits_
Definition: CordicXilinx.h:23
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const int outputBits_
Definition: CordicXilinx.h:24
CordicXilinx(int inputBits, int outputBits, bool debug=false)
Definition: CordicXilinx.cc:33
#define M_PI
const bool debug_
Definition: CordicXilinx.h:25
#define debug
Definition: HDRShower.cc:19
void operator()(int32_t xInput, int32_t yInput, int32_t &aPhi, uint32_t &aMagnitude) const
Definition: CordicXilinx.cc:67
int encodeAngle(const double angleFloat) const
Definition: CordicXilinx.cc:60
std::array< int, 3 > encodedAngles_
Definition: CordicXilinx.h:29
tuple cout
Definition: gather_cfg.py:121
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
tuple log
Definition: cmsBatch.py:341