source: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Prediction_unit/Prediction_unit_Glue/src/Prediction_unit_Glue_genMealy_predict.cpp @ 81

Last change on this file since 81 was 81, checked in by rosiere, 16 years ago
  • Finish Environment (and test)
  • Continue predictor_unit
  • Add external tools
  • svn keyword "Id" set
File size: 11.2 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/Prediction_unit_Glue/include/Prediction_unit_Glue.h"
10
11namespace morpheo                    {
12namespace behavioural {
13namespace core {
14namespace multi_front_end {
15namespace front_end {
16namespace prediction_unit {
17namespace prediction_unit_glue {
18
19
20#undef  FUNCTION
21#define FUNCTION "Prediction_unit_Glue::genMealy_predict"
22  void Prediction_unit_Glue::genMealy_predict (void)
23  {
24    log_printf(FUNC,Prediction_unit_Glue,FUNCTION,"Begin");
25   
26    Tcontrol_t ack [_param->_nb_context];
27    for (uint32_t i=0; i<_param->_nb_context; i++)
28      ack [i] = 0;
29   
30    for (uint32_t i=0; i<_param->_nb_inst_predict; i++)
31      {
32        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"PREDICT [%d]",i);
33
34        Tcontrol_t btb_val;
35        Tcontrol_t dir_val;
36        Tcontrol_t ras_val;
37        Tcontrol_t upt_val;
38
39        Tcontext_t context = (reg_PREDICT_PRIORITY+i)%_param->_nb_context;
40        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"  * context    : %d",context);
41
42        ack [context] = 1;
43           
44        if (PORT_READ(in_PREDICT_VAL[context]) == 0)
45          {
46            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"  * not valid ...");
47
48            btb_val = false;
49            dir_val = false;
50            ras_val = false;
51            upt_val = false;
52          }
53        else
54          {
55            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"  * valid ...");
56
57            Taddress_t          pc_previous           = PORT_READ(in_PREDICT_PC_PREVIOUS           [context]);
58            Taddress_t          pc_current            = PORT_READ(in_PREDICT_PC_CURRENT            [context]);
59            Tcontrol_t          pc_current_is_ds_take = PORT_READ(in_PREDICT_PC_CURRENT_IS_DS_TAKE [context]);
60
61            Taddress_t          pc_next                     ;
62            Tcontrol_t          pc_next_is_ds_take          ;
63            Tbranch_state_t     branch_state                ;
64            Tprediction_ptr_t   branch_update_prediction_id ;
65            Tinst_ifetch_ptr_t  inst_ifetch_ptr             ;
66           
67            // STEP (1) - Compute the address source
68            Taddress_t          address     = (pc_current_is_ds_take)?pc_previous:pc_current;
69            Taddress_t          address_lsb = pc_current%_param->_nb_instruction [context]; //if pc_current_is_ds_take, then pc_current%_param->_nb_instruction [context] == 0
70            Taddress_t          address_msb;
71
72            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"  * address    : 0x%x",address);
73
74            // STEP (2) - Test if branch (access at branch_target_buffer)
75            btb_val = true;
76            ack [context] &= PORT_READ(in_PREDICT_BTB_ACK [i]);
77
78            if (_param->_have_port_context_id)
79            PORT_WRITE(out_PREDICT_BTB_CONTEXT_ID [i],context);
80            PORT_WRITE(out_PREDICT_BTB_ADDRESS    [i],address);
81
82            // special case :
83            //  if pc_current_is_ds, then pc_previous have branch, also hit must be set.
84            //  else : a another branch have eject this branch : can't accurate
85            Tcontrol_t          hit         = PORT_READ(in_PREDICT_BTB_HIT[i]);
86            Tcontrol_t          is_accurate = PORT_READ(in_PREDICT_BTB_IS_ACCURATE  [i]) and not (pc_current_is_ds_take and not hit);
87
88            // STEP (3) : Test if have branch in the packet
89            if (hit == 1)
90              {
91                // STEP (3a) : branch - test condition
92
93                bool                use_dir      = false;
94                bool                use_ras      = false;
95                bool                use_upt      = false;
96               
97                Tbranch_condition_t cond         = PORT_READ(in_PREDICT_BTB_CONDITION    [i]);
98                Taddress_t          address_src  = PORT_READ(in_PREDICT_BTB_ADDRESS_SRC  [i]);
99                Taddress_t          address_dest = PORT_READ(in_PREDICT_BTB_ADDRESS_DEST [i]);
100                Tcontrol_t          push;
101                Tcontrol_t          direction;
102
103                switch (cond)
104                  {
105                  case BRANCH_CONDITION_NONE_WITHOUT_WRITE_STACK          : // l.j
106                    {
107                      // use none unit (dir, upt and ras)
108                      direction    = true;
109                      pc_next      = address_dest;
110                      branch_state = BRANCH_STATE_NSPEC_TAKE;
111                      break;
112                    }
113                  case BRANCH_CONDITION_NONE_WITH_WRITE_STACK             : // l.jal
114                    {
115                      use_upt      = true;
116                      use_ras      = true;
117                      push         = true;
118                      direction    = true;
119                      pc_next      = address_dest;
120                      branch_state = BRANCH_STATE_NSPEC_TAKE;
121                      break;
122                    }
123                  case BRANCH_CONDITION_FLAG_UNSET                        : // l.bnf
124                  case BRANCH_CONDITION_FLAG_SET                          : // l.bf
125                    {
126                      use_upt      = true;
127                      use_dir      = true;
128                      // Test direction
129                      direction = PORT_READ(in_PREDICT_DIR_DIRECTION [i]); // Direction is not the "flag predict" ... also flag_unset and flag_set is the same
130                      if (direction = 1)
131                        {
132                          branch_state = BRANCH_STATE_SPEC_TAKE;
133                          pc_next      = address_dest;
134                        }
135                      else
136                        {
137                          branch_state = BRANCH_STATE_SPEC_NTAKE;
138                          pc_next      = address_src+8; // +4 = delay slot
139                        }
140                      break;
141                    }
142                  case BRANCH_CONDITION_READ_REGISTER_WITHOUT_WRITE_STACK : // l.jr (rb!=9)
143                    {
144                      use_upt      = true;
145                      use_ras      = true;
146                      push         = true;
147                      direction    = true;
148                      pc_next      = address_dest;
149                      branch_state = BRANCH_STATE_SPEC_TAKE;
150                      break;
151                    }
152                  case BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK    : // l.jalr
153                    {
154                      use_upt      = true;
155                      use_ras      = true;
156                      push         = true;
157                      direction    = true;
158                      pc_next      = address_dest;
159                      branch_state = BRANCH_STATE_NSPEC_TAKE;
160                      break;
161                    }
162                  case BRANCH_CONDITION_READ_STACK                        : // l.jr (rb==9)
163                    {
164                      use_upt      = true;
165                      use_ras      = true;
166                      push         = false;
167                      direction    = true;
168                      pc_next      = PORT_READ(in_PREDICT_RAS_ADDRESS_POP  [i]);
169                      branch_state = BRANCH_STATE_SPEC_TAKE;
170                      break;
171                    }
172                  default :
173                    {
174                      ERRORMORPHEO(FUNCTION,"Unknow Condition");
175                      break;
176                    }
177                  }
178
179                if (use_dir)
180                  {
181                    ack[context] &= PORT_READ(in_PREDICT_DIR_ACK [i]);
182                    PORT_WRITE(out_PREDICT_DIR_ADDRESS_SRC [i], address_src);
183                    PORT_WRITE(out_PREDICT_DIR_STATIC      [i], address_dest<address_src); // if destination is previous : the static direction is take
184//                  PORT_WRITE(out_PREDICT_DIR_LAST_TAKE   [i], PORT_READ(in_PREDICT_BTB_LAST_TAKE [i]));
185                  }
186
187                if (use_ras)
188                  {
189                    ack[context] &= PORT_READ(in_PREDICT_RAS_ACK [i]);
190                    if (_param->_have_port_context_id)
191                    PORT_WRITE(out_PREDICT_RAS_CONTEXT_ID   [i], context);
192                    PORT_WRITE(out_PREDICT_RAS_PUSH         [i], push); 
193                    PORT_WRITE(out_PREDICT_RAS_ADDRESS_PUSH [i], address_src+8); 
194
195                    is_accurate &= PORT_READ(in_PREDICT_RAS_HIT [i]); // if miss - prediction is not accurate
196                  }
197
198                if (use_upt)
199                  {
200                    ack[context] &= PORT_READ(in_PREDICT_UPT_ACK [i]);
201                   
202                    PORT_WRITE(out_PREDICT_UPT_CONTEXT_ID       [i],context);
203                    PORT_WRITE(out_PREDICT_UPT_BTB_ADDRESS_SRC  [i],address_src);
204                    PORT_WRITE(out_PREDICT_UPT_BTB_ADDRESS_DEST [i],address_dest);
205                    PORT_WRITE(out_PREDICT_UPT_BTB_CONDITION    [i],cond);
206                    PORT_WRITE(out_PREDICT_UPT_BTB_LAST_TAKE    [i],direction);
207                    PORT_WRITE(out_PREDICT_UPT_BTB_IS_ACCURATE  [i],is_accurate);
208//                  PORT_WRITE(out_PREDICT_UPT_DIR_HISTORY      [i],PORT_READ(in_PREDICT_DIR_HISTORY      [i]));
209                    PORT_WRITE(out_PREDICT_UPT_RAS_ADDRESS      [i],PORT_READ(in_PREDICT_RAS_ADDRESS_POP  [i]));
210//                  PORT_WRITE(out_PREDICT_UPT_RAS_INDEX        [i],PORT_READ(in_PREDICT_RAS_INDEX        [i]));
211                  }
212
213                // ack = 1 if :
214                //   *             btb_ack
215                //   * use_dir and dir_ack
216                //   * use_ras and ras_ack
217                //   * use_upt and upt_ack
218//              ack [context] = (PORT_READ(in_PREDICT_BTB_ACK [i]) and
219//                               (use_dir and PORT_READ(in_PREDICT_DIR_ACK [i])) and
220//                               (use_ras and PORT_READ(in_PREDICT_RAS_ACK [i])) and
221//                               (use_upt and PORT_READ(in_PREDICT_UPT_ACK [i])));
222
223                dir_val = (PORT_READ(in_PREDICT_BTB_ACK [i]) and
224                           (use_ras and PORT_READ(in_PREDICT_RAS_ACK [i])) and
225                           (use_upt and PORT_READ(in_PREDICT_UPT_ACK [i])));
226
227                ras_val = (PORT_READ(in_PREDICT_BTB_ACK [i]) and
228                           (use_dir and PORT_READ(in_PREDICT_DIR_ACK [i])) and
229                           (use_upt and PORT_READ(in_PREDICT_UPT_ACK [i])));
230
231                upt_val = (PORT_READ(in_PREDICT_BTB_ACK [i]) and
232                           (use_dir and PORT_READ(in_PREDICT_DIR_ACK [i])) and
233                           (use_ras and PORT_READ(in_PREDICT_RAS_ACK [i])));
234
235//              pc_next      - is previously computed
236//              branch_state - is previously computed
237
238                Taddress_t address_src_lsb  = address_src%_param->_nb_instruction [context];
239
240                if (address_src_lsb == (_param->_nb_instruction [context]-1))
241                  {
242                    // branch is in the last slot of the packet
243                    address_msb        = _param->_nb_instruction [context]; // == (address_src_lsb+1)
244                    pc_next_is_ds_take = 1;
245                  }
246                else
247                  {
248                    // branch is in the last slot of the packet
249                    address_msb        = (address_src_lsb+2); // +1 == delayed slot
250                    pc_next_is_ds_take = 0;
251                  }
252
253                inst_ifetch_ptr             = address_src_lsb;
254                branch_update_prediction_id = (PORT_READ(in_DEPTH_UPT_TAIL[context])+PORT_READ(in_DEPTH_UPT_NB_BRANCH [context]))%_param->_size_depth[context];
255              }
256            else
257              {
258                // STEP (3b) : Sequential order : compute next paquet
259                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"  * BTB miss : sequential order");
260
261                pc_next                     = address-address_lsb+_param->_nb_instruction [context]; // sequencial
262                pc_next_is_ds_take          = 0; // no branch, also no delay slot
263                inst_ifetch_ptr             = 0;
264                branch_state                = BRANCH_STATE_NONE;
265                branch_update_prediction_id = 0;
266
267                address_msb = _param->_nb_instruction [context];
268              }
269             
270              PORT_WRITE(out_PREDICT_PC_NEXT                     [context]   , pc_next                    );
271              PORT_WRITE(out_PREDICT_PC_NEXT_IS_DS_TAKE          [context]   , pc_next_is_ds_take         );
272              for (uint32_t j=0; j<address_lsb; j++)
273              PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 0); // Before the address : not valid
274              for (uint32_t j=address_lsb; j<((pc_current_is_ds_take)?1:address_msb); j++)
275              PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 1); // Vald packet
276              for (uint32_t j=((pc_current_is_ds_take)?1:address_msb); j<_param->_nb_instruction [context]; j++)
277              PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 0); // After last address (branch) : not valid
278              if (_param->_have_port_inst_ifetch_ptr[context])
279              PORT_WRITE(out_PREDICT_INST_IFETCH_PTR             [context]   , inst_ifetch_ptr            );
280              PORT_WRITE(out_PREDICT_BRANCH_STATE                [context]   , branch_state               );
281              if (_param->_have_port_depth[context])
282              PORT_WRITE(out_PREDICT_BRANCH_UPDATE_PREDICTION_ID [context]   , branch_update_prediction_id);
283          }
284
285        // Write output
286        PORT_WRITE(out_PREDICT_BTB_VAL [i], btb_val);
287        PORT_WRITE(out_PREDICT_DIR_VAL [i], dir_val);
288        PORT_WRITE(out_PREDICT_RAS_VAL [i], ras_val);
289        PORT_WRITE(out_PREDICT_UPT_VAL [i], upt_val);
290      }
291
292    for (uint32_t i=0; i<_param->_nb_context; i++)
293      PORT_WRITE(out_PREDICT_ACK[i],ack[i]);
294
295    log_printf(FUNC,Prediction_unit_Glue,FUNCTION,"End");
296  };
297
298}; // end namespace prediction_unit_glue
299}; // end namespace prediction_unit
300}; // end namespace front_end
301}; // end namespace multi_front_end
302}; // end namespace core
303
304}; // end namespace behavioural
305}; // end namespace morpheo             
306#endif
Note: See TracBrowser for help on using the repository browser.