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
RevLine 
[83]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
[122]18#define MISS_FAST
[83]19
[111]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
[83]32#undef  FUNCTION
33#define FUNCTION "Context_State::transition"
34  void Context_State::transition (void)
35  {
36    log_begin(Context_State,FUNCTION);
[88]37    log_function(Context_State,FUNCTION,_name.c_str());
[83]38
39    if (PORT_READ(in_NRESET) == 0)
40      {
[88]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          }
[83]46      }
47    else
48      {
[88]49        // -------------------------------------------------------------------
[101]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
[122]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;
[101]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)
[122]75//                if (inst_decod_all == 0)
[101]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                }
[111]84              case CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE :
85                {
86                  // nothing : wait end of update upt
87                  break;
88                }
[105]89              case CONTEXT_STATE_KO_MISS_BRANCH_WAITEND :
[101]90                {
91                  // Wait end of all instruction
[122]92//                if (inst_all == 0)
93                  if (
94#ifdef  MISS_FAST
95                      inst_decod_all ==
96#else
97                      inst_all ==
98#endif
99                      0)
[101]100                   
[122]101//                  state = CONTEXT_STATE_OK;
[105]102                    state = CONTEXT_STATE_KO_MISS_BRANCH_ADDR;
[101]103                  break;
104                }
[105]105              case CONTEXT_STATE_KO_MISS_LOAD_WAITEND :
106                {
107                  // Wait end of all instruction
[122]108//                if (inst_all == 0)
109                  if (
110#ifdef  MISS_FAST
111                      inst_decod_all ==
112#else
113                      inst_all ==
114#endif
115                      0)
[105]116                    state = CONTEXT_STATE_KO_MISS_LOAD_ADDR;
117
118                  break;
119                }
[101]120              case CONTEXT_STATE_KO_EXCEP_SPR    :
121                {
122                  // nothing, wait the update of internal register (epcr, eear, sr, esr)
123                  break;
124                }
[105]125              case CONTEXT_STATE_KO_MISS_BRANCH_ADDR    :
[101]126                {
127                  // nothing, wait the update of internal register (pc)
128                  break;
129                }
[105]130              case CONTEXT_STATE_KO_MISS_LOAD_ADDR    :
131                {
132                  // nothing, wait the update of internal register (pc)
133                  break;
134                }
[111]135              case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAIT_UPDATE :
[108]136                {
[111]137                  // nothing : wait end of update upt
138                  break;
139                }
140              case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR    :
141                {
[108]142                  // nothing, wait the update of internal register (pc)
143                  break;
144                }
[111]145              case CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAITEND :
146                {
147                  // Wait end of all instruction
[122]148//                if (inst_all == 0)
149                  if (
150#ifdef  MISS_FAST
151                      inst_decod_all ==
152#else
153                      inst_all ==
154#endif
155                      0)
[111]156//                  state = CONTEXT_STATE_OK; // @@@ TODO : make MISS fast (miss decod)
157                    state = CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_ADDR;
158                  break;
159                }
[101]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        // -------------------------------------------------------------------
[111]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        // -------------------------------------------------------------------
[88]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            {
[98]302              log_printf(TRACE,Context_State,FUNCTION,"  * BRANCH_EVENT [%d]",i);
303
[88]304              context_state_t state = reg_STATE [i];
[83]305
[98]306              Tdepth_t   depth      = (_param->_have_port_depth)?PORT_READ(in_BRANCH_EVENT_DEPTH [i]):0;
[88]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;
[106]309              Tdepth_t   depth_max  = _param->_nb_inst_branch_speculated [i];
[88]310             
[106]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));
[83]315
[111]316              // priority : miss_load > miss_branch > excep > spr/sync
317              uint8_t    priority0  = get_priority(state);
[88]318              uint8_t    priority1  = 2; // miss
[83]319
[88]320              // is_valid = can modify local information
321              //   if context_state_ok : yes
[98]322              //   if context_state_ko : test the depth, and the priority of event
[88]323              bool       is_valid   = ((state == CONTEXT_STATE_OK) or
[111]324                                       (state == CONTEXT_STATE_KO_MISS_BRANCH_WAIT_UPDATE) or
325                                       (state == CONTEXT_STATE_KO_MISS_LOAD_AND_BRANCH_WAIT_UPDATE) or
[88]326                                       (depth1< depth0) or
[98]327                                       ((depth1==depth0) and (priority1>=priority0))); // >= because another branch can be a miss prediction with same depth
[83]328
[111]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
[106]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
[88]345              if (is_valid)
346                {
[105]347//                reg_STATE                  [i] =  CONTEXT_STATE_KO_MISS_BRANCH_ADDR;
[111]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                    {
[119]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]);
[111]357
[119]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;
[111]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
[117]388              Tcontext_t context_id = (_param->_have_port_context_id)?PORT_READ(in_BRANCH_COMPLETE_CONTEXT_ID [i]):0;
[111]389
[117]390              context_state_t state = reg_STATE [context_id];
391
[111]392              Tdepth_t   depth      = (_param->_have_port_depth)?PORT_READ(in_BRANCH_COMPLETE_DEPTH [i]):0;
[117]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];
[111]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));
[119]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));
[111]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
[117]413              log_printf(TRACE,Context_State,FUNCTION,"    * context_id: %d",context_id);
[111]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                {
[119]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;
[88]430                }
431            }
432       
433        // -------------------------------------------------------------------
434        // -----[ DECOD_EVENT ]-----------------------------------------------
435        // -------------------------------------------------------------------
[83]436
[88]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            {
[98]440              log_printf(TRACE,Context_State,FUNCTION,"  * DECOD_EVENT [%d]",i);
441
[88]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;
[106]446              Tdepth_t   depth_max  = _param->_nb_inst_branch_speculated [context];
[88]447             
[106]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));
[83]452
[88]453              context_state_t state = reg_STATE [context];
454              Tevent_type_t   type  = PORT_READ(in_DECOD_EVENT_TYPE [i]);
455             
[111]456              // miss_load > miss_branch > excep > spr/sync
457              uint8_t    priority0  = get_priority(state);
[88]458              uint8_t    priority1  = (state == EVENT_TYPE_EXCEPTION)?1:0;
[83]459
[88]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
[83]463
[88]464              bool       is_valid   = ((state == CONTEXT_STATE_OK) or
465                                       (depth1< depth0) or
[105]466                                       ((depth1==depth0) and (priority1>=priority0)));
[83]467
[106]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
[88]478              if (is_valid)
479                {
[101]480                  log_printf(TRACE,Context_State,FUNCTION,"    * is_valid");
481
[88]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]);
[83]487
[88]488                  switch (type)
489                    {
490                    case EVENT_TYPE_EXCEPTION          : 
491                      {
[101]492                        log_printf(TRACE,Context_State,FUNCTION,"    * EVENT_TYPE_EXCEPTION");
493
[88]494                        state_next = CONTEXT_STATE_KO_EXCEP; 
[83]495
[88]496                        break;
497                      }
498                    case EVENT_TYPE_SPR_ACCESS         : 
499                      {
[101]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; 
[88]504                        address++; // take next address
[101]505//                         if (is_delay_slot)
506//                           throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
[88]507                        break;
508                      }
509                    case EVENT_TYPE_MSYNC              : 
510                      {
[101]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;
[88]515                        address++;  // take next address
[101]516//                         if (is_delay_slot)
517//                           throw ERRORMORPHEO(FUNCTION,"MSYNC in delay slot, not supported.\n");
[88]518                        break;
519                      }
520                    case EVENT_TYPE_PSYNC              :
521                      {
[101]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;
[88]526                        address++;  // take next address
527                        if (is_delay_slot)
[101]528                          throw ERRORMORPHEO(FUNCTION,"PSYNC in delay slot, not supported.\n");
[88]529                        break;
530                      }
531                    case EVENT_TYPE_CSYNC              :
532                      {
[101]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;
[88]537                        address++;  // take next address
538                        if (is_delay_slot)
[101]539                          throw ERRORMORPHEO(FUNCTION,"CSYNC in delay slot, not supported.\n");
[88]540                        break;
541                      }               
542                    case EVENT_TYPE_NONE               :
[105]543                    case EVENT_TYPE_BRANCH_MISS_SPECULATION   :
544                    case EVENT_TYPE_LOAD_MISS_SPECULATION   :
545//                     case EVENT_TYPE_BRANCH_NO_ACCURATE :
[88]546                    default :
547                      {
548                        throw ERRORMORPHEO(FUNCTION,toString(_("DECOD_EVENT [%d] : invalid event_type : %s.\n"),i,toString(type).c_str()));
549                      }
550                    }
[83]551
[88]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;
[119]561                  reg_EVENT_FLUSH_ONLY       [context] = false;
[88]562                }
563            }
[83]564
[88]565        // -------------------------------------------------------------------
566        // -----[ COMMIT_EVENT ]----------------------------------------------
567        // -------------------------------------------------------------------
[83]568
[88]569        if (PORT_READ(in_COMMIT_EVENT_VAL ) and internal_COMMIT_EVENT_ACK )
570          {
[98]571            log_printf(TRACE,Context_State,FUNCTION,"  * COMMIT_EVENT");
572
[88]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;
[111]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];
[88]578           
[111]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));
[83]583
[88]584            context_state_t state = reg_STATE [context];
585            Tevent_type_t   type  = PORT_READ(in_COMMIT_EVENT_TYPE );
586           
[111]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)
[88]596
[111]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
[88]600
[111]601//             bool       is_valid   = ((state == CONTEXT_STATE_OK) or
602//                                      (depth1< depth0) or
603//                                      ((depth1==depth0) and (priority1>=priority0)));
[88]604
[111]605            // if commit send an event, also they have not yet event previous this instruction
606            bool       is_valid   = true;
607
[106]608            log_printf(TRACE,Context_State,FUNCTION,"    * depth     : %d",depth     );
[111]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 );
[106]616            log_printf(TRACE,Context_State,FUNCTION,"  * is_valid    : %d",is_valid  );
617
[88]618            if (is_valid)
619              {
620                // commit
621                // type : exception
622                context_state_t state_next = state;
623                switch (type)
624                  {
[105]625                  case EVENT_TYPE_EXCEPTION               : {state_next = CONTEXT_STATE_KO_EXCEP;             break;}
[108]626                  case EVENT_TYPE_LOAD_MISS_SPECULATION   : 
627                    {
628                      // Test if previous branch occure
[111]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                        }
[108]650                      break;
651                    }
[105]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      :
[88]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     ); 
[105]667                reg_EVENT_ADDRESS_EPCR_VAL [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EPCR_VAL );
[88]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    );
[105]671                reg_EVENT_IS_DS_TAKE       [context] = 0;
[88]672                reg_EVENT_DEPTH            [context] = depth;
[119]673                reg_EVENT_FLUSH_ONLY       [context] = false;
[88]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            {
[98]683              log_printf(TRACE,Context_State,FUNCTION,"  * SPR_EVENT [%d]",i);
684
[88]685              // Write spr
[83]686#ifdef DEBUG_TEST
[88]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()));
[83]691#endif
[88]692             
693              reg_STATE [i] = CONTEXT_STATE_OK;
694            }
[83]695
[88]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          }
[83]703      }
704
[120]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
[83]748#if DEBUG >= DEBUG_TRACE
749    for (uint32_t i=0; i<_param->_nb_context; i++)
750      {
[88]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]);
[119]761        log_printf(TRACE,Context_State,FUNCTION,"    * reg_EVENT_FLUSH_ONLY       : %d"         ,reg_EVENT_FLUSH_ONLY       [i]);
[83]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.