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 @ 82

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