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

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

Almost complete design
with Test and test platform

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