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

Last change on this file since 122 was 122, checked in by rosiere, 15 years ago

Modif for performance :
1) Load Store Unit : store send request to valid exeception
2) Commit_unit : retire can bypass store
3) Commit_unit : add stat to manage store instruction
4) Load Store Unit and Load Store Pointer Manager : add store_queue_ptr_read
5) Fix lot of bug

  • Property svn:keywords set to Id
File size: 62.3 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Commit_unit_transition.cpp 122 2009-06-03 08: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#include "Behavioural/include/Simulation.h"
11
12namespace morpheo                    {
13namespace behavioural {
14namespace core {
15namespace multi_ooo_engine {
16namespace ooo_engine {
17namespace commit_unit {
18 
19#undef  FUNCTION
20#define FUNCTION "Commit_unit::transition"
21  void Commit_unit::transition (void)
22  {
23    log_begin(Commit_unit,FUNCTION);
24    log_function(Commit_unit,FUNCTION,_name.c_str());
25
26    if (PORT_READ(in_NRESET) == 0)
27      {
28        // Clear all bank
29        for (uint32_t i=0; i<_param->_nb_bank; ++i)
30          {
31            while(not _rob[i].empty())
32              {
33                delete _rob[i].front();
34                _rob[i].pop_front();
35              }
36            reg_BANK_PTR [i] = 0;
37          }
38
39        // Reset pointer
40        reg_NUM_BANK_HEAD = 0;
41        reg_NUM_BANK_TAIL = 0;
42        reg_NUM_PTR_TAIL  = 0;
43
44        // Reset counter
45        for (uint32_t i=0; i<_param->_nb_front_end; i++)
46          for (uint32_t j=0; j<_param->_nb_context [i]; j++)
47            {
48              _nb_cycle_idle            [i][j] = 0;
49
50              reg_NB_INST_COMMIT_ALL    [i][j] = 0;
51              reg_NB_INST_COMMIT_MEM    [i][j] = 0;
52                                       
53              reg_EVENT_STATE           [i][j] = COMMIT_EVENT_STATE_NO_EVENT;
54//            reg_EVENT_FLUSH           [i][j] = false;
55              reg_EVENT_STOP            [i][j] = false;
56              reg_EVENT_LAST            [i][j] = false;
57
58//            reg_PC_PREVIOUS           [i][j] = (0x100-4)>>2;
59              reg_PC_CURRENT            [i][j] = (0x100  )>>2;
60              reg_PC_CURRENT_IS_DS      [i][j] = 0;
61              reg_PC_CURRENT_IS_DS_TAKE [i][j] = 0;
62              reg_PC_NEXT               [i][j] = (0x100+4)>>2;
63            }
64
65        // Reset priority algorithm
66        _priority_insert->reset();
67      }
68    else
69      {
70        // Increase number idle cycle
71        for (uint32_t i=0; i<_param->_nb_front_end; i++)
72          for (uint32_t j=0; j<_param->_nb_context [i]; j++)
73            _nb_cycle_idle [i][j] ++;
74
75        // Compute next priority
76        _priority_insert->transition();
77
78        // ===================================================================
79        // =====[ GARBAGE COLLECTOR ]=========================================
80        // ===================================================================
81        for (uint32_t i=0; i<_param->_nb_front_end; i++)
82          for (uint32_t j=0; j<_param->_nb_context [i]; j++)
83            {
84              // Test if can_restart : (can_restart is to signal at the state than the decod_queue is empty)
85              //   *     no previous can_restart (trap for one)
86              //   * and decod_queue is empty
87              //   * and have an event or have a futur event
88              if (not reg_EVENT_CAN_RESTART [i][j] and
89                   (PORT_READ(in_NB_INST_DECOD_ALL [i][j]) == 0) and
90                   (reg_EVENT_STOP [i][j] or (reg_EVENT_STATE [i][j] != COMMIT_EVENT_STATE_NO_EVENT)))
91                reg_EVENT_CAN_RESTART [i][j] = true;
92
93              // Test event state
94              switch (reg_EVENT_STATE [i][j])
95                {
96                case COMMIT_EVENT_STATE_EVENT    : 
97                  {
98                    // Have an event, test if all composant have ack
99                    if (internal_RETIRE_EVENT_VAL [i][j] and in_RETIRE_EVENT_ACK [i][j])
100                      {
101                        // A minor optimisation : test if wait_decod is previously empty.
102                        if (not reg_EVENT_CAN_RESTART [i][j])
103                          reg_EVENT_STATE [i][j] = COMMIT_EVENT_STATE_WAIT_DECOD;
104                        else
105                          reg_EVENT_STATE [i][j] = COMMIT_EVENT_STATE_WAIT_END; 
106                      }
107                   
108                    break;
109                  }
110                case COMMIT_EVENT_STATE_WAIT_DECOD : 
111                  {
112                    // Wait flush of decod_queue.
113                    // Test if can restart now
114                    if (reg_EVENT_CAN_RESTART [i][j])
115                      {
116                        //reg_EVENT_FLUSH [i][j] = false;
117
118                        // A minor optimisation : test if the last element is already retire
119                        if (not reg_EVENT_LAST [i][j])
120                          reg_EVENT_STATE [i][j] = COMMIT_EVENT_STATE_WAIT_END;
121                        else
122                          reg_EVENT_STATE [i][j] = COMMIT_EVENT_STATE_END; 
123                      }
124                    break;
125                  }
126                case COMMIT_EVENT_STATE_WAIT_END : 
127                  {
128                    // Wait the flush of Re Order Buffer.
129                    // Test if the last element is retire
130                    if (reg_EVENT_LAST [i][j])
131                      reg_EVENT_STATE [i][j] = COMMIT_EVENT_STATE_END ; 
132                   
133                    break;
134                  }
135                case COMMIT_EVENT_STATE_END      :
136                  {
137                    // Just one cycle
138                   
139                    // flush of re order buffer is finish
140                    reg_EVENT_STATE [i][j] = COMMIT_EVENT_STATE_NO_EVENT;
141                    reg_EVENT_LAST  [i][j] = false;
142                    break;
143                  }
144                  //case COMMIT_EVENT_STATE_NO_EVENT :
145                default : break;
146                }
147            }
148
149        // ===================================================================
150        // =====[ INSERT ]====================================================
151        // ===================================================================
152        {
153          // variable to count instruction insert
154          uint32_t nb_insert = 0;
155
156          for (uint32_t i=0; i<_param->_nb_bank; i++)
157            {
158              // compute first bank number
159              uint32_t num_bank = (reg_NUM_BANK_TAIL+i)%_param->_nb_bank;
160             
161              if (internal_BANK_INSERT_VAL [num_bank])
162                {
163                  // get rename unit source and instruction.
164                  uint32_t x = internal_BANK_INSERT_NUM_RENAME_UNIT [num_bank];
165                  uint32_t y = internal_BANK_INSERT_NUM_INST        [num_bank];
166                 
167                  // Test if an instruction is valid
168                  // (all in_order insert combinatory is in rename_unit )
169                  if (PORT_READ(in_INSERT_VAL [x][y]))
170                    {
171                      log_printf(TRACE,Commit_unit,FUNCTION,"  * INSERT            [%d][%d]",x,y);
172                     
173                      // get information
174                      Tcontext_t   front_end_id = (_param->_have_port_front_end_id)?PORT_READ(in_INSERT_FRONT_END_ID [x][y]):0;
175                      Tcontext_t   context_id   = (_param->_have_port_context_id  )?PORT_READ(in_INSERT_CONTEXT_ID   [x][y]):0;
176                      Ttype_t      type         = PORT_READ(in_INSERT_TYPE         [x][y]);
177                      Toperation_t operation    = PORT_READ(in_INSERT_OPERATION    [x][y]);
178                      bool         is_store     = is_operation_memory_store(operation);
179                     
180                      Texception_t exception    = PORT_READ(in_INSERT_EXCEPTION    [x][y]);
181                      Tcontrol_t   no_execute   = PORT_READ(in_INSERT_NO_EXECUTE   [x][y]);
182                     
183                      log_printf(TRACE,Commit_unit,FUNCTION,"    * front_end_id   : %d",front_end_id);
184                      log_printf(TRACE,Commit_unit,FUNCTION,"    * context_id     : %d",context_id);
185                      log_printf(TRACE,Commit_unit,FUNCTION,"    * type           : %s",toString(type).c_str());
186                      log_printf(TRACE,Commit_unit,FUNCTION,"    * operation      : %d",operation );
187                      log_printf(TRACE,Commit_unit,FUNCTION,"    * exception      : %d",exception );
188                     
189                      // Create new entry and write information
190                      entry_t * entry = new entry_t;
191                      uint32_t  ptr   = reg_BANK_PTR [num_bank];
192
193                      entry->ptr                     = ptr;
194                      entry->front_end_id            = front_end_id;
195                      entry->context_id              = context_id  ;
196                      entry->rename_unit_id          = x;
197                      entry->depth                   = (_param->_have_port_depth)?PORT_READ(in_INSERT_DEPTH [x][y]):0;
198                      entry->type                    = type;
199                      entry->operation               = operation;
200                      entry->is_delay_slot           = PORT_READ(in_INSERT_IS_DELAY_SLOT         [x][y]);
201//                    entry->address                 = PORT_READ(in_INSERT_ADDRESS               [x][y]);
202                      entry->exception               = exception;
203                      entry->exception_use           = PORT_READ(in_INSERT_EXCEPTION_USE         [x][y]);
204                      entry->use_store_queue         = (type == TYPE_MEMORY) and (    is_store) and (not no_execute);
205                      entry->use_load_queue          = (type == TYPE_MEMORY) and (not is_store) and (not no_execute);
206                      entry->store_queue_ptr_write   = PORT_READ(in_INSERT_STORE_QUEUE_PTR_WRITE [x][y]);
207                      entry->load_queue_ptr_write    = (_param->_have_port_load_queue_ptr)?PORT_READ(in_INSERT_LOAD_QUEUE_PTR_WRITE [x][y]):0;
208#ifdef DEBUG       
209                      entry->read_ra                 = PORT_READ(in_INSERT_READ_RA               [x][y]);
210                      entry->num_reg_ra_log          = PORT_READ(in_INSERT_NUM_REG_RA_LOG        [x][y]);
211                      entry->num_reg_ra_phy          = PORT_READ(in_INSERT_NUM_REG_RA_PHY        [x][y]);
212                      entry->read_rb                 = PORT_READ(in_INSERT_READ_RB               [x][y]);
213                      entry->num_reg_rb_log          = PORT_READ(in_INSERT_NUM_REG_RB_LOG        [x][y]);
214                      entry->num_reg_rb_phy          = PORT_READ(in_INSERT_NUM_REG_RB_PHY        [x][y]);
215                      entry->read_rc                 = PORT_READ(in_INSERT_READ_RC               [x][y]);
216                      entry->num_reg_rc_log          = PORT_READ(in_INSERT_NUM_REG_RC_LOG        [x][y]);
217                      entry->num_reg_rc_phy          = PORT_READ(in_INSERT_NUM_REG_RC_PHY        [x][y]);
218#endif               
219                      entry->write_rd                = PORT_READ(in_INSERT_WRITE_RD              [x][y]);
220                      entry->num_reg_rd_log          = PORT_READ(in_INSERT_NUM_REG_RD_LOG        [x][y]);
221                      entry->num_reg_rd_phy_old      = PORT_READ(in_INSERT_NUM_REG_RD_PHY_OLD    [x][y]);
222                      entry->num_reg_rd_phy_new      = PORT_READ(in_INSERT_NUM_REG_RD_PHY_NEW    [x][y]);
223                      entry->write_re                = PORT_READ(in_INSERT_WRITE_RE              [x][y]);
224                      entry->num_reg_re_log          = PORT_READ(in_INSERT_NUM_REG_RE_LOG        [x][y]);
225                      entry->num_reg_re_phy_old      = PORT_READ(in_INSERT_NUM_REG_RE_PHY_OLD    [x][y]);
226                      entry->num_reg_re_phy_new      = PORT_READ(in_INSERT_NUM_REG_RE_PHY_NEW    [x][y]);
227                      entry->no_sequence             = type == TYPE_BRANCH;
228                      entry->speculative             = true;
229#ifdef DEBUG       
230                      entry->address                 = PORT_READ(in_INSERT_ADDRESS               [x][y]);
231#endif               
232                      entry->address_next            = PORT_READ(in_INSERT_ADDRESS_NEXT          [x][y]);
233#ifdef DEBUG       
234                      entry->cycle_rob_in            = simulation_cycle();
235                      entry->cycle_commit            = simulation_cycle();
236#endif     
237           
238                      // Test if exception :
239                      //  * yes : no execute instruction, wait ROB Head
240                      //  * no  : test if no_execute (== instruction is flushed)
241                      //          else test type
242                      //            * BRANCH : l.j   -> branch is ended
243                      //                       other -> wait the execution end of branchment
244                      //            * MEMORY : store -> wait store is at head of ROB
245                      //                       other -> wait end of instruction
246                      //            * OTHER
247           
248                      {
249                        if (exception == EXCEPTION_NONE)
250                          {
251                            // no_execute : l.j, l.nop, l.rfe
252                           
253                            log_printf(TRACE,Commit_unit,FUNCTION,"    * no_execute     : %d",no_execute);
254                           
255                            switch (type)
256                              {
257                              case TYPE_BRANCH : {entry->state=(no_execute==1)?ROB_BRANCH_COMPLETE:ROB_BRANCH_WAIT_END  ; break;}
258                              case TYPE_MEMORY : {entry->state=(no_execute==1)?ROB_END_OK_SPECULATIVE:(entry->state=(is_store  ==1)?ROB_STORE_WAIT_END_OK:ROB_OTHER_WAIT_END); break;}
259                              default          : {entry->state=(no_execute==1)?ROB_END_OK_SPECULATIVE:ROB_OTHER_WAIT_END; break;}
260                              }
261                          }
262                        else
263                          {
264                            // Have an exception : wait head of ROB
265                            // in_INSERT_NO_EXECUTE [x][y] : l.sys, l.trap
266                           
267                            entry->state = ROB_END_EXCEPTION_WAIT_HEAD;
268                          }
269                      }
270
271#ifdef STATISTICS
272                      if (usage_is_set(_usage,USE_STATISTICS))
273                        (*_stat_nb_inst_insert [x]) ++;
274#endif
275                   
276                      // Push entry in rob
277                      _rob[num_bank].push_back(entry);
278                     
279                      // Update counter and pointer
280                      reg_NB_INST_COMMIT_ALL [front_end_id][context_id] ++;
281                      if (type == TYPE_MEMORY)
282                        reg_NB_INST_COMMIT_MEM [front_end_id][context_id] ++;
283                     
284
285                      // flush = present event or future event.
286                      //  * present event = don't can restart
287
288//                       bool flush = reg_EVENT_FLUSH [front_end_id][context_id];
289
290//                       bool flush = (((reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_EVENT) or
291//                                      (reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_WAIT_DECOD)) or
292//                                     (reg_EVENT_STOP [front_end_id][context_id]));
293                     
294                      // New instruction from decod_queue. Flush if :
295                      //     * future event (instruction don't need execute because they are a previous event (miss load/branch or exception))
296                      //     * or present_event
297                      //   * and not can_restart (previous empty decod queue), because between the event_stop (branch_complete) and the state event (miss in head), many cycle is occured.
298                      bool flush = ((// present event
299                                     ((reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_EVENT) or
300                                      (reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_WAIT_DECOD)) or
301                                     // futur event
302                                     reg_EVENT_STOP [front_end_id][context_id])
303                                    // can't restart
304                                    and not reg_EVENT_CAN_RESTART[front_end_id][context_id]
305                                    );
306
307                      if (flush)
308                        {
309                          // A new invalid instruction is push in rob -> new last instruction
310                          reg_EVENT_LAST          [front_end_id][context_id] = false;
311                          reg_EVENT_LAST_NUM_BANK [front_end_id][context_id] = num_bank;
312                          reg_EVENT_LAST_NUM_PTR  [front_end_id][context_id] = ptr;
313                        }
314                     
315                      // Update pointer
316                      reg_NUM_PTR_TAIL  = ptr;
317                      reg_BANK_PTR [num_bank]  = (reg_BANK_PTR [num_bank]+1)%_param->_size_bank;
318                      nb_insert ++;
319                    }
320                }
321            }
322          // Update pointer
323          reg_NUM_BANK_TAIL = (reg_NUM_BANK_TAIL+nb_insert)%_param->_nb_bank;
324        }
325
326        // ===================================================================
327        // =====[ COMMIT ]====================================================
328        // ===================================================================
329
330#ifdef STATISTICS
331        if (usage_is_set(_usage,USE_STATISTICS))
332          (*_stat_nb_inst_commit_conflit_access) += internal_BANK_COMMIT_CONFLIT_ACCESS;
333#endif
334
335        // For each commit instruction ...
336        for (uint32_t i=0; i<_param->_nb_bank; i++)
337          for (uint32_t j=0; j<_param->_nb_bank_access_commit; j++)
338            // ... test if an instruction have finish this execution
339            if (internal_BANK_COMMIT_VAL [i][j])
340              {
341                // An instruction is executed -> Change state of this instruction
342
343                // Get information
344                uint32_t x = internal_BANK_COMMIT_NUM_INST [i][j];
345
346                // Test if instruction is valid and is enable
347                // (can be disable if this instruction is reexecute)
348                if (PORT_READ(in_COMMIT_VAL [x]) and PORT_READ(in_COMMIT_WEN [x]))
349                  {
350                    log_printf(TRACE,Commit_unit,FUNCTION,"  * COMMIT            [%d]",x);
351
352#ifdef STATISTICS
353                    if (usage_is_set(_usage,USE_STATISTICS))
354                      (*_stat_nb_inst_commit) ++;
355#endif
356
357                    log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank   : %d",i);
358
359                    // find the good entry !!!
360                    entry_t *       entry        = internal_BANK_COMMIT_ENTRY [i][j];
361                                                 
362                  //Toperation_t    operation    = PORT_READ(in_COMMIT_OPERATION   [x]);
363                    Ttype_t         type         = entry->type;
364                    Tcontrol_t      no_sequence  = PORT_READ(in_COMMIT_NO_SEQUENCE [x]);
365
366#if 0
367                    if ((type == TYPE_MEMORY) and no_sequence)
368                      continue;
369#endif             
370
371                    Texception_t    exception    = PORT_READ(in_COMMIT_EXCEPTION   [x]);
372
373                    rob_state_t     state        = entry->state;
374                    Tcontext_t      front_end_id = entry->front_end_id;
375                    Tcontext_t      context_id   = entry->context_id;
376
377                    // change state : test exception_use
378                   
379                    bool have_exception        = false;
380                    bool have_miss_speculation = false;
381
382                    // Test if have an exception ...
383                    if (exception != EXCEPTION_NONE)
384                      {
385                        // Test if the instruction is a load and is a miss speculation
386                        // (load is commit, but they have an dependence with a previous store -> need restart pipeline)
387
388                        have_miss_speculation  = (exception == EXCEPTION_MEMORY_MISS_SPECULATION);
389
390                        //  * Test if the exception generated can be trap by this exception
391                        switch (entry->exception_use)
392                          {
393                            // Have overflow exception if bit overflow enable is set.
394                          case  EXCEPTION_USE_RANGE                    : {have_exception = ((exception == EXCEPTION_RANGE) and PORT_READ(in_SPR_READ_SR_OVE[front_end_id][context_id])); break;}
395                          case  EXCEPTION_USE_MEMORY_WITH_ALIGNMENT    : {have_exception = ((exception == EXCEPTION_BUS_ERROR) or
396                                                                                            (exception == EXCEPTION_DATA_TLB ) or
397                                                                                            (exception == EXCEPTION_DATA_PAGE) or
398                                                                                            (exception == EXCEPTION_ALIGNMENT)); break;};
399                          case  EXCEPTION_USE_MEMORY_WITHOUT_ALIGNMENT : {have_exception = ((exception == EXCEPTION_BUS_ERROR) or
400                                                                                            (exception == EXCEPTION_DATA_TLB ) or
401                                                                                            (exception == EXCEPTION_DATA_PAGE)); break;};
402                          case  EXCEPTION_USE_CUSTOM_0                 : {have_exception = (exception == EXCEPTION_CUSTOM_0); break;}; 
403                          case  EXCEPTION_USE_CUSTOM_1                 : {have_exception = (exception == EXCEPTION_CUSTOM_1); break;}; 
404                          case  EXCEPTION_USE_CUSTOM_2                 : {have_exception = (exception == EXCEPTION_CUSTOM_2); break;}; 
405                          case  EXCEPTION_USE_CUSTOM_3                 : {have_exception = (exception == EXCEPTION_CUSTOM_3); break;}; 
406                          case  EXCEPTION_USE_CUSTOM_4                 : {have_exception = (exception == EXCEPTION_CUSTOM_4); break;}; 
407                          case  EXCEPTION_USE_CUSTOM_5                 : {have_exception = (exception == EXCEPTION_CUSTOM_5); break;}; 
408                          case  EXCEPTION_USE_CUSTOM_6                 : {have_exception = (exception == EXCEPTION_CUSTOM_6); break;}; 
409                            // Case already manage (decod stage -> in insert in ROB)
410                          case  EXCEPTION_USE_TRAP                     : {have_exception = false; exception = EXCEPTION_NONE; break;};
411                          case  EXCEPTION_USE_NONE                     : {have_exception = false; exception = EXCEPTION_NONE; break;}; 
412                          case  EXCEPTION_USE_ILLEGAL_INSTRUCTION      : {have_exception = false; exception = EXCEPTION_NONE; break;};
413                          case  EXCEPTION_USE_SYSCALL                  : {have_exception = false; exception = EXCEPTION_NONE; break;};
414                          default :
415                            {
416                              throw ERRORMORPHEO(FUNCTION,_("Commit : invalid exception_use.\n"));
417                              break;
418                            }
419                          }
420                      }
421                   
422                    // Next state depends of previous state
423                    switch (state)
424                      {
425                        // Branch : if no exception, the branchement can be completed
426                      case ROB_BRANCH_WAIT_END : 
427                        {
428                          if (not have_exception)
429                            state = ROB_BRANCH_COMPLETE;
430                          else
431                            state = ROB_END_EXCEPTION_WAIT_HEAD;
432                          break;
433                        }
434                        // Previous event -> set state as execute
435                      case ROB_STORE_KO_WAIT_END :
436                      case ROB_EVENT_WAIT_END  : 
437                        {
438                          state = ROB_END_KO_SPECULATIVE; 
439                          break;
440                        }
441                        // No previous event - Load and other instruction
442                      case ROB_STORE_OK_WAIT_END :
443                      case ROB_OTHER_WAIT_END  : 
444                        {
445                          if (not have_exception)
446                            {
447                              if (not have_miss_speculation)
448                                state = ROB_END_OK_SPECULATIVE;
449                              else
450                                state = ROB_END_LOAD_MISS_SPECULATIVE; 
451                            }
452                          else
453                            state = ROB_END_EXCEPTION_WAIT_HEAD;
454                          break;
455                        }
456                      case ROB_STORE_WAIT_END_OK :
457                        {
458                          if (not have_exception)
459                            state = ROB_STORE_OK;
460                          else
461                            state = ROB_STORE_EVENT;
462                          break;
463                        }
464                      case ROB_STORE_WAIT_END_KO :
465                        {
466//                        if (not have_exception)
467                            state = ROB_STORE_KO;
468//                        else
469//                             state = ROB_END_EXCEPTION_WAIT_HEAD;
470                          break;
471                        }
472
473
474                      default :
475                        {
476                          throw ERRORMORPHEO(FUNCTION,toString(_("Commit [%d] : Bank [%d][%d], invalid state value (%s).\n"),x,i,j,toString(state).c_str()));
477                          break;
478                        }
479                      }
480
481                    // Commit an instruction ...
482                    // Test if have an event (miss_speculation or exception) and not manage a previous event
483                    // if yes, this instruction would modify state machine. Also stop Re Order Buffer
484
485//                  bool flush = reg_EVENT_FLUSH [entry->front_end_id][entry->context_id];
486                    bool flush = ((reg_EVENT_STATE [entry->front_end_id][entry->context_id] == COMMIT_EVENT_STATE_EVENT) or
487                                  (reg_EVENT_STATE [entry->front_end_id][entry->context_id] == COMMIT_EVENT_STATE_WAIT_DECOD) or
488                                  (reg_EVENT_STATE [entry->front_end_id][entry->context_id] == COMMIT_EVENT_STATE_WAIT_END));
489                   
490                    if ((have_exception or have_miss_speculation) and (not flush))
491                      {
492                        uint32_t packet = ((entry->ptr << _param->_shift_num_slot) | i);
493                       
494                        // test have a previous event detected (event_stop = 1)
495                        // if yes, test if the actual event if "before (in order)" that the previous event
496                        if (reg_EVENT_STOP [entry->front_end_id][entry->context_id])
497                          {
498                            // Compare packet_id (by construction instruction is insert in order by increase packet_id)
499
500                            uint32_t _top = ((_rob[ reg_NUM_BANK_HEAD].front()->ptr << _param->_shift_num_slot) | reg_NUM_BANK_HEAD);
501                            uint32_t _old = reg_EVENT_PACKET [entry->front_end_id][entry->context_id];
502                            uint32_t _new = packet;
503                            if (_old < _top) _old = _old+_param->_size_queue;
504                            if (_new < _top) _new = _new+_param->_size_queue;
505                            if (_new < _old) reg_EVENT_PACKET [entry->front_end_id][entry->context_id] = packet;
506                          }
507                        else
508                          reg_EVENT_PACKET [entry->front_end_id][entry->context_id] = packet;
509                       
510                        // have an error, stop issue instruction
511                        reg_EVENT_STOP          [entry->front_end_id][entry->context_id] = true;
512//                         reg_EVENT_NUM_BANK      [entry->front_end_id][entry->context_id] = i;
513//                         reg_EVENT_NUM_PTR       [entry->front_end_id][entry->context_id] = entry->ptr;
514
515//                      reg_EVENT_CAN_RESTART   [entry->front_end_id][entry->context_id] = false;
516                        reg_EVENT_LAST_NUM_BANK [entry->front_end_id][entry->context_id] = ((reg_NUM_BANK_TAIL==0)?_param->_nb_bank:reg_NUM_BANK_TAIL)-1;
517                        reg_EVENT_LAST_NUM_PTR  [entry->front_end_id][entry->context_id] = reg_NUM_PTR_TAIL;
518                      }
519                   
520                    // Update Re Order Buffer
521                    entry->state        = state;
522                    entry->exception    = exception;
523                    entry->flags        = PORT_READ(in_COMMIT_FLAGS       [x]);
524                    entry->no_sequence  = no_sequence;
525                    // jalr, jr : address_dest is in register
526                    if ((       type      == TYPE_BRANCH) and
527                        (entry->operation == OPERATION_BRANCH_L_JALR) and
528                        (entry->read_rb))
529                    entry->address_next = PORT_READ(in_COMMIT_ADDRESS     [x]);
530
531#ifdef DEBUG
532                    entry->load_data               = PORT_READ(in_COMMIT_ADDRESS [x]);
533                    entry->cycle_commit            = simulation_cycle();
534#endif
535                  }
536              }
537
538        // ===================================================================
539        // =====[ RETIRE ]====================================================
540        // ===================================================================
541        for (uint32_t i=0; i<_param->_nb_bank; i++)
542          {
543            // Compute bank number
544            uint32_t num_bank = (internal_BANK_RETIRE_HEAD+i)%_param->_nb_bank;
545           
546            // Test if have an request
547            if (internal_BANK_RETIRE_VAL [num_bank])
548              {
549                // Take num instruction
550                uint32_t x = internal_BANK_RETIRE_NUM_RENAME_UNIT [num_bank];
551                uint32_t y = internal_BANK_RETIRE_NUM_INST        [num_bank];
552               
553                log_printf(TRACE,Commit_unit,FUNCTION,"  * RETIRE            [%d][%d]",x,y);
554                log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank     : %d",num_bank     );
555               
556#ifdef DEBUG_TEST
557                if (not PORT_READ(in_RETIRE_ACK [x][y]))
558                  throw ERRORMORPHEO(FUNCTION,_("Retire : retire_ack must be set.\n"));
559#endif
560
561
562#ifdef STATISTICS
563            if (usage_is_set(_usage,USE_STATISTICS))
564              (*_stat_nb_inst_retire [x]) ++;
565               
566#endif
567               
568                // Read information
569                entry_t *   entry        =  _rob [num_bank].front();
570
571                entry->state_old = entry->state;
572                entry->state     = ROB_END;
573              }
574          }
575
576        for (uint32_t i=0; i<_param->_nb_bank; i++)
577          {
578            // Compute bank number
579            bool      can_continue = false;
580            uint32_t  num_bank = reg_NUM_BANK_HEAD;
581           
582            if (not _rob [num_bank].empty ())
583              {
584                entry_t * entry = _rob [num_bank].front();
585               
586                if (entry->state == ROB_END)
587                  {
588                    log_printf(TRACE,Commit_unit,FUNCTION,"  * RETIRE_ROB [%d]",num_bank);
589           
590                    can_continue = true;
591
592                    Tcontext_t  front_end_id = entry->front_end_id;
593                    Tcontext_t  context_id   = entry->context_id  ;
594                    uint32_t    num_thread   = _param->_translate_num_context_to_num_thread [front_end_id][context_id];
595                    rob_state_t state        = entry->state_old;
596                    Ttype_t     type         = entry->type        ;
597                    bool        retire_ok    = false;
598                    uint32_t    packet_id    = ((entry->ptr << _param->_shift_num_slot) | num_bank);
599                   
600                    log_printf(TRACE,Commit_unit,FUNCTION,"    * front_end_id : %d",front_end_id );
601                    log_printf(TRACE,Commit_unit,FUNCTION,"    * context_id   : %d",context_id   );
602                    log_printf(TRACE,Commit_unit,FUNCTION,"    * rob_ptr      : %d",packet_id    );
603                    log_printf(TRACE,Commit_unit,FUNCTION,"    * num_thread   : %d",num_thread   );
604                    log_printf(TRACE,Commit_unit,FUNCTION,"    * type         : %s",toString(type).c_str());
605                    log_printf(TRACE,Commit_unit,FUNCTION,"    * state        : %s",toString(state).c_str());
606                   
607                    // Test if the instruction is valid
608                    // (BRANCH_MISS = instruction branch is valid, but have make an invalid prediction)
609                    // (LOAD_MISS   = instruction load   is valid, but have make an invalid result)
610                    if ((state == ROB_END_OK         ) or
611//                      (state == ROB_END_KO         ) or
612                        (state == ROB_END_BRANCH_MISS) or
613                        (state == ROB_END_LOAD_MISS  )//  or
614//                      (state == ROB_END_MISS       ) or
615//                      (state == ROB_END_EXCEPTION  )
616                        )
617                      {
618                        log_printf(TRACE,Commit_unit,FUNCTION,"    * retire_ok");
619                   
620                        retire_ok = true;
621                   
622                        // Update PC information
623//                      reg_PC_PREVIOUS           [front_end_id][context_id] = reg_PC_CURRENT [front_end_id][context_id];
624                        reg_PC_CURRENT            [front_end_id][context_id] = reg_PC_NEXT    [front_end_id][context_id];
625                        reg_PC_CURRENT_IS_DS      [front_end_id][context_id] = type == TYPE_BRANCH;
626                        reg_PC_CURRENT_IS_DS_TAKE [front_end_id][context_id] = entry->no_sequence;
627                        reg_PC_NEXT               [front_end_id][context_id] = (entry->no_sequence)?(entry->address_next):(reg_PC_CURRENT [front_end_id][context_id]+1);
628                      }
629                   
630                    // Test if have an event
631                    if ((state == ROB_END_BRANCH_MISS) or
632                        (state == ROB_END_LOAD_MISS))
633                      {
634                          reg_EVENT_STATE         [front_end_id][context_id] = COMMIT_EVENT_STATE_EVENT;
635//                        reg_EVENT_FLUSH         [front_end_id][context_id] = true;
636                          reg_EVENT_STOP          [front_end_id][context_id] = false; // instruction flow can continue
637//                        reg_EVENT_CAN_RESTART   [front_end_id][context_id] = false;
638                          reg_EVENT_LAST          [front_end_id][context_id] = false;
639                          // it the head !
640                          reg_EVENT_PACKET        [front_end_id][context_id] = packet_id;
641                   
642                          // If event is an load_miss, many instruction can be inserted.
643                          // -> new last instruction
644                          if (state == ROB_END_LOAD_MISS)
645                            {
646                            reg_EVENT_CAN_RESTART   [front_end_id][context_id] = false;
647                           
648                            reg_EVENT_LAST_NUM_BANK [front_end_id][context_id] = ((reg_NUM_BANK_TAIL==0)?_param->_nb_bank:reg_NUM_BANK_TAIL)-1;
649                            reg_EVENT_LAST_NUM_PTR  [front_end_id][context_id] = reg_NUM_PTR_TAIL;
650                            }
651                        }
652                   
653                    // Test if this instruction is the last instruction of an event
654                    //   * need event
655                    //   * packet id = last packet id
656                    if ((reg_EVENT_STATE         [front_end_id][context_id] != COMMIT_EVENT_STATE_NO_EVENT) and
657                        (reg_EVENT_LAST_NUM_BANK [front_end_id][context_id] == num_bank            ) and
658                        (reg_EVENT_LAST_NUM_PTR  [front_end_id][context_id] == entry->ptr          ))
659                      reg_EVENT_LAST [front_end_id][context_id] = true;
660                   
661                    // Update nb_inst
662                    reg_NB_INST_COMMIT_ALL [front_end_id][context_id] --;
663                    if (type == TYPE_MEMORY)
664                    reg_NB_INST_COMMIT_MEM [front_end_id][context_id] --;
665                   
666                    // Update pointer
667                    reg_NUM_BANK_HEAD = (num_bank+1)%_param->_nb_bank;
668                   
669                    // Remove entry
670                    delete entry;
671                    _rob [num_bank].pop_front();
672                   
673                    // Reset watch dog timer because have transaction on retire interface
674                    _nb_cycle_idle [front_end_id][context_id] = 0;
675                   
676                    // Increase stop condition
677                    if (retire_ok)
678                      _simulation_nb_instruction_commited [num_thread] ++;
679
680#ifdef STATISTICS
681                    if (usage_is_set(_usage,USE_STATISTICS))
682                      {
683                        if (retire_ok)
684                          {
685                            (*_stat_nb_inst_retire_ok [num_thread]) ++;
686                            (*_stat_nb_inst_type      [type]      ) ++;
687                          }
688                        else
689                          (*_stat_nb_inst_retire_ko [num_thread]) ++;
690                      }
691#endif
692
693#if defined(DEBUG) and defined(DEBUG_Commit_unit) and (DEBUG_Commit_unit == true)
694                    {
695                      // log file
696                      instruction_log_file [num_thread] 
697                        << "[" << simulation_cycle() << "] "
698                        << std::hex
699                        << (entry->address<<2) << " (" << (entry->address) << ") "
700                        << std::dec
701                        << "[" << entry->cycle_rob_in << ", " << entry->cycle_commit << "] "
702                        << "{" << ((retire_ok)?"OK":"KO") << "} ";
703                     
704                      if ((type == TYPE_MEMORY) and  is_operation_memory_load(entry->operation))
705                        instruction_log_file [num_thread] << std::hex << entry->load_data << std::dec;
706                     
707                      instruction_log_file [num_thread] << std::endl;
708                    }
709#endif     
710                  }
711              }
712           
713            if (not can_continue)
714              break; // stop scan
715          }
716
717        // ===================================================================
718        // =====[ REEXECUTE ]=================================================
719        // ===================================================================
720        // Test if have an reexecute instruction (an store in head of rob)
721        for (uint32_t i=0; i<_param->_nb_inst_reexecute; ++i)
722          if (internal_REEXECUTE_VAL [i] and PORT_READ(in_REEXECUTE_ACK [i]))
723            {
724              log_printf(TRACE,Commit_unit,FUNCTION,"  * REEXECUTE         [%d]",i);
725             
726              uint32_t num_bank = internal_REEXECUTE_NUM_BANK [i];
727             
728              entry_t    * entry = _rob [num_bank].front();
729              rob_state_t  state = entry->state;
730             
731              // Change state
732              switch (state)
733                {
734                case ROB_STORE_OK    : {state = ROB_STORE_OK_WAIT_END; break; }
735                case ROB_STORE_KO    : {state = ROB_STORE_KO_WAIT_END; break; }
736                case ROB_STORE_EVENT : {state = ROB_EVENT_WAIT_END; break; }
737                default : {throw ERRORMORPHEO(FUNCTION,_("Reexecute : invalid state value.\n"));}
738                }
739             
740              entry->state = state;
741            }
742       
743        // ===================================================================
744        // =====[ BRANCH_COMPLETE ]===========================================
745        // ===================================================================
746        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
747          // Test if the prediction_unit have accept the branch complete transaction
748          if (internal_BRANCH_COMPLETE_VAL [i] and PORT_READ(in_BRANCH_COMPLETE_ACK [i]))
749            {
750              log_printf(TRACE,Commit_unit,FUNCTION,"  * BRANCH_COMPLETE   [%d]",i);
751
752              // Read information
753              uint32_t num_bank = internal_BRANCH_COMPLETE_NUM_BANK [i];
754             
755              entry_t   * entry = _rob [num_bank].front();
756
757#ifdef DEBUG_TEST
758              rob_state_t  state = entry->state;
759              if (state != ROB_BRANCH_COMPLETE)
760                throw ERRORMORPHEO(FUNCTION,_("Branch_complete : Invalid state value.\n"));
761#endif
762              Tcontrol_t miss = PORT_READ(in_BRANCH_COMPLETE_MISS_PREDICTION [i]);
763
764              log_printf(TRACE,Commit_unit,FUNCTION,"    * miss_prediction : %d",miss);
765             
766              entry->state = (miss)?ROB_END_BRANCH_MISS_SPECULATIVE:ROB_END_OK_SPECULATIVE;
767
768//            bool flush = reg_EVENT_FLUSH [entry->front_end_id][entry->context_id];
769
770              // Branch_complete can be execute if
771              //   * no present event
772              //   * futur event and most not speculative that the event
773
774              // Also, test if in this cycle, they have not an most recently event !!!
775              if (miss)
776                {
777                  uint32_t packet = ((entry->ptr << _param->_shift_num_slot) | num_bank);
778                     
779                  // test if this packet is before previous event
780                  if (reg_EVENT_STOP [entry->front_end_id][entry->context_id])
781                    {
782                      uint32_t _top = ((_rob[ reg_NUM_BANK_HEAD].front()->ptr << _param->_shift_num_slot) | reg_NUM_BANK_HEAD);
783                      uint32_t _old = reg_EVENT_PACKET [entry->front_end_id][entry->context_id];
784                      uint32_t _new = packet;
785                      if (_old < _top) _old = _old+_param->_size_queue;
786                      if (_new < _top) _new = _new+_param->_size_queue;
787                      if (_new < _old) reg_EVENT_PACKET [entry->front_end_id][entry->context_id] = packet;
788                    }
789                  else
790                    reg_EVENT_PACKET [entry->front_end_id][entry->context_id] = packet;
791
792                  // In all case, stop instruction flow
793                  reg_EVENT_STOP          [entry->front_end_id][entry->context_id] = true;
794//                   reg_EVENT_NUM_BANK      [entry->front_end_id][entry->context_id] = num_bank;
795//                   reg_EVENT_NUM_PTR       [entry->front_end_id][entry->context_id] = entry->ptr;
796
797                  reg_EVENT_CAN_RESTART   [entry->front_end_id][entry->context_id] = false;
798
799                  reg_EVENT_LAST_NUM_BANK [entry->front_end_id][entry->context_id] = ((reg_NUM_BANK_TAIL==0)?_param->_nb_bank:reg_NUM_BANK_TAIL)-1;
800                  reg_EVENT_LAST_NUM_PTR  [entry->front_end_id][entry->context_id] = reg_NUM_PTR_TAIL;
801                }
802            }
803
804        // ===================================================================
805        // =====[ UPDATE ]====================================================
806        // ===================================================================
807        // Update when exception or load_miss
808        if (internal_UPDATE_VAL and PORT_READ(in_UPDATE_ACK))
809          {
810            log_printf(TRACE,Commit_unit,FUNCTION,"  * UPDATE");
811
812            // Change state
813            entry_t * entry = _rob [internal_UPDATE_NUM_BANK].front();
814
815            switch (entry->state)
816              {
817//               case ROB_END_EXCEPTION_UPDATE :
818//                 {
819//                   entry->state = ROB_END_KO;
820//                   throw ERRORMORPHEO(FUNCTION,_("Moore : exception is not yet supported (Coming Soon).\n"));
821//                   break;
822//                 }
823              case ROB_END_LOAD_MISS_UPDATE :
824                {
825                  log_printf(TRACE,Commit_unit,FUNCTION,"    * ROB_END_LOAD_MISS_UPDATE");
826
827                  entry->state = ROB_END_LOAD_MISS;
828                  break;
829                }
830              default :
831                {
832                  throw ERRORMORPHEO(FUNCTION,_("Update : invalid state.\n"));
833                  break;
834                }
835              }
836          }
837
838        // ===================================================================
839        // =====[ EVENT ]=====================================================
840        // ===================================================================
841//         for (uint32_t i=0; i < _param->_nb_front_end; ++i)
842//           for (uint32_t j=0; j < _param->_nb_context[i]; ++j)
843//             if (PORT_READ(in_EVENT_VAL [i][j]) and internal_EVENT_ACK [i][j])
844//               {
845//                 log_printf(TRACE,Commit_unit,FUNCTION,"  * EVENT [%d][%d]",i,j);
846
847//                 reg_PC_CURRENT            [i][j] = PORT_READ(in_EVENT_ADDRESS      [i][j]);
848//                 reg_PC_CURRENT_IS_DS      [i][j] = PORT_READ(in_EVENT_IS_DS_TAKE   [i][j]); // ??
849//                 reg_PC_CURRENT_IS_DS_TAKE [i][j] = PORT_READ(in_EVENT_IS_DS_TAKE   [i][j]);
850//                 reg_PC_NEXT               [i][j] = PORT_READ(in_EVENT_ADDRESS_NEXT [i][j]);
851//                 // PORT_READ(in_EVENT_ADDRESS_NEXT_VAL [i][j]);
852//               }
853
854        // ===================================================================
855        // =====[ DEPTH - HEAD ]==============================================
856        // ===================================================================
857
858        {
859          bool EVENT_LAST [_param->_nb_front_end][_param->_max_nb_context];
860          for (uint32_t i=0; i<_param->_nb_front_end; i++)
861            for (uint32_t j=0; j<_param->_nb_context [i]; j++)
862              EVENT_LAST [i][j] = reg_EVENT_LAST [i][j];
863
864          // Read all instruction of all top bank
865          for (uint32_t i=0; i<_param->_nb_bank; i++)
866            {
867              uint32_t num_bank = (reg_NUM_BANK_HEAD+i)%_param->_nb_bank;
868             
869              // Test if have an instruction
870              if (not _rob[num_bank].empty())
871                {
872                  // Scan all instruction in windows and test if instruction is speculative
873                  entry_t    * entry        = _rob [num_bank].front();
874                 
875                  Tcontext_t   front_end_id = entry->front_end_id;
876                  Tcontext_t   context_id   = entry->context_id  ;
877                 
878                  // scan while last event instruction is not retire
879                  if (EVENT_LAST [front_end_id][context_id] == false)
880                    {
881                      // Read information
882                      rob_state_t  state        = entry->state;
883                      Tdepth_t     depth        = entry->depth;
884                     
885                      Tdepth_t     depth_min    = (_param->_have_port_depth)?PORT_READ(in_DEPTH_MIN[front_end_id][context_id]):0;
886                      Tdepth_t     depth_max    = (_param->_have_port_depth)?PORT_READ(in_DEPTH_MAX[front_end_id][context_id]):0;
887                      Tcontrol_t   depth_full   = PORT_READ(in_DEPTH_FULL [front_end_id][context_id]);
888                     
889                      // is a valid instruction ?
890                      // If DEPTH_CURRENT :
891                      // equal at     DEPTH_MIN            -> not speculative
892                      // not include ]DEPTH_MIN:DEPTH_MAX] -> previous branch miss
893                      //     include ]DEPTH_MIN:DEPTH_MAX] -> speculative
894                     
895                      // All case
896                      // ....... min ...X... max ....... OK
897                      // ....... min ....... max ...X... KO
898                      // ...X... min ....... max ....... KO
899                      // ....... max ....... min ...X... OK
900                      // ...X... max ....... min ....... OK
901                      // ....... max ...X... min ....... KO
902                     
903                      bool         flush         = ((reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_EVENT) or
904                                                    (reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_WAIT_DECOD) or
905                                                    (reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_WAIT_END));
906                      bool         speculative   = entry->speculative and not (depth == depth_min);
907                      Tcontrol_t   is_valid      = ((not speculative or
908                                                     (speculative and (depth_full or // all is valid
909                                                                       ((depth_min <= depth_max)? // test if depth is overflow
910                                                                        ((depth >= depth_min) and (depth <=depth_max)):
911                                                                        ((depth >= depth_min) or  (depth <=depth_max))))))
912                                                    and not flush); // no event
913                     
914                      //Tcontrol_t   is_valid      = ((depth == depth_min) and not flush);
915                     
916                      log_printf(TRACE,Commit_unit,FUNCTION,"  * HEAD              [%d] - %d",num_bank,((entry->ptr << _param->_shift_num_slot) | num_bank));
917                     
918                      log_printf(TRACE,Commit_unit,FUNCTION,"    * is_valid        : %d ((depth == depth_min) and not flush)",is_valid);
919                      log_printf(TRACE,Commit_unit,FUNCTION,"    * depth           : %d",depth    );
920                      log_printf(TRACE,Commit_unit,FUNCTION,"    * depth_min       : %d",depth_min);
921                      log_printf(TRACE,Commit_unit,FUNCTION,"    * depth_max       : %d",depth_max);
922                      log_printf(TRACE,Commit_unit,FUNCTION,"    * depth_full      : %d",depth_full);
923                      log_printf(TRACE,Commit_unit,FUNCTION,"    * speculative     : %d",speculative);
924                      log_printf(TRACE,Commit_unit,FUNCTION,"    * flush           : %d",flush);
925                   
926                      //------------------------------------------------------
927                      // test if instruction is miss speculative
928                      //------------------------------------------------------
929                      if (not is_valid)
930                        {
931                          // Change state
932                          switch (state)
933                            {
934                            case ROB_BRANCH_WAIT_END             : {state = ROB_EVENT_WAIT_END; break;}
935                            case ROB_BRANCH_COMPLETE             : {state = ROB_END_MISS      ; break;}
936                            case ROB_END_BRANCH_MISS             :
937                            case ROB_END_BRANCH_MISS_SPECULATIVE : {state = ROB_END_MISS      ; break;}
938                            case ROB_END_LOAD_MISS_UPDATE        :
939                            case ROB_END_LOAD_MISS               :
940                            case ROB_END_LOAD_MISS_SPECULATIVE   : {state = ROB_END_MISS      ; break;}
941                            case ROB_STORE_OK                    : {state = ROB_STORE_KO      ; break;}
942                            case ROB_STORE_WAIT_END_OK           : {state = ROB_STORE_WAIT_END_KO; break;}
943                            case ROB_STORE_OK_WAIT_END           : {state = ROB_STORE_KO_WAIT_END; break;}
944                            case ROB_OTHER_WAIT_END              : {state = ROB_EVENT_WAIT_END; break;}
945                            case ROB_END_OK                      :
946                            case ROB_END_OK_SPECULATIVE          : {state = ROB_END_MISS      ; break;}
947                            case ROB_END_KO                      :
948                            case ROB_END_KO_SPECULATIVE          : {state = ROB_END_MISS      ; break;}
949                            case ROB_END_EXCEPTION_UPDATE        :
950                            case ROB_END_EXCEPTION               :
951                            case ROB_END_EXCEPTION_WAIT_HEAD     : {state = ROB_END_MISS      ; break;}
952                             
953                              // don't change state -> wait
954                            case ROB_STORE_WAIT_END_KO           : {break;}
955                            case ROB_STORE_KO                    : {break;}
956                            case ROB_STORE_KO_WAIT_END           : {break;}
957                            case ROB_STORE_EVENT                 : {break;}
958                            case ROB_EVENT_WAIT_END              : {break;}
959                            case ROB_END_MISS                    : {break;}
960                            case ROB_END                         : {break;}
961                             
962                              // can't have miss speculation -> invalid state
963                            default                              : 
964                              {
965                                throw ERRORMORPHEO(FUNCTION,toString(_("Miss Speculation : Invalide state : %s.\n"),toString(state).c_str()));
966                                break;
967                              }
968                            }
969                        }
970                     
971                      //------------------------------------------------------
972                      // test if instruction is not speculative
973                      //------------------------------------------------------
974                      entry->speculative = speculative;
975//                    if (entry->depth == depth_min)
976                      // test if instruction is speculative (depth != depth_min)
977                      if (not speculative)
978                        {
979                          switch (state)
980                            {
981                            case ROB_END_OK_SPECULATIVE          : {state = ROB_END_OK                 ; break;}
982                            case ROB_END_KO_SPECULATIVE          : {state = ROB_END_KO                 ; break;}
983                            case ROB_END_BRANCH_MISS_SPECULATIVE : {state = ROB_END_BRANCH_MISS        ; break;}
984                            case ROB_END_LOAD_MISS_SPECULATIVE   : {state = ROB_END_LOAD_MISS_UPDATE   ; break;}
985                            default : {break;} // else, no change
986                            }
987                        }
988                   
989                      //------------------------------------------------------
990                      // test if instruction wait head and is the top of rob
991                      //------------------------------------------------------
992                      // TODO : retire OOO
993                      if (i == 0)
994                        {
995                          switch (state)
996                            {
997//                             case ROB_STORE_WAIT_HEAD_OK      : {state = ROB_STORE_HEAD_OK;        break;}
998                            case ROB_END_EXCEPTION_WAIT_HEAD : {state = ROB_END_EXCEPTION_UPDATE; break;}
999                            default : {break;} // else, no change
1000                            }
1001                        }
1002                   
1003                      // Write new state
1004                      entry->state = state;
1005                     
1006                      // Test if this instruction is the last of event
1007                      if ((reg_EVENT_STATE         [front_end_id][context_id] != COMMIT_EVENT_STATE_NO_EVENT) and
1008                          (reg_EVENT_LAST_NUM_BANK [front_end_id][context_id] == num_bank            ) and
1009                          (reg_EVENT_LAST_NUM_PTR  [front_end_id][context_id] == entry->ptr          ))
1010                        {
1011                          log_printf(TRACE,Commit_unit,FUNCTION,"  * Stop Scan !!!");
1012                         
1013                          EVENT_LAST [front_end_id][context_id] = true;
1014                        }
1015                    }
1016                }
1017            }
1018        }
1019
1020
1021
1022#ifdef STATISTICS
1023    for (uint32_t i=0; i<_param->_nb_bank; i++)
1024      if (usage_is_set(_usage,USE_STATISTICS))
1025        *(_stat_bank_nb_inst [i]) += _rob[i].size();
1026#endif
1027      }
1028
1029    // ===================================================================
1030    // =====[ OTHER ]=====================================================
1031    // ===================================================================
1032
1033#if (DEBUG >= DEBUG_TRACE) and (DEBUG_Commit_unit == true)
1034    {
1035      log_printf(TRACE,Commit_unit,FUNCTION,"  * Dump ROB (Re-Order-Buffer)");
1036      log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank_head : %d",reg_NUM_BANK_HEAD);
1037      log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank_tail : %d",reg_NUM_BANK_TAIL);
1038      log_printf(TRACE,Commit_unit,FUNCTION,"    * num_ptr_tail  : %d",reg_NUM_PTR_TAIL );
1039     
1040      for (uint32_t i=0; i<_param->_nb_front_end; i++)
1041        for (uint32_t j=0; j<_param->_nb_context [i]; j++)
1042          {
1043            log_printf(TRACE,Commit_unit,FUNCTION,"    * [%d][%d] - %d",i,j,_param->_translate_num_context_to_num_thread [i][j]);
1044            log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_STATE       : %s - %s",toString(reg_EVENT_STATE [i][j]).c_str(),toString(commit_event_state_to_event_state(reg_EVENT_STATE [i][j])).c_str());
1045//          log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_FLUSH       : %d",reg_EVENT_FLUSH [i][j]);
1046            log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_STOP        : %d",reg_EVENT_STOP  [i][j]);
1047//             log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT             : %d (bank %d, ptr %d)",((reg_EVENT_NUM_PTR [i][j] << _param->_shift_num_slot) | reg_EVENT_NUM_BANK [i][j]), reg_EVENT_NUM_BANK [i][j],reg_EVENT_NUM_PTR [i][j]);
1048            log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_CAN_RESTART : %d",reg_EVENT_CAN_RESTART [i][j]);
1049            log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_PACKET      : %d",reg_EVENT_PACKET[i][j]);
1050            log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_LAST        : %d",reg_EVENT_LAST [i][j]);
1051            log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_LAST        : %d (bank %d, ptr %d)",((reg_EVENT_LAST_NUM_PTR [i][j] << _param->_shift_num_slot) | reg_EVENT_LAST_NUM_BANK [i][j]), reg_EVENT_LAST_NUM_BANK [i][j],reg_EVENT_LAST_NUM_PTR [i][j]);
1052            log_printf(TRACE,Commit_unit,FUNCTION,"      * NB_INST_ALL       : %d",reg_NB_INST_COMMIT_ALL[i][j]);
1053            log_printf(TRACE,Commit_unit,FUNCTION,"      * NB_INST_MEM       : %d",reg_NB_INST_COMMIT_MEM[i][j]);
1054            log_printf(TRACE,Commit_unit,FUNCTION,"      * PC_CURRENT        : %.8x (%.8x) - %d %d",reg_PC_CURRENT [i][j],reg_PC_CURRENT [i][j]<<2, reg_PC_CURRENT_IS_DS [i][j], reg_PC_CURRENT_IS_DS_TAKE [i][j]);
1055            log_printf(TRACE,Commit_unit,FUNCTION,"      * PC_NEXT           : %.8x (%.8x)",reg_PC_NEXT [i][j],reg_PC_NEXT [i][j]<<2);
1056          }
1057
1058      std::list<entry_t*>::iterator iter [_param->_nb_bank];
1059      for (uint32_t i=0; i<_param->_nb_bank; i++)
1060        {
1061          uint32_t num_bank = (reg_NUM_BANK_HEAD+i)%_param->_nb_bank;
1062//           log_printf(TRACE,Commit_unit,FUNCTION,"      * Bank [%d] size : %d, ptr : %d",num_bank,(int)_rob[num_bank].size(), reg_BANK_PTR [i]);
1063
1064          iter [num_bank] = _rob[num_bank].begin();
1065        }
1066
1067      bool all_empty = false;
1068      while (not all_empty)
1069        {
1070          all_empty = true;
1071         
1072          for (uint32_t i=0; i<_param->_nb_bank; i++)
1073            {
1074              uint32_t num_bank = (reg_NUM_BANK_HEAD+i)%_param->_nb_bank;
1075     
1076              std::list<entry_t*>::iterator it = iter[num_bank];       
1077              if (it != _rob[num_bank].end())
1078                {
1079                  all_empty = false;
1080
1081                  log_printf(TRACE,Commit_unit,FUNCTION,"        [%.4d][%.4d] (%.4d) %.4d %.4d %.4d %.4d, %.3d %.3d, %.1d, %.1d %.4d, %.1d %.4d, %s",
1082                             num_bank                       ,
1083                             (*it)->ptr                     ,
1084                             (((*it)->ptr << _param->_shift_num_slot) | num_bank),
1085                             (*it)->front_end_id            ,
1086                             (*it)->context_id              ,
1087                             (*it)->rename_unit_id          ,
1088                             (*it)->depth                   ,
1089                             (*it)->type                    ,
1090                             (*it)->operation               ,
1091                             (*it)->is_delay_slot           ,
1092                             (*it)->use_store_queue         ,
1093                             (*it)->store_queue_ptr_write   ,
1094                             (*it)->use_load_queue          ,
1095                             (*it)->load_queue_ptr_write    ,
1096                             toString((*it)->state).c_str() );
1097                  log_printf(TRACE,Commit_unit,FUNCTION,"                     %.1d %.2d %.6d, %.1d %.2d %.6d, %.1d %.1d %.6d, %.1d %.2d %.6d %.6d, %.1d %.1d %.6d %.6d ",
1098                             (*it)->read_ra                 ,
1099                             (*it)->num_reg_ra_log          ,
1100                             (*it)->num_reg_ra_phy          ,
1101                             (*it)->read_rb                 ,
1102                             (*it)->num_reg_rb_log          ,
1103                             (*it)->num_reg_rb_phy          ,
1104                             (*it)->read_rc                 ,
1105                             (*it)->num_reg_rc_log          ,
1106                             (*it)->num_reg_rc_phy          ,
1107                             (*it)->write_rd                ,
1108                             (*it)->num_reg_rd_log          ,
1109                             (*it)->num_reg_rd_phy_old      ,
1110                             (*it)->num_reg_rd_phy_new      ,
1111                             (*it)->write_re                ,
1112                             (*it)->num_reg_re_log          ,
1113                             (*it)->num_reg_re_phy_old      ,
1114                             (*it)->num_reg_re_phy_new      );
1115                 
1116                  log_printf(TRACE,Commit_unit,FUNCTION,"                     %.2d %.2d %.1d %.1d %.1d - %.8x (%.8x) %.8x (%.8x)",
1117                             (*it)->exception_use ,
1118                             (*it)->exception     ,
1119                             (*it)->flags         ,
1120                             (*it)->no_sequence   ,
1121                             (*it)->speculative   ,
1122                             (*it)->address       ,
1123                             (*it)->address<<2    ,
1124                             (*it)->address_next  ,
1125                             (*it)->address_next<<2
1126                             );
1127                 
1128                  iter [num_bank] ++;
1129                }
1130            }
1131        }
1132    }
1133#endif
1134
1135#ifdef DEBUG_TEST
1136    {
1137      uint32_t x=reg_NUM_BANK_HEAD;
1138      if (not _rob[x].empty())
1139        {
1140          entry_t * entry = _rob [x].front();
1141
1142          if (false
1143//            or (entry->state == ROB_EMPTY                      )
1144//            or (entry->state == ROB_BRANCH_WAIT_END            )
1145//            or (entry->state == ROB_BRANCH_COMPLETE            )
1146//            or (entry->state == ROB_STORE_WAIT_HEAD_OK         )
1147//          //or (entry->state == ROB_STORE_WAIT_HEAD_KO         )
1148//            or (entry->state == ROB_STORE_HEAD_OK              )
1149//            or (entry->state == ROB_STORE_HEAD_KO              )
1150//            or (entry->state == ROB_OTHER_WAIT_END             )
1151//            or (entry->state == ROB_EVENT_WAIT_END             )
1152//            or (entry->state == ROB_END_OK_SPECULATIVE         )
1153              or (entry->state == ROB_END_OK                     )
1154//            or (entry->state == ROB_END_KO_SPECULATIVE         )
1155//            or (entry->state == ROB_END_KO                     )
1156//            or (entry->state == ROB_END_BRANCH_MISS_SPECULATIVE)
1157              or (entry->state == ROB_END_BRANCH_MISS            )
1158//            or (entry->state == ROB_END_LOAD_MISS_SPECULATIVE  )
1159//            or (entry->state == ROB_END_LOAD_MISS_UPDATE       )
1160              or (entry->state == ROB_END_LOAD_MISS              )
1161//            or (entry->state == ROB_END_MISS                   )
1162//            or (entry->state == ROB_END_EXCEPTION_WAIT_HEAD    )
1163//            or (entry->state == ROB_END_EXCEPTION_UPDATE       )
1164//            or (entry->state == ROB_END_EXCEPTION              )
1165              )
1166          if (entry->address != reg_PC_CURRENT[entry->front_end_id][entry->context_id])
1167            throw ERRORMORPHEO(FUNCTION,toString(_("Rob top address (0x%x) is different of reg_PC_CURRENT[%d][%d] (0x%x).\n"),
1168                                                 entry->address,
1169                                                 entry->front_end_id,
1170                                                 entry->context_id,
1171                                                 reg_PC_CURRENT[entry->front_end_id][entry->context_id]));
1172        }
1173    }
1174#endif
1175
1176#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
1177    end_cycle ();
1178#endif
1179
1180    // Stop Condition
1181    for (uint32_t i=0; i<_param->_nb_front_end; i++)
1182      for (uint32_t j=0; j<_param->_nb_context [i]; j++)
1183        if (_nb_cycle_idle [i][j] >= debug_idle_cycle)
1184          throw ERRORMORPHEO(FUNCTION,toString(_("Thread [%d] is idle since %.0f cycles.\n"),_param->_translate_num_context_to_num_thread[i][j],_nb_cycle_idle [i][j]));
1185
1186    log_end(Commit_unit,FUNCTION);
1187  };
1188
1189}; // end namespace commit_unit
1190}; // end namespace ooo_engine
1191}; // end namespace multi_ooo_engine
1192}; // end namespace core
1193
1194}; // end namespace behavioural
1195}; // end namespace morpheo             
1196#endif
Note: See TracBrowser for help on using the repository browser.