source: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Commit_unit/src/Commit_unit_genMoore.cpp @ 139

Last change on this file since 139 was 139, checked in by rosiere, 14 years ago
  • Add test for all configuration
  • RAT : add rat scheme (depth_save)
  • Property svn:keywords set to Id
File size: 15.9 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Commit_unit_genMoore.cpp 139 2010-07-30 14:47:27Z rosiere $
4 *
5 * [ Description ]
6 *
7 */
8
9#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Commit_unit/include/Commit_unit.h"
10
11namespace morpheo                    {
12namespace behavioural {
13namespace core {
14namespace multi_ooo_engine {
15namespace ooo_engine {
16namespace commit_unit {
17
18
19#undef  FUNCTION
20#define FUNCTION "Commit_unit::genMoore"
21  void Commit_unit::genMoore (void)
22  {
23    log_begin(Commit_unit,FUNCTION);
24    log_function(Commit_unit,FUNCTION,_name.c_str());
25
26    if (PORT_READ(in_NRESET))
27      {
28    // ===================================================================
29    // =====[ REEXECUTE ]=================================================
30    // ===================================================================
31    {
32      uint32_t num_scan_bank = 0; // last scan bank
33      bool     can_continue = true;
34
35      uint32_t event_nb_inst  [_param->_nb_front_end][_param->_max_nb_context];
36      for (uint32_t i=0; i<_param->_nb_front_end; i++)
37        for (uint32_t j=0; j<_param->_nb_context [i]; j++)
38          event_nb_inst [i][j] = 0;
39
40      // for each reexecute_port
41      for (uint32_t i=0; i<_param->_nb_inst_reexecute; ++i)
42        {
43          log_printf(TRACE,Commit_unit,FUNCTION,"  * REEXECUTE [%d]",i);
44         
45          // Store instruction comming Out Of Order in Load Store Unit.
46          // Must be executed in no speculative mode. Also, send a signal when an Store is in head of ROB
47         
48          Tcontrol_t val = false;
49
50          for (uint32_t j=num_scan_bank; j<_param->_nb_bank; j++)
51            {
52              num_scan_bank ++;
53             
54              // translate bank number
55              uint32_t num_bank = (reg_NUM_BANK_HEAD+j)%_param->_nb_bank;
56             
57              log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank      : %d",num_bank);
58
59              // Test if the head of rob is not empty
60              if (not _rob[num_bank].empty())
61                {
62                  log_printf(TRACE,Commit_unit,FUNCTION,"    * ROB is not empty");
63                 
64                  // Read state
65                  entry_t    * entry = _rob [num_bank].front();
66                  uint32_t     num_packet   = ((entry->ptr << _param->_shift_num_slot) | num_bank);
67                  Tcontext_t   front_end_id = entry->front_end_id;
68                  Tcontext_t   context_id   = entry->context_id  ;
69
70                  rob_state_t  state = entry->state;
71                 
72                  // Test state
73                  //  * store is ko, send signal at store_queue
74                  //  * store_is ok, test if in head
75//                val   = (((state == ROB_STORE_OK) and (num_bank == (reg_NUM_BANK_HEAD))) or
76//                          (state == ROB_STORE_KO)  or
77//                          (state == ROB_STORE_EVENT)
78//                          );
79                  val   = (((state == ROB_STORE_OK) and can_continue) or
80                            (state == ROB_STORE_KO)  or
81                            (state == ROB_STORE_EVENT)
82                            );
83                 
84                  event_nb_inst [front_end_id][context_id] ++;
85
86                  can_continue &= (((state == ROB_STORE_OK          ) or
87                                    (state == ROB_STORE_OK_WAIT_END ) or
88                                    (state == ROB_END_OK_SPECULATIVE) or
89                                    (state == ROB_END_OK            ) or
90                                    (state == ROB_END               )) and
91                                   not ((reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_NOT_YET_EVENT) and
92                                        (reg_EVENT_PACKET[front_end_id][context_id] == num_packet)) and
93                                   not ((reg_EVENT_NB_INST [front_end_id][context_id] > 0) and
94                                        ((event_nb_inst [front_end_id][context_id]) >= reg_EVENT_NB_INST [front_end_id][context_id]))
95                                   );
96
97                  log_printf(TRACE,Commit_unit,FUNCTION,"    * val           : %d",val);
98
99                  if (val)
100                    {
101                      internal_REEXECUTE_NUM_BANK [i] = num_bank;
102
103                      Tpacket_t packet_id = ((entry->ptr << _param->_shift_num_slot) | num_bank);
104                     
105                      log_printf(TRACE,Commit_unit,FUNCTION,"    * packet_id     : %d",packet_id);
106                     
107                      // Reexecute store
108                      if (_param->_have_port_context_id)
109                      PORT_WRITE(out_REEXECUTE_CONTEXT_ID            [i], entry->context_id           );
110                      if (_param->_have_port_front_end_id)
111                      PORT_WRITE(out_REEXECUTE_FRONT_END_ID          [i], entry->front_end_id         );
112                      if (_param->_have_port_rob_ptr  )
113                      PORT_WRITE(out_REEXECUTE_PACKET_ID             [i], packet_id                   );
114                      PORT_WRITE(out_REEXECUTE_TYPE                  [i], entry->type                 );
115                      PORT_WRITE(out_REEXECUTE_STORE_QUEUE_PTR_WRITE [i], entry->store_queue_ptr_write);
116                      PORT_WRITE(out_REEXECUTE_OPERATION             [i], (state == ROB_STORE_OK)?OPERATION_MEMORY_STORE_HEAD_OK:OPERATION_MEMORY_STORE_HEAD_KO);
117
118                      break; // Stop scan
119                    }
120                }
121            } 
122
123          internal_REEXECUTE_VAL      [i] = val;
124        }
125    }
126
127    // ===================================================================
128    // =====[ BRANCH_COMPLETE ]===========================================
129    // ===================================================================
130    {
131      // Branchement must be send at the prediction unit
132
133      uint32_t num_scan_bank = 0; // last scan bank
134
135      // for each port, find a valid branchement.
136      for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
137        {
138          log_printf(TRACE,Commit_unit,FUNCTION,"  * BRANCH_COMPLETE [%d]",i);
139
140          Tcontrol_t  val  = false;
141         
142          for (uint32_t j=num_scan_bank; j<_param->_nb_bank; j++)
143            {
144              num_scan_bank ++;
145
146              // translate bank number
147              uint32_t num_bank = (reg_NUM_BANK_HEAD+j)%_param->_nb_bank;
148
149              log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank           : %d",num_bank);
150             
151              // Test if in this bank, they have an instruction
152              if (not _rob [num_bank].empty())
153                {
154                  log_printf(TRACE,Commit_unit,FUNCTION,"    * not empty");
155
156                  // Read information
157                  entry_t    * entry    = _rob [num_bank].front();
158                  rob_state_t  state    = entry->state;
159                  Tcontext_t   front_end_id = entry->front_end_id;
160                  Tcontext_t   context_id   = entry->context_id  ;
161
162                  log_printf(TRACE,Commit_unit,FUNCTION,"    * front_end_id       : %d",front_end_id);
163                  log_printf(TRACE,Commit_unit,FUNCTION,"    * context_id         : %d",context_id  );
164
165                  // don't complete a branch when rob manage an present event
166                  if (((reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_NO_EVENT) or
167                       (reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_NOT_YET_EVENT)) and
168                      (state == ROB_BRANCH_COMPLETE))
169                    {
170                      log_printf(TRACE,Commit_unit,FUNCTION,"    * find !!!");
171
172                      // test if have a future event (stop is set)
173//                       log_printf(TRACE,Commit_unit,FUNCTION,"      * reg_EVENT_STOP   : %d",reg_EVENT_STOP [front_end_id][context_id]);
174
175                      if (reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_NOT_YET_EVENT)
176                        {
177                          // Have future event, can complete the branch if the event is most speculative than this branchement
178                          // Also, need compare packet_id (is order)
179
180                          uint32_t _top = ((_rob[reg_NUM_BANK_HEAD].front()->ptr << _param->_shift_num_slot) | reg_NUM_BANK_HEAD);
181                          uint32_t _old = reg_EVENT_PACKET [front_end_id][context_id];
182                          uint32_t _new = ((entry->ptr << _param->_shift_num_slot) | num_bank);
183
184//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _top             : %d",_top);
185//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _old (before)    : %d",_old);
186//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _new (before)    : %d",_new);
187
188                          if (_old < _top) _old = _old+_param->_size_queue;
189                          if (_new < _top) _new = _new+_param->_size_queue;
190                          if (_new < _old) val = true;
191
192//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _old (after )    : %d",_old);
193//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _new (after )    : %d",_new);
194
195                        }
196                      else
197                        val = true;
198                     
199                      log_printf(TRACE,Commit_unit,FUNCTION,"      * val              : %d",val);
200
201                      if (val)
202                        {
203                          // Have an valid branchement to complete
204                      internal_BRANCH_COMPLETE_NUM_BANK           [i] = num_bank;
205                     
206                      if (_param->_have_port_front_end_id)
207                      PORT_WRITE(out_BRANCH_COMPLETE_FRONT_END_ID [i],        front_end_id    );
208                      if (_param->_have_port_context_id)
209                      PORT_WRITE(out_BRANCH_COMPLETE_CONTEXT_ID   [i],        context_id      );
210                      if (_param->_have_port_depth)
211                      PORT_WRITE(out_BRANCH_COMPLETE_DEPTH        [i], entry->depth           );
212                      PORT_WRITE(out_BRANCH_COMPLETE_ADDRESS      [i], entry->address_next    );
213//                    PORT_WRITE(out_BRANCH_COMPLETE_FLAG         [i],(entry->flags&FLAG_F)!=0);
214                      PORT_WRITE(out_BRANCH_COMPLETE_NO_SEQUENCE  [i], entry->no_sequence     );
215                     
216                      break; // Stop scan
217                        }
218                    }
219                }
220            }
221
222          internal_BRANCH_COMPLETE_VAL [i] = val;
223        }
224    }
225
226    // ===================================================================
227    // =====[ UPDATE ]====================================================
228    // ===================================================================
229    {
230      internal_UPDATE_VAL = 0;
231      internal_UPDATE_NUM_BANK = reg_NUM_BANK_HEAD;
232
233      // Test if have an instruction
234      if (not _rob[internal_UPDATE_NUM_BANK].empty())
235        {
236          log_printf(TRACE,Commit_unit,FUNCTION,"  * UPDATE");
237          log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank : %d",internal_UPDATE_NUM_BANK);
238
239          entry_t * entry = _rob [internal_UPDATE_NUM_BANK].front();
240
241          // Test state
242          // Update if exception or load miss
243          switch (entry->state)
244            {
245            case ROB_END_EXCEPTION_UPDATE :
246              {
247                internal_UPDATE_VAL = 1;
248                throw ERRORMORPHEO(FUNCTION,_("Moore : exception is not yet supported (Coming Soon).\n"));
249                break;
250              }
251            case ROB_END_LOAD_MISS_UPDATE :
252              {
253                log_printf(TRACE,Commit_unit,FUNCTION,"    * ROB_END_LOAD_MISS_UPDATE");
254
255                internal_UPDATE_VAL = 1;
256
257                Tcontext_t front_end_id = entry->front_end_id;
258                Tcontext_t context_id   = entry->context_id  ;
259
260                log_printf(TRACE,Commit_unit,FUNCTION,"      * front_end_id : %d",front_end_id);
261                log_printf(TRACE,Commit_unit,FUNCTION,"      * context_id   : %d",context_id  );
262
263                if (_param->_have_port_front_end_id)
264                PORT_WRITE(out_UPDATE_FRONT_END_ID    ,front_end_id);
265                if (_param->_have_port_context_id)
266                PORT_WRITE(out_UPDATE_CONTEXT_ID      ,context_id  );
267                if (_param->_have_port_depth)
268                PORT_WRITE(out_UPDATE_DEPTH           ,entry->depth);
269                PORT_WRITE(out_UPDATE_TYPE            ,EVENT_TYPE_LOAD_MISS_SPECULATION);
270//                 PORT_WRITE(out_UPDATE_IS_DELAY_SLOT   ,reg_PC_CURRENT_IS_DS      [front_end_id][context_id]);
271//                 PORT_WRITE(out_UPDATE_ADDRESS         ,reg_PC_CURRENT            [front_end_id][context_id]);
272//                 PORT_WRITE(out_UPDATE_ADDRESS_EPCR_VAL,reg_PC_CURRENT_IS_DS_TAKE [front_end_id][context_id]);
273//                 PORT_WRITE(out_UPDATE_ADDRESS_EPCR    ,reg_PC_NEXT               [front_end_id][context_id]);
274//                 PORT_WRITE(out_UPDATE_ADDRESS_EEAR_VAL,0);
275// //              PORT_WRITE(out_UPDATE_ADDRESS_EEAR    ,);
276
277                PORT_WRITE(out_UPDATE_IS_DELAY_SLOT   ,0);
278                PORT_WRITE(out_UPDATE_ADDRESS         ,reg_PC_NEXT [front_end_id][context_id]);
279                PORT_WRITE(out_UPDATE_ADDRESS_EPCR_VAL,0);
280//              PORT_WRITE(out_UPDATE_ADDRESS_EPCR    ,);
281                PORT_WRITE(out_UPDATE_ADDRESS_EEAR_VAL,0);
282//              PORT_WRITE(out_UPDATE_ADDRESS_EEAR    ,);
283
284                break;
285              }
286            default :
287              {
288//                 internal_UPDATE_VAL = 0;
289              }
290            }
291        }
292     
293      log_printf(TRACE,Commit_unit,FUNCTION,"  * UPDATE (end)");
294    }
295 
296    // ===================================================================
297    // =====[ NB_INST ]===================================================
298    // ===================================================================
299    {
300#ifdef DEBUG_TEST
301      bool empty = true;
302#endif
303      for (uint32_t i=0; i<_param->_nb_front_end; i++)
304        for (uint32_t j=0; j<_param->_nb_context [i]; j++)
305          {
306#ifdef DEBUG_TEST
307            empty &= (reg_NB_INST_COMMIT_ALL [i][j] == 0);
308#endif
309            PORT_WRITE(out_NB_INST_COMMIT_ALL [i][j], reg_NB_INST_COMMIT_ALL [i][j]);
310            PORT_WRITE(out_NB_INST_COMMIT_MEM [i][j], reg_NB_INST_COMMIT_MEM [i][j]);
311          }
312#ifdef DEBUG_TEST
313      PORT_WRITE(out_INFO_ROB_EMPTY,empty);
314#endif
315    }
316
317
318    // ===================================================================
319    // =====[ RETIRE_EVENT ]==============================================
320    // ===================================================================
321    for (uint32_t i=0; i<_param->_nb_front_end; i++)
322      for (uint32_t j=0; j<_param->_nb_context [i]; j++)
323        {
324//           bool flush = (((reg_EVENT_STATE [i][j] == COMMIT_EVENT_STATE_EVENT) or
325//                          (reg_EVENT_STATE [i][j] == COMMIT_EVENT_STATE_WAIT_DECOD)) and
326//                         not reg_EVENT_CAN_RESTART[i][j]);
327
328          PORT_WRITE(out_RETIRE_EVENT_STATE [i][j], commit_event_state_to_event_state(reg_EVENT_STATE[i][j]));
329//        PORT_WRITE(out_RETIRE_EVENT_FLUSH [i][j], flush);
330//        PORT_WRITE(out_RETIRE_EVENT_STOP  [i][j], reg_EVENT_STOP [i][j]);
331          PORT_WRITE(out_RETIRE_EVENT_STOP  [i][j], ((reg_EVENT_STATE [i][j] == COMMIT_EVENT_STATE_NOT_YET_EVENT) or
332                                                     reg_EVENT_NEXT_STOP [i][j]));
333          if (_param->_rat_scheme[i] == RAT_DEPTH_SAVE)
334            {
335          PORT_WRITE(out_RETIRE_EVENT_TYPE  [i][j], reg_EVENT_TYPE  [i][j]);
336          if (_param->_have_port_depth)
337          PORT_WRITE(out_RETIRE_EVENT_DEPTH [i][j], reg_EVENT_DEPTH [i][j]);
338            }
339        }
340      }
341    else
342      {
343        for (uint32_t i=0; i<_param->_nb_inst_reexecute; ++i)
344          {
345            internal_REEXECUTE_VAL      [i] = 0;
346//             internal_REEXECUTE_NUM_BANK [i] = num_bank;
347          }
348
349        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
350          {
351            internal_BRANCH_COMPLETE_VAL [i] = 0;
352//             internal_BRANCH_COMPLETE_NUM_BANK           [i] = num_bank;
353          }
354
355        internal_UPDATE_VAL = 0;
356//       internal_UPDATE_NUM_BANK = reg_NUM_BANK_HEAD;
357
358
359        for (uint32_t i=0; i<_param->_nb_front_end; i++)
360          for (uint32_t j=0; j<_param->_nb_context [i]; j++)
361            {
362              PORT_WRITE(out_RETIRE_EVENT_STATE [i][j], commit_event_state_to_event_state(COMMIT_EVENT_STATE_NO_EVENT));
363//            PORT_WRITE(out_RETIRE_EVENT_FLUSH [i][j], flush);
364//            PORT_WRITE(out_RETIRE_EVENT_STOP  [i][j], reg_EVENT_STOP [i][j]);
365              PORT_WRITE(out_RETIRE_EVENT_STOP  [i][j], true);
366            }
367      }
368
369      for (uint32_t i=0; i<_param->_nb_inst_reexecute; ++i)
370        PORT_WRITE(out_REEXECUTE_VAL[i], internal_REEXECUTE_VAL [i]);
371      for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
372        PORT_WRITE(out_BRANCH_COMPLETE_VAL [i], internal_BRANCH_COMPLETE_VAL [i]);
373      PORT_WRITE(out_UPDATE_VAL, internal_UPDATE_VAL);
374       
375    log_end(Commit_unit,FUNCTION);
376  };
377
378}; // end namespace commit_unit
379}; // end namespace ooo_engine
380}; // end namespace multi_ooo_engine
381}; // end namespace core
382}; // end namespace behavioural
383}; // end namespace morpheo             
384#endif
Note: See TracBrowser for help on using the repository browser.