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

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

1) RAT : Fix bug when update and event in same cycle
2) Context State : Compute depth
3) Load Store Unit : In check logic, translate all access in little endian. More easy to check
4) UFPT : End Event

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