CMS 3D CMS Logo

List of all members | Public Member Functions | Private Types | Private Attributes
CordicXilinx Class Reference

#include <L1Trigger/L1TCalorimeter/src/firmware/CordicXilinx.cc>

Public Member Functions

 CordicXilinx (int inputBits, int outputBits, bool debug=false)
 
int encodeAngle (const double angleFloat) const
 
void operator() (int32_t xInput, int32_t yInput, int32_t &aPhi, uint32_t &aMagnitude) const
 

Private Types

enum  { Pi, HalfPi, NHalfPi }
 

Private Attributes

const bool debug_
 
std::array< int, 3 > encodedAngles_
 
const int inputBits_
 
int internalBits_
 
int iterations_
 
const int outputBits_
 
std::vector< int > rotations_
 
int scaleFactor_
 

Detailed Description

Description: Emulates parts of the Xilinx DSP IP CORDIC routine, as described in http://www.xilinx.com/support/documentation/ip_documentation/cordic/v6_0/pg105-cordic.pdf This class only implements the vector translation, returning magnitude and phase, given signed x and y inputs. The inputs and outputs are not packed, so that normal signed integer arithmetic works as expected. They can easily be packed into a fixed width by abs() and placing a sign bit at the appropriate offset. The applicable configuration parameters that are being emulated are the following:

Tests: Full circle at various magnitudes, including maximum; a few billion random inputs Limited hardware comparisons have shown agreement as well. Test framework: https://github.com/nsmith-/cordic_test

Original Author: Nick Smith ( nick..nosp@m.smit.nosp@m.h@cer.nosp@m.n.ch )

Definition at line 8 of file CordicXilinx.h.

Member Enumeration Documentation

anonymous enum
private
Enumerator
Pi 
HalfPi 
NHalfPi 

Definition at line 30 of file CordicXilinx.h.

Constructor & Destructor Documentation

CordicXilinx::CordicXilinx ( int  inputBits,
int  outputBits,
bool  debug = false 
)

Definition at line 34 of file CordicXilinx.cc.

References debug_, encodeAngle(), encodedAngles_, HalfPi, mps_fire::i, internalBits_, iterations_, cmsBatch::log, M_PI, NHalfPi, Pi, funct::pow(), idealTransformation::rotation, rotations_, JetEnergyShift_cfi::scaleFactor, and scaleFactor_.

34  :
35  inputBits_(inputBits),
36  outputBits_(outputBits),
37  debug_(debug)
38 {
39  // Coarse rotation lowers necessary iterations by 2
40  iterations_ = outputBits-2;
41  // Internal precision is by default this value (when set to 0 in xilinx config)
42  internalBits_ = outputBits+ceil(log((float) iterations_)/log(2.));
43 
44  double scaleFactor = 1.;
45  for(int i=1; i<=iterations_; ++i)
46  {
47  int rotation = encodeAngle(atan(pow(2.,-i)));
48  rotations_.push_back(rotation);
49  scaleFactor *= pow(1+pow(2.,-2*i), -0.5);
50  }
51  scaleFactor_ = scaleFactor*pow(2., internalBits_-1)+0.5;
52 
53  // Precompute angles table for speed
57 
58  if ( debug_ ) printf("Cordic setup: %d iterations, %d internal bits, scale factor = %d\n", iterations_, internalBits_, scaleFactor_);
59 }
std::vector< int > rotations_
Definition: CordicXilinx.h:27
const int inputBits_
Definition: CordicXilinx.h:23
const int outputBits_
Definition: CordicXilinx.h:24
#define M_PI
const bool debug_
Definition: CordicXilinx.h:25
#define debug
Definition: HDRShower.cc:19
int encodeAngle(const double angleFloat) const
Definition: CordicXilinx.cc:61
std::array< int, 3 > encodedAngles_
Definition: CordicXilinx.h:29
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40

Member Function Documentation

int CordicXilinx::encodeAngle ( const double  angleFloat) const

Definition at line 61 of file CordicXilinx.cc.

References internalBits_, M_PI, and funct::pow().

Referenced by CordicXilinx().

62 {
63  assert(fabs(angleFloat)<=M_PI);
64  // Xilinx seems to store rounded rotation table
65  return angleFloat*pow(2., internalBits_-3)+0.5;
66 }
#define M_PI
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
void CordicXilinx::operator() ( int32_t  xInput,
int32_t  yInput,
int32_t &  aPhi,
uint32_t &  aMagnitude 
) const

Definition at line 68 of file CordicXilinx.cc.

References funct::abs(), gather_cfg::cout, debug_, encodedAngles_, HalfPi, mps_fire::i, inputBits_, internalBits_, iterations_, NHalfPi, outputBits_, Pi, funct::pow(), idealTransformation::rotation, rotations_, scaleFactor_, Validation_hcalonly_cfi::sign, x, and y.

69 {
70  // Assumption in algorithm is that arithmetic shifts are used for ints (as opposed to logical shifts)
71  static_assert( ((int) -1)>>3 == (int) -1 , "Signed ints need to use arithmetic shifts for this algorithm to work properly!");
72 
73  // Input checks
74  // Input is in 2QN format, and for xilinx
75  // the max is +- 1.0000...
76  assert(abs(xInput) <= (1<<(inputBits_-1)));
77  assert(abs(yInput) <= (1<<(inputBits_-1)));
78 
79  // Rotation to get from current vector to origin
80  // must invert to get aPhi
81  int rotation(0);
82  int x,y;
83 
84  // Debug tool
85  auto printVals = [&x,&y,&rotation,this]
86  {
87  printf("x: % 8d y: % 8d phi: % 8d outphi: % 8d float phi = % f\n",
88  x,
89  y,
90  rotation,
91  (abs(rotation)>>(internalBits_-outputBits_)) * ((rotation>0) ? -1:1),
92  rotation/pow(2., internalBits_-3)
93  );
94  };
95 
96  // Convert to internal precision
97  if ( internalBits_ > inputBits_ )
98  {
99  x = xInput << (internalBits_-inputBits_);
100  y = yInput << (internalBits_-inputBits_);
101  }
102  else
103  {
104  x = xInput >> (inputBits_-internalBits_);
105  y = yInput >> (inputBits_-internalBits_);
106  }
107  if ( debug_ ) printVals();
108 
109  // Coarse rotate to [-pi/4,pi/4)
110  if ( x-y >= 0 )
111  {
112  if ( x+y >= 0 )
113  {
114  // East (Correct) quadrant
115  }
116  else
117  {
118  // South, rotate by +pi/2
119  int xtmp = -y;
120  int ytmp = x;
121  x = xtmp;
122  y = ytmp;
123  rotation += encodedAngles_[HalfPi];
124  }
125  }
126  else
127  {
128  if ( x+y >= 0 )
129  {
130  // North, rotate by -pi/2
131  int xtmp = y;
132  int ytmp = -x;
133  x = xtmp;
134  y = ytmp;
135  rotation += encodedAngles_[NHalfPi];
136  }
137  else
138  {
139  // West, rotate by pi
140  x = -x;
141  y = -y;
142  rotation += encodedAngles_[Pi];
143  }
144  }
145  if ( debug_ ) std::cout << "Coarse rotate" << std::endl;
146  if ( debug_ ) printVals();
147 
148  if ( debug_ ) std::cout << "Starting iterations" << std::endl;
149  for ( int i=1; i<=iterations_; ++i )
150  {
151  int sign = (y>=0) ? -1:1;
152  int xtmp = x - sign*(y>>i);
153  int ytmp = y + sign*(x>>i);
154  x = xtmp;
155  y = ytmp;
156  rotation += sign*rotations_[i-1];
157  if ( debug_ ) printVals();
158  }
159 
160  // need a little extra room for the last multiplication
161  aMagnitude = ((long) x * (long) scaleFactor_)>>(2*internalBits_-outputBits_-1);
162 
163  // Xilinx seems to just mod to [-pi,pi]
164  if ( rotation > encodedAngles_[Pi] ) rotation -= 2*encodedAngles_[Pi]+1;
165  aPhi = (-rotation)>>(internalBits_-outputBits_);
166 }
std::vector< int > rotations_
Definition: CordicXilinx.h:27
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
const bool debug_
Definition: CordicXilinx.h:25
std::array< int, 3 > encodedAngles_
Definition: CordicXilinx.h:29
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40

Member Data Documentation

const bool CordicXilinx::debug_
private

Definition at line 25 of file CordicXilinx.h.

Referenced by CordicXilinx(), and operator()().

std::array<int, 3> CordicXilinx::encodedAngles_
private

Definition at line 29 of file CordicXilinx.h.

Referenced by CordicXilinx(), and operator()().

const int CordicXilinx::inputBits_
private

Definition at line 23 of file CordicXilinx.h.

Referenced by operator()().

int CordicXilinx::internalBits_
private

Definition at line 32 of file CordicXilinx.h.

Referenced by CordicXilinx(), encodeAngle(), and operator()().

int CordicXilinx::iterations_
private

Definition at line 31 of file CordicXilinx.h.

Referenced by CordicXilinx(), and operator()().

const int CordicXilinx::outputBits_
private

Definition at line 24 of file CordicXilinx.h.

Referenced by operator()().

std::vector<int> CordicXilinx::rotations_
private

Definition at line 27 of file CordicXilinx.h.

Referenced by CordicXilinx(), and operator()().

int CordicXilinx::scaleFactor_
private

Definition at line 33 of file CordicXilinx.h.

Referenced by CordicXilinx(), and operator()().