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

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

1) Write_queue : fix multi write bug

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