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

Last change on this file since 83 was 83, checked in by rosiere, 16 years ago

Add component : Context_State (manage miss prediction, exception , decod_enable, synchronisation instruction ...)

  • Property svn:keywords set to Id
File size: 16.2 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Context_State_transition.cpp 83 2008-05-09 18:00:21Z 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#undef  FUNCTION
20#define FUNCTION "Context_State::transition"
21  void Context_State::transition (void)
22  {
23    log_begin(Context_State,FUNCTION);
24
25    if (PORT_READ(in_NRESET) == 0)
26      {
27        for (uint32_t i=0; i<_param->_nb_context; i++)
28          reg_STATE [i] = CONTEXT_STATE_OK;
29      }
30    else
31      {
32        // -------------------------------------------------------------------
33        // -----[ DECOD_EVENT ]-----------------------------------------------
34        // -------------------------------------------------------------------
35
36        for (uint32_t i=0; i<_param->_nb_decod_unit; i++)
37          if (PORT_READ(in_DECOD_EVENT_VAL [i]) and internal_DECOD_EVENT_ACK [i])
38            {
39              Tcontext_t context    = (_param->_have_port_context_id     )?PORT_READ(in_DECOD_EVENT_CONTEXT_ID [i]):0;
40              Tdepth_t   depth      = (_param->_have_port_max_depth      )?PORT_READ(in_DECOD_EVENT_DEPTH      [i]):0;
41              Tdepth_t   depth_cur  = reg_EVENT_DEPTH [context];
42              Tdepth_t   depth_base = (_param->_have_port_depth [context])?PORT_READ(in_DEPTH_TAIL       [context]):0;
43              Tdepth_t   depth_max  = _param->_size_depth [context];
44             
45              Tdepth_t   depth0     = (depth_cur>=depth_base)?(depth_cur-depth_base):((depth_cur+depth_max-depth_base));
46              Tdepth_t   depth1     = (depth    >=depth_base)?(depth    -depth_base):((depth    +depth_max-depth_base));
47
48              context_state_t state = reg_STATE [context];
49              Tevent_type_t   type  = PORT_READ(in_DECOD_EVENT_TYPE [i]);
50             
51              // miss > excep > spr/sync
52              uint8_t    priority0  = (state == CONTEXT_STATE_KO_MISS)?2:((state == CONTEXT_STATE_KO_EXCEP)?1:0);
53              uint8_t    priority1  = (state == EVENT_TYPE_EXCEPTION)?1:0;
54
55              // is_valid = can modify local information
56              //  if context_state_ok : yes
57              //  if context_state_ko : test the depth, and the priority of envent
58
59              bool       is_valid   = ((state == CONTEXT_STATE_OK) or
60                                       (depth1< depth0) or
61                                       ((depth1==depth0) and (priority1>priority0)));
62
63              if (is_valid)
64                {
65                  // decod :
66                  // type : csync, psync, msync, spr_access (l.mac, l.maci, l.macrc, l.msb, l.mfspr, l.mtspr), exception (l.sys)
67                  context_state_t state_next    = state;
68                  Taddress_t      address       = PORT_READ(in_DECOD_EVENT_ADDRESS       [i]);
69                  Tcontrol_t      is_delay_slot = PORT_READ(in_DECOD_EVENT_IS_DELAY_SLOT [i]);
70
71                  switch (type)
72                    {
73                    case EVENT_TYPE_EXCEPTION          : 
74                      {
75                        state_next = CONTEXT_STATE_KO_EXCEP; 
76                        break;
77                      }
78                    case EVENT_TYPE_SPR_ACCESS         : 
79                      {
80                        state_next = CONTEXT_STATE_KO_SPR  ; 
81                        address++; // take next address
82                        if (is_delay_slot)
83                          throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
84                        break;
85                      }
86                    case EVENT_TYPE_MSYNC              : 
87                      {
88                        state_next = CONTEXT_STATE_KO_MSYNC;
89                        address++;  // take next address
90                        if (is_delay_slot)
91                          throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
92                        break;
93                      }
94                    case EVENT_TYPE_PSYNC              :
95                      {
96                        state_next = CONTEXT_STATE_KO_PSYNC;
97                        address++;  // take next address
98                        if (is_delay_slot)
99                          throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
100                        break;
101                      }
102                    case EVENT_TYPE_CSYNC              :
103                      {
104                        state_next = CONTEXT_STATE_KO_CSYNC;
105                        address++;  // take next address
106                        if (is_delay_slot)
107                          throw ERRORMORPHEO(FUNCTION,"SPR access in delay slot, not supported.\n");
108                        break;
109                      }               
110                    case EVENT_TYPE_NONE               :
111                    case EVENT_TYPE_MISS_SPECULATION   :
112                    case EVENT_TYPE_BRANCH_NO_ACCURATE :
113                    default :
114                      {
115                        throw ERRORMORPHEO(FUNCTION,toString(_("DECOD_EVENT [%d] : invalid event_type : %s.\n"),i,toString(type).c_str()));
116                      }
117                    }
118
119                  reg_STATE                  [context] = state_next;
120                  reg_EVENT_ADDRESS          [context] = address;
121                  reg_EVENT_ADDRESS_EPCR     [context] = PORT_READ(in_DECOD_EVENT_ADDRESS_EPCR  [i]); 
122                  reg_EVENT_ADDRESS_EPCR_VAL [context] = 1;
123                //reg_EVENT_ADDRESS_EEAR     [context]
124                  reg_EVENT_ADDRESS_EEAR_VAL [context] = 0;
125                  reg_EVENT_IS_DELAY_SLOT    [context] = is_delay_slot;
126                //reg_EVENT_IS_DS_TAKE       [context] = 0;
127                  reg_EVENT_DEPTH            [context] = depth;
128                }
129            }
130
131        // -------------------------------------------------------------------
132        // -----[ COMMIT_EVENT ]----------------------------------------------
133        // -------------------------------------------------------------------
134
135        for (uint32_t i=0; i<_param->_nb_ooo_engine; i++)
136          if (PORT_READ(in_COMMIT_EVENT_VAL [i]) and internal_COMMIT_EVENT_ACK [i])
137            {
138              Tcontext_t context    = (_param->_have_port_context_id     )?PORT_READ(in_COMMIT_EVENT_CONTEXT_ID [i]):0;
139              Tdepth_t   depth      = (_param->_have_port_max_depth      )?PORT_READ(in_COMMIT_EVENT_DEPTH      [i]):0;
140              Tdepth_t   depth_cur  = reg_EVENT_DEPTH [context];
141              Tdepth_t   depth_base = (_param->_have_port_depth [context])?PORT_READ(in_DEPTH_TAIL        [context]):0;
142              Tdepth_t   depth_max  = _param->_size_depth [context];
143             
144              Tdepth_t   depth0     = (depth_cur>=depth_base)?(depth_cur-depth_base):((depth_cur+depth_max-depth_base));
145              Tdepth_t   depth1     = (depth    >=depth_base)?(depth    -depth_base):((depth    +depth_max-depth_base));
146
147              context_state_t state = reg_STATE [context];
148              Tevent_type_t   type  = PORT_READ(in_COMMIT_EVENT_TYPE [i]);
149             
150              // miss > excep > spr/sync
151              uint8_t    priority0  = (state == CONTEXT_STATE_KO_MISS)?2:((state == CONTEXT_STATE_KO_EXCEP)?1:0);
152              uint8_t    priority1  = 1;
153
154              // is_valid = can modify local information
155              //  if context_state_ok : yes
156              //  if context_state_ko : test the depth, and the priority of envent
157
158              bool       is_valid   = ((state == CONTEXT_STATE_OK) or
159                                       (depth1< depth0) or
160                                       ((depth1==depth0) and (priority1>priority0)));
161
162              if (is_valid)
163                {
164                  // commit
165                  // type : exception
166                  context_state_t state_next = state;
167                  switch (type)
168                    {
169                    case EVENT_TYPE_EXCEPTION          : {state_next = CONTEXT_STATE_KO_EXCEP; break;}
170                    case EVENT_TYPE_SPR_ACCESS         :
171                    case EVENT_TYPE_MSYNC              :
172                    case EVENT_TYPE_PSYNC              :
173                    case EVENT_TYPE_CSYNC              :
174                    case EVENT_TYPE_NONE               :
175                    case EVENT_TYPE_MISS_SPECULATION   :
176                    case EVENT_TYPE_BRANCH_NO_ACCURATE :
177                    default :
178                      {
179                        throw ERRORMORPHEO(FUNCTION,toString(_("COMMIT_EVENT [%d] : invalid event_type : %s.\n"),i,toString(type).c_str()));
180                      }
181                    }
182                  reg_STATE                  [context] = state_next;
183                  reg_EVENT_ADDRESS          [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS          [i]);
184                  reg_EVENT_ADDRESS_EPCR     [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EPCR     [i]); 
185                  reg_EVENT_ADDRESS_EPCR_VAL [context] = 1;
186                  reg_EVENT_ADDRESS_EEAR     [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EEAR     [i]); 
187                  reg_EVENT_ADDRESS_EEAR_VAL [context] = PORT_READ(in_COMMIT_EVENT_ADDRESS_EEAR_VAL [i]);
188                  reg_EVENT_IS_DELAY_SLOT    [context] = PORT_READ(in_COMMIT_EVENT_IS_DELAY_SLOT    [i]);
189                //reg_EVENT_IS_DS_TAKE       [context] = 0;
190                  reg_EVENT_DEPTH            [context] = depth;
191                }
192            }
193
194        // -------------------------------------------------------------------
195        // -----[ BRANCH_COMPLETE ]-------------------------------------------
196        // -------------------------------------------------------------------
197
198        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
199          if (PORT_READ(in_BRANCH_COMPLETE_VAL [i]) and internal_BRANCH_COMPLETE_ACK [i])
200            {
201              if (PORT_READ(in_BRANCH_COMPLETE_MISS_PREDICTION [i]))
202                {
203                  Tcontext_t context    = (_param->_have_port_context_id     )?PORT_READ(in_BRANCH_COMPLETE_CONTEXT_ID [i]):0;
204                  Tdepth_t   depth      = (_param->_have_port_max_depth      )?PORT_READ(in_BRANCH_COMPLETE_DEPTH      [i]):0;
205                  Tdepth_t   depth_cur  = reg_EVENT_DEPTH [context];
206                  Tdepth_t   depth_base = (_param->_have_port_depth [context])?PORT_READ(in_DEPTH_TAIL        [context]):0;
207                  Tdepth_t   depth_max  = _param->_size_depth [context];
208                 
209                  Tdepth_t   depth0     = (depth_cur>=depth_base)?(depth_cur-depth_base):((depth_cur+depth_max-depth_base));
210                  Tdepth_t   depth1     = (depth    >=depth_base)?(depth    -depth_base):((depth    +depth_max-depth_base));
211                 
212                  context_state_t state = reg_STATE [context];
213                 
214                  // miss > excep > spr/sync
215                  uint8_t    priority0  = (state == CONTEXT_STATE_KO_MISS)?2:((state == CONTEXT_STATE_KO_EXCEP)?1:0);
216                  uint8_t    priority1  = 2;
217                 
218                  // is_valid = can modify local information
219                  //  if context_state_ok : yes
220                  //  if context_state_ko : test the depth, and the priority of envent
221                 
222                  bool       is_valid   = ((state == CONTEXT_STATE_OK) or
223                                           (depth1< depth0) or
224                                           ((depth1==depth0) and (priority1>priority0)));
225                 
226                  if (is_valid)
227                    {
228                      // commit
229                      Tcontrol_t take = PORT_READ(in_BRANCH_COMPLETE_TAKE [i]);
230                      reg_STATE                  [context] = CONTEXT_STATE_KO_MISS;
231                      reg_EVENT_ADDRESS          [context] = PORT_READ(in_BRANCH_COMPLETE_ADDRESS_SRC  [i])+1; //DELAY_SLOT
232                      reg_EVENT_ADDRESS_EPCR     [context] = PORT_READ(in_BRANCH_COMPLETE_ADDRESS_DEST [i]); 
233                      reg_EVENT_ADDRESS_EPCR_VAL [context] = take; // if not take : in sequence
234                    //reg_EVENT_ADDRESS_EEAR     [context];
235                    //reg_EVENT_ADDRESS_EEAR_VAL [context];
236                      reg_EVENT_IS_DELAY_SLOT    [context] = take;
237                      reg_EVENT_IS_DS_TAKE       [context] = take;
238                      reg_EVENT_DEPTH            [context] = depth;
239                    }
240                }
241            }
242
243        // -------------------------------------------------------------------
244        // -----[ EVENT ]-----------------------------------------------------
245        // -------------------------------------------------------------------
246        for (uint32_t i=0; i<_param->_nb_context; i++)
247          if (internal_EVENT_VAL [i] and PORT_READ(in_EVENT_ACK [i]))
248            {
249              // Write pc
250              context_state_t state = reg_STATE [i];
251
252              switch (state)
253                {
254                case CONTEXT_STATE_KO_EXCEP_ADDR :
255                  {
256                    reg_STATE [i] = CONTEXT_STATE_KO_EXCEP_SPR;
257                    break;
258                  }
259                case CONTEXT_STATE_KO_MISS_ADDR  :
260                case CONTEXT_STATE_KO_PSYNC_ADDR :
261                case CONTEXT_STATE_KO_CSYNC_ADDR :
262                  {
263                    reg_STATE [i] = CONTEXT_STATE_OK;
264                    break;
265                  }
266                default :
267                  {
268#ifdef DEBUG_TEST
269                    throw ERRORMORPHEO(FUNCTION,toString(_("SPR[%d], Invalid state : %s.\n"),i,toString(state).c_str()));
270#endif
271                    break;
272                  }
273                }
274            }
275
276        // -------------------------------------------------------------------
277        // -----[ SPR ]-------------------------------------------------------
278        // -------------------------------------------------------------------
279        for (uint32_t i=0; i<_param->_nb_context; i++)
280          if (internal_SPR_VAL [i] and PORT_READ(in_SPR_ACK [i]))
281            {
282              // Write spr
283#ifdef DEBUG_TEST
284              context_state_t state = reg_STATE [i];
285           
286              if (state != CONTEXT_STATE_KO_EXCEP_SPR)
287                throw ERRORMORPHEO(FUNCTION,toString(_("SPR[%d], Invalid state : %s.\n"),i,toString(state).c_str()));
288#endif
289             
290              reg_STATE [i] = CONTEXT_STATE_OK;
291            }
292
293        // -------------------------------------------------------------------
294        // -----[ next state ]------------------------------------------------
295        // -------------------------------------------------------------------
296        for (uint32_t i=0; i<_param->_nb_context; i++)
297          {
298            uint32_t x = _param->_link_context_to_decod_unit    [i];
299            uint32_t y = _param->_link_decod_unit_to_ooo_engine [x];
300
301            Tcounter_t inst_all = PORT_READ(in_NB_INST_COMMIT_ALL [y]) + PORT_READ(in_NB_INST_DECOD_ALL [x]);
302            Tcounter_t inst_mem = PORT_READ(in_NB_INST_COMMIT_MEM [y]) + PORT_READ(in_NB_INST_DECOD_ALL [x]);
303
304            context_state_t state = reg_STATE [i];
305
306            switch (state)
307              {
308              case CONTEXT_STATE_OK              :
309                {
310                  // nothing, wait an event
311                  break;
312                }
313              case CONTEXT_STATE_KO_EXCEP        :
314                {
315                  // Wait end of all instruction
316                  if (inst_all == 0)
317                    state = CONTEXT_STATE_KO_EXCEP_ADDR;
318                  break;
319                }
320              case CONTEXT_STATE_KO_MISS         :
321                {
322                  // Wait end of all instruction
323                  if (inst_all == 0)
324                    state = CONTEXT_STATE_KO_MISS_ADDR;
325                  break;
326                }
327              case CONTEXT_STATE_KO_EXCEP_ADDR   :
328                {
329                  // nothing, wait the update of internal register (pc)
330                  break;
331                }
332              case CONTEXT_STATE_KO_EXCEP_SPR    :
333                {
334                  // nothing, wait the update of internal register (epcr, eear, sr, esr)
335                  break;
336                }
337              case CONTEXT_STATE_KO_MISS_ADDR    :
338                {
339                  // nothing, wait the update of internal register (pc)
340                  break;
341                }
342              case CONTEXT_STATE_KO_PSYNC        :
343                {
344                  // Wait end of all instruction
345                  if (inst_all == 0)
346//                  state = CONTEXT_STATE_KO_PSYNC_FLUSH;
347                    state = CONTEXT_STATE_KO_PSYNC_ADDR ;
348                  break;
349                }
350//            case CONTEXT_STATE_KO_PSYNC_FLUSH  :
351//              {
352//                // nothing, wait end of flush (ifetch)
353//                break;
354//              }
355              case CONTEXT_STATE_KO_PSYNC_ADDR   :
356                {
357                  // nothing, wait the pc write
358                  break;
359                }
360              case CONTEXT_STATE_KO_CSYNC        :
361                {
362                  // Wait end of all instruction
363                  if (inst_all == 0)
364                    state = CONTEXT_STATE_KO_CSYNC_ADDR ;
365//                  state = CONTEXT_STATE_KO_CSYNC_FLUSH;
366                  break;
367                }
368//            case CONTEXT_STATE_KO_CSYNC_FLUSH  :
369//              {
370//                // nothing, wait end of flush (all internal structure)
371//                break;
372//              }
373              case CONTEXT_STATE_KO_CSYNC_ADDR   :
374                {
375                  // nothing, wait the pc write
376                  break;
377                }
378              case CONTEXT_STATE_KO_MSYNC        :
379                {
380                  // Wait end of memory instruction
381                  if (inst_mem == 0)
382                    state = CONTEXT_STATE_KO_MSYNC_ISSUE;
383                  break;
384                }
385              case CONTEXT_STATE_KO_MSYNC_ISSUE  :
386                {
387                  // Wait the msync issue
388                  if (inst_mem != 0)
389                    state = CONTEXT_STATE_KO_MSYNC_EXEC;
390                  break;
391                }
392              case CONTEXT_STATE_KO_MSYNC_EXEC   :
393                {
394                  // Wait the end of msync
395                  if (inst_mem == 0)
396                    state = CONTEXT_STATE_OK;
397                  break;
398                }
399              case CONTEXT_STATE_KO_SPR          :
400                {
401                  // Wait end of all instruction
402                  if (inst_all == 0)
403                    state = CONTEXT_STATE_KO_SPR_ISSUE;
404                  break;
405                }
406              case CONTEXT_STATE_KO_SPR_ISSUE    :
407                {
408                  // Wait the spr_access issue
409                  if (inst_all != 0)
410                    state = CONTEXT_STATE_KO_SPR_EXEC;
411                  break;
412                }
413              case CONTEXT_STATE_KO_SPR_EXEC     :
414                {
415                  // Wait the spr_access execution
416                  if (inst_all == 0)
417                    state = CONTEXT_STATE_OK;
418                  break;
419                }
420
421              default :
422                {
423                  throw ERRORMORPHEO(FUNCTION,toString(_("Context[%d], Unknow state : %s.\n"),i,toString(state).c_str()));
424                }
425              }
426            reg_STATE [i] = state;
427          }
428      }
429
430#if DEBUG >= DEBUG_TRACE
431    for (uint32_t i=0; i<_param->_nb_context; i++)
432      {
433        log_printf(TRACE,Context_State,FUNCTION,"Context State [%d]",i);
434        log_printf(TRACE,Context_State,FUNCTION," * reg_STATE                  : %s"  ,toString(reg_STATE [i]).c_str());
435        log_printf(TRACE,Context_State,FUNCTION," * reg_EVENT_ADDRESS          : 0x%x",reg_EVENT_ADDRESS          [i]);
436        log_printf(TRACE,Context_State,FUNCTION," * reg_EVENT_ADDRESS_EPCR     : 0x%x",reg_EVENT_ADDRESS_EPCR     [i]); 
437        log_printf(TRACE,Context_State,FUNCTION," * reg_EVENT_ADDRESS_EPCR_VAL : %d"  ,reg_EVENT_ADDRESS_EPCR_VAL [i]);
438        log_printf(TRACE,Context_State,FUNCTION," * reg_EVENT_ADDRESS_EEAR     : 0x%x",reg_EVENT_ADDRESS_EEAR     [i]); 
439        log_printf(TRACE,Context_State,FUNCTION," * reg_EVENT_ADDRESS_EEAR_VAL : %d"  ,reg_EVENT_ADDRESS_EEAR_VAL [i]);
440        log_printf(TRACE,Context_State,FUNCTION," * reg_EVENT_IS_DELAY_SLOT    : %d"  ,reg_EVENT_IS_DELAY_SLOT    [i]);
441        log_printf(TRACE,Context_State,FUNCTION," * reg_EVENT_IS_DS_TAKE       : %d"  ,reg_EVENT_IS_DS_TAKE       [i]);
442        log_printf(TRACE,Context_State,FUNCTION," * reg_EVENT_DEPTH            : %d"  ,reg_EVENT_DEPTH            [i]);
443      }
444#endif
445
446#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
447    end_cycle ();
448#endif
449
450    log_end(Context_State,FUNCTION);
451  };
452
453}; // end namespace context_state
454}; // end namespace front_end
455}; // end namespace multi_front_end
456}; // end namespace core
457
458}; // end namespace behavioural
459}; // end namespace morpheo             
460#endif
Note: See TracBrowser for help on using the repository browser.