From 7e80a414172ec0db17dfe869e804ade763550026 Mon Sep 17 00:00:00 2001 From: ueqri Date: Fri, 17 Nov 2023 05:57:41 +0800 Subject: [PATCH] Added NoC flit traffic trace support --- rad-sim/example-designs/mlp/mlp_driver.cpp | 1 + rad-sim/sim/noc/booksim/channel.hpp | 7 +++--- rad-sim/sim/noc/booksim/flitchannel.cpp | 14 +++++++++++ rad-sim/sim/noc/booksim/flitchannel.hpp | 1 + rad-sim/sim/noc/booksim/networks/network.cpp | 7 ++++++ rad-sim/sim/noc/booksim/networks/network.hpp | 1 + rad-sim/sim/noc/booksim/routers/router.hpp | 1 + rad-sim/sim/noc/booksim/timed_module.hpp | 1 + rad-sim/sim/noc/radsim_noc.cpp | 1 + rad-sim/sim/radsim_telemetry.cpp | 12 ++++++++++ rad-sim/sim/radsim_telemetry.hpp | 11 +++++++++ rad-sim/sim/sanitize_flit_traces.py | 25 ++++++++++++++++++++ 12 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 rad-sim/sim/sanitize_flit_traces.py diff --git a/rad-sim/example-designs/mlp/mlp_driver.cpp b/rad-sim/example-designs/mlp/mlp_driver.cpp index e309e7f..1069425 100644 --- a/rad-sim/example-designs/mlp/mlp_driver.cpp +++ b/rad-sim/example-designs/mlp/mlp_driver.cpp @@ -132,6 +132,7 @@ void mlp_driver::sink() { end_cycle = GetSimulationCycle(1.0); std::cout << "Simulation Cycles = " << end_cycle - start_cycle << std::endl; NoCTransactionTelemetry::DumpStatsToFile("stats.csv"); + NoCFlitTelemetry::DumpNoCFlitTracesToFile("flit_traces.csv"); std::vector aggregate_bandwidths = NoCTransactionTelemetry::DumpTrafficFlows("traffic_flows", end_cycle - start_cycle, radsim_design.GetNodeModuleNames()); diff --git a/rad-sim/sim/noc/booksim/channel.hpp b/rad-sim/sim/noc/booksim/channel.hpp index 593407b..8742856 100644 --- a/rad-sim/sim/noc/booksim/channel.hpp +++ b/rad-sim/sim/noc/booksim/channel.hpp @@ -65,12 +65,13 @@ class Channel : public TimedModule { virtual void ReadInputs(); virtual void Evaluate() {} virtual void WriteOutputs(); + virtual void Trace([[maybe_unused]] ostream & os, [[maybe_unused]]double sim_time) {} protected: int _delay; T * _input; T * _output; - queue > _wait_queue; + deque > _wait_queue; }; @@ -100,7 +101,7 @@ T * Channel::Receive() { template void Channel::ReadInputs() { if(_input) { - _wait_queue.push(make_pair(GetSimTime() + _delay - 1, _input)); + _wait_queue.push_back(make_pair(GetSimTime() + _delay - 1, _input)); _input = 0; } } @@ -119,7 +120,7 @@ void Channel::WriteOutputs() { //assert(GetSimTime() == time); _output = item.second; assert(_output); - _wait_queue.pop(); + _wait_queue.pop_front(); } #endif diff --git a/rad-sim/sim/noc/booksim/flitchannel.cpp b/rad-sim/sim/noc/booksim/flitchannel.cpp index 9f1d2c1..271aa2b 100644 --- a/rad-sim/sim/noc/booksim/flitchannel.cpp +++ b/rad-sim/sim/noc/booksim/flitchannel.cpp @@ -89,3 +89,17 @@ void FlitChannel::WriteOutputs() { << "." << endl; } } + +void FlitChannel::Trace(ostream & os, double sim_time) { + auto src_router = this->_routerSource, sink_router = this->_routerSink; + int src_router_id = (src_router != nullptr) ? src_router->GetID() : -1; + int sink_router_id = (sink_router != nullptr) ? sink_router->GetID() : -1; + for (const auto & d : _wait_queue) { + os << sim_time << ", " << src_router_id << ", " << sink_router_id << ", " + << d.second->id << ", " << int(d.second->type) << ", " << 0 << endl; + } + if(_output) { + os << sim_time << ", " << src_router_id << ", " << sink_router_id << ", " + << _output->id << ", " << int(_output->type) << ", " << 1 << endl; + } +} diff --git a/rad-sim/sim/noc/booksim/flitchannel.hpp b/rad-sim/sim/noc/booksim/flitchannel.hpp index 704f6b9..3796ec0 100644 --- a/rad-sim/sim/noc/booksim/flitchannel.hpp +++ b/rad-sim/sim/noc/booksim/flitchannel.hpp @@ -77,6 +77,7 @@ class FlitChannel : public Channel { virtual void ReadInputs(); virtual void WriteOutputs(); + virtual void Trace(ostream & os, double sim_time); private: diff --git a/rad-sim/sim/noc/booksim/networks/network.cpp b/rad-sim/sim/noc/booksim/networks/network.cpp index 5e5e79a..14dac00 100644 --- a/rad-sim/sim/noc/booksim/networks/network.cpp +++ b/rad-sim/sim/noc/booksim/networks/network.cpp @@ -279,3 +279,10 @@ void Network::DumpNodeMap( ostream & os, string const & prefix ) const << _eject[s]->GetSource()->GetID() << ',' << _inject[s]->GetSink()->GetID() << endl; } + +void Network::Trace(ostream & os, double sim_time ) +{ + for(auto _timed_module : _timed_modules) { + _timed_module->Trace(os, sim_time); + } +} diff --git a/rad-sim/sim/noc/booksim/networks/network.hpp b/rad-sim/sim/noc/booksim/networks/network.hpp index 4b94524..b8cd3c8 100644 --- a/rad-sim/sim/noc/booksim/networks/network.hpp +++ b/rad-sim/sim/noc/booksim/networks/network.hpp @@ -103,6 +103,7 @@ class Network : public TimedModule { virtual void ReadInputs( ); virtual void Evaluate( ); virtual void WriteOutputs( ); + virtual void Trace( ostream & os, double sim_time ); // Print functions void Display( ostream & os = cout ) const; diff --git a/rad-sim/sim/noc/booksim/routers/router.hpp b/rad-sim/sim/noc/booksim/routers/router.hpp index 65bdac8..9fd435a 100644 --- a/rad-sim/sim/noc/booksim/routers/router.hpp +++ b/rad-sim/sim/noc/booksim/routers/router.hpp @@ -114,6 +114,7 @@ class Router : public TimedModule { virtual void ReadInputs( ) = 0; virtual void Evaluate( ); virtual void WriteOutputs( ) = 0; + virtual void Trace( [[maybe_unused]] ostream & os, [[maybe_unused]] double sim_time ) {} void OutChannelFault( int c, bool fault = true ); bool IsFaultyOutput( int c ) const; diff --git a/rad-sim/sim/noc/booksim/timed_module.hpp b/rad-sim/sim/noc/booksim/timed_module.hpp index cd2dd12..d766b26 100644 --- a/rad-sim/sim/noc/booksim/timed_module.hpp +++ b/rad-sim/sim/noc/booksim/timed_module.hpp @@ -39,6 +39,7 @@ class TimedModule : public Module { virtual void ReadInputs() = 0; virtual void Evaluate() = 0; virtual void WriteOutputs() = 0; + virtual void Trace(ostream &, double) = 0; }; #endif diff --git a/rad-sim/sim/noc/radsim_noc.cpp b/rad-sim/sim/noc/radsim_noc.cpp index baf7c24..f1dff96 100644 --- a/rad-sim/sim/noc/radsim_noc.cpp +++ b/rad-sim/sim/noc/radsim_noc.cpp @@ -300,6 +300,7 @@ void radsim_noc::Tick() { _ejected_flits->clear(); _booksim_noc->Evaluate(); _booksim_noc->WriteOutputs(); + _booksim_noc->Trace(NoCFlitTelemetry::ostream, double(GetSimTime()) / 1000); wait(); } } \ No newline at end of file diff --git a/rad-sim/sim/radsim_telemetry.cpp b/rad-sim/sim/radsim_telemetry.cpp index fd22bec..b529d67 100644 --- a/rad-sim/sim/radsim_telemetry.cpp +++ b/rad-sim/sim/radsim_telemetry.cpp @@ -111,6 +111,18 @@ std::vector NoCTransactionTelemetry::DumpTrafficFlows(const std::string& return aggregate_bandwidths; } +std::stringstream NoCFlitTelemetry::ostream; + +NoCFlitTelemetry::NoCFlitTelemetry() {} +NoCFlitTelemetry::~NoCFlitTelemetry() {} + +void NoCFlitTelemetry::DumpNoCFlitTracesToFile(const std::string& filename) { + std::ofstream ofile(filename, std::ofstream::out); + ofile << "t_trace, link_src_router, link_dest_router, flit_id, flit_type, is_channel_output" << endl; + ofile << NoCFlitTelemetry::ostream.rdbuf(); + ofile.close(); +} + SimLog::SimLog() { verbosity = 0; } diff --git a/rad-sim/sim/radsim_telemetry.hpp b/rad-sim/sim/radsim_telemetry.hpp index c05a588..539a975 100644 --- a/rad-sim/sim/radsim_telemetry.hpp +++ b/rad-sim/sim/radsim_telemetry.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -60,6 +61,16 @@ class NoCTransactionTelemetry { std::vector>>& node_module_names); }; +// Class for recording and storing flit traces +class NoCFlitTelemetry { + public: + static std::stringstream ostream; + + NoCFlitTelemetry(); + ~NoCFlitTelemetry(); + static void DumpNoCFlitTracesToFile(const std::string& filename); +}; + struct debug_t {}; constexpr auto debug = debug_t{}; struct trace_t {}; diff --git a/rad-sim/sim/sanitize_flit_traces.py b/rad-sim/sim/sanitize_flit_traces.py new file mode 100644 index 0000000..ceeb6da --- /dev/null +++ b/rad-sim/sim/sanitize_flit_traces.py @@ -0,0 +1,25 @@ +import csv + +quant = 100 + +print('time, pkt_src, pkt_dst, pkt_type') + +# TODO: use corresponding placement file for router ID mapping instead of hardcodes +placement = ['L1M0', 'D3', 'D0', 'L0M2', + 'L0M0', 'C', 'L1M1', 'L1M2', + 'L3M0', 'L2M1', 'D2', 'L0M3', + 'L3M1', 'D1', 'L0M1', 'L2M0'] + +with open('flit_traces.csv', 'r') as f: + reader = csv.reader(f) + rows = list(reader)[1:] + rows = sorted(rows, key=lambda x: int(x[0])) + for row in rows: + t_trace, src_router, dst_router, _, flit_type, _ = tuple(row) + if int(src_router) == -1 or int(dst_router) == -1: # injection or ejection + continue + t_trace = int(int(t_trace) // quant) + src_router = placement[int(src_router)] + dst_router = placement[int(dst_router)] + flit_type = str(flit_type).strip() + print(f'{t_trace}, {src_router}, {dst_router}, {flit_type}')