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

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

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

  • Property svn:keywords set to Id
File size: 19.8 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Return_Address_Stack_transition.cpp 111 2009-02-27 18:37:40Z rosiere $
4 *
5 * [ Description ]
6 *
7 */
8
9#include "Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Return_Address_Stack/include/Return_Address_Stack.h"
10
11namespace morpheo                    {
12namespace behavioural {
13namespace core {
14namespace multi_front_end {
15namespace front_end {
16namespace prediction_unit {
17namespace return_address_stack {
18
19
20#undef  FUNCTION
21#define FUNCTION "Return_Address_Stack::transition"
22  void Return_Address_Stack::transition (void)
23  {
24    log_begin(Return_Address_Stack,FUNCTION);
25    log_function(Return_Address_Stack,FUNCTION,_name.c_str());
26
27    if (PORT_READ(in_NRESET)==0)
28      {
29        // Reset all structure
30        for (uint32_t i=0; i<_param->_nb_context; i++)
31          {
32            reg_TOP    [i] = 0;
33//          reg_BOTTOM [i] = 0;
34            reg_NB_ELT [i] = 0;
35
36            reg_PREDICT_TOP    [i] = 0;
37//          reg_PREDICT_BOTTOM [i] = 0;
38            reg_PREDICT_NB_ELT [i] = 0;
39          }
40      }
41    else
42      {
43        // ===================================================================
44        // =====[ PREDICT ]===================================================
45        // ===================================================================
46        for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
47          if (PORT_READ(in_PREDICT_VAL [i]) and internal_PREDICT_ACK [i])
48            {
49              log_printf(TRACE,Return_Address_Stack,FUNCTION,"  * PREDICT [%d] : Transaction",i);
50             
51              // Read information and pointer
52              Tcontext_t context    = (_param->_have_port_context_id)?PORT_READ(in_PREDICT_CONTEXT_ID [i]):0;
53              Tcontrol_t push       = PORT_READ(in_PREDICT_PUSH [i]);
54
55              Tptr_t     top_old    = reg_PREDICT_TOP    [context];
56              Tptr_t     top_new    = top_old;
57//            Tptr_t     bottom_old = reg_PREDICT_BOTTOM [context];
58//            Tptr_t     bottom_new = bottom_old;
59              Tptr_t     nb_elt_old = reg_PREDICT_NB_ELT [context];
60              Tptr_t     nb_elt_new = nb_elt_old;
61
62              log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * context : %d",context);
63
64              // Hit  : push or not empty
65              // Miss : ifetch is stall, no update
66
67              // Test if hit
68              if (internal_PREDICT_HIT [i])
69                {
70                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * before");
71                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_old);
72//                log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_old);
73                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_old);
74
75                  // Test if push
76                  if (push)
77                    {
78                      Taddress_t address = PORT_READ(in_PREDICT_ADDRESS_PUSH [i]);
79
80                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * push (call procedure)");
81                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * address_push        : 0x%.8x",address);
82
83                      // push : increase the top (circular)
84                      top_new = (top_old+1)%_param->_size_queue[context];
85
86                      // Write new value in Queue
87                      reg_stack [context][top_new]._address = address;
88
89                      // Test if full
90                      //   -> is full, the push erase the oldest value in stack, also nb_elt is the same
91                      //   -> is not full, increase nb_elt
92//                    if (nb_elt_old==_param->_size_queue[context])
93//                      bottom_new = (bottom_old+1)%_param->_size_queue[context];
94//                       else
95//                      nb_elt_new ++;
96                      if (nb_elt_old!=_param->_size_queue[context])
97                        nb_elt_new ++;
98                    }
99                  else
100                    {
101                      // pop
102                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * pop (return procedure)");
103
104                      // Test if the stack is empty
105                      if (nb_elt_old>0)
106                        {
107                          top_new = (top_old==0)?(_param->_size_queue[context]-1):(top_old-1);
108                          nb_elt_new --;
109                        }
110                      // no else : can't pop
111                    }
112                 
113                  // Write new pointer
114                  reg_PREDICT_TOP    [context] = top_new;
115//                reg_PREDICT_BOTTOM [context] = bottom_new;
116                  reg_PREDICT_NB_ELT [context] = nb_elt_new;
117
118                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * after");
119                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_new);
120//                log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_new);
121                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_new);
122                }
123            }
124
125        // ===================================================================
126        // =====[ DECOD ]=====================================================
127        // ===================================================================
128        for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
129          if (PORT_READ(in_DECOD_VAL [i]) and internal_DECOD_ACK [i])
130            {
131              log_printf(TRACE,Return_Address_Stack,FUNCTION,"  * DECOD [%d] : Transaction",i);
132
133              // Read information
134              Tcontext_t context    = (_param->_have_port_context_id)?PORT_READ(in_DECOD_CONTEXT_ID [i]):0;
135              Tcontrol_t push       = PORT_READ(in_DECOD_PUSH [i]);
136
137              // Read pointer
138              Tptr_t     top_old    = reg_TOP    [context];
139              Tptr_t     top_new    = top_old;
140//            Tptr_t     bottom_old = reg_BOTTOM [context];
141//            Tptr_t     bottom_new = bottom_old;
142              Tptr_t     nb_elt_old = reg_NB_ELT [context];
143              Tptr_t     nb_elt_new = nb_elt_old;
144
145              log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * context : %d",context);
146
147              log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * before");
148              log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_old);
149//            log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_old);
150              log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_old);
151
152              // Test if push
153              if (push)
154                {
155                  Taddress_t address = PORT_READ(in_DECOD_ADDRESS_PUSH [i]);
156                 
157                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * push (call procedure)");
158                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * address_push        : 0x%.8x",address);
159                 
160                  // push : increase the top (circular)
161                  top_new = (top_old+1)%_param->_size_queue[context];
162                 
163                  // Write new value in Queue
164                  reg_stack [context][top_new]._address = address;
165                 
166                  // Test if full
167                  //   -> is full, the push erase the oldest value in stack, also nb_elt is the same
168                  //   -> is not full, increase nb_elt
169//                   if (nb_elt_old==_param->_size_queue[context])
170//                     bottom_new = (bottom_old+1)%_param->_size_queue[context];
171//                   else
172//                     nb_elt_new ++;
173                  if (nb_elt_old!=_param->_size_queue[context])
174                    nb_elt_new ++;
175                }
176              else
177                {
178                  // pop
179                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * pop (return procedure)");
180                 
181                  // Test if the stack is empty
182                  if (nb_elt_old>0)
183                    {
184                      top_new = (top_old==0)?(_param->_size_queue[context]-1):(top_old-1);
185                      nb_elt_new --;
186                    }
187                  // no else : can't pop
188                }
189             
190              // Write new pointer
191              reg_TOP    [context] = top_new;
192//            reg_BOTTOM [context] = bottom_new;
193              reg_NB_ELT [context] = nb_elt_new;
194             
195              log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * after");
196              log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_new);
197//            log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_new);
198              log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_new);
199             
200              // have previous miss of ifetch ?
201              // 2 miss :
202              //   1) miss predict : is very limited (local at context), can be update very quickly
203              //   2) miss decod   : result is in commit stage ...
204
205              // manage by Update_Fetch_Prediction_Table and Update_Prediction_Table
206              // Note :
207              //   if decod miss : ifetch can have predict call and return branchement. Also, the head of decod can be false
208
209              Tcontrol_t miss       = PORT_READ(in_DECOD_MISS_PREDICTION [i]);
210
211              log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * miss                : %d",miss);
212
213              if (miss)
214                {
215
216//                reg_PREDICT_BOTTOM [context] = reg_BOTTOM [context];
217                  reg_PREDICT_TOP    [context] = reg_TOP    [context];
218                  reg_PREDICT_NB_ELT [context] = reg_NB_ELT [context];
219                }
220            }
221
222        // ===================================================================
223        // =====[ UPDATE ]===================================================
224        // ===================================================================
225        for (uint32_t i=0; i<_param->_nb_inst_update; i++)
226          if (PORT_READ(in_UPDATE_VAL [i]) and internal_UPDATE_ACK [i])
227            {
228              log_printf(TRACE,Return_Address_Stack,FUNCTION,"  * UPDATE [%d] : Transaction",i);
229
230              Tcontext_t context_id        = (_param->_have_port_context_id)?PORT_READ(in_UPDATE_CONTEXT_ID [i]):0;
231              Tcontrol_t flush             = PORT_READ(in_UPDATE_FLUSH             [i]);
232
233              log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * context_id        : %d",context_id);
234              log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * flush             : %d",flush     );
235             
236              // An miss prediction on call/return = Return Address Stack is corrupted.
237              if (flush)
238                {
239                  Tcontrol_t push  = PORT_READ(in_UPDATE_PUSH [i]);
240                  Tptr_t     value = (push)?1:0;
241
242                  // All pointer is set at 0
243                  reg_TOP    [context_id] = value;
244//                reg_BOTTOM [context_id] = 0;
245                  reg_NB_ELT [context_id] = value;
246                 
247                  reg_PREDICT_TOP    [context_id] = value;
248//                reg_PREDICT_BOTTOM [context_id] = 0;
249                  reg_PREDICT_NB_ELT [context_id] = value;
250
251                  if (push)
252                    {
253                      // reinsert push value
254                      Taddress_t address = PORT_READ(in_UPDATE_ADDRESS [i]);
255                 
256                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * flush and push");
257                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * address_push        : 0x%.8x",address);
258
259                      reg_stack [context_id][value]._address = address;
260                    }
261                }
262              else
263                {
264                  // if miss_prediction -> restore queue
265                  // else, the prediction is correct
266                  Tcontrol_t miss_prediction   = PORT_READ(in_UPDATE_MISS_PREDICTION   [i]);
267
268                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * miss_prediction   : %d",miss_prediction);
269
270#ifdef DEBUG_TEST
271                  Tptr_t     index             = PORT_READ(in_UPDATE_INDEX             [i]);
272                  Tcontrol_t prediction_ifetch = PORT_READ(in_UPDATE_PREDICTION_IFETCH [i]);
273                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * index             : %d",index);
274                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * prediction_ifetch : %d",prediction_ifetch);
275
276//                   if (prediction_ifetch)
277//                     {
278//                       if (index != reg_PREDICT_TOP [context_id])
279//                         throw ERRORMORPHEO(FUNCTION,_("Index is different of predict_top"));
280//                     }
281//                   else
282//                     {
283//                       if (index != reg_TOP [context_id])
284//                         throw ERRORMORPHEO(FUNCTION,_("Index is different of top"));
285//                     }
286                 
287#endif
288                  if (miss_prediction)
289                    {
290                      Tcontrol_t push              = PORT_READ(in_UPDATE_PUSH              [i]);
291                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * push              : %d",push);
292#ifndef DEBUG_TEST
293                      Tptr_t     index             = PORT_READ(in_UPDATE_INDEX             [i]);
294                      Tcontrol_t prediction_ifetch = PORT_READ(in_UPDATE_PREDICTION_IFETCH [i]);
295                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * index             : %d",index);
296                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * prediction_ifetch : %d",prediction_ifetch);
297#endif
298
299                      Tptr_t     top_old    = (prediction_ifetch)?reg_PREDICT_TOP    [context_id]:reg_TOP    [context_id];
300                      Tptr_t     top_new    = top_old;
301
302//                    Tptr_t     bottom_old = (prediction_ifetch)?reg_PREDICT_BOTTOM [context_id]:reg_BOTTOM [context_id];
303//                    Tptr_t     bottom_new = bottom_old;
304
305                      Tptr_t     nb_elt_old = (prediction_ifetch)?reg_PREDICT_NB_ELT [context_id]:reg_NB_ELT [context_id];
306                      Tptr_t     nb_elt_new = nb_elt_old;
307                     
308                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * before");
309                      if (prediction_ifetch)
310                        {
311                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_old);
312//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_old);
313                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_old);
314                        }
315                      else
316                        {
317                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_top     : %d",top_old);
318//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_bottom  : %d",bottom_old);
319                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_nb_elt  : %d",nb_elt_old);
320                        }
321
322                      // if previous is push, pop the value
323                      // else is previous is pop, push the poped value
324                      if (push)
325                        {
326                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * previous is push, now pop");
327
328                          // previous is push, now must be pop
329
330                          // Test if the stack is empty (if previous flush)
331                          if (nb_elt_old>0)
332                            {
333                              top_new = (top_old==0)?(_param->_size_queue[context_id]-1):(top_old-1);
334                              nb_elt_new --;
335                            }
336                        }
337                      else
338                        {
339                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * previous is pop, now push");
340
341                          // previous is pop, now must be push
342                          Taddress_t address           = PORT_READ(in_UPDATE_ADDRESS           [i]);
343
344                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * address       : 0x%.8x",address);
345
346                          // push : increase the top (circular)
347//                        if (nb_elt_old==_param->_size_queue[context_id])
348//                          bottom_new = (bottom_old+1)%_param->_size_queue[context_id];
349//                        else
350//                          nb_elt_new ++;
351
352                          if (nb_elt_old!=_param->_size_queue[context_id])
353                            nb_elt_new ++;
354
355                          top_new = index;
356                         
357                          reg_stack [context_id][top_new]._address = address;
358                        }
359
360                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * after");
361
362                      if (prediction_ifetch)
363                        {
364                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",reg_TOP    [context_id]);
365//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",reg_BOTTOM [context_id]);
366                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",reg_NB_ELT [context_id]);
367
368                          reg_PREDICT_TOP    [context_id] = reg_TOP    [context_id];
369//                        reg_PREDICT_BOTTOM [context_id] = reg_BOTTOM [context_id];
370                          reg_PREDICT_NB_ELT [context_id] = reg_NB_ELT [context_id];
371
372//                           log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_new   );
373// //                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_new);
374//                           log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_new);
375
376//                           reg_PREDICT_TOP    [context_id] = top_new   ;
377// //                        reg_PREDICT_BOTTOM [context_id] = bottom_new;
378//                           reg_PREDICT_NB_ELT [context_id] = nb_elt_new;
379
380                        }
381                      else
382                        {
383                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_top     : %d",top_new);
384//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_bottom  : %d",bottom_new);
385                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_nb_elt  : %d",nb_elt_new);
386
387                          reg_TOP            [context_id] = top_new   ;
388//                        reg_BOTTOM         [context_id] = bottom_new;
389                          reg_NB_ELT         [context_id] = nb_elt_new;
390                          reg_PREDICT_TOP    [context_id] = top_new   ;
391//                        reg_PREDICT_BOTTOM [context_id] = bottom_new;
392                          reg_PREDICT_NB_ELT [context_id] = nb_elt_new;
393                        }
394                    }
395                }
396            }
397      }
398
399#if defined(DEBUG_Return_Address_Stack) and DEBUG>=DEBUG_TRACE
400    log_printf(TRACE,Return_Address_Stack,FUNCTION,"  * Dump RAS");
401    for (uint32_t i=0; i<_param->_nb_context; ++i)
402      {
403        log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * Return Address Stack [%d]",i);
404        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_TOP            : %d",reg_TOP            [i]);
405//      log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_BOTTOM         : %d",reg_BOTTOM         [i]);
406        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_NB_ELT         : %d",reg_NB_ELT         [i]);
407        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_PREDICT_TOP    : %d",reg_PREDICT_TOP    [i]);
408//      log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_PREDICT_BOTTOM : %d",reg_PREDICT_BOTTOM [i]);
409        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_PREDICT_NB_ELT : %d",reg_PREDICT_NB_ELT [i]);
410
411        for (uint32_t j=0; j<_param->_size_queue[i]; ++j)
412          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      [%d] %.8x (%.8x)",j,reg_stack [i][j]._address,reg_stack [i][j]._address<<2);
413      }
414#endif
415
416#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
417    end_cycle ();
418#endif
419
420    log_end(Return_Address_Stack,FUNCTION);
421  };
422
423}; // end namespace return_address_stack
424}; // end namespace prediction_unit
425}; // end namespace front_end
426}; // end namespace multi_front_end
427}; // end namespace core
428
429}; // end namespace behavioural
430}; // end namespace morpheo             
431#endif
Note: See TracBrowser for help on using the repository browser.