Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:56:11

0001 #include "L1Trigger/TrackerTFP/interface/Demonstrator.h"
0002 
0003 #include <vector>
0004 #include <string>
0005 #include <sstream>
0006 #include <fstream>
0007 
0008 using namespace std;
0009 using namespace edm;
0010 using namespace tt;
0011 
0012 namespace trackerTFP {
0013 
0014   Demonstrator::Demonstrator(const ParameterSet& iConfig, const Setup* setup)
0015       : dirIPBB_(iConfig.getParameter<string>("DirIPBB")),
0016         runTime_(iConfig.getParameter<double>("RunTime")),
0017         dirIn_(dirIPBB_ + "in.txt"),
0018         dirOut_(dirIPBB_ + "out.txt"),
0019         dirPre_(dirIPBB_ + "pre.txt"),
0020         dirDiff_(dirIPBB_ + "diff.txt"),
0021         numFrames_(setup->numFramesIO()),
0022         numFramesInfra_(setup->numFramesInfra()),
0023         numRegions_(setup->numRegions()) {}
0024 
0025   // plays input through modelsim and compares result with output
0026   bool Demonstrator::analyze(const vector<vector<Frame>>& input, const vector<vector<Frame>>& output) const {
0027     stringstream ss;
0028     // converts input into stringstream
0029     convert(input, ss);
0030     // play input through modelsim
0031     sim(ss);
0032     // converts output into stringstream
0033     convert(output, ss);
0034     // compares output with modelsim output
0035     return compare(ss);
0036   }
0037 
0038   // converts streams of bv into stringstream
0039   void Demonstrator::convert(const vector<vector<Frame>>& bits, stringstream& ss) const {
0040     // reset ss
0041     ss.str("");
0042     ss.clear();
0043     // number of tranceiver in a quad
0044     static constexpr int quad = 4;
0045     const int numChannel = bits.size() / numRegions_;
0046     const int voidChannel = numChannel % quad == 0 ? 0 : quad - numChannel % quad;
0047     // start with header
0048     ss << header(numChannel + voidChannel);
0049     int nFrame(0);
0050     // create one packet per region
0051     bool first = true;
0052     for (int region = 0; region < numRegions_; region++) {
0053       const int offset = region * numChannel;
0054       // start with emp 6 frame gap
0055       ss << infraGap(nFrame, numChannel + voidChannel);
0056       for (int frame = 0; frame < numFrames_; frame++) {
0057         // write one frame for all channel
0058         ss << this->frame(nFrame);
0059         for (int channel = 0; channel < numChannel; channel++) {
0060           const vector<Frame>& bvs = bits[offset + channel];
0061           ss << (frame < (int)bvs.size() ? hex(bvs[frame], first) : hex(Frame(), first));
0062         }
0063         for (int channel = 0; channel < voidChannel; channel++)
0064           ss << "  0000 " << string(TTBV::S_ / 4, '0');
0065         ss << endl;
0066         first = false;
0067       }
0068     }
0069   }
0070 
0071   // plays stringstream through modelsim
0072   void Demonstrator::sim(const stringstream& ss) const {
0073     // write ss to disk
0074     fstream fs;
0075     fs.open(dirIn_.c_str(), fstream::out);
0076     fs << ss.rdbuf();
0077     fs.close();
0078     // run modelsim
0079     stringstream cmd;
0080     cmd << "cd " << dirIPBB_ << " && ./run_sim -quiet -c work.top -do 'run " << runTime_
0081         << "us' -do 'quit' &> /dev/null";
0082     system(cmd.str().c_str());
0083   }
0084 
0085   // compares stringstream with modelsim output
0086   bool Demonstrator::compare(stringstream& ss) const {
0087     // write ss to disk
0088     fstream fs;
0089     fs.open(dirPre_.c_str(), fstream::out);
0090     fs << ss.rdbuf();
0091     fs.close();
0092     // use linux diff on disk
0093     const string c = "diff " + dirPre_ + " " + dirOut_ + " &> " + dirDiff_;
0094     system(c.c_str());
0095     ss.str("");
0096     ss.clear();
0097     // read diff output
0098     fs.open(dirDiff_.c_str(), fstream::in);
0099     ss << fs.rdbuf();
0100     fs.close();
0101     // count lines, 4 are expected
0102     int n(0);
0103     string token;
0104     while (getline(ss, token))
0105       n++;
0106     return n == 4;
0107   }
0108 
0109   // creates emp file header
0110   string Demonstrator::header(int numLinks) const {
0111     stringstream ss;
0112     // file header
0113     ss << "Board CMSSW" << endl
0114        << "Metadata: (strobe,) start of orbit, start of packet, end of packet, valid" << endl
0115        << endl;
0116     // link header
0117     ss << "      Link :";
0118     for (int link = 0; link < numLinks; link++)
0119       ss << "            " << setfill('0') << setw(3) << link << "        ";
0120     ss << endl;
0121     return ss.str();
0122   }
0123 
0124   // creates 6 frame gap between packets
0125   string Demonstrator::infraGap(int& nFrame, int numLinks) const {
0126     stringstream ss;
0127     for (int gap = 0; gap < numFramesInfra_; gap++) {
0128       ss << frame(nFrame);
0129       for (int link = 0; link < numLinks; link++)
0130         ss << "  0000 " << string(TTBV::S_ / 4, '0');
0131       ss << endl;
0132     }
0133     return ss.str();
0134   }
0135 
0136   // creates frame number
0137   string Demonstrator::frame(int& nFrame) const {
0138     stringstream ss;
0139     ss << "Frame " << setfill('0') << setw(4) << nFrame++ << " :";
0140     return ss.str();
0141   }
0142 
0143   // converts bv into hex
0144   string Demonstrator::hex(const Frame& bv, bool first) const {
0145     stringstream ss;
0146     ss << (first ? "  1001 " : "  0001 ") << setfill('0') << setw(TTBV::S_ / 4) << std::hex << bv.to_ullong();
0147     return ss.str();
0148   }
0149 
0150 }  // namespace trackerTFP