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

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

1) Fix test in Direction_Glue for Conditionnal Branch
2) Fix Instruction Address Compute

  • Property svn:keywords set to Id
File size: 18.2 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Return_Address_Stack_transition.cpp 107 2009-02-10 23:03:25Z 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                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * push (call procedure)");
79
80                      // push : increase the top (circular)
81                      top_new = (top_old+1)%_param->_size_queue[context];
82
83                      // Write new value in Queue
84                      reg_stack [context][top_new]._address = PORT_READ(in_PREDICT_ADDRESS_PUSH [i]);
85
86                      // Test if full
87                      //   -> is full, the push erase the oldest value in stack, also nb_elt is the same
88                      //   -> is not full, increase nb_elt
89//                    if (nb_elt_old==_param->_size_queue[context])
90//                      bottom_new = (bottom_old+1)%_param->_size_queue[context];
91//                       else
92//                      nb_elt_new ++;
93                      if (nb_elt_old!=_param->_size_queue[context])
94                        nb_elt_new ++;
95                    }
96                  else
97                    {
98                      // pop
99                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * pop (return procedure)");
100
101                      // Test if the stack is empty
102                      if (nb_elt_old>0)
103                        {
104                          top_new = (top_old==0)?(_param->_size_queue[context]-1):(top_old-1);
105                          nb_elt_new --;
106                        }
107                      // no else : can't pop
108                    }
109                 
110                  // Write new pointer
111                  reg_PREDICT_TOP    [context] = top_new;
112//                reg_PREDICT_BOTTOM [context] = bottom_new;
113                  reg_PREDICT_NB_ELT [context] = nb_elt_new;
114
115                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * after");
116                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_new);
117//                log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_new);
118                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_new);
119                }
120            }
121
122        // ===================================================================
123        // =====[ DECOD ]=====================================================
124        // ===================================================================
125        for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
126          if (PORT_READ(in_DECOD_VAL [i]) and internal_DECOD_ACK [i])
127            {
128              log_printf(TRACE,Return_Address_Stack,FUNCTION,"  * DECOD [%d] : Transaction",i);
129
130              // Read information
131              Tcontext_t context    = (_param->_have_port_context_id)?PORT_READ(in_DECOD_CONTEXT_ID [i]):0;
132              Tcontrol_t push       = PORT_READ(in_DECOD_PUSH [i]);
133
134              // Read pointer
135              Tptr_t     top_old    = reg_TOP    [context];
136              Tptr_t     top_new    = top_old;
137//            Tptr_t     bottom_old = reg_BOTTOM [context];
138//            Tptr_t     bottom_new = bottom_old;
139              Tptr_t     nb_elt_old = reg_NB_ELT [context];
140              Tptr_t     nb_elt_new = nb_elt_old;
141
142              log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * context : %d",context);
143
144              log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * before");
145              log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_old);
146//            log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_old);
147              log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_old);
148
149              // Test if push
150              if (push)
151                {
152                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * push (call procedure)");
153                 
154                  // push : increase the top (circular)
155                  top_new = (top_old+1)%_param->_size_queue[context];
156                 
157                  // Write new value in Queue
158                  reg_stack [context][top_new]._address = PORT_READ(in_DECOD_ADDRESS_PUSH [i]);
159                 
160                  // Test if full
161                  //   -> is full, the push erase the oldest value in stack, also nb_elt is the same
162                  //   -> is not full, increase nb_elt
163//                   if (nb_elt_old==_param->_size_queue[context])
164//                     bottom_new = (bottom_old+1)%_param->_size_queue[context];
165//                   else
166//                     nb_elt_new ++;
167                  if (nb_elt_old!=_param->_size_queue[context])
168                    nb_elt_new ++;
169                }
170              else
171                {
172                  // pop
173                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * pop (return procedure)");
174                 
175                  // Test if the stack is empty
176                  if (nb_elt_old>0)
177                    {
178                      top_new = (top_old==0)?(_param->_size_queue[context]-1):(top_old-1);
179                      nb_elt_new --;
180                    }
181                  // no else : can't pop
182                }
183             
184              // Write new pointer
185              reg_TOP    [context] = top_new;
186//            reg_BOTTOM [context] = bottom_new;
187              reg_NB_ELT [context] = nb_elt_new;
188             
189              log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * after");
190              log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_new);
191//            log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_new);
192              log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_new);
193             
194              // have previous miss of ifetch ?
195              // 2 miss :
196              //   1) miss predict : is very limited (local at context), can be update very quickly
197              //   2) miss decod   : result is in commit stage ...
198
199              // manage by Update_Fetch_Prediction_Table and Update_Prediction_Table
200              // Note :
201              //   if decod miss : ifetch can have predict call and return branchement. Also, the head of decod can be false
202
203//            Tcontrol_t miss       = PORT_READ(in_DECOD_MISS_PREDICTION [i]);
204
205//            if (miss)
206//              {
207//                reg_PREDICT_BOTTOM [context] = reg_BOTTOM [context];
208//                reg_PREDICT_TOP    [context] = reg_TOP    [context];
209//                reg_PREDICT_NB_ELT [context] = reg_NB_ELT [context];
210                 
211//                // Scan full assoc !!!
212//                for (uint32_t j=0; j<_param->_size_queue [context]; j++)
213//                  // Test if this slot is tagged with "predict" : if true, tagged as miss
214//                  if (reg_stack [context][j]._predict)
215//                    {
216//                      reg_stack [context][j]._predict = false;
217//                      reg_stack [context][j]._miss    = true;
218//                    }
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                      reg_stack [context_id][0]._address = PORT_READ(in_UPDATE_ADDRESS [i]);
255                    }
256                }
257              else
258                {
259                  // if miss_prediction -> restore queue
260                  // else, the prediction is correct
261                  Tcontrol_t miss_prediction   = PORT_READ(in_UPDATE_MISS_PREDICTION   [i]);
262
263                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * miss_prediction   : %d",miss_prediction);
264
265#ifdef DEBUG_TEST
266                  Tptr_t     index             = PORT_READ(in_UPDATE_INDEX             [i]);
267                  Tcontrol_t prediction_ifetch = PORT_READ(in_UPDATE_PREDICTION_IFETCH [i]);
268                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * index             : %d",index);
269                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * prediction_ifetch : %d",prediction_ifetch);
270
271//                   if (prediction_ifetch)
272//                     {
273//                       if (index != reg_PREDICT_TOP [context_id])
274//                         throw ERRORMORPHEO(FUNCTION,_("Index is different of predict_top"));
275//                     }
276//                   else
277//                     {
278//                       if (index != reg_TOP [context_id])
279//                         throw ERRORMORPHEO(FUNCTION,_("Index is different of top"));
280//                     }
281                 
282#endif
283                  if (miss_prediction)
284                    {
285                      Tcontrol_t push              = PORT_READ(in_UPDATE_PUSH              [i]);
286                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * push              : %d",push);
287#ifndef DEBUG_TEST
288                      Tptr_t     index             = PORT_READ(in_UPDATE_INDEX             [i]);
289                      Tcontrol_t prediction_ifetch = PORT_READ(in_UPDATE_PREDICTION_IFETCH [i]);
290                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * index             : %d",index);
291                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * prediction_ifetch : %d",prediction_ifetch);
292#endif
293
294
295                      Tptr_t     top_old    = (prediction_ifetch)?reg_PREDICT_TOP    [context_id]:reg_TOP    [context_id];
296                      Tptr_t     top_new    = top_old;
297
298//                    Tptr_t     bottom_old = (prediction_ifetch)?reg_PREDICT_BOTTOM [context_id]:reg_BOTTOM [context_id];
299//                    Tptr_t     bottom_new = bottom_old;
300
301                      Tptr_t     nb_elt_old = (prediction_ifetch)?reg_PREDICT_NB_ELT [context_id]:reg_NB_ELT [context_id];
302                      Tptr_t     nb_elt_new = nb_elt_old;
303                     
304                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * before");
305                      if (prediction_ifetch)
306                        {
307                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_old);
308//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_old);
309                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_old);
310                        }
311                      else
312                        {
313                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_top     : %d",top_old);
314//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_bottom  : %d",bottom_old);
315                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_nb_elt  : %d",nb_elt_old);
316                        }
317
318                      // if previous is push, pop the value
319                      // else is previous is pop, push the poped value
320                      if (push)
321                        {
322                          // previous is push, now must be pop
323
324                          // Test if the stack is empty (if previous flush)
325                          if (nb_elt_old>0)
326                            {
327                              top_new = (top_old==0)?(_param->_size_queue[context_id]-1):(top_old-1);
328                              nb_elt_new --;
329                            }
330                        }
331                      else
332                        {
333                          // previous is pop, now must be push
334                          Taddress_t address           = PORT_READ(in_UPDATE_ADDRESS           [i]);
335
336                          // push : increase the top (circular)
337//                        if (nb_elt_old==_param->_size_queue[context_id])
338//                          bottom_new = (bottom_old+1)%_param->_size_queue[context_id];
339//                        else
340//                          nb_elt_new ++;
341
342                          if (nb_elt_old!=_param->_size_queue[context_id])
343                            nb_elt_new ++;
344
345                          top_new = index;
346                         
347                          reg_stack [context_id][index]._address = address;
348                        }
349
350                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * after");
351
352                      if (prediction_ifetch)
353                        {
354                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_new);
355//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_new);
356                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_new);
357
358                          reg_PREDICT_TOP    [context_id] = top_new   ;
359//                        reg_PREDICT_BOTTOM [context_id] = bottom_new;
360                          reg_PREDICT_NB_ELT [context_id] = nb_elt_new;
361                        }
362                      else
363                        {
364                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_top     : %d",top_new);
365//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_bottom  : %d",bottom_new);
366                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_nb_elt  : %d",nb_elt_new);
367
368                          reg_TOP            [context_id] = top_new   ;
369//                        reg_BOTTOM         [context_id] = bottom_new;
370                          reg_NB_ELT         [context_id] = nb_elt_new;
371                        }
372                    }
373                }
374            }
375      }
376
377#if defined(DEBUG_Return_Address_Stack) and DEBUG>=DEBUG_TRACE
378    log_printf(TRACE,Return_Address_Stack,FUNCTION,"  * Dump RAS");
379    for (uint32_t i=0; i<_param->_nb_context; ++i)
380      {
381        log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * Return Address Stack [%d]",i);
382        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_TOP            : %d",reg_TOP            [i]);
383//      log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_BOTTOM         : %d",reg_BOTTOM         [i]);
384        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_NB_ELT         : %d",reg_NB_ELT         [i]);
385        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_PREDICT_TOP    : %d",reg_PREDICT_TOP    [i]);
386//      log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_PREDICT_BOTTOM : %d",reg_PREDICT_BOTTOM [i]);
387        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_PREDICT_NB_ELT : %d",reg_PREDICT_NB_ELT [i]);
388
389        for (uint32_t j=0; j<_param->_size_queue[i]; ++j)
390          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      [%d] %.8x (%.8x)",j,reg_stack [i][j]._address,reg_stack [i][j]._address<<2);
391      }
392#endif
393
394#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
395    end_cycle ();
396#endif
397
398    log_end(Return_Address_Stack,FUNCTION);
399  };
400
401}; // end namespace return_address_stack
402}; // end namespace prediction_unit
403}; // end namespace front_end
404}; // end namespace multi_front_end
405}; // end namespace core
406
407}; // end namespace behavioural
408}; // end namespace morpheo             
409#endif
Note: See TracBrowser for help on using the repository browser.