source: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/src/Update_Prediction_Table_transition.cpp @ 111

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

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

  • Property svn:keywords set to Id
File size: 59.5 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Update_Prediction_Table_transition.cpp 111 2009-02-27 18:37:40Z rosiere $
4 *
5 * [ Description ]
6 *
7 */
8
9#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Update_Prediction_Table/include/Update_Prediction_Table.h"
10
11namespace morpheo                    {
12namespace behavioural {
13namespace core {
14namespace multi_front_end {
15namespace front_end {
16namespace prediction_unit {
17namespace update_prediction_table {
18
19#undef  FUNCTION
20#define FUNCTION "Update_Prediction_Table::transition"
21  void Update_Prediction_Table::transition (void)
22  {
23    log_begin(Update_Prediction_Table,FUNCTION);
24    log_function(Update_Prediction_Table,FUNCTION,_name.c_str());
25
26    if (PORT_READ(in_NRESET) == 0)
27      {
28        // Initialisation
29
30        reg_UPDATE_PRIORITY = 0;
31
32        // All pointer is set at 0
33        for (uint32_t i=0; i<_param->_nb_context; i++)
34          {
35            for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; ++j)
36              reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state = UPDATE_FETCH_PREDICTION_STATE_EMPTY;
37            reg_UFPT_BOTTOM          [i] = 0;
38            reg_UFPT_TOP             [i] = 0;
39            reg_UFPT_UPDATE          [i] = 0;
40            reg_UFPT_NB_NEED_UPDATE  [i] = 0;
41            reg_UFPT_NB_UPDATE       [i] = 0;
42                                                               
43            for (uint32_t j=0; j<_param->_size_upt_queue[i]; ++j)
44              reg_UPDATE_PREDICTION_TABLE [i][j]._state = UPDATE_PREDICTION_STATE_EMPTY;
45            reg_UPT_BOTTOM           [i] = 0;
46            reg_UPT_TOP              [i] = 0;
47            reg_UPT_TOP_EVENT        [i] = 0;
48            reg_UPT_UPDATE           [i] = 0;
49            reg_UPT_EMPTY            [i] = true;
50                                                                                   
51            reg_IS_ACCURATE          [i] = true;
52           
53            reg_EVENT_VAL            [i] = false;
54            reg_EVENT_STATE          [i] = EVENT_STATE_OK;
55          }
56      }
57    else
58      {
59        bool flush_UFPT    [_param->_nb_context];
60        for (uint32_t i=0; i<_param->_nb_context; i++)
61          {
62            flush_UFPT    [i] = false;
63          }
64
65        // ===================================================================
66        // =====[ GARBAGE COLLECTOR ]=========================================
67        // ===================================================================
68
69        // Each cycle, if the most lastest branch have update all prediction struction (state = end), free this slot
70        //   * Update state -> new status is "empty"
71        //   * Update pointer (bottom and accurate)
72        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * GARBAGE COLLECTOR (BEGIN)");
73        for (uint32_t i=0; i<_param->_nb_context; i++)
74          {
75            // UPDATE_FETCH_PREDICTION_TABLE
76            {
77              uint32_t bottom = reg_UFPT_BOTTOM [i];
78             
79              // Test if state is end
80              if (reg_UPDATE_FETCH_PREDICTION_TABLE [i][bottom]._state == UPDATE_FETCH_PREDICTION_STATE_END)
81                {
82                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d]",i,bottom);
83                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state =  UPDATE_FETCH_PREDICTION_STATE_EMPTY",i,bottom);
84
85                  // Free slot
86                  reg_UPDATE_FETCH_PREDICTION_TABLE [i][bottom]._state = UPDATE_FETCH_PREDICTION_STATE_EMPTY;
87                  // Update pointer
88                  reg_UFPT_BOTTOM [i] = (bottom+1)%_param->_size_ufpt_queue[i];
89                }
90            }
91
92            // UPDATE_PREDICTION_TABLE
93            {
94              uint32_t      bottom      = reg_UPT_BOTTOM [i];
95              bool          end         = (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END);
96//               bool          end_ok      = (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END_OK);
97//               bool          end_ko      = (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END_KO);
98//               event_state_t event_state = reg_EVENT_STATE [i];
99
100              // Test if state is end
101//               if (end_ok or end_ko)
102              if (end)
103                {
104#if defined(DEBUG) and defined(DEBUG_Update_Prediction_Table) and (DEBUG_Update_Prediction_Table == true)
105                  if (reg_UPDATE_PREDICTION_TABLE [i][bottom]._retire_ok)
106                    {
107                      uint32_t num_thread = _param->_translate_num_context_to_num_thread [i];
108                      branchement_log_file [num_thread] 
109                        << std::hex
110                        << "0x" << reg_UPDATE_PREDICTION_TABLE [i][bottom]._address_src  << " "
111                        << "0x" << reg_UPDATE_PREDICTION_TABLE [i][bottom]._address_dest << " "
112                        << std::dec
113                        <<         reg_UPDATE_PREDICTION_TABLE [i][bottom]._good_take    << " "
114                        << std::endl;
115                    }
116#endif
117                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT [%d][%d]",i,bottom);
118                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT [%d][%d]._state =  UPDATE_PREDICTION_STATE_EMPTY",i,bottom);
119                  // Free slot
120                  reg_UPDATE_PREDICTION_TABLE [i][bottom]._state = UPDATE_PREDICTION_STATE_EMPTY;
121
122                  // Update pointer
123                  reg_UPT_BOTTOM [i] = (bottom+1)%_param->_size_upt_queue[i];
124                 
125                  if (reg_UPT_BOTTOM [i] == reg_UPT_TOP [i])
126                    reg_UPT_EMPTY [i] = true; // free a slot
127
128//                   if (bottom = reg_UPT_UPDATE [i])
129//                     reg_UPT_UPDATE [i] = reg_UPT_BOTTOM [i];
130
131                  if (reg_EVENT_VAL [i] and (reg_EVENT_UPT_PTR [i] == bottom))
132                    {
133                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * END EVENT");
134                     
135                      reg_EVENT_VAL  [i] = false;
136                      reg_UPT_TOP    [i] = reg_UPT_TOP_EVENT [i];
137                      reg_UPT_UPDATE [i] = reg_UPT_TOP_EVENT [i];
138                     
139                      if (reg_UPT_BOTTOM [i] != reg_UPT_TOP [i])
140                        reg_UPT_EMPTY [i] = false;
141
142                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_TOP             : %d",reg_UPT_TOP            [i]);
143                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_TOP_EVENT       : %d",reg_UPT_TOP_EVENT      [i]);
144                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_UPDATE          : %d",reg_UPT_UPDATE         [i]);
145                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_EMPTY           : %d",reg_UPT_EMPTY          [i]);
146                    }
147
148                }
149            }
150          }
151
152        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * GARBAGE COLLECTOR (END)");
153
154        // ===================================================================
155        // =====[ PREDICT ]===================================================
156        // ===================================================================
157       
158        // An ifetch_unit compute next cycle and have an branch : predict_val is set
159        //   * Alloc new entry -> new status is "wait decod"
160        //   * Save input (to restore in miss or error)
161        //   * Update pointer
162
163        for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
164          if (PORT_READ(in_PREDICT_VAL[i]) and internal_PREDICT_ACK [i])
165            {
166              Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_PREDICT_CONTEXT_ID [i]):0;
167              uint32_t   top     = internal_PREDICT_UPDATE_PREDICTION_ID [i];
168
169              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * PREDICT[%d] - Accepted",i);
170              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
171              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * top     : %d",top);
172
173#ifdef DEBUG_TEST
174              if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._state != UPDATE_FETCH_PREDICTION_STATE_EMPTY)
175                throw ERRORMORPHEO(FUNCTION,_("Predict : invalid state."));
176#endif
177
178              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD (predict)",context,top);
179              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._state        = UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD;
180
181              Tbranch_condition_t condition = PORT_READ(in_PREDICT_BTB_CONDITION [i]);
182
183              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._condition    = condition;
184              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._address_src  = PORT_READ(in_PREDICT_BTB_ADDRESS_SRC  [i]);
185              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._address_dest = PORT_READ(in_PREDICT_BTB_ADDRESS_DEST [i]);
186              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._last_take    = PORT_READ(in_PREDICT_BTB_LAST_TAKE    [i]);
187              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._is_accurate  = PORT_READ(in_PREDICT_BTB_IS_ACCURATE  [i]);
188              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._history      = (_param->_have_port_history)?PORT_READ(in_PREDICT_DIR_HISTORY [i]):0;
189              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._address_ras  = PORT_READ(in_PREDICT_RAS_ADDRESS      [i]);
190              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._index_ras    = PORT_READ(in_PREDICT_RAS_INDEX        [i]);
191
192              reg_UFPT_TOP     [context] = (top+1)%_param->_size_ufpt_queue [context];
193//            reg_UFPT_UPDATE  [context] = reg_UFPT_TOP [context];
194              if (need_update(condition))
195                {
196                  reg_UFPT_NB_NEED_UPDATE [context] ++;
197                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE (after) : %d",reg_UFPT_NB_NEED_UPDATE [context]);
198
199                }
200            }
201
202        // ===================================================================
203        // =====[ DECOD ]=====================================================
204        // ===================================================================
205
206
207        // An decod is detected by decod stage
208        //   1) Hit prediction : The instruction bundle have a branch predicted in ifetch stage and it is this branch
209        //      * Update state, wait_decod -> wait_end
210        //      * Pop ufpt -> push upt
211        //      * Update accurate register : if the predict stage have tagged this branch as not accurate, stop decod
212        //   2) Miss           : The instruction bundle have a branch but it is not predicted
213        //      * Flush ufpt
214        //      * decod information is write in upt
215
216        for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
217          if (PORT_READ(in_DECOD_VAL[i]) and internal_DECOD_ACK [i])
218            {
219              Tcontext_t          context       = (_param->_have_port_context_id)?PORT_READ(in_DECOD_CONTEXT_ID [i]):0;
220              Tcontrol_t          miss_ifetch   = PORT_READ(in_DECOD_MISS_IFETCH [i]);
221              Tcontrol_t          miss_decod    = PORT_READ(in_DECOD_MISS_DECOD  [i]);
222              uint32_t            upt_ptr_write = internal_DECOD_UPT_PTR_WRITE [i];
223              Tbranch_condition_t condition  ;
224              Tcontrol_t          is_accurate;
225              Taddress_t          address_src   = PORT_READ(in_DECOD_BTB_ADDRESS_SRC  [i]);
226              Taddress_t          address_dest  = PORT_READ(in_DECOD_BTB_ADDRESS_DEST [i]);
227              Tcontrol_t          last_take     = PORT_READ(in_DECOD_BTB_LAST_TAKE    [i]);
228
229              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * DECOD[%d] - Accepted",i);
230              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context       : %d",context);
231              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss_ifetch   : %d",miss_ifetch);
232              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss_decod    : %d",miss_decod);
233              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * upt_ptr_write : %d",upt_ptr_write);
234
235              if (miss_ifetch or miss_decod)
236                {
237                  // Have a miss !!!
238#ifdef DEBUG_TEST
239                  if (reg_EVENT_STATE [context] != EVENT_STATE_OK)
240                    throw ERRORMORPHEO(FUNCTION,_("Decod : invalid event state."));
241#endif
242                  if (reg_UFPT_NB_NEED_UPDATE [context] == 0)
243                    {
244                      // Change state
245                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_UPDATE_CONTEXT (decod - miss - no flush ufpt)",context);
246                      reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT;
247                    }
248                  else
249                    {
250                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_MISS_FLUSH_UFPT (decod - miss - flush ufpt)",context);
251                      reg_EVENT_STATE [context] = EVENT_STATE_MISS_FLUSH_UFPT;
252                    }
253                  reg_EVENT_SOURCE          [context] = EVENT_SOURCE_UFPT;
254
255                  // Flush UPFT
256                  flush_UFPT [context] = true;
257
258                  reg_EVENT_DEPTH           [context] = upt_ptr_write;
259                  reg_EVENT_ADDRESS_SRC     [context] = address_src; // delay_slot is compute in Context_State
260                  reg_EVENT_ADDRESS_DEST_VAL[context] = last_take;
261                  reg_EVENT_ADDRESS_DEST    [context] = address_dest;
262
263                  // Push upt (from decod interface)
264                  condition   = PORT_READ(in_DECOD_BTB_CONDITION [i]);
265                  is_accurate = PORT_READ(in_DECOD_IS_ACCURATE   [i]);
266
267                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._condition         = condition;
268                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_src       = address_src ;
269                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_dest      = address_dest;
270                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._last_take         = last_take   ;
271//                reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._good_take;
272                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._is_accurate       = is_accurate;
273//                reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._history           = ; // static prediction
274                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_ras       = PORT_READ(in_DECOD_RAS_ADDRESS [i]);
275                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._index_ras         = PORT_READ(in_DECOD_RAS_INDEX   [i]);
276                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._ifetch_prediction = false; // static prediction
277                }
278              else
279                {
280                  // Normal case : branch is previous predicated, change state of branch
281                  uint32_t ufpt_ptr_read = (_param->_have_port_depth)?PORT_READ(in_DECOD_UPDATE_PREDICTION_ID [i]):0;
282
283                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * ufpt_ptr_read : %d",ufpt_ptr_read);
284
285#ifdef DEBUG_TEST
286                  if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._state != UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD)
287                    throw ERRORMORPHEO(FUNCTION,_("Decod : invalid ufpt state."));
288#endif
289                  // Change state
290                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_END (decod - hit)",context,ufpt_ptr_read);
291                  reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._state = UPDATE_FETCH_PREDICTION_STATE_END;
292
293                  // Push upt (from Pop ufpt)
294                  condition   = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._condition;
295                  is_accurate = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._is_accurate;
296
297                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._condition         = condition;
298                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_src       = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._address_src ;
299                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_dest      = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._address_dest;
300                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._last_take         = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._last_take   ;
301//                reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._good_take;
302                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._is_accurate       = is_accurate;
303                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._history           = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._history     ;
304                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_ras       = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._address_ras ;
305                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._index_ras         = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._index_ras   ;
306                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._ifetch_prediction = true ; // prediction from ifetch
307
308                  // Update pointer
309                  if (need_update(condition))
310                    {
311                      reg_UFPT_NB_NEED_UPDATE [context] --;
312                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE (after) : %d",reg_UFPT_NB_NEED_UPDATE [context]);
313
314                    }
315                }
316
317              // All case !!!
318#ifdef DEBUG_TEST
319              if (reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._state != UPDATE_PREDICTION_STATE_EMPTY)
320                throw ERRORMORPHEO(FUNCTION,_("Decod : invalid upt state."));
321#endif
322             
323              // Change state
324              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_WAIT_END (decod - hit)",context,upt_ptr_write);
325              reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._state = UPDATE_PREDICTION_STATE_WAIT_END;
326              reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._retire_ok = false;
327
328              // Write new accurate
329#ifdef DEBUG_TEST
330              if (not reg_IS_ACCURATE [context]  and not is_accurate)
331                throw ERRORMORPHEO(FUNCTION,_("Decod : invalid accurate flag."));
332#endif
333              reg_IS_ACCURATE [context] = is_accurate;
334             
335              // Update pointer
336              reg_UPT_TOP     [context] = (upt_ptr_write+1)%_param->_size_upt_queue [context];
337              reg_UPT_EMPTY   [context] = false;
338//            reg_UPT_UPDATE  [context] = reg_UPT_TOP [context];
339
340//               if (miss_ifetch or miss_decod)
341//                 reg_UPT_TOP_EVENT [context] = reg_UPT_TOP [context];
342            }
343
344        // ===================================================================
345        // =====[ UPDATE ]====================================================
346        // ===================================================================
347        {
348          bool can_continue [_param->_nb_context];
349          for (uint32_t i=0; i<_param->_nb_context; ++i)
350            can_continue [i] = true;
351
352          for (uint32_t i=0; i<_param->_nb_inst_update; i++)
353            {
354              Tcontext_t context   = internal_UPDATE_CONTEXT_ID [i];
355
356              if ((internal_UPDATE_VAL[i] and PORT_READ(in_UPDATE_ACK [i])) or
357                  (internal_UPDATE_VAL_WITHOUT_ACK [i] and can_continue [context]))
358                {
359                  Tdepth_t   depth     = internal_UPDATE_DEPTH      [i];
360                 
361                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * UPDATE[%d] - Accepted",i);
362                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
363                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth   : %d",depth);
364                 
365                  if (internal_UPDATE_FROM_UFPT [i])
366                    {
367                      // if free a slot, also all queue is updated
368                      // Last slot ?
369//                       if (reg_UFPT_UPDATE [context] == reg_UFPT_BOTTOM [context])
370                      if ((--reg_UFPT_NB_UPDATE [context])==0)
371                        switch (reg_EVENT_STATE [context])
372                          {
373                          case EVENT_STATE_MISS_FLUSH_UFPT         : reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT; break;
374                            // impossible to have an update on ufpt and reg_upt_update>reg_upt_top
375                          case EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT : reg_EVENT_STATE [context] = EVENT_STATE_MISS_FLUSH_UPT ; break;
376                          case EVENT_STATE_EVENT_FLUSH_UFPT        : reg_EVENT_STATE [context] = EVENT_STATE_OK             ; break;
377                          case EVENT_STATE_EVENT_FLUSH_UFPT_AND_UPT: reg_EVENT_STATE [context] = EVENT_STATE_EVENT_FLUSH_UPT; break;
378                          default : break;
379                          }
380                     
381                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Fetch Prediction Table");
382                     
383                      // Change state
384#ifdef DEBUG_TEST
385                      if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state != UPDATE_FETCH_PREDICTION_STATE_EVENT)
386                        throw ERRORMORPHEO(FUNCTION,_("Update : invalid ufpt state."));
387#endif
388                     
389                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_END (update)",context,depth);
390                     
391                      reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state = UPDATE_FETCH_PREDICTION_STATE_END;
392                                           
393                      // Update pointer
394                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (before) : %d",reg_UFPT_UPDATE [context]);
395                      reg_UFPT_UPDATE [context] = ((depth==0)?_param->_size_ufpt_queue[context]:depth)-1;
396                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (after ) : %d",reg_UFPT_UPDATE [context]);
397                      // Free a register that need update ?
398                      if (need_update(reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._condition))
399                        {
400                          reg_UFPT_NB_NEED_UPDATE [context] --;
401                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE (after) : %d",reg_UFPT_NB_NEED_UPDATE [context]);
402                        }
403                    }
404                  else
405                    {
406                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Prediction Table");
407                     
408                      // Change state
409#ifdef DEBUG_TEST
410                      if (internal_UPDATE_RAS [i])
411                        {
412                          if ((reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_EVENT) and
413                              (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_KO   ) )
414                            throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
415                        }
416                      else
417                        {
418                          if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_OK   )
419                            throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
420                        }
421#endif
422
423//                    bool have_event = ((reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_KO) or
424//                                       (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_EVENT));
425#ifdef STATISTICS
426                      Tbranch_condition_t condition = reg_UPDATE_PREDICTION_TABLE [context][depth]._condition;
427#endif
428                      bool ok     = (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_OK);
429                      bool ko     = (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_KO);
430
431                      if (ok or ko)
432                        reg_UPDATE_PREDICTION_TABLE [context][depth]._retire_ok = true;
433
434                      // Have an update, test the state to transiste to the good state
435                      if (ko)
436                        {
437                          // Ko : wait end of all instruction
438//                           log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_KO_WAIT_END (update)",context,depth);
439                         
440//                           reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END_KO_WAIT_END;
441
442                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_KO (update)",context,depth);
443                         
444                          reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END_KO;
445
446                          reg_EVENT_VAL     [context] = true;
447                          reg_EVENT_UPT_PTR [context] = depth;
448
449#ifdef STATISTICS
450                          if (usage_is_set(_usage,USE_STATISTICS))
451                            (*_stat_nb_branch_miss [context][condition])++;
452#endif
453                        }
454                      else
455                        {
456//                           log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_OK (update)",context,depth);
457//                           reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END_OK;
458
459                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END (update)",context,depth);
460                          reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END;
461
462#ifdef STATISTICS
463                          if (usage_is_set(_usage,USE_STATISTICS))
464                            {
465                              if (ok)
466                                (*_stat_nb_branch_hit    [context][condition]) ++;
467                              else
468                                (*_stat_nb_branch_unused [context]) ++;
469                            }
470#endif
471                        }
472                     
473                      // Update pointer
474                      //  * if update RAS : update pointer is decreaste until it equal at top pointer
475                      if (internal_UPDATE_RAS [i])
476                        {
477                          // if end_event, restart too bottom, else decrease pointer
478                          bool end_event  = (reg_UPT_UPDATE [context] == reg_UPT_TOP [context]);
479                         
480                          reg_UPT_UPDATE [context] = (end_event)?reg_UPT_BOTTOM[context]:(((depth==0)?_param->_size_upt_queue[context]:depth)-1);
481                          if (end_event)
482                            {
483//                               reg_UPT_UPDATE [context] = reg_UPT_BOTTOM[context];
484
485                              if (reg_EVENT_STATE [context] == EVENT_STATE_EVENT_FLUSH_UPT)
486                                {
487                                  reg_EVENT_STATE [context] = EVENT_STATE_OK;
488                                }
489                              else
490                                reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT;
491                            }
492                          else
493                            {
494                              reg_UPT_UPDATE [context] = (((depth==0)?_param->_size_upt_queue[context]:depth)-1);
495                            }
496                        }
497                      else
498                        {
499                          // increase pointer
500                          reg_UPT_UPDATE [context] = (depth+1)%_param->_size_upt_queue[context];
501                        }
502                     
503                      // Free the branch with no accurate ?
504                      if ( (reg_UPDATE_PREDICTION_TABLE [context][depth]._is_accurate == false) and not ko)
505                        reg_IS_ACCURATE [context] = true;
506                    }
507                }
508              else
509                can_continue [context] = false;
510            }
511       
512          // Round robin
513          reg_UPDATE_PRIORITY = (reg_UPDATE_PRIORITY+1)%_param->_nb_context;
514        }
515
516
517        // ===================================================================
518        // =====[ BRANCH_COMPLETE ]===========================================
519        // ===================================================================
520       
521        // The branch is complete
522        //   * Hit  prediction :
523        //     * update status
524        //   * Miss prediction :
525        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
526          if (PORT_READ(in_BRANCH_COMPLETE_VAL[i]) and internal_BRANCH_COMPLETE_ACK [i])
527            {
528              Tcontext_t context   = (_param->_have_port_context_id)?PORT_READ(in_BRANCH_COMPLETE_CONTEXT_ID [i]):0;
529              Tdepth_t   depth     = (_param->_have_port_depth     )?PORT_READ(in_BRANCH_COMPLETE_DEPTH      [i]):0;
530              Tcontrol_t miss      = internal_BRANCH_COMPLETE_MISS_PREDICTION [i];
531              Tcontrol_t good_take = internal_BRANCH_COMPLETE_TAKE            [i];
532              Taddress_t good_addr = internal_BRANCH_COMPLETE_ADDRESS_DEST    [i];
533
534              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * BRANCH_COMPLETE[%d] - Accepted",i);
535              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context        : %d",context);
536              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth          : %d",depth);
537              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss           : %d",miss);
538             
539              if (miss)
540                {
541                  // Flush UPT
542                  uint32_t      top                 = reg_UPT_TOP [context];
543                  uint32_t      new_update          = ((top==0)?_param->_size_upt_queue[context]:top)-1; 
544                                                   
545                  Taddress_t    address_src         = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src;
546                  event_state_t event_state         = reg_EVENT_STATE [context];
547                  upt_state_t   event_top           = reg_UPDATE_PREDICTION_TABLE [context][top]._state;
548                  bool          previous_ufpt_event = ((event_state == EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT ) or
549                                                       (event_state == EVENT_STATE_MISS_FLUSH_UFPT         ) or
550                                                       (event_state == EVENT_STATE_EVENT_FLUSH_UFPT_AND_UPT) or
551                                                       (event_state == EVENT_STATE_EVENT_FLUSH_UFPT        ));
552
553                  bool          previous_upt_event  = ((event_state == EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT ) or
554                                                       (event_state == EVENT_STATE_MISS_FLUSH_UPT          ) or
555                                                       (event_state == EVENT_STATE_EVENT_FLUSH_UFPT_AND_UPT) or
556                                                       (event_state == EVENT_STATE_EVENT_FLUSH_UPT         ) or
557                                                       (event_top   == UPDATE_PREDICTION_STATE_END_KO      ) or
558                                                       (event_top   == UPDATE_PREDICTION_STATE_KO          )
559//                                                   (event_state == EVENT_STATE_WAIT_END_EVENT          ) or
560//                                                   ((event_state == EVENT_STATE_UPDATE_CONTEXT         ) and
561//                                                    (reg_EVENT_SOURCE [context] == EVENT_SOURCE_UPT))
562                                                  );
563//                bool          update_ras     = (new_update != depth);
564
565                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * top                 : %d",top);
566                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * new_update          : %d",new_update);
567//                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * update_ras          : %d",update_ras);
568                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * previous_upt_event  : %d",previous_upt_event);
569                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * previous_ufpt_event : %d",previous_ufpt_event);
570
571                  // Have a miss !!!
572                  // Flush UPFT
573                  flush_UFPT [context] = not previous_ufpt_event;
574                 
575                  if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_WAIT_END)
576                    {
577                      for (uint32_t j=(depth+1)%_param->_size_upt_queue[context];
578                           j!=top; 
579                           j=(j+1)%_param->_size_upt_queue[context])
580                        {
581                          reg_UPDATE_PREDICTION_TABLE [context][j]._state = UPDATE_PREDICTION_STATE_EVENT;
582                          reg_UPDATE_PREDICTION_TABLE [context][j]._retire_ok = false;
583                        }
584                     
585                 
586//                    reg_UPT_BOTTOM    [context];
587                      reg_UPT_TOP       [context] = depth;
588//                    reg_UPT_TOP_EVENT [context] = top;
589
590                      if (not previous_upt_event)
591                        {
592                          reg_UPT_TOP_EVENT [context] = top;
593                          reg_UPT_UPDATE    [context] = new_update;
594                        }
595                      else
596                        {
597                          // Have event. Top index this slot
598                          reg_UPDATE_PREDICTION_TABLE [context][top]._retire_ok = false;
599
600                          switch (event_top)
601                            {
602                            case UPDATE_PREDICTION_STATE_END_KO : 
603                              {
604                                // Have already update predictor
605                                reg_UPDATE_PREDICTION_TABLE [context][top]._state = UPDATE_PREDICTION_STATE_END;
606                                break;
607                              }
608                            case UPDATE_PREDICTION_STATE_KO :
609                              {
610                                // Doesn't have update predictor
611                                reg_UPDATE_PREDICTION_TABLE [context][top]._state = UPDATE_PREDICTION_STATE_EVENT;
612                                break;
613                              }
614                            default :
615                              {
616//                                 reg_UPDATE_PREDICTION_TABLE [context][top]._state = UPDATE_PREDICTION_STATE_EVENT;
617//                                 break;
618
619#ifdef DEBUG_TEST
620                                throw ERRORMORPHEO(FUNCTION,_("Branch complete : invalid upt state."));
621#endif
622                              }
623                            }
624                        }
625                     
626                      if (reg_UPT_BOTTOM [context] == reg_UPT_TOP [context])
627                        reg_UPT_EMPTY [context] = true;
628                     
629                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_KO (branch_complete, ifetch hit)",context,depth);
630                      reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_KO;
631
632                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE [%d] : %d",context,reg_UFPT_NB_NEED_UPDATE [context]);
633                     
634                      if ( (reg_UFPT_NB_NEED_UPDATE [context] > 0) or
635                           (reg_UFPT_NB_UPDATE      [context] > 0))
636                        {
637                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT (branch_complete - miss)",context);
638                          reg_EVENT_STATE [context] = EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT;
639                        }
640                      else
641                        {
642//                        if (not previous_update_ras)
643                          {
644                            // have ras prediction ?
645                            log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_MISS_FLUSH_UPT (branch_complete - miss)",context);
646                           
647                            reg_EVENT_STATE [context] = EVENT_STATE_MISS_FLUSH_UPT;
648                           
649                          }
650                        }
651                      reg_EVENT_SOURCE          [context] = EVENT_SOURCE_UPT;
652                     
653                      // else no update
654                     
655                      reg_EVENT_DEPTH           [context] = depth;
656                      reg_EVENT_ADDRESS_SRC     [context] = address_src; // delay_slot is compute in Context_State
657                      reg_EVENT_ADDRESS_DEST_VAL[context] = good_take;
658                      reg_EVENT_ADDRESS_DEST    [context] = good_addr;
659                    }
660                }
661              else
662                {
663                  // Hit case
664
665// #ifdef DEBUG_TEST
666//                   if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_WAIT_END)
667//                     throw ERRORMORPHEO(FUNCTION,_("Branch complete : invalid upt state."));
668// #endif
669
670                  if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_WAIT_END)
671                    {
672                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_OK (branch_complete, ifetch hit)",context,depth);
673                      reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_OK;
674                    }
675                }
676
677              // In all case : update good_take
678              reg_UPDATE_PREDICTION_TABLE [context][depth]._good_take    = good_take;
679
680              // Write address_dest if need read register
681              Tbranch_condition_t condition = reg_UPDATE_PREDICTION_TABLE [context][depth]._condition;
682             
683              if ((condition == BRANCH_CONDITION_READ_REGISTER_WITHOUT_WRITE_STACK) or
684                  (condition == BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK   ) or
685                  (condition == BRANCH_CONDITION_READ_STACK                       ) )
686                reg_UPDATE_PREDICTION_TABLE [context][depth]._address_dest = good_addr;
687            }
688
689        // ===================================================================
690        // =====[ BRANCH_EVENT ]==============================================
691        // ===================================================================
692        for (uint32_t i=0; i<_param->_nb_context; i++)
693          if (internal_BRANCH_EVENT_VAL [i] and PORT_READ(in_BRANCH_EVENT_ACK [i]))
694            {
695              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * BRANCH_EVENT [%d] - Accepted",i);
696
697              // if different : an other branch is occured
698              if (reg_EVENT_STATE [i] == EVENT_STATE_UPDATE_CONTEXT)
699                {
700                  // Change state
701                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_WAIT_END_EVENT (branch_event)",i);
702                 
703                  reg_EVENT_STATE [i] = EVENT_STATE_WAIT_END_EVENT;
704                }
705            }
706
707        // ===================================================================
708        // =====[ EVENT ]=====================================================
709        // ===================================================================
710        for (uint32_t i=0; i<_param->_nb_context; ++i)
711          if (PORT_READ(in_EVENT_VAL [i]) and internal_EVENT_ACK [i])
712            {
713              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * EVENT");
714
715              //----------------------------------------------------------------
716              // Cases
717              //----------------------------------------------------------------
718              //   * EVENT_TYPE_NONE               - nothing
719              //   * EVENT_TYPE_MISS_SPECULATION   - Change state, reset pointer
720              //   * EVENT_TYPE_EXCEPTION          - Flush upft and upt, Change state, reset pointer
721              //   * EVENT_TYPE_BRANCH_NO_ACCURATE - nothing : manage in decod and update
722              //   * EVENT_TYPE_SPR_ACCESS         - nothing
723              //   * EVENT_TYPE_MSYNC              - nothing
724              //   * EVENT_TYPE_PSYNC              - nothing
725              //   * EVENT_TYPE_CSYNC              - nothing
726             
727              Tevent_type_t  event_type  = PORT_READ(in_EVENT_TYPE  [i]);
728
729              // Test if end of miss -> all previous branch is complete
730              //                     -> all next     branch is finish
731
732              switch (event_type)
733                {
734                case EVENT_TYPE_BRANCH_MISS_SPECULATION :
735                  {
736                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * type  : EVENT_TYPE_BRANCH_MISS_SPECULATION");
737                   
738#ifdef DEBUG_TEST
739                    if (reg_EVENT_STATE [i] != EVENT_STATE_WAIT_END_EVENT)
740                      throw ERRORMORPHEO(FUNCTION,_("Event : invalid event state."));
741#endif
742                   
743                    // Change state
744                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_OK (event)",i);
745                   
746                    reg_EVENT_STATE [i] = EVENT_STATE_OK;
747                    reg_IS_ACCURATE [i] = true;
748
749                    Tdepth_t depth = reg_EVENT_UPT_PTR [i];
750
751                    if (reg_UPDATE_PREDICTION_TABLE [i][depth]._state == UPDATE_PREDICTION_STATE_END_KO)
752                      {
753                        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END (event)",i,depth);
754                       
755                        reg_UPDATE_PREDICTION_TABLE [i][depth]._state = UPDATE_PREDICTION_STATE_END;
756                      }
757
758#ifdef DEBUG_TEST
759//                     if (reg_UPDATE_PREDICTION_TABLE [i][depth]._state != UPDATE_PREDICTION_STATE_END_KO_WAIT_END)
760//                       throw ERRORMORPHEO(FUNCTION,_("Event : invalid upt event state."));
761//                  if (reg_UPDATE_PREDICTION_TABLE [i][depth]._state != UPDATE_PREDICTION_STATE_END_KO)
762//                    throw ERRORMORPHEO(FUNCTION,_("Event : invalid upt event state."));
763#endif
764
765//                     log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_KO (update)",i,depth);
766                   
767//                     reg_UPDATE_PREDICTION_TABLE [i][depth]._state = UPDATE_PREDICTION_STATE_END_KO;
768                   
769                    break;
770                  }
771                case EVENT_TYPE_LOAD_MISS_SPECULATION :
772                case EVENT_TYPE_EXCEPTION             :
773                  {
774                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * type  : EVENT_TYPE_LOAD_MISS_SPECULATION");
775
776                    // Have a miss !!!
777                    // Flush UPFT
778                    flush_UFPT [i] = true;
779                   
780                    // Flush UPT
781                    Tdepth_t depth      = (_param->_have_port_depth)?PORT_READ(in_EVENT_DEPTH [i]):0;
782                    uint32_t top        = reg_UPT_TOP    [i];
783                    uint32_t bottom     = reg_UPT_BOTTOM [i];
784                    uint32_t new_update = ((top==0)?_param->_size_upt_queue[i]:top)-1; 
785//                     bool     empty      = reg_UPT_EMPTY [i];
786
787                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * top        : %d",top);
788                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth      : %d",depth);
789                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * new_update : %d",new_update);
790
791                    event_state_t event_state         = reg_EVENT_STATE [i];
792                    bool          previous_update_ras = ((event_state == EVENT_STATE_MISS_FLUSH_UFPT_AND_UPT ) or
793                                                         (event_state == EVENT_STATE_MISS_FLUSH_UPT          ) or
794                                                         (event_state == EVENT_STATE_EVENT_FLUSH_UFPT_AND_UPT) or
795                                                         (event_state == EVENT_STATE_EVENT_FLUSH_UPT));
796
797                    bool     find = false; // have slot to update ???
798                    Tdepth_t depth_new = depth;
799
800                    // flush all slot after the event
801                    for (uint32_t j=(depth+1)%_param->_size_upt_queue[i];
802                         j!=top; 
803                         j=(j+1)%_param->_size_upt_queue[i])
804                      if ((reg_UPDATE_PREDICTION_TABLE [i][j]._state != UPDATE_PREDICTION_STATE_END) and
805                          (reg_UPDATE_PREDICTION_TABLE [i][j]._state != UPDATE_PREDICTION_STATE_EMPTY))
806                        {
807                          find = true;
808                          reg_UPDATE_PREDICTION_TABLE [i][j]._state = UPDATE_PREDICTION_STATE_EVENT;
809                          reg_UPDATE_PREDICTION_TABLE [i][j]._retire_ok = false;
810                        }
811                      else
812                        if (not find) // while state == end or empty
813                          depth_new ++;
814                   
815                    if ((reg_UPDATE_PREDICTION_TABLE [i][depth]._state != UPDATE_PREDICTION_STATE_END) and
816                        (reg_UPDATE_PREDICTION_TABLE [i][depth]._state != UPDATE_PREDICTION_STATE_EMPTY))
817                      {
818                        find = true;
819                        reg_UPDATE_PREDICTION_TABLE [i][depth]._state = UPDATE_PREDICTION_STATE_EVENT;
820                        reg_UPDATE_PREDICTION_TABLE [i][depth]._retire_ok = false;
821
822                      }
823                    else
824                      // while state == end or empty
825                      depth = (depth_new+1)%_param->_size_upt_queue[i];
826
827                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * find       : %d",find);
828                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth_new  : %d",depth_new);
829                   
830                    // Test if have update slot
831                    if (find)
832                      {
833//                         // flush all slot after the event
834//                         for (uint32_t j=(depth+1)%_param->_size_upt_queue[i];
835//                              j!=top;
836//                              j=(j+1)%_param->_size_upt_queue[i])
837//                           reg_UPDATE_PREDICTION_TABLE [i][j]._state = UPDATE_PREDICTION_STATE_EVENT;
838
839//                         reg_UPDATE_PREDICTION_TABLE [i][depth]._state = UPDATE_PREDICTION_STATE_EVENT;
840                       
841                        // reg_UPT_BOTTOM    [i];
842                        // TODO : special case : event is an exception on branch, also depth is not valid
843                        reg_UPT_TOP       [i] = depth; // depth is again valid
844                        reg_UPT_TOP_EVENT [i] = top;
845                       
846                        if (bottom == reg_UPT_TOP [i])
847                          reg_UPT_EMPTY [i] = true;
848                      }
849
850                    bool     full       = ((depth == top) and (top == bottom) and not reg_UPT_EMPTY [i]);
851                    bool     update_ras = find and ((top != depth) or full);
852                   
853                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * update_ras : %d",update_ras);
854                   
855                    if (not previous_update_ras and update_ras)
856                      reg_UPT_UPDATE [i]  = new_update;
857             
858                    // new state :
859                    //   * test if ufpt is empty
860                    //     * ok : flush upft and upt
861                    //     * ko : test if have previous flush upt
862                    //            * ok : nothing
863                    //            * ko : flush upt
864                    reg_EVENT_VAL     [i] = true;
865                    reg_EVENT_UPT_PTR [i] = depth;
866
867                    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE          : %d",reg_UFPT_NB_NEED_UPDATE [i]);
868//                     if (reg_UFPT_NB_NEED_UPDATE [i] > 0)
869                    if ( (reg_UFPT_NB_NEED_UPDATE [i] > 0) or
870                         (reg_UFPT_NB_UPDATE      [i] > 0))
871                      {
872                        if (update_ras)
873                          {
874                            log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_EVENT_FLUSH_UFPT_AND_UPT (branch_complete - miss)",i);
875                            reg_EVENT_STATE [i] = EVENT_STATE_EVENT_FLUSH_UFPT_AND_UPT;
876                          }
877                        else
878                          {
879                            log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_EVENT_FLUSH_UFPT (branch_complete - miss)",i);
880                            reg_EVENT_STATE [i] = EVENT_STATE_EVENT_FLUSH_UFPT;
881                          }                         
882                      }
883                    else
884                      {
885//                         if (not previous_update_ras)
886                        if (update_ras)
887                          {
888                            // have ras prediction ?
889                            log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_EVENT_FLUSH_UPT (branch_complete - miss)",i);
890                           
891                            reg_EVENT_STATE [i] = EVENT_STATE_EVENT_FLUSH_UPT;
892                          }
893                        else
894                          {
895                            // special case : nothing
896                            reg_EVENT_VAL     [i] = false;
897
898                            reg_EVENT_STATE [i] = EVENT_STATE_OK;
899                          }
900                      }
901
902                    // else no update
903                   
904                    reg_EVENT_DEPTH           [i] = depth;
905//                  reg_EVENT_ADDRESS_SRC     [i] = address_src; // delay_slot is compute in I_State
906//                  reg_EVENT_ADDRESS_DEST_VAL[i] = good_take;
907//                  reg_EVENT_ADDRESS_DEST    [i] = good_addr;
908
909                    break;
910                  }
911                default :
912                  {
913                    // nothing
914                    break;
915                  }
916                }
917            }
918
919        // ===================================================================
920        // =====[ FLUSH ]=====================================================
921        // ===================================================================
922
923        for (uint32_t i=0; i<_param->_nb_context; ++i)
924          {
925            if (flush_UFPT [i])
926              {
927                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * Flush Update Fetch Prediction Table");
928                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context                          : %d",i);
929                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE          : %d",reg_UFPT_NB_NEED_UPDATE [i]);
930
931              // It's to accelerate miss speculation
932              if (reg_UFPT_NB_NEED_UPDATE [i] == 0)
933                {
934                  // No entry need prediction, flush all entry -> Reset
935                  for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; ++j)
936                    reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state = UPDATE_FETCH_PREDICTION_STATE_EMPTY;
937                  reg_UFPT_BOTTOM [i] = 0;
938                  reg_UFPT_TOP    [i] = 0;
939//                reg_UFPT_UPDATE [i];
940                }
941              else
942                {
943                  uint32_t bottom = reg_UFPT_BOTTOM [i];
944                  for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; ++j)
945                    {
946                      uint32_t index = (bottom+j)%_param->_size_ufpt_queue[i];
947                      // EMPTY : no event
948                      // END   : already update
949                      // EVENT : previous event
950                      if (reg_UPDATE_FETCH_PREDICTION_TABLE [i][index]._state == UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD)
951                        {
952                          reg_UFPT_UPDATE    [i] = index;
953                          reg_UFPT_NB_UPDATE [i] ++;
954                          reg_UPDATE_FETCH_PREDICTION_TABLE [i][index]._state = UPDATE_FETCH_PREDICTION_STATE_EVENT;
955                        }
956                    }
957
958//                   // TOP is next write slot : last slot is TOP-1
959//                   uint32_t top = reg_UFPT_TOP [i];
960//                   reg_UFPT_UPDATE    [i] = ((top==0)?_param->_size_ufpt_queue[i]:top)-1;
961
962//                reg_UFPT_BOTTOM    [i];
963//                reg_UFPT_TOP       [i];
964                }
965
966              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE         (after ) : %d",reg_UFPT_UPDATE [i]);
967
968              }
969          }
970
971#ifdef STATISTICS
972        if (usage_is_set(_usage,USE_STATISTICS))
973          for (uint32_t i=0; i<_param->_nb_context; i++)
974            {
975              for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; j++)
976                if (reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state != UPDATE_FETCH_PREDICTION_STATE_EMPTY)
977                  (*_stat_ufpt_queue_nb_elt [i]) ++;
978              for (uint32_t j=0; j<_param->_size_upt_queue[i]; j++)
979                if (reg_UPDATE_PREDICTION_TABLE [i][j]._state != UPDATE_PREDICTION_STATE_EMPTY)
980                  (*_stat_upt_queue_nb_elt [i]) ++;
981            }
982#endif
983       
984        // ===================================================================
985        // =====[ PRINT ]=====================================================
986        // ===================================================================
987
988#if (DEBUG >= DEBUG_TRACE)
989    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * Dump Update_Prediction_Table");
990    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UPDATE_PRIORITY       : %d",reg_UPDATE_PRIORITY);
991    for (uint32_t i=0; i<_param->_nb_context; i++)
992      {
993        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_IS_ACCURATE           : %d",reg_IS_ACCURATE        [i]);
994        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_VAL             : %d"  ,reg_EVENT_VAL             [i]);
995        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_UPT_PTR         : %d"  ,reg_EVENT_UPT_PTR         [i]);
996        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_STATE           : %s"  ,toString(reg_EVENT_STATE [i]).c_str());
997        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_SOURCE          : %s"  ,toString(reg_EVENT_SOURCE[i]).c_str());
998        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_DEPTH           : %d"  ,reg_EVENT_DEPTH           [i]);
999        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_ADDRESS_SRC     : %.8x (%.8x)",reg_EVENT_ADDRESS_SRC     [i],reg_EVENT_ADDRESS_SRC     [i]<<2);
1000        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_ADDRESS_DEST_VAL: %d"  ,reg_EVENT_ADDRESS_DEST_VAL[i]);
1001        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_ADDRESS_DEST    : %.8x (%.8x)",reg_EVENT_ADDRESS_DEST    [i],reg_EVENT_ADDRESS_DEST    [i]<<2);
1002
1003        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update_Fetch_Prediction_Table   [%d]",i);
1004        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_BOTTOM         : %d",reg_UFPT_BOTTOM         [i]);
1005        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_TOP            : %d",reg_UFPT_TOP            [i]);
1006        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_UPDATE         : %d",reg_UFPT_UPDATE         [i]);
1007        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_NB_NEED_UPDATE : %d",reg_UFPT_NB_NEED_UPDATE [i]);
1008        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_NB_UPDATE      : %d",reg_UFPT_NB_UPDATE      [i]);
1009        for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; j++)
1010          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"        [%d] %.4d, %.8x (%.8x) %.8x (%.8x), %.1d   %.1d, %.8d %.8x (%.8x) %.4d - %s",
1011                     j,
1012                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._condition,
1013                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_src,
1014                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_src<<2,
1015                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_dest,
1016                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_dest<<2,
1017                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._last_take,
1018                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._is_accurate,
1019                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._history,
1020                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_ras,
1021                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_ras<<2,
1022                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._index_ras,
1023                     toString(reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state).c_str()
1024                     );
1025
1026        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update_Prediction_Table   [%d]",i);
1027        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_BOTTOM          : %d",reg_UPT_BOTTOM         [i]);
1028        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_TOP             : %d",reg_UPT_TOP            [i]);
1029        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_TOP_EVENT       : %d",reg_UPT_TOP_EVENT      [i]);
1030        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_UPDATE          : %d",reg_UPT_UPDATE         [i]);
1031        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_EMPTY           : %d",reg_UPT_EMPTY          [i]);
1032        for (uint32_t j=0; j<_param->_size_upt_queue[i]; j++)
1033          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"        [%d] %.4d, %.8x (%.8x) %.8x (%.8x), %.1d %.1d %.1d, %.8d %.8x (%.8x) %.4d - %s",
1034                     j,
1035                     reg_UPDATE_PREDICTION_TABLE [i][j]._condition,
1036                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_src,
1037                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_src<<2,
1038                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_dest,
1039                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_dest<<2,
1040                     reg_UPDATE_PREDICTION_TABLE [i][j]._last_take,
1041                     reg_UPDATE_PREDICTION_TABLE [i][j]._good_take,
1042                     reg_UPDATE_PREDICTION_TABLE [i][j]._is_accurate,
1043                     reg_UPDATE_PREDICTION_TABLE [i][j]._history,
1044                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_ras,
1045                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_ras<<2,
1046                     reg_UPDATE_PREDICTION_TABLE [i][j]._index_ras,
1047                     toString(reg_UPDATE_PREDICTION_TABLE [i][j]._state).c_str()
1048                     );
1049      }
1050#endif
1051
1052#ifdef DEBUG_TEST
1053    for (uint32_t i=0; i<_param->_nb_context; i++)
1054      {
1055        if (reg_UFPT_NB_NEED_UPDATE [i] > _param->_size_ufpt_queue[i])
1056          throw ERRORMORPHEO(FUNCTION,toString(_("reg_UFPT_NB_NEED_UPDATE [%d] (%d) is > at size_ufpt_queue (%d).\n"),i,reg_UFPT_NB_NEED_UPDATE [i],_param->_size_ufpt_queue[i]));
1057        if (reg_UFPT_NB_UPDATE [i] > _param->_size_ufpt_queue[i])
1058          throw ERRORMORPHEO(FUNCTION,toString(_("reg_UFPT_NB_UPDATE [%d] (%d) is > at size_ufpt_queue (%d).\n"),i,reg_UFPT_NB_UPDATE [i],_param->_size_ufpt_queue[i]));
1059      }
1060#endif
1061
1062      }
1063
1064
1065#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
1066    end_cycle ();
1067#endif
1068   
1069    log_end(Update_Prediction_Table,FUNCTION);
1070  };
1071
1072}; // end namespace update_prediction_table
1073}; // end namespace prediction_unit
1074}; // end namespace front_end
1075}; // end namespace multi_front_end
1076}; // end namespace core
1077
1078}; // end namespace behavioural
1079}; // end namespace morpheo             
1080#endif
Note: See TracBrowser for help on using the repository browser.