1 #include "replay_target.h"
2 #include <yaml-cpp/exceptions.h>
3 #include <yaml-cpp/node/parse.h>
4 #include <yaml-cpp/yaml.h>
10 replay_buffer::replay_buffer(
const sc_core::sc_module_name &nm):sc_core::sc_module(nm) {
12 SC_HAS_PROCESS(replay_buffer);
13 SC_METHOD(process_req2resp_fifos);
15 sensitive << clk_i.pos();
16 SC_THREAD(start_wr_resp_thread);
17 SC_THREAD(start_rd_resp_thread);
20 void replay_buffer::end_of_elaboration() {
21 clk_if =
dynamic_cast<sc_core::sc_clock*
>(clk_i.get_interface());
24 void replay_buffer::start_of_simulation() {
25 if(replay_file_name.get_value().length()) {
26 std::ifstream ifs(replay_file_name.get_value());
29 std::getline(ifs, line);
30 while (std::getline(ifs, line)) {
32 auto addr = strtoull(token[1].c_str(),
nullptr, 10);
33 auto id = strtoull(token[2].c_str(),
nullptr, 10);
34 auto start_cycle = strtoull(token[3].c_str(),
nullptr, 10);
35 auto req_resp_lat=strtoull(token[4].c_str(),
nullptr, 10);
36 if(token[0]==
"READ") {
37 if(
id>=rd_sequence.size())
38 rd_sequence.resize(
id+1);
39 rd_sequence[id].emplace_back(addr, req_resp_lat);
40 }
else if(token[0]==
"WRITE") {
41 if(
id>=wr_sequence.size())
42 wr_sequence.resize(
id+1);
43 wr_sequence[id].emplace_back(addr, req_resp_lat);
47 SCCINFO(SCMOD)<<
"SEQ file name of replay target = "<<replay_file_name.get_value();
51 void replay_buffer::transport(tlm::tlm_generic_payload &trans,
bool lt_transport) {
52 auto id = axi::get_axi_id(trans);
53 auto addr = trans.get_address();
54 auto cycle = clk_if? sc_core::sc_time_stamp()/clk_if->period():0;
55 if(trans.is_write()) {
56 if(
id<wr_sequence.size() && wr_sequence[
id].size()) {
57 auto it = std::find_if(std::begin(wr_sequence[
id]), std::end(wr_sequence[
id]), [addr](entry_t
const & e){
58 return std::get<0>(e) == addr;
60 if(it != std::end(wr_sequence[
id])) {
61 wr_req2resp_fifo.push_back(std::make_tuple(&trans, std::get<1>(*it)));
62 wr_sequence[id].erase(it);
66 if(replay_file_name.get_value().length()) {
67 SCCWARN(SCMOD)<<
"No transaction in write sequence buffer for "<<trans;
69 wr_req2resp_fifo.push_back(std::make_tuple(&trans, 0));
70 }
else if(trans.is_read()) {
71 if(
id<rd_sequence.size() && rd_sequence[
id].size()) {
72 auto it = std::find_if(std::begin(rd_sequence[
id]), std::end(rd_sequence[
id]), [addr](entry_t
const & e){
73 return std::get<0>(e) == addr;
75 if(it != std::end(rd_sequence[
id])) {
76 rd_req2resp_fifo.push_back(std::make_tuple(&trans, std::get<1>(*it)));
77 rd_sequence[id].erase(it);
81 if(replay_file_name.get_value().length()) {
82 SCCWARN(SCMOD)<<
"No transaction in read sequence buffer for "<<trans;
84 rd_req2resp_fifo.push_back(std::make_tuple(&trans, 0));
88 void replay_buffer::process_req2resp_fifos() {
89 while(rd_req2resp_fifo.avail()) {
90 auto& entry = rd_req2resp_fifo.front();
91 if(std::get<1>(entry) == 0) {
92 rd_resp_fifo.push_back(std::get<0>(entry));
94 std::get<1>(entry) -= 1;
95 rd_req2resp_fifo.push_back(entry);
97 rd_req2resp_fifo.pop_front();
99 while(wr_req2resp_fifo.avail()) {
100 auto& entry = wr_req2resp_fifo.front();
101 if(std::get<1>(entry) == 0) {
102 wr_resp_fifo.push_back(std::get<0>(entry));
104 std::get<1>(entry) -= 1;
105 wr_req2resp_fifo.push_back(entry);
107 wr_req2resp_fifo.pop_front();
111 void replay_buffer::start_rd_resp_thread() {
112 auto residual_clocks = 0.0;
114 wait(rd_resp_fifo.data_written_event());
115 while(rd_resp_fifo.avail())
116 if(
auto* trans = rd_resp_fifo.front()){
118 if(time_per_byte_total.value()) {
120 auto clocks = trans->get_data_length() * time_per_byte_total / clk_if->period() + total_residual_clocks;
121 auto delay =
static_cast<unsigned>(clocks);
122 total_residual_clocks = clocks - delay;
123 wait(delay*clk_if->period());
124 wait(clk_i.posedge_event());
125 }
else if(time_per_byte_rd.value()) {
126 auto clocks = trans->get_data_length() * time_per_byte_rd / clk_if->period() + residual_clocks;
127 auto delay =
static_cast<unsigned>(clocks);
128 residual_clocks = clocks - delay;
129 wait(delay*clk_if->period());
130 wait(clk_i.posedge_event());
133 while(bw_o->transport(*trans)!=0) wait(clk_i.posedge_event());
134 rd_resp_fifo.pop_front();
139 void replay_buffer::start_wr_resp_thread() {
140 auto residual_clocks = 0.0;
142 wait(wr_resp_fifo.data_written_event());
143 while(wr_resp_fifo.avail())
144 if(
auto* trans = wr_resp_fifo.front()){
146 if(time_per_byte_total.value()) {
148 auto clocks = trans->get_data_length() * time_per_byte_total / clk_if->period() + total_residual_clocks;
149 auto delay =
static_cast<unsigned>(clocks);
150 total_residual_clocks = clocks - delay;
151 wait(delay*clk_if->period());
152 wait(clk_i.posedge_event());
153 }
else if(time_per_byte_rd.value()) {
154 auto clocks = trans->get_data_length() * time_per_byte_rd / clk_if->period() + residual_clocks;
155 auto delay =
static_cast<unsigned>(clocks);
156 residual_clocks = clocks - delay;
157 wait(delay*clk_if->period());
158 wait(clk_i.posedge_event());
161 while(bw_o->transport(*trans)!=0) wait(clk_i.posedge_event());
162 wr_resp_fifo.pop_front();
TLM2.0 components modeling AHB.
std::vector< std::string > split(const std::string &s, char separator)