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

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

Modif for performance :
1) Load Store Unit : store send request to valid exeception
2) Commit_unit : retire can bypass store
3) Commit_unit : add stat to manage store instruction
4) Load Store Unit and Load Store Pointer Manager : add store_queue_ptr_read
5) Fix lot of bug

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