Skip to content

Commit 4429911

Browse files
committed
adds tlm::nw tracing
1 parent e373150 commit 4429911

File tree

13 files changed

+958
-24
lines changed

13 files changed

+958
-24
lines changed

src/interfaces/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ set(LIB_SOURCES
1111
axi/axi_target.cpp
1212
ocp/ocp_tlm.cpp
1313
tilelink/tl_tlm.cpp
14+
cxs/cxs_tlm.cpp
1415
)
1516

1617
add_library(${PROJECT_NAME} ${LIB_SOURCES})

src/interfaces/cxs/cxs_tlm.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2020 Arteris IP
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "cxs/cxs_tlm.h"
18+
#include <fmt/format.h>
19+
#include <tlm/scc/scv/tlm_extension_recording_registry.h>
20+
#include <tlm/scc/tlm_id.h>
21+
22+
namespace cxs {
23+
24+
class cxs_ext_recording : public tlm::scc::scv::tlm_extensions_recording_if<cxs_flit_types> {
25+
26+
void recordBeginTx(SCVNS scv_tr_handle& h, cxs_flit_types::tlm_payload_type& trans) override {
27+
if(auto ext = trans.get_extension<orig_pkt_extension>()) { // CTRL, DATA, RESP
28+
auto idx = 0U;
29+
for(auto& pkt : ext->orig_ext) {
30+
h.record_attribute(fmt::format("flit.packet{}.size", idx++).c_str(), pkt->get_data().size());
31+
if(pkt->get_extension_count())
32+
for(auto& extensionRecording : tlm::scc::scv::tlm_extension_recording_registry<cxs_packet_types>::inst().get())
33+
if(extensionRecording)
34+
extensionRecording->recordBeginTx(h, *pkt);
35+
}
36+
}
37+
}
38+
39+
void recordEndTx(SCVNS scv_tr_handle& handle, cxs_flit_types::tlm_payload_type& trans) override {}
40+
};
41+
#if defined(__GNUG__)
42+
__attribute__((constructor))
43+
#endif
44+
bool register_extensions() {
45+
cxs::orig_pkt_extension ext; // NOLINT
46+
if(!tlm::scc::scv::tlm_extension_recording_registry<cxs::cxs_flit_types>::inst().is_ext_registered(ext.ID))
47+
tlm::scc::scv::tlm_extension_recording_registry<cxs::cxs_flit_types>::inst().register_ext_rec(
48+
ext.ID,
49+
new cxs::cxs_ext_recording()); // NOLINT
50+
return true; // NOLINT
51+
}
52+
bool registered = register_extensions();
53+
} // namespace cxs

src/interfaces/cxs/cxs_tlm.h

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ struct cxs_flit_payload : public tlm::nw::tlm_network_payload<CXS_CMD> {
4444
uint8_t end{0};
4545
uint8_t end_error{0};
4646
bool last{false};
47+
48+
cxs_flit_payload& operator=(const cxs_flit_payload& x) {
49+
tlm::nw::tlm_network_payload<CXS_CMD>::operator=(x);
50+
start_ptr = x.start_ptr;
51+
end_ptr = x.end_ptr;
52+
end = x.end;
53+
end_error = x.end_error;
54+
last = x.last;
55+
return (*this);
56+
}
4757
};
4858

4959
struct cxs_flit_types {
@@ -64,6 +74,9 @@ struct cxs_packet_types {
6474
using tlm_phase_type = ::tlm::tlm_phase;
6575
};
6676

77+
bool register_extensions();
78+
extern bool registered;
79+
6780
} // namespace cxs
6881

6982
namespace tlm {
@@ -132,6 +145,7 @@ struct cxs_transmitter : public sc_core::sc_module,
132145

133146
cxs_transmitter(sc_core::sc_module_name const& nm)
134147
: sc_core::sc_module(nm) {
148+
register_extensions();
135149
tsck(*this);
136150
isck(*this);
137151
SC_HAS_PROCESS(cxs_transmitter);
@@ -158,9 +172,11 @@ struct cxs_transmitter : public sc_core::sc_module,
158172
}
159173

160174
tlm::tlm_sync_enum nb_transport_fw(pkt_tx_type& trans, pkt_phase_type& phase, sc_core::sc_time& t) override {
161-
SCCTRACE(SCMOD) << "Forwarding CXS packet with size " << trans.get_data().size() << "bytes";
175+
SCCTRACEALL(SCMOD) << "Forwarding CXS packet with size " << trans.get_data().size() << "bytes";
162176
if(phase == tlm::nw::REQUEST) {
163177
pkt_peq.notify(cxs_pkt_shared_ptr(&trans), t);
178+
if(clock_period.get_value() != sc_core::SC_ZERO_TIME)
179+
t += clock_period.get_value() - 1_ps;
164180
phase = tlm::nw::CONFIRM;
165181
return tlm::TLM_UPDATED;
166182
}
@@ -170,11 +186,13 @@ struct cxs_transmitter : public sc_core::sc_module,
170186
unsigned int transport_dbg(pkt_tx_type& trans) override { return 0; }
171187

172188
tlm::tlm_sync_enum nb_transport_bw(flit_tx_type& trans, flit_phase_type& phase, sc_core::sc_time& t) override {
173-
SCCTRACE(SCMOD) << "Received non-blocking transaction in bw path with phase " << phase.get_name();
174-
if(phase == tlm::nw::REQUEST) {
189+
SCCTRACEALL(SCMOD) << "Received non-blocking transaction in bw path with phase " << phase.get_name();
190+
if(phase == tlm::nw::REQUEST && trans.get_command() == cxs::CXS_CMD::CREDIT) {
175191
received_credits += trans.get_data()[0];
176-
SCCDEBUG(SCMOD) << "Received " << static_cast<unsigned>(trans.get_data()[0]) << " credit(s), " << received_credits.get()
192+
SCCTRACE(SCMOD) << "Received " << static_cast<unsigned>(trans.get_data()[0]) << " credit(s), " << received_credits.get()
177193
<< " credit(s) in total";
194+
if(clock_period.get_value() > sc_core::SC_ZERO_TIME)
195+
t += clock_period - 1_ps;
178196
phase = tlm::nw::CONFIRM;
179197
return tlm::TLM_UPDATED;
180198
}
@@ -228,6 +246,7 @@ struct cxs_transmitter : public sc_core::sc_module,
228246
received_credits -= burst_credits;
229247
}
230248
burst_credits--;
249+
SCCTRACE(SCMOD) << "Transmitted one flit, " << received_credits.get() << " credit(s) in total";
231250
}
232251

233252
void reset() {
@@ -273,6 +292,7 @@ struct cxs_receiver : public sc_core::sc_module,
273292

274293
cxs_receiver(sc_core::sc_module_name const& nm)
275294
: sc_core::sc_module(nm) {
295+
register_extensions();
276296
tsck(*this);
277297
isck(*this);
278298
SC_HAS_PROCESS(cxs_receiver);
@@ -302,28 +322,28 @@ struct cxs_receiver : public sc_core::sc_module,
302322
}
303323

304324
tlm::tlm_sync_enum nb_transport_fw(flit_tx_type& trans, flit_phase_type& phase, sc_core::sc_time& t) override {
305-
SCCTRACE(SCMOD) << "Received non-blocking transaction in fw path with phase " << phase.get_name();
325+
SCCTRACEALL(SCMOD) << "Received non-blocking transaction in fw path with phase " << phase.get_name();
306326
credit_returned.push_back(1);
307327
if(trans.end) {
308328
auto ext = trans.get_extension<cxs::orig_pkt_extension>();
309329
for(auto& orig_ptr : ext->orig_ext) {
310330
auto ph = tlm::nw::REQUEST;
311331
auto d = sc_core::SC_ZERO_TIME;
312-
SCCTRACE(SCMOD) << "Forwarding CXS pkt with size " << orig_ptr->get_data().size() << "bytes";
332+
SCCDEBUG(SCMOD) << "Forwarding CXS pkt with size " << orig_ptr->get_data().size() << "bytes";
313333
auto status = isck->nb_transport_fw(*orig_ptr, ph, t);
314334
sc_assert(status == tlm::TLM_UPDATED);
315335
}
316336
}
317-
phase = tlm::nw::RESPONSE;
318337
if(clock_period.get_value() != sc_core::SC_ZERO_TIME)
319338
t += clock_period.get_value() - 1_ps;
339+
phase = tlm::nw::RESPONSE;
320340
return tlm::TLM_UPDATED;
321341
}
322342

323343
unsigned int transport_dbg(flit_tx_type& trans) override { return 0; }
324344

325345
tlm::tlm_sync_enum nb_transport_bw(pkt_tx_type& trans, flit_phase_type& phase, sc_core::sc_time& t) override {
326-
SCCTRACE(SCMOD) << "Received non-blocking transaction in bw path with phase " << phase.get_name();
346+
SCCTRACEALL(SCMOD) << "Received non-blocking transaction in bw path with phase " << phase.get_name();
327347
if(phase == tlm::nw::CONFIRM)
328348
return tlm::TLM_ACCEPTED;
329349
throw std::runtime_error("illegal request in backward path");
@@ -367,8 +387,12 @@ struct cxs_channel : public sc_core::sc_module,
367387
using transaction_type = cxs_flit_types::tlm_payload_type;
368388
using phase_type = cxs_flit_types::tlm_phase_type;
369389

390+
sc_core::sc_in<bool> tx_clk_i{"tx_clk_i"};
391+
370392
cxs_flit_target_socket<PHITWIDTH> tsck{"tsck"};
371393

394+
sc_core::sc_in<bool> rx_clk_i{"rx_clk_i"};
395+
372396
cxs_flit_initiator_socket<PHITWIDTH> isck{"isck"};
373397

374398
cci::cci_param<sc_core::sc_time> channel_delay{"channel_delay", sc_core::SC_ZERO_TIME, "delay of the CXS channel"};
@@ -394,7 +418,7 @@ struct cxs_channel : public sc_core::sc_module,
394418
}
395419

396420
tlm::tlm_sync_enum nb_transport_fw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) override {
397-
SCCTRACE(SCMOD) << "Received non-blocking transaction in fw path with phase " << phase.get_name();
421+
SCCTRACEALL(SCMOD) << "Received non-blocking transaction in fw path with phase " << phase.get_name();
398422
if(phase == tlm::nw::REQUEST) {
399423
if(trans.get_data().size() > PHITWIDTH / 8) {
400424
SCCERR(SCMOD) << "A CXS flit can be maximal " << PHITWIDTH / 8 << " bytes long, current data length is "
@@ -413,9 +437,9 @@ struct cxs_channel : public sc_core::sc_module,
413437
}
414438

415439
tlm::tlm_sync_enum nb_transport_bw(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) override {
416-
SCCTRACE(SCMOD) << "Received non-blocking transaction in bw path with phase " << phase.get_name();
440+
SCCTRACEALL(SCMOD) << "Received non-blocking transaction in bw path with phase " << phase.get_name();
417441
if(phase == tlm::nw::REQUEST) { // this is a credit
418-
SCCDEBUG(SCMOD) << "Forwarding " << static_cast<unsigned>(trans.get_data()[0]) << " credit(s)";
442+
SCCTRACE(SCMOD) << "Forwarding " << static_cast<unsigned>(trans.get_data()[0]) << " credit(s)";
419443
bw_peq.notify(cxs_flit_shared_ptr(&trans), channel_delay.get_value());
420444
if(tx_clock_period.get_value() > sc_core::SC_ZERO_TIME)
421445
t += tx_clock_period - 1_ps;
@@ -431,6 +455,15 @@ struct cxs_channel : public sc_core::sc_module,
431455
unsigned int transport_dbg(transaction_type& trans) override { return isck->transport_dbg(trans); }
432456

433457
private:
458+
void start_of_simulation() override {
459+
if(tx_clock_period.get_value() == sc_core::SC_ZERO_TIME)
460+
if(auto clk_if = dynamic_cast<sc_core::sc_clock*>(tx_clk_i.get_interface()))
461+
tx_clock_period.set_value(clk_if->period());
462+
if(rx_clock_period.get_value() == sc_core::SC_ZERO_TIME)
463+
if(auto clk_if = dynamic_cast<sc_core::sc_clock*>(rx_clk_i.get_interface()))
464+
rx_clock_period.set_value(clk_if->period());
465+
}
466+
434467
void fw() {
435468
while(fw_peq.has_next()) {
436469
auto ptr = fw_peq.get();
@@ -467,5 +500,6 @@ struct cxs_channel : public sc_core::sc_module,
467500
scc::peq<cxs_flit_shared_ptr> bw_peq;
468501
sc_core::sc_event fw_resp, bw_resp;
469502
};
503+
470504
} // namespace cxs
471505
#endif // _CXS_CXS_TLM_H_
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*******************************************************************************
2+
* Copyright 2016-2022 MINRES Technologies GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*******************************************************************************/
16+
17+
#ifndef TLM_CXS_RECORDER_H_
18+
#define TLM_CXS_RECORDER_H_
19+
20+
#include <cxs/cxs_tlm.h>
21+
#include <tlm/nw/scv/tlm_recorder.h>
22+
#include <tlm/nw/scv/tlm_recorder_module.h>
23+
#ifdef HAS_SCV
24+
#include <scv.h>
25+
#else
26+
#include <scv-tr.h>
27+
#ifndef SCVNS
28+
#define SCVNS ::scv_tr::
29+
#endif
30+
#endif
31+
32+
//! @brief SystemC TLM
33+
namespace tlm {
34+
//! @brief SCC TLM utilities
35+
namespace nw {
36+
//! @brief SCC SCV4TLM classes and functions
37+
namespace scv {
38+
39+
template <> void record(SCVNS scv_tr_handle& handle, cxs::cxs_flit_payload const& o) {
40+
static const std::array<std::string, 3> cmd2char{{"FLIT", "CREDIT", "CRDRTN"}};
41+
handle.record_attribute("flit.ptr", reinterpret_cast<uintptr_t>(&o));
42+
handle.record_attribute("flit.type", cmd2char.at(static_cast<unsigned>(o.get_command())));
43+
// std::array<uint8_t, 8> start_ptr;
44+
// std::array<uint8_t, 8> end_ptr;
45+
handle.record_attribute("flit.start", static_cast<unsigned>(o.start));
46+
handle.record_attribute("flit.end", static_cast<unsigned>(o.end));
47+
handle.record_attribute("flit.end_error", o.end_error);
48+
handle.record_attribute("flit.last", o.last);
49+
}
50+
} // namespace scv
51+
} // namespace nw
52+
} // namespace tlm
53+
54+
#endif /* TLM2_RECORDER_H_ */

src/sysc/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ set(LIB_SOURCES
3838
scc/scv/scv_tr_ftr.cpp
3939
scc/vcd_pull_trace.cpp
4040
scc/vcd_push_trace.cpp
41-
tlm/scc/scv/tlm_recorder.cpp
42-
tlm/scc/pe/parallel_pe.cpp
4341
scc/hierarchy_dumper.cpp
4442
scc/cci_broker.cpp
4543
scc/configurer.cpp
4644
scc/configurable_tracer.cpp
4745
scc/sc_thread_pool.cpp
4846
scc/signal_opt_ports.cpp
47+
tlm/scc/scv/tlm_recorder.cpp
48+
tlm/scc/pe/parallel_pe.cpp
4949
tlm/scc/lwtr/tlm2_lwtr.cpp
5050
)
5151

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*******************************************************************************
2+
* Copyright 2016-2022 MINRES Technologies GmbH
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*******************************************************************************/
16+
17+
#ifndef SC_INCLUDE_DYNAMIC_PROCESSES
18+
#define SC_INCLUDE_DYNAMIC_PROCESSES
19+
#include "tlm/nw/tlm_network_sockets.h"
20+
#endif
21+
#include "tlm_recorder.h"
22+
#include <tlm/scc/scv/tlm_extension_recording_registry.h>
23+
#include <tlm/scc/tlm_id.h>
24+
25+
namespace tlm {
26+
namespace nw {
27+
namespace scv {
28+
namespace {
29+
const std::array<std::string, 3> cmd2char{{"READ", "WRITE", "IGNORE"}};
30+
const std::array<std::string, 7> resp2char{
31+
{"OK", "INCOMPLETE", "GENERIC_ERROR", "ADDRESS_ERROR", "COMMAND_ERROR", "BURST_ERROR", "BYTE_ENABLE_ERROR"}};
32+
const std::array<std::string, 3> gp_option2char{{"MIN_PAYLOAD", "FULL_PAYLOAD", "FULL_PAYLOAD_ACCEPTED"}};
33+
const std::array<std::string, 5> phase2char{{"UNINITIALIZED_PHASE", "BEGIN_REQ", "END_REQ", "BEGIN_RESP", "END_RESP"}};
34+
const std::array<std::string, 4> dmi2char{{"DMI_ACCESS_NONE", "DMI_ACCESS_READ", "DMI_ACCESS_WRITE", "DMI_ACCESS_READ_WRITE"}};
35+
const std::array<std::string, 3> sync2char{{"ACCEPTED", "UPDATED", "COMPLETED"}};
36+
37+
} // namespace
38+
void record(SCVNS scv_tr_handle& handle, tlm::nw::tlm_network_payload_base& o) {
39+
// handle.record_attribute("trans.ptr", reinterpret_cast<uintptr_t>(&o));
40+
// handle.record_attribute("trans.address", o.get_address());
41+
// handle.record_attribute("trans.cmd", cmd2char.at(o.get_command()));
42+
// handle.record_attribute("trans.data_ptr", o.get_data_ptr());
43+
// handle.record_attribute("trans.data_length", o.get_data_length());
44+
// handle.record_attribute("trans.response", resp2char.at(1 - o.get_response_status()));
45+
// handle.record_attribute("trans.dmi_allowed", o.is_dmi_allowed());
46+
// handle.record_attribute("trans.byte_enable", o.get_byte_enable_ptr());
47+
// handle.record_attribute("trans.byte_enable_length", o.get_byte_enable_length());
48+
// handle.record_attribute("trans.streaming_width", o.get_streaming_width());
49+
// handle.record_attribute("trans.gp_option", gp_option2char.at(o.get_gp_option()));
50+
// if(o.get_data_length() && o.get_data_length() < 9 && o.get_data_ptr()) {
51+
// uint64_t buf = 0;
52+
// memcpy(&buf, o.get_data_ptr(), o.get_data_length());
53+
// handle.record_attribute("trans.data_value", buf);
54+
// }
55+
}
56+
void record(SCVNS scv_tr_handle& handle, tlm::tlm_phase& o) {
57+
unsigned id = o;
58+
if(id < phase2char.size())
59+
handle.record_attribute("phase", phase2char[id]);
60+
else
61+
handle.record_attribute("phase_id", id);
62+
}
63+
void record(SCVNS scv_tr_handle& handle, tlm::tlm_sync_enum o) { handle.record_attribute("tlm_sync", sync2char.at(o)); }
64+
65+
} // namespace scv
66+
} // namespace nw
67+
} // namespace tlm

0 commit comments

Comments
 (0)