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

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

1) Add test and configuration
2) Fix Bug
3) Add log file in load store unit
4) Fix Bug in environment

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