17 #ifndef SC_INCLUDE_DYNAMIC_PROCESSES
18 #define SC_INCLUDE_DYNAMIC_PROCESSES
20 #include "initiator.h"
21 #include <ahb/ahb_tlm.h>
22 #include <scc/report.h>
23 #include <scc/utilities.h>
26 using namespace sc_core;
28 template <
unsigned WIDTH>
32 SC_THREAD(bus_addr_task);
33 SC_THREAD(bus_data_task);
35 tsckt.register_nb_transport_fw(
36 [
this](tlm::tlm_generic_payload& payload, tlm::tlm_phase& phase, sc_core::sc_time& delay) -> tlm::tlm_sync_enum {
37 if(phase == tlm::BEGIN_REQ) {
40 auto* ext = payload.get_extension<ahb_extension>();
42 ext = new ahb_extension();
43 payload.set_extension(ext);
45 this->inqueue.notify(payload);
47 return tlm::TLM_ACCEPTED;
52 auto& hready = HREADY_i.read();
54 wait(inqueue.get_event());
55 while(
auto trans = inqueue.get_next_transaction()) {
56 sc_assert(trans->get_data_length() * 8 <= WIDTH &&
"Transaction length larger than bus width, this is not supported");
57 SCCDEBUG(SCMOD) <<
"Recv beg req for read to addr 0x" << std::hex << trans->get_address();
58 auto bytes_exp = scc::ilog2(trans->get_data_length());
59 auto width_exp = scc::ilog2(WIDTH / 8);
61 for(; size < bytes_exp; ++size)
62 if(trans->get_address() & (1 << size))
64 auto* ext = trans->template get_extension<ahb_extension>();
65 HADDR_o.write(trans->get_address());
66 HWRITE_o.write(trans->is_write());
67 HMASTLOCK_o.write(ext->is_locked());
68 HPROT_o.write(ext->get_protection());
69 HBURST_o.write(
static_cast<unsigned>(ext->get_burst()));
71 HTRANS_o.write(
static_cast<unsigned>(ext->is_seq() ? trans_e::SEQ : trans_e::NONSEQ));
73 wait(HCLK_i.posedge_event());
75 SCCDEBUG(SCMOD) <<
"Send end req for read to addr 0x" << std::hex << trans->get_address();
76 tlm::tlm_phase phase{tlm::END_REQ};
78 auto res = tsckt->nb_transport_bw(*trans, phase, delay);
79 tx_in_flight.notify(*trans);
80 HTRANS_o.write(
static_cast<unsigned>(trans_e::IDLE));
86 auto const width = WIDTH / 8;
87 auto& hready = HREADY_i.read();
88 auto& rdata = HRDATA_i.read();
90 wait(tx_in_flight.get_event());
91 while(
auto trans = tx_in_flight.get_next_transaction()) {
92 auto bytes_exp = scc::ilog2(trans->get_data_length());
93 auto width_exp = scc::ilog2(WIDTH / 8);
95 for(; size < width_exp; ++size)
96 if(trans->get_address() & (1 << size))
98 auto beats = bytes_exp < size ? 1 : 1 << (bytes_exp - size);
99 auto start_offs = trans->get_address() & (width - 1);
100 auto len = trans->get_data_length();
101 if(trans->is_write()) {
103 for(
size_t i = start_offs * 8, j = 0; i < WIDTH; i += 8, ++j)
104 data.range(i + 7, i) = *(uint8_t*)(trans->get_data_ptr() + j);
105 HWDATA_o.write(data);
106 trans->set_response_status(tlm::TLM_OK_RESPONSE);
107 tlm::tlm_phase phase{tlm::BEGIN_RESP};
109 tsckt->nb_transport_bw(*trans, phase, delay);
112 wait(HCLK_i.posedge_event());
114 if(trans->is_read()) {
115 for(
size_t i = start_offs * 8, j = 0; i < WIDTH; i += 8, ++j)
116 *(uint8_t*)(trans->get_data_ptr() + j) = rdata.range(i + 7, i).to_uint();
117 trans->set_response_status(tlm::TLM_OK_RESPONSE);
118 tlm::tlm_phase phase{tlm::BEGIN_RESP};
120 tsckt->nb_transport_bw(*trans, phase, delay);