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

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

1) Fix bug (read unit, RAT -> write in R0, SPR desallocation ...)
2) Change VHDL Execute_queue -> use Generic/Queue?
3) Complete document on VHDL generation
4) Add soc test

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