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

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

1) Decod_queue : multi implementation (one_fifo, multi_fifo)
2) Issue_queue : multi implementation (in_order, out_of_order)
3) Direction : Add Meta predictor
4) Context_State : re add Branch_complete, More priority to Load miss (is not speculative)
5) Return_Address_Stack : update reg_PREDICT pointer on decod miss prediction
6) UPT : Fix bug in multi event
7) Prediction_glue : in read_stack case, insert in UPT pc_next
8) Rename select : when rob have an event (need flush), read_r{a,b,c} and write_r{d,e} is set at 0

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