Skip to content

Commit

Permalink
expand elink_relink to more delay values, controlable by user
Browse files Browse the repository at this point in the history
  • Loading branch information
tomeichlersmith committed Apr 6, 2022
1 parent 85f0536 commit 3a2d070
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 35 deletions.
28 changes: 25 additions & 3 deletions include/pflib/PolarfireTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,33 @@ struct PolarfireTarget {
bool loadBiasSettings(const std::string& file_name);

/** Carries out the standard elink alignment process */
void elink_relink(int ilink,int verbosity);
void elink_relink(int ilink,int min_delay = 0, int max_delay = 128);

void delay_loop(int ilink);
/**
* Go from min_delay up to max_delay stopping only if alignment is achieved
*
* Using bitslip_loop to test each delay value.
*
* @param[in] ilink link index to test
* @param[in] min_delay minimum value of delay parameter
* @param[in] max_delay maximum value of delay parameter
*/
void delay_loop(int ilink, int min_delay, int max_delay);

bool bitslip_loop(int ilink);
/**
* check all bitslip values and find the one with
* the most correct idle patterns
*
* each spy returns 60 bytes (or 15 4-byte words),
* the idle pattern is 0x9c or 0xac followed by three 0xcc.
*
* @param[in] ilink link index to loop over
* @param[out] best_slip set to best bitslip value
* @param[out] best_count set to number of idles that were correct for the best slip
* @return true if best slip value is perfect (i.e. link is aligned)
* (all possible words were corect pattern)
*/
bool bitslip_loop(int ilink, int& best_slip, int& best_count);

private:
int samples_per_event_;
Expand Down
51 changes: 21 additions & 30 deletions src/pflib/PolarfireTarget.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -462,41 +462,41 @@ bool PolarfireTarget::loadBiasSettings(const std::string& file_name) {
}
}

void PolarfireTarget::elink_relink(int ilink ,int verbosity) {
void PolarfireTarget::elink_relink(int ilink, int min_delay, int max_delay) {
pflib::Elinks& elinks=hcal.elinks();

if (ilink == -1){
for (int ilink=0; ilink<elinks.nlinks(); ilink++) {
delay_loop(ilink);
delay_loop(ilink, min_delay, max_delay);
}
} else delay_loop(ilink);

} else delay_loop(ilink, min_delay, max_delay);
}

void PolarfireTarget::delay_loop(int ilink){
void PolarfireTarget::delay_loop(int ilink, int min_delay, int max_delay){
pflib::Elinks& elinks = hcal.elinks();
bool passedBitslipLoop = false;
bool aligned = false;
if (elinks.isActive(ilink)){
for (int delay=20; delay<26; delay++){
int bitslip, count;
for (int delay=min_delay; delay<max_delay; delay++) {
elinks.setDelay(ilink,delay);
passedBitslipLoop = bitslip_loop(ilink);
if (passedBitslipLoop) break;
aligned = bitslip_loop(ilink,bitslip,count);
printf(" Elink %d delay %d bitslip %d (ok count=%d) %s\n",
ilink,delay,bitslip,count,aligned?"alignment achieved":"");
if (aligned) break;
}
if (!passedBitslipLoop) printf("Delay scan exceeded 25, you should do an elinks hardreset\n");
if (!aligned) printf("Delay scan from %d to %d was unable to align link %d.\n",
min_delay,max_delay,ilink);
} else printf(" Elink %d is not active.\n",ilink);
}

bool PolarfireTarget::bitslip_loop(int ilink){
bool PolarfireTarget::bitslip_loop(int ilink, int& best_slip, int& count) {
static int total_cycles = 5; // number of spies per bitslip value
pflib::Elinks& elinks=hcal.elinks();

elinks.setBitslipAuto(ilink,false);

int okcount[8];

for (int slip=0; slip<8; slip++) {
elinks.setBitslip(ilink,slip);
okcount[slip]=0;
for (int cycles=0; cycles<5; cycles++) {
for (int cycles=0; cycles < total_cycles; cycles++) {
std::vector<uint8_t> spy=elinks.spy(ilink);
for (size_t i=0; i+4<spy.size(); ) {
if (spy[i]==0x9c || spy[i]==0xac) {
Expand All @@ -506,23 +506,14 @@ bool PolarfireTarget::bitslip_loop(int ilink){
}
}
}
int imax=-1;
best_slip = -1;
for (int slip=0; slip<8; slip++) {
if (imax<0 || okcount[slip]>okcount[imax]) imax=slip;
}
elinks.setBitslip(ilink,imax);
printf(" Link %d bitslip %d (ok count=%d)\n",ilink,imax,okcount[imax]);

if (okcount[imax] == 75){
return true;
if (best_slip<0 || okcount[slip]>okcount[best_slip]) best_slip=slip;
}
else return false;

elinks.setBitslip(ilink,best_slip);
count = okcount[best_slip];
return (count == 15*total_cycles);
}

//}



} // namespace pflib

7 changes: 5 additions & 2 deletions tool/pftool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ static void link( const std::string& cmd, PolarfireTarget* pft ) {
* pflib::Hcal::elinks and then procede to the commands.
*
* ## Commands
* - RELINK : pflib::PolarfireTarget::elink_relink with verbosity 2
* - RELINK : pflib::PolarfireTarget::elink_relink
* - SPY : pflib::Elinks::spy
* - BITSLIP : pflib::Elinks::setBitslip and pflib::Elinks::setBitslipAuto
* - BIGSPY : PolarfireTarget::elinksBigSpy
Expand All @@ -240,9 +240,12 @@ static void link( const std::string& cmd, PolarfireTarget* pft ) {
static void elinks( const std::string& cmd, PolarfireTarget* pft ) {
pflib::Elinks& elinks=pft->hcal.elinks();
static int ilink=0;
static int min_delay{0}, max_delay{128};
if (cmd=="RELINK"){
ilink=BaseMenu::readline_int("Which elink? (-1 for all) ",ilink);
pft->elink_relink(ilink,2);
min_delay=BaseMenu::readline_int("Min delay? ",min_delay);
max_delay=BaseMenu::readline_int("Max delay? ",max_delay);
pft->elink_relink(ilink,min_delay,max_delay);
}
if (cmd=="SPY") {
ilink=BaseMenu::readline_int("Which elink? ",ilink);
Expand Down

0 comments on commit 3a2d070

Please sign in to comment.