44template <
unsigned int BUSWIDTH = LT,
unsigned int ADDR_UNIT_BITWIDTH = 8>
class tlm_target {
54 tlm_target(sc_core::sc_time& clock,
const char* socket_name =
"socket");
81 socket_map.addEntry(std::make_pair(&rai, base_addr), base_addr, std::max<size_t>(1, rai.
size() / (ADDR_UNIT_BITWIDTH / 8)));
90 for(
size_t idx = 0; idx < irai.
size(); ++idx) {
91 auto irai_size = std::max<size_t>(1, irai[idx].size() / (ADDR_UNIT_BITWIDTH / 8));
92 socket_map.addEntry(std::make_pair(&irai[idx], base_addr), base_addr, irai_size);
93 base_addr += irai_size;
99 for(
auto& e : socket_map) {
100 res = std::max<size_t>(res, e.first + e.second.index.second);
106 sc_core::sc_time& clk;
109 util::range_lut<std::pair<resource_access_if*, uint64_t>> socket_map;
140, socket_map(std::make_pair(nullptr, 0)) {
141 socket.register_b_transport([
this](tlm::tlm_generic_payload& gp, sc_core::sc_time& delay) ->
void { this->
b_tranport_cb(gp, delay); });
142 socket.register_transport_dbg([
this](tlm::tlm_generic_payload& gp) ->
unsigned {
return this->
tranport_dbg_cb(gp); });
149 std::tie(ra, base) = socket_map.getEntry(gp.get_address());
152 auto len = gp.get_data_length();
153 auto contigous =
true;
154 if(gp.get_byte_enable_ptr()) {
155 auto lower = std::numeric_limits<unsigned>::max();
156 auto upper = std::numeric_limits<unsigned>::max();
158 auto p = gp.get_byte_enable_ptr();
160 for(; i < gp.get_byte_enable_length(); ++i, ++p) {
162 if(lower != std::numeric_limits<unsigned>::max()) {
171 if(upper != std::numeric_limits<unsigned>::max()) {
180 if(i == gp.get_byte_enable_length() && upper == std::numeric_limits<unsigned>::max())
187 if(gp.get_data_length() > ra->
size()) {
188 gp.set_response_status(tlm::TLM_BURST_ERROR_RESPONSE);
189 }
else if(gp.get_data_length() != gp.get_streaming_width()) {
190 gp.set_response_status(tlm::TLM_GENERIC_ERROR_RESPONSE);
191 }
else if(gp.get_byte_enable_ptr() !=
nullptr && !(contigous && gp.get_byte_enable_length() == gp.get_data_length())) {
192 gp.set_response_status(tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE);
194 gp.set_response_status(tlm::TLM_COMMAND_ERROR_RESPONSE);
195 switch(gp.get_command()) {
196 case tlm::TLM_READ_COMMAND:
197 if(ra->read(gp.get_data_ptr() + offset, len, (gp.get_address() - base + offset), delay))
198 gp.set_response_status(tlm::TLM_OK_RESPONSE);
200 case tlm::TLM_WRITE_COMMAND:
201 if(ra->write(gp.get_data_ptr() + offset, len, (gp.get_address() - base + offset), delay))
202 gp.set_response_status(tlm::TLM_OK_RESPONSE);
207 gp.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
216 std::tie(ra, base) = socket_map.getEntry(gp.get_address());
218 if(gp.get_data_length() == ra->
size() && gp.get_byte_enable_ptr() ==
nullptr && gp.get_data_length() == gp.get_streaming_width()) {
219 if(gp.get_command() == tlm::TLM_READ_COMMAND) {
220 if(ra->
read_dbg(gp.get_data_ptr(), gp.get_data_length(), (gp.get_address() - base) / ra->
size()))
221 return gp.get_data_length();
222 }
else if(gp.get_command() == tlm::TLM_WRITE_COMMAND) {
223 if(ra->
write_dbg(gp.get_data_ptr(), gp.get_data_length(), (gp.get_address() - base) / ra->
size()))
224 return gp.get_data_length();