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

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

1) Add soc test
2) fix bug (Pc management, Decod and execute, Update prediction ...)

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