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

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

Modif for performance :
1) Load Store Unit : store send request to valid exeception
2) Commit_unit : retire can bypass store
3) Commit_unit : add stat to manage store instruction
4) Load Store Unit and Load Store Pointer Manager : add store_queue_ptr_read
5) Fix lot of bug

File size: 16.5 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id$
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
20#undef  FUNCTION
21#define FUNCTION "Update_Prediction_Table::genMoore"
22  void Update_Prediction_Table::genMoore (void)
23  {
24    log_begin(Update_Prediction_Table,FUNCTION);
25    log_function(Update_Prediction_Table,FUNCTION,_name.c_str());
26
27    if (PORT_READ(in_NRESET) == 1)
28      {
29
30    // ===================================================================
31    // =====[ DEPTH ]=====================================================
32    // ===================================================================
33
34    for (uint32_t i=0; i<_param->_nb_context; i++)
35      {
36        // is a valid instruction ?
37        // If DEPTH_CURRENT :
38        // equal at     DEPTH_MIN            -> not speculative
39        // not include ]DEPTH_MIN:DEPTH_MAX] -> previous branch miss
40        //     include ]DEPTH_MIN:DEPTH_MAX] -> speculative
41
42        uint32_t bottom = reg_UPT_BOTTOM [i];
43        uint32_t top    = reg_UPT_TOP    [i];
44        bool     empty  = reg_UPT_EMPTY [i];
45
46        // Depth_val is set when state is ok and the UPT[top] is empty
47        PORT_WRITE(out_DEPTH_VAL     [i],((reg_UPDATE_PREDICTION_TABLE [i][top]._state == UPDATE_PREDICTION_STATE_EMPTY) 
48                                          and (reg_UFPT_EVENT_STATE [i] == UFPT_EVENT_STATE_OK)
49                                          and (reg_UPT_EVENT_STATE  [i] == UPT_EVENT_STATE_OK)
50                                          ));
51        if (_param->_have_port_depth)
52          {
53        PORT_WRITE(out_DEPTH_CURRENT [i], top);
54        PORT_WRITE(out_DEPTH_MIN     [i], bottom);
55        PORT_WRITE(out_DEPTH_MAX     [i], top);
56          }
57        PORT_WRITE(out_DEPTH_FULL    [i], not empty and (top == bottom));
58      }
59
60    // ===================================================================
61    // =====[ UPDATE ]====================================================
62    // ===================================================================
63    {
64      bool     flush_ufpt      [_param->_nb_context]; // event ufpt -> restore RAS, else update upt
65      bool     flush_upt       [_param->_nb_context]; // event upt  -> restore RAS, else restore others structure
66      bool     ufpt_can_update [_param->_nb_context];
67      bool     upt_can_update  [_param->_nb_context];
68      Tdepth_t tab_ufpt_depth  [_param->_nb_context];
69      Tdepth_t tab_upt_depth   [_param->_nb_context];
70     
71      // Init
72      for (uint32_t i=0; i<_param->_nb_context; i++)
73        {
74          ufpt_event_state_t ufpt_event_state = reg_UFPT_EVENT_STATE [i];
75          upt_event_state_t  upt_event_state  = reg_UPT_EVENT_STATE [i];
76         
77          flush_ufpt      [i] = (ufpt_event_state == UFPT_EVENT_STATE_KO_FLUSH);
78          flush_upt       [i] = ((upt_event_state == UPT_EVENT_STATE_KO_MISS_FLUSH_UPT) or
79                                 (upt_event_state == UPT_EVENT_STATE_KO_EVENT_FLUSH_UPT));
80          ufpt_can_update [i] = true;
81          upt_can_update  [i] = true;
82          tab_ufpt_depth  [i] = reg_UFPT_UPDATE [i];
83          tab_upt_depth   [i] = reg_UPT_UPDATE  [i];
84        }
85
86    for (uint32_t i=0; i<_param->_nb_inst_update; i++)
87      {
88        Tcontext_t          context              = (reg_UPDATE_PRIORITY+i)%_param->_nb_context;
89
90        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"  * UPDATE [%d] (genMoore)",i);
91        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * context         : %d",context);
92        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * flush_ufpt      : %d",flush_ufpt[context]);
93        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * flush_upt       : %d",flush_upt [context]);
94
95        Tcontrol_t          val                  = false;
96        Tcontrol_t          val_without_ack      = false;
97        Tcontrol_t          miss_prediction      = 0; // not necessary init
98        Tcontrol_t          direction_good       = 0; // not necessary init
99        Tcontrol_t          prediction_ifetch    = 0; // not necessary init
100        Tcontrol_t          btb_val              = 0; // not necessary init
101        Taddress_t          btb_address_src      = 0; // not necessary init
102        Taddress_t          btb_address_dest     = 0; // not necessary init
103        Tbranch_condition_t btb_condition        = 0; // not necessary init
104        Tcontrol_t          dir_val              = 0; // not necessary init
105        Thistory_t          dir_history          = 0; // not necessary init
106        Tcontrol_t          ras_val              = 0; // not necessary init
107        Tcontrol_t          ras_flush            = 0; // not necessary init
108        Tcontrol_t          ras_push             = 0; // not necessary init
109        Taddress_t          ras_address          = 0; // not necessary init
110        Tptr_t              ras_index            = 0; // not necessary init
111
112        // Test if update fetch prediction table need update port
113        if (flush_ufpt [context])
114          {
115            if (ufpt_can_update [context])
116              {
117                // Update Fetch Prediction Table
118                // An update of ufpt is to previous miss. Just restore Prediction_unit
119               
120                // Read information
121                Tdepth_t            depth     = tab_ufpt_depth[context];
122                ufpt_state_t        state     = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._state; 
123                Tbranch_condition_t condition = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._condition; 
124               
125                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Fetch Prediction Table");
126                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth           : %d",depth    );
127                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * state           : %s",toString(state    ).c_str());
128                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * condition       : %s",toString(condition).c_str());
129               
130                val                   = (state == UPDATE_FETCH_PREDICTION_STATE_EVENT);
131//              val_without_ack       = not update_ras(condition);
132
133                miss_prediction       = 1; // need update, also previous miss
134//              direction_good        = ;
135                prediction_ifetch     = 1;
136                btb_val               = 0; // don't update btb (is update by the event branch)
137//              btb_address_src       = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src ;
138//              btb_address_dest      = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_dest;
139//              btb_condition         = condition;
140                dir_val               = update_dir(condition);
141                dir_history           = reg_UPDATE_PREDICTION_TABLE [context][depth]._history;
142                ras_val               = update_ras(condition); // repop/ repush data -> don't corrupt ras
143                ras_flush             = 0; // no ras corruption
144                ras_push              = push_ras(condition);
145                ras_address           = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._address_ras;
146                ras_index             = reg_UPDATE_FETCH_PREDICTION_TABLE [context][depth]._index_ras;
147               
148                internal_UPDATE_FROM_UFPT [i] = true;
149                internal_UPDATE_DEPTH     [i] = depth;
150                internal_UPDATE_RAS       [i] = false;
151
152                // Warning : don't update same entry
153                if (depth == reg_UFPT_BOTTOM[context])
154                  ufpt_can_update [context] = false;
155                else
156                  // update pointer
157                  tab_ufpt_depth[context] = ((depth==0)?_param->_size_ufpt_queue[context]:depth)-1;
158              }
159          }
160        else
161          {
162            if (upt_can_update [context])
163              {
164                // Update Prediction Table
165
166                // Read information
167                Tdepth_t            depth     = tab_upt_depth[context];
168                upt_state_t         state     = reg_UPDATE_PREDICTION_TABLE [context][depth]._state; 
169                Tbranch_condition_t condition = reg_UPDATE_PREDICTION_TABLE [context][depth]._condition; 
170                Tcontrol_t          ifetch    = reg_UPDATE_PREDICTION_TABLE [context][depth]._ifetch_prediction;
171               
172                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * Update Prediction Table");
173                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * depth           : %d",depth    );
174                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * state           : %s",toString(state    ).c_str());
175                log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * condition       : %s",toString(condition).c_str());
176             
177                // is the valid branch (valid branch hit, or valid branch miss)
178                Tcontrol_t          state_is_ok_ko = ((state == UPDATE_PREDICTION_STATE_OK   ) or
179                                                      (state == UPDATE_PREDICTION_STATE_KO   ));
180
181                if (not flush_upt [context])
182                  {
183                    // no event, just update predictor
184                val                   = (state == UPDATE_PREDICTION_STATE_OK);
185                val_without_ack       = false;
186                  }
187                else
188                  {
189                    // event, restore event (if need update)
190                val                   = ( (state == UPDATE_PREDICTION_STATE_KO   ) or
191                                         ((state == UPDATE_PREDICTION_STATE_EVENT) and     need_update(condition)));
192                val_without_ack       = ( (state == UPDATE_PREDICTION_STATE_EVENT) and not need_update(condition));
193                  }                 
194
195                miss_prediction       = (state != UPDATE_PREDICTION_STATE_OK);
196                direction_good        = reg_UPDATE_PREDICTION_TABLE [context][depth]._good_take   ;
197                prediction_ifetch     = ifetch;
198                btb_val               = state_is_ok_ko and update_btb(condition);
199                btb_address_src       = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src ;
200                btb_address_dest      = reg_UPDATE_PREDICTION_TABLE [context][depth]._address_dest;
201                btb_condition         = condition;
202                dir_val               = ifetch and update_dir(condition); // if not ifetch, then static prediction -> history is wrong
203                dir_history           = reg_UPDATE_PREDICTION_TABLE [context][depth]._history     ;
204                ras_val               = update_ras(condition); // repop/ repush data -> don't corrupt ras
205                ras_flush             = (state == UPDATE_PREDICTION_STATE_KO); // miss prediction on RAS -> RAS is corrupted
206                ras_push              = push_ras(condition);
207                // If corrupt, RAS must be flushed.
208                // Also, if instruction l.jal, l.jalr, push addr+2 (delay slot), else (no flush) restore RAS
209                ras_address           = (ras_flush)?(reg_UPDATE_PREDICTION_TABLE [context][depth]._address_src+2):reg_UPDATE_PREDICTION_TABLE [context][depth]._address_ras;
210                ras_index             = reg_UPDATE_PREDICTION_TABLE [context][depth]._index_ras;
211
212                internal_UPDATE_FROM_UFPT [i] = false;
213                internal_UPDATE_DEPTH     [i] = depth;
214                internal_UPDATE_RAS       [i] = flush_upt [context];
215
216                // Warning : don't update same entry
217                if (flush_upt [context])
218                  {
219                    // Stop condition
220                    if ((depth == reg_UPT_BOTTOM[context]) or not (val or val_without_ack))
221                      upt_can_update [context] = false;
222                   
223                    // flush -> ptr is decrease
224                    tab_upt_depth[context] = (depth==0)?(_param->_size_upt_queue[context]-1):(depth-1);
225                  }
226                else
227                  {
228                    // Stop condition
229                    if ((depth == reg_UPT_TOP [context]) or not (val or val_without_ack))
230                      upt_can_update [context] = false;
231                   
232                    // flush -> ptr is increase
233                    tab_upt_depth[context] = (depth+1)%_param->_size_upt_queue[context];
234                  }
235              }
236          }
237       
238        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * val             : %d",val    );
239        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * val_without_ack : %d",val_without_ack);
240        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * miss_prediction : %d",miss_prediction);
241        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * direction_good  : %d",direction_good );
242        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * btb_val         : %d",btb_val);
243        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * dir_val         : %d",dir_val);
244        log_printf(TRACE,Update_Prediction_Table,FUNCTION,"    * ras_val         : %d",ras_val);
245
246        internal_UPDATE_VAL             [i] = val;
247        internal_UPDATE_VAL_WITHOUT_ACK [i] = val_without_ack;
248        internal_UPDATE_CONTEXT_ID      [i] = context;
249
250        PORT_WRITE(out_UPDATE_VAL                   [i],internal_UPDATE_VAL [i]);
251        if (val)
252          {
253        if (_param->_have_port_context_id)
254        PORT_WRITE(out_UPDATE_CONTEXT_ID            [i],context              );
255        PORT_WRITE(out_UPDATE_MISS_PREDICTION       [i],miss_prediction      );
256        PORT_WRITE(out_UPDATE_DIRECTION_GOOD        [i],direction_good       );
257        PORT_WRITE(out_UPDATE_PREDICTION_IFETCH     [i],prediction_ifetch    );
258        PORT_WRITE(out_UPDATE_BTB_VAL               [i],btb_val              );
259        PORT_WRITE(out_UPDATE_BTB_ADDRESS_SRC       [i],btb_address_src      );
260        PORT_WRITE(out_UPDATE_BTB_ADDRESS_DEST      [i],btb_address_dest     );
261        PORT_WRITE(out_UPDATE_BTB_CONDITION         [i],btb_condition        );
262        PORT_WRITE(out_UPDATE_DIR_VAL               [i],dir_val              );
263        if (_param->_have_port_history)
264        PORT_WRITE(out_UPDATE_DIR_HISTORY           [i],dir_history          );
265        PORT_WRITE(out_UPDATE_RAS_VAL               [i],ras_val              );
266        PORT_WRITE(out_UPDATE_RAS_FLUSH             [i],ras_flush            );
267        PORT_WRITE(out_UPDATE_RAS_PUSH              [i],ras_push             );
268        PORT_WRITE(out_UPDATE_RAS_ADDRESS           [i],ras_address          );
269        PORT_WRITE(out_UPDATE_RAS_INDEX             [i],ras_index            );
270          }
271      }
272    }
273   
274    // ===================================================================
275    // =====[ BRANCH_EVENT ]==============================================
276    // ===================================================================
277
278    // For all context ...
279    for (uint32_t i=0; i<_param->_nb_context; i++)
280      {
281        // ... send an event if upt must be update the context
282        Tcontrol_t val = ((reg_UPT_EVENT_STATE [i] == UPT_EVENT_STATE_KO_DECODE_UPDATE_CONTEXT) or
283                          (reg_UPT_EVENT_STATE [i] == UPT_EVENT_STATE_KO_COMMIT_UPDATE_CONTEXT));
284        PORT_WRITE(out_BRANCH_EVENT_VAL              [i],val);
285        if (_param->_have_port_depth)
286        PORT_WRITE(out_BRANCH_EVENT_DEPTH            [i],reg_EVENT_DEPTH            [i]);
287        PORT_WRITE(out_BRANCH_EVENT_ADDRESS_SRC      [i],reg_EVENT_ADDRESS_SRC      [i]);
288        PORT_WRITE(out_BRANCH_EVENT_ADDRESS_DEST_VAL [i],reg_EVENT_ADDRESS_DEST_VAL [i]);
289        PORT_WRITE(out_BRANCH_EVENT_ADDRESS_DEST     [i],reg_EVENT_ADDRESS_DEST     [i]);
290        PORT_WRITE(out_BRANCH_EVENT_CAN_CONTINUE     [i],reg_EVENT_CAN_CONTINUE     [i]);
291       
292        internal_BRANCH_EVENT_VAL [i] = val;
293      }
294
295      }
296    else
297      {
298        // Reset
299        for (uint32_t i=0; i<_param->_nb_inst_update; i++)
300          {
301            internal_UPDATE_VAL             [i] = 0;
302            internal_UPDATE_VAL_WITHOUT_ACK [i] = 0;
303          }
304        for (uint32_t i=0; i<_param->_nb_context; i++)
305          {
306            internal_BRANCH_EVENT_VAL       [i] = 0;
307          }
308      }
309
310
311    log_end(Update_Prediction_Table,FUNCTION);
312  };
313
314}; // end namespace update_prediction_table
315}; // end namespace prediction_unit
316}; // end namespace front_end
317}; // end namespace multi_front_end
318}; // end namespace core
319
320}; // end namespace behavioural
321}; // end namespace morpheo             
322#endif
Note: See TracBrowser for help on using the repository browser.