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

Last change on this file since 145 was 145, checked in by rosiere, 14 years ago

1) add test with SPECINT2K
2) new config of Selftest
3) modif RAT to support multiple depth_save ... but not finish (need fix Update Prediction Table)
4) add Function_pointer but need fix

  • Property svn:keywords set to Id
File size: 15.9 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Commit_unit_genMoore.cpp 145 2010-10-13 18:15:51Z 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->_front_end_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.