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

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

1) Bug fix (Operation, Instruction)
2) Modif Return Address Stack
3) Add Soft Test
4) Add Soc Test

  • Property svn:keywords set to Id
File size: 17.8 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Return_Address_Stack_transition.cpp 100 2009-01-08 13:06:27Z 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                  // All pointer is set at 0
240                  reg_TOP    [context_id] = 0;
241//                reg_BOTTOM [context_id] = 0;
242                  reg_NB_ELT [context_id] = 0;
243                 
244                  reg_PREDICT_TOP    [context_id] = 0;
245//                reg_PREDICT_BOTTOM [context_id] = 0;
246                  reg_PREDICT_NB_ELT [context_id] = 0;
247                }
248              else
249                {
250                  // if miss_prediction -> restore queue
251                  // else, the prediction is correct
252                  Tcontrol_t miss_prediction   = PORT_READ(in_UPDATE_MISS_PREDICTION   [i]);
253
254                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * miss_prediction   : %d",miss_prediction);
255
256#ifdef DEBUG_TEST
257                  Tptr_t     index             = PORT_READ(in_UPDATE_INDEX             [i]);
258                  Tcontrol_t prediction_ifetch = PORT_READ(in_UPDATE_PREDICTION_IFETCH [i]);
259                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * index             : %d",index);
260                  log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * prediction_ifetch : %d",prediction_ifetch);
261
262//                   if (prediction_ifetch)
263//                     {
264//                       if (index != reg_PREDICT_TOP [context_id])
265//                         throw ERRORMORPHEO(FUNCTION,_("Index is different of predict_top"));
266//                     }
267//                   else
268//                     {
269//                       if (index != reg_TOP [context_id])
270//                         throw ERRORMORPHEO(FUNCTION,_("Index is different of top"));
271//                     }
272                 
273#endif
274                  if (miss_prediction)
275                    {
276                      Tcontrol_t push              = PORT_READ(in_UPDATE_PUSH              [i]);
277                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * push              : %d",push);
278#ifndef DEBUG_TEST
279                      Tptr_t     index             = PORT_READ(in_UPDATE_INDEX             [i]);
280                      Tcontrol_t prediction_ifetch = PORT_READ(in_UPDATE_PREDICTION_IFETCH [i]);
281                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * index             : %d",index);
282                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * prediction_ifetch : %d",prediction_ifetch);
283#endif
284
285
286                      Tptr_t     top_old    = (prediction_ifetch)?reg_PREDICT_TOP    [context_id]:reg_TOP    [context_id];
287                      Tptr_t     top_new    = top_old;
288
289//                    Tptr_t     bottom_old = (prediction_ifetch)?reg_PREDICT_BOTTOM [context_id]:reg_BOTTOM [context_id];
290//                    Tptr_t     bottom_new = bottom_old;
291
292                      Tptr_t     nb_elt_old = (prediction_ifetch)?reg_PREDICT_NB_ELT [context_id]:reg_NB_ELT [context_id];
293                      Tptr_t     nb_elt_new = nb_elt_old;
294                     
295                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * before");
296                      if (prediction_ifetch)
297                        {
298                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_old);
299//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_old);
300                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_old);
301                        }
302                      else
303                        {
304                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_top     : %d",top_old);
305//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_bottom  : %d",bottom_old);
306                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_nb_elt  : %d",nb_elt_old);
307                        }
308
309                      // if previous is push, pop the value
310                      // else is previous is pop, push the poped value
311                      if (push)
312                        {
313                          // previous is push, now must be pop
314
315                          // Test if the stack is empty
316                          if (nb_elt_old>0) // ??
317                            {
318                              top_new = (top_old==0)?(_param->_size_queue[context_id]-1):(top_old-1);
319                              nb_elt_new --;
320                            }
321                        }
322                      else
323                        {
324                          // previous is pop, now must be push
325                          Taddress_t address           = PORT_READ(in_UPDATE_ADDRESS           [i]);
326
327                          // push : increase the top (circular)
328//                        if (nb_elt_old==_param->_size_queue[context_id])
329//                          bottom_new = (bottom_old+1)%_param->_size_queue[context_id];
330//                        else
331//                          nb_elt_new ++;
332
333                          if (nb_elt_old!=_param->_size_queue[context_id])
334                            nb_elt_new ++;
335
336                          top_new = index;
337                         
338                          reg_stack [context_id][index]._address = address;
339                        }
340
341                      log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * after");
342
343                      if (prediction_ifetch)
344                        {
345                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_top     : %d",top_new);
346//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_bottom  : %d",bottom_new);
347                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_predict_nb_elt  : %d",nb_elt_new);
348
349                          reg_PREDICT_TOP    [context_id] = top_new   ;
350//                        reg_PREDICT_BOTTOM [context_id] = bottom_new;
351                          reg_PREDICT_NB_ELT [context_id] = nb_elt_new;
352                        }
353                      else
354                        {
355                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_top     : %d",top_new);
356//                        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_bottom  : %d",bottom_new);
357                          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_nb_elt  : %d",nb_elt_new);
358
359                          reg_TOP            [context_id] = top_new   ;
360//                        reg_BOTTOM         [context_id] = bottom_new;
361                          reg_NB_ELT         [context_id] = nb_elt_new;
362                        }
363                    }
364                }
365            }
366      }
367
368#if defined(DEBUG_Return_Address_Stack) and DEBUG>=DEBUG_TRACE
369    log_printf(TRACE,Return_Address_Stack,FUNCTION,"  * Dump RAS");
370    for (uint32_t i=0; i<_param->_nb_context; ++i)
371      {
372        log_printf(TRACE,Return_Address_Stack,FUNCTION,"    * Return Address Stack [%d]",i);
373        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_TOP            : %d",reg_TOP            [i]);
374//      log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_BOTTOM         : %d",reg_BOTTOM         [i]);
375        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_NB_ELT         : %d",reg_NB_ELT         [i]);
376        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_PREDICT_TOP    : %d",reg_PREDICT_TOP    [i]);
377//      log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_PREDICT_BOTTOM : %d",reg_PREDICT_BOTTOM [i]);
378        log_printf(TRACE,Return_Address_Stack,FUNCTION,"      * reg_PREDICT_NB_ELT : %d",reg_PREDICT_NB_ELT [i]);
379
380        for (uint32_t j=0; j<_param->_size_queue[i]; ++j)
381          log_printf(TRACE,Return_Address_Stack,FUNCTION,"      [%d] %.8x (%.8x)",j,reg_stack [i][j]._address,reg_stack [i][j]._address<<2);
382      }
383#endif
384
385#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
386    end_cycle ();
387#endif
388
389    log_end(Return_Address_Stack,FUNCTION);
390  };
391
392}; // end namespace return_address_stack
393}; // end namespace prediction_unit
394}; // end namespace front_end
395}; // end namespace multi_front_end
396}; // end namespace core
397
398}; // end namespace behavioural
399}; // end namespace morpheo             
400#endif
Note: See TracBrowser for help on using the repository browser.