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)