File indexing completed on 2023-03-17 11:13:50
0001 #include "L1Trigger/TrackFindingTracklet/interface/imath.h"
0002
0003 using namespace trklet;
0004
0005 void VarInv::writeLUT(std::ofstream& fs, HLS) const {
0006 for (int i = 0; i < Nelements_ - 1; ++i)
0007 fs << "0x" << std::hex << (LUT[i] & ((1 << nbits_) - 1)) << std::dec << ",\n";
0008 fs << "0x" << std::hex << (LUT[Nelements_ - 1] & ((1 << nbits_) - 1)) << std::dec << "\n";
0009 }
0010
0011 void VarBase::print_truncation(std::string& t, const std::string& o1, const int ps, HLS) const {
0012 if (ps > 0) {
0013 t += "const ap_int<" + itos(nbits_ + ps) + "> " + name_ + "_tmp = " + o1 + ";\n";
0014 t += "const ap_int<" + itos(nbits_) + "> " + name_ + " = " + name_ + "_tmp >> " + itos(ps) + ";\n";
0015 } else
0016 t += "const ap_int<" + itos(nbits_) + "> " + name_ + " = " + o1 + ";\n";
0017 }
0018
0019
0020
0021
0022
0023 void VarCut::print(std::map<const VarBase*, std::set<std::string> >& cut_strings,
0024 const int step,
0025 HLS,
0026 const std::map<const VarBase*, std::set<std::string> >* const previous_cut_strings) const {
0027 assert(step > -1);
0028 std::string name = cut_var_->name();
0029
0030 const int lower_cut = lower_cut_ / cut_var_->K();
0031 const int upper_cut = upper_cut_ / cut_var_->K();
0032 if (!previous_cut_strings || (previous_cut_strings && !previous_cut_strings->count(cut_var_))) {
0033 if (!cut_strings.count(cut_var_))
0034 cut_strings[cut_var_];
0035 cut_strings.at(cut_var_).insert(name + " > " + itos(lower_cut) + " && " + name + " < " + itos(upper_cut));
0036 }
0037 }
0038
0039 void VarBase::print_cuts(std::map<const VarBase*, std::set<std::string> >& cut_strings,
0040 const int step,
0041 HLS,
0042 const std::map<const VarBase*, std::set<std::string> >* const previous_cut_strings) const {
0043 if (p1_)
0044 p1_->print_cuts(cut_strings, step, hls, previous_cut_strings);
0045 if (p2_)
0046 p2_->print_cuts(cut_strings, step, hls, previous_cut_strings);
0047 if (p3_)
0048 p3_->print_cuts(cut_strings, step, hls, previous_cut_strings);
0049
0050 std::string name = name_;
0051
0052 for (const auto& cut : cuts_) {
0053 const VarCut* const cast_cut = (VarCut*)cut;
0054 const int lower_cut = cast_cut->lower_cut() / K_;
0055 const int upper_cut = cast_cut->upper_cut() / K_;
0056 if (!previous_cut_strings || (previous_cut_strings && !previous_cut_strings->count(this))) {
0057 if (!cut_strings.count(this))
0058 cut_strings[this];
0059 cut_strings.at(this).insert(name + " > " + itos(lower_cut) + " && " + name + " < " + itos(upper_cut));
0060 }
0061 }
0062 }
0063
0064 void VarAdjustK::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0065 assert(p1_);
0066 assert(l1 == 0);
0067 assert(l2 == 0);
0068 assert(l3 == 0);
0069
0070 std::string shift = "";
0071 if (lr_ > 0)
0072 shift = " >> " + itos(lr_);
0073 else if (lr_ < 0)
0074 shift = " << " + itos(-lr_);
0075
0076 std::string n1 = p1_->name();
0077
0078 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n";
0079 fs << "const ap_int<" << nbits_ << "> " << name_ << " = " << n1 << shift << ";\n";
0080 }
0081
0082 void VarAdjustKR::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0083 assert(p1_);
0084 assert(l1 == 0);
0085 assert(l2 == 0);
0086 assert(l3 == 0);
0087
0088 std::string n1 = p1_->name();
0089
0090 std::string o1 = n1;
0091 if (lr_ == 1)
0092 o1 = "(" + o1 + "+1)>>1";
0093 if (lr_ > 1)
0094 o1 = "( (" + o1 + ">>" + itos(lr_ - 1) + ")+1)>>1";
0095 if (lr_ < 0)
0096 o1 = "ap_int<" + itos(nbits_) + ">(" + o1 + ")<<" + itos(-lr_);
0097
0098 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n";
0099 fs << "const ap_int<" << nbits_ << "> " << name_ << " = " << o1 << ";\n";
0100 }
0101
0102 void VarDef::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0103 assert(l1 == 0);
0104 assert(l2 == 0);
0105 assert(l3 == 0);
0106
0107 fs << "// units " << kstring() << "\t" << K_ << "\n";
0108 fs << "const ap_int<" << nbits_ << "> " << name_ << " = " << name_ << "_wire;\n";
0109 }
0110
0111 void VarParam::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0112 assert(l1 == 0);
0113 assert(l2 == 0);
0114 assert(l3 == 0);
0115
0116 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n";
0117 fs << "static const ap_int<" << nbits_ << "> " << name_ << " = " << ival_ << ";\n";
0118 }
0119
0120 void VarAdd::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0121 assert(p1_);
0122 assert(p2_);
0123 assert(l1 == 0);
0124 assert(l2 == 0);
0125 assert(l3 == 0);
0126 std::string o1 = p1_->name();
0127 if (shift1 > 0) {
0128 o1 = "ap_int<" + itos(nbits_ + ps_) + ">(" + o1 + ")";
0129 o1 += "<<" + itos(shift1);
0130 o1 = "(" + o1 + ")";
0131 }
0132
0133 std::string o2 = p2_->name();
0134 if (shift2 > 0) {
0135 o2 = "ap_int<" + itos(nbits_ + ps_) + ">(" + o2 + ")";
0136 o2 += "<<" + itos(shift2);
0137 o2 = "(" + o2 + ")";
0138 }
0139
0140 o1 = o1 + " + " + o2;
0141
0142 std::string t = "";
0143 print_truncation(t, o1, ps_, hls);
0144 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t;
0145 }
0146
0147 void VarSubtract::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0148 assert(p1_);
0149 assert(p2_);
0150 assert(l1 == 0);
0151 assert(l2 == 0);
0152 assert(l3 == 0);
0153 std::string o1 = p1_->name();
0154 if (shift1 > 0) {
0155 o1 = "ap_int<" + itos(nbits_ + ps_) + ">(" + o1 + ")";
0156 o1 += "<<" + itos(shift1);
0157 o1 = "(" + o1 + ")";
0158 }
0159
0160 std::string o2 = p2_->name();
0161 if (shift2 > 0) {
0162 o2 = "ap_int<" + itos(nbits_ + ps_) + ">(" + o2 + ")";
0163 o2 += "<<" + itos(shift2);
0164 o2 = "(" + o2 + ")";
0165 }
0166
0167 o1 = o1 + " - " + o2;
0168
0169 std::string t = "";
0170 print_truncation(t, o1, ps_, hls);
0171 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t;
0172 }
0173
0174 void VarNounits::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0175 assert(p1_);
0176 assert(l1 == 0);
0177 assert(l2 == 0);
0178 assert(l3 == 0);
0179 std::string n1 = p1_->name();
0180 std::string o1 = "(" + n1 + " * " + itos(cI_) + ")";
0181
0182 std::string t = "";
0183 print_truncation(t, o1, ps_, hls);
0184 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t;
0185 }
0186
0187 void VarTimesC::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0188 assert(p1_);
0189 assert(l1 == 0);
0190 assert(l2 == 0);
0191 assert(l3 == 0);
0192 std::string n1 = p1_->name();
0193 std::string o1 = "(" + n1 + " * " + itos(cI_) + ")";
0194
0195 std::string t = "";
0196 print_truncation(t, o1, ps_, hls);
0197 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t;
0198 }
0199
0200 void VarNeg::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0201 assert(p1_);
0202 assert(l1 == 0);
0203 assert(l2 == 0);
0204 assert(l3 == 0);
0205 std::string n1 = p1_->name();
0206
0207 std::string t = "const ap_int<" + itos(nbits_) + "> " + name_ + " = -" + n1 + ";\n";
0208 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n";
0209 }
0210
0211 void VarShiftround::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0212 assert(p1_);
0213 assert(l1 == 0);
0214 assert(l2 == 0);
0215 assert(l3 == 0);
0216 std::string n1 = p1_->name();
0217 std::string o1 = n1;
0218 if (shift_ == 1)
0219 o1 = "(" + o1 + "+1)>>1";
0220 if (shift_ > 1)
0221 o1 = "( (" + o1 + ">>" + itos(shift_ - 1) + ")+1)>>1";
0222 if (shift_ < 0)
0223 o1 = "ap_int<" + itos(nbits_) + ">(" + o1 + ")<<" + itos(-shift_);
0224
0225 std::string t = "const ap_int<" + itos(nbits_) + "> " + name_ + " = " + o1 + ";\n";
0226 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n";
0227 }
0228
0229 void VarShift::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0230 assert(p1_);
0231 assert(l1 == 0);
0232 assert(l2 == 0);
0233 assert(l3 == 0);
0234 std::string n1 = p1_->name();
0235 std::string o1 = n1;
0236 if (shift_ > 0)
0237 o1 = o1 + ">>" + itos(shift_);
0238 if (shift_ < 0)
0239 o1 = "ap_int<" + itos(nbits_) + ">(" + o1 + ")<<" + itos(-shift_);
0240
0241 std::string t = "const ap_int<" + itos(nbits_) + "> " + name_ + " = " + o1 + ";\n";
0242 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t << ";\n";
0243 }
0244
0245 void VarMult::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0246 assert(l1 == 0);
0247 assert(l2 == 0);
0248 assert(l3 == 0);
0249 assert(p1_);
0250 std::string n1 = p1_->name();
0251 assert(p2_);
0252 std::string n2 = p2_->name();
0253 std::string o1 = n1 + " * " + n2;
0254
0255 std::string t = "";
0256 print_truncation(t, o1, ps_, hls);
0257 fs << "// " << nbits_ << " bits \t " << kstring() << "\t" << K_ << "\n" << t;
0258 }
0259
0260 void VarInv::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0261 assert(p1_);
0262 assert(l1 == 0);
0263 assert(l2 == 0);
0264 assert(l3 == 0);
0265
0266 fs << "static const ap_int<" << itos(nbits_) << "> LUT_" << name_ << "[" << Nelements_ << "] = {\n";
0267 fs << "#include \"LUT_" << name_ << ".h\"\n";
0268 fs << "};\n";
0269
0270 std::string n1 = p1_->name();
0271
0272 std::string t1 = "addr_" + name_;
0273 std::string t = "const ap_uint<" + itos(nbaddr_) + "> " + t1 + " = ";
0274 if (shift_ > 0)
0275 t = t + "(" + n1 + ">>" + itos(shift_) + ") & " + itos(mask_);
0276 else
0277 t = t + n1 + " & " + itos(mask_);
0278 fs << t << "; // address for the LUT\n";
0279
0280 t = "const ap_int<" + itos(nbits_) + "> " + name_ + " = LUT_" + name_ + "[addr_" + name_ + "];\n";
0281 fs << t;
0282 }
0283
0284 void VarFlag::print(std::ofstream& fs, HLS, int l1, int l2, int l3) {
0285 assert(l1 == 0);
0286 assert(l2 == 0);
0287 assert(l3 == 0);
0288
0289 fs << "const ap_int<1> " << name_ << " = (";
0290 std::map<const VarBase*, std::set<std::string> > cut_strings0, cut_strings1;
0291 for (const auto& cut : cuts_) {
0292 if (cut->op() != "cut")
0293 continue;
0294 const VarCut* const cast_cut = (VarCut*)cut;
0295 cast_cut->print(cut_strings0, step_, hls);
0296 }
0297 for (const auto& cut : cuts_) {
0298 if (cut->op() != "cut")
0299 cut->print_cuts(cut_strings1, step_, hls, &cut_strings0);
0300 else {
0301 if (cut->cut_var()->p1())
0302 cut->cut_var()->p1()->print_cuts(cut_strings1, step_, hls, &cut_strings1);
0303 if (cut->cut_var()->p2())
0304 cut->cut_var()->p2()->print_cuts(cut_strings1, step_, hls, &cut_strings1);
0305 if (cut->cut_var()->p3())
0306 cut->cut_var()->p3()->print_cuts(cut_strings1, step_, hls, &cut_strings1);
0307 }
0308 }
0309
0310 std::string separator = "";
0311 for (const auto& cut_var : cut_strings0) {
0312 separator += "((";
0313 for (const auto& cut_string : cut_var.second) {
0314 fs << separator << cut_string;
0315 separator = ") || (";
0316 }
0317 separator = ")) && ";
0318 }
0319 for (const auto& cut_var : cut_strings1) {
0320 separator += "((";
0321 for (const auto& cut_string : cut_var.second) {
0322 fs << separator << cut_string;
0323 separator = ") || (";
0324 }
0325 separator = ")) && ";
0326 }
0327
0328 fs << ")));";
0329 }
0330
0331 void VarBase::print_step(int step, std::ofstream& fs, HLS) {
0332 if (!readytoprint_)
0333 return;
0334 if (step > step_)
0335 return;
0336 if (p1_)
0337 p1_->print_step(step, fs, hls);
0338 if (p2_)
0339 p2_->print_step(step, fs, hls);
0340 if (p3_)
0341 p3_->print_step(step, fs, hls);
0342 if (step == step_) {
0343 print(fs, hls, 0, 0, 0);
0344 readytoprint_ = false;
0345 }
0346 }
0347
0348 void VarBase::print_all(std::ofstream& fs, HLS) {
0349 for (int i = 0; i <= step_; ++i) {
0350 fs << "//\n// STEP " << i << "\n\n";
0351 print_step(i, fs, hls);
0352 }
0353 }
0354
0355 void VarBase::design_print(const std::vector<VarBase*>& v, std::ofstream& fs, HLS) {
0356
0357
0358
0359 std::vector<VarBase*> vd;
0360 vd.clear();
0361 int imax = v.size();
0362 for (int i = 0; i < imax; ++i)
0363 (v[i])->inputs(&vd);
0364
0365
0366 fs << "#include \"ap_int.h\"\n\n";
0367 fs << "void XXX (\n";
0368
0369 imax = vd.size();
0370 for (int i = 0; i < imax; ++i)
0371 fs << " const ap_int<" << (vd[i])->nbits() << "> " << (vd[i])->name() << "_wire,\n";
0372 fs << "\n";
0373
0374 imax = v.size() - 1;
0375 for (int i = 0; i < imax; ++i)
0376 fs << " ap_int<" << (v[i])->nbits() << "> * const " << (v[i])->name() << "_wire,\n";
0377 if (imax >= 0)
0378 fs << " ap_int<" << (v[imax])->nbits() << "> * const " << (v[imax])->name() << "_wire\n";
0379 fs << ")\n{\n";
0380 fs << "#pragma HLS pipeline II=1\n";
0381 fs << "#pragma HLS latency max=25\n";
0382
0383
0384 imax = v.size();
0385 for (int i = 0; i < imax; ++i) {
0386 fs << "\n//\n";
0387 fs << "// calculating " << (v[i])->name() << "\n";
0388 fs << "//\n";
0389 (v[i])->print_all(fs, hls);
0390 }
0391 fs << "\n";
0392
0393
0394 fs << "\n";
0395 fs << "\n//\n";
0396 fs << "// wiring the outputs \n";
0397 fs << "//\n";
0398 for (int i = 0; i < imax; ++i) {
0399 std::string n = v[i]->name() + "_wire";
0400 fs << "*" << n << " = " << (v[i])->name() << ";\n";
0401 }
0402
0403 fs << "}\n";
0404 }