RecoSim  1.0
 All Classes Files Functions Variables Enumerations
testbench_algorithms.h
1 
21 #ifndef TESTBENCH_ALGORITHM_H
22 #define TESTBENCH_ALGORITHM_H
23 
24 #define NB_TRANSACTIONS_TO_SEND 100
25 
27 #include "testbench_in_interface.h"
30 #include "utils.h"
31 
32 template<int No>
33 void testbench_out_thread(Testbench_out_interface<No>& tb_interface) {
34 
35  //
36  // ALGORITHM COMMANDS (Optional)
37  //
38 
39  /*
40  // Example : sent the "command" to "module name" at 10 ms
41  tb_interface.TB_IF_add_execution_mode_command_to_queue("module name", "command", sc_time(10, SC_MS));
42  */
43 
44 
45  //
46  // DATA SEND (Generate a sequence of random transactions)
47  //
48  for (int i = 0; i < NB_TRANSACTIONS_TO_SEND; i++) {
49 
50  // Check that first module in the chain is ready
51 #ifdef GENERATE_LOG_FILE
52  Simulation_controller::get_logfile() << endl << sc_time_stamp() << ": " << tb_interface.TB_IF_name() << " checks instantiation for following modules" << endl;
53 #endif
54 
55  // INIT TRANSACTIONS : Initialize data to send for a default transaction for each out Interface (j port)
56  // It is possible to use the connection name tb_interface.TB_IF_get_data_out_ptr("Connection1")
57  // A default data of packet is [31:16] = Transaction number, [15:0] = index number (0 to packet_size-1 attribute)
58  for(int j = 0; j < No; j++) {
59 
60  int max_packet = tb_interface.TB_IF_get_packet_size(j);
61  int *data_out_ptr = tb_interface.TB_IF_get_data_out_ptr(j);
62  for(int k = 0; k < max_packet; k++)
63  data_out_ptr[k] = (i << 16) | k;
64  }
65 
66  // SEND TRANSACTIONS : ALL TRANSACTIONS SENT
67  // IT is possible to use TB_IF_nb_send_data(connectionName or connection id) to custom the sending
68  tb_interface.TB_IF_nb_send_all_data();
69 
70  /* DO NOTHING */
71  /* check_target method asks for following modules instantiation, answer from
72  * the manager will produce an event responsible for data transfers */
73 
74  // WAIT RESPONSES : Wait until all responses from following modules have been received
75  // QUESTIONFAB : et si on envoie que sur 2 sorties au lieu de trois, cela bloque ? est ce vrai ?
76  wait(tb_interface.TB_IF_all_responses_received_event());
77 
78 #ifdef GENERATE_LOG_FILE
79  Simulation_controller::get_logfile() << sc_time_stamp() << ": " << tb_interface.TB_IF_name() << ": Transaction " << i << " has been sent" << endl;
80 #endif
81 
82  // WAIT NEXT PERIOD
83  if(i != (NB_TRANSACTIONS_TO_SEND - 1)) {
84  // Delay next transaction by waiting extra time
85  sc_time delayToNextPacket((i + 1) * tb_interface.TB_IF_get_period() - sc_time_stamp());
86  if(delayToNextPacket < SC_ZERO_TIME) {
87  cerr << "ERROR in TB: Negative delay to next packet send! Consider revising periods and other timing information" << endl;
88  exit(RECOSIM_INTERNAL_ERROR_ERRCODE);
89  }
90  wait(delayToNextPacket);
91  }
92 
93  // NEXT TRANSACTION ID
95  }
96 
97 #ifdef GENERATE_LOG_FILE
98  Simulation_controller::get_logfile() << sc_time_stamp() << ": " << tb_interface.TB_IF_name() << ": All transactions have been sent" << endl;
99 #endif
100 }
101 
102 template<int Ni>
103 void testbench_in_thread(Testbench_in_interface<Ni> &tb_interface) {
104 
105  int nb_transactions_received = 0;
106  int nb_diff = 0;
107  int last_transaction_count[Ni];
108  for(int i = 0; i < Ni; i++) last_transaction_count[i] = 0;
109 
110  while(nb_transactions_received != NB_TRANSACTIONS_TO_SEND * Ni) {
111 
112  sc_time timeout(Reconfiguration_manager::getMaximumSimulationTime() - sc_time_stamp() - sc_time(1, SC_US)); // Time out right before end of simulation
113  wait(timeout, tb_interface.TB_IF_transaction_received_event());
114 
115  if(sc_time_stamp() == Reconfiguration_manager::getMaximumSimulationTime() - sc_time(1, SC_US)) {
116  // Reached end of simulation due to timeout, something is wrong with the testbench
117  cout << "CRITICAL WARNING: End of simulation reached but testbench thread is still waiting for transactions..." << endl;
118  cout << "Testbench name: " << tb_interface.TB_IF_name();
119  for(int i = 0; i < Ni; i++) cout << "Socket " << tb_interface.TB_IF_get_connection_name(i) << " received " << tb_interface.TB_IF_get_nb_transactions_received_per_socket(i) << " transactions" << endl;
120  cout << "Consider revising:" << endl;
121  cout << " - Testbench to wait for less transactions" << endl;
122  cout << " - Module algorithms to send data more often" << endl;
123  return;
124  } else {
125 
126  // Verify data 'on-the-fly'
127  //for(int i = 0; i < Ni; i++) {
128  vector<int> sockets_with_new_transactions(tb_interface.TB_IF_get_sockets_with_new_transactions());
129  for(int i = 0; i < (int) sockets_with_new_transactions.size(); i++) {
130  int socketID = sockets_with_new_transactions.at(i);
131  //if(tb_interface.TB_IF_get_nb_transactions_received_per_socket(i) != last_transaction_count[i]) {
132  // Data received on this socket
133  // Check data
134  int *data_ptr = tb_interface.TB_IF_get_data_in_ptr(socketID);
135  for(int j = 0; j < 16; j++) {
136  if(data_ptr[j] != ((last_transaction_count[socketID] << 16) | j)) {
137  nb_diff++;
138  cout << "Socket " << socketID << ", Transaction " << last_transaction_count[socketID] << ", Data " << j << " -> " << hex << data_ptr[j] << " (expected " << ((last_transaction_count[socketID] << 16) | j) << ")" << endl;
139  }
140  }
141 
142  // Update transaction count
143  last_transaction_count[socketID]++;
144  nb_transactions_received++;
145  //break;
146  //}
147  }
148 
149 
150  }
151 
152 
153  }
154 
155  if(nb_diff == 0) {
156  Simulation_controller::get_logfile() << endl << "==================================================" << endl;
157  Simulation_controller::get_logfile() << " CONGRATULATIONS: Simulation ended successfully " << endl;
158  Simulation_controller::get_logfile() << "==================================================" << endl << endl;
159 
160  // Communicate with the simulation controller
161  tb_interface.TB_IF_notify_simulation_controller(true);
162  } else {
163  Simulation_controller::get_logfile() << endl << "==================================================" << endl;
164  Simulation_controller::get_logfile() << " Simulation failed with " << dec << nb_diff << " errors " << endl;
165  Simulation_controller::get_logfile() << "==================================================" << endl << endl;
166 
167  exit(RECOSIM_TESTBENCH_CHECK_FAILED);
168  }
169 }
170 
171 #endif
virtual const sc_event & TB_IF_transaction_received_event(void) const =0
Get the event launched when a transaction has been received.
Definition: testbench_in_interface.h:31
virtual void TB_IF_nb_send_all_data(void)=0
Non-blocking data send through every socket.
virtual sc_time TB_IF_get_period(void) const =0
Get testbench period.
virtual void TB_IF_notify_simulation_controller(bool success)=0
Notifies simulation controller about success/failure of the simulation (e.g. data corruption)...
virtual const int TB_IF_get_nb_transactions_received_per_socket(int socketID) const =0
Get the number of transactions processed per socket.
virtual void TB_IF_increment_current_transaction_id(void)=0
Increments working transaction counter.
Definition: testbench_out_interface.h:31
virtual int * TB_IF_get_data_in_ptr(int socketID) const =0
Get incoming data pointer.
virtual string TB_IF_get_connection_name(int id) const =0
Get the name of the connection bound to a particular socket.
virtual int TB_IF_get_packet_size(int ID) const =0
Get socket packet size.
virtual vector< int > TB_IF_get_sockets_with_new_transactions(void)=0
Get a list of the sockets that received a new transaction since last function call. WARNING: Calling this function will reset the vector stored within the testbench and hence should be stored in a new vector within the algorithm thread.
virtual int * TB_IF_get_data_out_ptr(int socketID) const =0
Get pointer to ougoing data structure.
virtual const char * TB_IF_name(void) const =0
Get testbench full name.
virtual const sc_event & TB_IF_all_responses_received_event(void) const =0
Watch the event issued once all TLM responses have been sent from following modules to testbench...
virtual const char * TB_IF_name(void) const =0
Get testbench full name.