RecoSim  1.0
 All Classes Files Functions Variables Enumerations
module_algorithms.h
Go to the documentation of this file.
1 
21 #ifndef MODULE_ALGORITHMS_H
22 #define MODULE_ALGORITHMS_H
23 
25 #include "user_module_algorithms.h"
26 
27 template<int Ni, int No> void user_algorithm_generic(User_algorithm_interface<Ni, No> &user_algo_interface, bool hw) {
28 
29  /*******************************************************************************/
30  /* This is a Default Behavior */
31 
32  while(true) {
33 
34  /*******************************************************************************/
35  /**** MANDATORY PART (EXCEPT DISPLAY) ****/
36 
37 
38  /* WAIT FOR START ALGORITHM EVENT : Only for Dynamic tasks */
39  user_algo_interface.get_logfile() << sc_time_stamp() << ": " << user_algo_interface.get_name() << " Beginning of loop" << endl;
40  user_algo_interface.b_execution_requested();
41  user_algo_interface.get_logfile() << sc_time_stamp() << ": " << user_algo_interface.get_name() << " Execution requested" << endl;
42 
43  /* TRACE : The algorithm is idle in order to have an accurate trace */
44  user_algo_interface.set_algorithm_idle();
45 
46  /* WAIT FOR NEXT PERIOD to begin to start algorithm execution. For non-periodic modules, function returns right away */
47  user_algo_interface.wait_until_next_period();
48 #ifdef GENERATE_LOG_FILE
49  user_algo_interface.get_logfile() << sc_time_stamp() << ": " << user_algo_interface.get_name() << " New period started" << endl;
50 #endif
51  user_algo_interface.set_algorithm_waiting();
52 
53  /**** BEGINNING OF DATA RECEPTION SEGMENT ****/
54 
55  user_algo_interface.b_all_data_received();
56 
57  user_algo_interface.set_algorithm_running();
58 
59  /**** END OF DATA RECEPTION SEGMENT ****/
60 
61  /**** BEGINNING OF USER ALGORITHM ****/
62 #ifdef GENERATE_LOG_FILE
63  if(hw) user_algo_interface.get_logfile() << sc_time_stamp() << ": " << user_algo_interface.get_name() << " User algorithm started (HW impl) with command " << user_algo_interface.get_algorithm_execution_mode() << endl;
64  else user_algo_interface.get_logfile() << sc_time_stamp() << ": " << user_algo_interface.get_name() << " User algorithm started (SW impl) with command " << user_algo_interface.get_algorithm_execution_mode() << endl;
65 #endif
66 
67  // Preemption points
68  for(int i = 0; i < user_algo_interface.get_nb_preemption_points(); i++) {
69  //wait(user_algo_interface.get_WCET()/(user_algo_interface.get_nb_preemption_points() + 1));
70  user_algo_interface.compute(user_algo_interface.get_WCET()/(user_algo_interface.get_nb_preemption_points() + 1));
71 #ifdef GENERATE_LOG_FILE
72  user_algo_interface.get_logfile() << sc_time_stamp() << ": " << user_algo_interface.get_name() << " Preemption point " << i + 1 << " reached" << endl;
73 #endif
74  user_algo_interface.preemption_point();
75  user_algo_interface.set_algorithm_running();
76 #ifdef GENERATE_LOG_FILE
77  user_algo_interface.get_logfile() << sc_time_stamp() << ": " << user_algo_interface.get_name() << " Preemption point " << i + 1 << " returned" << endl;
78 #endif
79  }
80 
81  // Wait for the last execution segment (after last preemption point)
82  //wait(user_algo_interface.get_WCET()/(user_algo_interface.get_nb_preemption_points() + 1));
83  user_algo_interface.compute(user_algo_interface.get_WCET()/(user_algo_interface.get_nb_preemption_points() + 1));
84 
85 #ifdef GENERATE_LOG_FILE
86  user_algo_interface.get_logfile() << sc_time_stamp() << ": " << user_algo_interface.get_name() << " User algorithm ended" << endl;
87 #endif
88 
89  /**** END OF USER ALGORITHM ****/
90 
91 
92  // Check that all data issued from previous algorithm execution has been processed and sent
93  user_algo_interface.b_all_data_sent();
94 
95  // When all data is sent, indicate that a new sequence starts now
96  // MUST BE DONE ONLY AFTER VERIFYING THAT ALL PREVIOUS DATA HAVE BEEN SENT
97  user_algo_interface.start_new_transaction_sequence();
98 
99  // Find a channel that is not transient and has updated data
100  int channel_id = 0;
101  while(user_algo_interface.is_channel_transient(channel_id) || !user_algo_interface.nb_data_received(channel_id)) channel_id++;
102 
103  // Copy data
104  int data_in_length = 0;
105  int data_out_length = 0;
106  for(int i = 0; i < No; i++) {
107  data_in_length = user_algo_interface.get_data_in_length(channel_id);
108  data_out_length = user_algo_interface.get_data_out_length(i);
109 
110  if(data_out_length <= data_in_length) {
111  memcpy(user_algo_interface.get_data_out_ptr(i), user_algo_interface.get_data_in_ptr(channel_id), data_out_length);
112  } else {
113  memcpy(user_algo_interface.get_data_out_ptr(i), user_algo_interface.get_data_in_ptr(channel_id), data_in_length);
114  for(int j = data_in_length; j < data_out_length; j+=4) user_algo_interface.get_data_out_ptr(i)[j/4] = 0;
115  }
116 
117  user_algo_interface.set_address_out(i, user_algo_interface.get_address_in(channel_id));
118  }
119 
120  // Release input sockets (we won't need their data anymore) for they are used by preceding modules again
121  user_algo_interface.release_all_input_sockets();
122 
123  // Notify RZ to continue processing
124  user_algo_interface.end_of_algorithm();
125 
126  // Send data to all sockets
127  user_algo_interface.nb_send_all_data();
128 
129 
130  // Wait for the event notifying a possible change in the user algorithm thread
131  user_algo_interface.wait_for_update_user_algorithm();
132 
133  user_algo_interface.get_logfile() << sc_time_stamp() << ": " << user_algo_interface.get_name() << " Update user algorithm event received" << endl;
134 
135  if(user_algo_interface.kill_user_algorithm()) {
136 #ifdef GENERATE_LOG_FILE
137  user_algo_interface.get_logfile() << user_algo_interface.get_name() << " User algorithm thread has to be killed!" << endl;
138 #endif
139  return;
140  }
141  }
142 }
143 
144 template<int Ni, int No> void user_algorithm_HW(User_algorithm_interface<Ni, No> &user_algo_interface) {
145  user_algorithm_generic(user_algo_interface, true);
146 }
147 
148 template<int Ni, int No> void user_algorithm_SW(User_algorithm_interface<Ni, No> &user_algo_interface) {
149  user_algorithm_generic(user_algo_interface, false);
150 }
151 
152 #endif
virtual ofstream & get_logfile(void)=0
Get logfile.
virtual bool & kill_user_algorithm(void)=0
Get a reference to a boolean indicating whether the user algorithm should be killed or not (for insta...
virtual string get_algorithm_execution_mode(void)=0
Get current algorithm execution mode.
virtual void start_new_transaction_sequence(int id)=0
Indicate that a new transaction sequence is beginning (i.e. sending new data) for a particular socket...
virtual int * get_data_in_ptr(int socket)=0
Get pointer to incoming data from socket 'socket'.
virtual void set_address_out(int socket, sc_dt::uint64 value)=0
Set address for outgoing transaction on socket 'socket'.
virtual bool nb_data_received(string name)=0
Check if the data from channel 'name' have been received yet. Non-blocking function.
virtual int get_nb_preemption_points(void)=0
Get the number of preemption points that should be inserted in the algorithm.
virtual void b_all_data_received(void)=0
Check if the data from all channels have been received yet. Blocking function: if the data is not ava...
virtual void preemption_point(void)=0
Function to call to emulate preemption.
virtual sc_time get_WCET(void) const =0
Get task worst case execution time (WCET), depending on current implementation.
virtual int get_data_out_length(int socket) const =0
Get output socket data length.
virtual void compute(sc_time duration)=0
Emulate an execution time of the algorithm.
virtual void release_all_input_sockets(void)=0
Release all input socket so that preceding modules might send some more data.
virtual void set_algorithm_waiting(void)=0
Function to call when the algorithm is waiting for data in order to have an accurate trace...
virtual int get_data_in_length(int socket) const =0
Get input socket data length.
virtual const char * get_name(void) const =0
Get task name.
virtual void b_execution_requested(void)=0
Wait until an algorithm execution has been requested/granted by the manager.
Definition: user_algorithm_interface.h:35
virtual bool is_channel_transient(string name)=0
Check if channel 'name' is transient or not.
virtual void end_of_algorithm(void)=0
Function to call at the end of algorithm.
virtual int * get_data_out_ptr(int socket)=0
Get pointer to outgoing data from socket 'socket'.
virtual void set_algorithm_running(void)=0
Function to call when the algorithm is running in order to have an accurate trace.
virtual void set_algorithm_idle(void)=0
Function to call when the algorithm is idle in order to have an accurate trace.
virtual void wait_until_next_period(void)=0
Wait until the next period is started. For non-periodic tasks, return immediately.
virtual sc_dt::uint64 get_address_in(int socket) const =0
Retrieve address from the incoming transaction on socket 'socket'.
virtual void b_all_data_sent(void)=0
Check if data has been sent on every socket. Blocking function: if data send is not finished yet...
virtual void nb_send_all_data(void)=0
Send data towards all channels. Non-blocking function.