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

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

1) Decod_queue : multi implementation (one_fifo, multi_fifo)
2) Issue_queue : multi implementation (in_order, out_of_order)
3) Direction : Add Meta predictor
4) Context_State : re add Branch_complete, More priority to Load miss (is not speculative)
5) Return_Address_Stack : update reg_PREDICT pointer on decod miss prediction
6) UPT : Fix bug in multi event
7) Prediction_glue : in read_stack case, insert in UPT pc_next
8) Rename select : when rob have an event (need flush), read_r{a,b,c} and write_r{d,e} is set at 0

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