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

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

1) Fix test in Direction_Glue for Conditionnal Branch
2) Fix Instruction Address Compute

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