source: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Decod_unit/Decod/src/Decod_genMealy.cpp @ 136

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

1) Add new algo in ifetch queue
2) Add Cancel bit
3) new config

  • Property svn:keywords set to Id
File size: 17.4 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Decod_genMealy.cpp 136 2009-10-20 18:52:15Z rosiere $
4 *
5 * [ Description ]
6 *
7 */
8
9#include "Behavioural/Core/Multi_Front_end/Front_end/Decod_unit/Decod/include/Decod.h"
10
11namespace morpheo                    {
12namespace behavioural {
13namespace core {
14namespace multi_front_end {
15namespace front_end {
16namespace decod_unit {
17namespace decod {
18
19
20#undef  FUNCTION
21#define FUNCTION "Decod::genMealy"
22  void Decod::genMealy (void)
23  {
24    log_begin(Decod,FUNCTION);
25    log_function(Decod,FUNCTION,_name.c_str());
26
27    if (PORT_READ(in_NRESET))
28      {
29    //-----------------------------------
30    // Initialization
31    //-----------------------------------
32    Tcontrol_t context_event_val = false;
33    Tcontrol_t ifetch_ack [_param->_nb_context][_param->_max_nb_inst_fetch];
34    for (uint32_t i=0; i<_param->_nb_context; i++)
35      for (uint32_t j=0; j<_param->_nb_inst_fetch[i]; j++)
36        ifetch_ack [i][j] = false;
37
38    Tcontrol_t predict_val [_param->_nb_inst_decod];
39    Tcontrol_t decod_val   [_param->_nb_inst_decod];
40    for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
41      {
42        decod_val   [i] = false;
43        predict_val [i] = false;
44      }
45
46    Tcontrol_t can_continue      [_param->_nb_context];
47    Tcontrol_t have_decod_branch [_param->_nb_context];
48
49    Tcontext_t      CONTEXT_EVENT_CONTEXT_ID    = 0;
50    Tdepth_t        CONTEXT_EVENT_DEPTH         = 0;
51    Tevent_type_t   CONTEXT_EVENT_TYPE          = 0;
52    Tcontrol_t      CONTEXT_EVENT_IS_DELAY_SLOT = 0;
53    Tgeneral_data_t CONTEXT_EVENT_ADDRESS       = 0;
54    Tgeneral_data_t CONTEXT_EVENT_ADDRESS_EPCR  = 0;
55
56    for (uint32_t i=0; i<_param->_nb_context; i++)
57      {
58        internal_CONTEXT_HAVE_TRANSACTION [i] = false;
59        internal_CONTEXT_ADDRESS_PREVIOUS [i] = reg_CONTEXT_ADDRESS_PREVIOUS [i];
60        internal_CONTEXT_IS_DELAY_SLOT    [i] = reg_CONTEXT_IS_DELAY_SLOT    [i];
61       
62        can_continue                      [i] = PORT_READ(in_CONTEXT_DECOD_ENABLE [i]);
63        have_decod_branch                 [i] = false;
64      }
65   
66    //-----------------------------------
67    // Loop of decod
68    //-----------------------------------
69    // scan all decod "slot_out"
70    std::list<generic::priority::select_t> * select = _priority->select();
71    std::list<generic::priority::select_t>::iterator it=select->begin();
72    for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
73      {
74        log_printf(TRACE,Decod,FUNCTION,"  * DECOD [%d]",i);   
75
76        bool ifetch_val = false;
77        while ((it != select->end())    and  // have a no scanned "slot_in" ?
78//             (decod_val [i] == false) and  // have not a previous selected entry?
79               (ifetch_val    == false) and  // not find ifetch instruction valid
80               (context_event_val == false)) // Have not a context_event (spr_access, exception, ...)
81          {
82//          predict_val [i] = false;
83
84            Tcontext_t x = it->grp;
85            uint32_t   y = it->elt;
86
87            log_printf(TRACE,Decod,FUNCTION,"    * IFETCH [%d][%d]",x,y);   
88            log_printf(TRACE,Decod,FUNCTION,"      * in_IFETCH_VAL          : %d",PORT_READ(in_IFETCH_VAL [x][y]));
89            log_printf(TRACE,Decod,FUNCTION,"      * can_continue           : %d",can_continue [x]               );
90
91            // Test if this instruction is valid
92            if ((PORT_READ(in_IFETCH_VAL [x][y]) == 1) and // entry is valid
93                (can_continue [x]                == 1))    // context can decod instruction (have not a previous event)
94              {
95                log_printf(TRACE,Decod,FUNCTION,"      * decod_ack              : %d",PORT_READ(in_DECOD_ACK [i]));
96
97                ifetch_val        = true;
98                decod_val  [i]    = true;                        // fetch_val and decod_enable
99                ifetch_ack [x][y] = PORT_READ(in_DECOD_ACK [i]); // fetch_val and decod_enable and decod_ack
100
101                Tgeneral_data_t addr = PORT_READ(in_IFETCH_ADDRESS [x][y]);
102
103                _decod_instruction->_instruction        = PORT_READ(in_IFETCH_INSTRUCTION [x][y]);
104                _decod_instruction->_context_id         = x;
105                _decod_instruction->_address_previous   = internal_CONTEXT_ADDRESS_PREVIOUS [x];
106                _decod_instruction->_address            = addr; //Compute the current address
107                _decod_instruction->_address_next       = addr+1;
108                _decod_instruction->_is_delay_slot      = internal_CONTEXT_IS_DELAY_SLOT [x];
109                _decod_instruction->_type               = 0; // not necessary
110                _decod_instruction->_operation          = 0; // not necessary
111                _decod_instruction->_no_execute         = 0; // not necessary
112                _decod_instruction->_has_immediat       = 0; // not necessary
113                _decod_instruction->_immediat           = 0; // not necessary
114                _decod_instruction->_read_ra            = 0; // not necessary
115                _decod_instruction->_num_reg_ra         = 0; // not necessary
116                _decod_instruction->_read_rb            = 0; // not necessary
117                _decod_instruction->_num_reg_rb         = 0; // not necessary
118                _decod_instruction->_read_rc            = 0; // not necessary
119                _decod_instruction->_num_reg_rc         = 0; // not necessary
120                _decod_instruction->_write_rd           = 0; // not necessary
121                _decod_instruction->_num_reg_rd         = 0; // not necessary
122                _decod_instruction->_write_re           = 0; // not necessary
123                _decod_instruction->_num_reg_re         = 0; // not necessary
124                _decod_instruction->_exception_use      = EXCEPTION_USE_NONE; // not necessary
125                _decod_instruction->_exception          = EXCEPTION_DECOD_NONE; // not necessary
126                _decod_instruction->_branch_condition   = 0; // not necessary
127//              _decod_instruction->_branch_stack_write = 0; // not necessary
128                _decod_instruction->_branch_direction   = 0; // not necessary
129                _decod_instruction->_event_type         = EVENT_TYPE_NONE; // not necessary
130               
131
132
133                // Test IFetch exception
134                Texception_t ifetch_exception = PORT_READ(in_IFETCH_EXCEPTION [x][y]);
135
136                if (ifetch_exception == EXCEPTION_IFETCH_NONE)
137                  {
138                    // Decod !
139                    log_printf(TRACE,Decod,FUNCTION,"      * address                : %.8x (%.8x)",addr,(addr<<2));
140                    log_printf(TRACE,Decod,FUNCTION,"      * is_delay_slot          : %d",internal_CONTEXT_IS_DELAY_SLOT [x]);
141                   
142                    instruction_decod (_decod_instruction, _decod_param[x]);
143
144                    log_printf(TRACE,Decod,FUNCTION,"      * address_next           : %.8x (%.8x)",_decod_instruction->_address_next,(_decod_instruction->_address_next<<2));
145                  }
146                else
147                  {
148                    // No decod : nop
149                    instruction_l_nop (_decod_instruction, _decod_param[x]);
150
151                    _decod_instruction->_exception_use = EXCEPTION_USE_NONE;
152                    _decod_instruction->_exception     = exception_ifetch_to_exception_decod(ifetch_exception);
153                   
154                    // INSTRUCTION_TLB 
155                    // INSTRUCTION_PAGE
156                    // BUS_ERROR       
157                    if (_decod_instruction->_is_delay_slot)
158                      _decod_instruction->_address_next       = _decod_instruction->_address_previous;
159                    else
160                      _decod_instruction->_address_next       = _decod_instruction->_address;
161                   
162                    _decod_instruction->_event_type         = EVENT_TYPE_EXCEPTION;
163                  }
164
165                Ttype_t      type      = _decod_instruction->_type;
166                // Depth current. If have decod a branch and i can continue : depth = depth_next
167                Tdepth_t     depth     = (_param->_have_port_depth)?PORT_READ(in_CONTEXT_DEPTH [x]):0;
168
169                if ((_param->_nb_branch_speculated[x] > 0) and have_decod_branch [x])
170                  depth = (depth+1)%_param->_nb_branch_speculated[x];
171               
172                if (_param->_have_port_context_id)
173                PORT_WRITE(out_DECOD_CONTEXT_ID    [i], x);
174                if (_param->_have_port_depth)
175                PORT_WRITE(out_DECOD_DEPTH         [i], depth);
176                PORT_WRITE(out_DECOD_TYPE          [i], type);
177                PORT_WRITE(out_DECOD_OPERATION     [i], _decod_instruction->_operation     );
178                PORT_WRITE(out_DECOD_NO_EXECUTE    [i], _decod_instruction->_no_execute    );
179                PORT_WRITE(out_DECOD_IS_DELAY_SLOT [i], _decod_instruction->_is_delay_slot );
180#ifdef DEBUG
181                PORT_WRITE(out_DECOD_ADDRESS       [i], addr);
182#endif
183//                 if ((type == TYPE_BRANCH) and
184//                     ((_decod_instruction->_branch_condition = BRANCH_CONDITION_FLAG_SET) or
185//                      (_decod_instruction->_branch_condition = BRANCH_CONDITION_FLAG_UNSET)))
186//                 PORT_WRITE(out_DECOD_ADDRESS_NEXT  [i], _decod_instruction->_address+2);
187//                 else
188                PORT_WRITE(out_DECOD_ADDRESS_NEXT  [i], _decod_instruction->_address_next  );
189                PORT_WRITE(out_DECOD_HAS_IMMEDIAT  [i], _decod_instruction->_has_immediat  );
190                PORT_WRITE(out_DECOD_IMMEDIAT      [i], _decod_instruction->_immediat      );
191                PORT_WRITE(out_DECOD_READ_RA       [i], _decod_instruction->_read_ra       );
192                PORT_WRITE(out_DECOD_NUM_REG_RA    [i], _decod_instruction->_num_reg_ra    );
193                PORT_WRITE(out_DECOD_READ_RB       [i], _decod_instruction->_read_rb       );
194                PORT_WRITE(out_DECOD_NUM_REG_RB    [i], _decod_instruction->_num_reg_rb    );
195                PORT_WRITE(out_DECOD_READ_RC       [i], _decod_instruction->_read_rc       );
196                PORT_WRITE(out_DECOD_NUM_REG_RC    [i], _decod_instruction->_num_reg_rc    );
197                PORT_WRITE(out_DECOD_WRITE_RD      [i],(_decod_instruction->_num_reg_rd!=0)?_decod_instruction->_write_rd:0);
198                PORT_WRITE(out_DECOD_NUM_REG_RD    [i], _decod_instruction->_num_reg_rd    );
199                PORT_WRITE(out_DECOD_WRITE_RE      [i], _decod_instruction->_write_re      );
200                PORT_WRITE(out_DECOD_NUM_REG_RE    [i], _decod_instruction->_num_reg_re    );
201                PORT_WRITE(out_DECOD_EXCEPTION_USE [i], _decod_instruction->_exception_use );
202                PORT_WRITE(out_DECOD_EXCEPTION     [i], _decod_instruction->_exception     );
203
204                // Branch predictor can accept : the depth is valid
205                log_printf(TRACE,Decod,FUNCTION,"      * context_depth_val      : %d",PORT_READ(in_CONTEXT_DEPTH_VAL [x]));
206
207                decod_val   [i]    &= PORT_READ(in_CONTEXT_DEPTH_VAL [x]);
208                ifetch_ack  [x][y] &= PORT_READ(in_CONTEXT_DEPTH_VAL [x]);
209
210                if (type == TYPE_BRANCH)
211                  {
212                    log_printf(TRACE,Decod,FUNCTION,"      * Instruction is branch");
213                    log_printf(TRACE,Decod,FUNCTION,"        * predict_val       : %d",ifetch_ack [x][y]);
214                    log_printf(TRACE,Decod,FUNCTION,"        * predict_ack       : %d",PORT_READ(in_PREDICT_ACK [i]));
215                                                         
216                    log_printf(TRACE,Decod,FUNCTION,"        * address src       : %.8x (%.8x)",_decod_instruction->_address     ,_decod_instruction->_address     <<2);
217                    log_printf(TRACE,Decod,FUNCTION,"        * address dest      : %.8x (%.8x)",_decod_instruction->_address_next,_decod_instruction->_address_next<<2);
218                   
219                    // test if have already decod an branch : one branch per context
220                    predict_val [i]     = not have_decod_branch [x] and ifetch_ack  [x][y] // and decod_val [i]
221                      ;
222                    decod_val   [i]    &= not have_decod_branch [x] and PORT_READ(in_PREDICT_ACK [i]);// predict_ack and fetch_val and decod_enable                 
223                    ifetch_ack  [x][y] &= not have_decod_branch [x] and PORT_READ(in_PREDICT_ACK [i]);// predict_ack and fetch_val and decod_enable and decod_ack
224               
225                    // can continue is set if direction is "not take" (also, continue is sequential order)
226
227//                  can_continue [x] = false; // one branch per context, the DS don't execute
228                    can_continue [x]&= PORT_READ(in_PREDICT_CAN_CONTINUE [i]); // one branch per context, the DS don't execute
229                    have_decod_branch [x] = true;
230                   
231                    log_printf(TRACE,Decod,FUNCTION,"      * predict_can_continue   : %d",PORT_READ(in_PREDICT_CAN_CONTINUE [i]));
232                  }
233
234                Tbranch_state_t ifetch_branch_state = PORT_READ(in_IFETCH_BRANCH_STATE [x][y]);
235                if (_param->_have_port_context_id)
236                PORT_WRITE(out_PREDICT_CONTEXT_ID                  [i],x);
237//              PORT_WRITE(out_PREDICT_MATCH_INST_IFETCH_PTR       [i],y == ((_param->_have_port_inst_ifetch_ptr)?PORT_READ(in_IFETCH_INST_IFETCH_PTR [x]):0));
238                PORT_WRITE(out_PREDICT_MATCH_INST_IFETCH_PTR       [i],ifetch_branch_state != BRANCH_STATE_NONE);
239
240                PORT_WRITE(out_PREDICT_BRANCH_STATE                [i],ifetch_branch_state);
241                if (_param->_have_port_depth)
242                PORT_WRITE(out_PREDICT_BRANCH_UPDATE_PREDICTION_ID [i],PORT_READ(in_IFETCH_BRANCH_UPDATE_PREDICTION_ID [x][y]));
243                PORT_WRITE(out_PREDICT_BRANCH_CONDITION            [i],_decod_instruction->_branch_condition  );
244//              PORT_WRITE(out_PREDICT_BRANCH_STACK_WRITE          [i],_decod_instruction->_branch_stack_write);
245                PORT_WRITE(out_PREDICT_BRANCH_DIRECTION            [i],_decod_instruction->_branch_direction  );
246                PORT_WRITE(out_PREDICT_ADDRESS_SRC                 [i],_decod_instruction->_address           );
247                PORT_WRITE(out_PREDICT_ADDRESS_DEST                [i],_decod_instruction->_address_next      );
248
249                Tevent_type_t event_type = _decod_instruction->_event_type;
250                if (event_type != EVENT_TYPE_NONE)
251                  {
252                    log_printf(TRACE,Decod,FUNCTION,"      * Instruction make an EVENT (%s)",toString(event_type).c_str());
253                    log_printf(TRACE,Decod,FUNCTION,"        * context_event_ack : %d",PORT_READ(in_CONTEXT_EVENT_ACK));
254
255                    // speculative jump at the exception handler
256                    // if type = TYPE_BRANCH, also event_type == EVENT_TYPE_NONE
257                    context_event_val   = ifetch_ack  [x][y] // and decod_val [i]
258                      ;
259                    decod_val   [i]    &= PORT_READ(in_CONTEXT_EVENT_ACK);// context_event_ack and fetch_val and decod_enable             
260                    ifetch_ack  [x][y] &= PORT_READ(in_CONTEXT_EVENT_ACK);// context_event_ack and fetch_val and decod_enable and decod_ack
261
262                    CONTEXT_EVENT_CONTEXT_ID    = x;
263                    CONTEXT_EVENT_DEPTH         = depth;
264                    CONTEXT_EVENT_TYPE          = _decod_instruction->_event_type;
265                    CONTEXT_EVENT_IS_DELAY_SLOT = _decod_instruction->_is_delay_slot;
266                    CONTEXT_EVENT_ADDRESS       = _decod_instruction->_address;
267                    CONTEXT_EVENT_ADDRESS_EPCR  = _decod_instruction->_address_next ;
268               
269                  }
270
271                // fetch_ack =
272                //   ((event_type == EVENT_TYPE_NONE) or ((event_type != EVENT_TYPE_NONE) and context_event_ack)) and
273                //   ((type       == TYPE_BRANCH    ) or ((type       != TYPE_BRANCH    ) and predict_ack      )) and
274                //   fetch_val and decod_ack and decod_enable and true (is decod_val)
275
276                // To compute the "next previous" address
277                Tcontrol_t have_transaction = ifetch_ack [x][y];
278
279                internal_CONTEXT_HAVE_TRANSACTION [x] |= have_transaction;
280                if (have_transaction)
281                  {
282                    internal_CONTEXT_ADDRESS_PREVIOUS [x] = addr;
283                    internal_CONTEXT_IS_DELAY_SLOT    [x] = (type == TYPE_BRANCH); // next is a delay slot if current have branch type
284                  }
285
286                can_continue [x] &= have_transaction; // to have a in order decod !!! if a previous instruction can decod, also next instruction can't decod.
287
288                log_printf(TRACE,Decod,FUNCTION,"      * have_transaction       : %d",have_transaction);
289
290              }
291
292            log_printf(TRACE,Decod,FUNCTION,"    - num_(decod, context, fetch) : %d %d %d",i, x, y);
293            log_printf(TRACE,Decod,FUNCTION,"      - ifetch_ack             : %d",ifetch_ack  [x][y]);
294            log_printf(TRACE,Decod,FUNCTION,"      - context_event_val      : %d",context_event_val );
295            log_printf(TRACE,Decod,FUNCTION,"      - predict_val            : %d",predict_val [i]   );
296            log_printf(TRACE,Decod,FUNCTION,"      - decod_val              : %d",decod_val   [i]   );
297           
298            it ++;
299          }
300      }
301
302    //-----------------------------------
303    // Write output
304    //-----------------------------------
305
306    for (uint32_t i=0; i<_param->_nb_context; i++)
307      for (uint32_t j=0; j<_param->_nb_inst_fetch[i]; j++)
308        PORT_WRITE(out_IFETCH_ACK [i][j], ifetch_ack [i][j]);
309
310    PORT_WRITE(out_CONTEXT_EVENT_VAL, context_event_val);
311    if (_param->_have_port_context_id)
312    PORT_WRITE(out_CONTEXT_EVENT_CONTEXT_ID   , CONTEXT_EVENT_CONTEXT_ID   );
313    if (_param->_have_port_depth)
314    PORT_WRITE(out_CONTEXT_EVENT_DEPTH        , CONTEXT_EVENT_DEPTH        );
315    PORT_WRITE(out_CONTEXT_EVENT_TYPE         , CONTEXT_EVENT_TYPE         );
316    PORT_WRITE(out_CONTEXT_EVENT_IS_DELAY_SLOT, CONTEXT_EVENT_IS_DELAY_SLOT);
317    PORT_WRITE(out_CONTEXT_EVENT_ADDRESS      , CONTEXT_EVENT_ADDRESS      );
318    PORT_WRITE(out_CONTEXT_EVENT_ADDRESS_EPCR , CONTEXT_EVENT_ADDRESS_EPCR );
319
320    for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
321      {
322        PORT_WRITE(out_PREDICT_VAL [i], predict_val [i]);
323        PORT_WRITE(out_DECOD_VAL   [i], decod_val   [i]);
324       
325#ifdef STATISTICS
326        internal_DECOD_VAL [i] = decod_val [i];
327#endif
328      }
329      }
330    else
331      {
332    for (uint32_t i=0; i<_param->_nb_context; i++)
333      {
334        internal_CONTEXT_HAVE_TRANSACTION [i] = false;
335//      internal_CONTEXT_ADDRESS_PREVIOUS [i] = reg_CONTEXT_ADDRESS_PREVIOUS [i];
336//      internal_CONTEXT_IS_DELAY_SLOT    [i] = reg_CONTEXT_IS_DELAY_SLOT    [i];
337      for (uint32_t j=0; j<_param->_nb_inst_fetch[i]; j++)
338        PORT_WRITE(out_IFETCH_ACK [i][j], 0);
339      }
340
341    PORT_WRITE(out_CONTEXT_EVENT_VAL, 0);
342
343    for (uint32_t i=0; i<_param->_nb_inst_decod; i++)
344      {
345        PORT_WRITE(out_PREDICT_VAL [i], 0);
346        PORT_WRITE(out_DECOD_VAL   [i], 0);
347
348#ifdef STATISTICS
349        internal_DECOD_VAL [i] = 0;
350#endif
351      }
352      }
353
354    log_end(Decod,FUNCTION);
355  };
356
357}; // end namespace decod
358}; // end namespace decod_unit
359}; // end namespace front_end
360}; // end namespace multi_front_end
361}; // end namespace core
362
363}; // end namespace behavioural
364}; // end namespace morpheo             
365#endif
Note: See TracBrowser for help on using the repository browser.