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

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

1) Prediction unit : static prediction not blocking

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