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

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

1) Fix performance
2) add auto generation to SPECINT2000
3) add reset in genMoore and genMealy

File size: 16.7 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        if (val)
251          {
252        if (_param->_have_port_context_id)
253        PORT_WRITE(out_UPDATE_CONTEXT_ID            [i],context              );
254        PORT_WRITE(out_UPDATE_MISS_PREDICTION       [i],miss_prediction      );
255        PORT_WRITE(out_UPDATE_DIRECTION_GOOD        [i],direction_good       );
256        PORT_WRITE(out_UPDATE_PREDICTION_IFETCH     [i],prediction_ifetch    );
257        PORT_WRITE(out_UPDATE_BTB_VAL               [i],btb_val              );
258        PORT_WRITE(out_UPDATE_BTB_ADDRESS_SRC       [i],btb_address_src      );
259        PORT_WRITE(out_UPDATE_BTB_ADDRESS_DEST      [i],btb_address_dest     );
260        PORT_WRITE(out_UPDATE_BTB_CONDITION         [i],btb_condition        );
261        PORT_WRITE(out_UPDATE_DIR_VAL               [i],dir_val              );
262        if (_param->_have_port_history)
263        PORT_WRITE(out_UPDATE_DIR_HISTORY           [i],dir_history          );
264        PORT_WRITE(out_UPDATE_RAS_VAL               [i],ras_val              );
265        PORT_WRITE(out_UPDATE_RAS_FLUSH             [i],ras_flush            );
266        PORT_WRITE(out_UPDATE_RAS_PUSH              [i],ras_push             );
267        PORT_WRITE(out_UPDATE_RAS_ADDRESS           [i],ras_address          );
268        PORT_WRITE(out_UPDATE_RAS_INDEX             [i],ras_index            );
269          }
270      }
271    }
272   
273    // ===================================================================
274    // =====[ BRANCH_EVENT ]==============================================
275    // ===================================================================
276
277    // For all context ...
278    for (uint32_t i=0; i<_param->_nb_context; i++)
279      {
280        // ... send an event if upt must be update the context
281        Tcontrol_t val = ((reg_UPT_EVENT_STATE [i] == UPT_EVENT_STATE_KO_DECODE_UPDATE_CONTEXT) or
282                          (reg_UPT_EVENT_STATE [i] == UPT_EVENT_STATE_KO_COMMIT_UPDATE_CONTEXT));
283        if (_param->_have_port_depth)
284        PORT_WRITE(out_BRANCH_EVENT_DEPTH            [i],reg_EVENT_DEPTH            [i]);
285        PORT_WRITE(out_BRANCH_EVENT_ADDRESS_SRC      [i],reg_EVENT_ADDRESS_SRC      [i]);
286        PORT_WRITE(out_BRANCH_EVENT_ADDRESS_DEST_VAL [i],reg_EVENT_ADDRESS_DEST_VAL [i]);
287        PORT_WRITE(out_BRANCH_EVENT_ADDRESS_DEST     [i],reg_EVENT_ADDRESS_DEST     [i]);
288        PORT_WRITE(out_BRANCH_EVENT_CAN_CONTINUE     [i],reg_EVENT_CAN_CONTINUE     [i]);
289       
290        internal_BRANCH_EVENT_VAL [i] = val;
291      }
292
293      }
294    else
295      {
296        // Reset
297        for (uint32_t i=0; i<_param->_nb_inst_update; i++)
298          {
299            internal_UPDATE_VAL             [i] = 0;
300            internal_UPDATE_VAL_WITHOUT_ACK [i] = 0;
301            internal_UPDATE_CONTEXT_ID      [i] = 0;
302       
303          }
304        for (uint32_t i=0; i<_param->_nb_context; i++)
305          {
306            internal_BRANCH_EVENT_VAL       [i] = 0;
307          }
308      }
309
310    // Write output
311    for (uint32_t i=0; i<_param->_nb_inst_update; i++)
312      PORT_WRITE(out_UPDATE_VAL       [i],internal_UPDATE_VAL [i]);
313    for (uint32_t i=0; i<_param->_nb_context; i++)
314      PORT_WRITE(out_BRANCH_EVENT_VAL [i],internal_BRANCH_EVENT_VAL [i]);
315
316    log_end(Update_Prediction_Table,FUNCTION);
317  };
318
319}; // end namespace update_prediction_table
320}; // end namespace prediction_unit
321}; // end namespace front_end
322}; // end namespace multi_front_end
323}; // end namespace core
324
325}; // end namespace behavioural
326}; // end namespace morpheo             
327#endif
Note: See TracBrowser for help on using the repository browser.