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 @ 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: 22.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_begin(Prediction_unit_Glue,FUNCTION);
25    log_function(Prediction_unit_Glue,FUNCTION,_name.c_str());
26
27    if (PORT_READ(in_NRESET))
28      {
29    // Init
30    Tcontrol_t ack [_param->_nb_context];
31    for (uint32_t i=0; i<_param->_nb_context; i++)
32      ack [i] = 0;
33
34    for (uint32_t i=0; i<_param->_nb_inst_branch_predict; i++)
35      {
36        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"  * PREDICT [%d]",i);
37       
38        // No access
39        Tcontrol_t btb_val = false;
40        Tcontrol_t dir_val = false;
41        Tcontrol_t ras_val = false;
42        Tcontrol_t upt_val = false;
43
44        // Get ack
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
50        // Read context_id
51        Tcontext_t context = (reg_PREDICT_PRIORITY+i)%_param->_nb_context; // priority
52        log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * context    : %d",context);
53
54        // Now : ack transaction
55        ack [context] = 1;
56
57        if (PORT_READ(in_PREDICT_VAL[context]) == 0)
58          {
59            // Nothing
60            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * not valid ...");
61
62//             btb_val = false;
63//             dir_val = false;
64//             ras_val = false;
65//             upt_val = false;
66          }
67        else
68          {
69            // Have transaction
70            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * valid ...");
71
72            // Read information (PC)
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]);
76
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);
79            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_current_is_ds_take : %d"    ,pc_current_is_ds_take);
80
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
88            //   -> if pc_current is a ds take, then pc_previous is a branchement
89            //      get branchement address to send at the BTB
90            Taddress_t          address     = (pc_current_is_ds_take)?pc_previous:pc_current;
91            // Address_lsb = position in fetch packet
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;
94
95            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address               : 0x%.8x (0x%.8x)",address,address<<2);
96            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address_lsb           : %d"    ,address_lsb);
97
98            // STEP (2) - Test if branch (access at branch_target_buffer)
99            // Access at the btb
100            btb_val = true;
101
102            // Create the request
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);
106
107            // Transaction can be ack if btb is not busy
108            ack [context] &= btb_ack;
109
110            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * btb_ack               : %d"    ,btb_ack);
111
112            // BTB_ack = 0 ? else can continue
113            if (not btb_ack)
114              continue;
115
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
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]);
122
123            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * hit                   : %d"    ,hit);
124            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * is_accurate           : %d"    ,is_accurate);
125            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * btb_is_accurate       : %d"    ,btb_is_accurate);
126
127            // STEP (3) : Test if BTB find a branch instruction in the packet
128            if (hit == 1)
129              {
130                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * BTB hit : no sequential order");
131
132                // STEP (3a) : branch - test condition
133                bool                use_dir      = false;
134                bool                use_ras      = false;
135                bool                use_upt      = false;
136
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];
139
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
148                if ((not pc_current_is_ds_take) and // if pc_current is ds_take, then pc_next is the destination of branchement
149                    (address_src_lsb == (_param->_nb_instruction [context]-1)))
150                  {
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
155                    pc_next            = address_src+1; // sequential
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                  {
162                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * branch is not in the last slot of the packet");
163
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);
172
173                    switch (condition)
174                      {
175                      case BRANCH_CONDITION_NONE_WITHOUT_WRITE_STACK          : // l.j
176                        {
177                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_NONE_WITHOUT_WRITE_STACK");
178                         
179                          // use none unit (dir and ras)
180                          use_upt      = true;
181                          direction    = true;
182                          pc_next      = address_dest;
183                          branch_state = BRANCH_STATE_NSPEC_TAKE;
184//                        is_accurate &= btb_is_accurate;
185
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;
198//                        is_accurate &= btb_is_accurate;
199
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
211                          if (direction == 1)
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                            }
221
222//                        is_accurate &= btb_is_accurate;
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;
234                          branch_state = BRANCH_STATE_SPEC_TAKE;
235                          is_accurate &= btb_is_accurate;
236
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;
247                          pc_next      = address_dest;
248                          branch_state = BRANCH_STATE_NSPEC_TAKE;
249                          is_accurate &= btb_is_accurate;
250
251                          break;
252                        }
253                      case BRANCH_CONDITION_READ_STACK                        : // l.jr (rb==9)
254                        {
255                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_READ_STACK");
256                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"        * ras_hit : %d",PORT_READ(in_PREDICT_RAS_HIT [i]));
257                          use_upt      = true;
258                          use_ras      = true;
259                          push         = false;
260                          direction    = true;
261                          address_dest = PORT_READ(in_PREDICT_RAS_HIT [i])?PORT_READ(in_PREDICT_RAS_ADDRESS_POP [i]):address_dest;
262                          pc_next      = address_dest;
263                          branch_state = BRANCH_STATE_SPEC_TAKE;
264                          is_accurate  &= (PORT_READ(in_PREDICT_RAS_HIT [i]) or btb_is_accurate); // if miss - prediction is not accurate
265
266                          break;
267                        }
268                      default :
269                        {
270                          ERRORMORPHEO(FUNCTION,"Unknow Condition");
271                          break;
272                        }
273                      }
274                   
275                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * direction             : %d",direction);
276                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * branch_state          : %d",branch_state);
277                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_next               : 0x%.8x (0x%.8x)",pc_next,pc_next<<2);
278
279                    if (use_dir)
280                      {
281                        ack[context] &= dir_ack;
282                        PORT_WRITE(out_PREDICT_DIR_ADDRESS_SRC [i], address_src);
283                        PORT_WRITE(out_PREDICT_DIR_STATIC      [i], address_dest<address_src); // if destination is previous : the static direction is take
284//                      PORT_WRITE(out_PREDICT_DIR_LAST_TAKE   [i], PORT_READ(in_PREDICT_BTB_LAST_TAKE [i]));
285                      }
286                   
287                    if (use_ras)
288                      {
289                        ack[context] &= ras_ack;
290                        if (_param->_have_port_context_id)
291                        PORT_WRITE(out_PREDICT_RAS_CONTEXT_ID   [i], context);
292                        PORT_WRITE(out_PREDICT_RAS_PUSH         [i], push); 
293                        PORT_WRITE(out_PREDICT_RAS_ADDRESS_PUSH [i], address_src+2); 
294                      }
295                   
296                    if (use_upt)
297                      {
298                        ack[context] &= upt_ack;
299                       
300                        if (_param->_have_port_context_id)
301                        PORT_WRITE(out_PREDICT_UPT_CONTEXT_ID       [i],context);
302                        PORT_WRITE(out_PREDICT_UPT_BTB_ADDRESS_SRC  [i],address_src);
303                        PORT_WRITE(out_PREDICT_UPT_BTB_ADDRESS_DEST [i],address_dest);
304                        PORT_WRITE(out_PREDICT_UPT_BTB_CONDITION    [i],condition);
305                        PORT_WRITE(out_PREDICT_UPT_BTB_LAST_TAKE    [i],direction);
306                        PORT_WRITE(out_PREDICT_UPT_BTB_IS_ACCURATE  [i],is_accurate);
307//                      PORT_WRITE(out_PREDICT_UPT_DIR_HISTORY      [i],PORT_READ(in_PREDICT_DIR_HISTORY      [i]));
308                        PORT_WRITE(out_PREDICT_UPT_RAS_ADDRESS      [i],PORT_READ(in_PREDICT_RAS_ADDRESS_POP  [i]));
309//                      PORT_WRITE(out_PREDICT_UPT_RAS_INDEX        [i],PORT_READ(in_PREDICT_RAS_INDEX        [i]));
310                      }
311                   
312                    // ack = 1 if :
313                    //   *             btb_ack
314                    //   * use_dir and dir_ack
315                    //   * use_ras and ras_ack
316                    //   * use_upt and upt_ack
317//                  ack [context] = (btb_ack and
318//                                   (use_dir and dir_ack) and
319//                                   (use_ras and ras_ack) and
320//                                   (use_upt and upt_ack));
321
322                    dir_val = (btb_ack and
323                               use_dir and
324//                             use_ras and
325//                             use_upt and
326//                             (not use_dir or (use_dir and dir_ack)) and
327                               (not use_ras or (use_ras and ras_ack)) and
328                               (not use_upt or (use_upt and upt_ack)));
329                   
330                    ras_val = (btb_ack and
331//                             use_dir and
332                               use_ras and
333//                             use_upt and
334                               (not use_dir or (use_dir and dir_ack)) and
335//                             (not use_ras or (use_ras and ras_ack)) and
336                               (not use_upt or (use_upt and upt_ack)));
337                   
338                    upt_val = (btb_ack and
339//                             use_dir and
340//                             use_ras and
341                               use_upt and
342                               (not use_dir or (use_dir and dir_ack)) and
343                               (not use_ras or (use_ras and ras_ack))//  and
344//                             (not use_upt or (use_upt and upt_ack))
345                               );
346                   
347                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * btb_{     val, ack}   :    %d, %d",        btb_val, btb_ack);
348                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * dir_{use, val, ack}   : %d, %d, %d",use_dir,dir_val, dir_ack);
349                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * ras_{use, val, ack}   : %d, %d, %d",use_ras,ras_val, ras_ack);
350                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * upt_{use, val, ack}   : %d, %d, %d",use_upt,upt_val, upt_ack);
351
352                   
353//                  pc_next      - is previously computed
354//                  branch_state - is previously computed
355
356
357                    // branch is in the last slot of the packet
358                    address_msb        = (address_src_lsb+2); // +1 == delayed slot
359                    pc_next_is_ds_take = 0;
360                  }
361
362//              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;
363              }
364            else
365              {
366                // STEP (3b) : Sequential order : compute next paquet
367                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * BTB miss : sequential order");
368
369                // Take the address packet base and add new packet
370                pc_next                     = pc_current-address_lsb+_param->_nb_instruction [context]; // sequential
371                pc_next_is_ds_take          = 0; // no branch, also no delay slot
372                inst_ifetch_ptr             = 0;
373                branch_state                = BRANCH_STATE_NONE;
374//              branch_update_prediction_id = 0;
375
376                address_msb = _param->_nb_instruction [context];
377              }
378
379            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address_msb           : %d",address_msb);
380            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_next               : 0x%.8x (0x%.8x)",pc_next,pc_next<<2);
381            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_next_is_ds_take    : %d"    ,pc_next_is_ds_take);
382           
383            // Write Output
384            PORT_WRITE(out_PREDICT_PC_NEXT                     [context]   , pc_next                    );
385            PORT_WRITE(out_PREDICT_PC_NEXT_IS_DS_TAKE          [context]   , pc_next_is_ds_take         );
386
387            // Create enable mask
388            Taddress_t address_limit_min = address_lsb;
389            Taddress_t address_limit_max = ((pc_current_is_ds_take)?(address_lsb+1):address_msb);
390
391            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * instruction enable :");
392            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * nb_inst : %d",_param->_nb_instruction [context]);
393            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * [0:%d[ = 0" ,address_limit_min);
394            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * [%d:%d[ = 1",address_limit_min,address_limit_max);
395            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * [%d:%d[ = 0",address_limit_max,_param->_nb_instruction [context]);
396
397            for (uint32_t j=0; j<address_limit_min; j++)
398            PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 0); // Before the address : not valid
399            for (uint32_t j=address_limit_min; j<address_limit_max; j++)
400            PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 1); // Valid packet
401            for (uint32_t j=address_limit_max; j<_param->_nb_instruction [context]; j++)
402            PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 0); // After last address (branch) : not valid
403
404            if (_param->_have_port_inst_ifetch_ptr)
405            PORT_WRITE(out_PREDICT_INST_IFETCH_PTR             [context]   , inst_ifetch_ptr            );
406            PORT_WRITE(out_PREDICT_BRANCH_STATE                [context]   , branch_state               );
407            if (_param->_have_port_depth)
408            PORT_WRITE(out_PREDICT_BRANCH_UPDATE_PREDICTION_ID [context]   , PORT_READ(in_PREDICT_UPT_BRANCH_UPDATE_PREDICTION_ID [i]));
409          }
410
411        // Write output
412        PORT_WRITE(out_PREDICT_BTB_VAL [i], btb_val);
413        PORT_WRITE(out_PREDICT_DIR_VAL [i], dir_val);
414        PORT_WRITE(out_PREDICT_RAS_VAL [i], ras_val);
415        PORT_WRITE(out_PREDICT_UPT_VAL [i], upt_val);
416      }
417   
418    // Write output
419    for (uint32_t i=0; i<_param->_nb_context; i++)
420      PORT_WRITE(out_PREDICT_ACK[i],ack[i]);
421      }
422    else
423      {
424        // RESET
425        for (uint32_t i=0; i<_param->_nb_inst_branch_predict; i++)
426          {
427            PORT_WRITE(out_PREDICT_BTB_VAL [i], 0);
428            PORT_WRITE(out_PREDICT_DIR_VAL [i], 0);
429            PORT_WRITE(out_PREDICT_RAS_VAL [i], 0);
430            PORT_WRITE(out_PREDICT_UPT_VAL [i], 0);
431          }
432        for (uint32_t i=0; i<_param->_nb_context; i++)
433          PORT_WRITE(out_PREDICT_ACK[i],0);
434      }
435
436    log_end(Prediction_unit_Glue,FUNCTION);
437  };
438
439}; // end namespace prediction_unit_glue
440}; // end namespace prediction_unit
441}; // end namespace front_end
442}; // end namespace multi_front_end
443}; // end namespace core
444
445}; // end namespace behavioural
446}; // end namespace morpheo             
447#endif
Note: See TracBrowser for help on using the repository browser.