source: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit/Address_management/src/Address_management_transition.cpp @ 132

Last change on this file since 132 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.8 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Address_management_transition.cpp 128 2009-06-26 08:43:23Z rosiere $
4 *
5 * [ Description ]
6 *
7 */
8
9#include "Behavioural/Core/Multi_Front_end/Front_end/Ifetch_unit/Address_management/include/Address_management.h"
10
11namespace morpheo                    {
12namespace behavioural {
13namespace core {
14namespace multi_front_end {
15namespace front_end {
16namespace ifetch_unit {
17namespace address_management {
18
19
20#undef  FUNCTION
21#define FUNCTION "Address_management::transition"
22  void Address_management::transition (void)
23  {
24    log_begin(Address_management,FUNCTION);
25    log_function(Address_management,FUNCTION,_name.c_str());
26
27    if (PORT_READ(in_NRESET) == 0)
28      {
29        // nothing is valid
30        reg_PC_ACCESS_VAL                               = 0;
31        reg_PC_ACCESS                                   = 0;// not necessary
32        reg_PC_ACCESS_IS_DS_TAKE                        = 0;// not necessary
33        for (uint32_t i=0; i<_param->_nb_instruction; i++)
34        reg_PC_ACCESS_INSTRUCTION_ENABLE [i]            = 0;// not necessary
35        reg_PC_ACCESS_INST_IFETCH_PTR                   = 0;// not necessary
36        reg_PC_ACCESS_BRANCH_STATE                      = 0;// not necessary
37        reg_PC_ACCESS_BRANCH_UPDATE_PREDICTION_ID       = 0;// not necessary
38
39        reg_PC_CURRENT_VAL                              = 0;
40        reg_PC_CURRENT                                  = 0;// not necessary
41        reg_PC_CURRENT_IS_DS_TAKE                       = 0;// not necessary
42        for (uint32_t i=0; i<_param->_nb_instruction; i++)
43        reg_PC_CURRENT_INSTRUCTION_ENABLE [i]           = 0;// not necessary
44        reg_PC_CURRENT_INST_IFETCH_PTR                  = 0;// not necessary
45        reg_PC_CURRENT_BRANCH_STATE                     = 0;// not necessary
46        reg_PC_CURRENT_BRANCH_UPDATE_PREDICTION_ID      = 0;// not necessary
47
48        reg_PC_NEXT_VAL                                 = 1;
49        reg_PC_NEXT                                     = 0x100>>2;
50        reg_PC_NEXT_IS_DS_TAKE                          = 0;
51        uint32_t index = reg_PC_NEXT % _param->_nb_instruction;
52        for (uint32_t i=0; i<_param->_nb_instruction; i++)
53        reg_PC_NEXT_INSTRUCTION_ENABLE [i]              = 0;
54        reg_PC_NEXT_INSTRUCTION_ENABLE [index]          = 1;
55        reg_PC_NEXT_INST_IFETCH_PTR                     = 0;
56        reg_PC_NEXT_BRANCH_STATE                        = 0;
57        reg_PC_NEXT_BRANCH_UPDATE_PREDICTION_ID         = 0;
58
59        reg_PC_NEXT_NEXT_VAL                            = 0;
60        reg_PC_NEXT_NEXT                                = 0;// not necessary
61        reg_PC_NEXT_NEXT_IS_DS_TAKE                     = 0;// not necessary
62      }
63    else
64      {
65        // =========================================
66        // ===== PREDICT ===========================
67        // =========================================
68        if (PORT_READ(in_PREDICT_ACK) and internal_PREDICT_VAL)
69          {
70            log_printf(TRACE,Address_management,FUNCTION,"  * PREDICT");
71
72            bool branch_is_current = reg_PC_NEXT_IS_DS_TAKE;
73            if (branch_is_current)
74              {
75                if (_param->_have_port_inst_ifetch_ptr)
76                reg_PC_CURRENT_INST_IFETCH_PTR             = PORT_READ(in_PREDICT_INST_IFETCH_PTR            );
77                reg_PC_CURRENT_BRANCH_STATE                = PORT_READ(in_PREDICT_BRANCH_STATE               );
78                if (_param->_have_port_depth)
79                reg_PC_CURRENT_BRANCH_UPDATE_PREDICTION_ID = PORT_READ(in_PREDICT_BRANCH_UPDATE_PREDICTION_ID);
80              }
81            else
82              {
83                if (_param->_have_port_inst_ifetch_ptr)
84                reg_PC_NEXT_INST_IFETCH_PTR                = PORT_READ(in_PREDICT_INST_IFETCH_PTR            );
85                reg_PC_NEXT_BRANCH_STATE                   = PORT_READ(in_PREDICT_BRANCH_STATE               );
86                if (_param->_have_port_depth)
87                reg_PC_NEXT_BRANCH_UPDATE_PREDICTION_ID    = PORT_READ(in_PREDICT_BRANCH_UPDATE_PREDICTION_ID);
88              }
89
90            for (uint32_t i=0; i<_param->_nb_instruction; i++)
91            reg_PC_NEXT_INSTRUCTION_ENABLE [i] = PORT_READ(in_PREDICT_INSTRUCTION_ENABLE [i]);
92           
93            reg_PC_NEXT_NEXT_VAL                    = 1; // address is valid
94            reg_PC_NEXT_NEXT                        = PORT_READ(in_PREDICT_PC_NEXT                    );
95            reg_PC_NEXT_NEXT_IS_DS_TAKE             = PORT_READ(in_PREDICT_PC_NEXT_IS_DS_TAKE         );
96
97#ifdef STATISTICS
98            if (usage_is_set(_usage,USE_STATISTICS))
99              (*_stat_nb_transaction_predict) ++;
100#endif
101          }
102
103        // =========================================
104        // ===== ADDRESS ===========================
105        // =========================================
106        // transaction with icache
107        if (internal_ADDRESS_VAL and PORT_READ(in_ADDRESS_ACK))
108          {
109
110            reg_PC_ACCESS_VAL = 0;
111#ifdef STATISTICS
112            if (usage_is_set(_usage,USE_STATISTICS))
113              {
114                  (*_stat_nb_transaction_address) ++;
115                 
116                  for (uint32_t i=0; i<_param->_nb_instruction; i++)
117                    if (reg_PC_ACCESS_INSTRUCTION_ENABLE [i] == true)
118                      (*_stat_sum_packet_size) ++;
119                }
120#endif
121          }
122
123        // =========================================
124        // ===== Shift Register ====================
125        // =========================================
126       
127        // Shift register
128        if (reg_PC_NEXT_NEXT_VAL and reg_PC_NEXT_VAL and reg_PC_CURRENT_VAL and not reg_PC_ACCESS_VAL)
129          {
130            log_printf(TRACE,Address_management,FUNCTION,"  * New PC_ACCESS");
131
132            reg_PC_ACCESS_VAL  = 1; // new request
133            reg_PC_CURRENT_VAL = 0; // invalid current
134           
135            reg_PC_ACCESS                             = reg_PC_CURRENT                            ;
136            reg_PC_ACCESS_IS_DS_TAKE                  = reg_PC_CURRENT_IS_DS_TAKE                 ;
137            reg_PC_ACCESS_INST_IFETCH_PTR             = reg_PC_CURRENT_INST_IFETCH_PTR            ;
138            reg_PC_ACCESS_BRANCH_STATE                = reg_PC_CURRENT_BRANCH_STATE               ;
139            reg_PC_ACCESS_BRANCH_UPDATE_PREDICTION_ID = reg_PC_CURRENT_BRANCH_UPDATE_PREDICTION_ID;
140           
141            for (uint32_t i=0; i<_param->_nb_instruction; i++)
142              reg_PC_ACCESS_INSTRUCTION_ENABLE [i] = reg_PC_CURRENT_INSTRUCTION_ENABLE [i];
143          }
144       
145//      if (not reg_PC_CURRENT_VAL and reg_PC_NEXT_VAL)
146        if (reg_PC_NEXT_NEXT_VAL and reg_PC_NEXT_VAL and not reg_PC_CURRENT_VAL)
147          {
148            log_printf(TRACE,Address_management,FUNCTION,"  * New PC_CURRENT");
149
150            reg_PC_CURRENT_VAL = 1; // new PC_CURRENT if PC_NEXT is valid
151            reg_PC_NEXT_VAL    = 0; // invalid next
152
153            reg_PC_CURRENT                             = reg_PC_NEXT                            ;
154            reg_PC_CURRENT_IS_DS_TAKE                  = reg_PC_NEXT_IS_DS_TAKE                 ;
155            reg_PC_CURRENT_INST_IFETCH_PTR             = reg_PC_NEXT_INST_IFETCH_PTR            ;
156            reg_PC_CURRENT_BRANCH_STATE                = reg_PC_NEXT_BRANCH_STATE               ;
157            reg_PC_CURRENT_BRANCH_UPDATE_PREDICTION_ID = reg_PC_NEXT_BRANCH_UPDATE_PREDICTION_ID;
158           
159            for (uint32_t i=0; i<_param->_nb_instruction; i++)
160              reg_PC_CURRENT_INSTRUCTION_ENABLE [i] = reg_PC_NEXT_INSTRUCTION_ENABLE [i];
161          }
162
163//      if (not reg_PC_NEXT_VAL and reg_PC_NEXT_NEXT_VAL)
164        if (reg_PC_NEXT_NEXT_VAL and not reg_PC_NEXT_VAL)
165          {
166            log_printf(TRACE,Address_management,FUNCTION,"  * New PC_NEXT");
167
168            reg_PC_NEXT_VAL      = 1; // new PC_NEXT if PC_NEXT_NEXT is valid
169            reg_PC_NEXT_NEXT_VAL = 0; // invalid next_next
170           
171            reg_PC_NEXT                             = reg_PC_NEXT_NEXT                            ;
172            reg_PC_NEXT_IS_DS_TAKE                  = reg_PC_NEXT_NEXT_IS_DS_TAKE                 ;
173//          reg_PC_NEXT_INST_IFETCH_PTR             = reg_PC_NEXT_NEXT_INST_IFETCH_PTR            ;
174//          reg_PC_NEXT_BRANCH_STATE                = reg_PC_NEXT_NEXT_BRANCH_STATE               ;
175//          reg_PC_NEXT_BRANCH_UPDATE_PREDICTION_ID = reg_PC_NEXT_NEXT_BRANCH_UPDATE_PREDICTION_ID;
176           
177//          for (uint32_t i=0; i<_param->_nb_instruction; i++)
178//            reg_PC_NEXT_INSTRUCTION_ENABLE [i] = reg_PC_NEXT_NEXT_INSTRUCTION_ENABLE [i];
179          }
180
181        // =========================================
182        // ===== EVENT =============================
183        // =========================================
184
185        // Event is after shift register : because, it's to write in pc_next and in not pc_current
186
187        if (PORT_READ(in_EVENT_VAL) and internal_EVENT_ACK)
188          {
189            log_printf(TRACE,Address_management,FUNCTION,"  * EVENT : Transaction");
190            log_printf(TRACE,Address_management,FUNCTION,"    * IS_DS_TAKE       : %d"  ,PORT_READ(in_EVENT_IS_DS_TAKE      ));
191            log_printf(TRACE,Address_management,FUNCTION,"    * ADDRESS          : %.8x (%.8x)",PORT_READ(in_EVENT_ADDRESS         ),PORT_READ(in_EVENT_ADDRESS         )<<2);
192            log_printf(TRACE,Address_management,FUNCTION,"    * ADDRESS_NEXT     : %.8x (%.8x)",PORT_READ(in_EVENT_ADDRESS_NEXT    ),PORT_READ(in_EVENT_ADDRESS_NEXT    )<<2);
193            log_printf(TRACE,Address_management,FUNCTION,"    * ADDRESS_NEXT_VAL : %d"  ,PORT_READ(in_EVENT_ADDRESS_NEXT_VAL));
194
195            reg_PC_ACCESS_VAL                       = 0;
196            reg_PC_CURRENT_VAL                      = 0;
197            reg_PC_NEXT_VAL                         = 1;
198            reg_PC_NEXT                             = PORT_READ(in_EVENT_ADDRESS);
199            // Event is never is ds_take :
200            //  * branch miss speculation : can't be place a branch in delay slot
201            //  * load   miss speculation : the load is execute, the event_address is the next address (also the destination of branch)
202            //  * exception               : goto the first instruction of exception handler (also is not in delay slot).
203
204            reg_PC_NEXT_IS_DS_TAKE                  = PORT_READ(in_EVENT_IS_DS_TAKE);
205//          reg_PC_NEXT_INST_IFETCH_PTR             = 0;
206            reg_PC_NEXT_BRANCH_STATE                = BRANCH_STATE_NONE;
207//          reg_PC_NEXT_BRANCH_UPDATE_PREDICTION_ID = 0;
208           
209            // only the instruction at the event address is valid, because we have no information on the branch presence in the instruction bundle.
210            uint32_t index = reg_PC_NEXT % _param->_nb_instruction;
211            for (uint32_t i=0; i<_param->_nb_instruction; i++)
212            reg_PC_NEXT_INSTRUCTION_ENABLE [i]      = 0;
213            reg_PC_NEXT_INSTRUCTION_ENABLE [index]  = 1;
214
215            reg_PC_NEXT_NEXT_VAL                    = PORT_READ(in_EVENT_ADDRESS_NEXT_VAL);
216            reg_PC_NEXT_NEXT                        = PORT_READ(in_EVENT_ADDRESS_NEXT);
217            reg_PC_NEXT_NEXT_IS_DS_TAKE             = 0;//??
218
219            // Note : is_ds_take = address_next_val
220            // Because, is not ds take, can continue in sequence
221
222// #ifdef DEBUG_TEST
223//             if (PORT_READ(in_EVENT_ADDRESS_NEXT_VAL) and not PORT_READ(in_EVENT_IS_DS_TAKE))
224//               throw ERRORMORPHEO(FUNCTION,_("Event : address_next_next_val but next is not a ds take"));
225// #endif
226
227#ifdef STATISTICS
228            if (usage_is_set(_usage,USE_STATISTICS))
229              (*_stat_nb_transaction_event) ++;
230#endif
231          }
232      }
233
234#if defined(DEBUG) and DEBUG_Address_management and (DEBUG >= DEBUG_TRACE)
235    log_printf(TRACE,Address_management,FUNCTION,"  * Dump PC");
236    {
237      std::string instruction_enable;
238      for (uint32_t i=0; i<_param->_nb_instruction; ++i)
239        instruction_enable += ((reg_PC_ACCESS_VAL)?(toString(reg_PC_ACCESS_INSTRUCTION_ENABLE [i])):"X") + " ";
240
241      log_printf(TRACE,Address_management,FUNCTION,"    * Access    : %d %d 0x%.8x (%.8x) - %.2d %.2d %.2d - %s",
242                 reg_PC_ACCESS_VAL,
243                 reg_PC_ACCESS_IS_DS_TAKE,
244                 reg_PC_ACCESS,
245                 reg_PC_ACCESS<<2,
246                 reg_PC_ACCESS_BRANCH_STATE,
247                 reg_PC_ACCESS_INST_IFETCH_PTR,
248                 reg_PC_ACCESS_BRANCH_UPDATE_PREDICTION_ID,
249                 instruction_enable.c_str()
250                 );
251    }
252    {
253      std::string instruction_enable;
254      for (uint32_t i=0; i<_param->_nb_instruction; ++i)
255        instruction_enable += ((reg_PC_CURRENT_VAL)?(toString(reg_PC_CURRENT_INSTRUCTION_ENABLE [i])):"X") + " ";
256
257      log_printf(TRACE,Address_management,FUNCTION,"    * Current   : %d %d 0x%.8x (%.8x) - %.2d %.2d %.2d - %s",
258                 reg_PC_CURRENT_VAL,
259                 reg_PC_CURRENT_IS_DS_TAKE,
260                 reg_PC_CURRENT,
261                 reg_PC_CURRENT<<2,
262                 reg_PC_CURRENT_BRANCH_STATE,
263                 reg_PC_CURRENT_INST_IFETCH_PTR,
264                 reg_PC_CURRENT_BRANCH_UPDATE_PREDICTION_ID,
265                 instruction_enable.c_str()
266                 );
267    }
268    {
269      std::string instruction_enable;
270      for (uint32_t i=0; i<_param->_nb_instruction; ++i)
271        instruction_enable += ((reg_PC_NEXT_VAL)?(toString(reg_PC_NEXT_INSTRUCTION_ENABLE [i])):"X") + " ";
272
273      log_printf(TRACE,Address_management,FUNCTION,"    * Next      : %d %d 0x%.8x (%.8x) - %.2d %.2d %.2d - %s",
274                 reg_PC_NEXT_VAL,
275                 reg_PC_NEXT_IS_DS_TAKE,
276                 reg_PC_NEXT,
277                 reg_PC_NEXT<<2,
278                 reg_PC_NEXT_BRANCH_STATE,
279                 reg_PC_NEXT_INST_IFETCH_PTR,
280                 reg_PC_NEXT_BRANCH_UPDATE_PREDICTION_ID,
281                 instruction_enable.c_str());
282    }
283    log_printf(TRACE,Address_management,FUNCTION,"    * Next_Next : %d %d 0x%.8x (%.8x)",
284               reg_PC_NEXT_NEXT_VAL,
285               reg_PC_NEXT_NEXT_IS_DS_TAKE,
286               reg_PC_NEXT_NEXT,
287               reg_PC_NEXT_NEXT<<2);   
288#endif
289
290#if defined(STATISTICS) or defined(VHDL_TESTBENCH)
291    end_cycle ();
292#endif
293   
294    log_end(Address_management,FUNCTION);
295  };
296
297}; // end namespace address_management
298}; // end namespace ifetch_unit
299}; // end namespace front_end
300}; // end namespace multi_front_end
301}; // end namespace core
302
303}; // end namespace behavioural
304}; // end namespace morpheo             
305#endif
Note: See TracBrowser for help on using the repository browser.