source: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Commit_unit/src/Commit_unit_genMoore.cpp @ 123

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

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

  • Property svn:keywords set to Id
File size: 14.7 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Commit_unit_genMoore.cpp 123 2009-06-08 20:43:30Z rosiere $
4 *
5 * [ Description ]
6 *
7 */
8
9#include "Behavioural/Core/Multi_OOO_Engine/OOO_Engine/Commit_unit/include/Commit_unit.h"
10
11namespace morpheo                    {
12namespace behavioural {
13namespace core {
14namespace multi_ooo_engine {
15namespace ooo_engine {
16namespace commit_unit {
17
18
19#undef  FUNCTION
20#define FUNCTION "Commit_unit::genMoore"
21  void Commit_unit::genMoore (void)
22  {
23    log_begin(Commit_unit,FUNCTION);
24    log_function(Commit_unit,FUNCTION,_name.c_str());
25
26    if (PORT_READ(in_NRESET))
27      {
28    // ===================================================================
29    // =====[ REEXECUTE ]=================================================
30    // ===================================================================
31    {
32      uint32_t nb_scan_bank = 0; // last scan bank
33      bool     can_continue = true;
34
35      // for each reexecute_port
36      for (uint32_t i=0; i<_param->_nb_inst_reexecute; ++i)
37        {
38          log_printf(TRACE,Commit_unit,FUNCTION,"  * REEXECUTE [%d]",i);
39         
40          // Store instruction comming Out Of Order in Load Store Unit.
41          // Must be executed in no speculative mode. Also, send a signal when an Store is in head of ROB
42         
43          Tcontrol_t val = false;
44
45          for (uint32_t j=nb_scan_bank; j<_param->_nb_bank; j++)
46            {
47              nb_scan_bank ++;
48             
49              // translate bank number
50              uint32_t num_bank = (reg_NUM_BANK_HEAD+j)%_param->_nb_bank;
51             
52              log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank      : %d",num_bank);
53
54              // Test if the head of rob is not empty
55              if (not _rob[num_bank].empty())
56                {
57                  log_printf(TRACE,Commit_unit,FUNCTION,"    * ROB is not empty");
58                 
59                  // Read state
60                  entry_t    * entry = _rob [num_bank].front();
61                  rob_state_t  state = entry->state;
62                 
63                  // Test state
64                  //  * store is ko, send signal at store_queue
65                  //  * store_is ok, test if in head
66//                val   = (((state == ROB_STORE_OK) and (num_bank == (reg_NUM_BANK_HEAD))) or
67//                          (state == ROB_STORE_KO)  or
68//                          (state == ROB_STORE_EVENT)
69//                          );
70                  val   = (((state == ROB_STORE_OK) and can_continue) or
71                            (state == ROB_STORE_KO)  or
72                            (state == ROB_STORE_EVENT)
73                            );
74                 
75                  can_continue &= ((state == ROB_STORE_OK          ) or
76                                   (state == ROB_STORE_OK_WAIT_END ) or
77                                   (state == ROB_END_OK_SPECULATIVE) or
78                                   (state == ROB_END_OK            ) or
79                                   (state == ROB_END               )
80                                   );
81
82                  log_printf(TRACE,Commit_unit,FUNCTION,"    * val           : %d",val);
83
84                  if (val)
85                    {
86                      internal_REEXECUTE_NUM_BANK [i] = num_bank;
87
88                      Tpacket_t packet_id = ((entry->ptr << _param->_shift_num_slot) | num_bank);
89                     
90                      log_printf(TRACE,Commit_unit,FUNCTION,"    * packet_id     : %d",packet_id);
91                     
92                      // Reexecute store
93                      if (_param->_have_port_context_id)
94                      PORT_WRITE(out_REEXECUTE_CONTEXT_ID            [i], entry->context_id           );
95                      if (_param->_have_port_front_end_id)
96                      PORT_WRITE(out_REEXECUTE_FRONT_END_ID          [i], entry->front_end_id         );
97                      if (_param->_have_port_rob_ptr  )
98                      PORT_WRITE(out_REEXECUTE_PACKET_ID             [i], packet_id                   );
99                      PORT_WRITE(out_REEXECUTE_TYPE                  [i], entry->type                 );
100                      PORT_WRITE(out_REEXECUTE_STORE_QUEUE_PTR_WRITE [i], entry->store_queue_ptr_write);
101                      PORT_WRITE(out_REEXECUTE_OPERATION             [i], (state == ROB_STORE_OK)?OPERATION_MEMORY_STORE_HEAD_OK:OPERATION_MEMORY_STORE_HEAD_KO);
102
103                      break; // Stop scan
104                    }
105                }
106            } 
107
108          internal_REEXECUTE_VAL      [i] = val;
109        }
110    }
111
112    // ===================================================================
113    // =====[ BRANCH_COMPLETE ]===========================================
114    // ===================================================================
115    {
116      // Branchement must be send at the prediction unit
117
118      uint32_t nb_scan_bank = 0; // last scan bank
119
120      // for each port, find a valid branchement.
121      for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
122        {
123          log_printf(TRACE,Commit_unit,FUNCTION,"  * BRANCH_COMPLETE [%d]",i);
124
125          Tcontrol_t  val  = false;
126         
127          for (uint32_t j=nb_scan_bank; j<_param->_nb_bank; j++)
128            {
129              nb_scan_bank ++;
130
131              // translate bank number
132              uint32_t num_bank = (reg_NUM_BANK_HEAD+j)%_param->_nb_bank;
133
134              log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank           : %d",num_bank);
135             
136              // Test if in this bank, they have an instruction
137              if (not _rob [num_bank].empty())
138                {
139                  log_printf(TRACE,Commit_unit,FUNCTION,"    * not empty");
140
141                  // Read information
142                  entry_t    * entry    = _rob [num_bank].front();
143                  rob_state_t  state    = entry->state;
144                  Tcontext_t   front_end_id = entry->front_end_id;
145                  Tcontext_t   context_id   = entry->context_id  ;
146
147                  log_printf(TRACE,Commit_unit,FUNCTION,"    * front_end_id       : %d",front_end_id);
148                  log_printf(TRACE,Commit_unit,FUNCTION,"    * context_id         : %d",context_id  );
149
150                  // don't complete a branch when rob manage an present event
151                  if (((reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_NO_EVENT) or
152                       (reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_NOT_YET_EVENT)) and
153                      (state == ROB_BRANCH_COMPLETE))
154                    {
155                      log_printf(TRACE,Commit_unit,FUNCTION,"    * find !!!");
156
157                      // test if have a future event (stop is set)
158//                       log_printf(TRACE,Commit_unit,FUNCTION,"      * reg_EVENT_STOP   : %d",reg_EVENT_STOP [front_end_id][context_id]);
159
160                      if (reg_EVENT_STATE [front_end_id][context_id] == COMMIT_EVENT_STATE_NOT_YET_EVENT)
161                        {
162                          // Have future event, can complete the branch if the event is most speculative than this branchement
163                          // Also, need compare packet_id (is order)
164
165                          uint32_t _top = ((_rob[reg_NUM_BANK_HEAD].front()->ptr << _param->_shift_num_slot) | reg_NUM_BANK_HEAD);
166                          uint32_t _old = reg_EVENT_PACKET [front_end_id][context_id];
167                          uint32_t _new = ((entry->ptr << _param->_shift_num_slot) | num_bank);
168
169//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _top             : %d",_top);
170//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _old (before)    : %d",_old);
171//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _new (before)    : %d",_new);
172
173                          if (_old < _top) _old = _old+_param->_size_queue;
174                          if (_new < _top) _new = _new+_param->_size_queue;
175                          if (_new < _old) val = true;
176
177//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _old (after )    : %d",_old);
178//                           log_printf(TRACE,Commit_unit,FUNCTION,"      * _new (after )    : %d",_new);
179
180                        }
181                      else
182                        val = true;
183                     
184                      log_printf(TRACE,Commit_unit,FUNCTION,"      * val              : %d",val);
185
186                      if (val)
187                        {
188                          // Have an valid branchement to complete
189                      internal_BRANCH_COMPLETE_NUM_BANK           [i] = num_bank;
190                     
191                      if (_param->_have_port_front_end_id)
192                      PORT_WRITE(out_BRANCH_COMPLETE_FRONT_END_ID [i],        front_end_id    );
193                      if (_param->_have_port_context_id)
194                      PORT_WRITE(out_BRANCH_COMPLETE_CONTEXT_ID   [i],        context_id      );
195                      if (_param->_have_port_depth)
196                      PORT_WRITE(out_BRANCH_COMPLETE_DEPTH        [i], entry->depth           );
197                      PORT_WRITE(out_BRANCH_COMPLETE_ADDRESS      [i], entry->address_next    );
198//                    PORT_WRITE(out_BRANCH_COMPLETE_FLAG         [i],(entry->flags&FLAG_F)!=0);
199                      PORT_WRITE(out_BRANCH_COMPLETE_NO_SEQUENCE  [i], entry->no_sequence     );
200                     
201                      break; // Stop scan
202                        }
203                    }
204                }
205            }
206
207          internal_BRANCH_COMPLETE_VAL [i] = val;
208        }
209    }
210
211    // ===================================================================
212    // =====[ UPDATE ]====================================================
213    // ===================================================================
214    {
215      internal_UPDATE_VAL = 0;
216      internal_UPDATE_NUM_BANK = reg_NUM_BANK_HEAD;
217
218      // Test if have an instruction
219      if (not _rob[internal_UPDATE_NUM_BANK].empty())
220        {
221          log_printf(TRACE,Commit_unit,FUNCTION,"  * UPDATE");
222          log_printf(TRACE,Commit_unit,FUNCTION,"    * num_bank : %d",internal_UPDATE_NUM_BANK);
223
224          entry_t * entry = _rob [internal_UPDATE_NUM_BANK].front();
225
226          // Test state
227          // Update if exception or load miss
228          switch (entry->state)
229            {
230            case ROB_END_EXCEPTION_UPDATE :
231              {
232                internal_UPDATE_VAL = 1;
233                throw ERRORMORPHEO(FUNCTION,_("Moore : exception is not yet supported (Coming Soon).\n"));
234                break;
235              }
236            case ROB_END_LOAD_MISS_UPDATE :
237              {
238                log_printf(TRACE,Commit_unit,FUNCTION,"    * ROB_END_LOAD_MISS_UPDATE");
239
240                internal_UPDATE_VAL = 1;
241
242                Tcontext_t front_end_id = entry->front_end_id;
243                Tcontext_t context_id   = entry->context_id  ;
244
245                log_printf(TRACE,Commit_unit,FUNCTION,"      * front_end_id : %d",front_end_id);
246                log_printf(TRACE,Commit_unit,FUNCTION,"      * context_id   : %d",context_id  );
247
248                if (_param->_have_port_front_end_id)
249                PORT_WRITE(out_UPDATE_FRONT_END_ID    ,front_end_id);
250                if (_param->_have_port_context_id)
251                PORT_WRITE(out_UPDATE_CONTEXT_ID      ,context_id  );
252                if (_param->_have_port_depth)
253                PORT_WRITE(out_UPDATE_DEPTH           ,entry->depth);
254                PORT_WRITE(out_UPDATE_TYPE            ,EVENT_TYPE_LOAD_MISS_SPECULATION);
255//                 PORT_WRITE(out_UPDATE_IS_DELAY_SLOT   ,reg_PC_CURRENT_IS_DS      [front_end_id][context_id]);
256//                 PORT_WRITE(out_UPDATE_ADDRESS         ,reg_PC_CURRENT            [front_end_id][context_id]);
257//                 PORT_WRITE(out_UPDATE_ADDRESS_EPCR_VAL,reg_PC_CURRENT_IS_DS_TAKE [front_end_id][context_id]);
258//                 PORT_WRITE(out_UPDATE_ADDRESS_EPCR    ,reg_PC_NEXT               [front_end_id][context_id]);
259//                 PORT_WRITE(out_UPDATE_ADDRESS_EEAR_VAL,0);
260// //              PORT_WRITE(out_UPDATE_ADDRESS_EEAR    ,);
261
262                PORT_WRITE(out_UPDATE_IS_DELAY_SLOT   ,0);
263                PORT_WRITE(out_UPDATE_ADDRESS         ,reg_PC_NEXT [front_end_id][context_id]);
264                PORT_WRITE(out_UPDATE_ADDRESS_EPCR_VAL,0);
265//              PORT_WRITE(out_UPDATE_ADDRESS_EPCR    ,);
266                PORT_WRITE(out_UPDATE_ADDRESS_EEAR_VAL,0);
267//              PORT_WRITE(out_UPDATE_ADDRESS_EEAR    ,);
268
269                break;
270              }
271            default :
272              {
273//                 internal_UPDATE_VAL = 0;
274              }
275            }
276        }
277     
278      log_printf(TRACE,Commit_unit,FUNCTION,"  * UPDATE (end)");
279    }
280 
281    // ===================================================================
282    // =====[ NB_INST ]===================================================
283    // ===================================================================
284    {
285#ifdef DEBUG_TEST
286      bool empty = true;
287#endif
288      for (uint32_t i=0; i<_param->_nb_front_end; i++)
289        for (uint32_t j=0; j<_param->_nb_context [i]; j++)
290          {
291#ifdef DEBUG_TEST
292            empty &= (reg_NB_INST_COMMIT_ALL [i][j] == 0);
293#endif
294            PORT_WRITE(out_NB_INST_COMMIT_ALL [i][j], reg_NB_INST_COMMIT_ALL [i][j]);
295            PORT_WRITE(out_NB_INST_COMMIT_MEM [i][j], reg_NB_INST_COMMIT_MEM [i][j]);
296          }
297#ifdef DEBUG_TEST
298      PORT_WRITE(out_INFO_ROB_EMPTY,empty);
299#endif
300    }
301
302
303    // ===================================================================
304    // =====[ RETIRE_EVENT ]==============================================
305    // ===================================================================
306    for (uint32_t i=0; i<_param->_nb_front_end; i++)
307      for (uint32_t j=0; j<_param->_nb_context [i]; j++)
308        {
309//           bool flush = (((reg_EVENT_STATE [i][j] == COMMIT_EVENT_STATE_EVENT) or
310//                          (reg_EVENT_STATE [i][j] == COMMIT_EVENT_STATE_WAIT_DECOD)) and
311//                         not reg_EVENT_CAN_RESTART[i][j]);
312
313          PORT_WRITE(out_RETIRE_EVENT_STATE [i][j], commit_event_state_to_event_state(reg_EVENT_STATE[i][j]));
314//        PORT_WRITE(out_RETIRE_EVENT_FLUSH [i][j], flush);
315//        PORT_WRITE(out_RETIRE_EVENT_STOP  [i][j], reg_EVENT_STOP [i][j]);
316          PORT_WRITE(out_RETIRE_EVENT_STOP  [i][j], ((reg_EVENT_STATE [i][j] == COMMIT_EVENT_STATE_NOT_YET_EVENT) or
317                                                     reg_EVENT_NEXT_STOP [i][j]));
318        }
319      }
320    else
321      {
322        for (uint32_t i=0; i<_param->_nb_inst_reexecute; ++i)
323          {
324            internal_REEXECUTE_VAL      [i] = 0;
325//             internal_REEXECUTE_NUM_BANK [i] = num_bank;
326          }
327
328        for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
329          {
330            internal_BRANCH_COMPLETE_VAL [i] = 0;
331//             internal_BRANCH_COMPLETE_NUM_BANK           [i] = num_bank;
332          }
333
334        internal_UPDATE_VAL = 0;
335//       internal_UPDATE_NUM_BANK = reg_NUM_BANK_HEAD;
336
337
338        for (uint32_t i=0; i<_param->_nb_front_end; i++)
339          for (uint32_t j=0; j<_param->_nb_context [i]; j++)
340            {
341              PORT_WRITE(out_RETIRE_EVENT_STATE [i][j], commit_event_state_to_event_state(COMMIT_EVENT_STATE_NO_EVENT));
342//            PORT_WRITE(out_RETIRE_EVENT_FLUSH [i][j], flush);
343//            PORT_WRITE(out_RETIRE_EVENT_STOP  [i][j], reg_EVENT_STOP [i][j]);
344              PORT_WRITE(out_RETIRE_EVENT_STOP  [i][j], true);
345            }
346      }
347
348      for (uint32_t i=0; i<_param->_nb_inst_reexecute; ++i)
349        PORT_WRITE(out_REEXECUTE_VAL[i], internal_REEXECUTE_VAL [i]);
350      for (uint32_t i=0; i<_param->_nb_inst_branch_complete; i++)
351        PORT_WRITE(out_BRANCH_COMPLETE_VAL [i], internal_BRANCH_COMPLETE_VAL [i]);
352      PORT_WRITE(out_UPDATE_VAL, internal_UPDATE_VAL);
353       
354    log_end(Commit_unit,FUNCTION);
355  };
356
357}; // end namespace commit_unit
358}; // end namespace ooo_engine
359}; // end namespace multi_ooo_engine
360}; // end namespace core
361}; // end namespace behavioural
362}; // end namespace morpheo             
363#endif
Note: See TracBrowser for help on using the repository browser.