diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f517e7c5ba2..60f77c875d3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -181,7 +181,7 @@ MP-quality-check: <<: *template_quality-check variables: VIVADO_VERSION: "2019.2" - CLANG_TIDY_FILES: '../TestBenches/MatchProcessorL3_test.cpp ../TopFunctions/CombinedConfig/MatchProcessorTopL3.cpp' + CLANG_TIDY_FILES: '../TestBenches/MatchProcessor_test.cpp ../TopFunctions/CombinedConfig/MatchProcessorTop.cc' TB-quality-check: <<: *template_quality-check variables: @@ -262,8 +262,8 @@ MC-vivado-hls-build: PROJ_NAME: "MC" MP-vivado-hls-build: <<: *template_hls-build + allow_failure: true needs: ["download", "MP-quality-check"] - allow_failure: true # FIXME: remove after all errors are fixed variables: EXECUTABLE: 'vivado_hls' VIVADO_VERSION: "2019.2" diff --git a/TestBenches/Macros.h b/TestBenches/Macros.h index 5a2ac8d7dd5..0c191edd87e 100644 --- a/TestBenches/Macros.h +++ b/TestBenches/Macros.h @@ -1176,7 +1176,55 @@ X(TP_L3L4D_, "TP_L3L4D") \ X(TP_L5L6A_, "TP_L5L6A") \ X(TP_L5L6B_, "TP_L5L6B") \ X(TP_L5L6C_, "TP_L5L6C") \ -X(TP_L5L6D_, "TP_L5L6D") +X(TP_L5L6D_, "TP_L5L6D") \ +X(MP_D1PHIA_, "MP_D1PHIA") \ +X(MP_D1PHIB_, "MP_D1PHIB") \ +X(MP_D1PHIC_, "MP_D1PHIC") \ +X(MP_D1PHID_, "MP_D1PHID") \ +X(MP_D2PHIA_, "MP_D2PHIA") \ +X(MP_D2PHIB_, "MP_D2PHIB") \ +X(MP_D2PHIC_, "MP_D2PHIC") \ +X(MP_D2PHID_, "MP_D2PHID") \ +X(MP_D3PHIA_, "MP_D3PHIA") \ +X(MP_D3PHIB_, "MP_D3PHIB") \ +X(MP_D3PHIC_, "MP_D3PHIC") \ +X(MP_D3PHID_, "MP_D3PHID") \ +X(MP_D4PHIA_, "MP_D4PHIA") \ +X(MP_D4PHIB_, "MP_D4PHIB") \ +X(MP_D4PHIC_, "MP_D4PHIC") \ +X(MP_D4PHID_, "MP_D4PHID") \ +X(MP_D5PHIA_, "MP_D5PHIA") \ +X(MP_D5PHIB_, "MP_D5PHIB") \ +X(MP_D5PHIC_, "MP_D5PHIC") \ +X(MP_D5PHID_, "MP_D5PHID") \ +X(MP_L1PHIA_, "MP_L1PHIA") \ +X(MP_L1PHIB_, "MP_L1PHIB") \ +X(MP_L1PHIC_, "MP_L1PHIC") \ +X(MP_L1PHID_, "MP_L1PHID") \ +X(MP_L1PHIE_, "MP_L1PHIE") \ +X(MP_L1PHIF_, "MP_L1PHIF") \ +X(MP_L1PHIG_, "MP_L1PHIG") \ +X(MP_L1PHIH_, "MP_L1PHIH") \ +X(MP_L2PHIA_, "MP_L2PHIA") \ +X(MP_L2PHIB_, "MP_L2PHIB") \ +X(MP_L2PHIC_, "MP_L2PHIC") \ +X(MP_L2PHID_, "MP_L2PHID") \ +X(MP_L3PHIA_, "MP_L3PHIA") \ +X(MP_L3PHIB_, "MP_L3PHIB") \ +X(MP_L3PHIC_, "MP_L3PHIC") \ +X(MP_L3PHID_, "MP_L3PHID") \ +X(MP_L4PHIA_, "MP_L4PHIA") \ +X(MP_L4PHIB_, "MP_L4PHIB") \ +X(MP_L4PHIC_, "MP_L4PHIC") \ +X(MP_L4PHID_, "MP_L4PHID") \ +X(MP_L5PHIA_, "MP_L5PHIA") \ +X(MP_L5PHIB_, "MP_L5PHIB") \ +X(MP_L5PHIC_, "MP_L5PHIC") \ +X(MP_L5PHID_, "MP_L5PHID") \ +X(MP_L6PHIA_, "MP_L6PHIA") \ +X(MP_L6PHIB_, "MP_L6PHIB") \ +X(MP_L6PHIC_, "MP_L6PHIC") \ +X(MP_L6PHID_, "MP_L6PHID") #define X(module, name) module, enum Module : size_t diff --git a/TestBenches/MatchProcessorL3_test.cpp b/TestBenches/MatchProcessorL3_test.cpp deleted file mode 100644 index 3e139d0a81d..00000000000 --- a/TestBenches/MatchProcessorL3_test.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// ProjectionRouter test bench -#include "MatchProcessorTopL3.h" -#include "CandidateMatchMemory.h" -#include "VMProjectionMemory.h" -#include "ProjectionRouterBuffer.h" -#include "VMStubMEMemoryCM.h" -#include "FileReadUtility.h" -#include "hls_math.h" - -#include -#include -#include -#include -#include - -const int nevents = 100; // number of events to run - -using namespace std; - - - -int main() { - // error counter - int err_count = 0; - - // input memories - static TrackletProjectionMemory tproj[maxTrackletProjections]; - static AllStubMemory allstub; - - VMStubMEMemoryCM inputvmstubs; - - // declare output memory array to be filled by hls simulation - static FullMatchMemory fullmatch[maxFullMatchCopies]; - - ap_uint<8>* valid; - - // open input files - cout << "Open files..." << endl; - - ifstream fin_tproj[maxTrackletProjections]; - ifstream fin_as; - //ifstream fout_ap; - - if (not openDataFile(fin_tproj[0], "MP_L3PHIC/TrackletProjections_TPROJ_L1L2E_L3PHIC_04.dat")) return -1; - if (not openDataFile(fin_tproj[1], "MP_L3PHIC/TrackletProjections_TPROJ_L1L2F_L3PHIC_04.dat")) return -1; - if (not openDataFile(fin_tproj[2], "MP_L3PHIC/TrackletProjections_TPROJ_L1L2G_L3PHIC_04.dat")) return -1; - if (not openDataFile(fin_tproj[3], "MP_L3PHIC/TrackletProjections_TPROJ_L1L2H_L3PHIC_04.dat")) return -1; - if (not openDataFile(fin_tproj[4], "MP_L3PHIC/TrackletProjections_TPROJ_L1L2I_L3PHIC_04.dat")) return -1; - if (not openDataFile(fin_tproj[5], "MP_L3PHIC/TrackletProjections_TPROJ_L1L2J_L3PHIC_04.dat")) return -1; - if (not openDataFile(fin_tproj[6], "MP_L3PHIC/TrackletProjections_TPROJ_L1L2K_L3PHIC_04.dat")) return -1; - if (not openDataFile(fin_tproj[7], "MP_L3PHIC/TrackletProjections_TPROJ_L5L6B_L3PHIC_04.dat")) return -1; - if (not openDataFile(fin_tproj[8], "MP_L3PHIC/TrackletProjections_TPROJ_L5L6C_L3PHIC_04.dat")) return -1; - if (not openDataFile(fin_tproj[9], "MP_L3PHIC/TrackletProjections_TPROJ_L5L6D_L3PHIC_04.dat")) return -1; - - ifstream fin_vmstub; - - bool validvmstub = openDataFile(fin_vmstub,"MP_L3PHIC/VMStubs_VMSME_L3PHICn1_04.dat"); - if (not validvmstub) return -1; - - if (not openDataFile(fin_as,"MP_L3PHIC/AllStubs_AS_L3PHICn1_04.dat")) return -1; - - // open file(s) with reference results - ifstream fout_fm1; - ifstream fout_fm2; - ifstream fout_fm3; - ifstream fout_fm4; - ifstream fout_fm5; - ifstream fout_fm6; - ifstream fout_fm7; - - if (not openDataFile(fout_fm1,"MP_L3PHIC/FullMatches_FM_L1L2_L3PHIC_04.dat")) return -1; - if (not openDataFile(fout_fm3,"MP_L3PHIC/FullMatches_FM_L5L6_L3PHIC_04.dat")) return -1; - - // loop over events - for (int ievt = 0; ievt < nevents; ++ievt) { - cout << "Event: " << dec << ievt << endl; - - fullmatch[0].clear(); -// fullmatch[1].clear(); -// fullmatch[2].clear(); - fullmatch[3].clear(); -// fullmatch[4].clear(); -// fullmatch[5].clear(); -// fullmatch[6].clear(); -// fullmatch[7].clear(); - - // read event and write to memories - for(int i = 0; i < maxTrackletProjections; i++) - writeMemFromFile >(tproj[i], fin_tproj[i], ievt); - writeMemFromFile >(allstub, fin_as, ievt); - - writeMemFromFile >(inputvmstubs, fin_vmstub, ievt); - - //set bunch crossing - BXType bx=ievt; - BXType bx_out; - - int noutcandmatch = 0; - - // Unit Under Test - MatchProcessorTopL3(bx, - tproj, - inputvmstubs, - &allstub, - bx_out, - fullmatch); - - // compare the computed outputs with the expected ones for the candidate - // matches - bool truncation = false; - - // compare the computed outputs with the expected ones - std::cout << "FM: L1L2 seeding" << std::endl; - err_count += compareMemWithFile >(fullmatch[0], fout_fm1, ievt, "FullMatch", truncation); - //err_count += compareMemWithFile >(fullmatch[0], fout_fm1, ievt, "FullMatch", truncation); - //std::cout << "FM: L3L4 seeding" << std::endl; - //err_count += compareMemWithFile >(fullmatch2, fout_fm2, ievt, "FullMatch", truncation); - std::cout << "FM: L5L6 seeding" << std::endl; - err_count += compareMemWithFile >(fullmatch[3], fout_fm3, ievt, "FullMatch", truncation); - //err_count += compareMemWithFile >(fullmatch[2], fout_fm3, ievt, "FullMatch", truncation); - //std::cout << "FM: D1D2 seeding" << std::endl; - //err_count += compareMemWithFile >(fullmatch4, fout_fm4, ievt, "FullMatch", truncation); - //std::cout << "FM: D3D4 seeding" << std::endl; - //err_count += compareMemWithFile >(fullmatch5, fout_fm5, ievt, "FullMatch", truncation); - //std::cout << "FM: L1D1 seeding" << std::endl; - //err_count += compareMemWithFile >(fullmatch6, fout_fm6, ievt, "FullMatch", truncation); - //std::cout << "FM: L2D1 seeding" << std::endl; - //err_count += compareMemWithFile >(fullmatch7, fout_fm7, ievt, "FullMatch", truncation); - - - } // end of event loop - - // close files - for(int i = 0; i < maxTrackletProjections; i++) - fin_tproj[i].close(); - fin_vmstub.close(); - - fout_fm1.close(); - fout_fm2.close(); - fout_fm3.close(); - fout_fm4.close(); - fout_fm5.close(); - fout_fm6.close(); - fout_fm7.close(); - - // This is necessary because HLS seems to only return an 8-bit error count, so if err%256==0, the test bench can falsely pass - if (err_count > 255) err_count = 255; - return err_count; - -} diff --git a/TestBenches/MatchProcessor_test.cpp b/TestBenches/MatchProcessor_test.cpp new file mode 100644 index 00000000000..3458eea9f2a --- /dev/null +++ b/TestBenches/MatchProcessor_test.cpp @@ -0,0 +1,114 @@ +// Test bench for MatchProcessor +#include "MatchProcessorTop.h" + +#include +#include +#include +#include + +#include "Macros.h" +#include "FileReadUtility.h" +#include "Constants.h" + +// No macros can be defined from the command line in the case of C/RTL +// cosimulation, so we define defaults here. +#if !defined MODULE_ + #define MODULE_ MP_L3PHIC_ +#endif +#if !defined TOP_FUNC_ + #define TOP_FUNC_ MatchProcessor_L3PHIC +#endif + +const int nevents = 100; //number of events to run + +using namespace std; + +int main() +{ + // Define memory patterns + const string trackletProjectionPattern = "TrackletProjections*"; + const string allStubPatternarray = "AllStub*"; + const string vmStubPatternarray = "VMStubs_VMSME*"; + const string fullMatchPattern = "FullMatches*"; + + const auto stubMemType = (MODULE_ >= MP_L1PHIA_ && MODULE_ <= MP_L3PHID_) ? BARRELPS : (MODULE_ > MP_D5PHID_) ? BARREL2S : (MODULE_ >= MP_D3PHIA_) ? DISK2S : DISKPS; + const auto tprojMemType = (MODULE_ >= MP_L1PHIA_ && MODULE_ <= MP_L3PHID_) ? BARRELPS : (MODULE_ > MP_D5PHID_) ? BARREL2S : DISK; + const auto fmProjMemType = (MODULE_ >= MP_L1PHIA_ && MODULE_) ? BARREL : DISK; + TBHelper tb(std::string("MP/") + module_name[MODULE_]); + + // error counts + int err = 0; + + /////////////////////////// + // input memories + const auto nTrackletProjections = tb.nFiles(trackletProjectionPattern); + vector> tprojarray(nTrackletProjections); + const auto nAllStub = tb.nFiles(allStubPatternarray); + vector> allstub(nAllStub); + const auto nVMStubs = tb.nFiles(vmStubPatternarray); + VMStubMEMemoryCM vmstub; + + // output memories + const auto nFullMatches = tb.nFiles(fullMatchPattern); + vector > fullmatcharray(nFullMatches); + + // print the input files loaded + std::cout << "Loaded the input files:\n"; + for (unsigned i = 0; i < nTrackletProjections; i++) + std::cout << "\t" << tb.fileNames(trackletProjectionPattern).at(i) << "\n"; + for (unsigned i = 0; i < nAllStub; i++) + std::cout << "\t" << tb.fileNames(allStubPatternarray).at(i) << "\n"; + for (unsigned i = 0; i < nVMStubs; i++) + std::cout << "\t" << tb.fileNames(vmStubPatternarray).at(i) << "\n"; + for (unsigned i = 0; i < nFullMatches; i++) + std::cout << "\t" << tb.fileNames(fullMatchPattern).at(i) << "\n"; + std::cout << std::endl; + + // loop over events + cout << "Start event loop ..." << endl; + for (unsigned int ievt = 0; ievt < nevents; ++ievt) { + cout << "Event: " << dec << ievt << endl; + + // read event and write to memories + auto &fin_TrackletProjections = tb.files(trackletProjectionPattern); + for (unsigned int i = 0; i < nTrackletProjections; i++) + writeMemFromFile>(tprojarray[i], fin_TrackletProjections.at(i), ievt); + auto &fin_AllStub = tb.files(allStubPatternarray); + for (unsigned int i = 0; i < nAllStub; i++) + writeMemFromFile>(allstub[i], fin_AllStub.at(i), ievt); + auto &fin_VMStubs = tb.files(vmStubPatternarray); + writeMemFromFile>(vmstub, fin_VMStubs.at(0), ievt); + + // clear allarray, output memories before starting + for (unsigned int i = 0; i < nFullMatches; i++) + fullmatcharray[i].clear(); + + // bx + BXType bx = ievt; + BXType bx_out; + + // Unit Under Test + TOP_FUNC_(bx, tprojarray.data(), vmstub, allstub.data(), bx_out, fullmatcharray.data()); + + bool truncation = false; + auto &fout_fullmatch = tb.files(fullMatchPattern); + const auto &fullmatch_names = tb.fileNames(fullMatchPattern); + + // compare the computed outputs with the expected ones + for (unsigned int i = 0; i < fullmatch_names.size(); i++) { + const auto &fullmatch_name = fullmatch_names.at(i); + auto &fout = fout_fullmatch.at(i); + string label = "FullMatch " + to_string(i); + err += compareMemWithFile > + (fullmatcharray[i], fout, ievt, label, truncation); + } + + } // end of event loop + + // This is necessary because HLS seems to only return an 8-bit error count, so if err%256==0, the test bench can falsely pass + if (err > 255) err = 255; +// cout << "Module actually has " << err << " errors." << endl; +// return 0; + return err; + +} diff --git a/TopFunctions/CombinedConfig/MatchProcessorTopL3.cc b/TopFunctions/CombinedConfig/MatchProcessorTopL3.cc deleted file mode 100644 index f2b3aa9d4c9..00000000000 --- a/TopFunctions/CombinedConfig/MatchProcessorTopL3.cc +++ /dev/null @@ -1,38 +0,0 @@ -#include "MatchProcessorTopL3.h" - -void MatchProcessorTopL3(BXType bx, - const TrackletProjectionMemory projin[maxTrackletProjections], - const VMStubMEMemoryCM& instubdata, - const AllStubMemory* allstub, - BXType& bx_o, - FullMatchMemory fullmatch[maxFullMatchCopies]) { - - #pragma HLS interface register port=bx_o - for(int i = 0; i < maxTrackletProjections; ++i) { - #pragma HLS unroll - #pragma HLS resource variable=projin[i].get_mem() latency=2 - } - #pragma HLS resource variable=instubdata.get_mem() latency=2 - #pragma HLS resource variable=allstub->get_mem() latency=2 - #pragma HLS resource variable=fullmatch[0].get_mem() latency=2 - #pragma HLS resource variable=fullmatch[1].get_mem() latency=2 - #pragma HLS resource variable=fullmatch[2].get_mem() latency=2 - #pragma HLS resource variable=fullmatch[3].get_mem() latency=2 - #pragma HLS resource variable=fullmatch[4].get_mem() latency=2 - #pragma HLS resource variable=fullmatch[5].get_mem() latency=2 - #pragma HLS resource variable=fullmatch[6].get_mem() latency=2 - #pragma HLS resource variable=fullmatch[7].get_mem() latency=2 - - const auto LAYER = TF::L3; - const auto DISK = TF::D1; - const auto PHISEC = MC::C; - MatchProcessor - (bx, - projin, - instubdata, - allstub, - bx_o, - fullmatch); - -} - diff --git a/TopFunctions/CombinedConfig/MatchProcessorTopL3.h b/TopFunctions/CombinedConfig/MatchProcessorTopL3.h deleted file mode 100644 index b08310fdfb2..00000000000 --- a/TopFunctions/CombinedConfig/MatchProcessorTopL3.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef MATCHENGINETOPL3_H -#define MATCHENGINETOPL3_H - -#include "MatchProcessor.h" - -constexpr int maxTrackletProjections(10); -constexpr int maxFullMatchCopies(8); - -void MatchProcessorTopL3(BXType bx, - const TrackletProjectionMemory projin[maxTrackletProjections], - const VMStubMEMemoryCM& instubdata, - const AllStubMemory* allstub, - BXType& bx_o, - FullMatchMemory fullmatch[maxFullMatchCopies]); - -#endif diff --git a/TrackletAlgorithm/Constants.h b/TrackletAlgorithm/Constants.h index 408486d8626..c34aff8fa4e 100644 --- a/TrackletAlgorithm/Constants.h +++ b/TrackletAlgorithm/Constants.h @@ -30,7 +30,7 @@ constexpr unsigned int kNbitsrfinebintable = 4; // List of module types namespace module { - enum type {UNKNOWN, IR, VMR, TE, TC, PR, ME, MC, NMODULES}; + enum type {UNKNOWN, IR, VMR, TE, TC, PR, ME, MC, MP, NMODULES}; }; // Map from a module type to an offset used to reduce the number of iterations @@ -44,7 +44,8 @@ constexpr unsigned kMaxProcOffset(const module::type m) { (m == module::PR ? 0 : (m == module::ME ? 0 : (m == module::MC ? 0 : - (0))))))); + (m == module::MP ? 0 : + (0)))))))); } // Memory diff --git a/TrackletAlgorithm/MatchEngine.h b/TrackletAlgorithm/MatchEngine.h index eeda7eea18c..d0b2f2377b4 100644 --- a/TrackletAlgorithm/MatchEngine.h +++ b/TrackletAlgorithm/MatchEngine.h @@ -16,9 +16,6 @@ #endif #endif -// HLS Headers -#include "hls_math.h" - // STL Headers #include #include diff --git a/TrackletAlgorithm/MatchEngineUnit.h b/TrackletAlgorithm/MatchEngineUnit.h index 4abe0b4eac5..c19a0475f02 100644 --- a/TrackletAlgorithm/MatchEngineUnit.h +++ b/TrackletAlgorithm/MatchEngineUnit.h @@ -10,13 +10,10 @@ #include "AllStubMemory.h" #include "AllProjectionMemory.h" #include "FullMatchMemory.h" - -#include - #include #include #include -#include "MatchProcessor_parameters.h" +#include "MatchEngineUnit_parameters.h" template static const ap_uint<1 << nbits> hasOneStub() { @@ -50,6 +47,7 @@ class MatchEngineUnit : public MatchEngineUnitBase { stubmask_ = 0; nstubs_ = 0; idle_ = true; + empty_ = true; good_ = false; good__ = false; } @@ -91,6 +89,7 @@ class MatchEngineUnit : public MatchEngineUnitBase { idle_ = false; bx = bxin; istub_ = 0; + unit_ = unit; AllProjection aProj(projbuffer.getAllProj()); projbuffer_ = projbuffer; projindex = projbuffer.getIndex(); @@ -105,7 +104,6 @@ class MatchEngineUnit : public MatchEngineUnitBase { second_ = isSecond[index]; phiPlus_ = isPhiPlus[index]; nstubs_ = nstubsall_[index]; - assert(nstubs_!=0); ivmphi = projbuffer.getPhi(); iphi_ = iphi; auto const qdata=projbuffer_; @@ -156,14 +154,12 @@ inline typename ProjectionRouterBuffer::TCID getTCID( AllProjection allproj(allprojdata); return allproj.getTCID(); } - assert(!idle_||good_||good__); if (good__) { return projbuffer___.getTCID(); } if (good_) { return projbuffer__.getTCID(); } - assert(tcid==projbuffer_.getTCID()); return tcid; } @@ -221,11 +217,10 @@ inline MATCH read() { good_ = idle_ ? false : good_; good_ = nearfull ? false : good_; + + bool process = (!idle_) && (!nearfull); - // vmproj index - //typename VMProjection::VMPZBIN projzbin; - // Buffer still has projections to read out //If the buffer is not empty we have a projection that we need to //process. @@ -283,7 +278,6 @@ inline MATCH read() { second_ = index[0]; phiPlus_ = index[1]; nstubs_ = nstubsall_[index]; - assert(nstubs_!=0); } } else { istub_++; @@ -317,6 +311,7 @@ inline MATCH read() { ap_int<2> shift_; bool idle_; int ivmphi; + int unit_; // only used for debugging to identify MEU ap_uint<3> iphi_; BXType bx; bool empty_; diff --git a/TrackletAlgorithm/MatchProcessor_parameters.h b/TrackletAlgorithm/MatchEngineUnit_parameters.h similarity index 92% rename from TrackletAlgorithm/MatchProcessor_parameters.h rename to TrackletAlgorithm/MatchEngineUnit_parameters.h index 6c64485efc6..b80f798565c 100644 --- a/TrackletAlgorithm/MatchProcessor_parameters.h +++ b/TrackletAlgorithm/MatchEngineUnit_parameters.h @@ -1,5 +1,9 @@ -#ifndef TrackletAlgorithm_MatchProcessor_parameters_h -#define TrackletAlgorithm_MatchProcessor_parameters_h +#ifndef TrackAlgorithm_MatchEngineUnit_parameters_h +#define TrackAlgorithm_MatchEngineUnit_parameters_h + +// This file contains numbers of memories and bit masks that are specific to +// each MEU and that come directly from the wiring. +// template static const ap_uint<(1 << (2 * kNBitsBuffer))> nearFullUnit() { @@ -111,5 +115,4 @@ static const ap_uint<1 << 2*nbits> isLessThanSize() { } return tab; } - #endif diff --git a/TrackletAlgorithm/MatchProcessor.h b/TrackletAlgorithm/MatchProcessor.h index a187a0e8f91..6ff47c89851 100644 --- a/TrackletAlgorithm/MatchProcessor.h +++ b/TrackletAlgorithm/MatchProcessor.h @@ -11,7 +11,6 @@ #include "AllStubMemory.h" #include "FullMatchMemory.h" #include "MatchEngineUnit.h" - #include #include #include @@ -105,11 +104,6 @@ namespace PR constexpr unsigned int zbins_adjust_PSseed = 1; constexpr unsigned int zbins_adjust_2Sseed = 4; - // Number of loop iterations subtracted from the full 108 so that the function - // stays synchronized with other functions in the chain. Once we get these - // functions to rewind correctly, this can be set to zero (or simply removed) - constexpr unsigned int LoopItersCut = 0; - inline void zbinLUTinit(ap_uint<2*MEBinsBits> zbinLUT[128], int zbins_adjust_PSseed, int zbins_adjust_2Sseed){ for(unsigned int ibin=0; ibin<128; ibin++) { @@ -156,7 +150,6 @@ void readTable(ap_uint<1> table[]){ } } -/* FIXME uncomment these out when testing L2,L5, and L6. Need to be added to download.sh to work. if (L==TF::L2) { bool tmp[256]= #include "../emData/ME/tables/METable_L2.tab" @@ -165,7 +158,6 @@ void readTable(ap_uint<1> table[]){ table[i]=tmp[i]; } } -*/ if (L==TF::L3) { bool tmp[256]= @@ -185,7 +177,6 @@ void readTable(ap_uint<1> table[]){ } } -/* if (L==TF::L5) { bool tmp[512]= #include "../emData/ME/tables/METable_L5.tab" @@ -203,7 +194,6 @@ void readTable(ap_uint<1> table[]){ table[i]=tmp[i]; } } -*/ @@ -229,17 +219,17 @@ ap_uint iabs( ap_int value ) // Template to get look up tables // Table for phi or z cuts -template +template void readTable_Cuts(ap_uint table[depth]){ if (phi){ // phi cuts if (L==TF::L1){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L1PHIC_phicut.tab" +#include "../emData/MP/tables/MP_L1PHIC_phicut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else if (L==TF::L2){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L2PHIC_phicut.tab" +#include "../emData/MP/tables/MP_L2PHIC_phicut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else if (L==TF::L3){ @@ -249,17 +239,17 @@ void readTable_Cuts(ap_uint table[depth]){ } else if (L==TF::L4){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L4PHIC_phicut.tab" +#include "../emData/MP/tables/MP_L4PHIC_phicut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else if (L==TF::L5){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L5PHIC_phicut.tab" +#include "../emData/MP/tables/MP_L5PHIC_phicut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else if (L==TF::L6){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L6PHIC_phicut.tab" +#include "../emData/MP/tables/MP_L6PHIC_phicut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else { @@ -269,12 +259,12 @@ void readTable_Cuts(ap_uint table[depth]){ else { // z cuts if (L==TF::L1){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L1PHIC_zcut.tab" +#include "../emData/MP/tables/MP_L1PHIC_zcut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else if (L==TF::L2){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L2PHIC_zcut.tab" +#include "../emData/MP/tables/MP_L2PHIC_zcut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else if (L==TF::L3){ @@ -284,17 +274,17 @@ void readTable_Cuts(ap_uint table[depth]){ } else if (L==TF::L4){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L4PHIC_zcut.tab" +#include "../emData/MP/tables/MP_L4PHIC_zcut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else if (L==TF::L5){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L5PHIC_zcut.tab" +#include "../emData/MP/tables/MP_L5PHIC_zcut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else if (L==TF::L6){ ap_uint tmp[depth] = -#include "../emData/MC/tables/MC_L6PHIC_zcut.tab" +#include "../emData/MP/tables/MP_L6PHIC_zcut.tab" for (int i = 0; i < depth; i++) table[i] = tmp[i]; } else { @@ -313,8 +303,11 @@ void readTable_Cuts(ap_uint table[depth]){ namespace MC { enum imc {UNDEF_ITC, A = 0, B = 1, C = 2, D = 3, E = 4, F = 5, G = 6, H = 7, I = 8, J = 9, K = 10, L = 11, M = 12, N = 13, O = 14}; } +template constexpr bool FMMask(); +template constexpr uint32_t FMMask(); +#include "MatchProcessor_parameters.h" -template +template void MatchCalculator(BXType bx, ap_uint<1> newtracklet, ap_uint<1>& savedMatch, @@ -354,9 +347,9 @@ void MatchCalculator(BXType bx, const auto kFact = (LAYER < TF::L4)? 1 : (1<<(kNbitszprojL123-kNbitszprojL456)); // fact_ in emulation defined in MC const auto kPhi0_shift = (LAYER < TF::L4)? 3 : 0; // phi0shift_ in emulation defined in MC - constexpr int kShift_phi0bit = 1; // phi0bitshift in emulation defined in constants + const auto kShift_phi0bit = 1; // phi0bitshift in emulation defined in constants const ap_uint<10> kPhi_corr_shift_L123 = 7 + kNbitsdrinv + kShift_phi0bit - kShift_Rinv - kShift_Phider; // icorrshift for L123 - const ap_uint<10> kPhi_corr_shift_L456 = kPhi_corr_shift_L123 - 10 - kNbitsrL456; // icorrshift for L456 + const ap_uint<10> kPhi_corr_shift_L456 = kPhi_corr_shift_L123 - 10 + kNbitsrL456; // icorrshift for L456 const auto kPhi_corr_shift = (LAYER < TF::L4)? kPhi_corr_shift_L123 : kPhi_corr_shift_L456; // icorrshift_ in emulation const ap_uint<10> kZ_corr_shiftL123 = (-1-kShift_PS_zderL); // icorzshift for L123 (6 in L3) const ap_uint<10> kZ_corr_shiftL456 = (-1-kShift_2S_zderL + kNbitszprojL123 - kNbitszprojL456 + kNbitsrL456 - kNbitsrL123); // icorzshift for L456 @@ -412,7 +405,7 @@ void MatchCalculator(BXType bx, ap_int<10> delta_z = stub_z - proj_z_corr; ap_int<14> delta_z_fact = delta_z * kFact; ap_int<18> stub_phi_long = stub_phi; // make longer to allow for shifting - ap_int<18> proj_phi_long = proj_phi_corr; // make longer to allow for shifting + const ap_int<18> &proj_phi_long = proj_phi_corr; // make longer to allow for shifting ap_int<18> shiftstubphi = stub_phi_long << kPhi0_shift; // shift ap_int<18> shiftprojphi = proj_phi_long << (kShift_phi0bit - 1 + kPhi0_shift); // shift ap_int<17> delta_phi = shiftstubphi - shiftprojphi; @@ -430,7 +423,7 @@ void MatchCalculator(BXType bx, // Full match typename AllProjection::AProjTCSEED projseed_next; - FullMatch fm(fm_tcid,fm_tkid,(ap_uint<3>(2),fm_asid),fm_stubr,fm_phi,fm_z); + FullMatch fm(fm_tcid,fm_tkid,fm_asphi,fm_asid,fm_stubr,fm_phi,fm_z); //----------------------------------------------------------------------------------------------------------- //-------------------------------------- BEST MATCH LOGIC BLOCK --------------------------------------------- @@ -452,41 +445,57 @@ void MatchCalculator(BXType bx, // Store bestmatch goodmatch = true; } - + if(goodmatch) { // Write out only the best match, based on the seeding switch (proj_seed) { case 0: - fullmatch[0].write_mem(bx,fm,nmcout1-savedMatch); // L1L2 seed + if(FMMask()) { + fullmatch[FMCount()].write_mem(bx,fm,nmcout1-savedMatch); // L1L2 seed nmcout1+=1-savedMatch; - break; + } + break; case 1: - fullmatch[1].write_mem(bx,fm,nmcout2-savedMatch); // L2L3 seed + if(FMMask()) { + fullmatch[FMCount()].write_mem(bx,fm,nmcout2-savedMatch); // L2L3 seed nmcout2+=1-savedMatch; - break; + } + break; case 2: - fullmatch[2].write_mem(bx,fm,nmcout3-savedMatch); // L3L4 seed + if(FMMask()) { + fullmatch[FMCount()].write_mem(bx,fm,nmcout3-savedMatch); // L3L4 seed nmcout3+=1-savedMatch; - break; + } + break; case 3: - fullmatch[3].write_mem(bx,fm,nmcout4-savedMatch); // L5L6 seed + if(FMMask()) { + fullmatch[FMCount()].write_mem(bx,fm,nmcout4-savedMatch); // L5L6 seed nmcout4+=1-savedMatch; - break; + } + break; case 4: - fullmatch[4].write_mem(bx,fm,nmcout5-savedMatch); // D1D2 seed + if(FMMask()) { + fullmatch[FMCount()].write_mem(bx,fm,nmcout5-savedMatch); // D1D2 seed nmcout5+=1-savedMatch; - break; + } + break; case 5: - fullmatch[5].write_mem(bx,fm,nmcout6-savedMatch); // D3D4 seed + if(FMMask()) { + fullmatch[FMCount()].write_mem(bx,fm,nmcout6-savedMatch); // D3D4 seed nmcout6+=1-savedMatch; - break; + } + break; case 6: - fullmatch[6].write_mem(bx,fm,nmcout7-savedMatch); // L1D1 seed + if(FMMask()) { + fullmatch[FMCount()].write_mem(bx,fm,nmcout7-savedMatch); // L1D1 seed nmcout7+=1-savedMatch; - break; + } + break; case 7: - fullmatch[7].write_mem(bx,fm,nmcout8-savedMatch); // L2D1 seed + if(FMMask()) { + fullmatch[FMCount()].write_mem(bx,fm,nmcout8-savedMatch); // L2D1 seed nmcout8+=1-savedMatch; - break; + } + break; } savedMatch = 1; } @@ -517,7 +526,7 @@ void MatchProcessor(BXType bx, //Initialize table for bend-rinv consistency ap_uint<1> table[kNMatchEngines][(LAYER(table[iMEU]); } @@ -572,6 +581,7 @@ void MatchProcessor(BXType bx, MatchEngineUnit matchengine[kNMatchEngines]; #pragma HLS ARRAY_PARTITION variable=matchengine complete dim=0 #pragma HLS ARRAY_PARTITION variable=instubdata complete dim=1 +#pragma HLS ARRAY_PARTITION variable=projin dim=1 #pragma HLS ARRAY_PARTITION variable=numbersin complete dim=0 #pragma HLS dependence variable=istub inter false @@ -598,7 +608,7 @@ void MatchProcessor(BXType bx, nvmstubs[izbin][3],nvmstubs[izbin][2],nvmstubs[izbin][1],nvmstubs[izbin][0]) = instubdata.getEntries8(bx, izbin); } - PROC_LOOP: for (unsigned int istep = 0; istep < kMaxProc-LoopItersCut; ++istep) { + PROC_LOOP: for (ap_uint istep = 0; istep < kMaxProc - kMaxProcOffset(module::MP); istep++) { #pragma HLS PIPELINE II=1 //rewind auto readptr = projbufferarray.getReadPtr(); @@ -619,7 +629,7 @@ void MatchProcessor(BXType bx, bool anyidle = false; - MEU_get_trkids: for(unsigned int iMEU = 0; iMEU < kNMatchEngines; ++iMEU) { + MEU_get_trkids: for(int iMEU = 0; iMEU < kNMatchEngines; ++iMEU) { #pragma HLS unroll matchengine[iMEU].set_empty(); idles[iMEU] = matchengine[iMEU].idle(); @@ -627,13 +637,22 @@ void MatchProcessor(BXType bx, emptys[iMEU] = matchengine[iMEU].empty(); trkids[iMEU] = matchengine[iMEU].getTrkID(); } - + + //This printout exactly matches printout in emulation for tracking code differences + /* + std::cout << "istep = " << istep << " projBuff: " << readptr << " " << writeptr << " " << projBuffNearFull; + for(int iMEU = 0; iMEU < kNMatchEngines; ++iMEU) { + std::cout << " MEU"< smallest = ~emptys; #pragma HLS ARRAY_PARTITION variable=trkids complete dim=0 - MEU_smallest1: for(unsigned int iMEU1 = 0; iMEU1 < kNMatchEngines-1; ++iMEU1) { + MEU_smallest1: for(int iMEU1 = 0; iMEU1 < kNMatchEngines-1; ++iMEU1) { #pragma HLS unroll - MEU_smallest2: for(unsigned int iMEU2 = iMEU1+1; iMEU2 < kNMatchEngines; ++iMEU2) { + MEU_smallest2: for(int iMEU2 = iMEU1+1; iMEU2 < kNMatchEngines; ++iMEU2) { #pragma HLS unroll smallest[iMEU1] = smallest[iMEU1] & (trkids[iMEU1] shift = 0; @@ -793,14 +812,14 @@ void MatchProcessor(BXType bx, nstublastMinus = 0; nstublastPlus = 0; } - + ap_uint<16> nstubs=(nstublastPlus, nstubfirstPlus, nstublastMinus, nstubfirstMinus); VMProjection vmproj(index, zbin, finez, finephi, rinv, psseed); AllProjection allproj(projdata_.getTCID(), projdata_.getTrackletIndex(), projdata_.getPhi(), projdata_.getRZ(), projdata_.getPhiDer(), projdata_.getRZDer()); - if (nstubs!=0) { + if (nstubs!=0) { ProjectionRouterBuffer projbuffertmp(allproj.raw(), ivmMinus, shift, trackletid, nstubs, zfirst, vmproj, psseed); projbufferarray.addProjection(projbuffertmp); } diff --git a/TrackletAlgorithm/ProjectionRouterBufferArray.h b/TrackletAlgorithm/ProjectionRouterBufferArray.h index 790feab15f4..1ff2bd4b35f 100644 --- a/TrackletAlgorithm/ProjectionRouterBufferArray.h +++ b/TrackletAlgorithm/ProjectionRouterBufferArray.h @@ -2,7 +2,7 @@ #define PRBUFFERARRAY_HH #include "ProjectionRouterBuffer.h" -#include "MatchProcessor_parameters.h" +#include "MatchEngineUnit_parameters.h" template class ProjectionRouterBufferArray { public: diff --git a/emData/download.sh b/emData/download.sh index 0d5256b0fc7..0fbacaa484d 100755 --- a/emData/download.sh +++ b/emData/download.sh @@ -9,6 +9,16 @@ set -e memprints_url_reduced="https://cernbox.cern.ch/index.php/s/LkVZR8WRYGPJcPe/download" luts_url_reduced="https://cernbox.cern.ch/index.php/s/2zppC0iJ3eEy5C9/download" +#### test 211005/211217 #### +# Standard configuration +#memprints_url="https://aryd.web.cern.ch/aryd/MemPrints_Standard_211005.tgz" +#luts_url="https://aryd.web.cern.ch/aryd/LUTs_Standard_211005.tgz" +# Combined modules +#memprints_url_cm="https://aryd.web.cern.ch/aryd/MemPrints_Combined_211217.tgz" +#luts_url_cm="https://aryd.web.cern.ch/aryd/LUTs_Combined_211217.tgz" + + + #### fw_synch_210611 #### # Standard configuration memprints_url="https://cernbox.cern.ch/index.php/s/hUJUsqvCnKv2YdQ/download" @@ -139,7 +149,18 @@ declare -a processing_modules=( "MC_L6PHIC" # MatchProcessor + "MP_L1PHIB" + "MP_L2PHIB" + "MP_L3PHIB" + "MP_L4PHIB" + "MP_L5PHIB" + "MP_L6PHIB" + "MP_L1PHIC" + "MP_L2PHIC" "MP_L3PHIC" + "MP_L4PHIC" + "MP_L5PHIC" + "MP_L6PHIC" # TrackBuilder (aka FitTrack) "FT_L1L2" @@ -263,6 +284,7 @@ mkdir -p ../TopFunctions/ReducedConfig mkdir -p ../TopFunctions/CombinedConfig ./generate_VMRCM.py -d -w LUTsCM/wires.dat -o ../TopFunctions/CombinedConfig ./generate_TP.py -w LUTsCM/wires.dat -o ../TopFunctions/CombinedConfig +./generate_MP.py -w LUTsCM/wires.dat -o ../TopFunctions/CombinedConfig # Exit now if we are only downloading and unpacking LUTs.tar.gz. if [[ $tables_only != 0 ]] diff --git a/emData/generate_MP.py b/emData/generate_MP.py new file mode 100755 index 00000000000..fd0408a9f9b --- /dev/null +++ b/emData/generate_MP.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python + +# This script generates MatchProcessor_parameters.h, +# MatchProcessorTop.h, and MatchProcessorTop.cc in the +# TrackletAlgorithm/ directory. Currently supports all MPs for L3_PHIC. + +from __future__ import absolute_import +from __future__ import print_function +import os +import re +import sys +import argparse + +TF_index = ['L1L2', 'L2L3', 'L3L4', 'L5L6', 'D1D2', 'D3D4', 'L1D1', 'L2D1'] +TF_index = {k:v for v,k in enumerate(TF_index)} + +maxTPMems = "constexpr int maxTPMemories[" +maxFMMems = "constexpr int maxFMMemories[" + +def ASRegion(region): + if region in ['L1', 'L2', 'L3']: + return 'BARRELPS' + elif region in ['L4', 'L5', 'L6']: + return 'BARREL2S' + else: + return 'DISK' + +def APRegion(region): + if region in ['L1', 'L2', 'L3']: + return 'BARRELPS' + elif region in ['L4', 'L5', 'L6']: + return 'BARREL2S' + else: + return 'DISK' + + +def VMStubMERegion(region): + if region in ['L1', 'L2', 'L3']: + return 'BARRELPS' + elif region in ['L4', 'L5', 'L6']: + return 'BARREL2S' + else: + return 'DISK' + +def getTProjAndVMRegions(module): + if any(psword in module for psword in ["L1","L2","L3"]): TProjRegion = "BARRELPS" + elif any(psword in module for psword in ["L4","L5","L6"]): TProjRegion = "BARREL2S" + else: TProjRegion = "DISK" + + if any(psword in module for psword in ["L1","L2","L3","L4","L5","L6"]): VMProjRegion = "BARREL" + else: VMProjRegion = "DISK" + + if any(psword in module for psword in ["L1","L2","L3"]): VMStubRegion = "BARRELPS" + elif any(psword in module for psword in ["L4","L5","L6"]): VMStubRegion = "BARREL2S" + else: VMStubRegion = "DISK" + + return TProjRegion, VMProjRegion, VMStubRegion + +def FMRegion(region): + if region in ['L1', 'L2', 'L3', 'L4', 'L5', 'L6']: + return 'BARREL' + else: + return 'DISK' + +parser = argparse.ArgumentParser(description="This script generates MatchCalculatorTop.h, MatchCalculatorTop.cc, and\ +MatchCalculator_parameters.h in the TopFunctions/ directory.", + epilog="") +parser.add_argument("-o", "--outputDirectory", metavar="DIR", default="../TopFunctions/", type=str, help="The directory in which to write the output files (default=%(default)s)") +parser.add_argument("-w", "--wiresFileName", metavar="WIRES_FILE", default="LUTs/wires.dat", type=str, help="Name and directory of the configuration file for wiring (default = %(default)s)") +arguments = parser.parse_args() + +# First, parse the wires file and store the memory names associated with MPs in +# dictionaries with the MP names as keys. +with open(arguments.wiresFileName) as wiresFile: + TPMems = {} + FMMems = {} + for line in wiresFile: + # Only barrel-only seeds are supported right now. + if "MP_D" in line: + continue # No disks for now + line = line.rstrip() + mpName = re.sub(r".*MP_(......).*", r"MP_\1", line) + memName = line.split()[0] + if memName.startswith("TPROJ_"): + if mpName not in TPMems: + TPMems[mpName] = [] + TPMems[mpName].append(memName) + if memName.startswith("FM_"): + FM = re.sub(r"FM_(....)_......", r"\1", memName) + if mpName not in FMMems: + FMMems[mpName] = [] + FMMems[mpName].append(FM) + +# Open and print out preambles for the parameters and top files. +dirname = os.path.dirname(os.path.realpath('__file__')) +with open(os.path.join(dirname, arguments.outputDirectory, "MatchProcessor_parameters.h"), "w") as parametersFile, \ + open(os.path.join(dirname, arguments.outputDirectory, "MatchProcessorTop.h"), "w") as topHeaderFile, \ + open(os.path.join(dirname, arguments.outputDirectory, "MatchProcessorTop.cc"), "w") as topFile: + + parametersFile.write( + "#ifndef TrackletAlgorithm_MatchProcessor_parameters_h\n" + "#define TrackletAlgorithm_MatchProcessor_parameters_h\n" + "\n" + "// This file contains numbers of memories and bit masks that are specific to\n" + "// each MatchProcessor and that come directly from the wiring.\n" + "//\n" + "// The validity of each of the barrel Tracklet Parameter memories is determined by\n" + "// FMMask. The bits of this mask, from least significant to most\n" + "// significant, represent the memories in the order they are passed to\n" + "// MatchProcessor; e.g., the LSB corresponds to\n" + "// TF::L1L2. If a bit is set, the corresponding memory is\n" + "// valid, if it is not, the corresponding memory is not valid.\n" + ) + topHeaderFile.write( + "#ifndef TrackletAlgorithm_MatchProcessorTop_h\n" + "#define TrackletAlgorithm_MatchProcessorTop_h\n" + "\n" + "#include \"MatchProcessor.h\"\n" + "\n" + ) + topFile.write( + "#include \"MatchProcessorTop.h\"\n" + "\n" + "////////////////////////////////////////////////////////////////////////////////\n" + "// Top functions for various MatchProcessors (MP). For each iteration of\n" + "// the main processing loop, a MP retrieves an array of Traklet Projections,\n" + "// and computes Full Matches from each.\n" + "////////////////////////////////////////////////////////////////////////////////\n" + ) + + maxTPMems += str(len(TPMems.keys())) + "] = {" + maxFMMems += str(len(TPMems.keys())) + "] = {" + + # Calculate parameters and print out parameters and top function for each MP. + for mpName in sorted(TPMems.keys()): + seed = re.sub(r"MP_(..)....", r"\1", mpName) + iMP = re.sub(r"MP_.....(.)", r"\1", mpName) + + # numbers of memories + nTPMem = len(TPMems[mpName]) + nFMMem = len(FMMems[mpName]) + FMMask = 0 + for FM in FMMems[mpName]: + FMMask = FMMask | (1 << TF_index[FM]) + + maxTPMems += seed + "PHI" + iMP + "maxTrackletProjections" + maxFMMems += seed + "PHI" + iMP + "maxFullMatchCopies" + if mpName != sorted(TPMems.keys())[-1]: + maxTPMems += ",\n " + maxFMMems += ",\n " + + # Print out parameters for this MP. + parametersFile.write( + "\n" + "// magic numbers for " + mpName + "\n" + "template<> constexpr uint32_t FMMask() {\n" + " return 0x%X;\n" + "}\n" % FMMask + ) + + TProjRegion, VMProjRegion, VMStubRegion = getTProjAndVMRegions(seed) + # Print out prototype for top function for this MP. + topHeaderFile.write( + "\n" + "constexpr int " + seed + "PHI" + iMP + "maxTrackletProjections(" + str(nTPMem) + ");\n" + "constexpr int " + seed + "PHI" + iMP + "maxFullMatchCopies(" + str(nFMMem) + ");\n" + "\n" + "void MatchProcessor_" + seed + "PHI" + iMP + "(\n" + " const BXType bx,\n" + " const TrackletProjectionMemory<" + TProjRegion + "> projin[" + seed + "PHI" + iMP + "maxTrackletProjections],\n" + " const VMStubMEMemoryCM<" + VMStubMERegion(seed) + ", 3, 3, kNMatchEngines>& instubdata,\n" + " const AllStubMemory<" + ASRegion(seed) + ">* allstub,\n" + " BXType& bx_o,\n" + " FullMatchMemory<" + FMRegion(seed) + "> fullmatch[" + seed + "PHI" + iMP + "maxFullMatchCopies]\n" + ");\n" + ) + + # Print out definition of top function for this MP. + topFile.write( + "\n" + "void MatchProcessor_" + seed + "PHI" + iMP + "(\n" + " const BXType bx,\n" + " const TrackletProjectionMemory<" + TProjRegion + "> projin[" + seed + "PHI" + iMP + "maxTrackletProjections],\n" + " const VMStubMEMemoryCM<" + VMStubMERegion(seed) + ", 3, 3, kNMatchEngines>& instubdata,\n" + " const AllStubMemory<" + ASRegion(seed) + ">* allstub,\n" + " BXType& bx_o,\n" + " FullMatchMemory<" + FMRegion(seed) + "> fullmatch[" + seed + "PHI" + iMP + "maxFullMatchCopies]\n" + ") {\n" + "#pragma HLS inline off\n" + "#pragma HLS interface register port=bx_o\n" + ) + if nTPMem == 1: + topFile.write("#pragma HLS resource variable=projin.get_mem() latency=2\n") + else: + for i in range(nTPMem): + topFile.write("#pragma HLS resource variable=projin[" + str(i) + "].get_mem() latency=2\n") + if nFMMem == 1: + topFile.write("#pragma HLS resource variable=fullmatch.get_mem() latency=2\n") + else: + for i in range(nFMMem): + topFile.write("#pragma HLS resource variable=fullmatch[" + str(i) + "].get_mem() latency=2\n") + topFile.write( + "#pragma HLS resource variable=allstub->get_mem() latency=2\n" + "#pragma HLS resource variable=instubdata.get_mem() latency=2\n" + "\n" + "MP_" + seed + "PHI" + iMP + ": MatchProcessor<" + "" + TProjRegion + ", " + VMStubRegion + ", " + VMProjRegion + ", " + ASRegion(seed) + ", " + APRegion(seed) + ", " + FMRegion(seed) + ", " + seed + "PHI" + iMP + "maxTrackletProjections" + ", " + seed + "PHI" + iMP + "maxFullMatchCopies" + ",\n" + " TF::" + seed + ", " + "TF::" + "D1" + ", " + "MC::" + iMP + "> (\n" + " bx,\n" + " projin,\n" + " instubdata,\n" + " allstub,\n" + " bx_o,\n" + " fullmatch\n" + " );\n" + "}\n" + ) + + # Print out endifs and close files. + parametersFile.write( + "\n" + "// return mask bit AND mask\n" + "template constexpr bool FMMask() {\n" + " return FMMask() & (1<\n" + "static const ap_uint<1 << Seed> FMCount() {\n" + " ap_uint<1< bits(-1);\n" + " ap_uint<1< mask = bits & FMMask();\n" + " int slot = 0;\n" + " for(int i = 0; i < Seed; ++i) {\n" + " slot += mask.range(i,i);\n" + " }\n" + " return slot;\n" + "}\n\n" + "#endif\n" + ) + topHeaderFile.write( + "\n" + maxTPMems + "};\n" + "\n" + maxFMMems + "};\n" + "\n" + "\n#endif\n" + ) + topFile.write( + "\n" + "////////////////////////////////////////////////////////////////////////////////\n" + ) diff --git a/project/script_MP.tcl b/project/script_MP.tcl index 1ca4e0e8e74..c1dbb15c5d2 100644 --- a/project/script_MP.tcl +++ b/project/script_MP.tcl @@ -1,34 +1,62 @@ -# Script to generate project for PR -# vivado_hls -f script_PR.tcl +# Script to generate project for MP +# vivado_hls -f script_MP.tcl # vivado_hls -p match_processor # WARNING: this will wipe out the original project by the same name # get some information about the executable and environment source env_hls.tcl +set modules_to_test { + {MP_L1PHIC} + {MP_L2PHIC} + {MP_L3PHIC} + {MP_L4PHIC} + {MP_L5PHIC} + {MP_L6PHIC} +} +# module_to_export must correspond to the default macros set at the top of the +# test bench; otherwise, the C/RTL cosimulation will fail +set module_to_export MP_L3PHIC + # create new project (deleting any existing one of same name) open_project -reset match_processor # source files set CFLAGS {-std=c++11 -I../TrackletAlgorithm -I../TopFunctions/CombinedConfig} -set_top MatchProcessorTopL3 -add_files ../TopFunctions/CombinedConfig/MatchProcessorTopL3.cc -cflags "$CFLAGS" -add_files -tb ../TestBenches/MatchProcessorL3_test.cpp -cflags "$CFLAGS" - -open_solution "solution1" - -# Define FPGA, clock frequency & common HLS settings. -source settings_hls.tcl +add_files ../TopFunctions/CombinedConfig/MatchProcessorTop.cc -cflags "$CFLAGS" +add_files -tb ../TestBenches/MatchProcessor_test.cpp -cflags "$CFLAGS" # data files -add_files -tb ../emData/MP/tables/ -add_files -tb ../emData/MP/MP_L3PHIC/ - -csim_design -mflags "-j8" -csynth_design -cosim_design -export_design -format ip_catalog -# Adding "-flow impl" runs full Vivado implementation, providing accurate resource use numbers (very slow). -#export_design -format ip_catalog -flow impl +add_files -tb ../emData/MP/ + +foreach i $modules_to_test { + set layerDisk [string range $i 3 4] + set iMP [string range $i 8 9] + set top_func [join [list "MatchProcessor_" $layerDisk "PHI" $iMP] ""] + puts [join [list "======== TESTING " $i " ========"] ""] + puts [join [list "layerDisk = " $layerDisk] ""] + puts [join [list "iMP = " $iMP] ""] + puts [join [list "top function = " $top_func] ""] + + # set macros for this module in CCFLAG environment variable + set ::env(CCFLAG) [join [list "-D \"MODULE_=" $i "_\" -D \"TOP_FUNC_=" $top_func "\""] ""] + + # run C-simulation for each module in modules_to_test + set_top $top_func + open_solution [join [list "solution_" $layerDisk $iMP] ""] + + # Define FPGA, clock frequency & common HLS settings. + source settings_hls.tcl + csim_design -mflags "-j8" + + # only run C-synthesis, C/RTL cosimulation, and export for module_to_export + if { $i == $module_to_export } { + csynth_design + cosim_design + export_design -format ip_catalog + # Adding "-flow impl" runs full Vivado implementation, providing accurate resource use numbers (very slow). + #export_design -format ip_catalog -flow impl + } +} exit