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

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

1) Context_state : Add statistics
2) Add configuration with multi front_end
3) Add optionnal pid at log filename

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