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

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

1) Fix performance
2) add auto generation to SPECINT2000
3) add reset in genMoore and genMealy

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