Line data Source code
1 : #include "dtcInterfaceLib/EVBErrorStatus.h"
2 :
3 : #include <array>
4 : #include <iostream>
5 : #include <stdexcept>
6 :
7 : namespace {
8 893 : void require(bool condition, const std::string& message)
9 : {
10 893 : if (!condition)
11 1 : throw std::runtime_error(message);
12 892 : }
13 :
14 864 : std::string bitLine(const std::vector<std::string>& lines, unsigned bit)
15 : {
16 864 : const std::string prefix = " Bit " + std::to_string(bit) + " set: ";
17 3413 : for (const auto& line : lines)
18 2576 : if (line.compare(0, prefix.size(), prefix) == 0)
19 27 : return line;
20 837 : return {};
21 864 : }
22 : } // namespace
23 :
24 1 : int main()
25 : try
26 : {
27 1 : const std::array<const char*, 32> names = {{
28 : "write-while-full",
29 : "sequence gap",
30 : "valid EVB frame rejected",
31 : "DDR write CDC FIFO empty",
32 : "undefined TX state",
33 : "sent/drained counters disagree",
34 : "local stream misaligned",
35 : "stats pipeline collision",
36 : "DDR read desync",
37 : "staging FIFO write-while-full",
38 : "staging FIFO empty inside TX payload",
39 : "TX frame malformed",
40 : "Rx frame had fewer/more data words than its header declared",
41 : "Rx FCS bad",
42 : "ROC tag slip",
43 : "ROC record shape",
44 : "ROC input held",
45 : "self-subevent throttle",
46 : "destination has no credit",
47 : "DDR channel almost-full",
48 : "DDR write CDC FIFO full",
49 : "both staging FIFOs owned",
50 : "Rx source buffer",
51 : "DMA back-pressure",
52 : "peer frontier known",
53 : "DDR calibration complete",
54 : "frame not for this DTC",
55 : nullptr,
56 : nullptr,
57 : nullptr,
58 : nullptr,
59 : nullptr,
60 : }};
61 1 : require(DTCLib::DecodeEVBErrorStatus(0).size() == 2, "Zero value must hide all bit details");
62 56 : for (unsigned bit = 0; bit < names.size(); ++bit)
63 : {
64 28 : const auto lines = DTCLib::DecodeEVBErrorStatus(uint32_t{1} << bit);
65 28 : require(lines.size() == (names[bit] ? 3u : 2u),
66 58 : "Unexpected detail count for bit " + std::to_string(bit));
67 1782 : for (unsigned other = 0; other < names.size(); ++other)
68 : {
69 864 : const auto line = bitLine(lines, other);
70 864 : if (other == bit && names[bit])
71 27 : require(line.find(names[bit]) != std::string::npos,
72 54 : "Wrong decode for bit " + std::to_string(bit));
73 : else
74 1674 : require(line.empty(), "Displayed an unset or reserved bit");
75 864 : }
76 28 : }
77 :
78 0 : const auto mixed = DTCLib::DecodeEVBErrorStatus(0x040007C4u);
79 0 : require(mixed.front().find("0x07c4") != std::string::npos, "Wrong sticky error mask");
80 0 : require(bitLine(mixed, 2).find("valid EVB frame rejected") != std::string::npos,
81 : "Bit 2 must describe rejected EVB frames");
82 0 : require(bitLine(mixed, 6).find("not dropped") != std::string::npos,
83 : "Bit 6 must describe forwarding, not loss at the buffer manager");
84 0 : require(bitLine(mixed, 7).find("data intact") != std::string::npos,
85 : "Bit 7 must distinguish stats corruption from data loss");
86 0 : require(bitLine(mixed, 26).find("sticky since SoftReset, informational") != std::string::npos,
87 : "Bit 26 must be sticky informational");
88 0 : const auto foreignOnly = DTCLib::DecodeEVBErrorStatus(1u << 26);
89 0 : require(foreignOnly.front().find("0x0000") != std::string::npos,
90 : "Foreign frames must not set the error field");
91 0 : require(foreignOnly[1].find("bit 26 sticky-informational, others live") != std::string::npos,
92 : "Status heading must describe the sticky exception");
93 0 : require(foreignOnly[1].find("0x0400") != std::string::npos, "Wrong status mask");
94 0 : const auto all = DTCLib::DecodeEVBErrorStatus(0xFFFFFFFFu);
95 0 : require(all.size() == 29, "All bits must display only the 27 defined details and two headings");
96 0 : require(all.front().find("0xffff") != std::string::npos, "Raw error field must show all 16 bits");
97 0 : require(bitLine(all, 4).find("TX window overrun") != std::string::npos,
98 : "Bit 4 must include the 2026-09-19 window-overrun meaning");
99 0 : require(bitLine(all, 14).find("upstream") != std::string::npos,
100 : "Bit 14 must say the slip originated upstream of EVB3");
101 0 : require(bitLine(all, 2).find("addressed to this DTC but source offset > 31") != std::string::npos,
102 : "Bit 2 must exclude foreign frames");
103 0 : require(bitLine(all, 7).find("bit 1 and Rx BRAM rows/rates untrustworthy") != std::string::npos,
104 : "Bit 7 must qualify sequence-gap and Rx statistics");
105 0 : require(bitLine(all, 12).find("receiver-side print of a peer's bit 9") != std::string::npos,
106 : "Bit 12 must identify itself as the receiver-side view of a peer's staging-FIFO fault (hw agent 2026-10-16)");
107 0 : require(bitLine(all, 13).find("shifted 0x33 frames not checked") != std::string::npos,
108 : "FCS checking must not be claimed for shifted frames");
109 :
110 0 : constexpr uint32_t calibrated = 1u << 25;
111 0 : require(!DTCLib::CheckEVBStatus(0).readyToStart(), "Missing DDR calibration must block start");
112 0 : require(DTCLib::CheckEVBStatus(calibrated).readyToStart(), "Calibrated idle DTC must be ready");
113 0 : for (unsigned bit = 0; bit < 32; ++bit)
114 : {
115 0 : const auto check = DTCLib::CheckEVBStatus(calibrated | (1u << bit));
116 0 : require(check.stickyErrors == (bit < 16 ? (1u << bit) : 0u),
117 0 : "Wrong defined error mask for bit " + std::to_string(bit));
118 0 : require(check.readyToStart() == (bit >= 16),
119 : "Only defined sticky errors should block a calibrated DTC");
120 : }
121 0 : require(!DTCLib::CheckEVBStatus(calibrated, false).missingFrontier,
122 : "No frontier warning before traffic");
123 0 : require(DTCLib::CheckEVBStatus(calibrated, true).missingFrontier,
124 : "Missing frontier after traffic must warn");
125 0 : require(!DTCLib::CheckEVBStatus(calibrated | (1u << 24), true).missingFrontier,
126 : "Valid frontier must not warn");
127 0 : require(!DTCLib::CheckEVBStatus(calibrated, true, false).missingFrontier,
128 : "Single-node partition has no peer frontier requirement");
129 0 : const auto report = DTCLib::FormatEVBStatusCheck(calibrated | 0xFFFFu, "DTC_1", true);
130 0 : require(report.find("DTC DTC_1 EVB error/status (0x9370): 0x0200ffff") != std::string::npos,
131 : "Report must identify the DTC and exact raw snapshot");
132 0 : require(report.find("ROC input (upstream of EVB3)") == std::string::npos,
133 : "Bits 14-15 belong in the data-corrupt group, not a separate one");
134 0 : require(report.find("ERROR: run INVALID") != std::string::npos, "Errors must invalidate run");
135 0 : require(report.find("Data lost: Bit 0 RX_BUF_WRITE_FULL; Bit 1 RX_SEQ_GAP; Bit 9 STAGING_WRITE_FULL; Bit 12 RX_FRAME_SIZE;") != std::string::npos,
136 : "Wrong data-loss group");
137 0 : require(report.find("Data corrupt: Bit 3 DDR_WR_UNDERFLOW; Bit 6 LOCAL_BAD_HEADER; Bit 8 DDR_RD_BAD_COUNT; Bit 10 TX_PAYLOAD_UNDERFLOW; Bit 11 TX_FRAME_MALFORMED; Bit 13 RX_FCS_BAD; Bit 14 ROC_TAG_SLIP; Bit 15 ROC_RECORD_SHAPE;") != std::string::npos,
138 : "Wrong data-corruption group");
139 0 : require(report.find("Protocol / config: Bit 2 RX_PKT_REJECTED; Bit 4 TX_FSM_FAULT; Bit 5 CREDIT_VIOLATION; Bit 7 RX_STATS_COLLISION;") != std::string::npos,
140 : "Wrong protocol/config group");
141 0 : require(report.find("SoftReset all DTCs together") != std::string::npos,
142 : "Report must require coordinated reset");
143 0 : const auto informational = DTCLib::FormatEVBStatusCheck(0x07FF0000u, "DTC_0", true);
144 0 : require(informational.find("ERROR:") == std::string::npos,
145 : "Back-pressure and foreign frames must never invalidate a run");
146 0 : const auto plain = DTCLib::FormatEVBStatusCheck(calibrated | (1u << 11), "DTC_0", false, true, false);
147 0 : require(plain.find("TX_FRAME_MALFORMED") == std::string::npos &&
148 0 : plain.find("Bit 11 set: TX frame malformed") != std::string::npos,
149 : "GUI mode must retain plain-language descriptions without symbolic names");
150 0 : const auto noDDR = DTCLib::FormatEVBStatusCheck(0, "DTC_0");
151 0 : require(noDDR.find("DDR not calibrated; do not start") != std::string::npos,
152 : "Missing calibration must be explicit");
153 :
154 0 : std::cout << "EVB error/status decoding and B3 checks passed\n";
155 0 : return 0;
156 0 : }
157 1 : catch (const std::exception& error)
158 : {
159 1 : std::cerr << error.what() << '\n';
160 1 : return 1;
161 1 : }
|