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

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

1) Commit_unit : remove read information of ROB

  • Property svn:keywords set to Id
File size: 41.6 KB
RevLine 
[88]1#ifdef SYSTEMC
2/*
3 * $Id: Commit_unit_transition.cpp 121 2009-05-27 10:13:56Z rosiere $
4 *
5 * [ Description ]
6 *
7 */
8
9#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Commit_unit/include/Commit_unit.h"
[110]10#include "Behavioural/include/Simulation.h"
[88]11
12namespace morpheo                    {
13namespace behavioural {
14namespace core {
15namespace multi_ooo_engine {
16namespace ooo_engine {
17namespace commit_unit {
18
19 
20#undef  FUNCTION
21#define FUNCTION "Commit_unit::transition"
22  void Commit_unit::transition (void)
23  {
24    log_begin(Commit_unit,FUNCTION);
25    log_function(Commit_unit,FUNCTION,_name.c_str());
26
27    if (PORT_READ(in_NRESET) == 0)
28      {
[100]29        // Clear all bank
[115]30        for (uint32_t i=0; i<_param->_nb_bank; ++i)
[88]31          {
[115]32            while(not _rob[i].empty())
33              {
34                delete _rob[i].front();
35                _rob[i].pop_front();
36              }
[88]37            reg_BANK_PTR [i] = 0;
38          }
39
[100]40        // Reset pointer
[88]41        reg_NUM_BANK_HEAD = 0;
42        reg_NUM_BANK_TAIL = 0;
43
[100]44        // Reset counter
[88]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            {
[109]48              _nb_cycle_idle            [i][j] = 0;
49
[104]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] = EVENT_STATE_NO_EVENT;
54              reg_EVENT_FLUSH           [i][j] = false;
[112]55              reg_EVENT_STOP            [i][j] = false;
[100]56
[104]57//            reg_PC_PREVIOUS           [i][j] = (0x100-4)>>2;
58              reg_PC_CURRENT            [i][j] = (0x100  )>>2;
59              reg_PC_CURRENT_IS_DS      [i][j] = 0;
60              reg_PC_CURRENT_IS_DS_TAKE [i][j] = 0;
[105]61              reg_PC_NEXT               [i][j] = (0x100+4)>>2;
[88]62            }
63
[100]64        // Reset priority algorithm
[88]65        _priority_insert->reset();
66      }
67    else
68      {
[109]69        // Increase number idle cycle
70        for (uint32_t i=0; i<_param->_nb_front_end; i++)
71          for (uint32_t j=0; j<_param->_nb_context [i]; j++)
72            _nb_cycle_idle [i][j] ++;
73
[100]74        // Compute next priority
[88]75        _priority_insert->transition();
76
77        // ===================================================================
[100]78        // =====[ GARBAGE COLLECTOR ]=========================================
79        // ===================================================================
80        for (uint32_t i=0; i<_param->_nb_front_end; i++)
81          for (uint32_t j=0; j<_param->_nb_context [i]; j++)
82            switch (reg_EVENT_STATE [i][j])
83              {
[104]84              case EVENT_STATE_EVENT    : 
85                {
86                  if (internal_RETIRE_EVENT_VAL [i][j] and in_RETIRE_EVENT_ACK [i][j])
87                    reg_EVENT_STATE [i][j] = EVENT_STATE_WAITEND ; 
88                  break;
89                }
90              case EVENT_STATE_WAITEND  : 
91                {
[108]92                  Tcounter_t nb_inst_all = PORT_READ(in_NB_INST_DECOD_ALL [i][j]) + reg_NB_INST_COMMIT_ALL [i][j];
93                  if (nb_inst_all == 0)
[104]94                    {
95                      reg_EVENT_STATE [i][j] = EVENT_STATE_END;
96                      reg_EVENT_FLUSH [i][j] = false;
[112]97                      //reg_EVENT_STOP  [i][j] = false;
[104]98                    }
99                  break;
100                }
101              case EVENT_STATE_END      :
102                {
103                  reg_EVENT_STATE [i][j] = EVENT_STATE_NO_EVENT;
104                  break;
105                }
[100]106//            case EVENT_STATE_NO_EVENT :
107              default : break;
108              }
109
110        // ===================================================================
[88]111        // =====[ INSERT ]====================================================
112        // ===================================================================
113        for (uint32_t i=0; i<_param->_nb_bank; i++)
114          if (internal_BANK_INSERT_VAL [i])
115            {
[100]116              // get rename unit source and instruction.
[88]117              uint32_t x = internal_BANK_INSERT_NUM_RENAME_UNIT [i];
118              uint32_t y = internal_BANK_INSERT_NUM_INST        [i];
119
120              if (PORT_READ(in_INSERT_VAL [x][y]))
121                {
122                  log_printf(TRACE,Commit_unit,FUNCTION,"  * INSERT            [%d][%d]",x,y);
123
[100]124                  // get information
[88]125                  Tcontext_t   front_end_id = (_param->_have_port_front_end_id)?PORT_READ(in_INSERT_FRONT_END_ID [x][y]):0;
126                  Tcontext_t   context_id   = (_param->_have_port_context_id  )?PORT_READ(in_INSERT_CONTEXT_ID   [x][y]):0;
127                  Ttype_t      type         = PORT_READ(in_INSERT_TYPE         [x][y]);
128                  Toperation_t operation    = PORT_READ(in_INSERT_OPERATION    [x][y]);
[100]129                  bool         is_store     = is_operation_memory_store(operation);
130
[88]131                  Texception_t exception    = PORT_READ(in_INSERT_EXCEPTION    [x][y]);
[115]132                  Tcontrol_t   no_execute   = PORT_READ(in_INSERT_NO_EXECUTE   [x][y]);
[88]133
134                  log_printf(TRACE,Commit_unit,FUNCTION,"    * front_end_id   : %d",front_end_id);
135                  log_printf(TRACE,Commit_unit,FUNCTION,"    * context_id     : %d",context_id);
[97]136                  log_printf(TRACE,Commit_unit,FUNCTION,"    * type           : %s",toString(type).c_str());
[88]137                  log_printf(TRACE,Commit_unit,FUNCTION,"    * operation      : %d",operation );
138                  log_printf(TRACE,Commit_unit,FUNCTION,"    * exception      : %d",exception );
[100]139                 
140                  // Create new entry.
[88]141                  entry_t * entry = new entry_t;
142
143                  entry->ptr                     = reg_BANK_PTR [i];
144                  entry->front_end_id            = front_end_id;
145                  entry->context_id              = context_id  ;
146                  entry->rename_unit_id          = x;
147                  entry->depth                   = (_param->_have_port_depth)?PORT_READ(in_INSERT_DEPTH [x][y]):0;
148                  entry->type                    = type;
149                  entry->operation               = operation;
150                  entry->is_delay_slot           = PORT_READ(in_INSERT_IS_DELAY_SLOT         [x][y]);
[105]151//                entry->address                 = PORT_READ(in_INSERT_ADDRESS               [x][y]);
[88]152                  entry->exception               = exception;
153                  entry->exception_use           = PORT_READ(in_INSERT_EXCEPTION_USE         [x][y]);
[115]154                  entry->use_store_queue         = (type == TYPE_MEMORY) and (    is_store) and (not no_execute);
155                  entry->use_load_queue          = (type == TYPE_MEMORY) and (not is_store) and (not no_execute);
[88]156                  entry->store_queue_ptr_write   = PORT_READ(in_INSERT_STORE_QUEUE_PTR_WRITE [x][y]);
157                  entry->load_queue_ptr_write    = (_param->_have_port_load_queue_ptr)?PORT_READ(in_INSERT_LOAD_QUEUE_PTR_WRITE [x][y]):0;
[121]158#ifdef DEBUG
[88]159                  entry->read_ra                 = PORT_READ(in_INSERT_READ_RA               [x][y]);
160                  entry->num_reg_ra_log          = PORT_READ(in_INSERT_NUM_REG_RA_LOG        [x][y]);
161                  entry->num_reg_ra_phy          = PORT_READ(in_INSERT_NUM_REG_RA_PHY        [x][y]);
162                  entry->read_rb                 = PORT_READ(in_INSERT_READ_RB               [x][y]);
163                  entry->num_reg_rb_log          = PORT_READ(in_INSERT_NUM_REG_RB_LOG        [x][y]);
164                  entry->num_reg_rb_phy          = PORT_READ(in_INSERT_NUM_REG_RB_PHY        [x][y]);
165                  entry->read_rc                 = PORT_READ(in_INSERT_READ_RC               [x][y]);
166                  entry->num_reg_rc_log          = PORT_READ(in_INSERT_NUM_REG_RC_LOG        [x][y]);
167                  entry->num_reg_rc_phy          = PORT_READ(in_INSERT_NUM_REG_RC_PHY        [x][y]);
[121]168#endif
[88]169                  entry->write_rd                = PORT_READ(in_INSERT_WRITE_RD              [x][y]);
170                  entry->num_reg_rd_log          = PORT_READ(in_INSERT_NUM_REG_RD_LOG        [x][y]);
171                  entry->num_reg_rd_phy_old      = PORT_READ(in_INSERT_NUM_REG_RD_PHY_OLD    [x][y]);
172                  entry->num_reg_rd_phy_new      = PORT_READ(in_INSERT_NUM_REG_RD_PHY_NEW    [x][y]);
173                  entry->write_re                = PORT_READ(in_INSERT_WRITE_RE              [x][y]);
174                  entry->num_reg_re_log          = PORT_READ(in_INSERT_NUM_REG_RE_LOG        [x][y]);
175                  entry->num_reg_re_phy_old      = PORT_READ(in_INSERT_NUM_REG_RE_PHY_OLD    [x][y]);
176                  entry->num_reg_re_phy_new      = PORT_READ(in_INSERT_NUM_REG_RE_PHY_NEW    [x][y]);
[105]177                  entry->no_sequence             = type == TYPE_BRANCH;
[108]178                  entry->speculative             = true;
179#ifdef DEBUG
180                  entry->address                 = PORT_READ(in_INSERT_ADDRESS               [x][y]);
181#endif
[105]182                  entry->address_next            = PORT_READ(in_INSERT_ADDRESS_NEXT          [x][y]);
[111]183#ifdef DEBUG
[113]184                  entry->cycle_rob_in            = simulation_cycle();
185                  entry->cycle_commit            = simulation_cycle();
[111]186#endif
[88]187
[100]188                  // Test if exception :
189                  //  * yes : no execute instruction, wait ROB Head
190                  //  * no  : test type
191                  //            * BRANCH : l.j   -> branch is ended
192                  //                       other -> wait the execution end of branchment
193                  //            * MEMORY : store -> wait store is at head of ROB
194                  //                       other -> wait end of instruction
195                  //            * OTHER
[88]196
[108]197//                   bool       flush      = reg_EVENT_FLUSH [front_end_id][context_id];
[88]198
[108]199//                   log_printf(TRACE,Commit_unit,FUNCTION,"    * flush          : %d",flush);
[100]200
[108]201//                   if (flush)
202//                     {
203//                       entry->state    = ROB_END_MISS; // All type (branch, memory and others), because, is not execute
204//                     }
205//                   else
206                    {
207                      if (exception == EXCEPTION_NONE)
208                        {
209                          // no_execute : l.j, l.nop, l.rfe
210                         
211                          log_printf(TRACE,Commit_unit,FUNCTION,"    * no_execute     : %d",no_execute);
212                         
213                          switch (type)
214                            {
215                            case TYPE_BRANCH : {entry->state=(no_execute==1)?ROB_BRANCH_COMPLETE:ROB_BRANCH_WAIT_END  ; break;}
[115]216                            case TYPE_MEMORY : {entry->state=(no_execute==1)?ROB_END_OK_SPECULATIVE:(entry->state=(is_store  ==1)?ROB_STORE_WAIT_HEAD_OK:ROB_OTHER_WAIT_END); break;}
[108]217                            default          : {entry->state=(no_execute==1)?ROB_END_OK_SPECULATIVE:ROB_OTHER_WAIT_END; break;}
218                            }
219                        }
220                      else
221                        {
222                          // Have an exception : wait head of ROB
223                         
224                          // in_INSERT_NO_EXECUTE [x][y] : l.sys, l.trap
225                         
226                          entry->state = ROB_END_EXCEPTION_WAIT_HEAD;
227                        }
228                    }
[88]229
[110]230#ifdef STATISTICS
231                  if (usage_is_set(_usage,USE_STATISTICS))
232                    (*_stat_nb_inst_insert [x]) ++;
233#endif
234
[100]235                  // Push in rob
[88]236                  _rob[i].push_back(entry);
237
[100]238                  // Update counter and pointer
[88]239                  reg_NB_INST_COMMIT_ALL [front_end_id][context_id] ++;
240                  if (type == TYPE_MEMORY)
241                    reg_NB_INST_COMMIT_MEM [front_end_id][context_id] ++;
242
243                  reg_NUM_BANK_TAIL = (reg_NUM_BANK_TAIL+1)%_param->_nb_bank;
244                  reg_BANK_PTR [i]  = (reg_BANK_PTR [i]+1)%_param->_size_bank;
245                }
246            }
247
248        // ===================================================================
249        // =====[ COMMIT ]====================================================
250        // ===================================================================
251
252#ifdef STATISTICS
253        if (usage_is_set(_usage,USE_STATISTICS))
254          (*_stat_nb_inst_commit_conflit_access) += internal_BANK_COMMIT_CONFLIT_ACCESS;
255#endif
256
257        for (uint32_t i=0; i<_param->_nb_bank; i++)
258          for (uint32_t j=0; j<_param->_nb_bank_access_commit; j++)
259            if (internal_BANK_COMMIT_VAL [i][j])
260              {
[100]261                // An instruction is executed. Change state of this instruction
262
[88]263                uint32_t x = internal_BANK_COMMIT_NUM_INST [i][j];
264
265                if (PORT_READ(in_COMMIT_VAL [x]) and PORT_READ(in_COMMIT_WEN [x]))
266                  {
267                    log_printf(TRACE,Commit_unit,FUNCTION,"  * COMMIT            [%d]",x);
268
269#ifdef STATISTICS
270                    if (usage_is_set(_usage,USE_STATISTICS))
271                      (*_stat_nb_inst_commit) ++;
272#endif
273
274                    log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank   : %d",i);
275
276                    // find the good entry !!!
[100]277                    entry_t *       entry        = internal_BANK_COMMIT_ENTRY [i][j];
278                                                 
279                  //Toperation_t    operation    = PORT_READ(in_COMMIT_OPERATION   [x]);
280                  //Ttype_t         type         = PORT_READ(in_COMMIT_TYPE        [x]);
281                    Texception_t    exception    = PORT_READ(in_COMMIT_EXCEPTION   [x]);
[88]282
[100]283                    rob_state_t     state        = entry->state;
284                    Tcontext_t      front_end_id = entry->front_end_id;
285                    Tcontext_t      context_id   = entry->context_id;
[88]286
[100]287                    // change state : test exception_use
[88]288                    //  * test if exception : exception and mask
289                   
[100]290                    bool have_exception        = false;
291                    bool have_miss_speculation = false;
292
[88]293                    if (exception != EXCEPTION_NONE)
[100]294                      {
295                        // Test if the instruction is a load and is a miss speculation (load is commit, but they have an dependence with a previous store)
296                        have_miss_speculation  = (exception == EXCEPTION_MEMORY_MISS_SPECULATION);
[88]297
[100]298                        switch (entry->exception_use)
299                          {
300                            // Have overflow exception if bit overflow enable is set.
301                          case  EXCEPTION_USE_RANGE                    : {have_exception = ((exception == EXCEPTION_RANGE) and PORT_READ(in_SPR_READ_SR_OVE[front_end_id][context_id])); break;}
302                          case  EXCEPTION_USE_MEMORY_WITH_ALIGNMENT    : {have_exception = ((exception == EXCEPTION_BUS_ERROR) or
303                                                                                            (exception == EXCEPTION_DATA_TLB ) or
304                                                                                            (exception == EXCEPTION_DATA_PAGE) or
305                                                                                            (exception == EXCEPTION_ALIGNMENT)); break;};
306                          case  EXCEPTION_USE_MEMORY_WITHOUT_ALIGNMENT : {have_exception = ((exception == EXCEPTION_BUS_ERROR) or
307                                                                                            (exception == EXCEPTION_DATA_TLB ) or
308                                                                                            (exception == EXCEPTION_DATA_PAGE)); break;};
309                          case  EXCEPTION_USE_CUSTOM_0                 : {have_exception = (exception == EXCEPTION_CUSTOM_0); break;}; 
310                          case  EXCEPTION_USE_CUSTOM_1                 : {have_exception = (exception == EXCEPTION_CUSTOM_1); break;}; 
311                          case  EXCEPTION_USE_CUSTOM_2                 : {have_exception = (exception == EXCEPTION_CUSTOM_2); break;}; 
312                          case  EXCEPTION_USE_CUSTOM_3                 : {have_exception = (exception == EXCEPTION_CUSTOM_3); break;}; 
313                          case  EXCEPTION_USE_CUSTOM_4                 : {have_exception = (exception == EXCEPTION_CUSTOM_4); break;}; 
314                          case  EXCEPTION_USE_CUSTOM_5                 : {have_exception = (exception == EXCEPTION_CUSTOM_5); break;}; 
315                          case  EXCEPTION_USE_CUSTOM_6                 : {have_exception = (exception == EXCEPTION_CUSTOM_6); break;}; 
316                            // Case already manage (decod stage -> in insert in ROB)
317                          case  EXCEPTION_USE_TRAP                     : {have_exception = false; exception = EXCEPTION_NONE; break;};
318                          case  EXCEPTION_USE_NONE                     : {have_exception = false; exception = EXCEPTION_NONE; break;}; 
319                          case  EXCEPTION_USE_ILLEGAL_INSTRUCTION      : {have_exception = false; exception = EXCEPTION_NONE; break;};
320                          case  EXCEPTION_USE_SYSCALL                  : {have_exception = false; exception = EXCEPTION_NONE; break;};
321                          default :
322                            {
323                              throw ERRORMORPHEO(FUNCTION,_("Commit : invalid exception_use.\n"));
324                              break;
325                            }
326                          }
327                      }
328                   
329                    switch (state)
330                      {
331                        // Branch ...
332                      case ROB_BRANCH_WAIT_END : {state = (have_exception)?ROB_END_EXCEPTION_WAIT_HEAD:ROB_BRANCH_COMPLETE; break;}
333                        // Store KO
[112]334                      case ROB_EVENT_WAIT_END  : {state = ROB_END_KO_SPECULATIVE; break;}
[100]335                        // Store OK, Load and other instruction
[105]336                      case ROB_OTHER_WAIT_END  : {state = (have_exception)?ROB_END_EXCEPTION_WAIT_HEAD:((have_miss_speculation)?ROB_END_LOAD_MISS_SPECULATIVE:ROB_END_OK_SPECULATIVE); break;}
[100]337                      default :
338                        {
[115]339                          throw ERRORMORPHEO(FUNCTION,toString(_("Commit [%d] : Bank [%d][%d], invalid state value (%s).\n"),x,i,j,toString(state).c_str()));
[100]340                          break;
341                        }
342                      }
[88]343
[112]344                    if ((have_exception or have_miss_speculation) and
345                        (reg_EVENT_FLUSH [entry->front_end_id][entry->context_id] == 0))
346                      reg_EVENT_STOP [entry->front_end_id][entry->context_id] = true;
347
[88]348                    // update Re Order Buffer
[105]349                    entry->state        = state;
350                    entry->exception    = exception;
351                    entry->flags        = PORT_READ(in_COMMIT_FLAGS       [x]);
352                    entry->no_sequence  = PORT_READ(in_COMMIT_NO_SEQUENCE [x]);
353                    // jalr, jr : address_dest is in register
354                    if ((entry->type      == TYPE_BRANCH) and
355                        (entry->operation == OPERATION_BRANCH_L_JALR) and
356                        (entry->read_rb))
357                    entry->address_next = PORT_READ(in_COMMIT_ADDRESS     [x]);
[111]358
359#ifdef DEBUG
[113]360                  entry->cycle_commit            = simulation_cycle();
[111]361#endif
[88]362                  }
363              }
364
365        // ===================================================================
366        // =====[ RETIRE ]====================================================
367        // ===================================================================
368        for (uint32_t i=0; i<_param->_nb_bank; i++)
[110]369          {
370            uint32_t num_bank = (internal_BANK_RETIRE_HEAD+i)%_param->_nb_bank;
371           
372            if (internal_BANK_RETIRE_VAL [num_bank])
373              {
374                uint32_t x = internal_BANK_RETIRE_NUM_RENAME_UNIT [num_bank];
375                uint32_t y = internal_BANK_RETIRE_NUM_INST        [num_bank];
376               
377                log_printf(TRACE,Commit_unit,FUNCTION,"  * RETIRE            [%d][%d]",x,y);
[112]378                log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank     : %d",num_bank     );
[110]379               
[88]380#ifdef DEBUG_TEST
[110]381                if (not PORT_READ(in_RETIRE_ACK [x][y]))
382                  throw ERRORMORPHEO(FUNCTION,_("Retire : retire_ack must be set.\n"));
[88]383#endif
[110]384               
385                entry_t *  entry        =  _rob [num_bank].front();
386                rob_state_t state = entry->state;
387               
388                Tcontext_t front_end_id = entry->front_end_id;
389                Tcontext_t context_id   = entry->context_id  ;
390                uint32_t   num_thread   = _param->_translate_num_context_to_num_thread [front_end_id][context_id];
391                Ttype_t    type         = entry->type        ;
392                bool       retire_ok    = false;
[88]393
[110]394                log_printf(TRACE,Commit_unit,FUNCTION,"    * front_end_id : %d",front_end_id );
395                log_printf(TRACE,Commit_unit,FUNCTION,"    * context_id   : %d",context_id   );
[117]396                log_printf(TRACE,Commit_unit,FUNCTION,"    * rob_ptr      : %d",((entry->ptr << _param->_shift_num_slot) | num_bank));
[110]397                log_printf(TRACE,Commit_unit,FUNCTION,"    * num_thread   : %d",num_thread   );
398                log_printf(TRACE,Commit_unit,FUNCTION,"    * type         : %s",toString(type).c_str());
399                log_printf(TRACE,Commit_unit,FUNCTION,"    * state        : %s",toString(state).c_str());
[88]400
[110]401                if ((state == ROB_END_OK         ) or
402//                  (state == ROB_END_KO         ) or
403                    (state == ROB_END_BRANCH_MISS) or
404                    (state == ROB_END_LOAD_MISS  )//  or
405//                  (state == ROB_END_MISS       ) or
406//                  (state == ROB_END_EXCEPTION  )
407                    )
408                  {
409                    log_printf(TRACE,Commit_unit,FUNCTION,"    * retire_ok");
[100]410
[110]411                    retire_ok = true;
[106]412
[110]413//                  reg_PC_PREVIOUS           [front_end_id][context_id] = reg_PC_CURRENT [front_end_id][context_id];
414                    reg_PC_CURRENT            [front_end_id][context_id] = reg_PC_NEXT    [front_end_id][context_id];
415                    reg_PC_CURRENT_IS_DS      [front_end_id][context_id] = entry->type == TYPE_BRANCH;
416                    reg_PC_CURRENT_IS_DS_TAKE [front_end_id][context_id] = entry->no_sequence;
417                    reg_PC_NEXT               [front_end_id][context_id] = (entry->no_sequence)?(entry->address_next):(reg_PC_CURRENT [front_end_id][context_id]+1);
418
[106]419//                   if (entry->address_next != reg_PC_NEXT [front_end_id][context_id])
420//                     throw ERRORMORPHEO(FUNCTION,toString(_("Retire : Instruction's address_next (%.8x) is different of commit_unit's address_next (%.8x)"),entry->address_next,reg_PC_NEXT [front_end_id][context_id]));
[110]421                  }
[112]422
[110]423                if ((state == ROB_END_BRANCH_MISS) or
424                    (state == ROB_END_LOAD_MISS))
[112]425                    {
426                      reg_EVENT_STATE [front_end_id][context_id] = EVENT_STATE_EVENT;
427                      reg_EVENT_FLUSH [front_end_id][context_id] = true;
428                      reg_EVENT_STOP  [front_end_id][context_id] = false;
429                    }
[110]430               
[111]431#if defined(DEBUG) and defined(DEBUG_Commit_unit) and (DEBUG_Commit_unit == true)
432                // log file
433                instruction_log_file [num_thread] 
[113]434                  << "[" << simulation_cycle() << "] "
[111]435                  << std::hex
[114]436                  << (entry->address<<2) << " (" << (entry->address) << ") "
[111]437                  << std::dec
438                  << "[" << entry->cycle_rob_in << ", " << entry->cycle_commit << "] "
[114]439                  << "{" << ((retire_ok)?" OK ":"!KO!") << "} "
[111]440                  << std::endl;
441#endif
442
[110]443                // Update nb_inst
444                reg_NB_INST_COMMIT_ALL [front_end_id][context_id] --;
445                if (type == TYPE_MEMORY)
446                  reg_NB_INST_COMMIT_MEM [front_end_id][context_id] --;
447               
448                reg_NUM_BANK_HEAD = (reg_NUM_BANK_HEAD+1)%_param->_nb_bank;
449               
[115]450                delete entry;
[110]451                _rob [num_bank].pop_front();
452               
453                // Transaction on retire interface : reset watch dog timer.
454                _nb_cycle_idle [front_end_id][context_id] = 0;
[105]455
[110]456                // Increase stop condition
457                if (retire_ok)
458                  _simulation_nb_instruction_commited [num_thread] ++;
[100]459
[110]460#ifdef STATISTICS
461                if (usage_is_set(_usage,USE_STATISTICS))
462                  {
463                    (*_stat_nb_inst_retire [x]) ++;
464                   
465                    if (retire_ok)
466                      {
467                        (*_stat_nb_inst_retire_ok [num_thread]) ++;
468                        (*_stat_nb_inst_type      [type]      ) ++;
469                      }
470                    else
471                      (*_stat_nb_inst_retire_ko [num_thread]) ++;
472                  }
473#endif
474              }
475          }
[109]476
[88]477        // ===================================================================
478        // =====[ REEXECUTE ]=================================================
479        // ===================================================================
480        if (internal_REEXECUTE_VAL [0] and PORT_READ(in_REEXECUTE_ACK [0]))
481          {
[101]482            log_printf(TRACE,Commit_unit,FUNCTION,"  * REEXECUTE         [0]");
483
[88]484            uint32_t num_bank = internal_REEXECUTE_NUM_BANK [0];
485
486            entry_t    * entry = _rob [num_bank].front();
487            rob_state_t  state = entry->state;
488
489            switch (state)
490              {
491              case ROB_STORE_HEAD_OK : {state = ROB_OTHER_WAIT_END; break; }
[112]492              case ROB_STORE_HEAD_KO : {state = ROB_EVENT_WAIT_END; break; }
[88]493              default : {throw ERRORMORPHEO(FUNCTION,_("Reexecute : invalid state value.\n"));}
494              }
495
496            entry->state = state;
497          }
498
499        // ===================================================================
500        // =====[ BRANCH_COMPLETE ]===========================================
501        // ===================================================================
502        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
503          if (internal_BRANCH_COMPLETE_VAL [i] and PORT_READ(in_BRANCH_COMPLETE_ACK [i]))
504            {
[101]505              log_printf(TRACE,Commit_unit,FUNCTION,"  * BRANCH_COMPLETE   [%d]",i);
506              log_printf(TRACE,Commit_unit,FUNCTION,"    * miss_prediction : %d",PORT_READ(in_BRANCH_COMPLETE_MISS_PREDICTION [i]));
507
[88]508              uint32_t num_bank = internal_BRANCH_COMPLETE_NUM_BANK [i];
509             
510              entry_t   * entry = _rob [num_bank].front();
511
512#ifdef DEBUG_TEST
513              rob_state_t  state = entry->state;
514              if (state != ROB_BRANCH_COMPLETE)
515                throw ERRORMORPHEO(FUNCTION,_("Branch_complete : Invalid state value.\n"));
516#endif
[112]517              Tcontrol_t miss = PORT_READ(in_BRANCH_COMPLETE_MISS_PREDICTION [i]);
518             
519              entry->state = (miss)?ROB_END_BRANCH_MISS_SPECULATIVE:ROB_END_OK_SPECULATIVE;
520             
521              if (miss and (reg_EVENT_FLUSH [entry->front_end_id][entry->context_id] == 0))
522                reg_EVENT_STOP [entry->front_end_id][entry->context_id] = true;
[88]523
[112]524
[100]525//               entry->state = ROB_END_OK_SPECULATIVE;
[88]526            }
527
528        // ===================================================================
[100]529        // =====[ UPDATE ]====================================================
530        // ===================================================================
[105]531        if (internal_UPDATE_VAL and PORT_READ(in_UPDATE_ACK))
532          {
533            log_printf(TRACE,Commit_unit,FUNCTION,"  * UPDATE");
[100]534
[105]535            entry_t * entry = _rob [internal_UPDATE_NUM_BANK].front();
536
537            switch (entry->state)
538              {
539//               case ROB_END_EXCEPTION_UPDATE :
540//                 {
541//                   entry->state = ROB_END_KO;
542//                   throw ERRORMORPHEO(FUNCTION,_("Moore : exception is not yet supported (Coming Soon).\n"));
543//                   break;
544//                 }
545              case ROB_END_LOAD_MISS_UPDATE :
546                {
547                  log_printf(TRACE,Commit_unit,FUNCTION,"    * ROB_END_LOAD_MISS_UPDATE");
548
549                  entry->state = ROB_END_LOAD_MISS;
550                  break;
551                }
552              default :
553                {
554                  throw ERRORMORPHEO(FUNCTION,_("Update : invalid state.\n"));
555                  break;
556                }
557              }
558
559          }
560
[100]561        // ===================================================================
[88]562        // =====[ EVENT ]=====================================================
563        // ===================================================================
[108]564//         for (uint32_t i=0; i < _param->_nb_front_end; ++i)
565//           for (uint32_t j=0; j < _param->_nb_context[i]; ++j)
566//             if (PORT_READ(in_EVENT_VAL [i][j]) and internal_EVENT_ACK [i][j])
567//               {
568//                 log_printf(TRACE,Commit_unit,FUNCTION,"  * EVENT [%d][%d]",i,j);
[88]569
[108]570//                 reg_PC_CURRENT            [i][j] = PORT_READ(in_EVENT_ADDRESS      [i][j]);
571//                 reg_PC_CURRENT_IS_DS      [i][j] = PORT_READ(in_EVENT_IS_DS_TAKE   [i][j]); // ??
572//                 reg_PC_CURRENT_IS_DS_TAKE [i][j] = PORT_READ(in_EVENT_IS_DS_TAKE   [i][j]);
573//                 reg_PC_NEXT               [i][j] = PORT_READ(in_EVENT_ADDRESS_NEXT [i][j]);
574//                 // PORT_READ(in_EVENT_ADDRESS_NEXT_VAL [i][j]);
575//               }
576
[88]577        // ===================================================================
578        // =====[ DEPTH - HEAD ]==============================================
579        // ===================================================================
580        for (uint32_t i=0; i<_param->_nb_bank; i++)
581          if (not _rob[i].empty())
582            {
583              // Scan all instruction in windows and test if instruction is speculative
584              entry_t    * entry        = _rob [i].front();
585             
586              Tcontext_t   front_end_id = entry->front_end_id;
587              Tcontext_t   context_id   = entry->context_id  ;
588              rob_state_t  state        = entry->state;
589              Tdepth_t     depth        = entry->depth;
590
[101]591              Tdepth_t     depth_min    = (_param->_have_port_depth)?PORT_READ(in_DEPTH_MIN[front_end_id][context_id]):0;
[105]592              Tdepth_t     depth_max    = (_param->_have_port_depth)?PORT_READ(in_DEPTH_MAX[front_end_id][context_id]):0;
593              Tcontrol_t   depth_full   = PORT_READ(in_DEPTH_FULL [front_end_id][context_id]);
[88]594             
595              // is a valid instruction ?
596              // If DEPTH_CURRENT :
597              // equal at     DEPTH_MIN            -> not speculative
[101]598              // not include ]DEPTH_MIN:DEPTH_MAX] -> previous branch miss
599              //     include ]DEPTH_MIN:DEPTH_MAX] -> speculative
[88]600             
601              // All case
602              // ....... min ...X... max ....... OK
603              // ....... min ....... max ...X... KO
604              // ...X... min ....... max ....... KO
605              // ....... max ....... min ...X... OK
606              // ...X... max ....... min ....... OK
607              // ....... max ...X... min ....... KO
608             
[104]609              bool         flush         = reg_EVENT_FLUSH [front_end_id][context_id];
[108]610              bool         speculative   = entry->speculative and not (depth == depth_min);
611              Tcontrol_t   is_valid      = ((not speculative or
612                                             (speculative and (depth_full or // all is valid
613                                                               ((depth_min <= depth_max)? // test if depth is overflow
614                                                                ((depth >= depth_min) and (depth <=depth_max)):
615                                                                ((depth >= depth_min) or  (depth <=depth_max))))))
[105]616                                             and not flush);
617
618//            Tcontrol_t   is_valid      = ((depth == depth_min) and not flush);
619
[101]620              log_printf(TRACE,Commit_unit,FUNCTION,"  * HEAD              [%d]",i);
[105]621              log_printf(TRACE,Commit_unit,FUNCTION,"    * is_valid        : %d ((depth == depth_min) and not flush)",is_valid);
[101]622              log_printf(TRACE,Commit_unit,FUNCTION,"    * depth           : %d",depth    );
623              log_printf(TRACE,Commit_unit,FUNCTION,"    * depth_min       : %d",depth_min);
[105]624              log_printf(TRACE,Commit_unit,FUNCTION,"    * depth_max       : %d",depth_max);
625              log_printf(TRACE,Commit_unit,FUNCTION,"    * depth_full      : %d",depth_full);
[104]626              log_printf(TRACE,Commit_unit,FUNCTION,"    * flush           : %d",flush);
[101]627
[88]628              //------------------------------------------------------
629              // test if instruction is miss speculative
630              //------------------------------------------------------
631              if (not is_valid)
632                {
633                  switch (state)
634                    {
[112]635                    case ROB_BRANCH_WAIT_END             : {state = ROB_EVENT_WAIT_END; break;}
636                    case ROB_BRANCH_COMPLETE             : {state = ROB_END_MISS      ; break;}
[108]637                    case ROB_END_BRANCH_MISS             :
[112]638                    case ROB_END_BRANCH_MISS_SPECULATIVE : {state = ROB_END_MISS      ; break;}
[108]639                    case ROB_END_LOAD_MISS_UPDATE        :
640                    case ROB_END_LOAD_MISS               :
[112]641                    case ROB_END_LOAD_MISS_SPECULATIVE   : {state = ROB_END_MISS      ; break;}
642                    case ROB_STORE_WAIT_HEAD_OK          : {state = ROB_STORE_HEAD_KO ; break;}
[100]643                  //case ROB_STORE_WAIT_HEAD_KO          : {state = ; break;}
[112]644                    case ROB_OTHER_WAIT_END              : {state = ROB_EVENT_WAIT_END; break;}
[108]645                    case ROB_END_OK                      :
[112]646                    case ROB_END_OK_SPECULATIVE          : {state = ROB_END_MISS      ; break;}
[108]647                    case ROB_END_KO                      :
[112]648                    case ROB_END_KO_SPECULATIVE          : {state = ROB_END_MISS      ; break;}
[108]649                    case ROB_END_EXCEPTION_UPDATE        :
650                    case ROB_END_EXCEPTION               :
[112]651                    case ROB_END_EXCEPTION_WAIT_HEAD     : {state = ROB_END_MISS      ; break;}
[100]652                                                         
653                      // don't change                   
654                    case ROB_STORE_HEAD_KO               : {break;}
[112]655                    case ROB_EVENT_WAIT_END              : {break;}
[100]656                    case ROB_END_MISS                    : {break;}
657                                                         
658                      // can't have miss speculation     
659                    case ROB_STORE_HEAD_OK               :
660                    default                              : 
[88]661                      {
[108]662                        throw ERRORMORPHEO(FUNCTION,toString(_("Miss Speculation : Invalide state : %s.\n"),toString(state).c_str()));
[88]663                        break;
664                      }
665                    }
666                }
667             
668              //------------------------------------------------------
669              // test if instruction is not speculative
670              //------------------------------------------------------
[108]671              entry->speculative = speculative;
672//            if (entry->depth == depth_min)
673              if (not speculative)
[88]674                {
675                  switch (state)
676                    {
[100]677                    case ROB_END_OK_SPECULATIVE          : {state = ROB_END_OK                 ; break;}
678                    case ROB_END_KO_SPECULATIVE          : {state = ROB_END_KO                 ; break;}
679                    case ROB_END_BRANCH_MISS_SPECULATIVE : {state = ROB_END_BRANCH_MISS        ; break;}
[105]680                    case ROB_END_LOAD_MISS_SPECULATIVE   : {state = ROB_END_LOAD_MISS_UPDATE   ; break;}
[108]681                    default : {break;} // else, no change
[88]682                  }
683                }
684             
685              //------------------------------------------------------
686              // test if instruction is store and head
687              //------------------------------------------------------
688              if (i == reg_NUM_BANK_HEAD)
689                {
690                  switch (state)
691                    {
[105]692                    case ROB_STORE_WAIT_HEAD_OK      : {state = ROB_STORE_HEAD_OK;        break;}
693                    case ROB_END_EXCEPTION_WAIT_HEAD : {state = ROB_END_EXCEPTION_UPDATE; break;}
[112]694                    default : {break;} // else, no change
[88]695                    }
696                }
697             
698              entry->state = state;
699            }
700      }
701
702    // ===================================================================
703    // =====[ OTHER ]=====================================================
704    // ===================================================================
705
[108]706#ifdef STATISTICS
707    for (uint32_t i=0; i<_param->_nb_bank; i++)
708      if (usage_is_set(_usage,USE_STATISTICS))
709        *(_stat_bank_nb_inst [i]) += _rob[i].size();
710#endif
[88]711
[108]712#if (DEBUG >= DEBUG_TRACE) and (DEBUG_Commit_unit == true)
713    {
714      log_printf(TRACE,Commit_unit,FUNCTION,"  * Dump ROB (Re-Order-Buffer)");
715      log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank_head : %d",reg_NUM_BANK_HEAD);
716      log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank_tail : %d",reg_NUM_BANK_TAIL);
717     
718      for (uint32_t i=0; i<_param->_nb_front_end; i++)
719        for (uint32_t j=0; j<_param->_nb_context [i]; j++)
720          {
[110]721            log_printf(TRACE,Commit_unit,FUNCTION,"    * [%d][%d] - %d",i,j,_param->_translate_num_context_to_num_thread [i][j]);
[108]722            log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_STATE  : %s",toString(reg_EVENT_STATE [i][j]).c_str());
723            log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_FLUSH  : %d",reg_EVENT_FLUSH [i][j]);
[112]724            log_printf(TRACE,Commit_unit,FUNCTION,"      * EVENT_STOP   : %d",reg_EVENT_STOP  [i][j]);
[108]725            log_printf(TRACE,Commit_unit,FUNCTION,"      * NB_INST_ALL  : %d",reg_NB_INST_COMMIT_ALL[i][j]);
726            log_printf(TRACE,Commit_unit,FUNCTION,"      * NB_INST_MEM  : %d",reg_NB_INST_COMMIT_MEM[i][j]);
727            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]);
728            log_printf(TRACE,Commit_unit,FUNCTION,"      * PC_NEXT      : %.8x (%.8x)",reg_PC_NEXT [i][j],reg_PC_NEXT [i][j]<<2);
729          }
730
731      for (uint32_t i=0; i<_param->_nb_bank; i++)
[104]732        {
[108]733          uint32_t num_bank = (reg_NUM_BANK_HEAD+i)%_param->_nb_bank;
734
735          log_printf(TRACE,Commit_unit,FUNCTION,"      * Bank [%d] size : %d, ptr : %d",num_bank,(int)_rob[num_bank].size(), reg_BANK_PTR [i]);
736         
737          for (std::list<entry_t*>::iterator it=_rob[num_bank].begin();
738               it!=_rob[num_bank].end();
739               it++)
740            {
[110]741              log_printf(TRACE,Commit_unit,FUNCTION,"        [%.4d][%.4d] (%.4d) %.4d %.4d %.4d %.4d, %.3d %.3d, %.1d, %.1d %.4d, %.1d %.4d, %s",
742                         num_bank                       ,
743                         (*it)->ptr                     ,
[117]744                         (((*it)->ptr << _param->_shift_num_slot) | num_bank),
[108]745                         (*it)->front_end_id            ,
746                         (*it)->context_id              ,
747                         (*it)->rename_unit_id          ,
748                         (*it)->depth                   ,
749                         (*it)->type                    ,
750                         (*it)->operation               ,
751                         (*it)->is_delay_slot           ,
752                         (*it)->use_store_queue         ,
753                         (*it)->store_queue_ptr_write   ,
754                         (*it)->use_load_queue          ,
755                         (*it)->load_queue_ptr_write    ,
[110]756                         toString((*it)->state).c_str() );
757              log_printf(TRACE,Commit_unit,FUNCTION,"                     %.1d %.2d %.6d, %.1d %.2d %.6d, %.1d %.1d %.6d, %.1d %.2d %.6d %.6d, %.1d %.1d %.6d %.6d ",
[108]758                         (*it)->read_ra                 ,
759                         (*it)->num_reg_ra_log          ,
760                         (*it)->num_reg_ra_phy          ,
761                         (*it)->read_rb                 ,
762                         (*it)->num_reg_rb_log          ,
763                         (*it)->num_reg_rb_phy          ,
764                         (*it)->read_rc                 ,
765                         (*it)->num_reg_rc_log          ,
766                         (*it)->num_reg_rc_phy          ,
767                         (*it)->write_rd                ,
768                         (*it)->num_reg_rd_log          ,
769                         (*it)->num_reg_rd_phy_old      ,
770                         (*it)->num_reg_rd_phy_new      ,
771                         (*it)->write_re                ,
772                         (*it)->num_reg_re_log          ,
773                         (*it)->num_reg_re_phy_old      ,
774                         (*it)->num_reg_re_phy_new      );
775             
[110]776              log_printf(TRACE,Commit_unit,FUNCTION,"                     %.2d %.2d %.1d %.1d %.1d - %.8x (%.8x) %.8x (%.8x)",
[108]777                         (*it)->exception_use ,
778                         (*it)->exception     ,
779                         (*it)->flags         ,
780                         (*it)->no_sequence   ,
781                         (*it)->speculative   ,
782                         (*it)->address       ,
783                         (*it)->address<<2    ,
784                         (*it)->address_next  ,
785                         (*it)->address_next<<2
786                         );
787            }
[104]788        }
[108]789    }
[88]790#endif
791
[108]792#ifdef DEBUG_TEST
793    {
794      uint32_t x=reg_NUM_BANK_HEAD;
795      if (not _rob[x].empty())
796        {
797          entry_t * entry = _rob [x].front();
[97]798
[108]799          if (false
800//            or (entry->state == ROB_EMPTY                      )
801//            or (entry->state == ROB_BRANCH_WAIT_END            )
802//            or (entry->state == ROB_BRANCH_COMPLETE            )
803//            or (entry->state == ROB_STORE_WAIT_HEAD_OK         )
804//          //or (entry->state == ROB_STORE_WAIT_HEAD_KO         )
805//            or (entry->state == ROB_STORE_HEAD_OK              )
806//            or (entry->state == ROB_STORE_HEAD_KO              )
807//            or (entry->state == ROB_OTHER_WAIT_END             )
[112]808//            or (entry->state == ROB_EVENT_WAIT_END             )
[108]809//            or (entry->state == ROB_END_OK_SPECULATIVE         )
810              or (entry->state == ROB_END_OK                     )
811//            or (entry->state == ROB_END_KO_SPECULATIVE         )
812//            or (entry->state == ROB_END_KO                     )
813//            or (entry->state == ROB_END_BRANCH_MISS_SPECULATIVE)
814              or (entry->state == ROB_END_BRANCH_MISS            )
815//            or (entry->state == ROB_END_LOAD_MISS_SPECULATIVE  )
816//            or (entry->state == ROB_END_LOAD_MISS_UPDATE       )
817              or (entry->state == ROB_END_LOAD_MISS              )
818//            or (entry->state == ROB_END_MISS                   )
819//            or (entry->state == ROB_END_EXCEPTION_WAIT_HEAD    )
820//            or (entry->state == ROB_END_EXCEPTION_UPDATE       )
821//            or (entry->state == ROB_END_EXCEPTION              )
822              )
823          if (entry->address != reg_PC_CURRENT[entry->front_end_id][entry->context_id])
824            throw ERRORMORPHEO(FUNCTION,toString(_("Rob top address (%x) is different of reg_PC_CURRENT[%d][%d] (%x).\n"),
825                                                 entry->address,
826                                                 entry->front_end_id,
827                                                 entry->context_id,
828                                                 reg_PC_CURRENT[entry->front_end_id][entry->context_id]));
829        }
830    }
831#endif
[88]832
833#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
834    end_cycle ();
835#endif
836
[109]837    // Stop Condition
838    for (uint32_t i=0; i<_param->_nb_front_end; i++)
839      for (uint32_t j=0; j<_param->_nb_context [i]; j++)
[110]840        if (_nb_cycle_idle [i][j] >= debug_idle_cycle)
841          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]));
[109]842
[88]843    log_end(Commit_unit,FUNCTION);
844  };
845
846}; // end namespace commit_unit
847}; // end namespace ooo_engine
848}; // end namespace multi_ooo_engine
849}; // end namespace core
850
851}; // end namespace behavioural
852}; // end namespace morpheo             
853#endif
Note: See TracBrowser for help on using the repository browser.