void randomizeVector(LocationVector& V) { int n = V.size(); int n2 = (int)(n/2); int rand_index = 0; for(int i = 0; i < n2;) { rand_index = rand() % n; if(!V[rand_index]) { V[rand_index] = true; i++; } } }
void PSU1Rules::BuildGenericSignal(const GenericTupleVector& genericTupleVec) { std::cout << "BUILDING Generic Signals " << std::endl; for(uint16_t idx=0; idx<genericTupleVec.size(); ++idx) { // get all port.channel locations LocationVector lv = genericTupleVec[idx].get<0>(); // iterate through all locations and assign signal for(uint16_t jdx=0; jdx<lv.size(); ++jdx) { ports_[ChIndex(lv,jdx)] = genericTupleVec[idx].get<1>(); } } }
void PSU1Rules::BuildCodeSignal(const CodeTupleVector& codeTupleVec, const TrTupleVector& trTupleVec, const double bauda) { std::cout << "BUILDING CODE Signal " << std::endl; LocationVector lv = codeTupleVec[0].get<0>(); const Pattern pattern = codeTupleVec[0].get<1>(); const uint16_t pre_baud = round(trTupleVec[0].get<1>()/bauda); for(uint16_t idx=0; idx<lv.size(); ++idx) { const uint16_t ch_idx = ChIndex(lv,idx); ports_[ch_idx].resize(pre_baud+pattern.size()); for(uint16_t jdx=0; jdx<pattern.size(); ++jdx) { const uint16_t code_offset = pre_baud + jdx; ports_[ch_idx][code_offset] = pattern[jdx]; } } }
void PSU1Rules::BuildTxaSignal(const TxaTupleVector& txaTupleVec, const TrTupleVector& trTupleVec, const double txa, const double bauda) { std::cout << "BUILDING TXA Signal " << std::endl; LocationVector lv = txaTupleVec[0].get<0>(); const uint16_t pre_baud = round(trTupleVec[0].get<1>()/bauda); const double txa_baud = round(txa/bauda); for(uint16_t idx=0; idx<lv.size(); ++idx) { const uint16_t ch_idx = ChIndex(lv,idx); ports_[ch_idx].resize(pre_baud + txa_baud); for(uint16_t jdx=0; jdx<txa_baud; ++jdx) { const uint16_t txa_offset = jdx + pre_baud; ports_[ch_idx].set(txa_offset,true); } } }
void PSU1Rules::BuildTrSignal(const TrTupleVector& trTupleVec, const double txa, const double bauda) { std::cout << "BUILDING TR Signal " << std::endl; const uint16_t pre_baud = round(trTupleVec[0].get<1>()/bauda); const uint16_t post_baud = round(trTupleVec[0].get<2>()/bauda); const uint16_t txa_baud = round(txa/bauda); const uint16_t tr_baud = pre_baud + txa_baud + post_baud; LocationVector lv = trTupleVec[0].get<0>(); for(uint16_t idx=0; idx<lv.size(); ++idx) { const uint16_t ch_idx = ChIndex(lv,idx); ports_[ch_idx].resize(tr_baud); for(uint16_t jdx=0; jdx<tr_baud; ++jdx) { ports_[ch_idx].set(jdx,true); } } }
void PSU1Rules::BuildSaSignal(const SaTupleVector& saTupleVec, const TrTupleVector& trTupleVec, const double bauda) { std::cout << "BUILDING SA (Receive Window) Signal " << std::endl; for(uint16_t idx =0; idx<saTupleVec.size(); ++idx) { // get all port.channel locations LocationVector lv = saTupleVec[idx].get<0>(); bool isNeg = saTupleVec[idx].get<1>(); // convert to baud const uint16_t h0_baud = round(saTupleVec[idx].get<2>()/bauda); const uint16_t hf_baud = round(saTupleVec[idx].get<3>()/bauda); const uint16_t pre_baud = round(trTupleVec[0].get<1>()/bauda); //window's point of reference is TXA and not t=0 since we //are using a TR window to protect the receivers (i.e. add pre offset) const uint16_t h0_offset = h0_baud + pre_baud; const uint16_t hf_offset = hf_baud + pre_baud; for(uint16_t jdx=0; jdx<lv.size(); ++jdx) { const uint16_t ch_jdx = ChIndex(lv,jdx); ports_[ch_jdx].resize(hf_offset); // enable signal for defined receive window for(uint16_t kdx=h0_offset; kdx<hf_offset; ++kdx) { ports_[ch_jdx][kdx]=true; } // invert signal if negate set if(isNeg) { ports_[ch_jdx].flip(); } } } }
bool PSU1Rules::Verify() { //store all locations and compare to //ensure unique assignments LocationVector globalLocations; //contains tuple<LocationVector, Pattern, double> //single entry const CodeTupleVector& codeTupleVec = codeKey.GetTupleRef(); //contains tuple<LocationVector, double, double> //single entry const TrTupleVector& trTupleVec = trKey.GetTupleRef(); //contains tuple<LocationVector, double> //single entry const TxaTupleVector& txaTupleVec = txaKey.GetTupleRef(); //contains tuple<LocationVector, bool, double, double> //multiple entries const SaTupleVector& saTupleVec = saKey.GetTupleRef(); //contains simple Parameter //multiple entries const ParameterVector& t1Tuple = t1Key.GetTupleRef(); //contains tuple<LocationVector, dynamic_bitset<> > //optional with multiple entries GenericTupleVector genericTupleVec; if(gKey.Set()) { genericTupleVec = gKey.GetTupleRef(); } //contains simple Parameter //single entry //const ParameterVector& t2Tuple = t2Key.GetTupleRef(); const double txa = txaTupleVec[0].get<1>(); const double rfclk = any_cast<double>(param::FindParameter(t1Tuple, "refclock").value); const double baudb = any_cast<double>(param::FindParameter(t1Tuple, "baudb").value); const double ippa = any_cast<double>(param::FindParameter(t1Tuple, "ippa").value); const double bauda = any_cast<double>(param::FindParameter(t1Tuple, "bauda").value); const uint32_t txa_baud = round(txa/bauda); iif_.clkDivA = round(rfclk*bauda/2.0); iif_.clkDivB = round(rfclk*baudb/2.0); std::cout << "txa = " << txa << std::endl; std::cout << "txa_baud = " << txa_baud << std::endl; std::cout << "rfclk = " << rfclk << std::endl; std::cout << "baudb = " << baudb << std::endl; std::cout << "bauda = " << bauda << std::endl; std::cout << "ippa = " << ippa << std::endl; std::cout << "diva = " << iif_.clkDivA << std::endl; std::cout << "divb = " << iif_.clkDivB << std::endl; //const double ipp_b = rfclk/ipp; const double duty_cycle = txa/ippa; const uint32_t code_l = codeTupleVec[0].get<2>(); std::cout << "code length = " << code_l << std::endl; std::cout << "txa length = " << txa_baud << std::endl; //verify that code width matches the transmitted pulse width if(txa_baud != code_l) { cerr << "TXA Pulse Width != CODE Pulse Width => " << txa_baud << " != " << code_l << endl; throw std::runtime_error("PSU1Rules: TXA length != CODE length"); } //verify that code width matches the transmitted pulse width if( duty_cycle > MAX_DUTY_CYCLE ) { throw std::runtime_error("PSU1Rules - DUTY CYCLE " + lexical_cast<string>(duty_cycle) + " > " + lexical_cast<string>(MAX_DUTY_CYCLE)); } //push sa locations for(uint16_t idx=0; idx<saTupleVec.size(); ++idx) { LocationVector lv = saTupleVec[idx].get<0>(); globalLocations.insert(globalLocations.end(), lv.begin(), lv.end()); } //push generic location for(uint16_t idx=0; idx<genericTupleVec.size(); ++idx) { LocationVector lv = genericTupleVec[idx].get<0>(); globalLocations.insert(globalLocations.end(), lv.begin(), lv.end()); } //push all other locations LocationVector t = txaTupleVec[0].get<0>(); globalLocations.insert(globalLocations.end(), t.begin(), t.end() ); t = trTupleVec[0].get<0>(); globalLocations.insert(globalLocations.end(), t.begin(), t.end() ); t = codeTupleVec[0].get<0>(); globalLocations.insert(globalLocations.end(), t.begin(), t.end() ); //lazy way to check for duplicate signal assignments for(uint16_t idx=0; idx<globalLocations.size(); ++idx) { for(uint16_t jdx=idx+1; jdx<globalLocations.size(); ++jdx) { if(globalLocations[idx].channel == globalLocations[jdx].channel) { if(globalLocations[idx].port == globalLocations[jdx].port) { cout << globalLocations[idx].port << "." << globalLocations[idx].channel << " "; throw std::runtime_error("SIGNALS are assigned to the same port.channel"); } } } } return true; }
bool AsmCallBack(MessageEnum MessageType, const string &sMessage, const LocationVector &LocationStack) { unsigned int i, j, Length, PreLength, OrigPreLength, CutOff, Temp, StackLength = 0, StackNumber = LocationStack.size()-1; ostrstream sMsg; const char *Buffer; char DBuffer[MAX_CONSOLE_WIDTH+1]; char Space[MAX_CONSOLE_WIDTH/2+1]; memset(Space, ' ', ConsoleWidth/2); //store the last locationstack so that we don't reprint a possibly long "From included file" list //when the current error happens in the same file as the one we just printed. static LocationVector LastLocation; if(!LocationStack.empty()) { for(i = 0; i < StackNumber; i++) { if(LastLocation.size() > i+1 && LocationStack[i] == LastLocation[i]) continue; else LastLocation.clear(); sMsg << InputList[LocationStack[i].first].c_str() << "(" << LocationStack[i].second <<"): Info: From included file:\n"; } LastLocation = LocationStack; StackLength = sMsg.pcount(); } switch(MessageType) { case Info: if(!LocationStack.empty()) sMsg << InputList[LocationStack[StackNumber].first].c_str() << "(" << LocationStack[StackNumber].second << "): Info: "; break; case Warning: Warnings++; if(LocationStack.empty()) throw "Empty location stack for Warning!"; sMsg << InputList[LocationStack[StackNumber].first].c_str() << "(" << LocationStack[StackNumber].second << "): Warning: "; break; case Error: Errors++; if(LocationStack.empty()) throw "Empty location stack for Error!"; sMsg << InputList[LocationStack[StackNumber].first].c_str() << "(" << LocationStack[StackNumber].second << "): Error: "; break; case Fatal: Errors++; if(!LocationStack.empty()) sMsg << InputList[LocationStack[StackNumber].first].c_str() << "(" << LocationStack[StackNumber].second << "): "; sMsg << "Fatal: "; break; } //Print the pre-message if(LocationStack.empty()) OrigPreLength = PreLength = 0; else OrigPreLength = PreLength = sMsg.pcount() - StackLength; //If the pre-message is longer than half the width of the console, //add a newline and spaces so that it looks like the pre-message //ended at half-width. if(PreLength > ConsoleWidth/2) { sMsg << "\n"; Space[ConsoleWidth/2] = 0; PreLength = ConsoleWidth/2; sMsg << Space; } else Space[PreLength] = 0; Length = sMessage.size(); Buffer = sMessage.c_str(); //Check for tabs, which increases the effective length of the string for(i = 0; Buffer[i]; i++) if(Buffer[i] == '\t') PreLength += CONSOLE_TAB_SIZE - 1; //Print lines of the message while(true) { //Determine where to partition this message so that it fits in the console //The -1 is there so that there is room for the newline character. Temp = CutOff = MIN(Length, ConsoleWidth-PreLength-1); if(Temp != Length) { //Adjust the cutoff so that it doesn't break words while(Buffer[Temp] != ' ' && Buffer[Temp] != '\n' && Buffer[Temp] != '\t' && Buffer[Temp] != '\r' && Temp > 0) Temp--; if(Temp > 0) CutOff = Temp; } for(i = 0, j = 0; i < CutOff; i++) { if(Buffer[i] != '\n') { if(Buffer[i] == '\t') PreLength -= CONSOLE_TAB_SIZE - 1; DBuffer[j++] = Buffer[i]; } } DBuffer[j] = 0; while(CutOff != Length && (Buffer[CutOff] == ' ' || Buffer[CutOff] == '\n' || Buffer[CutOff] == '\t' || Buffer[CutOff] == '\r')) CutOff++; Buffer = &Buffer[CutOff]; Length -= CutOff; sMsg << DBuffer << '\n'; //While there is still message left, print spaces to line it up if(Length > 0) { if(OrigPreLength == 0) { OrigPreLength = PreLength = MIN(8, ConsoleWidth/2) + PreLength; Space[0] = ' '; Space[MIN(8, ConsoleWidth/2)] = 0; } sMsg << Space; } else break; } sMsg << ends; cout << sMsg.str(); cout.flush(); return true; }