File indexing completed on 2024-04-06 12:20:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include "L1Trigger/L1TCalorimeter/interface/CordicXilinx.h"
0026
0027 #include <vector>
0028 #include <iostream>
0029 #include <iomanip>
0030 #include <cassert>
0031 #include <cmath>
0032 #include <cmath>
0033
0034 CordicXilinx::CordicXilinx(int inputBits, int outputBits, bool debug)
0035 : inputBits_(inputBits), outputBits_(outputBits), debug_(debug) {
0036
0037 iterations_ = outputBits - 2;
0038
0039 internalBits_ = outputBits + ceil(log((float)iterations_) / log(2.));
0040
0041 double scaleFactor = 1.;
0042 for (int i = 1; i <= iterations_; ++i) {
0043 int rotation = encodeAngle(atan(pow(2., -i)));
0044 rotations_.push_back(rotation);
0045 scaleFactor *= pow(1 + pow(2., -2 * i), -0.5);
0046 }
0047 scaleFactor_ = scaleFactor * pow(2., internalBits_ - 1) + 0.5;
0048
0049
0050 encodedAngles_[Pi] = encodeAngle(M_PI);
0051 encodedAngles_[HalfPi] = encodeAngle(M_PI / 2);
0052 encodedAngles_[NHalfPi] = encodeAngle(-M_PI / 2);
0053
0054 if (debug_)
0055 printf(
0056 "Cordic setup: %d iterations, %d internal bits, scale factor = %d\n", iterations_, internalBits_, scaleFactor_);
0057 }
0058
0059 int CordicXilinx::encodeAngle(const double angleFloat) const {
0060 assert(fabs(angleFloat) <= M_PI);
0061
0062 return angleFloat * pow(2., internalBits_ - 3) + 0.5;
0063 }
0064
0065 void CordicXilinx::operator()(int32_t xInput, int32_t yInput, int32_t& aPhi, uint32_t& aMagnitude) const {
0066
0067 static_assert(((int)-1) >> 3 == (int)-1,
0068 "Signed ints need to use arithmetic shifts for this algorithm to work properly!");
0069
0070
0071
0072
0073 assert(abs(xInput) <= (1 << (inputBits_ - 1)));
0074 assert(abs(yInput) <= (1 << (inputBits_ - 1)));
0075
0076
0077
0078 int rotation(0);
0079 int x, y;
0080
0081
0082 auto printVals = [&x, &y, &rotation, this] {
0083 printf("x: % 8d y: % 8d phi: % 8d outphi: % 8d float phi = % f\n",
0084 x,
0085 y,
0086 rotation,
0087 (abs(rotation) >> (internalBits_ - outputBits_)) * ((rotation > 0) ? -1 : 1),
0088 rotation / pow(2., internalBits_ - 3));
0089 };
0090
0091
0092 if (internalBits_ > inputBits_) {
0093 x = xInput << (internalBits_ - inputBits_);
0094 y = yInput << (internalBits_ - inputBits_);
0095 } else {
0096 x = xInput >> (inputBits_ - internalBits_);
0097 y = yInput >> (inputBits_ - internalBits_);
0098 }
0099 if (debug_)
0100 printVals();
0101
0102
0103 if (x - y >= 0) {
0104 if (x + y >= 0) {
0105
0106 } else {
0107
0108 int xtmp = -y;
0109 int ytmp = x;
0110 x = xtmp;
0111 y = ytmp;
0112 rotation += encodedAngles_[HalfPi];
0113 }
0114 } else {
0115 if (x + y >= 0) {
0116
0117 int xtmp = y;
0118 int ytmp = -x;
0119 x = xtmp;
0120 y = ytmp;
0121 rotation += encodedAngles_[NHalfPi];
0122 } else {
0123
0124 x = -x;
0125 y = -y;
0126 rotation += encodedAngles_[Pi];
0127 }
0128 }
0129 if (debug_)
0130 std::cout << "Coarse rotate" << std::endl;
0131 if (debug_)
0132 printVals();
0133
0134 if (debug_)
0135 std::cout << "Starting iterations" << std::endl;
0136 for (int i = 1; i <= iterations_; ++i) {
0137 int sign = (y >= 0) ? -1 : 1;
0138 int xtmp = x - sign * (y >> i);
0139 int ytmp = y + sign * (x >> i);
0140 x = xtmp;
0141 y = ytmp;
0142 rotation += sign * rotations_[i - 1];
0143 if (debug_)
0144 printVals();
0145 }
0146
0147
0148 aMagnitude = ((long)x * (long)scaleFactor_) >> (2 * internalBits_ - outputBits_ - 1);
0149
0150
0151 if (rotation > encodedAngles_[Pi])
0152 rotation -= 2 * encodedAngles_[Pi] + 1;
0153 aPhi = (-rotation) >> (internalBits_ - outputBits_);
0154 }