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

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

1) Correct bug in link two signal
2) Fix error detected with valgrind
3) modif distexe script

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