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

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

1) decod_queue : add reg_LAST_SLOT.
2) Commit : insert on event -> to pop decod_queue. Head test : add information (speculative or not)
3) Context State / UPT : Branch miss and Load miss in same cycle.
4) Free List : Bank is on LSB not MSB.
5) Platforms : move data

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