rogue
Loading...
Searching...
No Matches
CoreV1.cpp
Go to the documentation of this file.
1
42
43#include <inttypes.h>
44#include <stdint.h>
45
46#include <cmath>
47#include <memory>
48#include <thread>
49
50#include "rogue/GeneralError.h"
54
57
59rpb::CoreV1Ptr rpb::CoreV1::create() {
60 rpb::CoreV1Ptr p = std::make_shared<rpb::CoreV1>();
61 return (p);
62}
63
65void rpb::CoreV1::setup_python() {}
66
68rpb::CoreV1::CoreV1() {
69 log_ = rogue::Logging::create("batcher.CoreV1");
70
71 headerSize_ = 0;
72 tailSize_ = 0;
73 seq_ = 0;
74}
75
77rpb::CoreV1::~CoreV1() {}
78
80void rpb::CoreV1::initSize(uint32_t size) {
81 list_.reserve(size);
82 tails_.reserve(size);
83}
84
86uint32_t rpb::CoreV1::count() {
87 return list_.size();
88}
89
91uint32_t rpb::CoreV1::headerSize() {
92 return headerSize_;
93}
94
96ris::FrameIterator rpb::CoreV1::beginHeader() {
97 return frame_->begin();
98}
99
101ris::FrameIterator rpb::CoreV1::endHeader() {
102 return frame_->begin() + headerSize_;
103}
104
106uint32_t rpb::CoreV1::tailSize() {
107 return tailSize_;
108}
109
111ris::FrameIterator rpb::CoreV1::beginTail(uint32_t index) {
112 if (index >= tails_.size())
113 throw(rogue::GeneralError::create("bather::CoreV1::beginTail",
114 "Attempt to get tail index %" PRIu32 " in message with %" PRIu32 " tails",
115 index,
116 tails_.size()));
117
118 // Invert order on return
119 return tails_[(tails_.size() - 1) - index];
120}
121
123ris::FrameIterator rpb::CoreV1::endTail(uint32_t index) {
124 if (index >= tails_.size())
125 throw rogue::GeneralError::create("batcher::CoreV1::tail",
126 "Attempt to access tail %" PRIu32 " in frame with %" PRIu32 " tails",
127 index,
128 tails_.size());
129
130 // Invert order on return
131 return tails_[(tails_.size() - 1) - index] + tailSize_;
132}
133
135rpb::DataPtr& rpb::CoreV1::record(uint32_t index) {
136 if (index >= list_.size())
137 throw rogue::GeneralError::create("batcher::CoreV1::record",
138 "Attempt to access record %" PRIu32 " in frame with %" PRIu32 " records",
139 index,
140 tails_.size());
141
142 // Invert order on return
143 return list_[(list_.size() - 1) - index];
144}
145
147uint32_t rpb::CoreV1::sequence() {
148 return seq_;
149}
150
152bool rpb::CoreV1::processFrame(ris::FramePtr frame) {
153 uint8_t temp;
154 uint32_t rem;
155 uint32_t fSize;
156 uint8_t dest;
157 uint8_t fUser;
158 uint8_t lUser;
159 uint32_t fJump;
160
161 // Reset old data
162 reset();
163
167
168 // Drop errored frames
169 if ((frame->getError())) {
170 log_->warning("Dropping frame due to error: 0x%" PRIx8, frame->getError());
171 return false;
172 }
173
174 // Drop small frames
175 if ((rem = frame->getPayload()) < 16) {
176 log_->warning("Dropping small frame size = %" PRIu32, frame->getPayload());
177 return false;
178 }
179
180 // Get version & size
181 beg = frame->begin();
182 ris::fromFrame(beg, 1, &temp);
183
185 // Super-Frame Header in firmware
187 // v.txMaster.tValid := '1';
188 // v.txMaster.tData(3 downto 0) := x"1"; -- Version = 0x1
189 // v.txMaster.tData(7 downto 4) := toSlv(log2(AXIS_WORD_SIZE_C/2), 4);
190 // v.txMaster.tData(15 downto 8) := r.seqCnt;
191 // v.txMaster.tData(511 downto 16) := (others => '0');
192 // ssiSetUserSof(AXIS_CONFIG_G, v.txMaster, '1');
194
195 // Check version, convert width
196 if ((temp & 0xF) != 1) {
197 log_->error("Version mismatch. Got %" PRIu8, (temp & 0xF));
198 return false;
199 }
200
202 // headerSize = (uint32_t)pow(2,float( ( (temp >> 4) & 0xF) + 1) );
204 // Integer pow() when powers of 2 (more efficient than floating point)
205 switch ((temp >> 4) & 0xF) {
206 case 0:
207 headerSize_ = 2;
208 break; // If WIDTH=0x0 (TYPE = 16-bit AXI stream), then appended header is 2 bytes.
209 case 1:
210 headerSize_ = 4;
211 break; // If WIDTH=0x1 (TYPE = 32-bit AXI stream), then appended header is 4 bytes.
212 case 2:
213 headerSize_ = 8;
214 break; // If WIDTH=0x2 (TYPE = 64-bit AXI stream), then appended header is 8 bytes.
215 case 3:
216 headerSize_ = 16;
217 break; // If WIDTH=0x3 (TYPE = 128-bit AXI stream), then appended header is 16 bytes.
218 case 4:
219 headerSize_ = 32;
220 break; // If WIDTH=0x4 (TYPE = 256-bit AXI stream), then appended header is 32 bytes.
221 case 5:
222 headerSize_ = 64;
223 break; // If WIDTH=0x5 (TYPE = 512-bit AXI stream), then appended header is 64 bytes.
224 default:
225 log_->error("Invalid AXIS Type Detected. Got %" PRIu8, ((temp >> 4) & 0xF));
226 return false;
227 }
228
229 // Set tail size, min 64-bits
230 tailSize_ = (headerSize_ < 8) ? 8 : headerSize_;
231
232 // Get sequence #
233 ris::fromFrame(beg, 1, &seq_);
234
235 // Frame needs to large enough for header + 1 tail
236 if (rem < (headerSize_ + tailSize_)) {
237 log_->error("Not enough space (%" PRIu32 ") for tail (%" PRIu32 ") + header (%" PRIu32 ")",
238 rem,
239 headerSize_,
240 tailSize_);
241 reset();
242 return false;
243 }
244
245 // Skip the rest of the header, compute remaining frame size
246 beg += (headerSize_ - 2); // Already read 2 bytes from frame
247 rem -= headerSize_;
248
249 // Set marker to end of frame
250 mark = frame->end();
251
252 // Process each frame, stop when we have reached just after the header
253 while (mark != beg) {
254 // sanity check
255 if (rem < tailSize_) {
256 log_->error("Not enough space (%" PRIu32 ") for tail (%" PRIu32 ")", rem, tailSize_);
257 reset();
258 return false;
259 }
260
261 // Jump to start of the tail
262 mark -= tailSize_;
263 rem -= tailSize_;
264
265 // Add tail iterator to end of list
266 tails_.push_back(mark);
267
268 // Get tail data, use a new iterator
269 tail = mark;
270 ris::fromFrame(tail, 4, &fSize);
271 ris::fromFrame(tail, 1, &dest);
272 ris::fromFrame(tail, 1, &fUser);
273 ris::fromFrame(tail, 1, &lUser);
274
275 // Round up rewind amount to width
276 if ((fSize % headerSize_) == 0)
277 fJump = fSize;
278 else
279 fJump = ((fSize / headerSize_) + 1) * headerSize_;
280
281 // Not enough data for rewind value
282 if (fJump > rem) {
283 log_->error("Not enough space (%" PRIu32 ") for frame (%" PRIu32 ")", rem, fJump);
284 reset();
285 return false;
286 }
287
288 // Set marker to start of data
289 mark -= fJump;
290 rem -= fJump;
291
292 // Create data record and add it to end of list
293 list_.push_back(rpb::Data::create(mark, fSize, dest, fUser, lUser));
294 }
295 return true;
296}
297
299void rpb::CoreV1::reset() {
300 frame_.reset();
301 list_.clear();
302 tails_.clear();
303
304 headerSize_ = 0;
305 tailSize_ = 0;
306 seq_ = 0;
307}
static GeneralError create(std::string src, const char *fmt,...)
Creates a formatted error instance.
static std::shared_ptr< rogue::Logging > create(const std::string &name, bool quiet=false)
Creates a logger instance.
Definition Logging.cpp:60
Random-access byte iterator across a Frame payload.
static void fromFrame(rogue::interfaces::stream::FrameIterator &iter, uint32_t size, void *dst)
Copies bytes from a frame iterator to a destination pointer.
std::shared_ptr< rogue::interfaces::stream::Frame > FramePtr
Shared pointer alias for Frame.
Definition Frame.h:549
std::shared_ptr< rogue::protocols::batcher::Data > DataPtr
Definition Data.h:148
std::shared_ptr< rogue::protocols::batcher::CoreV1 > CoreV1Ptr
Definition CoreV1.h:188