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

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

1) Fix performance
2) add auto generation to SPECINT2000
3) add reset in genMoore and genMealy

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