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

Last change on this file since 98 was 98, checked in by rosiere, 16 years ago

1) Fix bug (read unit, RAT -> write in R0, SPR desallocation ...)
2) Change VHDL Execute_queue -> use Generic/Queue?
3) Complete document on VHDL generation
4) Add soc test

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