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

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

1) Correct bug in link two signal
2) Fix error detected with valgrind
3) modif distexe script

  • Property svn:keywords set to Id
File size: 13.0 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Commit_unit_genMealy_retire.cpp 128 2009-06-26 08:43:23Z 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        }
60
61    // Scan Top of each bank
62    internal_BANK_RETIRE_HEAD = reg_NUM_BANK_HEAD;
63    for (uint32_t i=0; i<_param->_nb_bank; i++)
64      {
65        uint32_t num_bank = (internal_BANK_RETIRE_HEAD+i)%_param->_nb_bank;
66
67        log_printf(TRACE,Commit_unit,FUNCTION,"  * BANK [%d]",num_bank);
68
69        // Test if have instruction
70        if (not _rob[num_bank].empty())
71          {
72            // Scan all instruction in windows and test if instruction is speculative
73            entry_t  * entry = _rob [num_bank].front();
74            uint32_t   x     = entry->rename_unit_id;
75            uint32_t   y     = num_inst_retire [x];
76
77            log_printf(TRACE,Commit_unit,FUNCTION,"    * num_rename_unit        : %d",x);
78            log_printf(TRACE,Commit_unit,FUNCTION,"    * num_inst_retire        : %d",y);
79
80            if (y < _param->_nb_inst_retire [x])
81              {
82#ifdef DEBUG_TEST
83                if (x >= _param->_nb_rename_unit)
84                  throw ERRORMORPHEO(FUNCTION,toString(_("Invalid rename_unit number (%d, max is %d).\n"),x,_param->_nb_rename_unit));
85#endif
86                bool       bypass= false;
87
88                log_printf(TRACE,Commit_unit,FUNCTION,"    * can_retire             : %d",can_retire [x]);
89                log_printf(TRACE,Commit_unit,FUNCTION,"    * RETIRE_ACK             : %d",PORT_READ(in_RETIRE_ACK [x][y]));
90
91                // test if :
92                //  * can retire (all previous instruction is retired)
93                //  * all structure is ok (not busy)
94                if (can_retire [x] and // in-order
95                    PORT_READ(in_RETIRE_ACK [x][y])) // not busy
96                  {
97                    log_printf(TRACE,Commit_unit,FUNCTION,"    * valid !!!");
98
99                    rob_state_t state        = entry->state;
100                    Tcontext_t  front_end_id = entry->front_end_id;
101                    Tcontext_t  context_id   = entry->context_id; 
102
103                    log_printf(TRACE,Commit_unit,FUNCTION,"      * state                : %s",toString(state).c_str());
104                    log_printf(TRACE,Commit_unit,FUNCTION,"      * front_end_id         : %d",front_end_id);
105                    log_printf(TRACE,Commit_unit,FUNCTION,"      * context_id           : %d",context_id  );
106                   
107                    if ((state == ROB_END_OK         ) or
108                        (state == ROB_END_KO         ) or
109                        (state == ROB_END_BRANCH_MISS) or
110                        (state == ROB_END_LOAD_MISS  ) or
111                        (state == ROB_END_MISS       )//  or
112//                      (state == ROB_END_EXCEPTION)
113                        )
114                      {
115                        Tcontrol_t         write_re       = entry->write_re;
116                        Tspecial_address_t num_reg_re_log = entry->num_reg_re_log;
117                       
118                        // if state is ok, when write flags in the SR regsiters
119                        bool spr_write_ack = true;
120                       
121                        // Write in SR the good flag
122                        if ((state == ROB_END_OK  ) and write_re)
123                          // ROB_END_BRANCH_MISS is a valid branch instruction but don't modify RE
124                          {
125                            log_printf(TRACE,Commit_unit,FUNCTION,"      * need write SR flags");
126                            log_printf(TRACE,Commit_unit,FUNCTION,"      * SPR_WRITE_ACK        : %d",PORT_READ(in_SPR_WRITE_ACK [front_end_id][context_id]));
127
128                            spr_write_ack = PORT_READ(in_SPR_WRITE_ACK [front_end_id][context_id]);
129                           
130                            // retire_ack is set !!!
131                            spr_write_val       [front_end_id][context_id] = 1;
132                           
133                            Tspecial_data_t flags = entry->flags;
134                           
135                            switch (num_reg_re_log)
136                              {
137                              case SPR_LOGIC_SR_F     : 
138                                {
139                                  spr_write_sr_f_val  [front_end_id][context_id] = 1;
140                                  spr_write_sr_f      [front_end_id][context_id] = (flags & FLAG_F )!=0;
141                                 
142                                  break;
143                                }
144                              case SPR_LOGIC_SR_CY_OV :
145                                {
146                                  spr_write_sr_cy_val [front_end_id][context_id] = 1;
147                                  spr_write_sr_ov_val [front_end_id][context_id] = 1;   
148                                  spr_write_sr_cy     [front_end_id][context_id] = (flags & FLAG_CY)!=0;
149                                  spr_write_sr_ov     [front_end_id][context_id] = (flags & FLAG_OV)!=0;
150                                 
151                                  break;
152                                }
153                              default : 
154                                {
155#ifdef DEBUG_TEST
156                                  throw ERRORMORPHEO(FUNCTION,_("Invalid num_reg_re_log.\n"));
157#endif
158                                }
159                              }
160                          }
161                       
162                        // find an instruction can be retire, and in order
163                       
164                        if (spr_write_ack)
165                          {
166                            retire_val [x][y] = 1;
167                            num_inst_retire [x] ++;
168                            internal_BANK_RETIRE_VAL [num_bank] = true;
169                          }
170                       
171                        internal_BANK_RETIRE_NUM_RENAME_UNIT [num_bank] = x;
172                        internal_BANK_RETIRE_NUM_INST        [num_bank] = y;
173                       
174                        if (_param->_have_port_front_end_id)
175                        PORT_WRITE(out_RETIRE_FRONT_END_ID          [x][y], front_end_id                );
176                        if (_param->_have_port_context_id)
177                        PORT_WRITE(out_RETIRE_CONTEXT_ID            [x][y], context_id                  );
178//                      PORT_WRITE(out_RETIRE_RENAME_UNIT_ID        [x][y], entry->rename_unit_id       );
179                        PORT_WRITE(out_RETIRE_USE_STORE_QUEUE       [x][y], entry->use_store_queue      );
180                        PORT_WRITE(out_RETIRE_USE_LOAD_QUEUE        [x][y], entry->use_load_queue       );
181                        PORT_WRITE(out_RETIRE_STORE_QUEUE_PTR_WRITE [x][y], entry->store_queue_ptr_write);
182                        if (_param->_have_port_load_queue_ptr)
183                        PORT_WRITE(out_RETIRE_LOAD_QUEUE_PTR_WRITE  [x][y], entry->load_queue_ptr_write );
184//                      PORT_WRITE(out_RETIRE_READ_RA               [x][y], entry->read_ra              );
185//                      PORT_WRITE(out_RETIRE_NUM_REG_RA_PHY        [x][y], entry->num_reg_ra_phy       );
186//                      PORT_WRITE(out_RETIRE_READ_RB               [x][y], entry->read_rb              );
187//                      PORT_WRITE(out_RETIRE_NUM_REG_RB_PHY        [x][y], entry->num_reg_rb_phy       );
188//                      PORT_WRITE(out_RETIRE_READ_RC               [x][y], entry->read_rc              );
189//                      PORT_WRITE(out_RETIRE_NUM_REG_RC_PHY        [x][y], entry->num_reg_rc_phy       );
190                        PORT_WRITE(out_RETIRE_WRITE_RD              [x][y], entry->write_rd             );
191                        PORT_WRITE(out_RETIRE_NUM_REG_RD_LOG        [x][y], entry->num_reg_rd_log       );
192                        PORT_WRITE(out_RETIRE_NUM_REG_RD_PHY_OLD    [x][y], entry->num_reg_rd_phy_old   );
193                        PORT_WRITE(out_RETIRE_NUM_REG_RD_PHY_NEW    [x][y], entry->num_reg_rd_phy_new   );
194                        PORT_WRITE(out_RETIRE_WRITE_RE              [x][y], write_re                    );
195                        PORT_WRITE(out_RETIRE_NUM_REG_RE_LOG        [x][y], num_reg_re_log              );
196                        PORT_WRITE(out_RETIRE_NUM_REG_RE_PHY_OLD    [x][y], entry->num_reg_re_phy_old   );
197                        PORT_WRITE(out_RETIRE_NUM_REG_RE_PHY_NEW    [x][y], entry->num_reg_re_phy_new   );
198                       
199                        // Event -> rob must be manage this event
200                        if ((state == ROB_END_BRANCH_MISS) or
201                            (state == ROB_END_LOAD_MISS))
202                          can_retire [x] = false;
203                      }
204
205                    log_printf(TRACE,Commit_unit,FUNCTION,"      * bypass (before)      : %d",bypass);
206
207                    bypass = ((state == ROB_END              ) or
208                              (state == ROB_STORE_OK         ) or
209                              (state == ROB_STORE_KO         ) or
210                              (state == ROB_STORE_OK_WAIT_END) or
211                              (state == ROB_STORE_KO_WAIT_END));
212
213                    log_printf(TRACE,Commit_unit,FUNCTION,"      * bypass (after)       : %d",bypass);
214                   
215                    uint32_t packet = ((entry->ptr << _param->_shift_num_slot) | num_bank);
216
217                    log_printf(TRACE,Commit_unit,FUNCTION,"      * packet               : %d",packet);
218                   
219                    // if future event, don't update after this event
220                    if ((reg_EVENT_STATE  [front_end_id][context_id] == COMMIT_EVENT_STATE_NOT_YET_EVENT) and
221                        (reg_EVENT_PACKET [front_end_id][context_id] == packet))
222                      {
223                        log_printf(TRACE,Commit_unit,FUNCTION,"      * is the event instruction, stop bypass !!!");
224                        bypass = false;
225                      }
226                  }
227               
228                // Retire "in-order"
229                can_retire [x]  &= (retire_val [x][y] or bypass);
230              }
231          }
232      }
233   
234    for (uint32_t i=0; i<_param->_nb_rename_unit; i++)
235      for (uint32_t j=0; j<_param->_nb_inst_retire[i]; j++)
236        PORT_WRITE(out_RETIRE_VAL [i][j],retire_val [i][j]);
237
238    for (uint32_t i=0; i<_param->_nb_front_end; ++i)
239      for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
240        {
241          PORT_WRITE(out_SPR_WRITE_VAL       [i][j], spr_write_val       [i][j]);
242          PORT_WRITE(out_SPR_WRITE_SR_F_VAL  [i][j], spr_write_sr_f_val  [i][j]);
243          PORT_WRITE(out_SPR_WRITE_SR_F      [i][j], spr_write_sr_f      [i][j]);
244          PORT_WRITE(out_SPR_WRITE_SR_CY_VAL [i][j], spr_write_sr_cy_val [i][j]);
245          PORT_WRITE(out_SPR_WRITE_SR_CY     [i][j], spr_write_sr_cy     [i][j]);
246          PORT_WRITE(out_SPR_WRITE_SR_OV_VAL [i][j], spr_write_sr_ov_val [i][j]);
247          PORT_WRITE(out_SPR_WRITE_SR_OV     [i][j], spr_write_sr_ov     [i][j]);
248        }
249      }
250    else
251      {
252        for (uint32_t i=0; i<_param->_nb_rename_unit; i++)
253          for (uint32_t j=0; j<_param->_nb_inst_retire[i]; j++)
254            PORT_WRITE(out_RETIRE_VAL [i][j],0);
255
256        for (uint32_t i=0; i<_param->_nb_front_end; ++i)
257          for (uint32_t j=0; j<_param->_nb_context[i]; ++j)
258            PORT_WRITE(out_SPR_WRITE_VAL [i][j], 0);
259      }
260
261    log_end(Commit_unit,FUNCTION);
262  };
263
264}; // end namespace commit_unit
265}; // end namespace ooo_engine
266}; // end namespace multi_ooo_engine
267}; // end namespace core
268}; // end namespace behavioural
269}; // end namespace morpheo             
270#endif
Note: See TracBrowser for help on using the repository browser.