CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 33 of file CordicXilinx.cc.

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

33  :
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 }
int i
Definition: DBlmapReader.cc:9
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:60
std::array< int, 3 > encodedAngles_
Definition: CordicXilinx.h:29
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
tuple log
Definition: cmsBatch.py:347

Member Function Documentation

int CordicXilinx::encodeAngle ( const double  angleFloat) const

Definition at line 60 of file CordicXilinx.cc.

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

Referenced by CordicXilinx().

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 }
assert(m_qm.get())
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#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 67 of file CordicXilinx.cc.

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

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
const bool debug_
Definition: CordicXilinx.h:25
std::array< int, 3 > encodedAngles_
Definition: CordicXilinx.h:29
tuple cout
Definition: gather_cfg.py:121
Definition: DDAxes.h:10
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()().