RecoSim  1.0
 All Classes Files Functions Variables Enumerations
module.h
Go to the documentation of this file.
1 
22 #ifndef MODULE_H
23 #define MODULE_H
24 
25 #define SC_INCLUDE_DYNAMIC_PROCESSES
26 
27 #include <systemc.h>
28 #include "tlm.h"
29 #include "tlm_utils/peq_with_cb_and_phase.h"
30 #include "tlm_utils/multi_passthrough_initiator_socket.h"
31 #include "tlm_utils/multi_passthrough_target_socket.h"
32 #include "tlm_utils/simple_initiator_socket.h"
33 #include "tlm_utils/simple_target_socket.h"
34 
35 #include "memory_manager.h"
38 #include "trace.h"
39 #include "utils.h"
40 #include "manager_interface.h"
41 #include "module_interface.h"
42 
43 #include <vector>
44 #include <map>
45 #include <set>
46 #include <sstream>
47 
48 using namespace sc_core;
49 using namespace sc_dt;
50 using namespace std;
51 using namespace tlm;
52 using namespace tlm_utils;
53 
54 #define FOUT if(generate_logfile()) (*fout)
55 
56 
57 //#define CONSOLE_DEBUG
58 
59 template<int Ni = 1, int No = 1>
60 class Module : public sc_module, public Reconf_thread_interface, public User_algorithm_interface<Ni, No>, public Manager_interface {
61 
62 public:
63 
64  // I/O Sockets
65  multi_passthrough_target_socket<Module> target_socket;
66  multi_passthrough_initiator_socket<Module> initiator_socket;
67 
68  // Configuration socket
69  simple_target_socket<Module> manager_target_socket;
70  simple_initiator_socket<Module> manager_initiator_socket;
71 
72 private:
73 
74  // Memory manager
75  Memory_manager m_mm;
76 
77  // Payload event queues
78  peq_with_cb_and_phase<Module> m_peq;
79  peq_with_cb_and_phase<Module> m_peq_targ;
80 
81  // Maps to retrieve socket ID from a transaction in PEQ callbacks
82  map<tlm_generic_payload*, unsigned int> m_id_targ_map;
83  map<tlm_generic_payload*, unsigned int> m_id_init_map;
84 
85  // Implementation vector
86  vector<ModuleImplementation> implementation_execution_times_vector;
87 
88  // Data
89  sc_dt::uint64 address_in[Ni];
90  sc_dt::uint64 address_out[No];
91  int *data_in[Ni];
92  int *data_out[No];
93  int transactions_processed;
94  bool request_in_progress[No];
95 
96  // Transactions
97  tlm_generic_payload* incoming_transaction[Ni];
98  tlm_generic_payload* incoming_transaction_pending[Ni];
99  tlm_generic_payload* outgoing_transaction[No];
100 
101  // Events
102  sc_event end_of_response_channel_event[No];
103  sc_event configuration_updated_event;
104  sc_event start_initiator_channel_event[No];
105  sc_event question_manager_task_end_computation_event;
106  sc_event question_manager_task_preemption_event;
107  sc_event configuration_done_event;
108  sc_event continue_execution_event;
109  sc_event shared_channel_ready_event;
110  sc_event release_physical_channels_event[Ni];
111  sc_event send_end_req_event[Ni];
112  sc_event start_algorithm_event;
113 
114  sc_event parameter_computation_event;
115  Algorithm_Parameters* parameter_computation_data;
117  // Events to update trace packets
118  sc_event set_target_phase_idle_event[Ni];
119  sc_event set_initiator_phase_idle_event[No];
120 
121  // Timing parameters
122  sc_time begin_req_time[No];
123  sc_time end_req_time[Ni];
124  sc_time begin_resp_time[Ni];
125  sc_time end_resp_time[No];
126  sc_time deadline_time;
127  sc_time absolute_deadline_time;
128  sc_time last_absolute_deadline_time;
130  // Data stream configuration
131  int input_stream_packet_size[Ni];
132  int output_stream_packet_size[No];
134  // Lists of previous and next modules
135  vector<int> preceding_modules_list;
136  vector<int> following_modules_list;
137  vector<int> channel_connection_vector;
138  vector<string> following_modules_connection_name;
139  vector<string> preceding_modules_connection_name;
140  int application_offset;
142  // Misc
143  bool static_module;
144  int priority;
145 
146  // Log file stream
147  ofstream* fout;
148 
149  // Trace file
150  bool enable_configuration_trace;
151  sc_trace_file *tf;
152  trace_packet_t<Ni, No> trace_packet;
153 
154  // Interfaces stuff
155  map<string, ModuleInterface> module_interfaces; // Map with all interfaces needed by the module
156  int current_implementation_id; // Current implementation ID
157  map<string, int> physical_channels_map; // Number of physical channels available for each kind provided by the implementation
158 
159  // Periodic tasks parameters
160  sc_time task_period;
161  sc_time task_offset;
162 
163  // Cyclic diagrams parameters
164  bool first_transaction;
165  bool first_request;
166 
167  // User algorithm thread modification stuff
168  sc_event update_user_algorithm_event;
169  bool kill_user_algorithm_thread;
170 
171  map<int, vector<int> > channels_required;
172 
173  sc_buffer<bool> socket_data_received[Ni];
174  sc_event update_socket_data_received_buffer_event[Ni];
175  bool m_new_val_data_received[Ni];
176 
177  sc_buffer<bool> socket_data_sent[No];
178  sc_event update_socket_data_sent_buffer_event[No];
179  bool m_new_val_data_sent[No];
180  bool first_data_send_on_socket[No];
181 
182  bool algorithm_ended;
183  int nb_packets_remaining;
184 
185  int nb_algorithm_executions;
186 
187  string algorithm_execution_mode;
188 
189  bool algorithm_execution_requested;
190 
191 public:
192  SC_HAS_PROCESS(Module);
193  Module(
194  sc_module_name instname,
196  ofstream& logfile,
197  sc_trace_file *mtf) :
198  sc_module(instname),
199  target_socket("Module_T_Socket"),
200  initiator_socket("Module_I_Socket"),
201  manager_target_socket("Module_MT_socket"),
202  manager_initiator_socket("Module_MI_socket"),
203  m_peq(this, &Module::peq_callback),
204  m_peq_targ(this, &Module::peq_targ_callback),
205  fout(&logfile),
206  tf(mtf),
207  parameter_computation_data(NULL) {
208 
209  init();
210 
211  // Dynamic thread (Reconf thread)
212  sc_spawn(sc_bind(reconf_fct, sc_ref(*this), sc_ref(*this)));
213  }
214 
215  ~Module() {
216  for(int i = 0; i < Ni; i++) delete[] data_in[i];
217  for(int i = 0; i < No; i++) delete[] data_out[i];
218  }
219 
220 private:
221  // Main process
222  void init(void);
223  int retrieve_channel_id(int module_id);
224  void dynamic_transfer_process_method(int channel_id);
225  void initiator_process(int channel_id);
226 
227  // Manager scheduling threads & methods
228  void question_manager_task_end_computation_thread(void);
229  void question_manager_task_preemption_thread(void);
230  void question_manager_b_transport(int address, int data);
231 
232  // Payload event queue callback function
233  virtual void peq_callback(tlm_generic_payload& trans, const tlm_phase& phase);
234  void peq_targ_callback(tlm_generic_payload& trans, const tlm_phase& phase);
235 
236  // Helper functions
237  void send_response(int id, tlm_generic_payload& trans);
238  void send_error_response(int id, tlm_generic_payload& trans);
239  tlm_sync_enum send_end_req(int id, tlm_generic_payload& trans);
240  vector<ModuleImplementation>* get_implementation_vector_ptr(void);
241  void send_end_req_method(int id);
242 
243  // Trace packet
244  void init_packet(void);
245  void update_trace_packet(void);
246  void update_initiator_packet(int id, tlm_generic_payload* trans, tlm_phase phase);
247  void update_initiator_packet(int id, tlm_generic_payload* trans);
248  void update_target_packet(int id, tlm_phase phase);
249  void update_target_packet(int id);
250  void set_com_status_waiting(int id);
251  void set_com_status_tx(int id);
252  void set_com_status_idle(int id);
253  void set_target_phase(int id, tlm_phase& phase);
254  void set_initiator_phase(int id, tlm_phase& phase);
255  void set_config_phase(tlm_phase& phase);
256  void trace_update_algorithm_execution_mode(void);
257  void set_target_phase_idle(int);
258  void set_initiator_phase_idle(int);
259 
260  void remove_priority_channels_from_physical_channel_map(void);
261  bool are_priority_channels_respected(string);
262  void release_physical_channel(string connection_name);
263  void acquire_physical_channel(string connection_name);
264 
265 public:
266 
268  const char* get_name() const;
269  int* get_data_in_ptr(int);
270  int* get_data_in_ptr(string);
271  int get_data_in_length(int) const;
272  int get_data_in_length(string) const;
273  sc_dt::uint64 get_address_in(int) const;
274  sc_dt::uint64 get_address_in(string) const;
275  int* get_data_out_ptr(int);
276  int* get_data_out_ptr(string);
277  int get_data_out_length(int) const;
278  int get_data_out_length(string) const;
279  void set_address_out(int, sc_dt::uint64);
280  void set_address_out(string, sc_dt::uint64);
281  int get_input_socket_id(string name) const;
282  int get_output_socket_id(string name) const;
283  sc_time get_WCET(void) const;
284  sc_time get_BCET(void) const;
285  void end_of_algorithm(void);
286  void preemption_point(void);
287  void compute(sc_time duration);
288  bool isTransactionInMemory(void);
289  const sc_event& getEOREvent(void) const;
290  const sc_event& update_user_algorithm(void) const;
291  void wait_for_update_user_algorithm(void);
292  bool& kill_user_algorithm(void);
293  void b_data_received(string);
294  void b_data_received(int);
295  void b_all_data_received(void);
296  bool nb_data_received(string);
297  bool nb_data_received(int);
298  bool nb_all_data_received(void);
299  void nb_send_data(string);
300  void nb_send_data(int);
301  void nb_send_all_data(void);
302  void b_send_data(string);
303  void b_send_data(int);
304  void b_send_all_data(void);
305  void b_data_sent(int id);
306  bool nb_data_sent(int id);
307  void b_data_sent(string name);
308  bool nb_data_sent(string name);
309  void b_all_data_sent(void);
310  bool nb_all_data_sent(void);
311  void start_new_transaction_sequence(void);
312  void start_new_transaction_sequence(int id);
313  void start_new_transaction_sequence(string name);
314  bool is_channel_transient(string);
315  bool is_channel_transient(int);
316  int get_nb_preemption_points(void);
317  void set_algorithm_running(void);
318  void set_algorithm_idle(void);
319  void set_algorithm_waiting(void);
320  void wait_until_next_period(void);
321  ofstream& get_logfile(void);
322  string get_algorithm_execution_mode(void);
323  bool is_algorithm_execution_mode(string);
324  void release_input_socket(int socketID);
325  void release_input_socket(string connectionName);
326  void release_all_input_sockets(void);
327  void b_execution_requested(void);
328 
330  const sc_event& configuration_updated() const;
331  void finish_configuration(void);
332  int get_current_implementation_id(void);
333  vector<ModuleImplementation> get_implementation_vector(void);
334 
336  bool has_implementation(TaskImplementation&) const;
337  void set_current_implementation(string);
338  vector<ModuleImplementation> get_implementation_vector(void) const;
339  sc_time get_deadline_time(void) const;
340  sc_time get_task_deadline(void) const;
341  void set_request_time(void);
342  bool fits(RZ *rz);
343  string getName(void) const;
344  int get_nb_processed_transactions(void) const;
345  vector<int> getFollowingList(void) const;
346  vector<int> getPrecedingList(void) const;
347  void updateLists(int offset);
348  bool is_static(void) const;
349  int get_task_priority(void) const;
350  sc_time get_task_period(void) const;
351  sc_time get_task_offset(void) const;
352  string get_current_implementation_fullname(void);
353  bool has_current_implementation(void);
354  ModuleImplementation get_current_implementation(void);
355  void update_algorithm_execution_mode(string command);
356  bool use_context_switch_mode(string implementationName);
357  void send_start_algorithm_event(void);
358  sc_time get_new_period_start_time(void) const;
359  int get_nb_transient_channels(void);
360  void set_task_priority(int priority);
361 
364  // Transport functions
365  tlm_sync_enum nb_transport_bw(int id, tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay);
366  tlm_sync_enum nb_transport_fw(int id, tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay);
367  void b_transport_conf(tlm_generic_payload& trans, sc_time& delay);
368 
369  // Timing
370  void add_timing_info(tlm_phase_enum phase, string connection_name, sc_time time);
371  void set_begin_req_time(string connection_name, sc_time t);
372  void set_end_req_time(string connection_name, sc_time t);
373  void set_begin_resp_time(string connection_name, sc_time t);
374  void set_end_resp_time(string connection_name, sc_time t);
375  void set_deadline_time(sc_time t);
376 
377  // Next/Previous modules
378  void set_preceding_modules_list(vector<int> &v);
379  void set_following_modules_list(vector<int> &v);
380  void add_following_module_connection_name(string name);
381  void add_preceding_module_connection_name(string name);
382 
383  // Data stream configuration
384  void set_packet_size(string connection_name, int size);
385 
386  // Trace
387  void enable_configuration_signals_trace(void);
388  void activate_trace(void);
389 
390  // Misc
391  void info(void);
392  void verify_bindings(void);
393  void set_implementation_vector(vector<ModuleImplementation>& impl);
394  void set_static_module(void);
395  void set_priority(int);
396 
397  // Priority channels and typing
398  void add_interface(ModuleInterface mod_if);
399  void release_physical_channels_method(int channel_id);
400  bool is_physical_channel_available(string connection_name);
401  void display_physical_channels_map(void);
402  string get_input_connection_name(int id);
403  string get_output_connection_name(int id);
404 
405  void set_task_period(sc_time p);
406  void set_task_offset(sc_time o);
407 
408  void update_socket_data_received_buffer(int);
409  void update_socket_data_sent_buffer(int);
410 };
411 
412 template<int Ni, int No>
414  assert(id<Ni);
415  socket_data_received[id].write(m_new_val_data_received[id]);
416 }
417 
418 template<int Ni, int No>
420  assert(id<No);
421  socket_data_sent[id].write(m_new_val_data_sent[id]);
422 }
423 
424 
425 // Initialization function
426 template<int Ni, int No>
427 void Module<Ni, No>::init(void) {
428 
429  // Some initializations
430  for(int i = 0; i < Ni; i++) {
431  incoming_transaction[i] = 0;
432  incoming_transaction_pending[i] = 0;
433  socket_data_received[i].write(false);
434  m_new_val_data_received[i] = false;
435  end_req_time[i] = SC_ZERO_TIME;
436  begin_resp_time[i] = SC_ZERO_TIME;
437 
438  // Data stream configuration (default to 16 words)
439  input_stream_packet_size[i] = 16;
440  data_in[i] = new int[input_stream_packet_size[i]];
441  for(int j = 0; j < input_stream_packet_size[i]; j++) data_in[i][j] = 0;
442  }
443 
444  for(int i = 0; i < No; i++) {
445  outgoing_transaction[i] = 0;
446  request_in_progress[i] = false;
447  socket_data_sent[i].write(false);
448  m_new_val_data_sent[i] = false;
449  first_data_send_on_socket[i] = true;
450  begin_req_time[i] = SC_ZERO_TIME;
451  end_resp_time[i] = SC_ZERO_TIME;
452 
453  // Data stream configuration (default to 16 words)
454  output_stream_packet_size[i] = 16;
455  data_out[i] = new int[output_stream_packet_size[i]];
456  for(int j = 0; j < output_stream_packet_size[i]; j++) data_out[i][j] = 0;
457  }
458 
459  algorithm_execution_requested = false;
460 
461  transactions_processed = 0;
462  priority = 1;
463 
464  task_period = SC_ZERO_TIME;
465  task_offset = SC_ZERO_TIME;
466 
467  first_transaction = true;
468  first_request = true;
469 
470  kill_user_algorithm_thread = false;
471 
472  current_implementation_id = -1;
473 
474  algorithm_ended = false;
475  nb_packets_remaining = 0;
476  static_module = false;
477 
478  nb_algorithm_executions = 0;
479 
480  algorithm_execution_mode = "Default";
481 
482  // Init timing parameters
483  deadline_time = SC_ZERO_TIME;
484  absolute_deadline_time = deadline_time;
485  last_absolute_deadline_time = SC_ZERO_TIME;
486 
487  // Register transport methods
488  initiator_socket.register_nb_transport_bw(this, &Module<Ni, No>::nb_transport_bw);
489  target_socket.register_nb_transport_fw(this, &Module<Ni, No>::nb_transport_fw);
490  manager_target_socket.register_b_transport(this, &Module<Ni, No>::b_transport_conf);
491 
492  application_offset = 0;
493 
494  // Init trace packet
495  init_packet();
496 
497  // SC_THREADS initialization
498  SC_THREAD(question_manager_task_end_computation_thread);
499  SC_THREAD(question_manager_task_preemption_thread);
500 
501  // Dynamic threads initialization to handle dynamic channels
502  for(int i = 0; i < Ni; i++) {
503  sc_spawn_options method_options;
504  method_options.spawn_method();
505  method_options.dont_initialize();
506  method_options.set_sensitivity(&release_physical_channels_event[i]);
507  string process_name("decrement_nb_physical_channels_method_");
508  ostringstream out;
509  out << i;
510  process_name.append(out.str());
511 
512  sc_spawn(sc_bind(&Module<Ni, No>::release_physical_channels_method, this, i), process_name.c_str(), &method_options);
513  }
514 
515  // Dynamic threads initialization for channel communications
516  for(int i = 0; i < No; i++) {
517  sc_spawn_options method_options;
518  method_options.spawn_method();
519  method_options.dont_initialize();
520  method_options.set_sensitivity(&start_initiator_channel_event[i]);
521  string process_name("Dynamic_process_");
522  ostringstream out;
523  out << i;
524  process_name.append(out.str());
525 
526  sc_spawn(sc_bind(&Module<Ni, No>::dynamic_transfer_process_method, this, i), process_name.c_str(), &method_options);
527  }
528 
529  // Dynamic threads initialization for tracing purpose: set_target_phase_idle
530  for(int i = 0; i < Ni; i++) {
531  sc_spawn_options method_options;
532  method_options.spawn_method();
533  method_options.dont_initialize();
534  method_options.set_sensitivity(&set_target_phase_idle_event[i]);
535  string process_name("set_target_phase_idle_process_");
536  ostringstream out;
537  out << i;
538  process_name.append(out.str());
539 
540  sc_spawn(sc_bind(&Module<Ni, No>::set_target_phase_idle, this, i), process_name.c_str(), &method_options);
541  }
542 
543  // Dynamic threads initialization for tracing purpose: set_initiator_phase_idle
544  for(int i = 0; i < No; i++) {
545  sc_spawn_options method_options;
546  method_options.spawn_method();
547  method_options.dont_initialize();
548  method_options.set_sensitivity(&set_initiator_phase_idle_event[i]);
549  string process_name("set_initiator_phase_idle_process_");
550  ostringstream out;
551  out << i;
552  process_name.append(out.str());
553 
554  sc_spawn(sc_bind(&Module<Ni, No>::set_initiator_phase_idle, this, i), process_name.c_str(), &method_options);
555  }
556 
557  // Dynamic threads for sending END_REQ to transaction initiator
558  for(int i = 0; i < Ni; i++) {
559  sc_spawn_options method_options;
560  method_options.spawn_method();
561  method_options.dont_initialize();
562  method_options.set_sensitivity(&send_end_req_event[i]);
563  string process_name("send_end_req_process_");
564  ostringstream out;
565  out << i;
566  process_name.append(out.str());
567 
568  sc_spawn(sc_bind(&Module<Ni, No>::send_end_req_method, this, i), process_name.c_str(), &method_options);
569  }
570 
571 
572  // Dynamic threads for channel buffer updates
573  for(int i = 0; i < Ni; i++) {
574  sc_spawn_options method_options;
575  method_options.spawn_method();
576  method_options.dont_initialize();
577  method_options.set_sensitivity(&update_socket_data_received_buffer_event[i]);
578  string process_name("update_data_received_buffer_process_");
579  ostringstream out;
580  out << i;
581  process_name.append(out.str());
582 
583  sc_spawn(sc_bind(&Module<Ni, No>::update_socket_data_received_buffer, this, i), process_name.c_str(), &method_options);
584  }
585 
586  // Dynamic threads for channel buffer updates
587  for(int i = 0; i < No; i++) {
588  sc_spawn_options method_options;
589  method_options.spawn_method();
590  method_options.dont_initialize();
591  method_options.set_sensitivity(&update_socket_data_sent_buffer_event[i]);
592  string process_name("update_data_sent_buffer_process_");
593  ostringstream out;
594  out << i;
595  process_name.append(out.str());
596 
597  sc_spawn(sc_bind(&Module<Ni, No>::update_socket_data_sent_buffer, this, i), process_name.c_str(), &method_options);
598  }
599 }
600 
601 /***********************************
602  ****** Initiator part ******
603  ***********************************/
604 
605 // Backward path for initiator socket
606 template<int Ni, int No>
607 tlm_sync_enum Module<Ni, No>::nb_transport_bw(int id, tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay) {
608 
609  // Put the transaction into the queue
610  m_id_init_map[&trans] = id;
611  m_peq.notify(trans, phase, delay);
612 
613  set_initiator_phase(id, phase);
614 
615  return TLM_ACCEPTED;
616 }
617 
618 // Payload event queue callback function
619 template<int Ni, int No>
620 void Module<Ni, No>::peq_callback(tlm_generic_payload& trans, const tlm_phase& phase) {
621 
622  int socketID = m_id_init_map[&trans];
623 
624 #ifdef DEBUG
625  if (phase == END_REQ)
626  FOUT << sc_time_stamp() << ": " << name() << " (I" << socketID << ") received END_REQ at address " << hex << trans.get_address() << endl;
627  else if (phase == BEGIN_RESP)
628  FOUT << sc_time_stamp() << ": " << name() << " (I" << socketID << ") received BEGIN_RESP at address " << hex << trans.get_address() << endl;
629 #endif
630 
631  //if (phase == END_REQ || (&trans == outgoing_transaction[socketID] && phase == BEGIN_RESP)) {
632  if (phase == END_REQ) {
633 
634  update_initiator_packet(socketID, &trans, phase);
635 
636  nb_packets_remaining--;
637 
638  if(algorithm_ended && (nb_packets_remaining == 0)) {
639  FOUT << sc_time_stamp() << ": " << name()<< ": every packet transfered" << endl;
640  algorithm_ended = false;
641  }
642 
643  m_new_val_data_sent[socketID] = true;
644  update_socket_data_sent_buffer_event[socketID].notify();
645 
646  outgoing_transaction[socketID] = 0;
647 
648  release_physical_channel(get_output_connection_name(socketID));
649  shared_channel_ready_event.notify();
650 
651  set_com_status_idle(socketID);
652 
653  //set_initiator_phase_end_resp_event[socketID].notify();
654  set_initiator_phase_idle(socketID);
655 
656  } else if (phase == BEGIN_RESP) {
657  // The target has finished processing
658 
659  update_initiator_packet(socketID, &trans, phase);
660  Utils::check_transaction(trans);
661 
662  // Send final phase transition to target
663  tlm_phase fw_phase = END_RESP;
664  sc_time delay = end_resp_time[socketID];
665  initiator_socket[socketID]->nb_transport_fw(trans, fw_phase, delay);
666  // Ignore return value
667 
668  request_in_progress[socketID] = false;
669 
670  end_of_response_channel_event[socketID].notify();
671 
672  set_initiator_phase(socketID, fw_phase);
673  set_initiator_phase_idle_event[socketID].notify(delay);
674  } else if (phase == BEGIN_REQ || phase == END_RESP) SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by initiator");
675 
676 }
677 
678 template<int Ni, int No>
680  FOUT << "Physical channel map state" << endl;
681  for(map<string, int>::const_iterator it = physical_channels_map.begin(); it != physical_channels_map.end(); it++) {
682  FOUT << it->first << ": " << it->second << " channel(s) free" << endl;
683  }
684 }
685 
686 template<int Ni, int No>
687 bool Module<Ni, No>::is_physical_channel_available(string connection_name) {
688 
689  FOUT << "Checking interface availability for connection: " << connection_name << endl;
690 
691  display_physical_channels_map();
692 
693  if(are_priority_channels_respected(module_interfaces[connection_name].get_type())) {
694 
695  FOUT << "Priority channels respected" << endl;
696  if(module_interfaces[connection_name].is_priority_channel()) {
697  FOUT << "Priority channel!" << endl;
698  return true;
699  } else {
700  // Not a priority channel, do nothing
701  }
702 
703  }else {
704  FOUT << "Not enough physical channels to respect priority => not considering priority channels!" << endl;
705  }
706 
707  return (physical_channels_map[module_interfaces[connection_name].get_type()] != 0);
708 }
709 
710 template<int Ni, int No>
711 void Module<Ni, No>::release_physical_channel(string connection_name) {
712  if(!are_priority_channels_respected(module_interfaces[connection_name].get_type()) || !module_interfaces[connection_name].is_priority_channel()) {
713  physical_channels_map[module_interfaces[connection_name].get_type()]++;
714  }
715 
716  display_physical_channels_map();
717 }
718 
719 template<int Ni, int No>
720 void Module<Ni, No>::acquire_physical_channel(string connection_name) {
721  if(!are_priority_channels_respected(module_interfaces[connection_name].get_type()) || !module_interfaces[connection_name].is_priority_channel()) {
722  physical_channels_map[module_interfaces[connection_name].get_type()]--;
723  }
724 
725  display_physical_channels_map();
726 }
727 
728 
729 template<int Ni, int No>
731 
732  FOUT << sc_time_stamp() << ": Module " << name() << ": Channel " << channel_id << " ready! Launching initiator" << endl;
733 
734  if(request_in_progress[channel_id]) {
735  FOUT << sc_time_stamp() << ": " << name() << ": request already in progress in channel " << channel_id << ", waiting for end_of_response_channel_event" << endl;
736  next_trigger(end_of_response_channel_event[channel_id]);
737  return;
738  }
739 
740  if(!is_physical_channel_available(get_output_connection_name(channel_id)) && !static_module) {
741  FOUT << sc_time_stamp() << ": " << name() << ": no channel available at this point, waiting for shared_channel_ready" << endl;
742  next_trigger(shared_channel_ready_event);
743  return;
744  }
745 
746  // Decrease number of available channels
747  acquire_physical_channel(get_output_connection_name(channel_id));
748 
749  initiator_process(channel_id);
750 
751  next_trigger();
752 }
753 
754 template<int Ni, int No>
755 void Module<Ni, No>::initiator_process(int channel_id) {
756 
757  request_in_progress[channel_id] = true;
758 
759  tlm_generic_payload* trans;
760  tlm_phase phase;
761  sc_time delay;
762  tlm_command cmd;
763 
764  // Grab a new transaction from the memory manager
765  trans = m_mm.allocate();
766  trans->acquire();
767 
768  cmd = TLM_WRITE_COMMAND;
769  phase = BEGIN_REQ;
770 
771  // Set all attributes except byte_enable_length and extensions (unused)
772  trans->set_command(cmd);
773  trans->set_address(address_out[channel_id]);
774  trans->set_data_ptr(reinterpret_cast<unsigned char*>(data_out[channel_id]));
775  trans->set_data_length(4 * output_stream_packet_size[channel_id]);
776  trans->set_streaming_width(4 * output_stream_packet_size[channel_id]); // = data_length to indicate no streaming
777  trans->set_byte_enable_ptr(0); // 0 indicates unused
778  trans->set_dmi_allowed(false); // Mandatory initial value
779  trans->set_response_status(TLM_INCOMPLETE_RESPONSE); // Mandatory initial value
780 
781  outgoing_transaction[channel_id] = trans;
782 
783  // Timing annotation models processing time of initiator prior to call
784  delay = begin_req_time[channel_id];
785 
786  // Non-blocking transport call on the forward path
787  tlm_sync_enum status;
788  status = initiator_socket[channel_id]->nb_transport_fw(*trans, phase, delay);
789 
790  // Check value returned from nb_transport_fw
791  if (status == TLM_UPDATED) {
792  // The timing annotation must be honored
793  m_id_init_map[trans] = channel_id;
794  m_peq.notify(*trans, phase, delay);
795  } else if (status == TLM_COMPLETED) {
796  // The completion of the transaction necessarily ends the BEGIN_REQ phase
797  outgoing_transaction[channel_id] = 0;
798 
799  //physical_channels_map[module_interfaces[get_output_connection_name(channel_id)].get_type()]++;
800  release_physical_channel(get_output_connection_name(channel_id));
801  shared_channel_ready_event.notify();
802 
803  request_in_progress[channel_id] = false;
804  // The target has terminated the transaction
805  Utils::check_transaction(*trans);
806  }
807 
808  update_initiator_packet(channel_id, trans);
809  //set_initiator_phase_begin_req_event[channel_id].notify(delay);
810  set_initiator_phase(channel_id, phase);
811  //update_target_packet(channel_id);
812 
813  set_com_status_tx(channel_id);
814 }
815 
816 template<int Ni, int No>
817 int Module<Ni, No>::retrieve_channel_id(int module_id) {
818  int id = 0;
819  while(following_modules_list.at(id) != module_id) id++;
820  return id;
821 }
822 
823 
824 template<int Ni, int No>
826  return preceding_modules_connection_name.at(id);
827 }
828 
829 template<int Ni, int No>
831  return following_modules_connection_name.at(id);
832 }
833 
834 
835 
836 /***********************************
837  ****** Target part ******
838  ***********************************/
839 
840 // Forward path for the target socket
841 template<int Ni, int No>
842 tlm_sync_enum Module<Ni, No>::nb_transport_fw(int id, tlm_generic_payload& trans, tlm_phase& phase, sc_time& delay) {
843 
844  unsigned int len = trans.get_data_length();
845  unsigned char* byt = trans.get_byte_enable_ptr();
846  unsigned int wid = trans.get_streaming_width();
847 
848  // Obliged to check the transaction attributes for unsupported features
849  // and to generate the appropriate error response
850  if (byt != 0) {
851  trans.set_response_status(TLM_BYTE_ENABLE_ERROR_RESPONSE);
852  return TLM_COMPLETED;
853  }
854  if (len > (unsigned int)(4 * input_stream_packet_size[id]) || wid < len) {
855  trans.set_response_status(TLM_BURST_ERROR_RESPONSE);
856  return TLM_COMPLETED;
857  }
858 
859  // Now queue the transaction until the annotated time has elapsed
860  m_id_targ_map[&trans] = id;
861  m_peq_targ.notify(trans, phase, delay);
862 
863  set_target_phase(id, phase);
864 
865  return TLM_ACCEPTED;
866 }
867 
868 // Payload event queue callback (Target side)
869 template<int Ni, int No>
870 void Module<Ni, No>::peq_targ_callback(tlm_generic_payload& trans, const tlm_phase& phase) {
871 
872  //tlm_sync_enum status;
873  sc_time delay;
874 
875  int socketID = m_id_targ_map[&trans];
876 
877 #ifdef DEBUG
878  if(phase == BEGIN_REQ)
879  FOUT << sc_time_stamp() << ": " << name() << " (T" << socketID << ") received BEGIN_REQ at address " << hex << trans.get_address() << endl;
880  else if(phase == END_RESP)
881  FOUT << sc_time_stamp() << ": " << name() << " (T" << socketID << ") received END_RESP at address " << hex << trans.get_address() << endl;
882 #endif
883 
884  switch (phase) {
885  case BEGIN_REQ:
886 
887  // Increment the transaction reference count
888  trans.acquire();
889 
890  if(incoming_transaction_pending[socketID] != 0) {
891  send_error_response(socketID, trans);
892  return;
893  } else incoming_transaction_pending[socketID] = &trans;
894 
895  // Always notify the user algorithm thread
896  //update_user_algorithm_event.notify();
897 
898  // Consider both priority and non-priority channels equally
899  // Physical channel verification is done inside the method sensitive to the event launched
900  send_end_req_event[socketID].notify();
901 
902  update_target_packet(socketID, phase);
903  //set_target_phase_begin_resp_event[socketID].notify();
904  set_target_phase_idle(socketID);
905 
906  break;
907 
908  case END_RESP:
909 
910  update_target_packet(socketID, phase);
911  //set_target_phase_begin_resp_event[socketID].notify();
912  set_target_phase_idle(socketID);
913 
914  // On receiving END_RESP, the target can release the transaction
915  trans.release();
916  break;
917 
918  case END_REQ:
919  case BEGIN_RESP:
920  SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by target");
921  break;
922 
923  }
924 }
925 
926 template<int Ni, int No>
928  release_physical_channel(get_input_connection_name(channel_id));
929  shared_channel_ready_event.notify();
930 }
931 
932 template<int Ni, int No>
934 
935  if(!is_physical_channel_available(get_input_connection_name(id)) && !static_module) {
936  FOUT << sc_time_stamp() << ": " << name() << ": (T) request already in progress in shared channel, waiting for shared_channel_in_ready_event" << endl;
937  next_trigger(shared_channel_ready_event);
938  return;
939  }
940 
941  // Decrease number of available channels
942  acquire_physical_channel(get_input_connection_name(id));
943 
944  // Store transaction address and data into local memory
945  address_in[id] = incoming_transaction_pending[id]->get_address();
946  memcpy(data_in[id], incoming_transaction_pending[id]->get_data_ptr(), incoming_transaction_pending[id]->get_data_length());
947 #ifdef DEBUG
948  FOUT << sc_time_stamp() << ": " << name() << " (T" << id << ") Updating address and data for socket "
949  << id << ". New address: " << address_in[id] << endl;
950 #endif
951 
952  m_new_val_data_received[id] = true;
953  update_socket_data_received_buffer_event[id].notify(end_req_time[id]);
954 
955  send_end_req(id, *incoming_transaction_pending[id]);
956 
957  next_trigger();
958 }
959 
960 template<int Ni, int No>
961 tlm_sync_enum Module<Ni, No>::send_end_req(int id, tlm_generic_payload& trans) {
962 
963  tlm_sync_enum status;
964  tlm_phase bw_phase;
965  sc_time delay;
966 
967  // Queue the acceptance and the response with the appropriate latency
968  bw_phase = END_REQ;
969  delay = end_req_time[id];
970  status = target_socket[id]->nb_transport_bw(trans, bw_phase, delay);
971  if (status == TLM_COMPLETED) {
972  // Transaction aborted by the initiator
973  // (TLM_UPDATED cannot occur at this point in the base protocol, so need not be checked)
974  trans.release();
975  return status;
976  }
977 
978  release_physical_channels_event[id].notify(delay);
979 
980  //set_target_phase_end_req_event[id].notify(delay);
981  set_target_phase(id, bw_phase);
982  set_target_phase_idle_event[id].notify(delay);
983 
984  return status;
985 }
986 
987 template<int Ni, int No>
988 void Module<Ni, No>::send_response(int id, tlm_generic_payload& trans) {
989 
990  tlm_sync_enum status;
991  tlm_phase bw_phase;
992  sc_time delay;
993 
994  bw_phase = BEGIN_RESP;
995  delay = begin_resp_time[id];
996 
997  status = target_socket[id]->nb_transport_bw(trans, bw_phase, delay);
998 
999  if (status == TLM_UPDATED) {
1000  // The timing annotation must be honored
1001  m_id_targ_map[&trans] = id;
1002  m_peq_targ.notify(trans, bw_phase, delay);
1003  } else if (status == TLM_COMPLETED) {
1004  // The initiator has terminated the transaction
1005  trans.release();
1006  }
1007 
1008  //set_target_phase_begin_resp_event[id].notify(delay);
1009  set_target_phase(id, bw_phase);
1010 }
1011 
1012 template<int Ni, int No>
1013 void Module<Ni, No>::send_error_response(int id, tlm_generic_payload& trans) {
1014 
1015  tlm_sync_enum status;
1016  tlm_phase bw_phase;
1017  sc_time delay;
1018 
1019  bw_phase = BEGIN_RESP;
1020  delay = begin_resp_time[id];
1021 
1022  trans.set_response_status(TLM_COMMAND_ERROR_RESPONSE);
1023  status = target_socket[id]->nb_transport_bw(trans, bw_phase, delay);
1024 
1025  if (status == TLM_UPDATED) {
1026  // The timing annotation must be honored
1027  m_id_targ_map[&trans] = id;
1028  m_peq_targ.notify(trans, bw_phase, delay);
1029  } else if (status == TLM_COMPLETED) {
1030  // The initiator has terminated the transaction
1031  trans.release();
1032  }
1033 
1034  //set_target_phase_begin_resp_event[id].notify(delay);
1035  set_target_phase(id, bw_phase);
1036 }
1037 
1038 
1039 /***********************************
1040  ****** Configuration part ******
1041  ***********************************/
1042 template<int Ni, int No>
1043 void Module<Ni, No>::b_transport_conf(tlm_generic_payload& trans, sc_time& delay) {
1044 
1045  if(trans.get_address() == MANAGER_COMMAND_SCHEDULING) {
1046  /* Scheduling */
1047  int data = *(reinterpret_cast<int *>(trans.get_data_ptr()));
1048  User_algorithm_action action = (User_algorithm_action) (data & 0xffff);
1049  int module_ready = data >> 16;
1050 
1051  FOUT << sc_time_stamp() << ": " << name() << ": Module " << module_ready << " ready" << endl;
1052 
1053  // If next module ready, launch initiator
1054  if(action == NEXT_MODULE_READY) {
1055 
1056  for(int i = 0; i < (int) channels_required[module_ready].size(); i++) {
1057  FOUT << sc_time_stamp() << ": " << name() << ": Channel " << channels_required[module_ready].at(i) << " ready" << endl;
1058  start_initiator_channel_event[channels_required[module_ready].at(i)].notify();
1059  }
1060 
1061  channels_required[module_ready].clear();
1062 
1063  } else if(action == CURRENT_MODULE_READY) {
1064  // Preemption point ready to be returned
1065  continue_execution_event.notify();
1066  }
1067 
1068  // Wait, but delay should be 0
1069  //wait(delay);
1070  }
1071  else if(trans.get_address() == MANAGER_UPDATE_PARAMETER_COMMAND_SCHEDULING) {
1072  /* Parameters updated : RZ */
1073  Algorithm_Parameters* ap = (reinterpret_cast<Algorithm_Parameters *>(trans.get_data_ptr()));
1074 
1075  FOUT << sc_time_stamp() << ": " << name() << ": updated parameters of RZ : " << ap->getCurrentRZ().getName() << ", pt = " << ap->getCurrentRZ().getConfigFctPoint().toString() << endl;
1076 
1077  parameter_computation_data = ap;
1078  parameter_computation_event.notify();//tata
1079  }
1080 
1081  trans.set_response_status(TLM_OK_RESPONSE);
1082 }
1083 
1084 template<int Ni, int No>
1086  while(true) {
1087  wait(question_manager_task_end_computation_event);
1088  question_manager_b_transport(MANAGER_UPLINK_TASK_END_COMPUTATION, 0);
1089  }
1090 }
1091 
1092 template<int Ni, int No>
1094  while(true) {
1095  wait(question_manager_task_preemption_event);
1096  question_manager_b_transport(MANAGER_UPLINK_TASK_PREEMPTION, 0);
1097  }
1098 }
1099 
1100 template<int Ni, int No>
1101 void Module<Ni, No>::question_manager_b_transport(int address, int data) {
1102 
1103  switch(address) {
1104  case MANAGER_UPLINK_TASK_END_COMPUTATION: FOUT << sc_time_stamp() << ": " << name() << " sending a request to the manager using the uplink (end computation)" << endl; break;
1105  case MANAGER_UPLINK_TASK_PREEMPTION: FOUT << sc_time_stamp() << ": " << name() << " sending a request to the manager using the uplink (preemption point)" << endl; break;
1106  case MANAGER_UPLINK_TASK_CHECK_SOCKET: FOUT << sc_time_stamp() << ": " << name() << " sending a request to the manager using the uplink (check socket)" << endl; break;
1107  case MANAGER_UPLINK_ALGO_STATE_UPDATE: FOUT << sc_time_stamp() << ": " << name() << " sending a request to the manager using the uplink (algo update)" << endl; break;
1108  default: FOUT << sc_time_stamp() << ": " << name() << " cannot recognize address for manager b_transport (" << address << ")" << endl; break;
1109  }
1110 
1111  tlm_generic_payload* trans;
1112  sc_time delay(SC_ZERO_TIME);
1113  int local_data = data;
1114 
1115  // Grab a new transaction from the memory manager
1116  trans = m_mm.allocate();
1117  trans->acquire();
1118 
1119  // Set all attributes except byte_enable_length and extensions (unused)
1120  trans->set_command(TLM_READ_COMMAND);
1121  trans->set_address(address);
1122  trans->set_data_ptr(reinterpret_cast<unsigned char*>(&local_data));
1123  trans->set_data_length(4);
1124  trans->set_streaming_width(4); // = data_length to indicate no streaming
1125  trans->set_byte_enable_ptr(0); // 0 indicates unused
1126  trans->set_dmi_allowed(false); // Mandatory initial value
1127  trans->set_response_status(TLM_INCOMPLETE_RESPONSE); // Mandatory initial value
1128 
1129  manager_initiator_socket->b_transport(*trans, delay);
1130 
1131  if(trans->is_response_error()) SC_REPORT_ERROR("TLM-2", "Response error from manager b_transport");
1132 
1133  if(local_data == (int) NEXT_MODULE_READY) {
1134  if(address == MANAGER_UPLINK_TASK_CHECK_SOCKET) {
1135 
1136  for(int i = 0; i < (int) channels_required[data].size(); i++) {
1137  FOUT << sc_time_stamp() << ": " << name() << ": Channel " << channels_required[data].at(i) << " ready" << endl;
1138  start_initiator_channel_event[channels_required[data].at(i)].notify();
1139  }
1140 
1141  channels_required[data].clear();
1142 
1143  }
1144  } else if(local_data == (int) CURRENT_MODULE_READY) {
1145  // Task preempted, but ready to continue its execution
1146  continue_execution_event.notify();
1147  }
1148 
1149  trans->release();
1150 }
1151 
1152 /********
1153  * MISC *
1154  *******/
1155 template<int Ni, int No>
1156 void Module<Ni, No>::info(void) {
1157 
1158  FOUT << endl << "Module " << name();
1159  if(static_module) FOUT << " (static)";
1160  FOUT << ":"<< endl;
1161 
1162  for(int i = 0; i < No; i++) {
1163  FOUT << "Output socket " << i << " (Connection " << following_modules_connection_name.at(i) << "):" << endl;
1164  if(module_interfaces[following_modules_connection_name.at(i)].is_priority_channel()) FOUT << " Priority channel" << endl;
1165  FOUT << " Packet size: " << output_stream_packet_size[i] << endl;
1166  FOUT << " BEGIN_REQ time: " << begin_req_time[i] << endl;
1167  FOUT << " END_RESP time: " << end_resp_time[i] << endl;
1168  }
1169 
1170  for(int i = 0; i < Ni; i++) {
1171  FOUT << "Input socket " << i << " (Connection " << preceding_modules_connection_name.at(i) << "):" << endl;
1172  if(module_interfaces[preceding_modules_connection_name.at(i)].is_priority_channel()) FOUT << " Priority channel" << endl;
1173  FOUT << " Packet size: " << input_stream_packet_size[i] << endl;
1174  FOUT << " END_REQ time: " << end_req_time[i] << endl;
1175  FOUT << " BEGIN_RESP time: " << begin_resp_time[i] << endl;
1176  }
1177 
1178  FOUT << "Deadline time: " << deadline_time << endl;
1179  FOUT << "Following list: ";
1180  for(int i = 0; i < (int) following_modules_list.size(); i++) FOUT << dec << following_modules_list.at(i) << " ";
1181  FOUT << endl << "Preceding list: ";
1182  for(int i = 0; i < (int) preceding_modules_list.size(); i++) FOUT << dec << preceding_modules_list.at(i) << " ";
1183  FOUT << endl;
1184  FOUT << "Algorithm implementations:" << endl;
1185  for(int i = 0; i < (int) implementation_execution_times_vector.size(); i++) implementation_execution_times_vector.at(i).info((*fout));
1186 }
1187 
1188 template<int Ni, int No>
1190  application_offset = offset;
1191  for(int j = 0; j < (int) following_modules_list.size(); j++) {
1192  if(following_modules_list.at(j) != -1) following_modules_list[j] += offset;
1193  }
1194  for(int j = 0; j < (int) channel_connection_vector.size(); j++) {
1195  if(channel_connection_vector.at(j) != -1) channel_connection_vector[j] += offset;
1196  }
1197  for(int j = 0; j < (int) preceding_modules_list.size(); j++) {
1198  if(preceding_modules_list.at(j) != -1) preceding_modules_list[j] += offset;
1199  }
1200 }
1201 
1202 template<int Ni, int No>
1204  if(target_socket.size() != Ni || initiator_socket.size() != No || manager_target_socket.size() != 1 || manager_initiator_socket.size() != 1) {
1205  cerr << "ERROR: Incorrect bindings for module " << name() << "! Exiting..." << endl;
1206  exit(-1);
1207  }
1208 }
1209 
1210 template<int Ni, int No>
1212  trace_packet.trace_configuration_signals = true;
1213 }
1214 
1215 template<int Ni, int No>
1216 void Module<Ni, No>::activate_trace(void) {
1217  sc_trace(tf, trace_packet, (string) name());
1218 }
1219 
1220 template<int Ni, int No>
1221 void Module<Ni, No>::set_implementation_vector(vector<ModuleImplementation>& impl) {
1222  implementation_execution_times_vector = impl;
1223 }
1224 
1225 template<int Ni, int No>
1226 vector<ModuleImplementation>* Module<Ni, No>::get_implementation_vector_ptr(void) {
1227  return &implementation_execution_times_vector;
1228 }
1229 
1230 template<int Ni, int No>
1232  static_module = true;
1233  //cout << "Before addition" << endl;
1234  //set_current_implementation(implementation_execution_times_vector.at(0).get_name());
1235  //set_current_implementation("Hard1");
1236  //cout << "After addition" << endl;
1237 }
1238 
1239 
1240 /************************************
1241  * User_algorithm_interface methods *
1242  ************************************/
1243 template<int Ni, int No>
1244 const char* Module<Ni, No>::get_name() const {
1245  return name();
1246 }
1247 
1248 template<int Ni, int No>
1250  return data_in[socket];
1251 }
1252 
1253 template<int Ni, int No>
1255  // Retrieve socket ID
1256  int id = get_input_socket_id(name);
1257  if(id == -1) cerr << "ERROR: Unable to retrieve input socket ID from connection name" << endl;
1258 
1259  return data_in[id];
1260 }
1261 
1262 template<int Ni, int No>
1264  return data_out[socket];
1265 }
1266 
1267 template<int Ni, int No>
1269  // Retrieve socket ID
1270  int id = get_output_socket_id(name);
1271  if(id == -1) cerr << "ERROR: Unable to retrieve output socket ID from connection name" << endl;
1272 
1273  return data_out[id];
1274 }
1275 
1276 template<int Ni, int No>
1278  return input_stream_packet_size[id] * 4; // in bytes
1279 }
1280 
1281 template<int Ni, int No>
1282 int Module<Ni, No>::get_data_in_length(string name) const {
1283 
1284  // Retrieve socket ID
1285  int id = get_input_socket_id(name);
1286  if(id == -1) cerr << "ERROR: Unable to retrieve input socket ID from connection name" << endl;
1287 
1288  return input_stream_packet_size[id] * 4; // in bytes
1289 }
1290 
1291 template<int Ni, int No>
1293  return output_stream_packet_size[id] * 4; // in bytes
1294 }
1295 
1296 template<int Ni, int No>
1297 int Module<Ni, No>::get_data_out_length(string name) const {
1298 
1299  // Retrieve socket ID
1300  int id = get_output_socket_id(name);
1301  if(id == -1) cerr << "ERROR: Unable to retrieve output socket ID from connection name" << endl;
1302 
1303  return output_stream_packet_size[id] * 4; // in bytes
1304 }
1305 
1306 template<int Ni, int No>
1307 sc_dt::uint64 Module<Ni, No>::get_address_in(int socket) const {
1308  return address_in[socket];
1309 }
1310 
1311 template<int Ni, int No>
1312 sc_dt::uint64 Module<Ni, No>::get_address_in(string name) const {
1313  // Retrieve socket ID
1314  int id = get_input_socket_id(name);
1315  if(id == -1) cerr << "ERROR: Unable to retrieve input socket ID from connection name" << endl;
1316 
1317  return address_in[id];
1318 }
1319 
1320 template<int Ni, int No>
1321 void Module<Ni, No>::set_address_out(int socket, sc_dt::uint64 val) {
1322  address_out[socket] = val;
1323 }
1324 
1325 template<int Ni, int No>
1326 void Module<Ni, No>::set_address_out(string name, sc_dt::uint64 val) {
1327  // Retrieve socket ID
1328  int id = get_output_socket_id(name);
1329  if(id == -1) cerr << "ERROR: Unable to retrieve output socket ID from connection name" << endl;
1330 
1331  address_out[id] = val;
1332 }
1333 
1334 template<int Ni, int No>
1335 int Module<Ni, No>::get_input_socket_id(string connection_name) const {
1336  int socketID = -1;
1337  for(int i = 0; i < (int) preceding_modules_connection_name.size(); i++) {
1338  if(preceding_modules_connection_name.at(i).compare(connection_name) == 0) {
1339  socketID = i;
1340  break;
1341  }
1342  }
1343 
1344  return socketID;
1345 }
1346 
1347 template<int Ni, int No>
1348 int Module<Ni, No>::get_output_socket_id(string connection_name) const {
1349  int socketID = -1;
1350  for(int i = 0; i < (int) following_modules_connection_name.size(); i++) {
1351  if(following_modules_connection_name.at(i).compare(connection_name) == 0) {
1352  socketID = i;
1353  break;
1354  }
1355  }
1356 
1357  return socketID;
1358 }
1359 
1360 template<int Ni, int No>
1361 sc_time Module<Ni, No>::get_WCET(void) const {
1362  return implementation_execution_times_vector.at(current_implementation_id).get_worst_case_execution_time();
1363 }
1364 
1365 template<int Ni, int No>
1366 sc_time Module<Ni, No>::get_BCET(void) const {
1367  return implementation_execution_times_vector.at(current_implementation_id).get_best_case_execution_time();;
1368 }
1369 
1370 template<int Ni, int No>
1372 
1373  FOUT << sc_time_stamp() << ": Module " << name() << ": User process finished" << endl;
1374 
1375  // Question the manager about scheduling
1376  question_manager_task_end_computation_event.notify();
1377 
1378  transactions_processed++;
1379 
1380  // Sending response to all preceding modules
1381  //for(int i = 0; i < Ni; i++) {
1382 
1383  // // Checking for transient connections
1384  // bool transient = (module_interfaces[preceding_modules_connection_name.at(i)].is_transient());
1385  // if(!(first_transaction && transient)) {
1386  // incoming_transaction[i] = incoming_transaction_pending[i];
1387  // incoming_transaction_pending[i] = 0;
1388  // incoming_transaction[i]->set_response_status(TLM_OK_RESPONSE);
1389  // send_response(i, *incoming_transaction[i]);
1390  // } else FOUT << sc_time_stamp() << ": " << name() << ": Socket " << i << " (" << preceding_modules_connection_name.at(i) << ") is transient! Do not notify module" << endl;
1391  //}
1392 
1393  first_transaction = false;
1394 
1395  // After algorithm execution, reset boolean value to false
1396  kill_user_algorithm_thread = false;
1397 
1398  /*for(int i = 0; i < Ni; i++) {
1399  m_new_val_data_received[i] = false;
1400  update_socket_data_received_buffer_event[i].notify();
1401  }*/
1402 
1403  algorithm_ended = true;
1404 
1405  nb_algorithm_executions++;
1406 
1407  algorithm_execution_requested = false;
1408 
1409 }
1410 
1411 template<int Ni, int No>
1413 
1414  if(!static_module) {
1415 
1416  question_manager_task_preemption_event.notify();
1417 
1418  // Wait for the manager to restart task
1419  wait(continue_execution_event);
1420  }
1421 }
1422 
1423 template<int Ni, int No>
1424 void Module<Ni, No>::compute(sc_time duration) {
1425 
1426  if(!static_module) {
1427 
1428  float coeff = 1.0;
1429  sc_time ref_time = sc_time_stamp();
1430  sc_time current_duration = duration*coeff;
1431 
1432  while (current_duration > sc_time(0, SC_NS)) {
1433  wait (current_duration, parameter_computation_event);
1434  if (parameter_computation_data != NULL) {
1435 
1436  Config_fct_point fctPt = parameter_computation_data->getCurrentRZ().getConfigFctPoint();
1437  Config_fct_point nominalFctPt = parameter_computation_data->getRZConfig().getConfigDomain()->getNominalFctPoint();
1438 
1439  if (nominalFctPt.getFrequency() != 0.0 && nominalFctPt.getFrequency() != 0.0) {
1440 
1441  coeff = nominalFctPt.getFrequency() / fctPt.getFrequency();
1442  }
1443  else {
1444 
1445  coeff = 1.0F;
1446  FOUT << sc_time_stamp() << "Warning: Frequency of " << parameter_computation_data->getCurrentRZ().getName() << " is 0 MHz." << endl;
1447  }
1448 
1449  // Stop Event sended by scheduler
1450  sc_time remaining_time = duration - (sc_time_stamp() - ref_time);
1451 
1452  // If preemption (but here, just compute again exe time)
1453  // Send Premption Order to scheduler (Task sets to PREEMPTED State) and scheduler recalls
1454  //question_manager_task_preemption_event.notify();
1455  // Resume Event sended by scheduler
1456  //wait(continue_execution_event);
1457 
1458  current_duration = remaining_time * coeff;
1459 
1460  FOUT << sc_time_stamp() << " ****** duration : " << duration << endl;
1461  FOUT << sc_time_stamp() << " sc_time_stamp : " << sc_time_stamp() << endl;
1462  FOUT << sc_time_stamp() << " ref_time : " << ref_time << endl;
1463  FOUT << sc_time_stamp() << " sc_time_stamp - ref_time : " << (sc_time_stamp() - ref_time) << endl;
1464  FOUT << sc_time_stamp() << " COEFF : " << coeff << ", remaining time : " << remaining_time << ", current_duration : " << current_duration <<endl;
1465 
1466  ref_time = sc_time_stamp();
1467 
1468 
1469  // Set NULL (commsuming ok)
1470  parameter_computation_data = NULL;
1471  }
1472  else {
1473  // Exit
1474  current_duration = sc_time(0, SC_NS);
1475  }
1476  }
1477 
1478  }
1479 }
1480 
1481 template<int Ni, int No>
1482 const sc_event& Module<Ni, No>::update_user_algorithm(void) const {
1483  return update_user_algorithm_event;
1484 }
1485 
1486 template<int Ni, int No>
1488  // Makes no sense when considering a static module (or several accelerators implemented...)
1489  if(!static_module) wait(update_user_algorithm());
1490 }
1491 
1492 template<int Ni, int No>
1494  return kill_user_algorithm_thread;
1495 }
1496 
1497 // DATA RECEIVE
1498 template<int Ni, int No>
1499 void Module<Ni, No>::b_data_received(string connection_name) {
1500 
1501  // Retrieve socket ID
1502  int socketID = get_input_socket_id(connection_name);
1503  if(socketID == -1) cerr << "ERROR: Unable to retrieve input socket ID from connection name" << endl;
1504 
1505  b_data_received(socketID);
1506 
1507 }
1508 
1509 template<int Ni, int No>
1511 
1512  string connection_name(preceding_modules_connection_name.at(socketID));
1513 
1514  if(module_interfaces[connection_name].is_transient() && first_transaction) {
1515  FOUT << sc_time_stamp() << ": " << name() << ": Socket " << socketID << " (" << preceding_modules_connection_name.at(socketID) << ") is transient!" << endl;
1516  } else if(socket_data_received[socketID].read()) {
1517  FOUT << sc_time_stamp() << ": " << name() << ": Socket " << socketID << " (" << preceding_modules_connection_name.at(socketID) << ") is ready!" << endl;
1518  } else {
1519  FOUT << sc_time_stamp() << ": " << name() << ": Socket " << socketID << " (" << preceding_modules_connection_name.at(socketID) << ") is not ready yet..." << endl;
1520  while(!socket_data_received[socketID].read()) wait(socket_data_received[socketID].value_changed_event());
1521  FOUT << sc_time_stamp() << ": " << name() << ": Socket " << socketID << " (" << preceding_modules_connection_name.at(socketID) << ") is now ready!" << endl;
1522  }
1523 
1524 }
1525 
1526 template<int Ni, int No>
1528  for(int i = 0; i < (int) preceding_modules_connection_name.size(); i++) {
1529  b_data_received(preceding_modules_connection_name.at(i));
1530  }
1531 }
1532 
1533 template<int Ni, int No>
1534 bool Module<Ni, No>::nb_data_received(string connection_name) {
1535 
1536  // Retrieve socket ID
1537  int socketID = get_input_socket_id(connection_name);
1538  if(socketID == -1) cerr << "ERROR: Unable to retrieve input socket ID from connection name" << endl;
1539 
1540  return (nb_data_received(socketID));
1541 }
1542 
1543 template<int Ni, int No>
1545 
1546  return (socket_data_received[socketID].read());
1547 }
1548 
1549 template<int Ni, int No>
1551  for(int i = 0; i < (int) preceding_modules_connection_name.size(); i++) {
1552  if(!nb_data_received(preceding_modules_connection_name.at(i))) return false;
1553  }
1554 
1555  return true;
1556 }
1557 
1558 // DATA SEND
1559 template<int Ni, int No>
1560 void Module<Ni, No>::nb_send_data(string connection_name) {
1561 
1562  // Retrieve socket ID
1563  int socketID = get_output_socket_id(connection_name);
1564  if(socketID == -1) cerr << "ERROR: Unable to retrieve output socket ID from connection name" << endl;
1565  FOUT << "Socket ID: " << socketID << endl;
1566 
1567  nb_send_data(socketID);
1568 }
1569 
1570 template<int Ni, int No>
1571 void Module<Ni, No>::nb_send_data(int socketID) {
1572 
1574  //m_new_val_data_sent[socketID] = false;
1575  //update_socket_data_sent_buffer_event[socketID].notify();
1576 
1577  first_data_send_on_socket[socketID] = false;
1578 
1579  // Retrieve module ID
1580  int module_id = channel_connection_vector.at(socketID);
1581  FOUT << "Module ID: " << module_id << endl;
1582 
1583  bool first_module_request = (channels_required[module_id].empty());
1584  channels_required[module_id].push_back(socketID);
1585 
1586  nb_packets_remaining++;
1587 
1588  if(first_module_request) question_manager_b_transport(MANAGER_UPLINK_TASK_CHECK_SOCKET, module_id);
1589 
1590  set_com_status_waiting(socketID);
1591 }
1592 
1593 template<int Ni, int No>
1595  for(int i = 0; i < (int) following_modules_connection_name.size(); i++) {
1596  nb_send_data(following_modules_connection_name.at(i));
1597  }
1598 }
1599 
1600 template<int Ni, int No>
1601 void Module<Ni, No>::b_send_data(string connection_name) {
1602 
1603  // Retrieve socket ID
1604  int socketID = get_output_socket_id(connection_name);
1605  if(socketID == -1) cerr << "ERROR: Unable to retrieve output socket ID from connection name" << endl;
1606  FOUT << "Socket ID: " << socketID << endl;
1607 
1608  b_send_data(socketID);
1609 }
1610 
1611 template<int Ni, int No>
1612 void Module<Ni, No>::b_send_data(int socketID) {
1613 
1614  nb_send_data(socketID);
1615 
1616  FOUT << sc_time_stamp() << ": " << name() << ": Socket " << socketID << " (" << following_modules_connection_name.at(socketID) << ") is not ready yet..." << endl;
1617  while(!socket_data_sent[socketID].read()) wait(socket_data_sent[socketID].value_changed_event());
1618  FOUT << sc_time_stamp() << ": " << name() << ": Socket " << socketID << " (" << following_modules_connection_name.at(socketID) << ") is now ready!" << endl;
1619 }
1620 
1621 template<int Ni, int No>
1623 
1624  for(int i = 0; i < (int) following_modules_connection_name.size(); i++) {
1625  b_send_data(following_modules_connection_name.at(i));
1626  }
1627 }
1628 
1629 template<int Ni, int No>
1630 void Module<Ni, No>::b_data_sent(int socketID) {
1631  if(!first_data_send_on_socket[socketID]) {
1632  while(!socket_data_sent[socketID].read()) wait(socket_data_sent[socketID].value_changed_event());
1633  }
1634 }
1635 
1636 template<int Ni, int No>
1637 bool Module<Ni, No>::nb_data_sent(int socketID) {
1638  return (first_data_send_on_socket[socketID] || socket_data_sent[socketID].read());
1639 }
1640 
1641 template<int Ni, int No>
1642 void Module<Ni, No>::b_data_sent(string connection_name) {
1643 
1644  // Retrieve socket ID
1645  int socketID = get_output_socket_id(connection_name);
1646  if(socketID == -1) cerr << "ERROR: Unable to retrieve output socket ID from connection name" << endl;
1647  FOUT << "Socket ID: " << socketID << endl;
1648 
1649  b_data_sent(socketID);
1650 }
1651 
1652 template<int Ni, int No>
1653 bool Module<Ni, No>::nb_data_sent(string connection_name) {
1654 
1655  // Retrieve socket ID
1656  int socketID = get_output_socket_id(connection_name);
1657  if(socketID == -1) cerr << "ERROR: Unable to retrieve output socket ID from connection name" << endl;
1658  FOUT << "Socket ID: " << socketID << endl;
1659 
1660  return nb_data_sent(socketID);
1661 }
1662 
1663 template<int Ni, int No>
1665  for(int i = 0; i < No; i++) b_data_sent(i);
1666 }
1667 
1668 template<int Ni, int No>
1670  for(int i = 0; i < No; i++) {
1671  if(!nb_data_sent(i)) return false;
1672  }
1673 
1674  return true;
1675 }
1676 
1677 template<int Ni, int No>
1679  for(int i = 0; i < No; i++) start_new_transaction_sequence(i);
1680 }
1681 
1682 template<int Ni, int No>
1684  // Reset buffer value
1685  m_new_val_data_sent[socketID] = false;
1686  update_socket_data_sent_buffer_event[socketID].notify();
1687 }
1688 
1689 template<int Ni, int No>
1691  // Retrieve socket ID
1692  int socketID = get_output_socket_id(connection_name);
1693  if(socketID == -1) cerr << "ERROR: Unable to retrieve output socket ID from connection name" << endl;
1694  FOUT << "Socket ID: " << socketID << endl;
1695 
1696  start_new_transaction_sequence(socketID);
1697 }
1698 
1699 
1700 
1701 template<int Ni, int No>
1702 bool Module<Ni, No>::is_channel_transient(string connection_name) {
1703  return (module_interfaces[connection_name].is_transient());
1704 }
1705 
1706 template<int Ni, int No>
1708  return (module_interfaces[preceding_modules_connection_name.at(socketID)].is_transient());
1709 }
1710 
1711 template<int Ni, int No>
1713  return (implementation_execution_times_vector.at(current_implementation_id).get_nb_preemption_points());
1714 }
1715 
1716 template<int Ni, int No>
1718  question_manager_b_transport(MANAGER_UPLINK_ALGO_STATE_UPDATE, (int) RUNNING);
1719 }
1720 
1721 template<int Ni, int No>
1723  question_manager_b_transport(MANAGER_UPLINK_ALGO_STATE_UPDATE, (int) IDLE);
1724 }
1725 
1726 template<int Ni, int No>
1728  question_manager_b_transport(MANAGER_UPLINK_ALGO_STATE_UPDATE, (int) WAITING);
1729 }
1730 
1731 template<int Ni, int No>
1733  if(nb_algorithm_executions == 0) {
1734  if(task_offset != SC_ZERO_TIME) {
1735  sc_time time_to_offset = task_offset - sc_time_stamp();
1736  FOUT << sc_time_stamp() << ": " << name() << ": Time to wait before offset is verified: " << time_to_offset << endl;
1737  if(time_to_offset > SC_ZERO_TIME) wait(time_to_offset);
1738  last_absolute_deadline_time = absolute_deadline_time;
1739  }
1740  } else {
1741  if(task_period != SC_ZERO_TIME) {
1742  sc_time time_to_period = nb_algorithm_executions * task_period - sc_time_stamp();
1743  FOUT << sc_time_stamp() << ": " << name() << ": Time to wait before beginning of next period: " << time_to_period << endl;
1744  if(time_to_period > SC_ZERO_TIME) wait(time_to_period);
1745  last_absolute_deadline_time = absolute_deadline_time;
1746  }
1747  }
1748 }
1749 
1750 template<int Ni, int No>
1752  return (*fout);
1753 }
1754 
1755 template<int Ni, int No>
1757  return algorithm_execution_mode;
1758 }
1759 
1760 template<int Ni, int No>
1762  return (algorithm_execution_mode.compare(mode) == 0);
1763 }
1764 
1765 template<int Ni, int No>
1767 
1768  // Checking for transient connections
1769  bool transient = (module_interfaces[preceding_modules_connection_name.at(socketID)].is_transient());
1770  if(!(first_transaction && transient)) {
1771  incoming_transaction[socketID] = incoming_transaction_pending[socketID];
1772  incoming_transaction_pending[socketID] = 0;
1773  incoming_transaction[socketID]->set_response_status(TLM_OK_RESPONSE);
1774  send_response(socketID, *incoming_transaction[socketID]);
1775  } else FOUT << sc_time_stamp() << ": " << name() << ": Socket " << socketID << " (" << preceding_modules_connection_name.at(socketID) << ") is transient! Do not notify module" << endl;
1776 
1777  m_new_val_data_received[socketID] = false;
1778  update_socket_data_received_buffer_event[socketID].notify();
1779 }
1780 
1781 template<int Ni, int No>
1782 void Module<Ni, No>::release_input_socket(string connectionName) {
1783 
1784  int socketID = get_input_socket_id(connectionName);
1785  if(socketID == -1) {
1786  cerr << name() << ": Unable to retrieve socket ID from connection name (" << connectionName << "). Exiting" << endl;
1787  exit(RECOSIM_INTERNAL_ERROR_ERRCODE);
1788  }
1789 
1790  release_input_socket(socketID);
1791 }
1792 
1793 template<int Ni, int No>
1795  for(int i = 0; i < Ni; i++) release_input_socket(i);
1796 }
1797 
1798 template<int Ni, int No>
1800  if(!static_module) {
1801  if(!algorithm_execution_requested) wait(start_algorithm_event);
1802  }
1803 }
1804 
1805 
1806 /************************************
1807  * Reconf_thread_interface methods *
1808  ************************************/
1809 template<int Ni, int No>
1810 const sc_event& Module<Ni, No>::configuration_updated() const {
1811  return configuration_updated_event;
1812 }
1813 
1814 template<int Ni, int No>
1816  configuration_done_event.notify();
1817 }
1818 
1819 template<int Ni, int No>
1821  return current_implementation_id;
1822 }
1823 
1824 template<int Ni, int No>
1825 vector<ModuleImplementation> Module<Ni, No>::get_implementation_vector(void) {
1826  return implementation_execution_times_vector;
1827 }
1828 
1829 
1830 /************************************
1831  * Manager_interface methods *
1832  ************************************/
1833 
1834 template<int Ni, int No>
1836  return (getName().compare(impl.getTaskName()) == 0);
1837 }
1838 
1839 template<int Ni, int No>
1840 void Module<Ni, No>::set_current_implementation(string implementationName) {
1841 
1842  int old_id = current_implementation_id;
1843 
1844  current_implementation_id = -1;
1845  for(int i = 0; i < (int) implementation_execution_times_vector.size(); i++) {
1846  if(implementation_execution_times_vector.at(i).get_name().compare(implementationName) == 0) {
1847  /*if(worst_case) computation_time = implementation_execution_times_vector.at(i).get_worst_case_execution_time();
1848  else computation_time = implementation_execution_times_vector.at(i).get_best_case_execution_time();*/
1849  current_implementation_id = i;
1850  FOUT << sc_time_stamp() << ": Module " << name() << ": Changing current implementation to " << implementationName << " (" << current_implementation_id << ")" << endl;
1851  break;
1852  }
1853  }
1854 
1855  if(current_implementation_id == -1) cerr << "ERROR: Implementation not found!" << endl;
1856 
1857  // Notify the reconfiguration control thread only if a new thread should be created
1858  if(current_implementation_id != old_id) {
1859  FOUT << sc_time_stamp() << ": " << name() << "Sending request to change conf" << endl;
1860  kill_user_algorithm_thread = true;
1861  configuration_updated_event.notify();
1862  } else {
1863  kill_user_algorithm_thread = false;
1864  }
1865 
1866  // Update physical channel map with algorithm data
1867  physical_channels_map.clear();
1868  map<string, int> channels(implementation_execution_times_vector.at(current_implementation_id).get_physical_channel_map());
1869 
1870  // Consider each channel type defined for the module. If not available in the implementation, use module values
1871  for(map<string, ModuleInterface>::iterator moduleInterface_it = module_interfaces.begin(); moduleInterface_it != module_interfaces.end(); moduleInterface_it++) {
1872 
1873  // First, check if the interface has been defined for the implementation
1874  bool interface_defined = false;
1875  for(map<string, int>::const_iterator it = channels.begin(); it != channels.end(); it++) {
1876 
1877  if(it->first.compare(moduleInterface_it->second.get_type()) == 0) {
1878  FOUT << "Updating channel resources for interface " << it->first << " with value " << it->second << endl;
1879  physical_channels_map.insert(pair<string, int>(it->first, it->second));
1880  interface_defined = true;
1881  break;
1882  }
1883  }
1884 
1885  if(!interface_defined) {
1886 
1887  FOUT << "Updating channel resources for interface " << moduleInterface_it->second.get_type() << " with module value" << endl;
1888 
1889  if(physical_channels_map.find(moduleInterface_it->first) != physical_channels_map.end()) {
1890  if(moduleInterface_it->second.is_priority_channel()) physical_channels_map[moduleInterface_it->second.get_type()]++;
1891  } else {
1892  if(moduleInterface_it->second.is_priority_channel()) physical_channels_map.insert(pair<string, int>(moduleInterface_it->second.get_type(), 2));
1893  else physical_channels_map.insert(pair<string, int>(moduleInterface_it->second.get_type(), 1));
1894  }
1895  }
1896  }
1897 
1898  display_physical_channels_map();
1899 
1900  remove_priority_channels_from_physical_channel_map();
1901 
1902  display_physical_channels_map();
1903 }
1904 
1905 template<int Ni, int No>
1907 
1908  FOUT << "Removing priority channels from map" << endl;
1909  for(map<string, int>::iterator it = physical_channels_map.begin(); it != physical_channels_map.end(); it++) {
1910  if(are_priority_channels_respected(it->first)) {
1911  // Count the number of priority channels and remove it from map
1912  int nbPriorityChannels = 0;
1913  for(map<string, ModuleInterface>::iterator modIT = module_interfaces.begin(); modIT != module_interfaces.end(); modIT++) {
1914  if(modIT->second.get_type().compare(it->first) == 0 && modIT->second.is_priority_channel()) nbPriorityChannels++;
1915  }
1916 
1917  physical_channels_map[it->first] -= nbPriorityChannels;
1918  }
1919  }
1920 }
1921 
1922 template<int Ni, int No>
1923 bool Module<Ni, No>::are_priority_channels_respected(string interface_type) {
1924 
1925  // Check if priority channels apply here (i.e. nbIF > nb priority channels + 1)
1926  int nbIF = implementation_execution_times_vector.at(current_implementation_id).get_physical_channel_map()[interface_type];
1927  FOUT << "Number of " << interface_type << " interfaces provided by the implementation: " << nbIF << endl;
1928 
1929  int nbPriorityChannels = 0;
1930  for(map<string, ModuleInterface>::iterator it = module_interfaces.begin(); it != module_interfaces.end(); it++) {
1931  if(it->second.get_type().compare(interface_type) == 0 && it->second.is_priority_channel()) nbPriorityChannels++;
1932  }
1933  FOUT << "Number of " << interface_type << " priority channels: " << nbPriorityChannels << endl;
1934 
1935  if(nbPriorityChannels == module_interfaces.size()) return (nbIF >= nbPriorityChannels);
1936  else return (nbIF > nbPriorityChannels);
1937 }
1938 
1939 template<int Ni, int No>
1940 vector<ModuleImplementation> Module<Ni, No>::get_implementation_vector(void) const {
1941  return implementation_execution_times_vector;
1942 }
1943 
1944 template<int Ni, int No>
1946  return absolute_deadline_time;
1947 }
1948 
1949 template<int Ni, int No>
1951  return deadline_time;
1952 }
1953 
1954 template<int Ni, int No>
1956  if(task_period == SC_ZERO_TIME) absolute_deadline_time = task_offset + sc_time_stamp() + deadline_time;
1957  else absolute_deadline_time = task_offset + nb_algorithm_executions * task_period + deadline_time;
1958 }
1959 
1960 template<int Ni, int No>
1962 
1963  // Check if the task is in the RZ list of compatibility
1964  vector<TaskImplementation> taskVector = rz->getTaskImplementationVector();
1965 
1966  for(int i = 0; i < (int) taskVector.size(); i++) {
1967  if(taskVector.at(i).getTaskName().compare(name()) == 0) return true;
1968  }
1969 
1970  return false;
1971 }
1972 
1973 template<int Ni, int No>
1974 string Module<Ni, No>::getName(void) const {
1975  return name();
1976 }
1977 
1978 template<int Ni, int No>
1980  return transactions_processed;
1981 }
1982 
1983 template<int Ni, int No>
1984 vector<int> Module<Ni, No>::getFollowingList(void) const {
1985  return following_modules_list;
1986 }
1987 
1988 template<int Ni, int No>
1989 vector<int> Module<Ni, No>::getPrecedingList(void) const {
1990  return preceding_modules_list;
1991 }
1992 
1993 template<int Ni, int No>
1994 bool Module<Ni, No>::is_static(void) const {
1995  return static_module;
1996 }
1997 
1998 template<int Ni, int No>
2000  return priority;
2001 }
2002 
2003 template<int Ni, int No>
2004 sc_time Module<Ni, No>::get_task_period(void) const {
2005  return task_period;
2006 }
2007 
2008 template<int Ni, int No>
2009 sc_time Module<Ni, No>::get_task_offset(void) const {
2010  return task_offset;
2011 }
2012 
2013 template<int Ni, int No>
2015  return (name() + (string)"." + implementation_execution_times_vector.at(current_implementation_id).get_name());
2016 }
2017 
2018 template<int Ni, int No>
2020  return current_implementation_id != -1;
2021 }
2022 
2023 template<int Ni, int No>
2025  return implementation_execution_times_vector.at(current_implementation_id);
2026 }
2027 
2028 template<int Ni, int No>
2030  algorithm_execution_mode = command;
2031  trace_update_algorithm_execution_mode();
2032 }
2033 
2034 template<int Ni, int No>
2035 bool Module<Ni, No>::use_context_switch_mode(string implementationName) {
2036  // Look through module implementation vector to find the good one
2037  for(int i = 0; i < (int) implementation_execution_times_vector.size(); i++) {
2038  if(implementation_execution_times_vector.at(i).get_name().compare(implementationName) == 0) return implementation_execution_times_vector.at(i).use_context_switch_mode();
2039  }
2040 
2041  cerr << name() << ": Unable to retrieve implementation by its name... Implementation name: " << implementationName << ". Exiting" << endl;
2042  exit(RECOSIM_INTERNAL_ERROR_ERRCODE);
2043 }
2044 
2045 template<int Ni, int No>
2047 
2048  // Always notify the user algorithm thread
2049  update_user_algorithm_event.notify();
2050 
2051  FOUT << sc_time_stamp() << ": " << name() << " send start algorithm request" << endl;
2052  algorithm_execution_requested = true;
2053  start_algorithm_event.notify(SC_ZERO_TIME);
2054 }
2055 
2056 template<int Ni, int No>
2058  sc_time new_period_start_time;
2059  if(nb_algorithm_executions == 0) new_period_start_time = (task_offset > sc_time_stamp()) ? task_offset : SC_ZERO_TIME;
2060  else new_period_start_time = ((nb_algorithm_executions * task_period) > sc_time_stamp()) ? nb_algorithm_executions * task_period : SC_ZERO_TIME;
2061 
2062  return new_period_start_time;
2063 }
2064 
2065 template<int Ni, int No>
2067  int nb_transient = 0;
2068  for(int i = 0; i < Ni; i++) {
2069  if(is_channel_transient(i)) nb_transient++;
2070  }
2071 
2072  return nb_transient;
2073 }
2074 
2075 template<int Ni, int No>
2077  priority = p;
2078 }
2079 
2080 
2081 
2082 
2083 
2084 
2085 // Data stream configuration
2086 template<int Ni, int No>
2087 void Module<Ni, No>::set_packet_size(string connection_name, int size) {
2088 
2089  // First, find if target module is a following or a preceding module
2090  bool preceding_mod = false;
2091  int socketID = -1;
2092  for(int i = 0; i < (int) preceding_modules_connection_name.size(); i++) {
2093  if(preceding_modules_connection_name.at(i).compare(connection_name) == 0) {
2094  preceding_mod = true;
2095  socketID = i;
2096  break;
2097  }
2098  }
2099 
2100  if(!preceding_mod) {
2101  for(int i = 0; i < (int) following_modules_connection_name.size(); i++) {
2102  if(following_modules_connection_name.at(i).compare(connection_name) == 0) {
2103  socketID = i;
2104  break;
2105  }
2106  }
2107  }
2108 
2109 #ifdef CONSOLE_DEBUG
2110  if(preceding_mod) cout << "Preceding module" << endl;
2111  else cout << "Following module" << endl;
2112  cout << "Socket ID: " << socketID << endl;
2113 #endif
2114 
2115  try {
2116  if(preceding_mod) {
2117  assert(socketID < Ni);
2118  input_stream_packet_size[socketID] = size;
2119  delete[] data_in[socketID];
2120  data_in[socketID] = 0;
2121  data_in[socketID] = new int[input_stream_packet_size[socketID]];
2122  for(int i = 0; i < input_stream_packet_size[socketID]; i++) data_in[socketID][i] = 0;
2123  } else {
2124  assert(socketID < No);
2125  output_stream_packet_size[socketID] = size;
2126  delete[] data_out[socketID];
2127  data_out[socketID] = 0;
2128  data_out[socketID] = new int[output_stream_packet_size[socketID]];
2129  for(int i = 0; i < output_stream_packet_size[socketID]; i++) data_out[socketID][i] = 0;
2130  }
2131  } catch (bad_alloc& ba) {
2132  cerr << "ERROR: " << name() << " bad_alloc caught: " << ba.what() << endl;
2133  //exit(-1);
2134  Simulation_controller::endSimulation();
2135  }
2136 
2137 }
2138 
2139 // Timing
2140 template<int Ni, int No>
2141 void Module<Ni, No>::set_deadline_time(sc_time t) {
2142  deadline_time = t;
2143 }
2144 
2145 template<int Ni, int No>
2146 void Module<Ni, No>::set_begin_req_time(string connection_name, sc_time t) {
2147  add_timing_info(BEGIN_REQ, connection_name, t);
2148 }
2149 
2150 template<int Ni, int No>
2151 void Module<Ni, No>::set_end_req_time(string connection_name, sc_time t) {
2152  add_timing_info(END_REQ, connection_name, t);
2153 }
2154 
2155 template<int Ni, int No>
2156 void Module<Ni, No>::set_begin_resp_time(string connection_name, sc_time t) {
2157  add_timing_info(BEGIN_RESP, connection_name, t);
2158 }
2159 
2160 template<int Ni, int No>
2161 void Module<Ni, No>::set_end_resp_time(string connection_name, sc_time t) {
2162  add_timing_info(END_RESP, connection_name, t);
2163 }
2164 
2165 template<int Ni, int No>
2166 void Module<Ni, No>::add_timing_info(tlm_phase_enum phase, string connection_name, sc_time time) {
2167 
2168  // First, find if target module is a following or a preceding module
2169  bool preceding_mod = false;
2170  int socketID = -1;
2171  for(int i = 0; i < (int) preceding_modules_connection_name.size(); i++) {
2172  if(preceding_modules_connection_name.at(i).compare(connection_name) == 0) {
2173  preceding_mod = true;
2174  socketID = i;
2175  break;
2176  }
2177  }
2178 
2179  if(!preceding_mod) {
2180  for(int i = 0; i < (int) following_modules_connection_name.size(); i++) {
2181  if(following_modules_connection_name.at(i).compare(connection_name) == 0) {
2182  socketID = i;
2183  break;
2184  }
2185  }
2186  }
2187 
2188 #ifdef CONSOLE_DEBUG
2189  if(preceding_mod) cout << "Preceding module" << endl;
2190  else cout << "Following module" << endl;
2191  cout << "Socket ID: " << socketID << endl;
2192 #endif
2193 
2194 
2195  switch(phase) {
2196  case BEGIN_REQ: begin_req_time[socketID] = time; break;
2197  case END_REQ: end_req_time[socketID] = time; break;
2198  case BEGIN_RESP: begin_resp_time[socketID] = time; break;
2199  case END_RESP: end_resp_time[socketID] = time; break;
2200  default: cerr << "ERROR: Phase not recognized!" << endl;
2201  }
2202 }
2203 
2204 // Next/Previous modules
2205 template<int Ni, int No>
2206 void Module<Ni, No>::set_preceding_modules_list(vector<int> &v) {
2207  preceding_modules_list = v;
2208 }
2209 
2210 template<int Ni, int No>
2211 void Module<Ni, No>::set_following_modules_list(vector<int> &v) {
2212 
2213  channel_connection_vector = v;
2214  following_modules_list.clear();
2215 
2216  // Check for redundancies for following modules list
2217  for(int i = 0; i < (int) channel_connection_vector.size(); i++) {
2218  bool item_found = false;
2219  for(int j = 0; j < (int) following_modules_list.size(); j++) {
2220  if(following_modules_list.at(j) == channel_connection_vector.at(i)) item_found = true;
2221  }
2222  if(!item_found) following_modules_list.push_back(channel_connection_vector.at(i));
2223  }
2224 }
2225 
2226 template<int Ni, int No>
2228  following_modules_connection_name.push_back(name);
2229 }
2230 
2231 template<int Ni, int No>
2233  preceding_modules_connection_name.push_back(name);
2234 }
2235 
2236 template<int Ni, int No>
2237 void Module<Ni, No>::set_priority(int v) {
2238  priority = v;
2239 }
2240 
2241 template<int Ni, int No>
2243  module_interfaces.insert(pair<string, ModuleInterface>(mod_if.get_name(), mod_if));
2244 }
2245 
2246 template<int Ni, int No>
2247 void Module<Ni, No>::set_task_period(sc_time p) {
2248  task_period = p;
2249 }
2250 
2251 template<int Ni, int No>
2252 void Module<Ni, No>::set_task_offset(sc_time o) {
2253  task_offset = o;
2254 }
2255 
2256 /**********************************
2257  * Packet trace methods *
2258  **********************************/
2259 template<int Ni, int No>
2260 void Module<Ni, No>::init_packet(void) {
2261  trace_packet.algorithm_execution_mode = Utils::string_to_ascii(algorithm_execution_mode);
2262  for(int i = 0; i < Ni; i++) update_target_packet(i, 0);
2263  for(int i = 0; i < No; i++) {
2264  update_initiator_packet(i, 0, 0);
2265  trace_packet.communication_status[i] = IDLE_ASCII;
2266  }
2267 }
2268 
2269 template<int Ni, int No>
2271  for(int i = 0; i < Ni; i++) {
2272  trace_packet.address_in[i] = (int) address_in[i];
2273  trace_packet.data_in[i] = data_in[i][0];
2274  }
2275 
2276  for(int i = 0; i < No; i++) {
2277  trace_packet.address_out[i] = (int) address_out[i];
2278  trace_packet.data_out[i] = data_out[i][0];
2279  }
2280 }
2281 
2282 template<int Ni, int No>
2283 void Module<Ni, No>::update_initiator_packet(int id, tlm_generic_payload* trans, tlm_phase phase) {
2284  assert(id < No);
2285  trace_packet.initiator_packet[id].phase = tlm_phase_to_ascii(phase);
2286  update_initiator_packet(id, trans);
2287 }
2288 
2289 template<int Ni, int No>
2290 void Module<Ni, No>::update_initiator_packet(int id, tlm_generic_payload* trans) {
2291  assert(id < No);
2292  update_trace_packet();
2293  trace_packet.initiator_packet[id].transaction.update_transaction(trans);
2294 }
2295 
2296 template<int Ni, int No>
2297 void Module<Ni, No>::update_target_packet(int id, tlm_phase phase) {
2298  assert(id < Ni);
2299  update_target_packet(id);
2300  trace_packet.target_packet[id].phase = tlm_phase_to_ascii(phase);
2301 }
2302 
2303 template<int Ni, int No>
2305  assert(id < Ni);
2306  update_trace_packet();
2307  trace_packet.target_packet[id].transaction.update_transaction(incoming_transaction[id]);
2308  trace_packet.target_packet[id].transaction_pending.update_transaction(incoming_transaction_pending[id]);
2309 }
2310 
2311 template<int Ni, int No>
2313  trace_packet.target_packet[id].phase = IDLE_ASCII;
2314 }
2315 
2316 template<int Ni, int No>
2317 void Module<Ni, No>::set_target_phase(int id, tlm_phase& phase) {
2318  assert(id < Ni);
2319  trace_packet.target_packet[id].phase = tlm_phase_to_ascii(phase);
2320 }
2321 
2322 template<int Ni, int No>
2323 void Module<Ni, No>::set_initiator_phase(int id, tlm_phase& phase) {
2324  assert(id < No);
2325  trace_packet.initiator_packet[id].phase = tlm_phase_to_ascii(phase);
2326 }
2327 
2328 template<int Ni, int No>
2330  trace_packet.initiator_packet[id].phase = IDLE_ASCII;
2331 }
2332 
2333 template<int Ni, int No>
2334 void Module<Ni, No>::set_config_phase(tlm_phase& phase) {
2335  trace_packet.configuration_packet.phase = tlm_phase_to_ascii(phase);
2336 }
2337 
2338 template<int Ni, int No>
2340  assert(id < No);
2341  trace_packet.communication_status[id] = COM_WAITING_T_ASCII;
2342 }
2343 
2344 template<int Ni, int No>
2345 void Module<Ni, No>::set_com_status_tx(int id) {
2346  assert(id < No);
2347  trace_packet.communication_status[id] = COM_TX_T_ASCII;
2348 }
2349 
2350 template<int Ni, int No>
2352  assert(id < No);
2353  trace_packet.communication_status[id] = IDLE_ASCII;
2354 }
2355 
2356 template<int Ni, int No>
2358  trace_packet.algorithm_execution_mode = Utils::string_to_ascii(algorithm_execution_mode);
2359 }
2360 
2361 #endif
int get_nb_transient_channels(void)
Get number of transient channels within the module.
Definition: module.h:2066
bool use_context_switch_mode(string implementationName)
Check if context switch mode is enabled for the implementation named 'implementationName'. In this mode, specific to HW implementations, a context switch is performed each time the task is being replaced on a reconfigurable zone (not only when the task is being preempted).
Definition: module.h:2035
bool has_implementation(TaskImplementation &) const
Definition: module.h:1835
void set_request_time(void)
Set the time at which a configuration request has been made in order to update deadlines.
Definition: module.h:1955
void updateLists(int offset)
Update lists after the entire application has been defined. Called once by the reconfiguration manage...
Definition: module.h:1189
bool has_current_implementation(void)
Check if exist a current implementation.
Definition: module.h:2019
bool is_channel_transient(string)
Check if channel 'name' is transient or not.
Definition: module.h:1702
Definition: reconf_thread_interface.h:28
const sc_event & configuration_updated() const
Definition: module.h:1810
void set_algorithm_idle(void)
Function to call when the algorithm is idle in order to have an accurate trace.
Definition: module.h:1722
void wait_until_next_period(void)
Wait until the next period is started. For non-periodic tasks, return immediately.
Definition: module.h:1732
sc_time get_new_period_start_time(void) const
Retrieve time of the beginning for next period.
Definition: module.h:2057
Definition: module_interface.h:27
void b_data_sent(int id)
Check if data has been sent on a particular socket. Blocking function: if data send is not finished y...
Definition: module.h:1630
Definition: memory_manager.h:29
vector< int > getFollowingList(void) const
Get a list of tasks following this one in the block diagram. If an ID of vector is -1...
Definition: module.h:1984
bool is_algorithm_execution_mode(string)
Check for a particular execution mode.
Definition: module.h:1761
void b_send_data(string)
Send data towards channel 'name'. Blocking function: it will exit only when the following module has ...
Definition: module.h:1601
int get_output_socket_id(string name) const
Get input socket id by the name of the connection.
Definition: module.h:1348
int get_data_in_length(int) const
Get input socket data length.
Definition: module.h:1277
string get_algorithm_execution_mode(void)
Get current algorithm execution mode.
Definition: module.h:1756
void set_address_out(int, sc_dt::uint64)
Set address for outgoing transaction on socket 'socket'.
Definition: module.h:1321
sc_time get_BCET(void) const
Get task best case execution time (BCET), depending on current implementation.
Definition: module.h:1366
void nb_send_all_data(void)
Send data towards all channels. Non-blocking function.
Definition: module.h:1594
Definition: config_fct_point.h:31
sc_time get_deadline_time(void) const
Get task deadline (as the maximum acceptable time for one task execution)
Definition: module.h:1945
void release_input_socket(int socketID)
Release a particular input socket so that preceding module might send some more data.
Definition: module.h:1766
Definition: module_implementation.h:37
Definition: reconfigurable_zone.h:62
void set_algorithm_running(void)
Function to call when the algorithm is running in order to have an accurate trace.
Definition: module.h:1717
void set_task_priority(int priority)
Change the task priority.
Definition: module.h:2076
void start_new_transaction_sequence(void)
Indicate that a new transaction sequence is beginning (i.e. sending new data) for every socket...
Definition: module.h:1678
Definition: user_algorithm_interface.h:35
int * get_data_in_ptr(int)
Get pointer to incoming data from socket 'socket'.
Definition: module.h:1249
bool nb_all_data_received(void)
Check if the data from all channels have been received yet. Non-blocking function.
Definition: module.h:1550
void update_algorithm_execution_mode(string command)
Transmit algorithm execution mode from issued by the testbench to the module (e.g. change algorithm implementation to 'VHDL'.
Definition: module.h:2029
Definition: module.h:60
Definition: scheduler_request.h:27
ModuleImplementation get_current_implementation(void)
Get current implementation.
Definition: module.h:2024
int get_nb_processed_transactions(void) const
Get the number of transactions processed so far.
Definition: module.h:1979
bool nb_all_data_sent(void)
Check if data has been sent on every socket. Non-blocking function.
Definition: module.h:1669
ofstream & get_logfile(void)
Get logfile.
Definition: module.h:1751
void set_current_implementation(string)
Set current implementation for the module, based on its name ('implementationName').
Definition: module.h:1840
sc_time get_task_offset(void) const
Return task offset.
Definition: module.h:2009
int get_nb_preemption_points(void)
Get the number of preemption points that should be inserted in the algorithm.
Definition: module.h:1712
const sc_event & update_user_algorithm(void) const
Get the event launched when the user algorithm has to be modified (e.g. changing working implementati...
Definition: module.h:1482
sc_time get_task_deadline(void) const
Get task deadline (absolute time representation)
Definition: module.h:1950
void end_of_algorithm(void)
Function to call at the end of algorithm.
Definition: module.h:1371
bool nb_data_sent(int id)
Check if data has been sent on a particular socket. Non-blocking function. If no send request has eve...
Definition: module.h:1637
void b_execution_requested(void)
Wait until an algorithm execution has been requested/granted by the manager.
Definition: module.h:1799
bool nb_data_received(string)
Check if the data from channel 'name' have been received yet. Non-blocking function.
Definition: module.h:1534
vector< int > getPrecedingList(void) const
Get a list of tasks preceding this one in the block diagram. If an ID of vector is -1...
Definition: module.h:1989
tlm_sync_enum nb_transport_bw(int id, tlm_generic_payload &trans, tlm_phase &phase, sc_time &delay)
Definition: module.h:607
sc_time get_WCET(void) const
Get task worst case execution time (WCET), depending on current implementation.
Definition: module.h:1361
int get_data_out_length(int) const
Get output socket data length.
Definition: module.h:1292
void b_send_all_data(void)
Send data towards every channels. Blocking function: it will exit only when the following modules hav...
Definition: module.h:1622
void send_start_algorithm_event(void)
Send a notification to the module in order to start the user algorithm.
Definition: module.h:2046
string getName(void) const
Return module name.
Definition: module.h:1974
void set_algorithm_waiting(void)
Function to call when the algorithm is waiting for data in order to have an accurate trace...
Definition: module.h:1727
Definition: manager_interface.h:28
void nb_send_data(string)
Send data towards channel 'name'. Non-blocking function.
Definition: module.h:1560
User_algorithm_action
Definition: user_algorithm_interface.h:32
Definition: task_implementation.h:46
string get_current_implementation_fullname(void)
Get current implementation ID.
Definition: module.h:2014
int get_input_socket_id(string name) const
Get input socket id by the name of the connection.
Definition: module.h:1335
int * get_data_out_ptr(int)
Get pointer to outgoing data from socket 'socket'.
Definition: module.h:1263
void b_all_data_received(void)
Check if the data from all channels have been received yet. Blocking function: if the data is not ava...
Definition: module.h:1527
void b_data_received(string)
Check if the data from channel 'name' have been received yet. Blocking function: if the data is not a...
Definition: module.h:1499
const char * get_name() const
Definition: module.h:1244
sc_time get_task_period(void) const
Return task period.
Definition: module.h:2004
void b_all_data_sent(void)
Check if data has been sent on every socket. Blocking function: if data send is not finished yet...
Definition: module.h:1664
int get_task_priority(void) const
Return task priority.
Definition: module.h:1999
Definition: trace.h:126
bool & kill_user_algorithm(void)
Get a reference to a boolean indicating whether the user algorithm should be killed or not (for insta...
Definition: module.h:1493
void preemption_point(void)
Function to call to emulate preemption.
Definition: module.h:1412
sc_dt::uint64 get_address_in(int) const
Retrieve address from the incoming transaction on socket 'socket'.
Definition: module.h:1307
bool is_static(void) const
Check if the module has been defined static (i.e. always implemented on the FPGA) ...
Definition: module.h:1994
bool fits(RZ *rz)
Check if task fits a reconfigurable zone (verifying every hardware implementations defined for the mo...
Definition: module.h:1961
void compute(sc_time duration)
Emulate an execution time of the algorithm.
Definition: module.h:1424
void release_all_input_sockets(void)
Release all input socket so that preceding modules might send some more data.
Definition: module.h:1794