Skip to content

Commit

Permalink
Merge pull request #46 from LDMX-Software/iss_40
Browse files Browse the repository at this point in the history
Iss 40
  • Loading branch information
tomeichlersmith authored Apr 4, 2022
2 parents 19fae31 + 5b1bb35 commit 13e1bf1
Show file tree
Hide file tree
Showing 12 changed files with 599 additions and 50 deletions.
8 changes: 6 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ add_library(pflib SHARED
src/pflib/ROC.cxx
src/pflib/WishboneTarget.cxx
src/pflib/Compile.cxx
src/pflib/PolarfireTarget.cxx)
src/pflib/PolarfireTarget.cxx
src/pflib/decoding/RocPacket.cxx
src/pflib/decoding/PolarfirePacket.cxx
src/pflib/decoding/SuperPacket.cxx
)
target_include_directories(pflib PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:include>")
Expand Down Expand Up @@ -127,7 +131,7 @@ else()
endif()

if (NOT Rogue_FOUND AND NOT Uhal_FOUND)
message(FATAL_ERROR "Neither Rogue or Uhal were found. At least one is necessary for polarfire interaction library.")
message(WARNING "Neither Rogue or Uhal were found. At least one is necessary for a functional polarfire interaction library.")
endif()

set_target_properties(pflib ${comm_libs} PROPERTIES PREFIX "libpflib_")
Expand Down
6 changes: 5 additions & 1 deletion include/pflib/PolarfireTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,11 @@ struct PolarfireTarget {
bool loadBiasSettings(const std::string& file_name);

/** Carries out the standard elink alignment process */
void elink_relink(int verbosity);
void elink_relink(int ilink,int verbosity);

void delay_loop(int ilink);

bool bitslip_loop(int ilink);

private:
int samples_per_event_;
Expand Down
47 changes: 47 additions & 0 deletions include/pflib/decoding/PolarfirePacket.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef pflib_decoding_PolarfirePacket_h
#define pflib_decoding_PolarfirePacket_h 1

#include "pflib/decoding/RocPacket.h"

namespace pflib {
namespace decoding {

/** \class This class decodes the innermost part of an HGCROC packet given
a pointer to a series of unsigned 32-bit integers and a length.
*/
class PolarfirePacket {
public:
PolarfirePacket(const uint32_t* header_ptr, int len) : data_{header_ptr}, length_{len} { }

int length() const { if (length_<1) return -1; return data_[0]&0xFFF; }
int nlinks() const { if (length_<1) return -1; return (data_[0]>>14)&0x3F; }
int fpgaid() const { if (length_<1) return -1; return (data_[0]>>20)&0xFF; }
int formatversion() const { if (length_<1) return -1; return (data_[0]>>28)&0xF; }

int length_for_elink(int ilink) const { if (ilink>=nlinks()) return 0; return (data_[2+(ilink/4)]>>(8*(ilink%4)))&0x3F; }

int bxid() const { if (length_<2) return -1; return (data_[1]>>20)&0xFFF;}

int rreq() const { if (length_<2) return -1; return (data_[1]>>10)&0x3FF;}

int orbit() const { if (length_<2) return -1; return data_[1]&0x3FF;}

int linklen(int link) const { if (length_<3) return -1; return (data_[2]>>(link*8))&0x3F;}

int linkcrc(int link) const { if (length_<3) return -1; return (data_[2]>>(link*8+6))&0x1;}

int linkrid(int link) const { if (length_<3) return -1; return (data_[2]>>(link*8+7))&0x1;}

RocPacket roc(int iroc) const;
private:
int offset_to_elink(int iroc) const;

const uint32_t* data_;
int length_;
};

}
}

#endif// pflib_decoding_PolarfirePacket_h

46 changes: 46 additions & 0 deletions include/pflib/decoding/RocPacket.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef pflib_decoding_RocPacket_h
#define pflib_decoding_RocPacket_h 1

#include <stdint.h>

namespace pflib {
namespace decoding {

/** \class This class decodes the innermost part of an HGCROC packet given
a pointer to a series of unsigned 32-bit integers and a length.
*/
class RocPacket {
public:
RocPacket(const uint32_t* header_ptr, int len);

int rocid() const { if (length_==0) return -1; return (data_[0]>>16)&0xFFFF;}

int crc() const {if (length_==0) return -1; return (data_[0]>>15)&0x1;}

int bxid() const { if (length_<3) return -1; return (data_[2]>>11)&0x7FF;}

int wadd() const { if (length_<3) return -1; return (data_[2]>>3)&0xFF;}

bool has_chan(int ichan) const { return offset_to_chan(ichan)>=0; }

int get_tot(int ichan) const { int offset = offset_to_chan(ichan); if (offset == -1) return -1; return (data_[offset]>>20)&0xFFF;}

int get_toa(int ichan) const { int offset = offset_to_chan(ichan); if (offset == -1) return -1; return (data_[offset]>>10)&0x3FF;}

int get_adc(int ichan) const { int offset = offset_to_chan(ichan); if (offset == -1) return -1; return data_[offset]&0x3FF;}

void dump() const;

private:
int offset_to_chan(int ichan) const;

const uint32_t* data_;
int length_;

};

}
}

#endif// pflib_decoding_RocPacket_h

33 changes: 33 additions & 0 deletions include/pflib/decoding/SuperPacket.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef pflib_decoding_SuperPacket_h
#define pflib_decoding_SuperPacket_h 1

#include "pflib/decoding/PolarfirePacket.h"

namespace pflib {
namespace decoding {

/** \class This class decodes the outer level of a multisample packet
*/
class SuperPacket {
public:
SuperPacket(const uint32_t* header_ptr, int len);

int length64() const;
int length32() const;
int fpgaid() const {if (length_ == 0) return -1; return (data_[0]>>20)&0xFF;}
int nsamples() const {if (length_ == 0) return -1; return (data_[0]>>16)&0xF;}
int formatversion() const {if (length_ == 0) return -1; return (data_[0]>>28)&0xF;}
int length32_for_sample(int isample) const;

PolarfirePacket sample(int isample) const;
private:
const uint32_t* data_;
int length_;
int version_;
};

}
}

#endif// pflib_decoding_PolarfirePacket_h

91 changes: 51 additions & 40 deletions src/pflib/PolarfireTarget.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ void PolarfireTarget::prepareNewRun() {
hcal.fc().getMultisampleSetup(enable,extra_samples);
samples_per_event_=extra_samples+1;


daq.enable(true);
}

Expand Down Expand Up @@ -299,7 +300,7 @@ void PolarfireTarget::daqStatus(std::ostream& os) {

os << "-----Off-detector FIFO-----\n";
backend->daq_status(full, empty, events,asize);
os << " " << std::setw(8) << (full ? "FULL" : "NOT-FULL")
os << " " << std::setfill(' ') << std::setw(8) << (full ? "FULL" : "NOT-FULL")
<< " " << std::setw(9) << (empty ? "EMPTY" : "NOT_EMPTY")
<< " Events ready: " << std::setw(3) << events
<< " Next event size: " << asize
Expand Down Expand Up @@ -440,55 +441,65 @@ bool PolarfireTarget::loadBiasSettings(const std::string& file_name) {
}
}

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

if (verbosity>0)
printf("...Setting phase delays\n");
for (int ilink=0; ilink<elinks.nlinks(); ilink++)
if (elinks.isActive(ilink))
elinks.setDelay(ilink,20);
if (ilink == -1){
for (int ilink=0; ilink<elinks.nlinks(); ilink++) {
delay_loop(ilink);
}
} else delay_loop(ilink);


if (verbosity>0) {
printf("...Hard reset\n");
}
elinks.resetHard();
sleep(1);

if (verbosity>0) {
printf("...Scanning bitslip values\n");
}
}

void PolarfireTarget::delay_loop(int ilink){
pflib::Elinks& elinks = hcal.elinks();
bool passedBitslipLoop = false;
if (elinks.isActive(ilink)){
for (int delay=20; delay<26; delay++){
elinks.setDelay(ilink,delay);
passedBitslipLoop = bitslip_loop(ilink);
if (passedBitslipLoop) break;
}
if (!passedBitslipLoop) printf("Delay scan exceeded 25, you should do an elinks hardreset\n");
} else printf(" Elink %d is not active.\n",ilink);
}

for (int ilink=0; ilink<elinks.nlinks(); ilink++) {
if (!elinks.isActive(ilink)) continue;
bool PolarfireTarget::bitslip_loop(int ilink){
pflib::Elinks& elinks=hcal.elinks();

elinks.setBitslipAuto(ilink,false);
elinks.setBitslipAuto(ilink,false);

int okcount[8];
int okcount[8];

for (int slip=0; slip<8; slip++) {
elinks.setBitslip(ilink,slip);
okcount[slip]=0;
for (int cycles=0; cycles<5; 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) {
if (spy[i+1]==0xcc && spy[i+2]==0xcc && spy[i+3]==0xcc) okcount[slip]++;
i+=4;
} else i++;
}
}
}
int imax=-1;
for (int slip=0; slip<8; slip++) {
if (imax<0 || okcount[slip]>okcount[imax]) imax=slip;
for (int slip=0; slip<8; slip++) {
elinks.setBitslip(ilink,slip);
okcount[slip]=0;
for (int cycles=0; cycles<5; 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) {
if (spy[i+1]==0xcc && spy[i+2]==0xcc && spy[i+3]==0xcc) okcount[slip]++;
i+=4;
} else i++;
}
}
elinks.setBitslip(ilink,imax);
printf(" Link %d bitslip %d (ok count=%d)\n",ilink,imax,okcount[imax]);
}

int imax=-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;
}
else return false;

}

//}



Expand Down
21 changes: 21 additions & 0 deletions src/pflib/decoding/PolarfirePacket.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "pflib/decoding/PolarfirePacket.h"

namespace pflib {
namespace decoding {

RocPacket PolarfirePacket::roc(int ilink) const {
int offset=offset_to_elink(ilink);
if (offset<0) return RocPacket(0,0);
else return RocPacket(data_+offset,length_for_elink(ilink));
}

int PolarfirePacket::offset_to_elink(int ilink) const {
if (ilink<0 || ilink>=nlinks()) return -1;
int offset=2+((nlinks()+3)/4); // header words
for (int i=0; i<ilink; i++)
offset+=length_for_elink(i);
return offset;
}

}
}
38 changes: 38 additions & 0 deletions src/pflib/decoding/RocPacket.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "pflib/decoding/RocPacket.h"
#include <stdio.h>

namespace pflib {
namespace decoding {

RocPacket::RocPacket(const uint32_t* header_ptr, int len) : data_{header_ptr}, length_{len} {

}

void RocPacket::dump() const {
for (int i=0; i<length_; i++) {
printf("%2d %08x ",i,data_[i]);
if (i<36 && has_chan(i)) printf(" %d",get_adc(i));
printf("\n");
}
}

int RocPacket::offset_to_chan(int ichan) const {
if (length_<2 || ichan<0 || ichan>=36) return -1;
int offset=0;

uint64_t readout_map=(uint64_t(data_[0])<<32)|data_[1];

int inominal=ichan+1; // first word in ROC V2 is header
if (ichan>=18) inominal+=2; // common mode and calib in the middle

for (int i=0; i<inominal; i++) {
if (readout_map&0x1) offset++;
readout_map=readout_map>>1;
}
if (readout_map&0x1) return offset+2; // +2 for the two Polarfire header words
else return -1;

}

}
}
31 changes: 31 additions & 0 deletions src/pflib/decoding/SuperPacket.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "pflib/decoding/SuperPacket.h"
#include <stdio.h>

namespace pflib {
namespace decoding {

SuperPacket::SuperPacket(const uint32_t* header_ptr, int len) : data_{header_ptr}, length_{len}{
bool found_header=false;
while (length_>0 && !found_header) {
if (*data_==0xBEEF2021u) found_header=true;
length_--;
data_++;
}
}

int SuperPacket::length64() const { return -1;}
int SuperPacket::length32() const { return -1;}
int SuperPacket::length32_for_sample(int isample) const {
if (isample<0 || isample>=nsamples()) return 0;
return (data_[1+(isample/2)]>>(16*(isample%2)))&0xFFF;
}

PolarfirePacket SuperPacket::sample(int isample) const {
int offset=1+((nsamples()+1)/2);
for (int i=0; i<isample; i++)
offset+=length32_for_sample(i);
return PolarfirePacket(data_+offset,length32_for_sample(isample));
}

}
}
3 changes: 2 additions & 1 deletion tool/Menu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ std::string BaseMenu::readline(const std::string& prompt,

if (!cmdTextQueue_.empty()) {
retval = cmdTextQueue_.front();
printf("%s %s\n", trueprompt.c_str(), retval.c_str());
if (retval.empty()) retval=defval;
printf("%s %s\n", trueprompt.c_str(), retval.c_str());

if (!retval.empty() && retval[0] == '~') {
retval.erase(0, 1);
Expand Down
2 changes: 1 addition & 1 deletion tool/pfdecoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ int main(int argc, char* argv[]) {
}
if (verbosity>0)
printf("\n");
} else if (rel_super>2+(samples+1)/2 && rel_super<=2+8) {
} else if (rel_super>2+(samples+1)/2 && rel_super<=2+8 && fmt==2) {
word_type=wt_junk; // empty sample words
} else if (int(packet_pointers.size())>isample+1 && i==packet_pointers[isample+1]) {
packet_header=i;
Expand Down
Loading

0 comments on commit 13e1bf1

Please sign in to comment.