RecoSim  1.0
 All Classes Files Functions Variables Enumerations
testbench_out.h
Go to the documentation of this file.
1 
22 #ifndef TESTBENCH_OUT_H
23 #define TESTBENCH_OUT_H
24 
25 // Needed for the simple_target_socket
26 #define SC_INCLUDE_DYNAMIC_PROCESSES
27 
28 #include <systemc.h>
29 #include "tlm.h"
30 #include "tlm_utils/simple_initiator_socket.h"
31 #include "tlm_utils/simple_target_socket.h"
32 #include "tlm_utils/multi_passthrough_initiator_socket.h"
33 #include "tlm_utils/peq_with_cb_and_phase.h"
34 #include "utils.h"
35 #include "memory_manager.h"
36 #include "trace.h"
37 #include "simulation_controller.h"
38 #include "user_parameters.h"
40 #include "testbench_algorithms.h"
41 #include <map>
42 #include <queue>
43 #include "algorithm_mode_command.h"
44 
45 using namespace sc_core;
46 using namespace sc_dt;
47 using namespace std;
48 using namespace tlm;
49 using namespace tlm_utils;
50 
51 #define FOUT if(generate_logfile()) (*fout)
52 
53 template<int No>
54 class TestbenchOut : public sc_module, public Testbench_out_interface<No> {
55 
56 public:
57 
58  // I/O sockets
59  multi_passthrough_initiator_socket<TestbenchOut> output_initiator_socket;
60 
61  // Configuration socket
62  simple_initiator_socket<TestbenchOut> manager_initiator_socket;
63  simple_target_socket<TestbenchOut> manager_target_socket;
64 
65 private:
66 
67  // Payload event queues
68  peq_with_cb_and_phase<TestbenchOut> m_peq;
69 
70  // Maps to retrieve socket ID from a transaction in PEQ callbacks
71  map<tlm_generic_payload*, unsigned int> m_id_init_map;
72 
73  // Events
74  sc_event transaction_transmitted_event[No];
75  sc_event configuration_done_event;
76  sc_event all_responses_received_event;
77  sc_event start_initiator_channel_event[No];
78  sc_event end_of_response_channel_event[No];
79 
80  // Transactions
81  tlm_generic_payload* request_in_progress[No];
82  tlm_generic_payload* configuration_in_progress;
83 
84  // Memory manager
85  Memory_manager m_mm;
86 
87  // Data
88  int *data_out[No];
89  uint64 address_out[No];
90 
91  // Packet sizes
92  int output_packet_size[No]; /* Linked to attribute */
93 
94  // Timing parameters
95  sc_time begin_req_time[No]; /* Linked to attribute */
96  sc_time end_resp_time[No]; /* Linked to attribute */
97 
98  // Trace methods events
99  sc_event set_initiator_phase_begin_req_event[No];
100  sc_event set_initiator_phase_end_resp_event[No];
101 
102  // Log file stream
103  ofstream* fout;
104 
105  // Trace file
106  sc_trace_file *tf;
107  trace_packet_testbench_t<0, No> trace_packet;
108 
109  // Connections lists (only following modules)
110  vector<int> channel_connection_vector; // w/ redundancies
111  vector<int> following_modules_list; // w/o redundancies
112 
113  vector<string> following_modules_connection_name;
114  vector<string> preceding_modules_connection_name;
115 
116  // Misc
117  int nb_responses_received; /*< Number of responses received so far */
118  int current_transaction_id; /*< Transaction currently processed */
119 
120  // Priority channels
121  set<int> priority_channels_out;
122  int nb_non_priority_channels_requests_out;
123  sc_event shared_channel_out_ready_event;
125  string applicationName;
126 
127  void (*testbench_thread_ptr)(Testbench_out_interface<No> &);
128 
129  sc_time period;
130 
131  map<int, vector<int> > channels_required; /* <module_id, list of socket ID> */
132 
133  // Algorithms execution modes control
134  sc_event_queue algorithm_mode_command_event_queue;
135  priority_queue<AlgorithmModeCommand, vector<AlgorithmModeCommand>, AlgorithmModeCommandComparison> algorithm_mode_command_priority_queue;
136 
137 public:
138 
139  // Constructor
140  SC_HAS_PROCESS(TestbenchOut);
141  TestbenchOut(sc_module_name instname, void (*tb_thread)(Testbench_out_interface<No> &), ofstream& logfile, sc_trace_file *mtf) :
142  output_initiator_socket("output_initiator_socket"),
143  manager_initiator_socket("manager_initiator_socket"),
144  manager_target_socket("manager_target_socket"),
145  m_peq(this, &TestbenchOut::peq_callback),
146  fout(&logfile),
147  configuration_in_progress(0),
148  testbench_thread_ptr(tb_thread),
149  tf(mtf) {
150 
151  for(int i = 0; i < No; i++) request_in_progress[i]= 0;
152 
153  nb_responses_received = 0;
154  current_transaction_id = 0;
155  nb_non_priority_channels_requests_out = 0;
156 
157  period = SC_ZERO_TIME;
158 
159  // Data out initialization
160  for(int i = 0; i < No; i++) {
161  output_packet_size[i] = 16;
162  data_out[i] = new int[output_packet_size[i]];
163  for(int j = 0; j < output_packet_size[i]; j++) data_out[i][j] = 0;
164  }
165 
166  // Init timing parameters
167  for(int i = 0; i < No; i++) begin_req_time[i] = sc_time(1, SC_US);
168  for(int i = 0; i < No; i++) end_resp_time[i] = sc_time(1, SC_US);
169 
170  // Register transport methods
171  output_initiator_socket.register_nb_transport_bw(this, &TestbenchOut::nb_transport_bw);
172  manager_target_socket.register_b_transport(this, &TestbenchOut::b_transport_manager);
173 
174  // Spawn testbench thread as a function outside the class
175  sc_spawn(sc_bind(testbench_thread_ptr, sc_ref(*this)), "testbench_out_thread");
176 
177  SC_METHOD(launch_algorithm_command);
178  sensitive << algorithm_mode_command_event_queue;
179  dont_initialize();
180 
181  // Dynamic threads initialization for channel communications
182  for(int i = 0; i < No; i++) {
183  sc_spawn_options method_options;
184  method_options.spawn_method();
185  method_options.dont_initialize();
186  method_options.set_sensitivity(&start_initiator_channel_event[i]);
187  string process_name("Dynamic_process_");
188  ostringstream out;
189  out << i;
190  process_name.append(out.str());
191 
192  sc_spawn(sc_bind(&TestbenchOut<No>::dynamic_transfer_process_method, this, i), process_name.c_str(), &method_options);
193  }
194 
195  // Dynamic threads initialization for tracing purpose: set_initiator_phase_begin_req
196  for(int i = 0; i < No; i++) {
197  sc_spawn_options method_options;
198  method_options.spawn_method();
199  method_options.dont_initialize();
200  method_options.set_sensitivity(&set_initiator_phase_begin_req_event[i]);
201  string process_name("set_initiator_phase_begin_req_process_");
202  ostringstream out;
203  out << i;
204  process_name.append(out.str());
205 
206  sc_spawn(sc_bind(&TestbenchOut<No>::set_initiator_phase_begin_req, this, i), process_name.c_str(), &method_options);
207  }
208 
209  // Dynamic threads initialization for tracing purpose: set_initiator_phase_end_resp
210  for(int i = 0; i < No; i++) {
211  sc_spawn_options method_options;
212  method_options.spawn_method();
213  method_options.dont_initialize();
214  method_options.set_sensitivity(&set_initiator_phase_end_resp_event[i]);
215  string process_name("set_initiator_phase_end_resp_process_");
216  ostringstream out;
217  out << i;
218  process_name.append(out.str());
219 
220  sc_spawn(sc_bind(&TestbenchOut<No>::set_initiator_phase_end_resp, this, i), process_name.c_str(), &method_options);
221  }
222 
223  // Add signals to trace
224  init_packet();
225  sc_trace(tf, trace_packet, (string) name());
226  }
227 
228  ~TestbenchOut() {
229  for(int i = 0; i < No; i++) {
230  delete[] data_out[i];
231  }
232  }
233 
234  // Transfer methods
235  void dynamic_transfer_process_method(int channel_id);
236  void initiator_process(int id);
237 
238  // Payload event queue callback function
239  void peq_callback(tlm_generic_payload& trans, const tlm_phase& phase);
240 
241  // Transport methods
242  virtual tlm_sync_enum nb_transport_bw(int id, tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay);
243  void b_transport_manager(tlm_generic_payload& trans, sc_time& delay);
244 
245  // Simulation controller interface
246  void notify_simulation_controller(bool);
247 
248  // User interface
249  void verify_bindings(void);
250  void set_packet_size(string connection_name, int val);
251  void set_following_modules_list(vector<int> &v);
252  void set_application_offset(int offset);
253 
254  void add_following_module_connection_name(string name);
255  void add_timing_info(tlm_phase_enum phase, string connection_name, sc_time time);
256  void set_begin_req_time(string connection_name, sc_time t);
257  void set_end_resp_time(string connection_name, sc_time t);
258 
259  void info(void);
260 
261  // Priority channels
262  void add_priority_channel(string connection_name);
263  bool is_priority_channel_out(int id);
264 
265  // Trace packet
266  void init_packet(void);
267  void update_initiator_packet(int id, tlm_generic_payload* trans, tlm_phase phase);
268  void update_initiator_packet(int id, tlm_generic_payload* trans);
269  void set_initiator_phase_begin_req(int id);
270  void set_initiator_phase_end_resp(int id);
271 
272  void set_application_name(string s);
273  void set_period(sc_time p);
274 
275  int get_output_socket_id(string connection_name) const;
276 
277  // TB OUT Interface
278  const char * TB_IF_name(void) const;
279  string TB_IF_get_instance_name(void) const;
280  int* TB_IF_get_data_out_ptr(int) const;
281  int* TB_IF_get_data_out_ptr(string) const;
282  void TB_IF_nb_send_data(int socketID);
283  void TB_IF_nb_send_data(string connectionName);
284  void TB_IF_nb_send_all_data(void);
285  const sc_event& TB_IF_all_responses_received_event(void) const;
286  void TB_IF_increment_current_transaction_id(void);
287  string TB_IF_getApplicationName(void);
288  sc_time TB_IF_get_period(void) const;
289  void TB_IF_add_execution_mode_command_to_queue(string module_name, string command, sc_time delay);
290  int TB_IF_get_packet_size(int ID) const;
291  int TB_IF_get_packet_size(string connectionName) const;
292  int TB_IF_get_output_socket_id(string name) const;
293 
294  void launch_algorithm_command(void);
295  void send_algorithm_command_to_manager(AlgorithmModeCommand*);
296 
297  void manager_b_transport(int module_id);
298 };
299 
300 
301 
302 /*******************************************
303  ****** Manager communication part ******
304  *******************************************/
305 
306 // REM: Communication du module vers reconf manager
307 // QUESTIONFAB : mais elle sert exactement à quoi cette fonction ? elle prépare un paquet pour quoi ? On dirait que le paquer contient que le module id comme info ?
308 
309 template<int No>
310 void TestbenchOut<No>::manager_b_transport(int module_id) {
311 
312  tlm_generic_payload* trans;
313  sc_time delay(SC_ZERO_TIME);
314  int local_data = module_id;
315 
316  // Grab a new transaction from the memory manager
317  trans = m_mm.allocate();
318  trans->acquire();
319 
320  // Set all attributes except byte_enable_length and extensions (unused)
321  trans->set_command(TLM_READ_COMMAND);
322  trans->set_address(TB_TO_MANAGER_CHECK_SOCKET);
323  trans->set_data_ptr(reinterpret_cast<unsigned char*>(&local_data));
324  trans->set_data_length(4);
325  trans->set_streaming_width(4); // = data_length to indicate no streaming
326  trans->set_byte_enable_ptr(0); // 0 indicates unused
327  trans->set_dmi_allowed(false); // Mandatory initial value
328  trans->set_response_status(TLM_INCOMPLETE_RESPONSE); // Mandatory initial value
329 
330  manager_initiator_socket->b_transport(*trans, delay);
331 
332  if(trans->is_response_error()) SC_REPORT_ERROR("TLM-2", "Response error from TB b_transport");
333 
334  Utils::check_transaction(*trans);
335 }
336 
337 template<int No>
339 
340  tlm_generic_payload* trans;
341  sc_time delay(SC_ZERO_TIME);
342 
343  // Grab a new transaction from the memory manager
344  trans = m_mm.allocate();
345  trans->acquire();
346 
347  // Set all attributes except byte_enable_length and extensions (unused)
348  trans->set_command(TLM_WRITE_COMMAND);
349  trans->set_address(TB_TO_MANAGER_ALGORITHM_COMMAND);
350  trans->set_data_ptr(reinterpret_cast<unsigned char*>(cmd));
351  trans->set_data_length(4);
352  trans->set_streaming_width(4); // = data_length to indicate no streaming
353  trans->set_byte_enable_ptr(0); // 0 indicates unused
354  trans->set_dmi_allowed(false); // Mandatory initial value
355  trans->set_response_status(TLM_INCOMPLETE_RESPONSE); // Mandatory initial value
356 
357  manager_initiator_socket->b_transport(*trans, delay);
358 
359  if(trans->is_response_error()) SC_REPORT_ERROR("TLM-2", "Response error from TB b_transport");
360 
361  Utils::check_transaction(*trans);
362 }
363 
364 template<int No>
365 void TestbenchOut<No>::b_transport_manager(tlm_generic_payload& trans, sc_time& delay) {
366 
367  if(trans.get_address() == MANAGER_COMMAND_SCHEDULING) {
368 
369  int data = *(reinterpret_cast<int *>(trans.get_data_ptr()));
370  User_algorithm_action action = (User_algorithm_action) (data & 0xffff);
371  int module_ready = data >> 16;
372 
373  // If next module ready, launch initiator
374  if(action == NEXT_MODULE_READY) {
375 
376  FOUT << sc_time_stamp() << ": " << name() << ": Module " << module_ready << " ready" << endl;
377 
378  // Multiple channels may be connected to the same module. Check for this particular case
379  for(int i = 0; i < No; i++) {
380 
381  for(int i = 0; i < (int) channels_required[module_ready].size(); i++) {
382  FOUT << sc_time_stamp() << ": " << name() << ": Channel " << channels_required[module_ready].at(i) << " ready" << endl;
383  start_initiator_channel_event[channels_required[module_ready].at(i)].notify();
384  }
385 
386  channels_required[module_ready].clear();
387  }
388  }
389 
390  // Wait, but delay should be 0
391  //wait(delay);
392 
393  trans.set_response_status(TLM_OK_RESPONSE);
394 
395  } else {
396  cerr << sc_time_stamp() << ": " << name() << ": ERROR: Address contained a wrong command" << endl;
397  //exit(-1);
398  Simulation_controller::endSimulation();
399  }
400 }
401 
402 
403 /****************************
404  **** Initiator part ****
405  ****************************/
406 
407 template<int No>
408 tlm_sync_enum TestbenchOut<No>::nb_transport_bw(int id, tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay) {
409 
410  // Put the transaction into the queue
411  m_id_init_map[&trans] = id;
412  m_peq.notify(trans, phase, delay);
413  return TLM_ACCEPTED;
414 }
415 
416 // Payload event queue callback function
417 template<int No>
418 void TestbenchOut<No>::peq_callback(tlm_generic_payload& trans, const tlm_phase& phase) {
419 
420  int socketID = m_id_init_map[&trans];
421 
422  #ifdef DEBUG
423  if (phase == END_REQ)
424  FOUT << sc_time_stamp() << ": " << name() << " (I" << socketID << ") received END_REQ at address " << hex << trans.get_address() << endl;
425  else if (phase == BEGIN_RESP)
426  FOUT << sc_time_stamp() << ": " << name() << " (I" << socketID << ") received BEGIN_RESP at address " << hex << trans.get_address() << endl;
427  #endif
428 
429  if (phase == END_REQ || (&trans == request_in_progress[socketID] && phase == BEGIN_RESP)) {
430  update_initiator_packet(socketID, &trans, phase);
431 
432  // The end of the BEGIN_REQ phase
433  request_in_progress[socketID] = 0;
434 
435  if(!is_priority_channel_out(socketID)) nb_non_priority_channels_requests_out--;
436  if(nb_non_priority_channels_requests_out == 0) shared_channel_out_ready_event.notify();
437 
438  } else if (phase == BEGIN_REQ || phase == END_RESP)
439  SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by initiator (testbench)");
440 
441  if (phase == BEGIN_RESP) {
442 
443  // The target has finished processing
444  Utils::check_transaction(trans);
445 
446  // Send final phase transition to target
447  tlm_phase fw_phase = END_RESP;
448  sc_time delay = end_resp_time[socketID];
449  output_initiator_socket[socketID]->nb_transport_fw(trans, fw_phase, delay);
450  // Ignore return value
451 
452  set_initiator_phase_end_resp_event[socketID].notify(delay);
453 
454  // End of transaction
455  request_in_progress[socketID] = 0;
456  //response_received_event.notify();
457 
458 
459  if(++nb_responses_received == No) {
460  nb_responses_received = 0;
461  all_responses_received_event.notify(delay);
462  }
463 
464  update_initiator_packet(socketID, &trans, phase);
465  }
466 }
467 
468 
469 template<int No>
471 
472  FOUT << sc_time_stamp() << ": Module " << name() << ": Channel " << channel_id << " ready! Launching initiator" << endl;
473  if(is_priority_channel_out(channel_id)) FOUT << sc_time_stamp() << ": Module " << name() << ": Priority channel!" << endl;
474  else FOUT << sc_time_stamp() << ": Module " << name() << ": Non priority channel!" << endl;
475 
476  if(request_in_progress[channel_id]) {
477  FOUT << sc_time_stamp() << ": " << name() << ": request already in progress in channel " << channel_id << ", waiting for end_of_response_channel_event" << endl;
478  next_trigger(end_of_response_channel_event[channel_id]);
479  return;
480  }
481 
482  if(!is_priority_channel_out(channel_id) && nb_non_priority_channels_requests_out != 0) {
483  FOUT << sc_time_stamp() << ": " << name() << ": request already in progress in shared channel, waiting for shared_channel_ready" << endl;
484  next_trigger(shared_channel_out_ready_event);
485  return;
486  }
487 
488  initiator_process(channel_id);
489 
490  next_trigger();
491 }
492 
493 template<int No>
495 
496  tlm_generic_payload* trans;
497  tlm_phase phase = BEGIN_REQ;
498  sc_time delay;
499 
500  if(!is_priority_channel_out(id)) nb_non_priority_channels_requests_out++;
501 
502  trans = m_mm.allocate();
503  trans->acquire();
504 
505  FOUT << endl << sc_time_stamp() << ": " << name() << " creates transaction " << current_transaction_id << " for socket " << id << endl;
506 
507  int adr = current_transaction_id;
508  FOUT << "Address: " << adr << endl;
509 
510  // Set all attributes except byte_enable_length and extensions (unused)
511  trans->set_command(TLM_WRITE_COMMAND);
512  trans->set_address(adr);
513  trans->set_data_ptr(reinterpret_cast<unsigned char*>(data_out[id]));
514  trans->set_data_length(4 * output_packet_size[id]);
515  trans->set_streaming_width(4 * output_packet_size[id]); // = data_length to indicate no streaming
516  trans->set_byte_enable_ptr(0); // 0 indicates unused
517  trans->set_dmi_allowed(false); // Mandatory initial value
518  trans->set_response_status(TLM_INCOMPLETE_RESPONSE); // Mandatory initial value
519 
520  request_in_progress[id] = trans;
521 
522  // Timing annotation models processing time of initiator prior to call
523  delay = begin_req_time[id];
524 
525  tlm_sync_enum status = output_initiator_socket[id]->nb_transport_fw(*trans, phase, delay);
526 
527  set_initiator_phase_begin_req_event[id].notify(delay);
528 
529  // Check value returned from nb_transport_fw
530  if (status == TLM_UPDATED) { /* Not used by the model */
531  // The timing annotation must be honored
532  m_id_init_map[trans] = id;
533  m_peq.notify(*trans, phase, delay);
534  } else if (status == TLM_COMPLETED) { /* Happens only when there is an error in the transaction */
535 
536  // The completion of the transaction necessarily ends the BEGIN_REQ phase
537  Utils::check_transaction(*trans);
538 
539  request_in_progress[id] = 0;
540 
541  //trans->release();
542  }
543 }
544 
545 template<int No>
547  Reconfiguration_manager::endApplication(applicationName, success);
548 }
549 
550 /******************************
551  **** User interface ****
552  ******************************/
553 template<int No>
554 void TestbenchOut<No>::set_packet_size(string connection_name, int val) {
555 
556  int socketID = -1;
557  for(int i = 0; i < (int) following_modules_connection_name.size(); i++) {
558  if(following_modules_connection_name.at(i).compare(connection_name) == 0) {
559  socketID = i;
560  break;
561  }
562  }
563 
564 #ifdef CONSOLE_DEBUG
565  cout << "Following module" << endl;
566  cout << "Socket ID: " << socketID << endl;
567 #endif
568 
569  try {
570  assert(socketID < No);
571  output_packet_size[socketID] = val;
572  delete[] data_out[socketID];
573  data_out[socketID] = new int[output_packet_size[socketID]];
574  for(int i = 0; i < output_packet_size[socketID]; i++) data_out[socketID][i] = 0;
575  } catch (bad_alloc& ba) {
576  cerr << "ERROR: " << name() << " bad_alloc caught: " << ba.what() << endl;
577  //exit(-1);
578  Simulation_controller::endSimulation();
579  }
580 }
581 
582 template<int No>
584 
585  channel_connection_vector = v;
586  following_modules_list.clear();
587 
588  // Check for redundancies for following modules list
589  for(int i = 0; i < (int) channel_connection_vector.size(); i++) {
590  bool item_found = false;
591  for(int j = 0; j < (int) following_modules_list.size(); j++) {
592  if(following_modules_list.at(j) == channel_connection_vector.at(i)) item_found = true;
593  }
594  if(!item_found) following_modules_list.push_back(channel_connection_vector.at(i));
595  }
596 }
597 
598 template<int No>
600  for(int j = 0; j < (int) following_modules_list.size(); j++) {
601  if(following_modules_list.at(j) != -1) following_modules_list[j] += offset;
602  }
603  for(int j = 0; j < (int) channel_connection_vector.size(); j++) {
604  if(channel_connection_vector.at(j) != -1) channel_connection_vector[j] += offset;
605  }
606 }
607 
608 template<int No>
610  if(output_initiator_socket.size() != No) {
611  cerr << "ERROR: Incorrect bindings for module " << name() << "! Exiting..." << endl;
612  exit(-1);
613  }
614 }
615 
616 
617 template<int No>
618 void TestbenchOut<No>::set_begin_req_time(string connection_name, sc_time t) {
619  add_timing_info(BEGIN_REQ, connection_name, t);
620 }
621 
622 template<int No>
623 void TestbenchOut<No>::set_end_resp_time(string connection_name, sc_time t) {
624  add_timing_info(END_RESP, connection_name, t);
625 }
626 
627 template<int No>
629  following_modules_connection_name.push_back(name);
630 }
631 
632 template<int No>
633 void TestbenchOut<No>::add_timing_info(tlm_phase_enum phase, string connection_name, sc_time time) {
634 
635  int socketID = -1;
636  for(int i = 0; i < (int) following_modules_connection_name.size(); i++) {
637  if(following_modules_connection_name.at(i).compare(connection_name) == 0) {
638  socketID = i;
639  break;
640  }
641  }
642 
643  switch(phase) {
644  case BEGIN_REQ: begin_req_time[socketID] = time; break;
645  case END_RESP: end_resp_time[socketID] = time; break;
646  default: cerr << "ERROR: Phase not recognized!" << endl;
647  }
648 }
649 
650 template<int No>
651 void TestbenchOut<No>::info(void) {
652 
653  FOUT << endl << "Testbench " << name() << ":" << endl;
654  FOUT << "Period: " << period << endl;
655 
656  for(int i = 0; i < No; i++) {
657  FOUT << "Output socket " << i << " (Connection " << following_modules_connection_name.at(i) << "):" << endl;
658  if(priority_channels_out.find(i) != priority_channels_out.end()) FOUT << " Priority channel" << endl;
659  FOUT << " Packet size: " << output_packet_size[i] << endl;
660  FOUT << " BEGIN_REQ time: " << begin_req_time[i] << endl;
661  FOUT << " END_RESP time: " << end_resp_time[i] << endl;
662  }
663 
664  FOUT << "Following list: ";
665  for(int i = 0; i < (int) following_modules_list.size(); i++) FOUT << dec << following_modules_list.at(i) << " ";
666  FOUT << endl;
667 }
668 
669 // Priority channels
670 template<int No>
671 void TestbenchOut<No>::add_priority_channel(string connection_name) {
672  int id = -1;
673 
674  for(int i = 0; i < (int) following_modules_connection_name.size(); i++) {
675  if(following_modules_connection_name.at(i).compare(connection_name) == 0) {
676  id = i;
677  break;
678  }
679  }
680 
681  if(id == -1) cerr << "ERROR: Module " << name() << " cannot find connection name through preceding or following modules vector!" << endl;
682 
683  assert(id < No);
684  priority_channels_out.insert(id);
685 }
686 
687 template<int No>
689  return (priority_channels_out.find(id) != priority_channels_out.end());
690 }
691 
692 template<int No>
694  applicationName = s;
695 }
696 
697 template<int No>
698 void TestbenchOut<No>::set_period(sc_time p) {
699  period = p;
700 }
701 
702 
703 template<int No>
704 int TestbenchOut<No>::get_output_socket_id(string connection_name) const {
705  int socketID = -1;
706  for(int i = 0; i < (int) following_modules_connection_name.size(); i++) {
707  if(following_modules_connection_name.at(i).compare(connection_name) == 0) {
708  socketID = i;
709  break;
710  }
711  }
712 
713  if(socketID == -1) {
714  cerr << "Error: Testbench unable to retrieve output socket ID via connection name" << endl;
715  exit(RECOSIM_INTERNAL_ERROR_ERRCODE);
716  }
717 
718  return socketID;
719 }
720 
721 
722 /*********************************
723  * Testbench out interface *
724  *********************************/
725 template<int No>
726 const char * TestbenchOut<No>::TB_IF_name(void) const {
727  return name();
728 }
729 
730 template<int No>
732  string fullname(name());
733  if(fullname.find("/") != string::npos) {
734  return (fullname.substr(fullname.find("/") + 1)).c_str();
735  } else return name();
736 }
737 
738 template<int No>
740  return data_out[socketID];
741 }
742 
743 template<int No>
744 int* TestbenchOut<No>::TB_IF_get_data_out_ptr(string connectionName) const {
745  return data_out[get_output_socket_id(connectionName)];
746 }
747 
748 template<int No>
750  // Retrieve module ID
751  int module_id = channel_connection_vector.at(socketID);
752  FOUT << "Module ID: " << module_id << endl;
753 
754  // QUESTIONFAB : a quoi cela sert exactement "channels_required" ?
755  bool first_module_request = (channels_required[module_id].empty());
756  channels_required[module_id].push_back(socketID);
757 
758  if(first_module_request) manager_b_transport(module_id);
759 }
760 
761 template<int No>
762 void TestbenchOut<No>::TB_IF_nb_send_data(string connectionName) {
763  TB_IF_nb_send_data(get_output_socket_id(connectionName));
764 }
765 
766 template<int No>
768  for(int i = 0; i < No; i++) TB_IF_nb_send_data(i);
769 }
770 
771 template<int No>
773  return all_responses_received_event;
774 }
775 
776 template<int No>
778  current_transaction_id++;
779 }
780 
781 template<int No>
783  return applicationName;
784 }
785 
786 template<int No>
788  return period;
789 }
790 
791 template<int No>
792 void TestbenchOut<No>::TB_IF_add_execution_mode_command_to_queue(string module_name, string command, sc_time delay) {
793  algorithm_mode_command_priority_queue.push(AlgorithmModeCommand(module_name, command, delay));
794  algorithm_mode_command_event_queue.notify(delay);
795 }
796 
797 template<int No>
799 
800  AlgorithmModeCommand top_command(algorithm_mode_command_priority_queue.top());
801  cout << name() << ": Popping command " << top_command.get_command() << " for module " << top_command.get_target_module() << " at t=" << sc_time_stamp() << endl;
802  send_algorithm_command_to_manager(&top_command);
803  algorithm_mode_command_priority_queue.pop();
804 
805 }
806 
807 template<int No>
809  return output_packet_size[ID];
810 }
811 
812 template<int No>
813 int TestbenchOut<No>::TB_IF_get_packet_size(string connectionName) const {
814  return TB_IF_get_packet_size(get_output_socket_id(connectionName));
815 }
816 
817 template<int No>
818 int TestbenchOut<No>::TB_IF_get_output_socket_id(string connectionName) const {
819  return get_output_socket_id(connectionName);
820 }
821 
822 
823 /**********************************
824  * Packet trace methods *
825  **********************************/
826 template<int No>
828  //update_initiator_packet(0);
829  //update_target_packet(0);
830 }
831 
832 template<int No>
833 void TestbenchOut<No>::update_initiator_packet(int id, tlm_generic_payload* trans, tlm_phase phase) {
834  assert(id < No);
835  trace_packet.initiator_packet[id].phase = tlm_phase_to_ascii(phase);
836  update_initiator_packet(id, trans);
837 }
838 
839 template<int No>
840 void TestbenchOut<No>::update_initiator_packet(int id, tlm_generic_payload* trans) {
841  assert(id < No);
842  trace_packet.initiator_packet[id].transaction.update_transaction(trans);
843 }
844 
845 template<int No>
847  assert(id < No);
848  trace_packet.initiator_packet[id].phase = BEGIN_REQ_ASCII;
849 }
850 
851 template<int No>
853  assert(id < No);
854  trace_packet.initiator_packet[id].phase = END_RESP_ASCII;
855 }
856 
857 #endif
void TB_IF_nb_send_data(int socketID)
Non-blocking data send through a given socket.
Definition: testbench_out.h:749
int * TB_IF_get_data_out_ptr(int) const
Get pointer to ougoing data structure.
Definition: testbench_out.h:739
string TB_IF_get_instance_name(void) const
Get testbench instance name.
Definition: testbench_out.h:731
int TB_IF_get_packet_size(int ID) const
Get socket packet size.
Definition: testbench_out.h:808
Definition: algorithm_mode_command.h:30
Definition: memory_manager.h:29
string TB_IF_getApplicationName(void)
Get application name (application in which this testbench has been instantiated). ...
Definition: testbench_out.h:782
Definition: testbench_out_interface.h:31
void TB_IF_nb_send_all_data(void)
Non-blocking data send through every socket.
Definition: testbench_out.h:767
sc_time TB_IF_get_period(void) const
Get testbench period.
Definition: testbench_out.h:787
Definition: testbench_out.h:54
const char * TB_IF_name(void) const
Get testbench full name.
Definition: testbench_out.h:726
void TB_IF_increment_current_transaction_id(void)
Increments working transaction counter.
Definition: testbench_out.h:777
const sc_event & TB_IF_all_responses_received_event(void) const
Watch the event issued once all TLM responses have been sent from following modules to testbench...
Definition: testbench_out.h:772
Definition: trace.h:161
User_algorithm_action
Definition: user_algorithm_interface.h:32
void TB_IF_add_execution_mode_command_to_queue(string module_name, string command, sc_time delay)
Add an algorithm control command to the waiting queue. After the delay passed as parameter, testbench will notify module 'module_name' that its algorithm should go to mode 'command'.
Definition: testbench_out.h:792
Definition: algorithm_mode_command.h:48
int TB_IF_get_output_socket_id(string name) const
Get input socket id by the name of the connection.
Definition: testbench_out.h:818