#pragma once #include "RegisterHelperStructs.hpp" #include "fmt/format.h" #include #include #include #include #include #include #include // TODO: maybe should be templated on address type (e.g. uint32_t register or // uint64_t register) for more flexibility? namespace sls { template struct IpCoreRegisterBlock { const std::map &operator()() const { return memoryblocks_; } std::map &operator()() { return memoryblocks_; } private: std::map memoryblocks_; }; template class BusCommunication { public: BusCommunication() = default; void mapToMemory(); uint32_t readRegister(const Register ®ister_) const; void writeRegister(const Register ®ister_, const uint32_t data); private: /// @brief stores register blocks for each IP core IpCoreRegisterBlock ipcoreregisterblocks; void bus_w(const uint32_t offset, IPCoreEnumType baseadress, const uint32_t data); uint32_t bus_r(const uint32_t offset, IPCoreEnumType baseadress) const; }; template void BusCommunication::mapToMemory() { for (auto &map_elem : ipcoreregisterblocks()) { map_elem.second.mapToMemory(); } } template uint32_t BusCommunication::readRegister( const Register ®ister_) const { return bus_r(register_.offset_in_bytes, register_.ip_core); } template void BusCommunication::writeRegister( const Register ®ister_, const uint32_t data) { bus_w(register_.offset_in_bytes, register_.ip_core, data); } template uint32_t BusCommunication::bus_r( const uint32_t offset, const IPCoreEnumType baseadress) const { auto ptr1 = ipcoreregisterblocks().at(baseadress).getMappedMemoryPtr() + offset / (sizeof(uint32_t)); return *ptr1; } template void BusCommunication::bus_w( const uint32_t offset, const IPCoreEnumType baseadress, const uint32_t data) { auto ptr1 = ipcoreregisterblocks().at(baseadress).getMappedMemoryPtr() + offset / (sizeof(uint32_t)); *ptr1 = data; } } // namespace sls