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

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

1) Add soc test
2) fix bug (Pc management, Decod and execute, Update prediction ...)

File size: 20.4 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 = PORT_READ(in_PREDICT_BTB_IS_ACCURATE  [i]) and not (pc_current_is_ds_take and not hit);
121
122            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * hit                   : %d"    ,hit);
123            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * is_accurate           : %d"    ,is_accurate);
124
125            // STEP (3) : Test if BTB find a branch instruction in the packet
126            if (hit == 1)
127              {
128                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * BTB hit : no sequential order");
129
130                // STEP (3a) : branch - test condition
131                bool                use_dir      = false;
132                bool                use_ras      = false;
133                bool                use_upt      = false;
134
135                Taddress_t          address_src      = PORT_READ(in_PREDICT_BTB_ADDRESS_SRC  [i]);
136                Taddress_t          address_src_lsb  = address_src%_param->_nb_instruction [context];
137
138                inst_ifetch_ptr = address_src_lsb;
139
140                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * address_src     : 0x%.8x (0x%.8x)",address_src,address_src<<2);
141                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * address_src_lsb : %d",address_src_lsb);
142
143                // Special case :
144                //   * BTB hit and the branchement is the PC current and it's the last slot.
145                //     -> next pc must be the delay slot
146                if ((not pc_current_is_ds_take) and // if pc_current is ds_take, alors pc_next is the destination of branchement
147                    (address_src_lsb == (_param->_nb_instruction [context]-1)))
148                  {
149                    // branch is in the last slot of the packet
150                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * branch is in the last slot of the packet");
151               
152                    // Branch is the last slot : next paquet is the delay slot
153                    pc_next            = address_src+1; // sequential
154                    pc_next_is_ds_take = 1;
155                    address_msb        = _param->_nb_instruction [context]; // == (address_src_lsb+1)
156                    branch_state       = BRANCH_STATE_NONE;
157                  }
158                else
159                  {
160                    Tbranch_condition_t condition    = PORT_READ(in_PREDICT_BTB_CONDITION    [i]);
161                    Taddress_t          address_dest = PORT_READ(in_PREDICT_BTB_ADDRESS_DEST [i]);
162                    Tcontrol_t          push     ;
163                    Tcontrol_t          direction;
164                   
165                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * condition             : %s"    ,toString(condition).c_str());
166                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address_src           : 0x%.8x (0x%.8x)",address_src ,address_src <<2);
167                    log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address_dest          : 0x%.8x (0x%.8x)",address_dest,address_dest<<2);
168                   
169                    switch (condition)
170                      {
171                      case BRANCH_CONDITION_NONE_WITHOUT_WRITE_STACK          : // l.j
172                        {
173                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_NONE_WITHOUT_WRITE_STACK");
174                         
175                          // use none unit (dir, upt and ras)
176                          direction    = true;
177                          pc_next      = address_dest;
178                          branch_state = BRANCH_STATE_NSPEC_TAKE;
179                          break;
180                        }
181                      case BRANCH_CONDITION_NONE_WITH_WRITE_STACK             : // l.jal
182                        {
183                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_NONE_WITH_WRITE_STACK");
184                         
185                          use_upt      = true;
186                          use_ras      = true;
187                          push         = true;
188                          direction    = true;
189                          pc_next      = address_dest;
190                          branch_state = BRANCH_STATE_NSPEC_TAKE;
191                          break;
192                        }
193                      case BRANCH_CONDITION_FLAG_UNSET                        : // l.bnf
194                      case BRANCH_CONDITION_FLAG_SET                          : // l.bf
195                        {
196                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_FLAG");
197                         
198                          use_upt      = true;
199                          use_dir      = true;
200                          // Test direction
201                          direction = PORT_READ(in_PREDICT_DIR_DIRECTION [i]); // Direction is not the "flag predict" ... also flag_unset and flag_set is the same
202                          if (direction = 1)
203                            {
204                              branch_state = BRANCH_STATE_SPEC_TAKE;
205                              pc_next      = address_dest;
206                            }
207                          else
208                            {
209                              branch_state = BRANCH_STATE_SPEC_NTAKE;
210                              pc_next      = address_src+2; // +1 = delay slot
211                            }
212                          break;
213                        }
214                      case BRANCH_CONDITION_READ_REGISTER_WITHOUT_WRITE_STACK : // l.jr (rb!=9)
215                        {
216                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_READ_REGISTER_WITHOUT_WRITE_STACK");
217                         
218                          use_upt      = true;
219                          use_ras      = true;
220                          push         = true;
221                          direction    = true;
222                          pc_next      = address_dest;
223                          branch_state = BRANCH_STATE_SPEC_TAKE;
224                          break;
225                        }
226                      case BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK    : // l.jalr
227                        {
228                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_READ_REGISTER_WITH_WRITE_STACK");
229                         
230                          use_upt      = true;
231                          use_ras      = true;
232                          push         = true;
233                          direction    = true;
234                          pc_next      = address_dest;
235                          branch_state = BRANCH_STATE_NSPEC_TAKE;
236                          break;
237                        }
238                      case BRANCH_CONDITION_READ_STACK                        : // l.jr (rb==9)
239                        {
240                          log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * BRANCH_CONDITION_READ_STACK");
241                          use_upt      = true;
242                          use_ras      = true;
243                          push         = false;
244                          direction    = true;
245                          pc_next      = PORT_READ(in_PREDICT_RAS_ADDRESS_POP  [i]);
246                          branch_state = BRANCH_STATE_SPEC_TAKE;
247                          break;
248                        }
249                      default :
250                        {
251                          ERRORMORPHEO(FUNCTION,"Unknow Condition");
252                          break;
253                        }
254                      }
255                   
256                    if (use_dir)
257                      {
258                        ack[context] &= dir_ack;
259                        PORT_WRITE(out_PREDICT_DIR_ADDRESS_SRC [i], address_src);
260                        PORT_WRITE(out_PREDICT_DIR_STATIC      [i], address_dest<address_src); // if destination is previous : the static direction is take
261//                      PORT_WRITE(out_PREDICT_DIR_LAST_TAKE   [i], PORT_READ(in_PREDICT_BTB_LAST_TAKE [i]));
262                      }
263                   
264                    if (use_ras)
265                      {
266                        ack[context] &= ras_ack;
267                        if (_param->_have_port_context_id)
268                        PORT_WRITE(out_PREDICT_RAS_CONTEXT_ID   [i], context);
269                        PORT_WRITE(out_PREDICT_RAS_PUSH         [i], push); 
270                        PORT_WRITE(out_PREDICT_RAS_ADDRESS_PUSH [i], address_src+2); 
271                       
272                        is_accurate &= PORT_READ(in_PREDICT_RAS_HIT [i]); // if miss - prediction is not accurate
273                      }
274                   
275                    if (use_upt)
276                      {
277                        ack[context] &= upt_ack;
278                       
279                        if (_param->_have_port_context_id)
280                        PORT_WRITE(out_PREDICT_UPT_CONTEXT_ID       [i],context);
281                        PORT_WRITE(out_PREDICT_UPT_BTB_ADDRESS_SRC  [i],address_src);
282                        PORT_WRITE(out_PREDICT_UPT_BTB_ADDRESS_DEST [i],address_dest);
283                        PORT_WRITE(out_PREDICT_UPT_BTB_CONDITION    [i],condition);
284                        PORT_WRITE(out_PREDICT_UPT_BTB_LAST_TAKE    [i],direction);
285                        PORT_WRITE(out_PREDICT_UPT_BTB_IS_ACCURATE  [i],is_accurate);
286//                      PORT_WRITE(out_PREDICT_UPT_DIR_HISTORY      [i],PORT_READ(in_PREDICT_DIR_HISTORY      [i]));
287                        PORT_WRITE(out_PREDICT_UPT_RAS_ADDRESS      [i],PORT_READ(in_PREDICT_RAS_ADDRESS_POP  [i]));
288//                      PORT_WRITE(out_PREDICT_UPT_RAS_INDEX        [i],PORT_READ(in_PREDICT_RAS_INDEX        [i]));
289                      }
290                   
291                    // ack = 1 if :
292                    //   *             btb_ack
293                    //   * use_dir and dir_ack
294                    //   * use_ras and ras_ack
295                    //   * use_upt and upt_ack
296//                  ack [context] = (btb_ack and
297//                                   (use_dir and dir_ack) and
298//                                   (use_ras and ras_ack) and
299//                                   (use_upt and upt_ack));
300
301                    dir_val = (btb_ack and
302                               use_dir and
303//                             use_ras and
304//                             use_upt and
305//                             (not use_dir or (use_dir and dir_ack)) and
306                               (not use_ras or (use_ras and ras_ack)) and
307                               (not use_upt or (use_upt and upt_ack)));
308                   
309                    ras_val = (btb_ack and
310//                             use_dir and
311                               use_ras and
312//                             use_upt and
313                               (not use_dir or (use_dir and dir_ack)) and
314//                             (not use_ras or (use_ras and ras_ack)) and
315                               (not use_upt or (use_upt and upt_ack)));
316                   
317                    upt_val = (btb_ack and
318//                             use_dir and
319//                             use_ras and
320                               use_upt and
321                               (not use_dir or (use_dir and dir_ack)) and
322                               (not use_ras or (use_ras and ras_ack))//  and
323//                             (not use_upt or (use_upt and upt_ack))
324                               );
325                   
326//                  pc_next      - is previously computed
327//                  branch_state - is previously computed
328
329
330                    // branch is in the last slot of the packet
331                    address_msb        = (address_src_lsb+2); // +1 == delayed slot
332                    pc_next_is_ds_take = 0;
333                  }
334
335//              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;
336              }
337            else
338              {
339                // STEP (3b) : Sequential order : compute next paquet
340                log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * BTB miss : sequential order");
341
342                // Take the address packet base and add new packet
343                pc_next                     = pc_current-address_lsb+_param->_nb_instruction [context]; // sequential
344                pc_next_is_ds_take          = 0; // no branch, also no delay slot
345                inst_ifetch_ptr             = 0;
346                branch_state                = BRANCH_STATE_NONE;
347//              branch_update_prediction_id = 0;
348
349                address_msb = _param->_nb_instruction [context];
350              }
351
352            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * address_msb           : %d",address_msb);
353            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_next               : 0x%.8x (0x%.8x)",pc_next,pc_next<<2);
354            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * pc_next_is_ds_take    : %d"    ,pc_next_is_ds_take);
355           
356            // Write Output
357            PORT_WRITE(out_PREDICT_PC_NEXT                     [context]   , pc_next                    );
358            PORT_WRITE(out_PREDICT_PC_NEXT_IS_DS_TAKE          [context]   , pc_next_is_ds_take         );
359
360            // Create enable mask
361            Taddress_t address_limit_min = address_lsb;
362            Taddress_t address_limit_max = ((pc_current_is_ds_take)?(address_lsb+1):address_msb);
363
364            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"    * instruction enable :");
365            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * nb_inst : %d",_param->_nb_instruction [context]);
366            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * [0:%d[ = 0" ,address_limit_min);
367            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * [%d:%d[ = 1",address_limit_min,address_limit_max);
368            log_printf(TRACE,Prediction_unit_Glue,FUNCTION,"      * [%d:%d[ = 0",address_limit_max,_param->_nb_instruction [context]);
369
370            for (uint32_t j=0; j<address_limit_min; j++)
371            PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 0); // Before the address : not valid
372            for (uint32_t j=address_limit_min; j<address_limit_max; j++)
373            PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 1); // Valid packet
374            for (uint32_t j=address_limit_max; j<_param->_nb_instruction [context]; j++)
375            PORT_WRITE(out_PREDICT_INSTRUCTION_ENABLE          [context][j], 0); // After last address (branch) : not valid
376
377            if (_param->_have_port_inst_ifetch_ptr)
378            PORT_WRITE(out_PREDICT_INST_IFETCH_PTR             [context]   , inst_ifetch_ptr            );
379            PORT_WRITE(out_PREDICT_BRANCH_STATE                [context]   , branch_state               );
380            if (_param->_have_port_depth)
381            PORT_WRITE(out_PREDICT_BRANCH_UPDATE_PREDICTION_ID [context]   , PORT_READ(in_PREDICT_UPT_BRANCH_UPDATE_PREDICTION_ID [i]));
382          }
383
384        // Write output
385        PORT_WRITE(out_PREDICT_BTB_VAL [i], btb_val);
386        PORT_WRITE(out_PREDICT_DIR_VAL [i], dir_val);
387        PORT_WRITE(out_PREDICT_RAS_VAL [i], ras_val);
388        PORT_WRITE(out_PREDICT_UPT_VAL [i], upt_val);
389      }
390   
391    // Write output
392    for (uint32_t i=0; i<_param->_nb_context; i++)
393      PORT_WRITE(out_PREDICT_ACK[i],ack[i]);
394      }
395
396    log_end(Prediction_unit_Glue,FUNCTION);
397  };
398
399}; // end namespace prediction_unit_glue
400}; // end namespace prediction_unit
401}; // end namespace front_end
402}; // end namespace multi_front_end
403}; // end namespace core
404
405}; // end namespace behavioural
406}; // end namespace morpheo             
407#endif
Note: See TracBrowser for help on using the repository browser.