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

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

1) Add soc test
2) fix bug (Pc management, Decod and execute, Update prediction ...)

  • Property svn:keywords set to Id
File size: 41.0 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Update_Prediction_Table_transition.cpp 101 2009-01-15 17:19:08Z 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_TOP_EVENT        [i] = 0;
47            reg_UPT_UPDATE           [i] = 0;
48            reg_UPT_EMPTY            [i] = true;
49                                                                                   
50            reg_IS_ACCURATE          [i] = true;
51           
52            reg_EVENT_STATE          [i] = EVENT_STATE_OK;
53          }
54      }
55    else
56      {
57        bool flush_UFPT [_param->_nb_context];
58        for (uint32_t i=0; i<_param->_nb_context; i++)
59          flush_UFPT [i] = false;
60
61        // ===================================================================
62        // =====[ GARBAGE COLLECTOR ]=========================================
63        // ===================================================================
64
65        // Each cycle, if the most lastest branch have update all prediction struction (state = end), free this slot
66        //   * Update state -> new status is "empty"
67        //   * Update pointer (bottom and accurate)
68        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * GARBAGE COLLECTOR");
69        for (uint32_t i=0; i<_param->_nb_context; i++)
70          {
71            // UPDATE_FETCH_PREDICTION_TABLE
72            {
73              uint32_t bottom = reg_UFPT_BOTTOM [i];
74             
75              // Test if state is end
76              if (reg_UPDATE_FETCH_PREDICTION_TABLE [i][bottom]._state == UPDATE_FETCH_PREDICTION_STATE_END)
77                {
78                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d]",i,bottom);
79                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state =  UPDATE_FETCH_PREDICTION_STATE_EMPTY",i,bottom);
80
81                  // Free slot
82                  reg_UPDATE_FETCH_PREDICTION_TABLE [i][bottom]._state = UPDATE_FETCH_PREDICTION_STATE_EMPTY;
83                  // Update pointer
84                  reg_UFPT_BOTTOM [i] = (bottom+1)%_param->_size_ufpt_queue[i];
85                }
86            }
87
88            // UPDATE_PREDICTION_TABLE
89            {
90              uint32_t      bottom      = reg_UPT_BOTTOM [i];
91              bool          end_ok      = (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END_OK);
92              bool          end_ko      = (reg_UPDATE_PREDICTION_TABLE [i][bottom]._state == UPDATE_PREDICTION_STATE_END_KO);
93//               event_state_t event_state = reg_EVENT_STATE [i];
94
95              // Test if state is end
96//               if ((end_ok or end_ko) and
97//                   ((event_state != EVENT_STATE_UPDATE_CONTEXT) and
98//                    (event_state != EVENT_STATE_WAIT_END_EVENT)))
99              if (end_ok or end_ko)
100                {
101                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT [%d][%d]",i,bottom);
102                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT [%d][%d]._state =  UPDATE_PREDICTION_STATE_EMPTY",i,bottom);
103
104                  // Free slot
105                  reg_UPDATE_PREDICTION_TABLE [i][bottom]._state = UPDATE_PREDICTION_STATE_EMPTY;
106
107                  // Update pointer
108                  reg_UPT_BOTTOM [i] = (bottom+1)%_param->_size_upt_queue[i];
109
110                  if (reg_UPT_BOTTOM [i] == reg_UPT_TOP [i])
111                    reg_UPT_EMPTY [i] = true; // free a slot
112
113//                   if (bottom = reg_UPT_UPDATE [i])
114//                     reg_UPT_UPDATE [i] = reg_UPT_BOTTOM [i];
115                  if (end_ko) // free
116                    {
117                      reg_UPT_TOP    [i] = reg_UPT_TOP_EVENT [i];
118                      reg_UPT_UPDATE [i] = reg_UPT_TOP_EVENT [i];
119
120                      if (reg_UPT_BOTTOM [i] != reg_UPT_TOP [i])
121                        reg_UPT_EMPTY [i] = false;
122                    }
123                }
124            }
125          }
126
127        // ===================================================================
128        // =====[ PREDICT ]===================================================
129        // ===================================================================
130       
131        // An ifetch_unit compute next cycle and have an branch : predict_val is set
132        //   * Alloc new entry -> new status is "wait decod"
133        //   * Save input (to restore in miss or error)
134        //   * Update pointer
135
136        for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
137          if (PORT_READ(in_PREDICT_VAL[i]) and internal_PREDICT_ACK [i])
138            {
139              Tcontext_t context = (_param->_have_port_context_id)?PORT_READ(in_PREDICT_CONTEXT_ID [i]):0;
140              uint32_t   top     = internal_PREDICT_UPDATE_PREDICTION_ID [i];
141
142              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * PREDICT[%d] - Accepted",i);
143              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
144              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * top     : %d",top);
145
146#ifdef DEBUG_TEST
147              if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._state != UPDATE_FETCH_PREDICTION_STATE_EMPTY)
148                throw ERRORMORPHEO(FUNCTION,_("Predict : invalid state."));
149#endif
150
151              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD (predict)",context,top);
152              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._state        = UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD;
153
154              Tbranch_condition_t condition = PORT_READ(in_PREDICT_BTB_CONDITION [i]);
155
156              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._condition    = condition;
157              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._address_src  = PORT_READ(in_PREDICT_BTB_ADDRESS_SRC  [i]);
158              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._address_dest = PORT_READ(in_PREDICT_BTB_ADDRESS_DEST [i]);
159              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._last_take    = PORT_READ(in_PREDICT_BTB_LAST_TAKE    [i]);
160              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._is_accurate  = PORT_READ(in_PREDICT_BTB_IS_ACCURATE  [i]);
161              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._history      = (_param->_have_port_history)?PORT_READ(in_PREDICT_DIR_HISTORY [i]):0;
162              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._address_ras  = PORT_READ(in_PREDICT_RAS_ADDRESS      [i]);
163              reg_UPDATE_FETCH_PREDICTION_TABLE [context][top]._index_ras    = PORT_READ(in_PREDICT_RAS_INDEX        [i]);
164
165              reg_UFPT_TOP     [context] = (top+1)%_param->_size_ufpt_queue [context];
166//            reg_UFPT_UPDATE  [context] = reg_UFPT_TOP [context];
167              if (need_update(condition))
168                reg_UFPT_NB_NEED_UPDATE [context] ++;
169            }
170
171        // ===================================================================
172        // =====[ DECOD ]=====================================================
173        // ===================================================================
174
175
176        // An decod is detected by decod stage
177        //   1) Hit prediction : The instruction bundle have a branch predicted in ifetch stage and it is this branch
178        //      * Update state, wait_decod -> wait_end
179        //      * Pop ufpt -> push upt
180        //      * Update accurate register : if the predict stage have tagged this branch as not accurate, stop decod
181        //   2) Miss           : The instruction bundle have a branch but it is not predicted
182        //      * Flush ufpt
183        //      * decod information is write in upt
184
185        for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
186          if (PORT_READ(in_DECOD_VAL[i]) and internal_DECOD_ACK [i])
187            {
188              Tcontext_t          context       = (_param->_have_port_context_id)?PORT_READ(in_DECOD_CONTEXT_ID [i]):0;
189              Tcontrol_t          miss_ifetch   = PORT_READ(in_DECOD_MISS_IFETCH [i]);
190              Tcontrol_t          miss_decod    = PORT_READ(in_DECOD_MISS_DECOD  [i]);
191              uint32_t            upt_ptr_write = internal_DECOD_UPT_PTR_WRITE [i];
192              Tbranch_condition_t condition  ;
193              Tcontrol_t          is_accurate;
194              Taddress_t          address_src   = PORT_READ(in_DECOD_BTB_ADDRESS_SRC  [i]);
195              Taddress_t          address_dest  = PORT_READ(in_DECOD_BTB_ADDRESS_DEST [i]);
196              Tcontrol_t          last_take     = PORT_READ(in_DECOD_BTB_LAST_TAKE    [i]);
197
198              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * DECOD[%d] - Accepted",i);
199              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context       : %d",context);
200              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss_ifetch   : %d",miss_ifetch);
201              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss_decod    : %d",miss_decod);
202              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * upt_ptr_write : %d",upt_ptr_write);
203             
204              if (miss_ifetch or miss_decod)
205                {
206                  // Have a miss !!!
207#ifdef DEBUG_TEST
208                  if (reg_EVENT_STATE [context] != EVENT_STATE_OK)
209                    throw ERRORMORPHEO(FUNCTION,_("Decod : invalid event state."));
210#endif
211                 
212                  if (reg_UFPT_NB_NEED_UPDATE [context] == 0)
213                    {
214                      // Change state
215                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_UPDATE_CONTEXT (decod - miss - no flush ufpt)",context);
216                      reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT;
217                    }
218                  else
219                    {
220                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_FLUSH_UFPT (decod - miss - flush ufpt)",context);
221                      reg_EVENT_STATE [context] = EVENT_STATE_FLUSH_UFPT;
222                    }
223
224                  // Flush UPFT
225                  flush_UFPT [context] = true;
226
227                  reg_EVENT_DEPTH           [context] = upt_ptr_write;
228                  reg_EVENT_ADDRESS_SRC     [context] = address_src; // delay_slot is compute in Context_State
229                  reg_EVENT_ADDRESS_DEST_VAL[context] = last_take;
230                  reg_EVENT_ADDRESS_DEST    [context] = address_dest;
231
232                  // Push upt (from decod interface)
233                  condition   = PORT_READ(in_DECOD_BTB_CONDITION [i]);
234                  is_accurate = PORT_READ(in_DECOD_IS_ACCURATE   [i]);
235
236                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._condition         = condition;
237                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_src       = address_src ;
238                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_dest      = address_dest;
239                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._last_take         = last_take   ;
240//                reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._good_take;
241                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._is_accurate       = is_accurate;
242//                reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._history           = ; // static prediction
243                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_ras       = PORT_READ(in_DECOD_RAS_ADDRESS [i]);
244                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._index_ras         = PORT_READ(in_DECOD_RAS_INDEX   [i]);
245                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._ifetch_prediction = false; // static prediction
246                }
247              else
248                {
249                  // Normal case : branch is previous predicated, change state of branch
250                  uint32_t ufpt_ptr_read = (_param->_have_port_depth)?PORT_READ(in_DECOD_UPDATE_PREDICTION_ID [i]):0;
251
252                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * ufpt_ptr_read : %d",ufpt_ptr_read);
253
254#ifdef DEBUG_TEST
255                  if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._state != UPDATE_FETCH_PREDICTION_STATE_WAIT_DECOD)
256                    throw ERRORMORPHEO(FUNCTION,_("Decod : invalid ufpt state."));
257#endif
258                  // Change state
259                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_END (decod - hit)",context,ufpt_ptr_read);
260                  reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._state = UPDATE_FETCH_PREDICTION_STATE_END;
261
262                  // Push upt (from Pop ufpt)
263                  condition   = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._condition;
264                  is_accurate = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._is_accurate;
265
266                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._condition         = condition;
267                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_src       = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._address_src ;
268                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_dest      = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._address_dest;
269                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._last_take         = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._last_take   ;
270//                reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._good_take;
271                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._is_accurate       = is_accurate;
272                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._history           = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._history     ;
273                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._address_ras       = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._address_ras ;
274                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._index_ras         = reg_UPDATE_FETCH_PREDICTION_TABLE [context][ufpt_ptr_read]._index_ras   ;
275                  reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._ifetch_prediction = true; // prediction from ifetch
276
277                  // Update pointer
278                  if (need_update(condition))
279                    {
280                      reg_UFPT_NB_NEED_UPDATE [context] --;
281                    }
282                }
283
284              // All case !!!
285
286#ifdef DEBUG_TEST
287              if (reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._state != UPDATE_PREDICTION_STATE_EMPTY)
288                throw ERRORMORPHEO(FUNCTION,_("Decod : invalid upt state."));
289#endif
290             
291              // Change state
292              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_WAIT_END (decod - hit)",context,upt_ptr_write);
293              reg_UPDATE_PREDICTION_TABLE [context][upt_ptr_write]._state = UPDATE_PREDICTION_STATE_WAIT_END;
294             
295              // Write new accurate
296#ifdef DEBUG_TEST
297              if (not reg_IS_ACCURATE [context]  and not is_accurate)
298                throw ERRORMORPHEO(FUNCTION,_("Decod : invalid accurate flag."));
299#endif
300              reg_IS_ACCURATE [context] = is_accurate;
301             
302              // Update pointer
303              reg_UPT_TOP     [context] = (upt_ptr_write+1)%_param->_size_upt_queue [context];
304              reg_UPT_EMPTY   [context] = false;
305//            reg_UPT_UPDATE  [context] = reg_UPT_TOP [context];
306            }
307
308        // ===================================================================
309        // =====[ BRANCH_COMPLETE ]===========================================
310        // ===================================================================
311       
312        // The branch is complete
313        //   * Hit  prediction :
314        //     * update status
315        //   * Miss prediction :
316        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
317          if (PORT_READ(in_BRANCH_COMPLETE_VAL[i]) and internal_BRANCH_COMPLETE_ACK [i])
318            {
319              Tcontext_t context   = (_param->_have_port_context_id)?PORT_READ(in_BRANCH_COMPLETE_CONTEXT_ID [i]):0;
320              Tdepth_t   depth     = (_param->_have_port_depth     )?PORT_READ(in_BRANCH_COMPLETE_DEPTH      [i]):0;
321              Tcontrol_t miss      = internal_BRANCH_COMPLETE_MISS_PREDICTION [i];
322              Tcontrol_t good_take = internal_BRANCH_COMPLETE_TAKE            [i];
323              Taddress_t good_addr = internal_BRANCH_COMPLETE_ADDRESS_DEST    [i];
324
325              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * BRANCH_COMPLETE[%d] - Accepted",i);
326              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context    : %d",context);
327              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth      : %d",depth);
328              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss       : %d",miss);
329             
330              if (miss)
331                {
332                  // Have a miss !!!
333                  // Flush UPFT
334                  flush_UFPT [context] = true;
335                 
336                  // Flush UPT
337                  uint32_t top        = reg_UPT_TOP [context];
338                  uint32_t new_update = ((top==0)?_param->_size_upt_queue[context]:top)-1; 
339
340                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * top        : %d",top);
341                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * new_update : %d",new_update);
342
343                  for (uint32_t j=(depth+1)%_param->_size_upt_queue[context];
344                                j!=top; 
345                                j=(j+1)%_param->_size_upt_queue[context])
346                    reg_UPDATE_PREDICTION_TABLE [context][j]._state = UPDATE_PREDICTION_STATE_EVENT;
347                 
348                 
349//                reg_UPT_BOTTOM    [context];
350                  reg_UPT_TOP       [context] = depth;
351                  reg_UPT_TOP_EVENT [context] = top;
352
353                  if (reg_UPT_BOTTOM [context] == reg_UPT_TOP [context])
354                    reg_UPT_EMPTY [i] = true;
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_KO (branch_complete, ifetch hit)",context,depth);
362                  reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_KO;
363                 
364                  Taddress_t    address_src         = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src;
365                  event_state_t event_state         = reg_EVENT_STATE [context];
366                  bool          previous_update_ras = (event_state == EVENT_STATE_FLUSH_UPT);
367                  bool          update_ras          = (new_update != depth);
368
369                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * update_ras : %d",update_ras);
370
371                  if (reg_UFPT_NB_NEED_UPDATE [context] > 0)
372                    {
373                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_FLUSH_UFPT_AND_UPT (branch_complete - miss)",context);
374                      reg_EVENT_STATE [context] = EVENT_STATE_FLUSH_UFPT_AND_UPT;
375                    }
376                  else
377                    {
378                      if (not previous_update_ras)
379                        {
380                          // have ras prediction ?
381                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_FLUSH_UPT (branch_complete - miss)",context);
382
383                          reg_EVENT_STATE [context] = EVENT_STATE_FLUSH_UPT;
384             
385                        }
386                    }
387
388                  if (not previous_update_ras)
389                    {
390                      reg_UPT_UPDATE [context]  = new_update;
391                    }
392                  // else no update
393
394                  reg_EVENT_DEPTH           [context] = depth;
395                  reg_EVENT_ADDRESS_SRC     [context] = address_src; // delay_slot is compute in Context_State
396                  reg_EVENT_ADDRESS_DEST_VAL[context] = good_take;
397                  reg_EVENT_ADDRESS_DEST    [context] = good_addr;
398                }
399              else
400                {
401                  // Hit case
402
403#ifdef DEBUG_TEST
404                  if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_WAIT_END)
405                    throw ERRORMORPHEO(FUNCTION,_("Branch complete : invalid upt state."));
406#endif
407                   
408                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_OK (branch_complete, ifetch hit)",context,depth);
409                  reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_OK;
410                }
411
412              // In all case : update good_take
413              reg_UPDATE_PREDICTION_TABLE [context][depth]._good_take = good_take;
414            }
415
416        // ===================================================================
417        // =====[ UPDATE ]====================================================
418        // ===================================================================
419        {
420          bool can_continue [_param->_nb_context];
421          for (uint32_t i=0; i<_param->_nb_context; ++i)
422            can_continue [i] = true;
423
424          for (uint32_t i=0; i<_param->_nb_inst_update; i++)
425            {
426              Tcontext_t context   = internal_UPDATE_CONTEXT_ID [i];
427
428              if ((internal_UPDATE_VAL[i] and PORT_READ(in_UPDATE_ACK [i])) or
429                  (internal_UPDATE_VAL_WITHOUT_ACK [i] and can_continue [context]))
430                {
431                  Tdepth_t   depth     = internal_UPDATE_DEPTH      [i];
432                 
433                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * UPDATE[%d] - Accepted",i);
434                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context : %d",context);
435                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth   : %d",depth);
436                 
437                  if (internal_UPDATE_FROM_UFPT [i])
438                    {
439                      // if free a slot, also all queue is updated
440                      // Last slot ?
441                      if (reg_UFPT_UPDATE [context] == reg_UFPT_BOTTOM [context])
442                        switch (reg_EVENT_STATE [context])
443                          {
444                          case EVENT_STATE_FLUSH_UFPT             : reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT; break;
445                            // impossible to have an update on ufpt and reg_upt_update>reg_upt_top
446                          case EVENT_STATE_FLUSH_UFPT_AND_UPT : reg_EVENT_STATE [context] = EVENT_STATE_FLUSH_UPT ; break;
447                          default : break;
448                          }
449                     
450                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Fetch Prediction Table");
451                     
452                      // Change state
453#ifdef DEBUG_TEST
454                      if (reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state != UPDATE_FETCH_PREDICTION_STATE_EVENT)
455                        throw ERRORMORPHEO(FUNCTION,_("Update : invalid ufpt state."));
456#endif
457                     
458                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UFPT [%d][%d].state <- UPDATE_FETCH_PREDICTION_STATE_END (update)",context,depth);
459                     
460                      reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state = UPDATE_FETCH_PREDICTION_STATE_END;
461                     
462                     
463                      // Update pointer
464                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (before) : %d",reg_UFPT_UPDATE [context]);
465                      reg_UFPT_UPDATE [context] = ((depth==0)?_param->_size_ufpt_queue[context]:depth)-1;
466                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE (after ) : %d",reg_UFPT_UPDATE [context]);
467                      // Free a register that need update ?
468                      if (need_update(reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._condition))
469                        reg_UFPT_NB_NEED_UPDATE [context] --;
470                    }
471                  else
472                    {
473                      log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Prediction Table");
474                     
475                      // Change state
476#ifdef DEBUG_TEST
477                      if (internal_UPDATE_RAS [i])
478                        {
479                          if ((reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_EVENT) and
480                              (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_KO   ))
481                            throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
482                        }
483                      else
484                        {
485                          if (reg_UPDATE_PREDICTION_TABLE [context][depth]._state != UPDATE_PREDICTION_STATE_OK   )
486                            throw ERRORMORPHEO(FUNCTION,_("Update : invalid upt state."));
487                        }
488#endif
489
490//                    bool have_event = ((reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_KO) or
491//                                       (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_EVENT));
492#ifdef STATISTICS
493                      Tbranch_condition_t condition = reg_UPDATE_PREDICTION_TABLE [context][depth]._condition;
494                      bool ok     = (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_OK);
495#endif
496                      bool ko     = (reg_UPDATE_PREDICTION_TABLE [context][depth]._state == UPDATE_PREDICTION_STATE_KO);
497
498                      // Have an update, test the state to transiste to the good state
499                      if (ko)
500                        {
501                          // Ko : wait end of all instruction
502//                           log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_KO_WAIT_END (update)",context,depth);
503                         
504//                           reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END_KO_WAIT_END;
505
506                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_KO (update)",context,depth);
507                         
508                          reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END_KO;
509
510#ifdef STATISTICS
511                          if (usage_is_set(_usage,USE_STATISTICS))
512                            (*_stat_nb_branch_miss [context][condition])++;
513#endif
514                        }
515                      else
516                        {
517                          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_OK (update)",context,depth);
518                         
519                          reg_UPDATE_PREDICTION_TABLE [context][depth]._state = UPDATE_PREDICTION_STATE_END_OK;
520
521
522#ifdef STATISTICS
523                          if (usage_is_set(_usage,USE_STATISTICS))
524                            {
525                              if (ok)
526                                (*_stat_nb_branch_hit    [context][condition]) ++;
527                              else
528                                (*_stat_nb_branch_unused [context]) ++;
529                            }
530#endif
531                        }
532                     
533                      // Update pointer
534                      //  * if update RAS : update pointer is decreaste until it equal at top pointer
535                      if (internal_UPDATE_RAS [i])
536                        {
537                          // if end_event, restart too bottom, else decrease pointer
538                          bool end_event  = (reg_UPT_UPDATE [context] == reg_UPT_TOP [context]);
539                         
540                          reg_UPT_UPDATE [context] = (end_event)?reg_UPT_BOTTOM[context]:(((depth==0)?_param->_size_upt_queue[context]:depth)-1);
541                          if (end_event)
542                            {
543                              reg_UPT_UPDATE [context] = reg_UPT_BOTTOM[context];
544                              reg_EVENT_STATE [context] = EVENT_STATE_UPDATE_CONTEXT;
545                            }
546                          else
547                            {
548                              reg_UPT_UPDATE [context] = (((depth==0)?_param->_size_upt_queue[context]:depth)-1);
549                            }
550                        }
551                      else
552                        {
553                          // increase pointer
554                          reg_UPT_UPDATE [context] = (depth+1)%_param->_size_upt_queue[context];
555                        }
556                     
557                      // Free the branch with no accurate ?
558                      if ( (reg_UPDATE_PREDICTION_TABLE [context][depth]._is_accurate == false) and not ko)
559                        reg_IS_ACCURATE [context] = true;
560                    }
561                }
562              else
563                can_continue [context] = false;
564            }
565       
566          // Round robin
567          reg_UPDATE_PRIORITY = (reg_UPDATE_PRIORITY+1)%_param->_nb_context;
568        }
569
570        // ===================================================================
571        // =====[ BRANCH_EVENT ]==============================================
572        // ===================================================================
573        for (uint32_t i=0; i<_param->_nb_context; i++)
574          if (internal_BRANCH_EVENT_VAL [i] and PORT_READ(in_BRANCH_EVENT_ACK [i]))
575            {
576              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * BRANCH_EVENT [%d] - Accepted",i);
577
578#ifdef DEBUG_TEST
579              if (reg_EVENT_STATE [i] != EVENT_STATE_UPDATE_CONTEXT)
580                throw ERRORMORPHEO(FUNCTION,_("Decod : invalid event state."));
581#endif
582             
583              // Change state
584              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_WAIT_END_EVENT (branch_event)",i);
585             
586              reg_EVENT_STATE [i] = EVENT_STATE_WAIT_END_EVENT;
587            }
588
589        // ===================================================================
590        // =====[ EVENT ]=====================================================
591        // ===================================================================
592        for (uint32_t i=0; i<_param->_nb_context; ++i)
593          if (PORT_READ(in_EVENT_VAL [i]) and internal_EVENT_ACK [i])
594            {
595              //----------------------------------------------------------------
596              // Cases
597              //----------------------------------------------------------------
598              //   * EVENT_TYPE_NONE               - nothing
599              //   * EVENT_TYPE_MISS_SPECULATION   - Change state, reset pointer
600              //   * EVENT_TYPE_EXCEPTION          - Flush upft and upt, Change state, reset pointer
601              //   * EVENT_TYPE_BRANCH_NO_ACCURATE - nothing : manage in decod and update
602              //   * EVENT_TYPE_SPR_ACCESS         - nothing
603              //   * EVENT_TYPE_MSYNC              - nothing
604              //   * EVENT_TYPE_PSYNC              - nothing
605              //   * EVENT_TYPE_CSYNC              - nothing
606             
607              Tevent_type_t  event_type  = PORT_READ(in_EVENT_TYPE  [i]);
608//            Tdepth_t       depth       = PORT_READ(in_EVENT_DEPTH [i]);
609           
610              // Test if end of miss -> all previous branch is complete
611              //                     -> all next     branch is finish
612              if (event_type  == EVENT_TYPE_MISS_SPECULATION)
613                {
614                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * EVENT");
615                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * type  : EVENT_TYPE_MISS_SPECULATION");
616                 
617#ifdef DEBUG_TEST
618                  if (reg_EVENT_STATE [i] != EVENT_STATE_WAIT_END_EVENT)
619                    throw ERRORMORPHEO(FUNCTION,_("Event : invalid event state."));
620#endif
621                 
622                  // Change state
623                  log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * EVENT [%d] <- EVENT_STATE_OK (event)",i);
624                 
625                  reg_EVENT_STATE [i] = EVENT_STATE_OK;
626                  reg_IS_ACCURATE [i] = true;
627
628//                   Tdepth_t depth = reg_UPT_TOP [i];
629
630#ifdef DEBUG_TEST
631//                   if (reg_UPDATE_PREDICTION_TABLE [i][depth]._state != UPDATE_PREDICTION_STATE_END_KO_WAIT_END)
632//                     throw ERRORMORPHEO(FUNCTION,_("Event : invalid upt event state."));
633//                   if (reg_UPDATE_PREDICTION_TABLE [i][depth]._state != UPDATE_PREDICTION_STATE_END_KO)
634//                     throw ERRORMORPHEO(FUNCTION,_("Event : invalid upt event state."));
635#endif
636                 
637//                   log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * UPT  [%d][%d].state <- UPDATE_PREDICTION_STATE_END_KO (update)",i,depth);
638                         
639//                   reg_UPDATE_PREDICTION_TABLE [i][depth]._state = UPDATE_PREDICTION_STATE_END_KO;
640
641                }
642            }
643
644        // ===================================================================
645        // =====[ FLUSH ]=====================================================
646        // ===================================================================
647
648        for (uint32_t i=0; i<_param->_nb_context; ++i)
649          {
650            if (flush_UFPT [i])
651              {
652                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * Flush Update Fetch Prediction Table");
653                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context                          : %d",i);
654                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_NB_NEED_UPDATE          : %d",reg_UFPT_NB_NEED_UPDATE [i]);
655
656              // It's to accelerate miss speculation
657              if (reg_UFPT_NB_NEED_UPDATE [i] == 0)
658                {
659
660                  // No entry need prediction, flush all entry -> Reset
661                  for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; ++j)
662                    reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state = UPDATE_FETCH_PREDICTION_STATE_EMPTY;
663                  reg_UFPT_BOTTOM [i] = 0;
664                  reg_UFPT_TOP    [i] = 0;
665//                reg_UFPT_UPDATE [i];
666                }
667              else
668                {
669                  for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; ++j)
670                    reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state = UPDATE_FETCH_PREDICTION_STATE_EVENT;
671                 
672                  // TOP is next write slot : last slot is TOP-1
673                  uint32_t top = reg_UFPT_TOP [i];
674                  reg_UFPT_UPDATE [i] = ((top==0)?_param->_size_ufpt_queue[i]:top)-1;
675                 
676//                reg_UFPT_BOTTOM [i];
677//                reg_UFPT_TOP    [i];
678                }
679
680              log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UFPT_UPDATE         (after ) : %d",reg_UFPT_UPDATE [i]);
681
682              }
683          }
684
685#ifdef STATISTICS
686        if (usage_is_set(_usage,USE_STATISTICS))
687          for (uint32_t i=0; i<_param->_nb_context; i++)
688            {
689              for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; j++)
690                if (reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state != UPDATE_FETCH_PREDICTION_STATE_EMPTY)
691                  (*_stat_ufpt_queue_nb_elt [i]) ++;
692              for (uint32_t j=0; j<_param->_size_upt_queue[i]; j++)
693                if (reg_UPDATE_PREDICTION_TABLE [i][j]._state != UPDATE_PREDICTION_STATE_EMPTY)
694                  (*_stat_upt_queue_nb_elt [i]) ++;
695            }
696#endif
697       
698        // ===================================================================
699        // =====[ PRINT ]=====================================================
700        // ===================================================================
701
702#if (DEBUG >= DEBUG_TRACE)
703    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * Dump Update_Prediction_Table");
704    log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_UPDATE_PRIORITY       : %d",reg_UPDATE_PRIORITY);
705    for (uint32_t i=0; i<_param->_nb_context; i++)
706      {
707        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_IS_ACCURATE           : %d",reg_IS_ACCURATE        [i]);
708        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_STATE           : %s"  ,toString(reg_EVENT_STATE [i]).c_str());
709        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_DEPTH           : %d"  ,reg_EVENT_DEPTH           [i]);
710        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_ADDRESS_SRC     : %.8x",reg_EVENT_ADDRESS_SRC     [i]);
711        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_ADDRESS_DEST_VAL: %d"  ,reg_EVENT_ADDRESS_DEST_VAL[i]);
712        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * reg_EVENT_ADDRESS_DEST    : %.8x",reg_EVENT_ADDRESS_DEST    [i]);
713
714        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update_Fetch_Prediction_Table   [%d]",i);
715        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_BOTTOM         : %d",reg_UFPT_BOTTOM         [i]);
716        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_TOP            : %d",reg_UFPT_TOP            [i]);
717        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_UPDATE         : %d",reg_UFPT_UPDATE         [i]);
718        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UFPT_NB_NEED_UPDATE : %d",reg_UFPT_NB_NEED_UPDATE [i]);
719        for (uint32_t j=0; j<_param->_size_ufpt_queue[i]; j++)
720          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"        [%d] %.4d, %.8x %.8x, %.1d   %.1d, %.8d %.8x %.4d - %s",
721                     j,
722                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._condition,
723                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_src,
724                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_dest,
725                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._last_take,
726                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._is_accurate,
727                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._history,
728                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._address_ras,
729                     reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._index_ras,
730                     toString(reg_UPDATE_FETCH_PREDICTION_TABLE [i][j]._state).c_str()
731                     );
732
733        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update_Prediction_Table   [%d]",i);
734        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_BOTTOM          : %d",reg_UPT_BOTTOM         [i]);
735        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_TOP             : %d",reg_UPT_TOP            [i]);
736        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_TOP_EVENT       : %d",reg_UPT_TOP_EVENT      [i]);
737        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_UPDATE          : %d",reg_UPT_UPDATE         [i]);
738        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"      * reg_UPT_EMPTY           : %d",reg_UPT_EMPTY          [i]);
739        for (uint32_t j=0; j<_param->_size_upt_queue[i]; j++)
740          log_printf(TRACE,Update_Prediction_Table,FUNCTION,"        [%d] %.4d, %.8x %.8x, %.1d %.1d %.1d, %.8d %.8x %.4d - %s",
741                     j,
742                     reg_UPDATE_PREDICTION_TABLE [i][j]._condition,
743                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_src,
744                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_dest,
745                     reg_UPDATE_PREDICTION_TABLE [i][j]._last_take,
746                     reg_UPDATE_PREDICTION_TABLE [i][j]._good_take,
747                     reg_UPDATE_PREDICTION_TABLE [i][j]._is_accurate,
748                     reg_UPDATE_PREDICTION_TABLE [i][j]._history,
749                     reg_UPDATE_PREDICTION_TABLE [i][j]._address_ras,
750                     reg_UPDATE_PREDICTION_TABLE [i][j]._index_ras,
751                     toString(reg_UPDATE_PREDICTION_TABLE [i][j]._state).c_str()
752                     );
753      }
754#endif
755      }
756
757
758#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
759    end_cycle ();
760#endif
761   
762    log_end(Update_Prediction_Table,FUNCTION);
763  };
764
765}; // end namespace update_prediction_table
766}; // end namespace prediction_unit
767}; // end namespace front_end
768}; // end namespace multi_front_end
769}; // end namespace core
770
771}; // end namespace behavioural
772}; // end namespace morpheo             
773#endif
Note: See TracBrowser for help on using the repository browser.