Skip to content

Commit e128405

Browse files
RoC: Adjustments for new CRU data format
1 parent 4a5d3c2 commit e128405

File tree

2 files changed

+87
-47
lines changed

2 files changed

+87
-47
lines changed

src/CommandLineUtilities/ProgramDmaBench.cxx

Lines changed: 74 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "CommandLineUtilities/Program.h"
2626
#include "Common/Iommu.h"
2727
#include "Common/SuffixOption.h"
28+
#include "Cru/DataFormat.h"
2829
#include "ExceptionInternal.h"
2930
#include "InfoLogger/InfoLogger.hxx"
3031
#include "folly/ProducerConsumerQueue.h"
@@ -45,6 +46,10 @@ namespace b = boost;
4546
namespace po = boost::program_options;
4647

4748
namespace {
49+
/// Initial value for link counters
50+
constexpr auto LINK_COUNTER_INITIAL_VALUE = std::numeric_limits<uint64_t>::max();
51+
/// Maximum supported links
52+
constexpr auto MAX_LINKS = 32;
4853
/// Interval for low priority thread (display updates, etc)
4954
constexpr auto LOW_PRIORITY_INTERVAL = 10ms;
5055
/// Resting time if push thread has nothing to do
@@ -60,7 +65,7 @@ const std::string PROGRESS_FORMAT(" %02s:%02s:%02s %-12s %-12s %-12s %-5.1
6065
/// Path for error log
6166
auto READOUT_ERRORS_PATH = "readout_errors.txt";
6267
/// Max amount of errors that are recorded into the error stream
63-
constexpr int64_t MAX_RECORDED_ERRORS = 1000;
68+
constexpr int64_t MAX_RECORDED_ERRORS = 10000;
6469
/// End InfoLogger message alias
6570
constexpr auto endm = InfoLogger::endm;
6671
} // Anonymous namespace
@@ -159,6 +164,10 @@ class ProgramDmaBench: public Program
159164

160165
virtual void run(const po::variables_map& map)
161166
{
167+
for (auto& i : mLinkCounters) {
168+
i = LINK_COUNTER_INITIAL_VALUE;
169+
}
170+
162171
auto params = Options::getOptionsParameterMap(map);
163172
auto cardId = Options::getOptionCardId(map);
164173
mLogger << "DMA channel: " << mOptions.dmaChannel << endm;
@@ -259,7 +268,8 @@ class ProgramDmaBench: public Program
259268
// Note that we can force unlock because we know for sure this process is not holding the lock. If we did not know
260269
// this, it would be very dangerous to force the lock.
261270
params.setForcedUnlockEnabled(true);
262-
params.setLinkMask(Parameters::linkMaskFromString(mOptions.links));
271+
mLinkMask = Parameters::linkMaskFromString(mOptions.links);
272+
params.setLinkMask(mLinkMask);
263273

264274
mInfinitePages = (mOptions.maxBytes <= 0);
265275
mMaxPages = mOptions.maxBytes / mPageSize;
@@ -508,6 +518,17 @@ class ProgramDmaBench: public Program
508518
return value;
509519
}
510520

521+
uint32_t getDataGeneratorCounterFromPage(uintptr_t pageAddress)
522+
{
523+
switch (mCardType) {
524+
case CardType::Crorc:
525+
return get32bitFromPage(pageAddress, 0);
526+
case CardType::Cru:
527+
return get32bitFromPage(pageAddress, 23);
528+
default: throw std::runtime_error("Error checking unsupported for this card type");
529+
}
530+
};
531+
511532
void readoutPage(uintptr_t pageAddress, size_t pageSize, int64_t readoutCount)
512533
{
513534
// Read out to file
@@ -517,25 +538,39 @@ class ProgramDmaBench: public Program
517538

518539
// Data error checking
519540
if (!mOptions.noErrorCheck) {
520-
auto getDataGeneratorCounterFromPage = [&]{
521-
switch (mCardType) {
522-
case CardType::Crorc:
523-
return get32bitFromPage(pageAddress, 0);
524-
case CardType::Cru:
525-
return get32bitFromPage(pageAddress, 23);
526-
default: throw std::runtime_error("Error checking unsupported for this card type");
541+
542+
// Get link ID if needed
543+
int linkId = 0; // Use 0 for non-CRU cards
544+
if (mCardType == CardType::Cru) {
545+
linkId = Cru::DataFormat::getLinkId(reinterpret_cast<const char*>(pageAddress));
546+
if (linkId >= mLinkCounters.size()) {
547+
BOOST_THROW_EXCEPTION(Exception()
548+
<< ErrorInfo::Message("Link ID from superpage out of range")
549+
<< ErrorInfo::Index(linkId));
527550
}
528-
};
551+
}
529552

530-
if (mDataGeneratorCounter == -1) {
531-
// First page initializes the counter
532-
mDataGeneratorCounter = getDataGeneratorCounterFromPage();
553+
// First received page initializes the counter
554+
if (mLinkCounters[linkId] == LINK_COUNTER_INITIAL_VALUE) {
555+
mLinkCounters[linkId] = getDataGeneratorCounterFromPage(pageAddress);
556+
}
557+
558+
// Check for errors
559+
bool hasError = true;
560+
switch (mCardType) {
561+
case CardType::Crorc:
562+
hasError = checkErrorsCrorc(pageAddress, pageSize, readoutCount, linkId);
563+
break;
564+
case CardType::Cru:
565+
hasError = checkErrorsCru(pageAddress, pageSize, readoutCount, linkId);
566+
break;
567+
default:
568+
throw std::runtime_error("Error checking unsupported for this card type");
533569
}
534570

535-
bool hasError = checkErrors(pageAddress, pageSize, readoutCount);
536571
if (hasError && !mOptions.noResyncCounter) {
537572
// Resync the counter
538-
mDataGeneratorCounter = getDataGeneratorCounterFromPage();
573+
mLinkCounters[linkId] = getDataGeneratorCounterFromPage(pageAddress);
539574
}
540575
}
541576

@@ -545,39 +580,40 @@ class ProgramDmaBench: public Program
545580
}
546581
}
547582

548-
bool checkErrorsCru(uintptr_t pageAddress, size_t pageSize, int64_t eventNumber)
583+
bool checkErrorsCru(uintptr_t pageAddress, size_t pageSize, int64_t eventNumber, int linkId)
549584
{
550-
auto counter = mDataGeneratorCounter;
585+
uint64_t counter = mLinkCounters[linkId];
551586
// Get stuff from the header
552-
auto words = get32bitFromPage(pageAddress, 4); // Amount of 256 bit words in DMA page
553-
auto wordsBytes = words * 256 / 8;
587+
auto words256 = Cru::DataFormat::getEventSize(reinterpret_cast<const char*>(pageAddress)); // Amount of 256 bit words in DMA page
588+
auto wordsBytes = words256 * (256 / 8);
554589

555-
if (words < 2 || wordsBytes > pageSize) {
590+
if (words256 < 2 || wordsBytes > pageSize) {
556591
// Report error
557592
mErrorCount++;
558593
if (mErrorCount < MAX_RECORDED_ERRORS) {
559-
mErrorStream << b::format("event:%d cnt:%d size out of range\n") % eventNumber % counter;
594+
mErrorStream << b::format("event:%1% l:%2% cnt:%3% words:%4% size:%5% words out of range\n") % eventNumber
595+
% linkId % counter % words256 % pageSize;
560596
}
561597
return false;
562598
}
563599

564-
mDataGeneratorCounter += words - 2;
565-
566600
auto page = reinterpret_cast<const volatile uint32_t*>(pageAddress);
567-
constexpr uint32_t HEADER_WORDS = 2; // We skip the 2 header words
601+
constexpr size_t HEADER_WORDS_256 = Cru::DataFormat::getHeaderSizeWords(); // We skip the header
602+
603+
mLinkCounters[linkId] += words256 - HEADER_WORDS_256;
568604

569-
for (uint32_t i = 0; (i + HEADER_WORDS) < words; ++i) {
570-
constexpr uint32_t INTS_PER_WORD = 8; // Each word should contain 8 identical 32-bit integers
571-
for (uint32_t j = 0; j < INTS_PER_WORD; ++j) {
605+
for (uint32_t i = 0; (i + HEADER_WORDS_256) < words256; ++i) {
606+
constexpr uint32_t INTS_PER_WORD_256 = 8; // Each word should contain 8 identical 32-bit integers
607+
for (uint32_t j = 0; j < INTS_PER_WORD_256; ++j) {
572608
uint32_t expectedValue = counter + i;
573-
uint32_t actualValue = page[(i + HEADER_WORDS) * INTS_PER_WORD + j];
609+
uint32_t actualValue = page[(i + HEADER_WORDS_256) * INTS_PER_WORD_256 + j];
574610

575611
if (actualValue != expectedValue) {
576612
// Report error
577613
mErrorCount++;
578614
if (mErrorCount < MAX_RECORDED_ERRORS) {
579-
mErrorStream << b::format("event:%d i:%d cnt:%d exp:0x%x val:0x%x\n")
580-
% eventNumber % i % counter % expectedValue % actualValue;
615+
mErrorStream << b::format("event:%d l:%d i:%d cnt:%d exp:0x%x val:0x%x\n")
616+
% eventNumber % linkId % i % counter % expectedValue % actualValue;
581617
}
582618
return true;
583619
}
@@ -625,10 +661,10 @@ class ProgramDmaBench: public Program
625661
}
626662
}
627663

628-
bool checkErrorsCrorc(uintptr_t pageAddress, size_t pageSize, int64_t eventNumber)
664+
bool checkErrorsCrorc(uintptr_t pageAddress, size_t pageSize, int64_t eventNumber, int linkId)
629665
{
630-
auto counter = mDataGeneratorCounter;
631-
mDataGeneratorCounter++;
666+
uint64_t counter = mLinkCounters[linkId];
667+
mLinkCounters[linkId]++;
632668

633669
auto check = [&](auto patternFunction) {
634670
auto page = reinterpret_cast<const volatile uint32_t*>(pageAddress);
@@ -665,19 +701,6 @@ class ProgramDmaBench: public Program
665701
<< ErrorInfo::GeneratorPattern(mOptions.generatorPattern));
666702
}
667703

668-
/// Checks and reports errors
669-
bool checkErrors(uintptr_t pageAddress, size_t pageSize, int64_t eventNumber)
670-
{
671-
switch (mCardType) {
672-
case CardType::Crorc:
673-
return checkErrorsCrorc(pageAddress, pageSize, eventNumber);
674-
case CardType::Cru:
675-
return checkErrorsCru(pageAddress, pageSize, eventNumber);
676-
default:
677-
throw std::runtime_error("Error checking unsupported for this card type");
678-
}
679-
}
680-
681704
void resetPage(uintptr_t pageAddress, size_t pageSize)
682705
{
683706
auto page = reinterpret_cast<volatile uint32_t*>(pageAddress);
@@ -891,7 +914,6 @@ class ProgramDmaBench: public Program
891914
std::atomic<uint64_t> mPushCount { 0 };
892915
std::atomic<uint64_t> mReadoutCount { 0 };
893916
int64_t mErrorCount = 0;
894-
int64_t mDataGeneratorCounter = -1;
895917
size_t mSuperpageSize = 0;
896918
size_t mMaxSuperpages = 0;
897919
size_t mPagesPerSuperpage = 0;
@@ -930,7 +952,12 @@ class ProgramDmaBench: public Program
930952

931953
InfoLogger mLogger;
932954

955+
std::set<uint32_t> mLinkMask;
956+
933957
std::shared_ptr<DmaChannelInterface> mChannel;
958+
959+
/// Page counters per link. Indexed by link ID.
960+
std::array<std::atomic<uint64_t>, MAX_LINKS> mLinkCounters;
934961
};
935962

936963
int main(int argc, char** argv)

src/Cru/DataFormat.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ uint32_t getEventSize(const char* data)
3939
return Utilities::getBits(getWord(data, 3), 4, 4+12-1);
4040
}
4141

42+
/// Get header size in bytes
43+
constexpr size_t getHeaderSize()
44+
{
45+
// Two 256-bit words = 64 bytes
46+
return 64;
47+
}
48+
49+
/// Get header size in 256-bit words
50+
constexpr size_t getHeaderSizeWords()
51+
{
52+
return 2;
53+
}
54+
4255
} // namespace DataFormat
4356
} // namespace Cru
4457
} // namespace roc

0 commit comments

Comments
 (0)