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

Last change on this file since 139 was 139, checked in by rosiere, 14 years ago
  • Add test for all configuration
  • RAT : add rat scheme (depth_save)
  • Property svn:keywords set to Id
File size: 16.3 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Commit_unit_genMealy_retire.cpp 139 2010-07-30 14:47:27Z 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                        PORT_WRITE(out_RETIRE_USE_STORE_QUEUE       [x][y], entry->use_store_queue      );
228                        PORT_WRITE(out_RETIRE_USE_LOAD_QUEUE        [x][y], entry->use_load_queue       );
229                        PORT_WRITE(out_RETIRE_STORE_QUEUE_PTR_WRITE [x][y], entry->store_queue_ptr_write);
230                        if (_param->_have_port_load_queue_ptr)
231                        PORT_WRITE(out_RETIRE_LOAD_QUEUE_PTR_WRITE  [x][y], entry->load_queue_ptr_write );
232//                      PORT_WRITE(out_RETIRE_READ_RA               [x][y], entry->read_ra              );
233//                      PORT_WRITE(out_RETIRE_NUM_REG_RA_PHY        [x][y], entry->num_reg_ra_phy       );
234//                      PORT_WRITE(out_RETIRE_READ_RB               [x][y], entry->read_rb              );
235//                      PORT_WRITE(out_RETIRE_NUM_REG_RB_PHY        [x][y], entry->num_reg_rb_phy       );
236//                      PORT_WRITE(out_RETIRE_READ_RC               [x][y], entry->read_rc              );
237//                      PORT_WRITE(out_RETIRE_NUM_REG_RC_PHY        [x][y], entry->num_reg_rc_phy       );
238                        PORT_WRITE(out_RETIRE_WRITE_RD              [x][y], entry->write_rd             );
239                        PORT_WRITE(out_RETIRE_NUM_REG_RD_LOG        [x][y], entry->num_reg_rd_log       );
240                        PORT_WRITE(out_RETIRE_NUM_REG_RD_PHY_OLD    [x][y], entry->num_reg_rd_phy_old   );
241                        PORT_WRITE(out_RETIRE_NUM_REG_RD_PHY_NEW    [x][y], entry->num_reg_rd_phy_new   );
242                        PORT_WRITE(out_RETIRE_WRITE_RE              [x][y], write_re                    );
243                        PORT_WRITE(out_RETIRE_NUM_REG_RE_LOG        [x][y], num_reg_re_log              );
244                        PORT_WRITE(out_RETIRE_NUM_REG_RE_PHY_OLD    [x][y], entry->num_reg_re_phy_old   );
245                        PORT_WRITE(out_RETIRE_NUM_REG_RE_PHY_NEW    [x][y], entry->num_reg_re_phy_new   );
246                        PORT_WRITE(out_RETIRE_RESTORE               [x][y],retire_restore);
247                        PORT_WRITE(out_RETIRE_RESTORE_RD_PHY_OLD    [x][y],internal_BANK_RETIRE_RESTORE_RD_PHY_OLD [num_bank]);
248                        PORT_WRITE(out_RETIRE_RESTORE_RE_PHY_OLD    [x][y],internal_BANK_RETIRE_RESTORE_RE_PHY_OLD [num_bank]);
249                       
250                        // Event -> rob must be manage this event
251                        if ((state == ROB_END_BRANCH_MISS) or
252                            (state == ROB_END_LOAD_MISS))
253                          can_retire [x] = false;
254                      }
255
256                    log_printf(TRACE,Commit_unit,FUNCTION,"      * bypass (before)      : %d",bypass);
257
258                    bypass = ((state == ROB_END              ) or
259                              (state == ROB_STORE_OK         ) or
260                              (state == ROB_STORE_KO         ) or
261                              (state == ROB_STORE_OK_WAIT_END) or
262                              (state == ROB_STORE_KO_WAIT_END));
263
264                    log_printf(TRACE,Commit_unit,FUNCTION,"      * bypass (after)       : %d",bypass);
265                   
266                    uint32_t packet = ((entry->ptr << _param->_shift_num_slot) | num_bank);
267
268                    log_printf(TRACE,Commit_unit,FUNCTION,"      * packet               : %d",packet);
269                   
270                    // if future event, don't update after this event
271                    if ((reg_EVENT_STATE  [front_end_id][context_id] == COMMIT_EVENT_STATE_NOT_YET_EVENT) and
272                        (reg_EVENT_PACKET [front_end_id][context_id] == packet))
273                      {
274                        log_printf(TRACE,Commit_unit,FUNCTION,"      * is the event instruction, stop bypass !!!");
275                        bypass = false;
276                      }
277                  }
278               
279                // Retire "in-order"
280                can_retire [x]  &= (retire_val [x][y] or bypass);
281              }
282          }
283      }
284   
285    for (uint32_t i=0; i<_param->_nb_rename_unit; i++)
286      for (uint32_t j=0; j<_param->_nb_inst_retire[i]; j++)
287        PORT_WRITE(out_RETIRE_VAL [i][j],retire_val [i][j]);
288
289    for (uint32_t i=0; i<_param->_nb_front_end; ++i)
290      for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
291        {
292          PORT_WRITE(out_SPR_WRITE_VAL       [i][j], spr_write_val       [i][j]);
293          PORT_WRITE(out_SPR_WRITE_SR_F_VAL  [i][j], spr_write_sr_f_val  [i][j]);
294          PORT_WRITE(out_SPR_WRITE_SR_F      [i][j], spr_write_sr_f      [i][j]);
295          PORT_WRITE(out_SPR_WRITE_SR_CY_VAL [i][j], spr_write_sr_cy_val [i][j]);
296          PORT_WRITE(out_SPR_WRITE_SR_CY     [i][j], spr_write_sr_cy     [i][j]);
297          PORT_WRITE(out_SPR_WRITE_SR_OV_VAL [i][j], spr_write_sr_ov_val [i][j]);
298          PORT_WRITE(out_SPR_WRITE_SR_OV     [i][j], spr_write_sr_ov     [i][j]);
299        }
300      }
301    else
302      {
303        for (uint32_t i=0; i<_param->_nb_rename_unit; i++)
304          for (uint32_t j=0; j<_param->_nb_inst_retire[i]; j++)
305            PORT_WRITE(out_RETIRE_VAL [i][j],0);
306
307        for (uint32_t i=0; i<_param->_nb_front_end; ++i)
308          for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
309            PORT_WRITE(out_SPR_WRITE_VAL [i][j], 0);
310      }
311
312    log_end(Commit_unit,FUNCTION);
313  };
314
315}; // end namespace commit_unit
316}; // end namespace ooo_engine
317}; // end namespace multi_ooo_engine
318}; // end namespace core
319}; // end namespace behavioural
320}; // end namespace morpheo             
321#endif
Note: See TracBrowser for help on using the repository browser.