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

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

1) Correct bug in link two signal
2) Fix error detected with valgrind
3) modif distexe script

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