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

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

Update document on Vhdl generation.

  • Property svn:keywords set to Id
File size: 31.5 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Update_Prediction_Table_transition.cpp 94 2008-12-15 11:04:03Z 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                                                               
42            for (uint32_t j=0; j<_param->_size_upt_queue[i]; ++j)
43              reg_UPDATE_PREDICTION_TABLE [i][j]._state = UPDATE_PREDICTION_STATE_EMPTY;
44            reg_UPT_BOTTOM           [i] = 0;
45            reg_UPT_TOP              [i] = 0;
46            reg_UPT_UPDATE           [i] = 0;
47                                                                                   
48            reg_IS_ACCURATE          [i] = true;
49           
50            reg_EVENT_STATE          [i] = EVENT_STATE_OK;
51          }
52      }
53    else
54      {
55        bool flush_UFPT [_param->_nb_context];
56        for (uint32_t i=0; i<_param->_nb_context; i++)
57          flush_UFPT [i] = false;
58
59        // ===================================================================
60        // =====[ GARBAGE COLLECTOR ]=========================================
61        // ===================================================================
62
63        // Each cycle, if the most lastest branch have update all prediction struction (state = end), free this slot
64        //   * Update state -> new status is "empty"
65        //   * Update pointer (bottom and accurate)
66        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * GARBAGE COLLECTOR");
67        for (uint32_t i=0; i<_param->_nb_context; i++)
68          {
69            // UPDATE_FETCH_PREDICTION_TABLE
70            {
71              uint32_t bottom = reg_UFPT_BOTTOM [i];
72             
73              // Test if state is end
74              if (reg_UPDATE_FETCH_PREDICTION_TABLE [i][bottom]._state == UPDATE_FETCH_PREDICTION_STATE_END)
75                {
76                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d]",i,bottom);
77                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state =  UPDATE_FETCH_PREDICTION_STATE_EMPTY",i,bottom);
78
79                  // Free slot
80                  reg_UPDATE_FETCH_PREDICTION_TABLE [i][bottom]._state = UPDATE_FETCH_PREDICTION_STATE_EMPTY;
81                  // Update pointer
82                  reg_UFPT_BOTTOM [i] = (bottom+1)%_param->_size_ufpt_queue[i];
83                }
84            }
85
86            // UPDATE_PREDICTION_TABLE
87            {
88              uint32_t bottom = reg_UPT_BOTTOM [i];
89             
90              // Test if state is end
91              if (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END)
92                {
93                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT [%d][%d]",i,bottom);
94                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT [%d][%d]._state =  UPDATE_PREDICTION_STATE_EMPTY",i,bottom);
95
96                  // Free slot
97                  reg_UPDATE_PREDICTION_TABLE [i][bottom]._state = UPDATE_PREDICTION_STATE_EMPTY;
98                  // Update pointer
99                  reg_UPT_BOTTOM [i] = (bottom+1)%_param->_size_upt_queue[i];
100                }
101            }
102          }
103
104        // ===================================================================
105        // =====[ PREDICT ]===================================================
106        // ===================================================================
107       
108        // An ifetch_unit compute next cycle and have an branch : predict_val is set
109        //   * Alloc new entry -> new status is "wait decod"
110        //   * Save input (to restore in miss or error)
111        //   * Update pointer
112
113        for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
114          if (PORT_READ(in_PREDICT_VAL[i]) and internal_PREDICT_ACK [i])
115            {
116              Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_PREDICT_CONTEXT_ID [i]):0;
117              uint32_t   top     = internal_PREDICT_UPDATE_PREDICTION_ID [i];
118
119              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * PREDICT[%d] - Accepted",i);
120              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
121              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * top     : %d",top);
122
123#ifdef DEBUG_TEST
124              if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._state != UPDATE_FETCH_PREDICTION_STATE_EMPTY)
125                throw ERRORMORPHEO(FUNCTION,_("Predict : invalid state."));
126#endif
127
128              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD (predict)",context,top);
129              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._state        = UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD;
130
131              Tbranch_condition_t condition = PORT_READ(in_PREDICT_BTB_CONDITION [i]);
132
133              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._condition    = condition;
134              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._address_src  = PORT_READ(in_PREDICT_BTB_ADDRESS_SRC  [i]);
135              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._address_dest = PORT_READ(in_PREDICT_BTB_ADDRESS_DEST [i]);
136              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._last_take    = PORT_READ(in_PREDICT_BTB_LAST_TAKE    [i]);
137              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._is_accurate  = PORT_READ(in_PREDICT_BTB_IS_ACCURATE  [i]);
138              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._history      = (_param->_have_port_history)?PORT_READ(in_PREDICT_DIR_HISTORY [i]):0;
139              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._address_ras  = PORT_READ(in_PREDICT_RAS_ADDRESS      [i]);
140              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._index_ras    = PORT_READ(in_PREDICT_RAS_INDEX        [i]);
141
142              reg_UFPT_TOP     [context] = (top+1)%_param->_size_ufpt_queue [context];
143//            reg_UFPT_UPDATE  [context] = reg_UFPT_TOP [context];
144              if (need_update(condition))
145                reg_UFPT_NB_NEED_UPDATE [context] ++;
146            }
147
148        // ===================================================================
149        // =====[ DECOD ]=====================================================
150        // ===================================================================
151
152
153        // An decod is detected by decod stage
154        //   1) Hit prediction : The instruction bundle have a branch predicted in ifetch stage and it is this branch
155        //      * Update state, wait_decod -> wait_end
156        //      * Pop ufpt -> push upt
157        //      * Update accurate register : if the predict stage have tagged this branch as not accurate, stop decod
158        //   2) Miss           : The instruction bundle have a branch but it is not predicted
159        //      * Flush ufpt
160        //      * decod information is write in upt
161
162        for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
163          if (PORT_READ(in_DECOD_VAL[i]) and internal_DECOD_ACK [i])
164            {
165              Tcontext_t          context       = (_param->_have_port_context_id)?PORT_READ(in_DECOD_CONTEXT_ID [i]):0;
166              Tcontrol_t          miss_ifetch   = PORT_READ(in_DECOD_MISS_IFETCH [i]);
167              Tcontrol_t          miss_decod    = PORT_READ(in_DECOD_MISS_DECOD  [i]);
168              uint32_t            upt_ptr_write = internal_DECOD_UPT_PTR_WRITE [i];
169              Tbranch_condition_t condition  ;
170              Tcontrol_t          is_accurate;
171              Taddress_t          address_src   = PORT_READ(in_DECOD_BTB_ADDRESS_SRC  [i]);
172              Taddress_t          address_dest  = PORT_READ(in_DECOD_BTB_ADDRESS_DEST [i]);
173              Tcontrol_t          last_take     = PORT_READ(in_DECOD_BTB_LAST_TAKE    [i]);
174
175              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * DECOD[%d] - Accepted",i);
176              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context       : %d",context);
177              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss_ifetch   : %d",miss_ifetch);
178              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss_decod    : %d",miss_decod);
179              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * upt_ptr_write : %d",upt_ptr_write);
180             
181              if (miss_ifetch or miss_decod)
182                {
183                  // Have a miss !!!
184#ifdef DEBUG_TEST
185                  if (reg_EVENT_STATE [context] != EVENT_STATE_OK)
186                    throw ERRORMORPHEO(FUNCTION,_("Decod : invalid event state."));
187#endif
188                 
189                  if (reg_UFPT_NB_NEED_UPDATE [context] == 0)
190                    {
191                      // Change state
192                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_UPDATE_CONTEXT (decod - miss - no flush ufpt)",context);
193                      reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT;
194                    }
195                  else
196                    {
197                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_FLUSH_UFPT (decod - miss - flush ufpt)",context);
198                      reg_EVENT_STATE [context] = EVENT_STATE_FLUSH_UFPT;
199                    }
200
201                  // Flush UPFT
202                  flush_UFPT [context] = true;
203
204                  reg_EVENT_ADDRESS_SRC     [context] = address_src; // delay_slot is compute in Context_State
205                  reg_EVENT_ADDRESS_DEST_VAL[context] = last_take;
206                  reg_EVENT_ADDRESS_DEST    [context] = address_dest;
207
208                  // Push upt (from decod interface)
209                  condition   = PORT_READ(in_DECOD_BTB_CONDITION [i]);
210                  is_accurate = PORT_READ(in_DECOD_IS_ACCURATE   [i]);
211
212                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._condition         = condition;
213                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_src       = address_src ;
214                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_dest      = address_dest;
215                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._last_take         = last_take   ;
216//                reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._good_take;
217                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._is_accurate       = is_accurate;
218//                reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._history           = ; // static prediction
219                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_ras       = PORT_READ(in_DECOD_RAS_ADDRESS [i]);
220                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._index_ras         = PORT_READ(in_DECOD_RAS_INDEX   [i]);
221                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._ifetch_prediction = false; // static prediction
222                }
223              else
224                {
225                  // Normal case : branch is previous predicated, change state of branch
226                  uint32_t ufpt_ptr_read = (_param->_have_port_depth)?PORT_READ(in_DECOD_UPDATE_PREDICTION_ID [i]):0;
227
228                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * ufpt_ptr_read : %d",ufpt_ptr_read);
229
230#ifdef DEBUG_TEST
231                  if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._state != UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD)
232                    throw ERRORMORPHEO(FUNCTION,_("Decod : invalid ufpt state."));
233#endif
234                  // Change state
235                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_END (decod - hit)",context,ufpt_ptr_read);
236                  reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._state = UPDATE_FETCH_PREDICTION_STATE_END;
237
238                  // Push upt (from Pop ufpt)
239                  condition   = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._condition;
240                  is_accurate = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._is_accurate;
241
242                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._condition         = condition;
243                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_src       = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._address_src ;
244                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_dest      = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._address_dest;
245                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._last_take         = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._last_take   ;
246//                reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._good_take;
247                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._is_accurate       = is_accurate;
248                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._history           = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._history     ;
249                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_ras       = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._address_ras ;
250                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._index_ras         = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._index_ras   ;
251                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._ifetch_prediction = true; // prediction from ifetch
252
253                  // Update pointer
254                  if (need_update(condition))
255                    {
256                      reg_UFPT_NB_NEED_UPDATE [context] --;
257                    }
258                }
259
260              // All case !!!
261
262#ifdef DEBUG_TEST
263              if (reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._state != UPDATE_PREDICTION_STATE_EMPTY)
264                throw ERRORMORPHEO(FUNCTION,_("Decod : invalid upt state."));
265#endif
266             
267              // Change state
268              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_WAIT_END (decod - hit)",context,upt_ptr_write);
269              reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._state = UPDATE_PREDICTION_STATE_WAIT_END;
270             
271              // Write new accurate
272#ifdef DEBUG_TEST
273              if (not reg_IS_ACCURATE [context]  and not is_accurate)
274                throw ERRORMORPHEO(FUNCTION,_("Decod : invalid accurate flag."));
275#endif
276              reg_IS_ACCURATE [context] = is_accurate;
277             
278              // Update pointer
279              reg_UPT_TOP     [context] = (upt_ptr_write+1)%_param->_size_upt_queue [context];
280//            reg_UPT_UPDATE  [context] = reg_UPT_TOP [context];
281            }
282
283        // ===================================================================
284        // =====[ BRANCH_COMPLETE ]===========================================
285        // ===================================================================
286       
287        // The branch is complete
288        //   * Hit  prediction :
289        //     * update status
290        //   * Miss prediction :
291        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
292          if (PORT_READ(in_BRANCH_COMPLETE_VAL[i]) and internal_BRANCH_COMPLETE_ACK [i])
293            {
294              Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_BRANCH_COMPLETE_CONTEXT_ID [i]):0;
295              Tdepth_t   depth   = (_param->_have_port_depth     )?PORT_READ(in_BRANCH_COMPLETE_DEPTH      [i]):0;
296              Tcontrol_t miss      = internal_BRANCH_COMPLETE_MISS_PREDICTION [i];
297              Tcontrol_t good_take = internal_BRANCH_COMPLETE_TAKE            [i];
298              Taddress_t good_addr = internal_BRANCH_COMPLETE_ADDRESS_DEST    [i];
299
300              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * BRANCH_COMPLETE[%d] - Accepted",i);
301              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
302              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth   : %d",depth);
303              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss    : %d",miss);
304             
305              if (miss)
306                {
307                  // Have a miss !!!
308                  // Flush UPFT
309                  flush_UFPT [context] = true;
310                 
311                  // Flush UPT
312                  uint32_t top        = reg_UPT_TOP [context];
313                  uint32_t new_update = ((top==0)?_param->_size_upt_queue[context]:top)-1; 
314                  for (uint32_t j=(depth+1)%_param->_size_upt_queue[context];
315                                j!=top; 
316                                j=(j+1)%_param->_size_upt_queue[context])
317                    reg_UPDATE_PREDICTION_TABLE [context][j]._state = UPDATE_PREDICTION_STATE_EVENT;
318                 
319                  // TOP is next write slot : last slot is TOP-1
320                  reg_UPT_UPDATE [context] = new_update;
321                 
322//                reg_UPT_BOTTOM [context];
323                  reg_UPT_TOP    [context] = depth;
324
325#ifdef DEBUG_TEST
326                  if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_WAIT_END)
327                    throw ERRORMORPHEO(FUNCTION,_("Branch complete : invalid upt state."));
328#endif
329                 
330                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_KO (branch_complete, ifetch hit)",context,depth);
331                  reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_KO;
332                 
333
334                  Taddress_t          address_src = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src;
335
336                  if (reg_UFPT_NB_NEED_UPDATE [context] > 0)
337                    {
338                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_FLUSH_UFPT_AND_UPT (branch_complete - miss)",context);
339                      reg_EVENT_STATE [context] = EVENT_STATE_FLUSH_UFPT_AND_UPT;
340                    }
341                  else
342                    {
343                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_FLUSH_UFPT_RAS (branch_complete - miss)",context);
344                      // have ras prediction ?
345                      reg_EVENT_STATE [context] = (new_update!=depth)?EVENT_STATE_FLUSH_UPT_RAS:EVENT_STATE_UPDATE_CONTEXT;
346                    }
347
348                  reg_EVENT_ADDRESS_SRC     [context] = address_src; // delay_slot is compute in Context_State
349                  reg_EVENT_ADDRESS_DEST_VAL[context] = good_take;
350                  reg_EVENT_ADDRESS_DEST    [context] = good_addr;
351                }
352              else
353                {
354                  // Hit case
355
356#ifdef DEBUG_TEST
357                  if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_WAIT_END)
358                    throw ERRORMORPHEO(FUNCTION,_("Branch complete : invalid upt state."));
359#endif
360                   
361                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_OK (branch_complete, ifetch hit)",context,depth);
362                  reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_OK;
363                }
364
365              // In all case : update good_take
366              reg_UPDATE_PREDICTION_TABLE [context][depth]._good_take = good_take;
367            }
368
369        // ===================================================================
370        // =====[ UPDATE ]====================================================
371        // ===================================================================
372        for (uint32_t i=0; i<_param->_nb_inst_update; i++)
373          if ((internal_UPDATE_VAL[i] and PORT_READ(in_UPDATE_ACK [i])) or
374              (internal_UPDATE_VAL_WITHOUT_ACK [i]))
375            {
376              Tcontext_t context = internal_UPDATE_CONTEXT_ID [i];
377              Tdepth_t   depth   = internal_UPDATE_DEPTH      [i];
378              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * UPDATE[%d] - Accepted",i);
379              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
380              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth   : %d",depth);
381
382              if (internal_UPDATE_FROM_UFPT [i])
383                {
384                // if free a slot, also all queue is updated
385                // Last slot ?
386                if (reg_UFPT_UPDATE [context] == reg_UFPT_BOTTOM [context])
387                  switch (reg_EVENT_STATE [context])
388                    {
389                    case EVENT_STATE_FLUSH_UFPT         : reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT; break;
390                    case EVENT_STATE_FLUSH_UFPT_AND_UPT : reg_EVENT_STATE [context] = (reg_UPT_UPDATE[context]!=reg_UPT_TOP[context])?EVENT_STATE_FLUSH_UPT_RAS:EVENT_STATE_UPDATE_CONTEXT;  break;
391                    default : break;
392                    }
393               
394                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Fetch Prediction Table");
395                 
396                  // Change state
397#ifdef DEBUG_TEST
398                  if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state != UPDATE_FETCH_PREDICTION_STATE_EVENT)
399                    throw ERRORMORPHEO(FUNCTION,_("Update : invalid ufpt state."));
400#endif
401
402                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_END (update)",context,depth);
403
404                  reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state = UPDATE_FETCH_PREDICTION_STATE_END;
405
406
407                  // Update pointer
408                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (before) : %d",reg_UFPT_UPDATE [context]);
409                  reg_UFPT_UPDATE [context] = ((depth==0)?_param->_size_ufpt_queue[context]:depth)-1;
410                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (after ) : %d",reg_UFPT_UPDATE [context]);
411                  // Free a register that need update ?
412                  if (need_update(reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._condition))
413                    reg_UFPT_NB_NEED_UPDATE [context] --;
414                }
415              else
416                {
417                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Prediction Table");
418                 
419                  // Change state
420#ifdef DEBUG_TEST
421                  if (internal_UPDATE_RAS [i])
422                    {
423                      if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_EVENT)
424                        throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
425                    }
426                  else
427                    {
428                      if ((reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_OK   ) and
429                          (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_KO   ))
430                        throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
431                    }
432#endif
433
434                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END (update)",context,depth);
435
436                  reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END;
437
438                  // Update pointer
439                  bool end_event = (reg_UPT_UPDATE [context] == reg_UPT_TOP [context]);
440
441                  if (internal_UPDATE_RAS [i])
442                    {
443                      reg_UPT_UPDATE [context] = (end_event)?reg_UPT_BOTTOM[context]:(((depth==0)?_param->_size_upt_queue[context]:depth)-1);
444                    }
445                  else
446                    {
447                      reg_UPT_UPDATE [context] = (depth+1)%_param->_size_upt_queue[context];
448                    }
449                 
450                  // End and event ?
451                  if (end_event and
452                      (reg_EVENT_STATE [context] != EVENT_STATE_OK))
453                    {
454                      reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT;
455                    }
456
457                  // Free the branch with no accurate ?
458                  if (reg_UPDATE_PREDICTION_TABLE [context][depth]._is_accurate == false)
459                    reg_IS_ACCURATE [context] = true;
460                }
461            }
462       
463        // Round robin
464        reg_UPDATE_PRIORITY = (reg_UPDATE_PRIORITY+1)%_param->_nb_context;
465
466        // ===================================================================
467        // =====[ BRANCH_EVENT ]==============================================
468        // ===================================================================
469        for (uint32_t i=0; i<_param->_nb_context; i++)
470          if (internal_BRANCH_EVENT_VAL [i] and PORT_READ(in_BRANCH_EVENT_ACK [i]))
471            {
472              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * UPDATE[%d] - Accepted",i);
473
474#ifdef DEBUG_TEST
475              if (reg_EVENT_STATE [i] != EVENT_STATE_UPDATE_CONTEXT)
476                throw ERRORMORPHEO(FUNCTION,_("Decod : invalid event state."));
477#endif
478             
479              // Change state
480              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_OK (branch_event)",i);
481             
482              reg_EVENT_STATE [i] = EVENT_STATE_OK;
483            }
484
485        // ===================================================================
486        // =====[ FLUSH ]=====================================================
487        // ===================================================================
488
489        for (uint32_t i=0; i<_param->_nb_context; ++i)
490          {
491            if (flush_UFPT [i])
492              {
493                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * Flush Update Fetch Prediction Table");
494                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context                          : %d",i);
495                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE          : %d",reg_UFPT_NB_NEED_UPDATE [i]);
496
497              // It's to accelerate miss speculation
498              if (reg_UFPT_NB_NEED_UPDATE [i] == 0)
499                {
500
501                  // No entry need prediction, flush all entry -> Reset
502                  for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; ++j)
503                    reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state = UPDATE_FETCH_PREDICTION_STATE_EMPTY;
504                  reg_UFPT_BOTTOM [i] = 0;
505                  reg_UFPT_TOP    [i] = 0;
506//                reg_UFPT_UPDATE [i];
507                }
508              else
509                {
510                  for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; ++j)
511                    reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state = UPDATE_FETCH_PREDICTION_STATE_EVENT;
512                 
513                  // TOP is next write slot : last slot is TOP-1
514                  uint32_t top = reg_UFPT_TOP [i];
515                  reg_UFPT_UPDATE [i] = ((top==0)?_param->_size_ufpt_queue[i]:top)-1;
516                 
517//                reg_UFPT_BOTTOM [i];
518//                reg_UFPT_TOP    [i];
519                }
520
521              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE         (after ) : %d",reg_UFPT_UPDATE [i]);
522
523              }
524          }
525
526        // ===================================================================
527        // =====[ PRINT ]=====================================================
528        // ===================================================================
529
530#if (DEBUG >= DEBUG_TRACE)
531    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * Dump Update_Prediction_Table");
532    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UPDATE_PRIORITY       : %d",reg_UPDATE_PRIORITY);
533    for (uint32_t i=0; i<_param->_nb_context; i++)
534      {
535        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_IS_ACCURATE           : %d",reg_IS_ACCURATE        [i]);
536        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_STATE           : %s"  ,toString(reg_EVENT_STATE [i]).c_str());
537        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_ADDRESS_SRC     : %.8x",reg_EVENT_ADDRESS_SRC     [i]);
538        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_ADDRESS_DEST_VAL: %d"  ,reg_EVENT_ADDRESS_DEST_VAL[i]);
539        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_ADDRESS_DEST    : %.8x",reg_EVENT_ADDRESS_DEST    [i]);
540
541        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update_Fetch_Prediction_Table   [%d]",i);
542        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_BOTTOM         : %d",reg_UFPT_BOTTOM         [i]);
543        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_TOP            : %d",reg_UFPT_TOP            [i]);
544        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_UPDATE         : %d",reg_UFPT_UPDATE         [i]);
545        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_NB_NEED_UPDATE : %d",reg_UFPT_NB_NEED_UPDATE [i]);
546        for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; j++)
547          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"        [%d] %.4d, %.8x %.8x, %.1d   %.1d, %.8d %.8x %.4d - %s",
548                     j,
549                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._condition,
550                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_src,
551                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_dest,
552                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._last_take,
553                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._is_accurate,
554                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._history,
555                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_ras,
556                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._index_ras,
557                     toString(reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state).c_str()
558                     );
559
560        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update_Prediction_Table   [%d]",i);
561        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_BOTTOM          : %d",reg_UPT_BOTTOM         [i]);
562        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_TOP             : %d",reg_UPT_TOP            [i]);
563        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_UPDATE          : %d",reg_UPT_UPDATE         [i]);
564        for (uint32_t j=0; j<_param->_size_upt_queue[i]; j++)
565          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"        [%d] %.4d, %.8x %.8x, %.1d %.1d %.1d, %.8d %.8x %.4d - %s",
566                     j,
567                     reg_UPDATE_PREDICTION_TABLE [i][j]._condition,
568                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_src,
569                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_dest,
570                     reg_UPDATE_PREDICTION_TABLE [i][j]._last_take,
571                     reg_UPDATE_PREDICTION_TABLE [i][j]._good_take,
572                     reg_UPDATE_PREDICTION_TABLE [i][j]._is_accurate,
573                     reg_UPDATE_PREDICTION_TABLE [i][j]._history,
574                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_ras,
575                     reg_UPDATE_PREDICTION_TABLE [i][j]._index_ras,
576                     toString(reg_UPDATE_PREDICTION_TABLE [i][j]._state).c_str()
577                     );
578      }
579#endif
580      }
581
582
583#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
584    end_cycle ();
585#endif
586   
587    log_end(Update_Prediction_Table,FUNCTION);
588  };
589
590}; // end namespace update_prediction_table
591}; // end namespace prediction_unit
592}; // end namespace front_end
593}; // end namespace multi_front_end
594}; // end namespace core
595
596}; // end namespace behavioural
597}; // end namespace morpheo             
598#endif
Note: See TracBrowser for help on using the repository browser.