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

anonymous enum
private
Enumerator
Pi 
HalfPi 
NHalfPi 

Definition at line 29 of file CordicXilinx.h.

Constructor & Destructor Documentation

◆ CordicXilinx()

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

Definition at line 34 of file CordicXilinx.cc.

References reco::ceil(), debug_, encodeAngle(), encodedAngles_, HalfPi, mps_fire::i, internalBits_, iterations_, dqm-mbProfile::log, M_PI, NHalfPi, Pi, funct::pow(), idealTransformation::rotation, rotations_, multiplicitycorr_cfi::scaleFactor, and scaleFactor_.

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

Member Function Documentation

◆ encodeAngle()

int CordicXilinx::encodeAngle ( const double  angleFloat) const

Definition at line 59 of file CordicXilinx.cc.

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

Referenced by CordicXilinx().

59  {
60  assert(fabs(angleFloat) <= M_PI);
61  // Xilinx seems to store rounded rotation table
62  return angleFloat * pow(2., internalBits_ - 3) + 0.5;
63 }
assert(be >=bs)
#define M_PI
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

◆ operator()()

void CordicXilinx::operator() ( int32_t  xInput,
int32_t  yInput,
int32_t &  aPhi,
uint32_t &  aMagnitude 
) const

Definition at line 65 of file CordicXilinx.cc.

References funct::abs(), simKBmtfDigis_cfi::aPhi, cms::cuda::assert(), 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.

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

Member Data Documentation

◆ debug_

const bool CordicXilinx::debug_
private

Definition at line 24 of file CordicXilinx.h.

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

◆ encodedAngles_

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

Definition at line 28 of file CordicXilinx.h.

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

◆ inputBits_

const int CordicXilinx::inputBits_
private

Definition at line 22 of file CordicXilinx.h.

Referenced by operator()().

◆ internalBits_

int CordicXilinx::internalBits_
private

Definition at line 31 of file CordicXilinx.h.

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

◆ iterations_

int CordicXilinx::iterations_
private

Definition at line 30 of file CordicXilinx.h.

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

◆ outputBits_

const int CordicXilinx::outputBits_
private

Definition at line 23 of file CordicXilinx.h.

Referenced by operator()().

◆ rotations_

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

Definition at line 26 of file CordicXilinx.h.

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

◆ scaleFactor_

int CordicXilinx::scaleFactor_
private

Definition at line 32 of file CordicXilinx.h.

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