17 #ifndef SC_INCLUDE_DYNAMIC_PROCESSES
18 #define SC_INCLUDE_DYNAMIC_PROCESSES
21 #include <ahb/ahb_tlm.h>
22 #include <scc/report.h>
23 #include <scc/utilities.h>
24 #include <tlm/scc/tlm_mm.h>
27 using namespace sc_core;
29 template <
unsigned DWIDTH,
unsigned AWIDTH>
33 SC_THREAD(bus_addr_task);
34 SC_THREAD(bus_data_task);
35 isckt.register_nb_transport_bw([
this](tlm::tlm_generic_payload& gp, tlm::tlm_phase& phase, sc_core::sc_time& delay) {
36 if(phase == tlm::END_REQ) {
37 end_req_evt.notify(delay);
38 waiting4end_req =
false;
39 }
else if(phase == tlm::BEGIN_RESP) {
41 end_req_evt.notify(delay);
42 waiting4end_req =
false;
44 resp_que.notify(gp, delay);
46 return tlm::TLM_ACCEPTED;
53 auto const width_exp = scc::ilog2(DWIDTH / 8);
55 auto& htrans = HTRANS_i.read();
56 auto& hsel = HSEL_i.read();
57 auto& hready = HREADY_o.read();
58 auto& size = HSIZE_i.read();
60 if(!HRESETn_i.read()) {
61 wait(HRESETn_i.posedge_event());
63 wait(HCLK_i.posedge_event());
64 if(hsel && hready && htrans > 1) {
67 SCCERR(SCMOD) <<
"Access size (" << sz <<
") is larger than bus wDWIDTH(" << width_exp <<
")!";
68 unsigned length = (1 << sz);
71 gp->set_streaming_width(length);
72 gp->set_address(HADDR_i.read());
73 auto* ext = gp->get_extension<ahb_extension>();
74 ext->set_locked(HMASTLOCK_i.read());
75 ext->set_protection(HPROT_i.read());
76 ext->set_seq(htrans == 3);
77 ext->set_burst(
static_cast<ahb::burst_e
>(HBURST_i.read().to_uint()));
83 tx_in_flight.notify(*gp);
90 auto const width = DWIDTH / 8;
91 auto& wdata = HWDATA_i.read();
94 if(!HRESETn_i.read()) {
95 HREADY_o.write(
false);
96 wait(HRESETn_i.posedge_event());
99 auto gp = wait4tx(tx_in_flight);
100 auto ext = gp->template get_extension<ahb::ahb_extension>();
101 auto start_offs = gp->get_address() & (width - 1);
102 sc_assert((start_offs + gp->get_data_length()) <= width);
103 auto len = gp->get_data_length();
104 HREADY_o.write(
false);
106 wait(HCLK_i.negedge_event());
107 for(
size_t i = start_offs * 8, j = 0; i < DWIDTH; i += 8, ++j)
108 *(uint8_t*)(gp->get_data_ptr() + j) = wdata.range(i + 7, i).to_uint();
110 SCCDEBUG(SCMOD) <<
"Send beg req for " << (gp->is_write() ?
"write to" :
"read from") <<
" addr 0x" << std::hex
111 << gp->get_address();
113 tlm::tlm_phase phase{tlm::BEGIN_REQ};
114 auto res = isckt->nb_transport_fw(*gp, phase, delay);
115 if(res == tlm::TLM_ACCEPTED) {
116 waiting4end_req =
true;
118 phase = tlm::END_REQ;
120 SCCDEBUG(SCMOD) <<
"Recv end req for " << (gp->is_write() ?
"write to" :
"read from") <<
" addr 0x" << std::hex
121 << gp->get_address();
122 if(phase != tlm::BEGIN_RESP) {
123 auto resp = wait4tx(resp_que);
124 sc_assert(gp == resp);
126 SCCDEBUG(SCMOD) <<
"Recv beg resp for " << (gp->is_write() ?
"write to" :
"read from") <<
" addr 0x" << std::hex
127 << gp->get_address();
130 for(
size_t i = start_offs * 8, j = 0; j < len; i += 8, ++j)
131 data.range(i + 7, i) = *(uint8_t*)(gp->get_data_ptr() + j);
132 HRDATA_o.write(data);
134 delay = sc_core::SC_ZERO_TIME;
135 phase = tlm::END_RESP;
136 SCCDEBUG(SCMOD) <<
"Send end resp for " << (gp->is_write() ?
"write to" :
"read from") <<
" addr 0x" << std::hex
137 << gp->get_address();
138 res = isckt->nb_transport_fw(*gp, phase, delay);
140 HREADY_o.write(
true);
141 wait(HCLK_i.posedge_event());
payload_type * allocate()
get a plain tlm_payload_type without extensions
static tlm_mm & get()
accessor function of the singleton