Back to home page

Project CMSSW displayed by LXR

 
 

    


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 // print functions
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   //first calculate address
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   //header of the module
0357 
0358   //inputs
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   //print header
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   //body of the module
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   //trailer
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 }