Skip to content

Commit

Permalink
Merge pull request #38 from edcallaghan/structure_alignment_parsing
Browse files Browse the repository at this point in the history
fpga alignment command and parsing
  • Loading branch information
edcallaghan authored Jul 25, 2024
2 parents 4bd3394 + 65d8199 commit 4531588
Show file tree
Hide file tree
Showing 14 changed files with 631 additions and 1 deletion.
1 change: 1 addition & 0 deletions otsdaq-mu2e-tracker/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ add_subdirectory(Generators)
add_subdirectory(ArtModules)
add_subdirectory(Ui)
add_subdirectory(Gui)
add_subdirectory(ParseAlignment)
60 changes: 60 additions & 0 deletions otsdaq-mu2e-tracker/ParseAlignment/Alignment.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Ed Callaghan
// Aggregate of book-keeping across an set of iterations
// July 2024

#include "otsdaq-mu2e-tracker/ParseAlignment/Alignment.hh"

Alignment::Alignment(words_t buffer){
// account for two header and one footer word
unsigned int adjusted = buffer.size() - 3;
if (adjusted % AlignmentIteration::payload_size != 0){
std::string msg = "Malformed alignment returned payload: ";
msg += "iteration payload size (";
msg += std::to_string(AlignmentIteration::payload_size);
msg += ") ";
msg += "does not divide adjusted size (";
msg += std::to_string(buffer.size());
msg += " - 3 = ";
msg += std::to_string(adjusted) + ")";
throw cet::exception("ALIGNMENT::Alignment") << msg;
}
unsigned int n_iterations = adjusted / AlignmentIteration::payload_size;
this->iterations.resize(n_iterations);

// first, the simple part
this->eye_monitor_width = static_cast<unsigned int>(buffer[0]);
this->if_pattern_check = static_cast<bool>(buffer[1]);

// next, forward iteration-level blocks
for (size_t i = 0 ; i < this->iterations.size() ; i++){
size_t offset = 2 + i*AlignmentIteration::payload_size;
words_t tmp(AlignmentIteration::payload_size);
for (size_t j = 0 ; j < tmp.size() ; j++){
tmp[j] = buffer[offset+j];
}
this->iterations[i] = AlignmentIteration(i, tmp);
}

// one last simple part
this->faulted_adc = static_cast<unsigned int>(buffer.size() - 1);
}

unsigned int Alignment::EyeMonitorWidth() const{
auto rv = this->eye_monitor_width;
return rv;
}

bool Alignment::IfPatternCheck() const{
auto rv = this->if_pattern_check;
return rv;
}

unsigned int Alignment::FaultedADC() const{
auto rv = this->faulted_adc;
return rv;
}

std::vector<AlignmentIteration> Alignment::Iterations() const{
auto& rv = this->iterations;
return rv;
}
36 changes: 36 additions & 0 deletions otsdaq-mu2e-tracker/ParseAlignment/Alignment.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Ed Callaghan
// Aggregate of book-keeping across an set of iterations
// July 2024

#ifndef Alignment_h
#define Alignment_h

#include <string>
#include <vector>
#include "cetlib_except/exception.h"
#include "otsdaq-mu2e-tracker/ParseAlignment/AlignmentIteration.hh"
#include "otsdaq-mu2e-tracker/ParseAlignment/Types.hh"

// EyeMonitorWidth: 1 per routine: 1 x unsigned short
// IfPatternCheck: 1 per routine: 1 x unsigned short
// Iteration blocks: N per routine: N x 127 x unsigned short
// FaultedADC: 1 per routine: 1 x unsigned short

class Alignment{
public:
Alignment(words_t);

unsigned int EyeMonitorWidth() const;
bool IfPatternCheck() const;
unsigned int FaultedADC() const;
std::vector<AlignmentIteration> Iterations() const;
protected:
unsigned int eye_monitor_width;
bool if_pattern_check;
unsigned int faulted_adc;
std::vector<AlignmentIteration> iterations;
private:
/**/
};

#endif
79 changes: 79 additions & 0 deletions otsdaq-mu2e-tracker/ParseAlignment/AlignmentChannel.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Ed Callaghan
// Lowest-level book-keeping of results of adc alignment
// July 2024

#include "otsdaq-mu2e-tracker/ParseAlignment/AlignmentChannel.hh"

// copied from default serial mapping
const std::map<unsigned int, unsigned int>
AlignmentChannel::adc_to_straw_map = {
{ 0,91}, { 1,85}, { 2,79}, { 3,73}, { 4,67}, { 5,61}, { 6,55}, { 7,49},
{ 8,43}, { 9,37}, {10,31}, {11,25}, {12,19}, {13,13}, {14, 7}, {15, 1},
{16,90}, {17,84}, {18,78}, {19,72}, {20,66}, {21,60}, {22,54}, {23,48},
{24,42}, {25,36}, {26,30}, {27,24}, {28,18}, {29,12}, {30, 6}, {31, 0},
{32,93}, {33,87}, {34,81}, {35,75}, {36,69}, {37,63}, {38,57}, {39,51},
{40,45}, {41,39}, {42,33}, {43,27}, {44,21}, {45,15}, {46, 9}, {47, 3},
{48,44}, {49,38}, {50,32}, {51,26}, {52,20}, {53,14}, {54, 8}, {55, 2},
{56,92}, {57,86}, {58,80}, {59,74}, {60,68}, {61,62}, {62,56}, {63,50},
{64,47}, {65,41}, {66,35}, {67,29}, {68,23}, {69,17}, {70,11}, {71, 5},
{72,95}, {73,89}, {74,83}, {75,77}, {76,71}, {77,65}, {78,59}, {79,53},
{80,46}, {81,40}, {82,34}, {83,28}, {84,22}, {85,16}, {86,10}, {87, 4},
{88,94}, {89,88}, {90,82}, {91,76}, {92,70}, {93,64}, {94,58}, {95,52},
};

AlignmentChannel::AlignmentChannel(unsigned int adc,
bool active,
bool complete,
bool error,
bool bitslip_done,
unsigned int bitslip_step,
bool pattern_match):
adc(adc),
active(active),
complete(complete),
error(error),
bitslip_done(bitslip_done),
bitslip_step(bitslip_step),
pattern_match(pattern_match){
this->channel = AlignmentChannel::adc_to_straw_map[this->adc];
}

unsigned int AlignmentChannel::ADC() const{
auto rv = this->adc;
return rv;
}

unsigned int AlignmentChannel::Channel() const{
auto rv = this->channel;
return rv;
}

bool AlignmentChannel::Active() const{
auto rv = this->active;
return rv;
}

bool AlignmentChannel::Complete() const{
auto rv = this->complete;
return rv;
}

bool AlignmentChannel::Error() const{
auto rv = this->error;
return rv;
}

unsigned int AlignmentChannel::BitSlipStep() const{
auto rv = this->bitslip_step;
return rv;
}

bool AlignmentChannel::BitSlipDone() const{
auto rv = this->bitslip_done;
return rv;
}

bool AlignmentChannel::PatternMatch() const{
auto rv = this->pattern_match;
return rv;
}
38 changes: 38 additions & 0 deletions otsdaq-mu2e-tracker/ParseAlignment/AlignmentChannel.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Ed Callaghan
// Lowest-level book-keeping of results of adc alignment
// July 2024

#ifndef AlignmentChannel_h
#define AlignmentChannel_h

#include <map>

class AlignmentChannel{
public:
AlignmentChannel() = default;
AlignmentChannel(unsigned int, bool, bool, bool, bool, unsigned int, bool);

unsigned int ADC() const;
unsigned int Channel() const;
bool Active() const;
bool Complete() const;
bool Error() const;
unsigned int BitSlipStep() const;
bool BitSlipDone() const;
bool PatternMatch() const;

protected:
static const std::map<unsigned int, unsigned int> adc_to_straw_map;

private:
unsigned int adc;
unsigned int channel;
bool active;
bool complete;
bool error;
bool bitslip_done;
unsigned int bitslip_step;
bool pattern_match;
};

#endif
120 changes: 120 additions & 0 deletions otsdaq-mu2e-tracker/ParseAlignment/AlignmentIteration.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Ed Callaghan
// Aggregate of book-keeping across an iteration
// July 2024

#include <iostream>
#include "otsdaq-mu2e-tracker/ParseAlignment/AlignmentIteration.hh"

AlignmentIteration::ChannelMask::ChannelMask(unsigned int lo,
unsigned int md,
unsigned int hi):
lo(lo), md(md), hi(hi){
/**/
}

bool AlignmentIteration::ChannelMask::TestBit(unsigned int i){
bool rv = false;
if (i < 32){
rv = this->lo & (1 << i);
}
else if (i < 64){
i -= 32;
rv = this->md & (1 << i);
}
else if (i < 96){
i -= 64;
rv = this->hi & (1 << i);
}
else{
// should never reach here
}

return rv;
}

// described further in header
const unsigned int AlignmentIteration::payload_size = 127;

const unsigned int AlignmentIteration::channel_count = 96;

unsigned int AlignmentIteration::Index(){
auto rv = this->index;
return rv;
}

int AlignmentIteration::ADCPhase(){
auto rv = this->adc_phase;
return rv;
}

std::vector<AlignmentChannel>& AlignmentIteration::Channels(){
auto& rv = this->channels;
return rv;
}

AlignmentIteration::AlignmentIteration(unsigned int index, words_t words){
this->index = index;
this->adc_phase = static_cast<int>(words[0]);

// reserve space for channel-level data
this->channels.resize(AlignmentIteration::channel_count);

// parse the payloads out of the structured representation
// this->packed.structured
// subtract two to compensate for routine-level header in rusu's decoding
unsigned int mask_lo;
unsigned int mask_md;
unsigned int mask_hi;

// first few masks are constructed out of first block of ushorts
mask_lo = this->construct_concatenated_word(words, 0, 1, 2);
mask_md = this->construct_concatenated_word(words, 2, 1, 2);
mask_hi = this->construct_concatenated_word(words, 4, 1, 2);
ChannelMask active_mask(mask_lo, mask_md, mask_hi);

mask_lo = this->construct_concatenated_word(words, 0, 7, 9);
mask_md = this->construct_concatenated_word(words, 4, 7, 9);
mask_hi = this->construct_concatenated_word(words, 8, 7, 9);
ChannelMask complete_mask(mask_lo, mask_md, mask_hi);

mask_lo = this->construct_concatenated_word(words, 0, 8, 10);
mask_md = this->construct_concatenated_word(words, 4, 8, 10);
mask_hi = this->construct_concatenated_word(words, 8, 8, 10);
ChannelMask error_mask(mask_lo, mask_md, mask_hi);

mask_lo = this->construct_concatenated_word(words, 0, 19, 20);
mask_md = this->construct_concatenated_word(words, 2, 19, 20);
mask_hi = this->construct_concatenated_word(words, 4, 19, 20);
ChannelMask bitslip_done_mask(mask_lo, mask_md, mask_hi);

// final mask is constructed from second block of ushorts
mask_lo = this->construct_concatenated_word(words, 0, 121, 122);
mask_md = this->construct_concatenated_word(words, 2, 121, 122);
mask_hi = this->construct_concatenated_word(words, 4, 121, 122);
ChannelMask pattern_match_mask(mask_lo, mask_md, mask_hi);


size_t steps_offset = 1 + 24; // after first packed blocks
for (size_t i = 0 ; i < this->channels.size() ; i++){
bool active = active_mask.TestBit(i);
bool complete = complete_mask.TestBit(i);
bool error = error_mask.TestBit(i);
bool bitslip_done = bitslip_done_mask.TestBit(i);
unsigned int bitslip_step = static_cast<unsigned int>(words[steps_offset+i]);
bool pattern_match = pattern_match_mask.TestBit(i);
this->channels[i] = AlignmentChannel(i,
active, complete, error,
bitslip_done, bitslip_step,
pattern_match);
}
}

unsigned int AlignmentIteration::construct_concatenated_word(const words_t& v,
size_t offset,
size_t idx_lo,
size_t idx_hi){
unsigned int rv = 0;
rv |= static_cast<unsigned int>(v[offset + idx_lo]) & 0xFFFF; // lower 16 bits
rv |= static_cast<unsigned int>(v[offset + idx_hi]) << 16; // upper 16 bits
return rv;
}
53 changes: 53 additions & 0 deletions otsdaq-mu2e-tracker/ParseAlignment/AlignmentIteration.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Ed Callaghan
// Aggregate of book-keeping across an iteration
// July 2024

#ifndef AlignmentIteration_h
#define AlignmentIteration_h

#include <cstddef>
#include <vector>
#include "otsdaq-mu2e-tracker/ParseAlignment/AlignmentChannel.hh"
#include "otsdaq-mu2e-tracker/ParseAlignment/Types.hh"

// ADCPhase: 1 per iteration: 1 x unsigned short
// ActiveCh, AlignCmp, AlignErr, BitSlipDone:
// 1 per channel: packed into 24 x unsigned short = 96 x 4 bits
// BitSlipStep: 1 per channel: 96 x unsigned short
// PatternMatch: 1 per channel: packed into 6 x unsigned short = 96 x 1 bits
// Total: 127 x unsigned short

class AlignmentIteration{
class ChannelMask{
public:
ChannelMask(unsigned int, unsigned int, unsigned int);
bool TestBit(unsigned int);
protected:
unsigned int lo;
unsigned int md;
unsigned int hi;
private:
/**/
};

public:
static const unsigned int payload_size; // 127 words, as above
static const unsigned int channel_count; // 96 channels

AlignmentIteration() = default;
AlignmentIteration(unsigned int, words_t);

unsigned int Index();
int ADCPhase();
std::vector<AlignmentChannel>& Channels();
protected:
unsigned int index;
int adc_phase;
std::vector<AlignmentChannel> channels;

unsigned int construct_concatenated_word(const words_t&, size_t, size_t, size_t);
private:
/**/
};

#endif
Loading

0 comments on commit 4531588

Please sign in to comment.