4.5.6. AXI#

4.5.6.1. AXI-Light#

4.5.6.1.1. AXI Subordinate#

namespace simbricks#

Functions

inline uint64_t pow2(uint64_t exponent)#
struct AXIOperation#

Public Functions

inline AXIOperation(uint64_t addr, size_t len, uint64_t axi_id, size_t step_size)#

Public Members

uint64_t addr#
size_t len#
uint64_t id#
std::unique_ptr<uint8_t[]> buf#
size_t step_size#
bool completed = false#
template<size_t BytesAddr, size_t BytesId, size_t BytesData, size_t MaxInFlight = 16>
class AXISubordinateRead#

Public Functions

inline AXISubordinateRead(const uint8_t *const ar_addr, const uint8_t *const ar_id, uint8_t &ar_ready, const uint8_t &ar_valid, const uint8_t &ar_len, const uint8_t &ar_size, const uint8_t &ar_burst, uint8_t *const r_data, uint8_t *const r_id, const uint8_t &r_ready, uint8_t &r_valid, uint8_t &r_last)#
void read_done(uint64_t axi_id, const uint8_t *data)#
void step(uint64_t cur_ts)#
void step_apply()#

Protected Functions

virtual void do_read(const AXIOperation &axi_op) = 0#

Private Functions

void send_next_data_segment()#

Private Members

const uint8_t *const ar_addr_#
const uint8_t *const ar_id_#
uint8_t &ar_ready_#
const uint8_t &ar_valid_#
const uint8_t &ar_len_#
const uint8_t &ar_size_#
const uint8_t &ar_burst_#
uint8_t *const r_data_#
uint8_t *const r_id_#
const uint8_t &r_ready_#
uint8_t &r_valid_#
uint8_t &r_last_#
uint8_t ar_ready_tmp_ = 0#
uint8_t r_valid_tmp_ = 0#
uint8_t r_last_tmp_ = 0#
uint8_t r_data_tmp_[BytesData] = {0}#
uint32_t r_id_tmp_#
uint64_t main_time_ = 0#
std::deque<AXIOperation> pending_ = {}#
std::unordered_map<uint64_t, std::reference_wrapper<AXIOperation>> id_op_map_ = {}#
AXIOperation *cur_op_ = nullptr#
size_t cur_off_ = 0#
uint32_t rolling_id_ = 0#
template<size_t BytesAddr, size_t BytesId, size_t BytesData, size_t MaxInFlight = 16>
class AXISubordinateWrite#

Public Functions

inline AXISubordinateWrite(const uint8_t *aw_addr, const uint8_t *aw_id, uint8_t &aw_ready, const uint8_t &aw_valid, const uint8_t &aw_len, const uint8_t &aw_size, const uint8_t &aw_burst, const uint8_t *w_data, uint8_t &w_ready, const uint8_t &w_valid, const uint8_t &w_strb, const uint8_t &w_last, uint8_t *b_id, const uint8_t &b_ready, uint8_t &b_valid, uint8_t &b_resp)#
void write_done(uint64_t axi_id)#
void step(uint64_t cur_ts)#
void step_apply()#

Protected Functions

virtual void do_write(const AXIOperation &axi_op) = 0#

Private Members

const uint8_t *const aw_addr_#
const uint8_t *const aw_id_#
uint8_t &aw_ready_#
const uint8_t &aw_valid_#
const uint8_t &aw_len_#
const uint8_t &aw_size_#
const uint8_t &aw_burst_#
const uint8_t *const w_data_#
uint8_t &w_ready_#
const uint8_t &w_valid_#
const uint8_t &w_strb_#
const uint8_t &w_last_#
uint8_t *const b_id_#
const uint8_t &b_ready_#
uint8_t &b_valid_#
uint8_t &b_resp_#
uint8_t aw_ready_tmp_ = 0#
uint8_t w_ready_tmp_ = 0#
uint8_t b_valid_tmp_ = 0#
uint64_t b_id_tmp_ = 0#
uint64_t main_time_ = 0#
uint64_t cur_off_ = 0#
uint64_t num_pending_ = 0#
std::optional<AXIOperation> cur_op_ = std::nullopt#

4.5.6.1.2. AXIL Manager#

namespace simbricks
struct AXILOperationR#

Public Functions

inline AXILOperationR(uint64_t addr, uint64_t req_id)#

Public Members

uint64_t addr#
uint64_t req_id#
uint64_t data = 0#
struct AXILOperationW#

Public Functions

inline AXILOperationW(uint64_t addr, uint64_t req_id, uint64_t data, bool posted)#

Public Members

uint64_t addr#
uint64_t req_id#
uint64_t data#
bool posted#
template<size_t BytesAddr, size_t BytesData>
class AXILManagerReadPort#

Public Functions

inline AXILManagerReadPort(uint8_t *ar_addr, const uint8_t &ar_ready, uint8_t &ar_valid, const uint8_t *r_data, uint8_t &r_ready, const uint8_t &r_valid, uint8_t &r_resp, std::function<void()> op_done_cb)#
void step(uint64_t cur_ts)#
void step_apply()#
inline void set_op(AXILOperationR &axi_op)#

Private Members

uint8_t *const ar_addr_#
const uint8_t &ar_ready_#
uint8_t &ar_valid_#
const uint8_t *const r_data_#
uint8_t &r_ready_#
const uint8_t &r_valid_#
uint8_t &r_resp_#
uint8_t ar_valid_tmp_ = 0#
uint64_t ar_addr_tmp_ = 0#
uint64_t main_time_ = 0#
AXILOperationR *cur_op_ = nullptr#
std::function<void()> op_done_cb_#
bool handling_op_ = false#
template<size_t BytesAddr, size_t BytesData>
class AXILManagerWritePort#

Public Functions

inline AXILManagerWritePort(uint8_t *aw_addr, const uint8_t &aw_ready, uint8_t &aw_valid, uint8_t *w_data, const uint8_t &w_ready, uint8_t &w_valid, uint8_t &w_strb, uint8_t &b_ready, const uint8_t &b_valid, const uint8_t &b_resp, std::function<void()> op_done_cb)#
void step(uint64_t cur_ts)#
void step_apply()#
inline void set_op(AXILOperationW &axi_op)#

Private Members

uint8_t *const aw_addr_#
const uint8_t &aw_ready_#
uint8_t &aw_valid_#
uint8_t *const w_data_#
const uint8_t &w_ready_#
uint8_t &w_valid_#
uint8_t &w_strb_#
uint8_t &b_ready_#
const uint8_t &b_valid_#
const uint8_t &b_resp_#
uint8_t aw_valid_tmp_ = 0#
uint64_t aw_addr_tmp_ = 0#
uint8_t w_valid_tmp_ = 0#
uint64_t w_data_tmp_ = 0#
uint64_t main_time_ = 0#
AXILOperationW *cur_op_ = nullptr#
std::function<void()> op_done_cb_#
bool handling_op_ = false#
template<size_t BytesAddr, size_t BytesData>
class AXILManager#

Public Functions

inline AXILManager(uint8_t *ar_addr, const uint8_t &ar_ready, uint8_t &ar_valid, const uint8_t *r_data, uint8_t &r_ready, const uint8_t &r_valid, uint8_t &r_resp, uint8_t *aw_addr, const uint8_t &aw_ready, uint8_t &aw_valid, uint8_t *w_data, const uint8_t &w_ready, uint8_t &w_valid, uint8_t &w_strb, uint8_t &b_ready, const uint8_t &b_valid, const uint8_t &b_resp)#
void step(uint64_t cur_ts)#
void step_apply()#
void issue_read(uint64_t req_id, uint64_t addr)#
void issue_write(uint64_t req_id, uint64_t addr, uint64_t data, bool posted)#

Protected Functions

virtual void read_done(AXILOperationR &axi_op) = 0#
virtual void write_done(AXILOperationW &axi_op) = 0#

Private Types

enum [anonymous]#

Values:

enumerator NONE#
enumerator READ#
enumerator WRITE#
using ReadPortT = AXILManagerReadPort<BytesAddr, BytesData>#
using WritePortT = AXILManagerWritePort<BytesAddr, BytesData>#

Private Functions

void op_done()#
void ports_set_op()#

Private Members

ReadPortT read_port_#
WritePortT write_port_#
std::deque<std::variant<AXILOperationR, AXILOperationW>> pending_ = {}#
enum simbricks::AXILManager::[anonymous] step_on_ = NONE#

4.5.6.2. AXI-Stream#

namespace simbricks
template<size_t DataWidthBytes = 4, size_t AmountSlots = 32, size_t BufferSize = 2048, typename = typename std::enable_if_t<(DataWidthBytes >= 1) and (DataWidthBytes <= 128) and simbricks::isPowerOfTwo(DataWidthBytes) and (AmountSlots > 0)>>
class AXISManager#

Public Functions

inline explicit AXISManager(uint8_t &tvalid, const uint8_t &tready, uint8_t *const tdata, uint8_t *const tkeep, uint8_t &tlast, const uint8_t *const tuser)#
inline bool full() const noexcept#
inline bool empty() const noexcept#
inline void read(const uint8_t *data, size_t len) noexcept#

When implementing the exchange of SimBricks messages within a Simulators adapter, this method shall be called if e.g. the AXI stream interface receives a packet. This can e.g. happen if a NIC receives a network packet.

inline void step() noexcept#

Private Functions

inline void move_read_head() noexcept#
inline bool data_transfer_can_happen() const#
inline void setIndex(uint8_t *const bitmap, size_t index) const#
inline void reset(uint8_t *bitmap, size_t size)#

Private Members

uint8_t &tvalid_#

TVALID indicates the Transmitter is driving a valid transfer. A transfer takes place when both TVALID and TREADY are asserted.

const uint8_t &tready_#

TREADY indicates that a Receiver can accept a transfer.

uint8_t *const tdata_#

TDATA is the primary payload used to provide the data that is passing across the interface. TDATA_WIDTH must be an integer number of bytes and is recommended to be 8, 16, 32, 64, 128, 256, 512 or 1024-bits.

uint8_t *const tkeep_#

TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte TKEEP is the byte qualifier that indicates whether content of the associated byte of TDATA is processed as part of the data stream.

const size_t kKeepWidth = DataWidthBytes / 8#
uint8_t &tlast_#

TLAST indicates the boundary of a packet

const uint8_t *const tuser_#

TID is a data stream identifier. TDEST provides routing information for the data stream. TUSER is a user-defined sideband information that can be transmitted along the data stream. TUSER_WIDTH is recommended to be an integer multiple of TDATA_WIDTH/8.

std::array<core::ManagerBuffer<BufferSize>, AmountSlots> buffer_ring_#

TWAKEUP identifies any activity associated with AXI-Stream interface. Packet ring-buffer for storing packets that shall be sent

size_t write_index_ = 0#
size_t read_index_ = 0#
size_t cur_size_ = 0#
template<size_t DataWidthBytes = 4, size_t PacketBufSize = 2048, typename = typename std::enable_if_t<(DataWidthBytes >= 1) and simbricks::isPowerOfTwo(DataWidthBytes) and (PacketBufSize >= 2048) and simbricks::isPowerOfTwo(PacketBufSize) and (DataWidthBytes <= 128)>>
class AXISSubordinate#

Public Functions

inline explicit AXISSubordinate(const uint8_t &tvalid, uint8_t &tready, const uint8_t *const tdata, const uint8_t *const tkeep, uint8_t &tlast, const uint8_t *const tuser)#
inline bool is_packet_done() const#
inline void step() noexcept#
inline void write(uint8_t *destination, size_t *len, uint8_t &user) noexcept#

When implementing the exchange of SimBricks messages within a Simulators adapter,this method shall be called to copy the packet data into the SimBricks message buffer.

Private Functions

inline bool data_transfer_can_happen() const#
inline bool isSet(const uint8_t *const bitmap, size_t index) const#

Private Members

const uint8_t &tvalid_#

TVALID indicates the Transmitter is driving a valid transfer. A transfer takes place when both TVALID and TREADY are asserted.

uint8_t &tready_#

TREADY indicates that a Receiver can accept a transfer.

const uint8_t *const tdata_#

TDATA is the primary payload used to provide the data that is passing across the interface. TDATA_WIDTH must be an integer number of bytes and is recommended to be 8, 16, 32, 64, 128, 256, 512 or 1024-bits.

const uint8_t *const tkeep_#

TSTRB is the byte qualifier that indicates whether the content of the associated byte of TDATA is processed as a data byte or a position byte TKEEP is the byte qualifier that indicates whether content of the associated byte of TDATA is processed as part of the data stream.

const size_t kKeepWidth = DataWidthBytes / 8#
uint8_t &tlast_#

TLAST indicates the boundary of a packet

const uint8_t *const tuser_#

TID is a data stream identifier. TDEST provides routing information for the data stream. TUSER is a user-defined sideband information that can be transmitted along the data stream. TUSER_WIDTH is recommended to be an integer multiple of TDATA_WIDTH/8.

core::SubordinateBuffer<PacketBufSize> packet_buf_#

TWAKEUP identifies any activity associated with AXI-Stream interface. Packet Buffer to store the packet that is to be forwarded.

namespace core#
template<size_t BufferSize = 2048, typename = typename std::enable_if_t<(BufferSize >= 2048) and simbricks::isPowerOfTwo(BufferSize)>>
class ManagerBuffer#

Public Functions

inline void reset(const uint8_t *data, size_t len) noexcept#
inline bool done() const noexcept#
inline bool empty() const noexcept#
inline uint8_t read() noexcept#

Private Members

std::array<uint8_t, BufferSize> packet_buf_ = {0}#
size_t packet_len_ = 0#
size_t read_offset_ = 0#
template<size_t BufferSize = 2048, typename = typename std::enable_if_t<(BufferSize >= 2048) and simbricks::isPowerOfTwo(BufferSize)>>
class SubordinateBuffer#

Public Functions

inline bool full() const noexcept#
inline bool done() const noexcept#
inline void setDone() noexcept#
inline void setNextByte(uint8_t by)#
inline void assign(uint8_t *data, size_t *len) noexcept#

Private Members

std::array<uint8_t, BufferSize> packet_buf_ = {0}#
size_t packet_len_ = 0#
bool done_ = 0#