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

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

1) Add test and configuration
2) Fix Bug
3) Add log file in load store unit
4) Fix Bug in environment

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