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

Last change on this file since 145 was 145, checked in by rosiere, 14 years ago

1) add test with SPECINT2K
2) new config of Selftest
3) modif RAT to support multiple depth_save ... but not finish (need fix Update Prediction Table)
4) add Function_pointer but need fix

  • Property svn:keywords set to Id
File size: 16.5 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Commit_unit_genMealy_retire.cpp 145 2010-10-13 18: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::genMealy_retire"
21  void Commit_unit::genMealy_retire (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    Tcontrol_t retire_val          [_param->_nb_rename_unit][_param->_max_nb_inst_retire];
29    uint32_t   num_inst_retire     [_param->_nb_rename_unit];
30    bool       can_retire          [_param->_nb_rename_unit];
31
32    Tcontrol_t spr_write_val       [_param->_nb_front_end][_param->_max_nb_context];
33    Tcontrol_t spr_write_sr_f_val  [_param->_nb_front_end][_param->_max_nb_context];
34    Tcontrol_t spr_write_sr_f      [_param->_nb_front_end][_param->_max_nb_context];
35    Tcontrol_t spr_write_sr_cy_val [_param->_nb_front_end][_param->_max_nb_context];
36    Tcontrol_t spr_write_sr_cy     [_param->_nb_front_end][_param->_max_nb_context];
37    Tcontrol_t spr_write_sr_ov_val [_param->_nb_front_end][_param->_max_nb_context];
38    Tcontrol_t spr_write_sr_ov     [_param->_nb_front_end][_param->_max_nb_context];
39
40    // Initialisation
41    for (uint32_t i=0; i<_param->_nb_bank; i++)
42      internal_BANK_RETIRE_VAL  [i] = false;
43
44    for (uint32_t i=0; i<_param->_nb_rename_unit; i++)
45      {
46        num_inst_retire [i] = 0;
47        can_retire      [i] = true ;
48        for (uint32_t j=0; j<_param->_nb_inst_retire[i]; j++)
49          retire_val [i][j] = false;
50      }
51    for (uint32_t i=0; i<_param->_nb_front_end; ++i)
52      for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
53        {
54          spr_write_val       [i][j] = 0;
55          spr_write_sr_f_val  [i][j] = 0;
56          spr_write_sr_cy_val [i][j] = 0;
57          spr_write_sr_ov_val [i][j] = 0;
58
59          spr_write_sr_f      [i][j] = 0; // not necessary
60          spr_write_sr_cy     [i][j] = 0; // not necessary
61          spr_write_sr_ov     [i][j] = 0; // not necessary
62
63          // Init internal update table
64         
65          // Test if an event occure
66          // bool event = (PORT_READ(in_RETIRE_EVENT_STATE [i][j]) != EVENT_STATE_NO_EVENT);
67          bool reset_update_table = (commit_event_state_to_event_state(reg_EVENT_STATE[i][j]) == EVENT_STATE_EVENT);
68
69          log_printf(TRACE,Register_Address_Translation_unit,FUNCTION,"    * reset_update_table : %d",reset_update_table);
70
71          // not event -> update_table == 1 -> always update
72          // event     -> update_table and not reset
73          for (uint32_t k=0; k<_param->_nb_general_register_logic; ++k)
74            internal_rat_gpr_update_table [i][j][k] = // not event or
75                                                      (not reset_update_table and rat_gpr_update_table [i][j][k]);
76          for (uint32_t k=0; k<_param->_nb_special_register_logic; ++k)
77            internal_rat_spr_update_table [i][j][k] = // not event or
78                                                      (not reset_update_table and rat_spr_update_table [i][j][k]);
79        }
80
81    // Scan Top of each bank
82    internal_BANK_RETIRE_HEAD = reg_NUM_BANK_HEAD;
83    for (uint32_t i=0; i<_param->_nb_bank; i++)
84      {
85        uint32_t num_bank = (internal_BANK_RETIRE_HEAD+i)%_param->_nb_bank;
86
87        log_printf(TRACE,Commit_unit,FUNCTION,"  * BANK [%d]",num_bank);
88
89        // Test if have instruction
90        if (not _rob[num_bank].empty())
91          {
92            // Scan all instruction in windows and test if instruction is speculative
93            entry_t  * entry = _rob [num_bank].front();
94            uint32_t   x     = entry->rename_unit_id;
95            uint32_t   y     = num_inst_retire [x];
96
97            log_printf(TRACE,Commit_unit,FUNCTION,"    * num_rename_unit        : %d",x);
98            log_printf(TRACE,Commit_unit,FUNCTION,"    * num_inst_retire        : %d",y);
99
100            if (y < _param->_nb_inst_retire [x])
101              {
102#ifdef DEBUG_TEST
103                if (x >= _param->_nb_rename_unit)
104                  throw ERRORMORPHEO(FUNCTION,toString(_("Invalid rename_unit number (%d, max is %d).\n"),x,_param->_nb_rename_unit));
105#endif
106                bool       bypass= false;
107
108                log_printf(TRACE,Commit_unit,FUNCTION,"    * can_retire             : %d",can_retire [x]);
109                log_printf(TRACE,Commit_unit,FUNCTION,"    * RETIRE_ACK             : %d",PORT_READ(in_RETIRE_ACK [x][y]));
110
111                // test if :
112                //  * can retire (all previous instruction is retired)
113                //  * all structure is ok (not busy)
114                if (can_retire [x] and // in-order
115                    PORT_READ(in_RETIRE_ACK [x][y])) // not busy
116                  {
117                    log_printf(TRACE,Commit_unit,FUNCTION,"    * valid !!!");
118
119                    rob_state_t state        = entry->state;
120                    Tcontext_t  front_end_id = entry->front_end_id;
121                    Tcontext_t  context_id   = entry->context_id; 
122
123                    log_printf(TRACE,Commit_unit,FUNCTION,"      * state                : %s",toString(state).c_str());
124                    log_printf(TRACE,Commit_unit,FUNCTION,"      * front_end_id         : %d",front_end_id);
125                    log_printf(TRACE,Commit_unit,FUNCTION,"      * context_id           : %d",context_id  );
126                   
127                    if ((state == ROB_END_OK         ) or
128                        (state == ROB_END_KO         ) or
129                        (state == ROB_END_BRANCH_MISS) or
130                        (state == ROB_END_LOAD_MISS  ) or
131                        (state == ROB_END_MISS       )//  or
132//                      (state == ROB_END_EXCEPTION)
133                        )
134                      {
135                        Tcontrol_t         write_rd       = entry->write_rd;
136                        Tcontrol_t         write_re       = entry->write_re;
137                        Tgeneral_address_t num_reg_rd_log = entry->num_reg_rd_log;
138                        Tspecial_address_t num_reg_re_log = entry->num_reg_re_log;
139                       
140                        // if state is ok, when write flags in the SR regsiters
141                        bool spr_write_ack = true;
142                       
143                        // Write in SR the good flag
144                        if ((state == ROB_END_OK  ) and write_re)
145                          // ROB_END_BRANCH_MISS is a valid branch instruction but don't modify RE
146                          {
147                            log_printf(TRACE,Commit_unit,FUNCTION,"      * need write SR flags");
148                            log_printf(TRACE,Commit_unit,FUNCTION,"      * SPR_WRITE_ACK        : %d",PORT_READ(in_SPR_WRITE_ACK [front_end_id][context_id]));
149
150                            spr_write_ack = PORT_READ(in_SPR_WRITE_ACK [front_end_id][context_id]);
151                           
152                            // retire_ack is set !!!
153                            spr_write_val       [front_end_id][context_id] = 1;
154                           
155                            Tspecial_data_t flags = entry->flags;
156                           
157                            switch (num_reg_re_log)
158                              {
159                              case SPR_LOGIC_SR_F     : 
160                                {
161                                  spr_write_sr_f_val  [front_end_id][context_id] = 1;
162                                  spr_write_sr_f      [front_end_id][context_id] = (flags & FLAG_F )!=0;
163                                 
164                                  break;
165                                }
166                              case SPR_LOGIC_SR_CY_OV :
167                                {
168                                  spr_write_sr_cy_val [front_end_id][context_id] = 1;
169                                  spr_write_sr_ov_val [front_end_id][context_id] = 1;   
170                                  spr_write_sr_cy     [front_end_id][context_id] = (flags & FLAG_CY)!=0;
171                                  spr_write_sr_ov     [front_end_id][context_id] = (flags & FLAG_OV)!=0;
172                                 
173                                  break;
174                                }
175                              default : 
176                                {
177#ifdef DEBUG_TEST
178                                  throw ERRORMORPHEO(FUNCTION,_("Invalid num_reg_re_log.\n"));
179#endif
180                                }
181                              }
182                          }
183                       
184                        // find an instruction can be retire, and in order
185                       
186                        if (spr_write_ack)
187                          {
188                            retire_val [x][y] = 1;
189                            num_inst_retire [x] ++;
190                            internal_BANK_RETIRE_VAL [num_bank] = true;
191                          }
192                       
193                        // Restore Old Register
194                        Tcontrol_t retire_restore = (commit_event_state_to_event_state(reg_EVENT_STATE[front_end_id][context_id]) != EVENT_STATE_NO_EVENT);
195
196                        // Test if event -> need restore ?
197                        if (retire_restore)
198                          {
199                            log_printf(TRACE,Commit_unit,FUNCTION,"      * Restore");
200                           
201                            // Test and update update table
202                            if (write_rd)
203                              {
204                                internal_BANK_RETIRE_RESTORE_RD_PHY_OLD [num_bank] = (internal_rat_gpr_update_table[front_end_id][context_id][num_reg_rd_log] == 0);
205
206                                internal_rat_gpr_update_table[front_end_id][context_id][num_reg_rd_log] = 1;
207                              }
208                            if (write_re)
209                              {
210                                internal_BANK_RETIRE_RESTORE_RE_PHY_OLD [num_bank] = (internal_rat_spr_update_table[front_end_id][context_id][num_reg_re_log] == 0);
211                               
212                                internal_rat_spr_update_table[front_end_id][context_id][num_reg_re_log] = 1;
213                              }
214
215                            log_printf(TRACE,Commit_unit,FUNCTION,"      * restore_rd_phy_old   : %d",internal_BANK_RETIRE_RESTORE_RD_PHY_OLD [num_bank]);
216                            log_printf(TRACE,Commit_unit,FUNCTION,"      * restore_re_phy_old   : %d",internal_BANK_RETIRE_RESTORE_RE_PHY_OLD [num_bank]);
217                          }
218
219                        internal_BANK_RETIRE_NUM_RENAME_UNIT    [num_bank] = x;
220                        internal_BANK_RETIRE_NUM_INST           [num_bank] = y;
221                       
222                        if (_param->_have_port_front_end_id)
223                        PORT_WRITE(out_RETIRE_FRONT_END_ID          [x][y], front_end_id                );
224                        if (_param->_have_port_context_id)
225                        PORT_WRITE(out_RETIRE_CONTEXT_ID            [x][y], context_id                  );
226//                      PORT_WRITE(out_RETIRE_RENAME_UNIT_ID        [x][y], entry->rename_unit_id       );
227//                      if (_param->_have_port_depth and (_param->_rat_scheme[x] == RAT_DEPTH_SAVE))
228//                      PORT_WRITE(out_RETIRE_DEPTH                 [x][y], entry->depth                );
229                        PORT_WRITE(out_RETIRE_USE_STORE_QUEUE       [x][y], entry->use_store_queue      );
230                        PORT_WRITE(out_RETIRE_USE_LOAD_QUEUE        [x][y], entry->use_load_queue       );
231                        PORT_WRITE(out_RETIRE_STORE_QUEUE_PTR_WRITE [x][y], entry->store_queue_ptr_write);
232                        if (_param->_have_port_load_queue_ptr)
233                        PORT_WRITE(out_RETIRE_LOAD_QUEUE_PTR_WRITE  [x][y], entry->load_queue_ptr_write );
234//                      PORT_WRITE(out_RETIRE_READ_RA               [x][y], entry->read_ra              );
235//                      PORT_WRITE(out_RETIRE_NUM_REG_RA_PHY        [x][y], entry->num_reg_ra_phy       );
236//                      PORT_WRITE(out_RETIRE_READ_RB               [x][y], entry->read_rb              );
237//                      PORT_WRITE(out_RETIRE_NUM_REG_RB_PHY        [x][y], entry->num_reg_rb_phy       );
238//                      PORT_WRITE(out_RETIRE_READ_RC               [x][y], entry->read_rc              );
239//                      PORT_WRITE(out_RETIRE_NUM_REG_RC_PHY        [x][y], entry->num_reg_rc_phy       );
240                        PORT_WRITE(out_RETIRE_WRITE_RD              [x][y], entry->write_rd             );
241                        PORT_WRITE(out_RETIRE_NUM_REG_RD_LOG        [x][y], entry->num_reg_rd_log       );
242                        PORT_WRITE(out_RETIRE_NUM_REG_RD_PHY_OLD    [x][y], entry->num_reg_rd_phy_old   );
243                        PORT_WRITE(out_RETIRE_NUM_REG_RD_PHY_NEW    [x][y], entry->num_reg_rd_phy_new   );
244                        PORT_WRITE(out_RETIRE_WRITE_RE              [x][y], write_re                    );
245                        PORT_WRITE(out_RETIRE_NUM_REG_RE_LOG        [x][y], num_reg_re_log              );
246                        PORT_WRITE(out_RETIRE_NUM_REG_RE_PHY_OLD    [x][y], entry->num_reg_re_phy_old   );
247                        PORT_WRITE(out_RETIRE_NUM_REG_RE_PHY_NEW    [x][y], entry->num_reg_re_phy_new   );
248                        PORT_WRITE(out_RETIRE_RESTORE               [x][y],retire_restore);
249                        PORT_WRITE(out_RETIRE_RESTORE_RD_PHY_OLD    [x][y],internal_BANK_RETIRE_RESTORE_RD_PHY_OLD [num_bank]);
250                        PORT_WRITE(out_RETIRE_RESTORE_RE_PHY_OLD    [x][y],internal_BANK_RETIRE_RESTORE_RE_PHY_OLD [num_bank]);
251                       
252                        // Event -> rob must be manage this event
253                        if ((state == ROB_END_BRANCH_MISS) or
254                            (state == ROB_END_LOAD_MISS))
255                          can_retire [x] = false;
256                      }
257
258                    log_printf(TRACE,Commit_unit,FUNCTION,"      * bypass (before)      : %d",bypass);
259
260                    bypass = ((state == ROB_END              ) or
261                              (state == ROB_STORE_OK         ) or
262                              (state == ROB_STORE_KO         ) or
263                              (state == ROB_STORE_OK_WAIT_END) or
264                              (state == ROB_STORE_KO_WAIT_END));
265
266                    log_printf(TRACE,Commit_unit,FUNCTION,"      * bypass (after)       : %d",bypass);
267                   
268                    uint32_t packet = ((entry->ptr << _param->_shift_num_slot) | num_bank);
269
270                    log_printf(TRACE,Commit_unit,FUNCTION,"      * packet               : %d",packet);
271                   
272                    // if future event, don't update after this event
273                    if ((reg_EVENT_STATE  [front_end_id][context_id] == COMMIT_EVENT_STATE_NOT_YET_EVENT) and
274                        (reg_EVENT_PACKET [front_end_id][context_id] == packet))
275                      {
276                        log_printf(TRACE,Commit_unit,FUNCTION,"      * is the event instruction, stop bypass !!!");
277                        bypass = false;
278                      }
279                  }
280               
281                // Retire "in-order"
282                can_retire [x]  &= (retire_val [x][y] or bypass);
283              }
284          }
285      }
286   
287    for (uint32_t i=0; i<_param->_nb_rename_unit; i++)
288      for (uint32_t j=0; j<_param->_nb_inst_retire[i]; j++)
289        PORT_WRITE(out_RETIRE_VAL [i][j],retire_val [i][j]);
290
291    for (uint32_t i=0; i<_param->_nb_front_end; ++i)
292      for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
293        {
294          PORT_WRITE(out_SPR_WRITE_VAL       [i][j], spr_write_val       [i][j]);
295          PORT_WRITE(out_SPR_WRITE_SR_F_VAL  [i][j], spr_write_sr_f_val  [i][j]);
296          PORT_WRITE(out_SPR_WRITE_SR_F      [i][j], spr_write_sr_f      [i][j]);
297          PORT_WRITE(out_SPR_WRITE_SR_CY_VAL [i][j], spr_write_sr_cy_val [i][j]);
298          PORT_WRITE(out_SPR_WRITE_SR_CY     [i][j], spr_write_sr_cy     [i][j]);
299          PORT_WRITE(out_SPR_WRITE_SR_OV_VAL [i][j], spr_write_sr_ov_val [i][j]);
300          PORT_WRITE(out_SPR_WRITE_SR_OV     [i][j], spr_write_sr_ov     [i][j]);
301        }
302      }
303    else
304      {
305        for (uint32_t i=0; i<_param->_nb_rename_unit; i++)
306          for (uint32_t j=0; j<_param->_nb_inst_retire[i]; j++)
307            PORT_WRITE(out_RETIRE_VAL [i][j],0);
308
309        for (uint32_t i=0; i<_param->_nb_front_end; ++i)
310          for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
311            PORT_WRITE(out_SPR_WRITE_VAL [i][j], 0);
312      }
313
314    log_end(Commit_unit,FUNCTION);
315  };
316
317}; // end namespace commit_unit
318}; // end namespace ooo_engine
319}; // end namespace multi_ooo_engine
320}; // end namespace core
321}; // end namespace behavioural
322}; // end namespace morpheo             
323#endif
Note: See TracBrowser for help on using the repository browser.