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