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

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

1) Configuration : instance configuration file : regroup similar instance
2) Configuration : timing default = 0
3) Debug/Commit_unit : Add watch dog timer
4) Issue_queue : Test parameters : add test if type is optionnal
5) Cor_glue : Fix insert index
6) Free_list : remove bank_by_pop (else deadlock)
7) Update Free List : add register to source event

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