source: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Context_State/src/Context_State_transition.cpp @ 145

Last change on this file since 145 was 145, checked in by rosiere, 14 years ago

1) add test with SPECINT2K
2) new config of Selftest
3) modif RAT to support multiple depth_save ... but not finish (need fix Update Prediction Table)
4) add Function_pointer but need fix

  • Property svn:keywords set to Id
File size: 40.8 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Context_State_transition.cpp 145 2010-10-13 18:15:51Z rosiere $
4 *
5 * [ Description ]
6 *
7 */
8
9#include "Behavioural/Core/Multi_Front_end/Front_end/Context_State/include/Context_State.h"
10
11namespace morpheo                    {
12namespace behavioural {
13namespace core {
14namespace multi_front_end {
15namespace front_end {
16namespace context_state {
17
18// #define MANAGE_EVENT MANAGE_EVENT_WAIT_ALL
19// #define MANAGE_EVENT MANAGE_EVENT_WAIT_DECODE
20#define MANAGE_EVENT MANAGE_EVENT_NO_WAIT
21
22#define PRIORITY_MISS_LOAD   3
23#define PRIORITY_MISS_BRANCH 2
24#define PRIORITY_EXCEPTION   1
25#define PRIORITY_NONE        0
26
27#define get_priority(x) \
28  (((state == CONTEXT_STATE_KO_MISS_LOAD_ADDR                  ) or  \
29    (state == CONTEXT_STATE_KO_MISS_LOAD_WAITEND               ) or  \
30    (state == CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR       ) or  \
31    (state == CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAITEND    ) or  \
32    (state == CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAIT_UPDATE))?PRIORITY_MISS_LOAD: \
33  (((state == CONTEXT_STATE_KO_MISS_BRANCH_ADDR                ) or  \
34    (state == CONTEXT_STATE_KO_MISS_BRANCH_WAITEND             ) or  \
35    (state == CONTEXT_STATE_KO_MISS_BRANCH_INACCURATE          ) or  \
36    (state == CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE         ))?PRIORITY_MISS_BRANCH: \
37   ((state == EVENT_TYPE_EXCEPTION)?PRIORITY_EXCEPTION:                           \
38    0)))
39
40#undef  FUNCTION
41#define FUNCTION "Context_State::transition"
42  void Context_State::transition (void)
43  {
44    log_begin(Context_State,FUNCTION);
45    log_function(Context_State,FUNCTION,_name.c_str());
46
47    if (PORT_READ(in_NRESET) == 0)
48      {
49        for (uint32_t i=0; i<_param->_nb_context; i++)
50          {
51            reg_STATE            [i] = CONTEXT_STATE_OK;
52            reg_INTERRUPT_ENABLE [i] = 0;
53
54            reg_EVENT_ADDRESS          [i] = 0; // not necessary
55            reg_EVENT_ADDRESS_EPCR     [i] = 0; // not necessary
56            reg_EVENT_ADDRESS_EPCR_VAL [i] = 0; // not necessary
57            reg_EVENT_ADDRESS_EEAR     [i] = 0; // not necessary
58            reg_EVENT_ADDRESS_EEAR_VAL [i] = 0; // not necessary
59            reg_EVENT_IS_DELAY_SLOT    [i] = 0; // not necessary
60            reg_EVENT_IS_DS_TAKE       [i] = 0; // not necessary
61            reg_EVENT_DEPTH            [i] = 0; // not necessary
62            reg_EVENT_FLUSH_ONLY       [i] = 0; // not necessary
63          }
64      }
65    else
66      {
67        // -------------------------------------------------------------------
68        // -----[ next state ]------------------------------------------------
69        // -------------------------------------------------------------------
70        for (uint32_t i=0; i<_param->_nb_context; i++)
71          {
72//             uint32_t x = _param->_link_context_to_decod_unit    [i];
73
74            Tcounter_t inst_commit_all = PORT_READ(in_NB_INST_COMMIT_ALL[i]);
75//          Tcounter_t inst_commit_mem = PORT_READ(in_NB_INST_COMMIT_MEM[i]);
76            Tcounter_t inst_decod_all  = PORT_READ(in_NB_INST_DECOD_ALL [i]);
77            Tcounter_t inst_all        = inst_commit_all + inst_decod_all;
78//          Tcounter_t inst_mem        = inst_commit_mem + inst_decod_all;
79            bool       condition       = ( (MANAGE_EVENT == MANAGE_EVENT_WAIT_ALL   )?(inst_all       == 0):
80                                          ((MANAGE_EVENT == MANAGE_EVENT_WAIT_DECODE)?(inst_decod_all == 0):
81                                            true));
82
83            context_state_t state = reg_STATE [i];
84
85            switch (state)
86              {
87              case CONTEXT_STATE_OK              :
88                {
89                  // nothing, wait an event
90                  break;
91                }
92              case CONTEXT_STATE_KO_EXCEP        :
93                {
94                  // Wait end of all instruction
95                  if (inst_all == 0)
96//                if (inst_decod_all == 0)
97                    state = CONTEXT_STATE_KO_EXCEP_ADDR;
98                  break;
99                }
100              case CONTEXT_STATE_KO_EXCEP_ADDR   :
101                {
102                  // nothing, wait the update of internal register (pc)
103                  break;
104                }
105              case CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE :
106                {
107                  // nothing : wait end of update upt
108                  break;
109                }
110              case CONTEXT_STATE_KO_MISS_BRANCH_WAITEND :
111                {
112                  if (condition)
113//                  state = CONTEXT_STATE_OK;
114                    state = CONTEXT_STATE_KO_MISS_BRANCH_ADDR;
115                  break;
116                }
117              case CONTEXT_STATE_KO_MISS_BRANCH_INACCURATE :
118                {
119                  if (inst_all == 0)
120//                  state = CONTEXT_STATE_OK;
121                    state = CONTEXT_STATE_OK;
122                  break;
123                }
124              case CONTEXT_STATE_KO_MISS_LOAD_WAITEND :
125                {
126                  // Wait end of all instruction
127                  if (condition)
128                    state = CONTEXT_STATE_KO_MISS_LOAD_ADDR;
129
130                  break;
131                }
132              case CONTEXT_STATE_KO_EXCEP_SPR    :
133                {
134                  // nothing, wait the update of internal register (epcr, eear, sr, esr)
135                  break;
136                }
137              case CONTEXT_STATE_KO_MISS_BRANCH_ADDR    :
138                {
139                  // nothing, wait the update of internal register (pc)
140                  break;
141                }
142              case CONTEXT_STATE_KO_MISS_LOAD_ADDR    :
143                {
144                  // nothing, wait the update of internal register (pc)
145                  break;
146                }
147              case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAIT_UPDATE :
148                {
149                  // nothing : wait end of update upt
150                  break;
151                }
152              case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR    :
153                {
154                  // nothing, wait the update of internal register (pc)
155                  break;
156                }
157              case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAITEND :
158                {
159                  // Wait end of all instruction
160                  if (condition)
161//                  state = CONTEXT_STATE_OK; // @@@ TODO : make MISS fast (miss decod)
162                    state = CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR;
163                  break;
164                }
165//               case CONTEXT_STATE_KO_PSYNC        :
166//                 {
167//                   // Wait end of all instruction
168//                   if (inst_all == 0)
169//                     state = CONTEXT_STATE_KO_PSYNC_FLUSH;
170//                   break;
171//                 }
172              case CONTEXT_STATE_KO_PSYNC_FLUSH  :
173                {
174                  // nothing, wait end of flush (ifetch)
175                  if (inst_all == 0)
176//                  state = CONTEXT_STATE_KO_PSYNC_ADDR;
177                    state = CONTEXT_STATE_OK;
178                   
179                  break;
180                }
181              case CONTEXT_STATE_KO_PSYNC_ADDR   :
182                {
183                  // nothing, wait the pc write
184                  break;
185                }
186//               case CONTEXT_STATE_KO_CSYNC        :
187//                 {
188//                   // Wait end of all instruction
189//                   if (inst_all == 0)
190//                     state = CONTEXT_STATE_KO_CSYNC_FLUSH;
191//                   break;
192//                 }
193              case CONTEXT_STATE_KO_CSYNC_FLUSH  :
194                {
195                  // nothing, wait end of flush (all internal structure)
196                  if (inst_all == 0)
197                    state = CONTEXT_STATE_KO_CSYNC_ADDR;
198                  break;
199                }
200              case CONTEXT_STATE_KO_CSYNC_ADDR   :
201                {
202                  // nothing, wait the pc write
203                  break;
204                }
205//               case CONTEXT_STATE_KO_MSYNC        :
206//                 {
207//                   // Wait end of memory instruction
208//                   if (inst_mem == 0)
209//                     state = CONTEXT_STATE_KO_MSYNC_ISSUE;
210//                   break;
211//                 }
212//               case CONTEXT_STATE_KO_MSYNC_ISSUE  :
213//                 {
214//                   // Wait the msync issue
215//                   if (inst_mem != 0)
216//                     state = CONTEXT_STATE_KO_MSYNC_EXEC;
217//                   break;
218//                 }
219              case CONTEXT_STATE_KO_MSYNC_EXEC   :
220                {
221                  // Wait the end of msync
222                  if (inst_all == 0)
223                    state = CONTEXT_STATE_OK;
224                  break;
225                }
226//               case CONTEXT_STATE_KO_SPR          :
227//                 {
228//                   // Wait end of all instruction
229//                   if (inst_all == 0)
230//                     state = CONTEXT_STATE_KO_SPR_ISSUE;
231//                   break;
232//                 }
233//               case CONTEXT_STATE_KO_SPR_ISSUE    :
234//                 {
235//                   // Wait the spr_access issue
236//                   if (inst_all != 0)
237//                     state = CONTEXT_STATE_KO_SPR_EXEC;
238//                   break;
239//                 }
240              case CONTEXT_STATE_KO_SPR_EXEC     :
241                {
242                  // Wait the spr_access execution
243                  if (inst_all == 0)
244                    state = CONTEXT_STATE_OK;
245                  break;
246                }
247
248              default :
249                {
250                  throw ERRORMORPHEO(FUNCTION,toString(_("Context[%d], Unknow state : %s.\n"),i,toString(state).c_str()));
251                }
252              }
253            reg_STATE [i] = state;
254          }
255
256        // -------------------------------------------------------------------
257        // -----[ BRANCH_EVENT ]----------------------------------------------
258        // -------------------------------------------------------------------
259        for (uint32_t i=0; i<_param->_nb_context; ++i)
260          if (PORT_READ(in_BRANCH_EVENT_VAL [i]) and internal_BRANCH_EVENT_ACK [i])
261            {
262              log_printf(TRACE,Context_State,FUNCTION,"  * BRANCH_EVENT [%d]",i);
263
264              context_state_t state = reg_STATE [i];
265
266              Tdepth_t   depth      = (_param->_have_port_depth)?PORT_READ(in_BRANCH_EVENT_DEPTH [i]):0;
267              Tdepth_t   depth_cur  = reg_EVENT_DEPTH [i];
268              Tdepth_t   depth_min  = (_param->_have_port_depth)?PORT_READ(in_DEPTH_MIN [i]):0;
269              Tdepth_t   depth_max  = _param->_nb_inst_branch_speculated [i];
270             
271              Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur-depth_min):((depth_cur+depth_max-depth_min));
272              Tdepth_t   depth1     = (depth    >=depth_min)?(depth    -depth_min):((depth    +depth_max-depth_min));
273//               Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur):((depth_cur+depth_max));
274//               Tdepth_t   depth1     = (depth    >=depth_min)?(depth    ):((depth    +depth_max));
275
276              // priority : miss_load > miss_branch > excep > spr/sync
277              uint8_t    priority0  = get_priority(state);
278              uint8_t    priority1  = PRIORITY_MISS_BRANCH; // miss
279
280              // is_valid = can modify local information
281              //   if context_state_ok : yes
282              //   if context_state_ko : test the depth, and the priority of event
283              bool       is_valid   = ((state == CONTEXT_STATE_OK) or
284                                       (state == CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE) or
285//                                     (state == CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAIT_UPDATE) or
286                                       (depth1< depth0) or
287                                       ((depth1==depth0) and (priority1>=priority0))); // >= because another branch can be a miss prediction with same depth
288
289              bool       is_invalid = priority0 == PRIORITY_MISS_LOAD;
290
291#ifdef DEBUG_TEST
292              if ((state == CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE) and
293                  (depth0 != depth1))
294                throw ERRORMORPHEO(FUNCTION,toString(_("BRANCH_EVENT[%d] : Invalid state : %s.\n"),i,toString(state).c_str()));
295#endif
296
297              log_printf(TRACE,Context_State,FUNCTION,"    * state     : %s",toString(state).c_str());
298              log_printf(TRACE,Context_State,FUNCTION,"    * depth     : %d",depth     );
299              log_printf(TRACE,Context_State,FUNCTION,"    * depth_cur : %d",depth_cur );
300              log_printf(TRACE,Context_State,FUNCTION,"    * depth_min : %d",depth_min );
301              log_printf(TRACE,Context_State,FUNCTION,"    * depth_max : %d",depth_max );
302              log_printf(TRACE,Context_State,FUNCTION,"    * depth0    : %d",depth0    );
303              log_printf(TRACE,Context_State,FUNCTION,"    * depth1    : %d",depth1    );
304              log_printf(TRACE,Context_State,FUNCTION,"    * priority0 : %d",priority0 );
305              log_printf(TRACE,Context_State,FUNCTION,"    * priority1 : %d",priority1 );
306              log_printf(TRACE,Context_State,FUNCTION,"  * is_valid    : %d",is_valid  );
307              log_printf(TRACE,Context_State,FUNCTION,"  * is_invalid  : %d",is_invalid);
308
309              if (is_valid and not is_invalid)
310                {
311//                reg_STATE                  [i] =  CONTEXT_STATE_KO_MISS_BRANCH_ADDR;
312
313                  if (state == CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAIT_UPDATE)
314                    {
315// #if (MANAGE_EVENT == MANAGE_EVENT_NO_WAIT)
316//                       reg_STATE                  [i] =  CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR;
317// #else
318                      reg_STATE                  [i] =  CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAITEND;
319// #endif
320                    }
321                  else
322                    {
323                      Tcontrol_t can_continue = PORT_READ(in_BRANCH_EVENT_CAN_CONTINUE    [i]);
324                      Tcontrol_t dest_val     = PORT_READ(in_BRANCH_EVENT_ADDRESS_DEST_VAL[i]);
325
326                      log_printf(TRACE,Context_State,FUNCTION,"  * dest_val    : %d",dest_val    );
327                      log_printf(TRACE,Context_State,FUNCTION,"  * can_continue: %d",can_continue);
328
329                      if (can_continue)
330                        reg_STATE                [i] =  CONTEXT_STATE_KO_MISS_BRANCH_ADDR;
331                      else 
332                        // cf UPT : dest_val = direction, accurate depend of jump type (e.g. jr is inacurate)
333                        // reg_STATE                [i] =  CONTEXT_STATE_KO_MISS_BRANCH_WAITEND;
334                        reg_STATE                [i] =  CONTEXT_STATE_KO_MISS_BRANCH_INACCURATE;
335
336                      reg_EVENT_ADDRESS          [i] = PORT_READ(in_BRANCH_EVENT_ADDRESS_SRC  [i])+1; // address delay slot
337                      reg_EVENT_ADDRESS_EPCR     [i] = PORT_READ(in_BRANCH_EVENT_ADDRESS_DEST [i]);   // address_next
338                      reg_EVENT_ADDRESS_EPCR_VAL [i] = dest_val;
339                    //reg_EVENT_ADDRESS_EEAR     [i] = 0;
340                      reg_EVENT_ADDRESS_EEAR_VAL [i] = 0;
341                      reg_EVENT_IS_DELAY_SLOT    [i] = 1;
342                      reg_EVENT_IS_DS_TAKE       [i] = dest_val;
343                      reg_EVENT_DEPTH            [i] = depth;
344                      reg_EVENT_FLUSH_ONLY       [i] = can_continue;
345                    }
346                }
347            }
348       
349        // -------------------------------------------------------------------
350        // -----[ DECOD_EVENT ]-----------------------------------------------
351        // -------------------------------------------------------------------
352
353        for (uint32_t i=0; i<_param->_nb_decod_unit; i++)
354          if (PORT_READ(in_DECOD_EVENT_VAL [i]) and internal_DECOD_EVENT_ACK [i])
355            {
356              log_printf(TRACE,Context_State,FUNCTION,"  * DECOD_EVENT [%d]",i);
357
358              Tcontext_t context    = (_param->_have_port_context_id )?PORT_READ(in_DECOD_EVENT_CONTEXT_ID [i]):0;
359              Tdepth_t   depth      = (_param->_have_port_depth      )?PORT_READ(in_DECOD_EVENT_DEPTH      [i]):0;
360              Tdepth_t   depth_cur  = reg_EVENT_DEPTH [context];
361              Tdepth_t   depth_min = (_param->_have_port_depth      )?PORT_READ(in_DEPTH_MIN [context]):0;
362              Tdepth_t   depth_max  = _param->_nb_inst_branch_speculated [context];
363             
364              Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur-depth_min):((depth_cur+depth_max-depth_min));
365              Tdepth_t   depth1     = (depth    >=depth_min)?(depth    -depth_min):((depth    +depth_max-depth_min));
366//               Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur):((depth_cur+depth_max));
367//               Tdepth_t   depth1     = (depth    >=depth_min)?(depth    ):((depth    +depth_max));
368
369              context_state_t state = reg_STATE [context];
370              Tevent_type_t   type  = PORT_READ(in_DECOD_EVENT_TYPE [i]);
371             
372              // miss_load > miss_branch > excep > spr/sync
373              uint8_t    priority0  = get_priority(state);
374              uint8_t    priority1  = (state == EVENT_TYPE_EXCEPTION)?PRIORITY_EXCEPTION:PRIORITY_NONE;
375
376              // is_valid = can modify local information
377              //  if context_state_ok : yes
378              //  if context_state_ko : test the depth, and the priority of envent
379
380              bool       is_valid   = ((state == CONTEXT_STATE_OK) or
381                                       (depth1< depth0) or
382                                       ((depth1==depth0) and (priority1>=priority0)));
383
384              log_printf(TRACE,Context_State,FUNCTION,"    * depth     : %d",depth     );
385              log_printf(TRACE,Context_State,FUNCTION,"    * depth_cur : %d",depth_cur );
386              log_printf(TRACE,Context_State,FUNCTION,"    * depth_min : %d",depth_min );
387              log_printf(TRACE,Context_State,FUNCTION,"    * depth_max : %d",depth_max );
388              log_printf(TRACE,Context_State,FUNCTION,"    * depth0    : %d",depth0    );
389              log_printf(TRACE,Context_State,FUNCTION,"    * depth1    : %d",depth1    );
390              log_printf(TRACE,Context_State,FUNCTION,"    * priority0 : %d",priority0 );
391              log_printf(TRACE,Context_State,FUNCTION,"    * priority1 : %d",priority1 );
392              log_printf(TRACE,Context_State,FUNCTION,"  * is_valid    : %d",is_valid  );
393
394              if (is_valid)
395                {
396                  log_printf(TRACE,Context_State,FUNCTION,"    * is_valid");
397
398                  // decod :
399                  // type : csync, psync, msync, spr_access (l.mac, l.maci, l.macrc, l.msb, l.mfspr, l.mtspr), exception (l.sys)
400                  context_state_t state_next    = state;
401                  Taddress_t      address       = PORT_READ(in_DECOD_EVENT_ADDRESS       [i]);
402                  Tcontrol_t      is_delay_slot = PORT_READ(in_DECOD_EVENT_IS_DELAY_SLOT [i]);
403
404                  switch (type)
405                    {
406                    case EVENT_TYPE_EXCEPTION          : 
407                      {
408                        log_printf(TRACE,Context_State,FUNCTION,"    * EVENT_TYPE_EXCEPTION");
409
410                        state_next = CONTEXT_STATE_KO_EXCEP; 
411
412                        break;
413                      }
414                    case EVENT_TYPE_SPR_ACCESS         : 
415                      {
416                        log_printf(TRACE,Context_State,FUNCTION,"    * EVENT_TYPE_SPR_ACCESS");
417
418//                      state_next = CONTEXT_STATE_KO_SPR  ;
419                        state_next = CONTEXT_STATE_KO_SPR_EXEC; 
420                        address++; // take next address
421//                         if (is_delay_slot)
422//                           throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
423                        break;
424                      }
425                    case EVENT_TYPE_MSYNC              : 
426                      {
427                        log_printf(TRACE,Context_State,FUNCTION,"    * EVENT_TYPE_MSYNC");
428
429//                      state_next = CONTEXT_STATE_KO_MSYNC;
430                        state_next = CONTEXT_STATE_KO_MSYNC_EXEC;
431                        address++;  // take next address
432//                         if (is_delay_slot)
433//                           throw ERRORMORPHEO(FUNCTION,"MSYNC in delay slot, not supported.\n");
434                        break;
435                      }
436                    case EVENT_TYPE_PSYNC              :
437                      {
438                        log_printf(TRACE,Context_State,FUNCTION,"    * EVENT_TYPE_PSYNC");
439
440//                      state_next = CONTEXT_STATE_KO_PSYNC;
441                        state_next = CONTEXT_STATE_KO_PSYNC_FLUSH;
442                        address++;  // take next address
443                        if (is_delay_slot)
444                          throw ERRORMORPHEO(FUNCTION,"PSYNC in delay slot, not supported.\n");
445                        break;
446                      }
447                    case EVENT_TYPE_CSYNC              :
448                      {
449                        log_printf(TRACE,Context_State,FUNCTION,"    * EVENT_TYPE_CSYNC");
450
451//                      state_next = CONTEXT_STATE_KO_CSYNC;
452                        state_next = CONTEXT_STATE_KO_CSYNC_FLUSH;
453                        address++;  // take next address
454                        if (is_delay_slot)
455                          throw ERRORMORPHEO(FUNCTION,"CSYNC in delay slot, not supported.\n");
456                        break;
457                      }               
458                    case EVENT_TYPE_NONE               :
459                    case EVENT_TYPE_BRANCH_MISS_SPECULATION   :
460                    case EVENT_TYPE_LOAD_MISS_SPECULATION   :
461//                     case EVENT_TYPE_BRANCH_NO_ACCURATE :
462                    default :
463                      {
464                        throw ERRORMORPHEO(FUNCTION,toString(_("DECOD_EVENT [%d] : invalid event_type : %s.\n"),i,toString(type).c_str()));
465                      }
466                    }
467
468                  reg_STATE                  [context] = state_next;
469                  reg_EVENT_ADDRESS          [context] = address;
470                  reg_EVENT_ADDRESS_EPCR     [context] = PORT_READ(in_DECOD_EVENT_ADDRESS_EPCR  [i]); 
471                  reg_EVENT_ADDRESS_EPCR_VAL [context] = 1;
472                //reg_EVENT_ADDRESS_EEAR     [context]
473                  reg_EVENT_ADDRESS_EEAR_VAL [context] = 0;
474                  reg_EVENT_IS_DELAY_SLOT    [context] = is_delay_slot;
475                //reg_EVENT_IS_DS_TAKE       [context] = 0;
476                  reg_EVENT_DEPTH            [context] = depth;
477                  reg_EVENT_FLUSH_ONLY       [context] = false;
478                }
479            }
480
481        // -------------------------------------------------------------------
482        // -----[ EVENT ]-----------------------------------------------------
483        // -------------------------------------------------------------------
484        for (uint32_t i=0; i<_param->_nb_context; i++)
485          if (internal_EVENT_VAL [i] and PORT_READ(in_EVENT_ACK [i]))
486            {
487              log_printf(TRACE,Context_State,FUNCTION,"  * EVENT [%d]",i);
488              // Write pc
489              context_state_t state = reg_STATE [i];
490
491              switch (state)
492                {
493                case CONTEXT_STATE_KO_EXCEP_ADDR :
494                  {
495                    reg_STATE [i] = CONTEXT_STATE_KO_EXCEP_SPR;
496                    break;
497                  }
498                case CONTEXT_STATE_KO_MISS_BRANCH_ADDR:
499
500//                   {
501//                     reg_STATE [i] = CONTEXT_STATE_KO_MISS_WAITEND; //@@@ TODO : make MISS fast (miss decod)
502//                     break;
503//                   }
504                case CONTEXT_STATE_KO_MISS_LOAD_ADDR  :
505                case CONTEXT_STATE_KO_PSYNC_ADDR :
506                case CONTEXT_STATE_KO_CSYNC_ADDR :
507                  {
508                    reg_STATE [i] = CONTEXT_STATE_OK;
509                    break;
510                  }
511                case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR:
512                  {
513                    reg_STATE [i] = CONTEXT_STATE_KO_MISS_LOAD_ADDR;
514                    break;
515                  }
516                default :
517                  {
518#ifdef DEBUG_TEST
519                    throw ERRORMORPHEO(FUNCTION,toString(_("SPR[%d], Invalid state : %s.\n"),i,toString(state).c_str()));
520#endif
521                    break;
522                  }
523                }
524            }
525
526        // -------------------------------------------------------------------
527        // -----[ BRANCH_COMPLETE ]----------------------------------------------
528        // -------------------------------------------------------------------
529        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; ++i)
530          if (PORT_READ(in_BRANCH_COMPLETE_VAL [i]) and internal_BRANCH_COMPLETE_ACK [i] 
531              and PORT_READ(in_BRANCH_COMPLETE_MISS_PREDICTION [i]))
532            {
533              log_printf(TRACE,Context_State,FUNCTION,"  * BRANCH_COMPLETE [%d]",i);
534
535              Tcontext_t context_id = (_param->_have_port_context_id)?PORT_READ(in_BRANCH_COMPLETE_CONTEXT_ID [i]):0;
536
537              context_state_t state = reg_STATE [context_id];
538
539              Tdepth_t   depth      = (_param->_have_port_depth)?PORT_READ(in_BRANCH_COMPLETE_DEPTH [i]):0;
540              Tdepth_t   depth_cur  = reg_EVENT_DEPTH [context_id];
541              Tdepth_t   depth_min  = (_param->_have_port_depth)?PORT_READ(in_DEPTH_MIN [context_id]):0;
542              Tdepth_t   depth_max  = _param->_nb_inst_branch_speculated [context_id];
543             
544              Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur-depth_min):((depth_cur+depth_max-depth_min));
545              Tdepth_t   depth1     = (depth    >=depth_min)?(depth    -depth_min):((depth    +depth_max-depth_min));
546//            Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur):((depth_cur+depth_max));
547//            Tdepth_t   depth1     = (depth    >=depth_min)?(depth    ):((depth    +depth_max));
548
549              // priority : miss_load > miss_branch > excep > spr/sync
550              uint8_t    priority0  = get_priority(state);
551              uint8_t    priority1  = PRIORITY_MISS_BRANCH; // miss
552
553              // is_valid = can modify local information
554              //   if context_state_ok : yes
555              //   if context_state_ko : test the depth, and the priority of event
556              bool       is_valid   = ((state == CONTEXT_STATE_OK) or
557                                       (depth1< depth0) or
558                                       ((depth1==depth0) and (priority1>=priority0))); // >= because another branch can be a miss prediction with same depth
559
560              log_printf(TRACE,Context_State,FUNCTION,"    * context_id: %d",context_id);
561              log_printf(TRACE,Context_State,FUNCTION,"    * depth     : %d",depth     );
562              log_printf(TRACE,Context_State,FUNCTION,"    * depth_cur : %d",depth_cur );
563              log_printf(TRACE,Context_State,FUNCTION,"    * depth_min : %d",depth_min );
564              log_printf(TRACE,Context_State,FUNCTION,"    * depth_max : %d",depth_max );
565              log_printf(TRACE,Context_State,FUNCTION,"    * depth0    : %d",depth0    );
566              log_printf(TRACE,Context_State,FUNCTION,"    * depth1    : %d",depth1    );
567              log_printf(TRACE,Context_State,FUNCTION,"    * priority0 : %d",priority0 );
568              log_printf(TRACE,Context_State,FUNCTION,"    * priority1 : %d",priority1 );
569              log_printf(TRACE,Context_State,FUNCTION,"  * is_valid    : %d",is_valid  );
570
571              if (is_valid)
572                {
573//                reg_STATE                  [context_id] = CONTEXT_STATE_KO_MISS_BRANCH_ADDR;
574                  reg_STATE                  [context_id] = CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE;
575                  reg_EVENT_DEPTH            [context_id] = depth;
576                  reg_EVENT_FLUSH_ONLY       [context_id] = false;
577                }
578            }
579
580        // -------------------------------------------------------------------
581        // -----[ COMMIT_EVENT ]----------------------------------------------
582        // -------------------------------------------------------------------
583
584        if (PORT_READ(in_COMMIT_EVENT_VAL ) and internal_COMMIT_EVENT_ACK )
585          {
586            log_printf(TRACE,Context_State,FUNCTION,"  * COMMIT_EVENT");
587
588            Tcontext_t context    = (_param->_have_port_context_id)?PORT_READ(in_COMMIT_EVENT_CONTEXT_ID ):0;
589            Tdepth_t   depth      = (_param->_have_port_depth     )?PORT_READ(in_COMMIT_EVENT_DEPTH      ):0;
590//             Tdepth_t   depth_cur  = reg_EVENT_DEPTH [context];
591//             Tdepth_t   depth_min = (_param->_have_port_depth     )?PORT_READ(in_DEPTH_MIN [context]):0;
592//             Tdepth_t   depth_max  = _param->_nb_inst_branch_speculated [context];
593           
594//             Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur-depth_min):((depth_cur+depth_max-depth_min));
595//             Tdepth_t   depth1     = (depth    >=depth_min)?(depth    -depth_min):((depth    +depth_max-depth_min));
596// //             Tdepth_t   depth0     = (depth_cur>=depth_min)?(depth_cur):((depth_cur+depth_max));
597// //             Tdepth_t   depth1     = (depth    >=depth_min)?(depth    ):((depth    +depth_max));
598
599            context_state_t state = reg_STATE [context];
600            Tevent_type_t   type  = PORT_READ(in_COMMIT_EVENT_TYPE );
601           
602//             // miss > excep > spr/sync
603//               uint8_t    priority0  = ((state == CONTEXT_STATE_KO_MISS_BRANCH_ADDR            ) or
604//                                        (state == CONTEXT_STATE_KO_MISS_LOAD_ADDR              ) or
605//                                        (state == CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR   ) or
606//                                        (state == CONTEXT_STATE_KO_MISS_BRANCH_WAITEND         ) or
607//                                        (state == CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE     ) or
608//                                        (state == CONTEXT_STATE_KO_MISS_LOAD_WAITEND           ) or
609//                                        (state == CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAITEND))?2:((state == CONTEXT_STATE_KO_EXCEP)?1:0);
610//             uint8_t    priority1  = (state == EVENT_TYPE_EXCEPTION)?1:2; // else load_miss_speculation (EVENT_TYPE_MISS_SPECULATION)
611
612//             // is_valid = can modify local information
613//             //  if context_state_ok : yes
614//             //  if context_state_ko : test the depth, and the priority of envent
615
616//             bool       is_valid   = ((state == CONTEXT_STATE_OK) or
617//                                      (depth1< depth0) or
618//                                      ((depth1==depth0) and (priority1>=priority0)));
619
620            // if commit send an event, also they have not yet event previous this instruction
621            bool       is_valid   = true;
622
623            log_printf(TRACE,Context_State,FUNCTION,"    * depth     : %d",depth     );
624//             log_printf(TRACE,Context_State,FUNCTION,"    * depth_cur : %d",depth_cur );
625//             log_printf(TRACE,Context_State,FUNCTION,"    * depth_min : %d",depth_min );
626//             log_printf(TRACE,Context_State,FUNCTION,"    * depth_max : %d",depth_max );
627//             log_printf(TRACE,Context_State,FUNCTION,"    * depth0    : %d",depth0    );
628//             log_printf(TRACE,Context_State,FUNCTION,"    * depth1    : %d",depth1    );
629//             log_printf(TRACE,Context_State,FUNCTION,"    * priority0 : %d",priority0 );
630//             log_printf(TRACE,Context_State,FUNCTION,"    * priority1 : %d",priority1 );
631            log_printf(TRACE,Context_State,FUNCTION,"  * is_valid    : %d",is_valid  );
632
633            if (is_valid)
634              {
635                // commit
636                // type : exception
637                context_state_t state_next = state;
638                switch (type)
639                  {
640                  case EVENT_TYPE_EXCEPTION               : {state_next = CONTEXT_STATE_KO_EXCEP;             break;}
641                  case EVENT_TYPE_LOAD_MISS_SPECULATION   : 
642                    {
643                      // Test if previous branch occure
644                      switch (state)
645                        {
646                        case CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE      :
647                          {
648                            state_next = CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAIT_UPDATE;
649                            break;
650                          }
651                        case CONTEXT_STATE_KO_MISS_BRANCH_ADDR             :
652                        case CONTEXT_STATE_KO_MISS_BRANCH_WAITEND          :
653                        case CONTEXT_STATE_KO_MISS_BRANCH_INACCURATE       :
654                        case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR    :
655                        case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAITEND :
656                          {
657// #if (MANAGE_EVENT == MANAGE_EVENT_NO_WAIT)
658//                             state_next = CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR;
659// #else
660                            state_next = CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAITEND;
661// #endif
662                            break;
663                          }
664                        default :
665                          {
666// #if (MANAGE_EVENT == MANAGE_EVENT_NO_WAIT)
667//                             state_next = CONTEXT_STATE_KO_MISS_LOAD_ADDR;
668// #else
669                            state_next = CONTEXT_STATE_KO_MISS_LOAD_WAITEND;
670// #endif
671                            break;
672                          }
673                        }
674
675                      depth = (depth+1)%_param->_nb_inst_branch_speculated[context];
676
677                      break;
678                    }
679                  case EVENT_TYPE_BRANCH_MISS_SPECULATION :
680                  case EVENT_TYPE_SPR_ACCESS              :
681                  case EVENT_TYPE_MSYNC                   :
682                  case EVENT_TYPE_PSYNC                   :
683                  case EVENT_TYPE_CSYNC                   :
684                  case EVENT_TYPE_NONE                    :
685//                case EVENT_TYPE_BRANCH_NO_ACCURATE      :
686                  default :
687                    {
688                      throw ERRORMORPHEO(FUNCTION,toString(_("COMMIT_EVENT : invalid event_type : %s.\n"),toString(type).c_str()));
689                    }
690                  }
691                reg_STATE                  [context] = state_next;
692                reg_EVENT_ADDRESS          [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS          );
693                reg_EVENT_ADDRESS_EPCR     [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EPCR     ); 
694                reg_EVENT_ADDRESS_EPCR_VAL [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EPCR_VAL );
695                reg_EVENT_ADDRESS_EEAR     [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EEAR     ); 
696                reg_EVENT_ADDRESS_EEAR_VAL [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EEAR_VAL );
697                reg_EVENT_IS_DELAY_SLOT    [context] = PORT_READ(in_COMMIT_EVENT_IS_DELAY_SLOT    );
698                reg_EVENT_IS_DS_TAKE       [context] = 0;
699                reg_EVENT_DEPTH            [context] = depth;
700                reg_EVENT_FLUSH_ONLY       [context] = false;
701              }
702          }
703
704        // -------------------------------------------------------------------
705        // -----[ SPR_EVENT ]-------------------------------------------------
706        // -------------------------------------------------------------------
707        for (uint32_t i=0; i<_param->_nb_context; i++)
708          if (internal_SPR_EVENT_VAL [i] and PORT_READ(in_SPR_EVENT_ACK [i]))
709            {
710              log_printf(TRACE,Context_State,FUNCTION,"  * SPR_EVENT [%d]",i);
711
712              // Write spr
713#ifdef DEBUG_TEST
714              context_state_t state = reg_STATE [i];
715           
716              if (state != CONTEXT_STATE_KO_EXCEP_SPR)
717                throw ERRORMORPHEO(FUNCTION,toString(_("SPR_EVENT[%d], Invalid state : %s.\n"),i,toString(state).c_str()));
718#endif
719             
720              reg_STATE [i] = CONTEXT_STATE_OK;
721            }
722
723        // -------------------------------------------------------------------
724        // -----[ INTERRUPT ]-------------------------------------------------
725        // -------------------------------------------------------------------
726        for (uint32_t i=0; i<_param->_nb_context; ++i)
727          {
728            reg_INTERRUPT_ENABLE [i] = PORT_READ(in_INTERRUPT_ENABLE [i]) and PORT_READ(in_SPR_SR_IEE [i]);
729
730            if (reg_INTERRUPT_ENABLE [i])
731              throw ERRORMORPHEO(FUNCTION,toString(_("Context[%d], Have an interruption, Not yet supported (Comming Soon).\n"),i));
732          }
733
734
735#if (MANAGE_EVENT == MANAGE_EVENT_NO_WAIT)
736        for (uint32_t i=0; i<_param->_nb_context; i++)
737          switch (reg_STATE [i])
738            {
739            case CONTEXT_STATE_KO_MISS_BRANCH_WAITEND          : reg_STATE [i] = CONTEXT_STATE_KO_MISS_BRANCH_ADDR         ; break;
740            case CONTEXT_STATE_KO_MISS_LOAD_WAITEND            : reg_STATE [i] = CONTEXT_STATE_KO_MISS_LOAD_ADDR           ; break;
741            case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAITEND : reg_STATE [i] = CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR; break;
742            default : break;
743            }
744#endif
745      }
746
747
748#ifdef STATISTICS
749    if (usage_is_set(_usage,USE_STATISTICS))
750      for (uint32_t i=0; i<_param->_nb_context; ++i)
751        switch(reg_STATE[i])
752          {
753          case CONTEXT_STATE_OK                                 : (*_stat_nb_cycle_state_ok                      [i])++; break;
754
755          case CONTEXT_STATE_KO_EXCEP                           : 
756          case CONTEXT_STATE_KO_EXCEP_ADDR                      : 
757          case CONTEXT_STATE_KO_EXCEP_SPR                       : (*_stat_nb_cycle_state_ko_excep                [i])++; break;
758
759          case CONTEXT_STATE_KO_MISS_BRANCH_INACCURATE          : 
760          case CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE         : 
761          case CONTEXT_STATE_KO_MISS_BRANCH_ADDR                : 
762          case CONTEXT_STATE_KO_MISS_BRANCH_WAITEND             : (*_stat_nb_cycle_state_ko_miss_branch          [i])++; break;
763
764          case CONTEXT_STATE_KO_MISS_LOAD_ADDR                  : 
765          case CONTEXT_STATE_KO_MISS_LOAD_WAITEND               : (*_stat_nb_cycle_state_ko_miss_load            [i])++; break;
766
767          case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAIT_UPDATE: 
768          case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR       : 
769          case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAITEND    : (*_stat_nb_cycle_state_ko_miss_load_and_branch [i])++; break;
770
771//        case CONTEXT_STATE_KO_MSYNC                           :
772//        case CONTEXT_STATE_KO_MSYNC_ISSUE                     :
773          case CONTEXT_STATE_KO_MSYNC_EXEC                      : (*_stat_nb_cycle_state_ko_msync                [i])++; break;
774
775//        case CONTEXT_STATE_KO_PSYNC                           :
776          case CONTEXT_STATE_KO_PSYNC_FLUSH                     : 
777          case CONTEXT_STATE_KO_PSYNC_ADDR                      : (*_stat_nb_cycle_state_ko_psync                [i])++; break;
778
779//        case CONTEXT_STATE_KO_CSYNC                           :
780          case CONTEXT_STATE_KO_CSYNC_FLUSH                     : 
781          case CONTEXT_STATE_KO_CSYNC_ADDR                      : (*_stat_nb_cycle_state_ko_csync                [i])++; break;
782
783//        case CONTEXT_STATE_KO_SPR                             :
784//        case CONTEXT_STATE_KO_SPR_ISSUE                       :
785          case CONTEXT_STATE_KO_SPR_EXEC                        : (*_stat_nb_cycle_state_ko_spr                  [i])++; break;
786          }
787#endif
788
789
790
791#if DEBUG >= DEBUG_TRACE
792    for (uint32_t i=0; i<_param->_nb_context; i++)
793      {
794        log_printf(TRACE,Context_State,FUNCTION,"  * Dump Context State [%d]",i);
795        log_printf(TRACE,Context_State,FUNCTION,"    * reg_STATE                  : %s"         ,toString(reg_STATE [i]).c_str());
796        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS          : 0x%x (0x%x)",reg_EVENT_ADDRESS          [i],reg_EVENT_ADDRESS      [i]<<2);
797        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS_EPCR     : 0x%x (0x%x)",reg_EVENT_ADDRESS_EPCR     [i],reg_EVENT_ADDRESS_EPCR [i]<<2); 
798        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS_EPCR_VAL : %d"         ,reg_EVENT_ADDRESS_EPCR_VAL [i]);
799        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS_EEAR     : 0x%x (0x%x)",reg_EVENT_ADDRESS_EEAR     [i],reg_EVENT_ADDRESS_EEAR [i]<<2); 
800        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_ADDRESS_EEAR_VAL : %d"         ,reg_EVENT_ADDRESS_EEAR_VAL [i]);
801        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_IS_DELAY_SLOT    : %d"         ,reg_EVENT_IS_DELAY_SLOT    [i]);
802        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_IS_DS_TAKE       : %d"         ,reg_EVENT_IS_DS_TAKE       [i]);
803        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_DEPTH            : %d"         ,reg_EVENT_DEPTH            [i]);
804        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_FLUSH_ONLY       : %d"         ,reg_EVENT_FLUSH_ONLY       [i]);
805      }
806#endif
807
808#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
809    end_cycle ();
810#endif
811
812    log_end(Context_State,FUNCTION);
813  };
814
815}; // end namespace context_state
816}; // end namespace front_end
817}; // end namespace multi_front_end
818}; // end namespace core
819
820}; // end namespace behavioural
821}; // end namespace morpheo             
822#endif
Note: See TracBrowser for help on using the repository browser.