Program Listing for File decoder.hpp
↰ Return to documentation for file (decoder.hpp
)
#ifndef FELIX_DECODER_H_
#define FELIX_DECODER_H_
#include <string>
#include <memory>
#include "device.hpp"
#include "elink.hpp"
#include "tohost_monitor.hpp"
#include "block.hpp"
#include "publisher.hpp"
#include "l0id_decoder.hpp"
struct chunk_buffer
{
std::uint8_t m_status_byte{};
size_t chunk_size{};
std::vector<iovec> iov;
chunk_buffer() : m_status_byte(0), chunk_size(0){
iov.emplace_back(&m_status_byte, 1);
};
void push_back(iovec&& x) {
iov.push_back(x);
chunk_size += x.iov_len;
}
void clear() noexcept {
iov.resize(1);
chunk_size = 0;
m_status_byte = 0;
}
bool empty() const noexcept {
// Status byte
return iov.size() == 1;
}
void remove_last_entry() {
chunk_size -= iov.back().iov_len;
iov.resize(iov.size()-1);
}
void update_status_byte(uint8_t status) {
m_status_byte |= status;
}
uint8_t get_status_byte() const {
return m_status_byte;
}
size_t byte_size() {
return chunk_size;
}
size_t iov_len() {
return iov.size();
}
iovec* iov_addr() {
return iov.data();
}
};
class Decoder
{
public:
Decoder(const Decoder&) = delete;
Decoder& operator=(const Decoder&) = delete;
Decoder(Decoder&&) = default;
Decoder& operator=(Decoder&&) = default;
Decoder(const Elink &elink, Publisher &publisher, flx_tohost_format fmt,
int l0id_decoder_fmt, unsigned int block_size, uint64_t buf_vaddr);
uint32_t get_last_block(){return m_last_block;}
uint64_t get_fid(){return m_elink.fid;}
void set_block_size(unsigned int block_size){m_block_size = block_size;}
Publisher::Result decode(Block & block);
ToHostElinkStats get_decoder_stats(){return m_stats;}
ToHostElinkStats get_decoder_stats_increment(ToHostElinkStats & previous);
private:
enum SubchunkType {
NIL = 0, FIRST, LAST, WHOLE, MIDDLE, TIMEOUT, OOB
};
Publisher::Result post_subchunk(uint8_t *data, uint32_t length, SubchunkType type, uint8_t err);
[[nodiscard]] Publisher::Result check_block_integrity(Block & block);
Publisher::Result decode_subchunk_headers(Block & block);
Publisher::Result decode_subchunk_trailers(Block & block);
void on_successful_send();
private:
ToHostElinkStats m_stats;
Elink m_elink;
Publisher &m_publisher;
uint64_t m_buffer_vaddr;
unsigned int m_block_size;
uint8_t m_seqnr_err = 0;
uint8_t m_last_seqnr = 0;
uint32_t m_last_block = 0;
uint16_t m_chunk_position = 0;
std::function< Publisher::Result(Block & block)> m_decode;
std::unique_ptr<L0Decoder> m_l0id_checker;
std::vector<std::pair<uint16_t, uint32_t>> m_subchunks;
chunk_buffer m_scratch;
};
#endif /* FELIX_DECODER_H_ */