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

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

Modif for performance :
1) Load Store Unit : store send request to valid exeception
2) Commit_unit : retire can bypass store
3) Commit_unit : add stat to manage store instruction
4) Load Store Unit and Load Store Pointer Manager : add store_queue_ptr_read
5) Fix lot of bug

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