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

Last change on this file since 108 was 107, checked in by rosiere, 16 years ago

1) Fix test in Direction_Glue for Conditionnal Branch
2) Fix Instruction Address Compute

File size: 22.0 KB
RevLine 
[81]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  {
[88]24    log_begin(Prediction_unit_Glue,FUNCTION);
25    log_function(Prediction_unit_Glue,FUNCTION,_name.c_str());
[98]26
27    if (PORT_READ(in_NRESET))
28      {
29    // Init
[81]30    Tcontrol_t ack [_param->_nb_context];
31    for (uint32_t i=0; i<_param->_nb_context; i++)
[98]32      ack [i] = 0;
[82]33
34    for (uint32_t i=0; i<_param->_nb_inst_branch_predict; i++)
35      {
[88]36        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"  * PREDICT [%d]",i);
[100]37       
38        // No access
[98]39        Tcontrol_t btb_val = false;
40        Tcontrol_t dir_val = false;
41        Tcontrol_t ras_val = false;
42        Tcontrol_t upt_val = false;
[81]43
[100]44        // Get ack
[98]45        Tcontrol_t btb_ack = PORT_READ(in_PREDICT_BTB_ACK [i]);
46        Tcontrol_t dir_ack = PORT_READ(in_PREDICT_DIR_ACK [i]);
47        Tcontrol_t ras_ack = PORT_READ(in_PREDICT_RAS_ACK [i]);
48        Tcontrol_t upt_ack = PORT_READ(in_PREDICT_UPT_ACK [i]);
49
[100]50        // Read context_id
[98]51        Tcontext_t context = (reg_PREDICT_PRIORITY+i)%_param->_nb_context; // priority
[88]52        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * context    : %d",context);
[81]53
[100]54        // Now : ack transaction
[88]55        ack [context] = 1;
[98]56
[88]57        if (PORT_READ(in_PREDICT_VAL[context]) == 0)
58          {
[100]59            // Nothing
[88]60            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * not valid ...");
[81]61
[98]62//             btb_val = false;
63//             dir_val = false;
64//             ras_val = false;
65//             upt_val = false;
[88]66          }
67        else
68          {
[100]69            // Have transaction
[88]70            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * valid ...");
[81]71
[100]72            // Read information (PC)
[88]73            Taddress_t          pc_previous           = PORT_READ(in_PREDICT_PC_PREVIOUS           [context]);
74            Taddress_t          pc_current            = PORT_READ(in_PREDICT_PC_CURRENT            [context]);
75            Tcontrol_t          pc_current_is_ds_take = PORT_READ(in_PREDICT_PC_CURRENT_IS_DS_TAKE [context]);
[81]76
[100]77            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_previous           : 0x%.8x (0x%.8x)",pc_previous,pc_previous<<2);
78            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_current            : 0x%.8x (0x%.8x)",pc_current ,pc_current <<2);
[98]79            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_current_is_ds_take : %d"    ,pc_current_is_ds_take);
80
[88]81            Taddress_t          pc_next                     ;
82            Tcontrol_t          pc_next_is_ds_take          ;
83            Tbranch_state_t     branch_state                ;
84//          Tprediction_ptr_t   branch_update_prediction_id ;
85            Tinst_ifetch_ptr_t  inst_ifetch_ptr             ;
86           
87            // STEP (1) - Compute the address source
[100]88            //   -> if pc_current is a ds take, then pc_previous is a branchement
89            //      get branchement address to send at the BTB
[88]90            Taddress_t          address     = (pc_current_is_ds_take)?pc_previous:pc_current;
[100]91            // Address_lsb = position in fetch packet
[88]92            Taddress_t          address_lsb = pc_current%_param->_nb_instruction [context]; //if pc_current_is_ds_take, then pc_current%_param->_nb_instruction [context] == 0
93            Taddress_t          address_msb;
[81]94
[100]95            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address               : 0x%.8x (0x%.8x)",address,address<<2);
[98]96            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address_lsb           : %d"    ,address_lsb);
[81]97
[88]98            // STEP (2) - Test if branch (access at branch_target_buffer)
[100]99            // Access at the btb
[88]100            btb_val = true;
[81]101
[100]102            // Create the request
[88]103            if (_param->_have_port_context_id)
104            PORT_WRITE(out_PREDICT_BTB_CONTEXT_ID [i],context);
105            PORT_WRITE(out_PREDICT_BTB_ADDRESS    [i],address);
[81]106
[100]107            // Transaction can be ack if btb is not busy
[98]108            ack [context] &= btb_ack;
109
110            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * btb_ack               : %d"    ,btb_ack);
111
[100]112            // BTB_ack = 0 ? else can continue
[98]113            if (not btb_ack)
114              continue;
115
[100]116            // Test a special case :
117            //  if pc_current is a delay slot, then pc_previous is a branchement instruction, also hit must be set.
118            //  else : an another branch instruction have eject this branch : can't accurate
[107]119            Tcontrol_t          hit             = PORT_READ(in_PREDICT_BTB_HIT[i]);
120            Tcontrol_t          is_accurate     = not (pc_current_is_ds_take and not hit);
121            Tcontrol_t          btb_is_accurate = PORT_READ(in_PREDICT_BTB_IS_ACCURATE  [i]);
[81]122
[98]123            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * hit                   : %d"    ,hit);
124            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * is_accurate           : %d"    ,is_accurate);
[107]125            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * btb_is_accurate       : %d"    ,btb_is_accurate);
[98]126
[100]127            // STEP (3) : Test if BTB find a branch instruction in the packet
[88]128            if (hit == 1)
129              {
[100]130                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * BTB hit : no sequential order");
131
[88]132                // STEP (3a) : branch - test condition
133                bool                use_dir      = false;
134                bool                use_ras      = false;
135                bool                use_upt      = false;
[81]136
[100]137                Taddress_t          address_src      = PORT_READ(in_PREDICT_BTB_ADDRESS_SRC  [i]);
138                Taddress_t          address_src_lsb  = address_src%_param->_nb_instruction [context];
[98]139
[100]140                inst_ifetch_ptr = address_src_lsb;
141
142                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * address_src     : 0x%.8x (0x%.8x)",address_src,address_src<<2);
143                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * address_src_lsb : %d",address_src_lsb);
144
145                // Special case :
146                //   * BTB hit and the branchement is the PC current and it's the last slot.
147                //     -> next pc must be the delay slot
[106]148                if ((not pc_current_is_ds_take) and // if pc_current is ds_take, then pc_next is the destination of branchement
[100]149                    (address_src_lsb == (_param->_nb_instruction [context]-1)))
[88]150                  {
[100]151                    // branch is in the last slot of the packet
152                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * branch is in the last slot of the packet");
153               
154                    // Branch is the last slot : next paquet is the delay slot
[101]155                    pc_next            = address_src+1; // sequential
[100]156                    pc_next_is_ds_take = 1;
157                    address_msb        = _param->_nb_instruction [context]; // == (address_src_lsb+1)
158                    branch_state       = BRANCH_STATE_NONE;
159                  }
160                else
161                  {
[107]162                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * branch is not in the last slot of the packet");
163
[100]164                    Tbranch_condition_t condition    = PORT_READ(in_PREDICT_BTB_CONDITION    [i]);
165                    Taddress_t          address_dest = PORT_READ(in_PREDICT_BTB_ADDRESS_DEST [i]);
166                    Tcontrol_t          push     ;
167                    Tcontrol_t          direction;
168                   
169                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * condition             : %s"    ,toString(condition).c_str());
170                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address_src           : 0x%.8x (0x%.8x)",address_src ,address_src <<2);
171                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address_dest          : 0x%.8x (0x%.8x)",address_dest,address_dest<<2);
[107]172
[100]173                    switch (condition)
174                      {
175                      case BRANCH_CONDITION_NONE_WITHOUT_WRITE_STACK          : // l.j
[88]176                        {
[100]177                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_NONE_WITHOUT_WRITE_STACK");
178                         
[106]179                          // use none unit (dir and ras)
180                          use_upt      = true;
[100]181                          direction    = true;
182                          pc_next      = address_dest;
183                          branch_state = BRANCH_STATE_NSPEC_TAKE;
[107]184//                        is_accurate &= btb_is_accurate;
185
[100]186                          break;
187                        }
188                      case BRANCH_CONDITION_NONE_WITH_WRITE_STACK             : // l.jal
189                        {
190                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_NONE_WITH_WRITE_STACK");
191                         
192                          use_upt      = true;
193                          use_ras      = true;
194                          push         = true;
195                          direction    = true;
196                          pc_next      = address_dest;
197                          branch_state = BRANCH_STATE_NSPEC_TAKE;
[107]198//                        is_accurate &= btb_is_accurate;
199
[100]200                          break;
201                        }
202                      case BRANCH_CONDITION_FLAG_UNSET                        : // l.bnf
203                      case BRANCH_CONDITION_FLAG_SET                          : // l.bf
204                        {
205                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_FLAG");
206                         
207                          use_upt      = true;
208                          use_dir      = true;
209                          // Test direction
210                          direction = PORT_READ(in_PREDICT_DIR_DIRECTION [i]); // Direction is not the "flag predict" ... also flag_unset and flag_set is the same
[107]211                          if (direction == 1)
[100]212                            {
213                              branch_state = BRANCH_STATE_SPEC_TAKE;
214                              pc_next      = address_dest;
215                            }
216                          else
217                            {
218                              branch_state = BRANCH_STATE_SPEC_NTAKE;
219                              pc_next      = address_src+2; // +1 = delay slot
220                            }
[107]221
222//                        is_accurate &= btb_is_accurate;
[100]223                          break;
224                        }
225                      case BRANCH_CONDITION_READ_REGISTER_WITHOUT_WRITE_STACK : // l.jr (rb!=9)
226                        {
227                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_READ_REGISTER_WITHOUT_WRITE_STACK");
228                         
229                          use_upt      = true;
230                          use_ras      = true;
231                          push         = true;
232                          direction    = true;
233                          pc_next      = address_dest;
[88]234                          branch_state = BRANCH_STATE_SPEC_TAKE;
[107]235                          is_accurate &= btb_is_accurate;
236
[100]237                          break;
238                        }
239                      case BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK    : // l.jalr
240                        {
241                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK");
242                         
243                          use_upt      = true;
244                          use_ras      = true;
245                          push         = true;
246                          direction    = true;
[88]247                          pc_next      = address_dest;
[100]248                          branch_state = BRANCH_STATE_NSPEC_TAKE;
[107]249                          is_accurate &= btb_is_accurate;
250
[100]251                          break;
[88]252                        }
[100]253                      case BRANCH_CONDITION_READ_STACK                        : // l.jr (rb==9)
[88]254                        {
[100]255                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_READ_STACK");
256                          use_upt      = true;
257                          use_ras      = true;
258                          push         = false;
259                          direction    = true;
[107]260                          pc_next      = PORT_READ(in_PREDICT_RAS_HIT [i])?PORT_READ(in_PREDICT_RAS_ADDRESS_POP [i]):address_dest;
[100]261                          branch_state = BRANCH_STATE_SPEC_TAKE;
[107]262                          is_accurate  &= (PORT_READ(in_PREDICT_RAS_HIT [i]) or btb_is_accurate); // if miss - prediction is not accurate
263
[100]264                          break;
[88]265                        }
[100]266                      default :
267                        {
268                          ERRORMORPHEO(FUNCTION,"Unknow Condition");
269                          break;
270                        }
271                      }
272                   
[107]273                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * direction             : %d",direction);
274                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * branch_state          : %d",branch_state);
275                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_next               : %.8x",pc_next);
276
[100]277                    if (use_dir)
278                      {
279                        ack[context] &= dir_ack;
280                        PORT_WRITE(out_PREDICT_DIR_ADDRESS_SRC [i], address_src);
281                        PORT_WRITE(out_PREDICT_DIR_STATIC      [i], address_dest<address_src); // if destination is previous : the static direction is take
282//                      PORT_WRITE(out_PREDICT_DIR_LAST_TAKE   [i], PORT_READ(in_PREDICT_BTB_LAST_TAKE [i]));
283                      }
284                   
285                    if (use_ras)
286                      {
287                        ack[context] &= ras_ack;
288                        if (_param->_have_port_context_id)
289                        PORT_WRITE(out_PREDICT_RAS_CONTEXT_ID   [i], context);
290                        PORT_WRITE(out_PREDICT_RAS_PUSH         [i], push); 
291                        PORT_WRITE(out_PREDICT_RAS_ADDRESS_PUSH [i], address_src+2); 
292                      }
293                   
294                    if (use_upt)
295                      {
296                        ack[context] &= upt_ack;
297                       
298                        if (_param->_have_port_context_id)
299                        PORT_WRITE(out_PREDICT_UPT_CONTEXT_ID       [i],context);
300                        PORT_WRITE(out_PREDICT_UPT_BTB_ADDRESS_SRC  [i],address_src);
301                        PORT_WRITE(out_PREDICT_UPT_BTB_ADDRESS_DEST [i],address_dest);
302                        PORT_WRITE(out_PREDICT_UPT_BTB_CONDITION    [i],condition);
303                        PORT_WRITE(out_PREDICT_UPT_BTB_LAST_TAKE    [i],direction);
304                        PORT_WRITE(out_PREDICT_UPT_BTB_IS_ACCURATE  [i],is_accurate);
305//                      PORT_WRITE(out_PREDICT_UPT_DIR_HISTORY      [i],PORT_READ(in_PREDICT_DIR_HISTORY      [i]));
306                        PORT_WRITE(out_PREDICT_UPT_RAS_ADDRESS      [i],PORT_READ(in_PREDICT_RAS_ADDRESS_POP  [i]));
307//                      PORT_WRITE(out_PREDICT_UPT_RAS_INDEX        [i],PORT_READ(in_PREDICT_RAS_INDEX        [i]));
308                      }
309                   
310                    // ack = 1 if :
311                    //   *             btb_ack
312                    //   * use_dir and dir_ack
313                    //   * use_ras and ras_ack
314                    //   * use_upt and upt_ack
315//                  ack [context] = (btb_ack and
316//                                   (use_dir and dir_ack) and
317//                                   (use_ras and ras_ack) and
318//                                   (use_upt and upt_ack));
[81]319
[100]320                    dir_val = (btb_ack and
321                               use_dir and
322//                             use_ras and
323//                             use_upt and
324//                             (not use_dir or (use_dir and dir_ack)) and
325                               (not use_ras or (use_ras and ras_ack)) and
326                               (not use_upt or (use_upt and upt_ack)));
[88]327                   
[100]328                    ras_val = (btb_ack and
329//                             use_dir and
330                               use_ras and
331//                             use_upt and
332                               (not use_dir or (use_dir and dir_ack)) and
333//                             (not use_ras or (use_ras and ras_ack)) and
334                               (not use_upt or (use_upt and upt_ack)));
335                   
336                    upt_val = (btb_ack and
337//                             use_dir and
338//                             use_ras and
339                               use_upt and
340                               (not use_dir or (use_dir and dir_ack)) and
341                               (not use_ras or (use_ras and ras_ack))//  and
342//                             (not use_upt or (use_upt and upt_ack))
343                               );
344                   
[106]345                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * btb_{     val, ack}   :    %d, %d",        btb_val, btb_ack);
346                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * dir_{use, val, ack}   : %d, %d, %d",use_dir,dir_val, dir_ack);
347                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * ras_{use, val, ack}   : %d, %d, %d",use_ras,ras_val, ras_ack);
348                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * upt_{use, val, ack}   : %d, %d, %d",use_upt,upt_val, upt_ack);
349
350                   
[100]351//                  pc_next      - is previously computed
352//                  branch_state - is previously computed
[81]353
354
[88]355                    // branch is in the last slot of the packet
356                    address_msb        = (address_src_lsb+2); // +1 == delayed slot
357                    pc_next_is_ds_take = 0;
358                  }
[81]359
[88]360//              branch_update_prediction_id = (_param->_have_port_depth)?((PORT_READ(in_DEPTH_UPT_TAIL[context])+PORT_READ(in_DEPTH_UPT_NB_BRANCH [context]))%_param->_array_size_depth[context]):0;
361              }
362            else
363              {
364                // STEP (3b) : Sequential order : compute next paquet
365                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * BTB miss : sequential order");
[81]366
[100]367                // Take the address packet base and add new packet
[101]368                pc_next                     = pc_current-address_lsb+_param->_nb_instruction [context]; // sequential
[88]369                pc_next_is_ds_take          = 0; // no branch, also no delay slot
370                inst_ifetch_ptr             = 0;
371                branch_state                = BRANCH_STATE_NONE;
372//              branch_update_prediction_id = 0;
[81]373
[88]374                address_msb = _param->_nb_instruction [context];
375              }
[82]376
[100]377            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address_msb           : %d",address_msb);
378            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_next               : 0x%.8x (0x%.8x)",pc_next,pc_next<<2);
379            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_next_is_ds_take    : %d"    ,pc_next_is_ds_take);
380           
381            // Write Output
382            PORT_WRITE(out_PREDICT_PC_NEXT                     [context]   , pc_next                    );
383            PORT_WRITE(out_PREDICT_PC_NEXT_IS_DS_TAKE          [context]   , pc_next_is_ds_take         );
[98]384
[100]385            // Create enable mask
386            Taddress_t address_limit_min = address_lsb;
387            Taddress_t address_limit_max = ((pc_current_is_ds_take)?(address_lsb+1):address_msb);
[82]388
[100]389            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * instruction enable :");
390            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * nb_inst : %d",_param->_nb_instruction [context]);
391            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * [0:%d[ = 0" ,address_limit_min);
392            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * [%d:%d[ = 1",address_limit_min,address_limit_max);
393            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * [%d:%d[ = 0",address_limit_max,_param->_nb_instruction [context]);
394
395            for (uint32_t j=0; j<address_limit_min; j++)
396            PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 0); // Before the address : not valid
397            for (uint32_t j=address_limit_min; j<address_limit_max; j++)
398            PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 1); // Valid packet
399            for (uint32_t j=address_limit_max; j<_param->_nb_instruction [context]; j++)
400            PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 0); // After last address (branch) : not valid
401
402            if (_param->_have_port_inst_ifetch_ptr)
403            PORT_WRITE(out_PREDICT_INST_IFETCH_PTR             [context]   , inst_ifetch_ptr            );
404            PORT_WRITE(out_PREDICT_BRANCH_STATE                [context]   , branch_state               );
405            if (_param->_have_port_depth)
406            PORT_WRITE(out_PREDICT_BRANCH_UPDATE_PREDICTION_ID [context]   , PORT_READ(in_PREDICT_UPT_BRANCH_UPDATE_PREDICTION_ID [i]));
[88]407          }
[81]408
[88]409        // Write output
410        PORT_WRITE(out_PREDICT_BTB_VAL [i], btb_val);
411        PORT_WRITE(out_PREDICT_DIR_VAL [i], dir_val);
412        PORT_WRITE(out_PREDICT_RAS_VAL [i], ras_val);
413        PORT_WRITE(out_PREDICT_UPT_VAL [i], upt_val);
[81]414      }
[100]415   
416    // Write output
[81]417    for (uint32_t i=0; i<_param->_nb_context; i++)
418      PORT_WRITE(out_PREDICT_ACK[i],ack[i]);
[98]419      }
[81]420
[88]421    log_end(Prediction_unit_Glue,FUNCTION);
[81]422  };
423
424}; // end namespace prediction_unit_glue
425}; // end namespace prediction_unit
426}; // end namespace front_end
427}; // end namespace multi_front_end
428}; // end namespace core
429
430}; // end namespace behavioural
431}; // end namespace morpheo             
432#endif
Note: See TracBrowser for help on using the repository browser.