source: trunk/IPs/systemC/processor/Morpheo/Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/src/Load_store_unit_function_speculative_load_access_transition.cpp @ 138

Last change on this file since 138 was 138, checked in by rosiere, 14 years ago

1) add counters_t type for interface
2) fix in check load in load_store_unit
3) add parameters (but not yet implemented)
4) change environment and add script (distcc_env.sh ...)
5) add warning if an unser change rename flag with l.mtspr instruction
6) ...

  • Property svn:keywords set to Id
File size: 67.1 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Load_store_unit_function_speculative_load_access_transition.cpp 138 2010-05-12 17:34:01Z rosiere $
4 *
5 * [ Description ]
6 *
7 */
8
9#include "Behavioural/Core/Multi_Execute_loop/Execute_loop/Multi_Execute_unit/Execute_unit/Load_store_unit/include/Load_store_unit.h"
10#include "Behavioural/include/Identification.h"
11
12namespace morpheo                    {
13namespace behavioural {
14namespace core {
15namespace multi_execute_loop {
16namespace execute_loop {
17namespace multi_execute_unit {
18namespace execute_unit {
19namespace load_store_unit {
20
21template <typename T>
22T swapBytes (T data, uint32_t size_data, uint32_t size_access)
23{
24  uint64_t x = static_cast<uint64_t>(data);
25
26//   switch (size_data)
27//     {
28//     case 2 : // 16 bits
29//       {
30//         switch (size_access)
31//           {
32//           case 2 :
33//             {
34//               x = ((((x>> 8)&0xff) <<  0) |
35//                    (((x>> 0)&0xff) <<  8) );
36//               break;
37//             }
38//           default :
39//             {
40//               break;
41//             }
42//           }
43//         break;
44//       }
45//     case 4 : // 32 bits
46//       {
47//         switch (size_access)
48//           {
49//           case 2 :
50//             {
51//               x = ((((x>> 8)&0xff) <<  0) |
52//                    (((x>> 0)&0xff) <<  8) |
53//                    (((x>>24)&0xff) << 16) |
54//                    (((x>>16)&0xff) << 24) );
55//               break;
56//             }
57//           case 4 :
58//             {
59//               x = ((((x>>24)&0xff) <<  0) |
60//                    (((x>>16)&0xff) <<  8) |
61//                    (((x>> 8)&0xff) << 16) |
62//                    (((x>> 0)&0xff) << 24) );
63//               break;
64//             }
65//           default :
66//             {
67//               break;
68//             }
69//           }
70//         break;
71//       }
72//     case 8 : // 64 bits
73//       {
74//         switch (size_access)
75//           {
76//           case 2 :
77//             {
78//               x = ((((x>> 8)&0xff) <<  0) |
79//                    (((x>> 0)&0xff) <<  8) |
80//                    (((x>>24)&0xff) << 16) |
81//                    (((x>>16)&0xff) << 24) |
82//                    (((x>>40)&0xff) << 32) |
83//                    (((x>>32)&0xff) << 40) |
84//                    (((x>>56)&0xff) << 48) |
85//                    (((x>>48)&0xff) << 56) );
86//               break;
87//             }
88//           case 4 :
89//             {
90//               x = ((((x>>24)&0xff) <<  0) |
91//                    (((x>>16)&0xff) <<  8) |
92//                    (((x>> 8)&0xff) << 16) |
93//                    (((x>> 0)&0xff) << 24) |
94//                    (((x>>56)&0xff) << 32) |
95//                    (((x>>48)&0xff) << 40) |
96//                    (((x>>40)&0xff) << 48) |
97//                    (((x>>32)&0xff) << 56) );
98//               break;
99//             }
100//           case 8 :
101//             {
102//               x = ((((x>>56)&0xff) <<  0) |
103//                    (((x>>48)&0xff) <<  8) |
104//                    (((x>>40)&0xff) << 16) |
105//                    (((x>>32)&0xff) << 24) |
106//                    (((x>>24)&0xff) << 32) |
107//                    (((x>>16)&0xff) << 40) |
108//                    (((x>> 8)&0xff) << 48) |
109//                    (((x>> 0)&0xff) << 56) );
110//               break;
111//             }
112//           default :
113//             {
114//               break;
115//             }
116//           }
117//         break;
118//       }
119//     default :
120//       {
121//         break;
122//       }
123//     }
124
125
126  uint64_t y=0;
127
128  for (uint32_t i=0; i<size_data; i+=size_access)
129    {
130      uint32_t offset = i<<3;
131
132      switch (size_access)
133        {
134        case 1 :
135          {
136            y = x;
137            break;
138          }
139        case 2 : 
140          {
141            y |= ((((x>>( 8+offset))&0xff) << ( 0+offset)) |
142                  (((x>>( 0+offset))&0xff) << ( 8+offset)) );
143            break;
144          }
145        case 4 : 
146          {
147            y |= ((((x>>(24+offset))&0xff) << ( 0+offset)) |
148                  (((x>>(16+offset))&0xff) << ( 8+offset)) |
149                  (((x>>( 8+offset))&0xff) << (16+offset)) |
150                  (((x>>( 0+offset))&0xff) << (24+offset)) );
151            break;
152          }
153        case 8 : 
154          {
155            y |= ((((x>>(56+offset))&0xff) << ( 0+offset)) |
156                  (((x>>(48+offset))&0xff) << ( 8+offset)) |
157                  (((x>>(40+offset))&0xff) << (16+offset)) |
158                  (((x>>(32+offset))&0xff) << (24+offset)) |
159                  (((x>>(24+offset))&0xff) << (32+offset)) |
160                  (((x>>(16+offset))&0xff) << (40+offset)) |
161                  (((x>>( 8+offset))&0xff) << (48+offset)) |
162                  (((x>>( 0+offset))&0xff) << (56+offset)) );
163            break;
164          }
165        default :
166            {
167              break;
168            }
169        }
170    }
171
172  return static_cast<T>(y);
173}
174
175template <typename T>
176T swapBits (T data, uint32_t size_data, uint32_t size_access)
177{
178  uint8_t x = static_cast<uint8_t>(data);
179
180  uint8_t y=0;
181
182  for (uint32_t i=0; i<size_data; i+=size_access)
183    {
184      uint32_t offset = i;
185
186      switch (size_access)
187        {
188        case 1 :
189          {
190            y = x;
191            break;
192          }
193        case 2 : 
194          {
195            y |= ((((x>>( 1+offset))&0x1) << ( 0+offset)) |
196                  (((x>>( 0+offset))&0x1) << ( 1+offset)) );
197            break;
198          }
199        case 4 : 
200          {
201            y |= ((((x>>( 3+offset))&0x1) << ( 0+offset)) |
202                  (((x>>( 2+offset))&0x1) << ( 1+offset)) |
203                  (((x>>( 1+offset))&0x1) << ( 2+offset)) |
204                  (((x>>( 0+offset))&0x1) << ( 3+offset)) );
205            break;
206          }
207        case 8 : 
208          {
209            y |= ((((x>>( 7+offset))&0x1) << ( 0+offset)) |
210                  (((x>>( 6+offset))&0x1) << ( 1+offset)) |
211                  (((x>>( 5+offset))&0x1) << ( 2+offset)) |
212                  (((x>>( 4+offset))&0x1) << ( 3+offset)) |
213                  (((x>>( 3+offset))&0x1) << ( 4+offset)) |
214                  (((x>>( 2+offset))&0x1) << ( 5+offset)) |
215                  (((x>>( 1+offset))&0x1) << ( 6+offset)) |
216                  (((x>>( 0+offset))&0x1) << ( 7+offset)) );
217            break;
218          }
219        default :
220            {
221              break;
222            }
223        }
224    }
225
226  return static_cast<T>(y);
227}
228
229#undef  FUNCTION
230#define FUNCTION "Load_store_unit::function_speculative_load_access_transition"
231  void Load_store_unit::function_speculative_load_access_transition (void)
232  {
233    log_begin(Load_store_unit,FUNCTION);
234    log_function(Load_store_unit,FUNCTION,_name.c_str());
235
236    if (PORT_READ(in_NRESET) == 0)
237      {
238        // Reset : clear all queue
239        _speculative_access_queue_control->clear();
240
241        reg_STORE_QUEUE_PTR_READ       = 0;
242        reg_LOAD_QUEUE_CHECK_PRIORITY  = 0;
243
244        for (uint32_t i=0; i< _param->_size_store_queue             ; i++)
245          {
246            reg_STORE_QUEUE_NB_CHECK  [i] = 0;
247//          reg_STORE_QUEUE_INVALID   [i] = 0;
248            _store_queue              [i]._state                 = STORE_QUEUE_EMPTY;
249            _store_queue              [i]._context_id            = 0; // not necessary
250            _store_queue              [i]._front_end_id          = 0; // not necessary
251            _store_queue              [i]._ooo_engine_id         = 0; // not necessary
252            _store_queue              [i]._packet_id             = 0; // not necessary
253            _store_queue              [i]._operation             = 0; // not necessary
254            _store_queue              [i]._cancel                = 0; // not necessary
255            _store_queue              [i]._load_queue_ptr_write  = 0; // not necessary
256            _store_queue              [i]._address               = 0; // not necessary
257            _store_queue              [i]._wdata                 = 0; // not necessary
258//          _store_queue              [i]._write_rd              = 0; // not necessary
259//          _store_queue              [i]._num_reg_rd            = 0; // not necessary
260            _store_queue              [i]._exception             = 0; // not necessary
261            _store_queue              [i]._send_commit           = 0; // not necessary
262          }
263
264        for (uint32_t i=0; i< _param->_size_load_queue              ; i++)
265          {
266            _load_queue               [i]._state                 = LOAD_QUEUE_EMPTY;
267            _load_queue               [i]._context_id            = 0; // not necessary
268            _load_queue               [i]._front_end_id          = 0; // not necessary
269            _load_queue               [i]._ooo_engine_id         = 0; // not necessary
270            _load_queue               [i]._packet_id             = 0; // not necessary
271            _load_queue               [i]._operation             = 0; // not necessary
272            _load_queue               [i]._cancel                = 0; // not necessary
273            _load_queue               [i]._store_queue_ptr_write = 0; // not necessary
274            _load_queue               [i]._store_queue_ptr_read  = 0; // not necessary
275            _load_queue               [i]._store_queue_empty     = 0; // not necessary
276            _load_queue               [i]._address               = 0; // not necessary
277            _load_queue               [i]._check_hit_byte        = 0; // not necessary
278            _load_queue               [i]._check_hit             = 0; // not necessary
279            _load_queue               [i]._shift                 = 0; // not necessary
280            _load_queue               [i]._is_load_signed        = 0; // not necessary
281            _load_queue               [i]._access_size           = 0; // not necessary
282            _load_queue               [i]._rdata                 = 0; // not necessary
283            _load_queue               [i]._write_rd              = 0; // not necessary
284            _load_queue               [i]._num_reg_rd            = 0; // not necessary
285            _load_queue               [i]._exception             = 0; // not necessary
286            _load_queue               [i]._can_speculative_commit= 0; // not necessary
287          }
288
289        for (uint32_t i=0; i< _param->_size_speculative_access_queue; i++)
290          {
291            _speculative_access_queue [i]._state                 = SPECULATIVE_ACCESS_QUEUE_EMPTY;
292            _speculative_access_queue [i]._context_id            = 0; // not necessary
293            _speculative_access_queue [i]._front_end_id          = 0; // not necessary
294            _speculative_access_queue [i]._ooo_engine_id         = 0; // not necessary
295            _speculative_access_queue [i]._packet_id             = 0; // not necessary
296            _speculative_access_queue [i]._operation             = 0; // not necessary
297            _speculative_access_queue [i]._cancel                = 0; // not necessary
298            _speculative_access_queue [i]._load_queue_ptr_write  = 0; // not necessary
299            _speculative_access_queue [i]._store_queue_ptr_write = 0; // not necessary
300            _speculative_access_queue [i]._store_queue_ptr_read  = 0; // not necessary
301            _speculative_access_queue [i]._store_queue_empty     = 0; // not necessary
302            _speculative_access_queue [i]._address               = 0; // not necessary
303            _speculative_access_queue [i]._write_rd              = 0; // not necessary
304            _speculative_access_queue [i]._num_reg_rd            = 0; // not necessary
305            _speculative_access_queue [i]._exception             = 0; // not necessary
306          }
307      }
308    else
309      {
310        // load_queue_push if speculative_access_queue have access at the dcache, or they have an event
311        bool load_queue_push = (_speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._state == SPECULATIVE_ACCESS_QUEUE_WAIT_LOAD_QUEUE);
312
313        //================================================================
314        // Interface "MEMORY_OUT"
315        //================================================================
316
317        if ((    internal_MEMORY_OUT_VAL  == 1) and
318            (PORT_READ(in_MEMORY_OUT_ACK[0]) == 1))
319          {
320            log_printf(TRACE,Load_store_unit,FUNCTION,"  * MEMORY_OUT[0] transaction");
321
322            switch (internal_MEMORY_OUT_SELECT_QUEUE)
323              {
324              case SELECT_STORE_QUEUE :
325                {
326                  // =======================
327                  // ===== STORE_QUEUE =====
328                  // =======================
329                 
330                  log_printf(TRACE,Load_store_unit,FUNCTION,"    * store_queue [%d]",internal_MEMORY_OUT_PTR);
331           
332                  // Entry flush and increase the read pointer
333                  if (_store_queue [internal_MEMORY_OUT_PTR]._send_commit)
334                    {
335                      _store_queue [internal_MEMORY_OUT_PTR]._state = STORE_QUEUE_EMPTY;
336                      reg_STORE_QUEUE_PTR_READ = (reg_STORE_QUEUE_PTR_READ+1)%_param->_size_store_queue;
337                    }
338                  else
339                    _store_queue [internal_MEMORY_OUT_PTR]._send_commit = true;
340
341                  break;
342                }
343              case SELECT_LOAD_QUEUE :
344                {
345                  // ======================
346                  // ===== LOAD_QUEUE =====
347                  // ======================
348                 
349                  log_printf(TRACE,Load_store_unit,FUNCTION,"    * load_queue  [%d]",internal_MEMORY_OUT_PTR);
350                 
351                  // Entry flush and increase the read pointer
352                 
353                  _load_queue [internal_MEMORY_OUT_PTR]._state = LOAD_QUEUE_EMPTY;
354                 
355                  // reg_LOAD_QUEUE_PTR_READ = (reg_LOAD_QUEUE_PTR_READ+1)%_param->_size_load_queue;
356
357                  break;
358                }
359              case SELECT_LOAD_QUEUE_SPECULATIVE :
360                {
361                  log_printf(TRACE,Load_store_unit,FUNCTION,"    * load_queue  [%d] (speculative)",internal_MEMORY_OUT_PTR);
362                 
363                  // !!! WARNING !!!
364                  // !!! Test special case :
365                  // !!! in a cycle an instruction can check the last store AND commit instruction
366                  // !!! also the memory_out is before the port_check
367
368                  _load_queue [internal_MEMORY_OUT_PTR]._state    = LOAD_QUEUE_CHECK;
369                  // NOTE : a speculative load write in the register file.
370                  // if the speculation is a miss, write_rd is re set at 1.
371                  _load_queue [internal_MEMORY_OUT_PTR]._write_rd = 0;
372
373#ifdef STATISTICS
374                  if (usage_is_set(_usage,USE_STATISTICS))
375                    (*_stat_nb_inst_load_commit_speculative) ++;
376#endif
377
378                  break;
379                }
380
381                break;
382              }
383          }
384
385        //================================================================
386        // Interface "PORT_CHECK"
387        //================================================================
388       
389        // Plusieurs moyens de faire la verification de dépendance entre les loads et les stores.
390        //  1) un load ne peut vérifier qu'un store par cycle. Dans ce cas port_check <= size_load_queue
391        //  2) un load tente de vérifier le maximum de store par cycle. Dans ce cas ce n'est pas du pointeur d'écriture qu'il lui faut mais un vecteur de bit indiquant quel store à déjà été testé. De plus il faut un bit indiquant qu'il y a un match mais que ce n'est pas forcément le premier.
392
393        // solution 1)
394        log_printf(TRACE,Load_store_unit,FUNCTION,"  * CHECK");
395        for (uint32_t i=0, nb_check=0; (nb_check<_param->_nb_port_check) and (i<_param->_size_load_queue); i++)
396          {
397            // Get an index from load queue
398            uint32_t index_load_queue = (i + reg_LOAD_QUEUE_CHECK_PRIORITY)%_param->_size_load_queue;
399
400            // Test if this load must ckecked store queue
401            if (((_load_queue[index_load_queue]._state == LOAD_QUEUE_WAIT_CHECK) or
402                 (_load_queue[index_load_queue]._state == LOAD_QUEUE_COMMIT_CHECK) or
403                 (_load_queue[index_load_queue]._state == LOAD_QUEUE_CHECK)) and
404                is_operation_memory_load(_load_queue[index_load_queue]._operation))
405              {
406                log_printf(TRACE,Load_store_unit,FUNCTION,"    * Find a load : %d",index_load_queue);
407
408                nb_check++; // use one port
409
410                // find a entry that it need a check
411                Tlsq_ptr_t store_queue_ptr_write     = _load_queue[index_load_queue]._store_queue_ptr_write;
412                Tlsq_ptr_t store_queue_ptr_read      = _load_queue[index_load_queue]._store_queue_ptr_read ;
413                Tlsq_ptr_t store_queue_empty         = _load_queue[index_load_queue]._store_queue_empty    ;
414//              Tlsq_ptr_t store_queue_ptr_write_old = store_queue_ptr_write;
415
416                // Init variable
417                bool       end_check    = false;
418                bool       change_state = false;
419                bool       next         = false;
420
421                // At the first store queue empty, stop check.
422                // Explication :
423                //  * rename logic keep a empty case in the store queue (also size_store_queue > 1)
424                //  * when a store is out of store queue, also it was in head of re order buffer. Also, they are none previous load.
425
426                log_printf(TRACE,Load_store_unit,FUNCTION,"    * store_queue_ptr_write    : %d",store_queue_ptr_write);
427                log_printf(TRACE,Load_store_unit,FUNCTION,"    * store_queue_ptr_read     : %d",store_queue_ptr_read );
428//              log_printf(TRACE,Load_store_unit,FUNCTION,"    * store_queue_empty        : %d",store_queue_empty );
429                log_printf(TRACE,Load_store_unit,FUNCTION,"    * reg_STORE_QUEUE_PTR_READ : %d",reg_STORE_QUEUE_PTR_READ);
430
431                if ((store_queue_ptr_write ==     store_queue_ptr_read) or
432                    (store_queue_ptr_write == reg_STORE_QUEUE_PTR_READ))
433//              if (store_queue_empty)
434                  {
435                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * store_queue_ptr_write == store_queue_ptr_read");
436                    end_check    = true;
437                    change_state = true;
438                  }
439                else
440                  {
441                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * store_queue_ptr_write != store_queue_ptr_read");
442
443                    store_queue_ptr_write = (store_queue_ptr_write-1)%(_param->_size_store_queue); // store_queue_ptr_write target the next slot to write, also the slot is not significatif when the load is renaming
444
445                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * store_queue_ptr_write : %d",store_queue_ptr_write);
446
447                    bool test_thread_id = true;
448                   
449                    // Test thread id
450                    if (_param->_have_port_context_id)
451                      test_thread_id &= (_load_queue[index_load_queue]._context_id    == _store_queue[store_queue_ptr_write]._context_id);
452                    if (_param->_have_port_front_end_id)
453                      test_thread_id &= (_load_queue[index_load_queue]._front_end_id  == _store_queue[store_queue_ptr_write]._front_end_id);
454                    if (_param->_have_port_ooo_engine_id)
455                      test_thread_id &= (_load_queue[index_load_queue]._ooo_engine_id == _store_queue[store_queue_ptr_write]._ooo_engine_id);
456                   
457                    // switch on store_queue state
458                    switch (_store_queue[store_queue_ptr_write]._state)
459                      {
460                      case STORE_QUEUE_VALID_NO_SPECULATIVE : 
461                      case STORE_QUEUE_COMMIT :
462                      case STORE_QUEUE_VALID_SPECULATIVE :
463                        {
464                          log_printf(TRACE,Load_store_unit,FUNCTION,"      * store have a valid entry");
465                         
466                          // TODO : MMU - nous considérons que les adresses sont physique
467                          if (test_thread_id)
468                            {
469                              // the load and store are in the same thread. Now, we must test address.
470
471                              log_printf(TRACE,Load_store_unit,FUNCTION,"        * load and store is the same thread.");
472                              Tdcache_address_t load_addr  = _load_queue [index_load_queue ]._address;
473                              Tdcache_address_t store_addr = _store_queue[store_queue_ptr_write]._address;
474                             
475                              log_printf(TRACE,Load_store_unit,FUNCTION,"          * load_addr                     : %.8x.",load_addr );
476                              log_printf(TRACE,Load_store_unit,FUNCTION,"          * store_addr                    : %.8x.",store_addr);
477                              log_printf(TRACE,Load_store_unit,FUNCTION,"          * load_addr  & mask_address_msb : %.8x.",load_addr  & _param->_mask_address_msb);
478                              log_printf(TRACE,Load_store_unit,FUNCTION,"          * store_addr & mask_address_msb : %.8x.",store_addr & _param->_mask_address_msb);
479                              // Test if the both address target the same "word"
480                              if ((load_addr  & _param->_mask_address_msb) == 
481                                  (store_addr & _param->_mask_address_msb))
482                                {
483                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * address_msb is the same.");
484
485                                  // all case - [] : store, () : load
486                                  // (1) store_max >= load_max and store_min <= load_min  ...[...(...)...]... Ok - inclusion in store
487                                  // (2) store_min >  load_max                            ...[...]...(...)... Ok - no conflit
488                                  // (3) store_max <  load_min                            ...(...)...[...]... Ok - no conflit
489                                  // (4) store_max <  load_max and store_min >  load_min  ...(...[...]...)... Ko - inclusion in load
490                                  // (5) store_max >= load_max and store_min >  load_min  ...[...(...]...)... Ko - conflit
491                                  // (6) store_max <  load_max and store_min <= load_min  ...(...[...)...]... Ko - conflit
492                                  // but :
493                                  // load in the cache is a word !
494                                  // the mask can be make when the load is commited. Also, the rdata content a full word.
495                                  // the only case is (4)
496                                 
497                                  // Read data
498                                  bool is_big_endian = true;
499
500                                  Tgeneral_data_t   load_data      = _load_queue [index_load_queue ]._rdata  ;
501                                  Tgeneral_data_t   store_data     = _store_queue[store_queue_ptr_write]._wdata  ;
502                                  Tdcache_address_t check_hit_byte = _load_queue [index_load_queue ]._check_hit_byte;
503                                  Tcontrol_t        check_hit      = _load_queue [index_load_queue ]._check_hit;
504                                  uint32_t          load_size_access  = memory_size(_load_queue [index_load_queue ]._operation)>>3;
505                                  uint32_t          store_size_access = memory_size(_store_queue[store_queue_ptr_write]._operation)>>3;
506
507                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * is_big_endian           : %d",is_big_endian);
508                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * load_data               : 0x%.8x",load_data);
509                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_data              : 0x%.8x",store_data);
510                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit_byte          : %x",check_hit_byte);
511                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit               : %d",check_hit);
512
513                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * load_size_access        : %d",load_size_access );
514                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_size_access       : %d",store_size_access);
515
516                                  if (is_big_endian)
517                                    {
518                                      // swap in little endian
519                                      load_data      = swapBytes<Tgeneral_data_t  >(load_data     , _param->_size_general_data>>3,load_size_access);
520                                      store_data     = swapBytes<Tgeneral_data_t  >(store_data    , _param->_size_general_data>>3,store_size_access);
521                                      check_hit_byte = swapBits <Tdcache_address_t>(check_hit_byte, _param->_size_general_data>>3,load_size_access);
522                                     
523                                     
524                                      log_printf(TRACE,Load_store_unit,FUNCTION,"            * load_data      (swap 1) : 0x%.8x",load_data);
525                                      log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_data     (swap 1) : 0x%.8x",store_data);
526                                      log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit_byte (swap 1) : %x",check_hit_byte);
527                                    }
528
529                                  uint32_t store_nb_byte     = (1<<memory_access(_store_queue[store_queue_ptr_write]._operation));
530
531                                  // Take interval to the store
532                                  uint32_t store_num_byte_min = (store_addr & _param->_mask_address_lsb);
533                                  uint32_t store_num_byte_max = store_num_byte_min+store_nb_byte;
534
535                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_num_byte_min      : %d",store_num_byte_min);
536                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_num_byte_max      : %d",store_num_byte_max);
537
538
539                                  // The bypass is checked byte per byte
540                                  // Is same endianness : because to change endianness, we must write in special register. Also the pipeline is flushed.
541                                  for (uint32_t num_store_byte=store_num_byte_min; num_store_byte<store_num_byte_max; num_store_byte ++)
542                                    {
543                                      // Make a mask
544                                      uint32_t num_load_byte = num_store_byte;
545
546//                                       if (is_big_endian)
547//                                         {
548//                                           // sd 0 : 0 1 2 3 4 5 6 7
549//                                           // ld 0 : 0 1 2 3 4 5 6 7 >>  0
550//                                           // lw 0 :         0 1 2 3 >>  0 -4
551//                                           // lw 4 : 4 5 6 7         >> 32 +4
552//                                           // lh 0 :             0 1 >>  0 -6
553//                                           // lh 2 :         2 3     >> 16 -2
554//                                           // lh 4 :     4 5         >> 32 +2
555//                                           // lh 6 : 6 7             >> 48 +6
556//                                           // lb 0 :               0 >>  0 -7
557//                                           // lb 1 :             1   >>  8 -5
558//                                           // lb 2 :           2     >> 16 -3
559//                                           // lb 3 :         3       >> 24 -1
560//                                           // lb 4 :       4         >> 32 +1
561//                                           // lb 5 :     5           >> 40 +3
562//                                           // lb 6 :   6             >> 48 +5
563//                                           // lb 7 : 7               >> 56 +7
564
565//                                           // diff : (store_nb_byte + load_nb_byte) - 2*nb_load_byte*((num_store_byte+1)
566
567//                                           // store duplicate = all store access can be see as full size_data store
568// //                                           uint32_t load_nb_byte = (1<<memory_access(_load_queue [index_load_queue ]._operation));
569
570// //                                           int32_t diff = ((_param->_size_general_data>>3)+load_nb_byte-2*load_nb_byte*((num_store_byte/load_nb_byte)+1));
571
572// //                                           num_load_byte =num_store_byte+diff;
573
574// //                                           log_printf(TRACE,Load_store_unit,FUNCTION,"              * load_nb_byte   : %d",load_nb_byte);
575// //                                           log_printf(TRACE,Load_store_unit,FUNCTION,"              * diff           : %d",diff);
576
577
578//                                           num_load_byte = num_store_byte;
579//                                         }
580//                                       else
581//                                         {
582//                                           // sd 0 : 0 1 2 3 4 5 6 7
583//                                           // ld 0 : 0 1 2 3 4 5 6 7 >>  0
584//                                           // lw 0 :         4 5 6 7 >>  0
585//                                           // lw 4 : 0 1 2 3         >> 32
586//                                           // lh 0 :             6 7 >>  0
587//                                           // lh 2 :         4 5     >> 16
588//                                           // lh 4 :     2 3         >> 32
589//                                           // lh 6 : 0 1             >> 48
590//                                           // lb 0 :               7 >>  0
591//                                           // lb 1 :             6   >>  8
592//                                           // lb 2 :           5     >> 16
593//                                           // lb 3 :         4       >> 24
594//                                           // lb 4 :       3         >> 32
595//                                           // lb 5 :     2           >> 40
596//                                           // lb 6 :   1             >> 48
597//                                           // lb 7 : 0               >> 56
598                                         
599//                                           num_load_byte = num_store_byte;
600//                                         }
601
602                                      uint32_t mask  = 1<<num_load_byte;
603
604                                      log_printf(TRACE,Load_store_unit,FUNCTION,"              * num_store_byte : %d",num_store_byte);
605                                      log_printf(TRACE,Load_store_unit,FUNCTION,"              * num_load_byte  : %d",num_load_byte);
606                                      log_printf(TRACE,Load_store_unit,FUNCTION,"              * mask           : %d",mask);
607
608                                      // Accept the bypass if :
609                                      //   * they have not a previous bypass with an another store
610                                      //   * it's a valid request of load
611                                      if ((check_hit_byte&mask)==0)
612                                        {
613                                          // Note : Store is duplicate = all store access can be see as full size_data store
614
615                                          uint32_t num_store_bit_min = num_store_byte<<3; //*8
616//                                        uint32_t num_store_bit_max = num_store_bit_min+8-1;
617                                          uint32_t num_load_bit_min  = num_load_byte <<3; //*8
618                                          uint32_t num_load_bit_max  = num_load_bit_min+8-1;
619
620                                          log_printf(TRACE,Load_store_unit,FUNCTION,"              * bypass !!!");
621//                                        log_printf(TRACE,Load_store_unit,FUNCTION,"              * interval store : [%d:%d]",num_store_bit_max,num_store_bit_min);
622                                          log_printf(TRACE,Load_store_unit,FUNCTION,"              * interval store : [..:%d]",num_store_bit_min);
623                                          log_printf(TRACE,Load_store_unit,FUNCTION,"              * interval load  : [%d:%d]",num_load_bit_max,num_load_bit_min);
624                                          log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_old : 0x%.8x", load_data);
625
626                                          load_data = ((((store_data>>num_store_bit_min) & 0xff) << num_load_bit_min) |
627                                                       mask_not<Tdcache_data_t>(load_data,num_load_bit_max,num_load_bit_min));
628
629                                          check_hit_byte |= mask;
630                                          check_hit       = 1;
631                                          change_state = true;
632
633                                          log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_new : 0x%.8x", load_data);
634                                        }
635                                    }
636
637                                  if (is_big_endian)
638                                    {
639                                      // swap in little endian
640                                      load_data      = swapBytes<Tgeneral_data_t  >(load_data     , _param->_size_general_data>>3,load_size_access);
641                                      check_hit_byte = swapBits <Tdcache_address_t>(check_hit_byte, _param->_size_general_data>>3,load_size_access);
642                                     
643                                     
644                                      log_printf(TRACE,Load_store_unit,FUNCTION,"            * load_data      (swap 2) : 0x%.8x",load_data);
645                                      log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit_byte (swap 2) : %x",check_hit_byte);
646                                    }
647
648                                  _load_queue[index_load_queue]._rdata          = load_data;
649                                  _load_queue[index_load_queue]._check_hit_byte = check_hit_byte;
650                                  _load_queue[index_load_queue]._check_hit      = check_hit;
651
652                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * load_data  (after) : 0x%.8x",load_data);
653
654                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit          : %x",check_hit);
655                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit_byte     : %x",check_hit_byte);
656
657                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * mask_end_check     : %x",(-1& _param->_mask_address_lsb));
658                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * mask_check_hit_byte: %x",_param->_mask_check_hit_byte);
659                                  // The check is finish if all bit is set
660                                  end_check = (_load_queue[index_load_queue]._check_hit_byte == _param->_mask_check_hit_byte);
661                                }
662                            }
663                         
664                          next = true;
665                          break;
666                        }
667                      case STORE_QUEUE_EMPTY :
668                        {
669                          log_printf(TRACE,Load_store_unit,FUNCTION,"      * store is empty ... wait.");
670                          break;
671                        }
672
673                      case STORE_QUEUE_NO_VALID_NO_SPECULATIVE :
674                        {
675                          log_printf(TRACE,Load_store_unit,FUNCTION,"      * store have an invalid entry");
676
677                          if (test_thread_id)
678                            {
679                              end_check    = true; // previous store is invalid -> exception
680                              change_state = true;
681                            }
682                          else
683                            next = true;
684                           
685                          break;
686                        }
687                      }
688                  }
689
690                if (next)
691                  {
692                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * next");
693                    log_printf(TRACE,Load_store_unit,FUNCTION,"                * new store_queue_ptr_write : %d",store_queue_ptr_write);
694
695                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * update reg_STORE_QUEUE_NB_CHECK");
696#ifdef DEBUG
697                    if (reg_STORE_QUEUE_NB_CHECK [store_queue_ptr_write] == 0)
698                      throw ERRORMORPHEO(FUNCTION,_("reg_STORE_QUEUE_NB_CHECK must be > 0\n"));
699#endif
700
701                    reg_STORE_QUEUE_NB_CHECK [store_queue_ptr_write] --;
702
703                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * reg_STORE_QUEUE_NB_CHECK 1 [%d] <- %d", store_queue_ptr_write,reg_STORE_QUEUE_NB_CHECK [store_queue_ptr_write]);
704
705                    if ((store_queue_ptr_write ==     store_queue_ptr_read) or
706                        (store_queue_ptr_write == reg_STORE_QUEUE_PTR_READ))
707                      {
708//                      store_queue_empty = true;
709                        end_check         = true;
710                        change_state      = true;
711                      }
712
713//                  if (_load_queue[index_load_queue]._store_queue_ptr_write == 0)
714//                    _load_queue[index_load_queue]._store_queue_ptr_write = _param->_size_store_queue-1;
715//                  else
716//                    _load_queue[index_load_queue]._store_queue_ptr_write --;
717                    _load_queue[index_load_queue]._store_queue_ptr_write = store_queue_ptr_write; // because the index store have be decrease
718                    _load_queue[index_load_queue]._store_queue_empty     = store_queue_empty; // because the index store have be decrease
719
720                    // FIXME : peut n'est pas obliger de faire cette comparaison. Au prochain cycle on le détectera que les pointeur sont égaux. Ceci évitera d'avoir deux comparateurs avec le registre "store_queue_ptr_read"
721                  }
722
723                if (change_state)
724                  {
725                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * change_state");
726                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * end_check : %d",end_check);
727
728                    log_printf(TRACE,Load_store_unit,FUNCTION,"                * state old : %s",toString(_load_queue[index_load_queue]._state).c_str());
729
730                    switch (_load_queue[index_load_queue]._state)
731                      {
732                      case LOAD_QUEUE_WAIT_CHECK   : 
733                        {
734                          if (end_check)
735                            _load_queue[index_load_queue]._state = LOAD_QUEUE_WAIT  ; 
736                          break;
737                        }
738                      case LOAD_QUEUE_COMMIT_CHECK : 
739                        {
740                          if (end_check)
741                            _load_queue[index_load_queue]._state = LOAD_QUEUE_COMMIT; 
742                          else
743                            _load_queue[index_load_queue]._state = LOAD_QUEUE_CHECK; // No commit : check hit and no end
744                          break;
745                        }
746                      case LOAD_QUEUE_CHECK        : 
747                        {
748                          if (end_check)
749                            _load_queue[index_load_queue]._state     = LOAD_QUEUE_COMMIT;
750
751                          // check find a bypass. A speculative load have been committed : report a speculation miss.
752                          if ((_load_queue[index_load_queue]._check_hit != 0) and
753                              (_load_queue[index_load_queue]._write_rd  == 0) // is commit
754                              )
755                            {
756                              _load_queue[index_load_queue]._exception = EXCEPTION_MEMORY_MISS_SPECULATION;
757                              _load_queue[index_load_queue]._write_rd  = 1; // write the good result
758
759#ifdef STATISTICS
760                              if (usage_is_set(_usage,USE_STATISTICS))
761                                (*_stat_nb_inst_load_commit_miss) ++;
762#endif
763                            }
764                         
765                          break;
766                        }
767                      default : break;
768                      }
769                    log_printf(TRACE,Load_store_unit,FUNCTION,"                * state new : %s",toString(_load_queue[index_load_queue]._state).c_str());
770                    log_printf(TRACE,Load_store_unit,FUNCTION,"                * exception : %d",_load_queue[index_load_queue]._exception);
771
772                    if (end_check//  and not store_queue_empty
773                        )
774                      {
775                        log_printf(TRACE,Load_store_unit,FUNCTION,"                * end check, decrease all nb_check");
776                       
777                        uint32_t i=store_queue_ptr_write;
778                        while (i!=store_queue_ptr_read)
779                          {
780                            i=((i==0)?_param->_size_store_queue:i)-1;
781                           
782#ifdef DEBUG
783                            if (reg_STORE_QUEUE_NB_CHECK [i] == 0)
784                              throw ERRORMORPHEO(FUNCTION,_("reg_STORE_QUEUE_NB_CHECK must be > 0\n"));
785#endif
786                           
787                            reg_STORE_QUEUE_NB_CHECK [i] --;
788
789                            log_printf(TRACE,Load_store_unit,FUNCTION,"              * reg_STORE_QUEUE_NB_CHECK 2 [%d] <- %d", i,reg_STORE_QUEUE_NB_CHECK [i]);
790
791                            //i=(i+1)%_param->_size_store_queue;
792                          }
793                       
794                        _load_queue[index_load_queue]._store_queue_empty = true; // end of check
795                      }
796                  }
797              }
798            // else : don't use a port
799          }
800       
801        //================================================================
802        // Interface "MEMORY_IN"
803        //================================================================
804       
805        if ((PORT_READ(in_MEMORY_IN_VAL [internal_MEMORY_IN_PORT]) == 1) and
806            (    internal_MEMORY_IN_ACK  == 1))
807          {
808            log_printf(TRACE,Load_store_unit,FUNCTION,"  * MEMORY_IN [%d]",internal_MEMORY_IN_PORT);
809
810            // Test operation :
811            //~~~~~~~~~~~~~~~~~
812            //  store  in store_queue
813            //  load   in speculation_access_queue
814            //  others in speculation_access_queue
815
816#ifdef DEBUG_TEST
817            if (PORT_READ(in_MEMORY_IN_TYPE [internal_MEMORY_IN_PORT]) != TYPE_MEMORY)
818              throw ERRORMORPHEO(FUNCTION,"The type is different at 'TYPE_MEMORY'");
819#endif
820            Toperation_t    operation            = PORT_READ(in_MEMORY_IN_OPERATION[internal_MEMORY_IN_PORT]);
821            Tcontrol_t      cancel               = PORT_READ(in_MEMORY_IN_CANCEL   [internal_MEMORY_IN_PORT]);
822            Tgeneral_data_t address              = (PORT_READ(in_MEMORY_IN_IMMEDIAT[internal_MEMORY_IN_PORT]) +
823                                                    PORT_READ(in_MEMORY_IN_DATA_RA [internal_MEMORY_IN_PORT]));
824            bool            exception_alignement = (mask_memory_access(operation) & address) != 0;
825                                                   
826            if (is_operation_memory_store(operation) == true)
827              {
828                // =======================
829                // ===== STORE_QUEUE =====
830                // =======================
831                // There a two store request type :
832                //   - first is operation with address and data
833                //   - second is the information of re order buffer : the store become not speculative and can access at the data cache
834
835                log_printf(TRACE,Load_store_unit,FUNCTION,"    * store_queue");
836                log_printf(TRACE,Load_store_unit,FUNCTION,"      * PUSH");
837               
838                // Write pointer is define in rename stage :
839                Tlsq_ptr_t           index         = PORT_READ(in_MEMORY_IN_STORE_QUEUE_PTR_WRITE[internal_MEMORY_IN_PORT]);
840                log_printf(TRACE,Load_store_unit,FUNCTION,"      * index         : %d",index);
841               
842                // Need read : state and exception.
843                Tstore_queue_state_t old_state     = _store_queue [index]._state;
844                Tstore_queue_state_t new_state     = old_state;
845                bool                 update_info   = false;
846
847                Texception_t         old_exception = _store_queue [index]._exception;
848                Texception_t         new_exception = old_exception;
849
850                // Compute next state
851                switch (old_state)
852                  {
853                  case STORE_QUEUE_EMPTY                   :
854                    {
855//                    reg_STORE_QUEUE_INVALID [index] = false; // new first store instruction
856
857                      if (is_operation_memory_store_head(operation) == true)
858                        {
859                          new_state = STORE_QUEUE_NO_VALID_NO_SPECULATIVE;
860
861                          // test if is a speculation
862                          if (operation == OPERATION_MEMORY_STORE_HEAD_KO)
863                            {
864                              new_exception = EXCEPTION_MEMORY_MISS_SPECULATION;
865//                            reg_STORE_QUEUE_INVALID [index] = true;
866                            }
867                          else
868                            new_exception = EXCEPTION_MEMORY_NONE;
869                        }
870                      else
871                        {
872                          new_state = STORE_QUEUE_VALID_SPECULATIVE;
873
874                          // Test if have an exception
875                          if (exception_alignement == true)
876                            new_exception = EXCEPTION_MEMORY_ALIGNMENT;
877                          else
878                            new_exception = EXCEPTION_MEMORY_NONE;
879
880                          update_info = true;
881                        }
882                      break;
883                    }
884                  case STORE_QUEUE_NO_VALID_NO_SPECULATIVE :
885                    {
886#ifdef DEBUG_TEST
887                      if (is_operation_memory_store_head(operation) == true)
888                        throw ERRORMORPHEO(FUNCTION,_("Transaction in memory_in's interface, actual state of store_queue is \"STORE_QUEUE_NO_VALID_NO_SPECULATIVE\", also a previous store_head have been receiveid. But this operation is a store_head."));
889#endif
890                      // Test if have a new exception (priority : miss_speculation)
891                      if ((exception_alignement == true) and (old_exception == EXCEPTION_MEMORY_NONE))
892                        new_exception = EXCEPTION_MEMORY_ALIGNMENT;
893                     
894                      if (new_exception != EXCEPTION_MEMORY_NONE)
895                        new_state = STORE_QUEUE_COMMIT;
896                      else
897                        new_state = STORE_QUEUE_VALID_NO_SPECULATIVE;
898                     
899                      update_info = true;
900                      break;
901                    }
902                  case STORE_QUEUE_VALID_SPECULATIVE       :
903                    {
904#ifdef DEBUG_TEST
905                      if (is_operation_memory_store_head(operation) == false)
906                        throw ERRORMORPHEO(FUNCTION,_("Transaction in memory_in's interface, actual state of store_queue is \"STORE_QUEUE_VALID_SPECULATIVE\", also a previous access with register and address have been receiveid. But this operation is a not store_head."));
907#endif
908                      if (operation == OPERATION_MEMORY_STORE_HEAD_KO)
909                        {
910                          new_exception = EXCEPTION_MEMORY_MISS_SPECULATION; // great prioritary
911//                        reg_STORE_QUEUE_INVALID [index] = true;
912                        }
913
914                      if (new_exception != EXCEPTION_MEMORY_NONE)
915                        new_state = STORE_QUEUE_COMMIT;
916                      else
917                        new_state = STORE_QUEUE_VALID_NO_SPECULATIVE;
918                     
919                      break;
920                    }
921                  case STORE_QUEUE_VALID_NO_SPECULATIVE    :
922                  case STORE_QUEUE_COMMIT                  :
923                    {
924                      throw ERRORMORPHEO(FUNCTION,"<Load_store_unit::function_speculative_load_access_transition> Invalid state and operation");
925                    }
926                  }
927
928                _store_queue [index]._state     = new_state;
929                _store_queue [index]._exception = new_exception;
930               
931                if (update_info == true)
932                  {
933                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * Update information");
934
935                    _store_queue [index]._context_id           = (not _param->_have_port_context_id   )?0:PORT_READ(in_MEMORY_IN_CONTEXT_ID   [internal_MEMORY_IN_PORT]);
936                    _store_queue [index]._front_end_id         = (not _param->_have_port_front_end_id )?0:PORT_READ(in_MEMORY_IN_FRONT_END_ID [internal_MEMORY_IN_PORT]);
937                    _store_queue [index]._ooo_engine_id        = (not _param->_have_port_ooo_engine_id)?0:PORT_READ(in_MEMORY_IN_OOO_ENGINE_ID[internal_MEMORY_IN_PORT]);
938                    _store_queue [index]._packet_id            = (not _param->_have_port_rob_ptr      )?0:PORT_READ(in_MEMORY_IN_PACKET_ID    [internal_MEMORY_IN_PORT]);
939                    _store_queue [index]._operation            = operation;
940                    _store_queue [index]._cancel               = cancel   ;
941                    _store_queue [index]._load_queue_ptr_write = (not _param->_have_port_load_queue_ptr)?0:PORT_READ(in_MEMORY_IN_LOAD_QUEUE_PTR_WRITE[internal_MEMORY_IN_PORT]);
942                    _store_queue [index]._address              = address;
943                    _store_queue [index]._send_commit          = false;
944
945                    // reordering data
946                    _store_queue [index]._wdata                = duplicate<Tgeneral_data_t>(_param->_size_general_data,PORT_READ(in_MEMORY_IN_DATA_RB[internal_MEMORY_IN_PORT]), memory_size(operation), 0); 
947//                  _store_queue [index]._num_reg_rd           = PORT_READ(in_MEMORY_IN_NUM_REG_RD  [internal_MEMORY_IN_PORT]);
948                  }
949              }
950            else
951              {
952                // ====================================
953                // ===== SPECULATIVE_ACCESS_QUEUE =====
954                // ====================================
955
956                // In speculative access queue, they are many type's request
957                log_printf(TRACE,Load_store_unit,FUNCTION,"    * speculative_access_queue");
958                log_printf(TRACE,Load_store_unit,FUNCTION,"      * PUSH");
959               
960                // Write in reservation station
961                uint32_t     index = _speculative_access_queue_control->push();
962
963                log_printf(TRACE,Load_store_unit,FUNCTION,"      * index : %d", index);
964
965                Texception_t exception;
966
967                if (exception_alignement == true)
968                  exception = EXCEPTION_MEMORY_ALIGNMENT;
969                else
970                  exception = EXCEPTION_MEMORY_NONE;
971                               
972                // if exception, don't access at the cache
973                // NOTE : type "other" (lock, invalidate, flush and sync) can't make an alignement exception (access is equivalent at a 8 bits)
974                _speculative_access_queue [index]._state                = (exception == EXCEPTION_MEMORY_NONE)?SPECULATIVE_ACCESS_QUEUE_WAIT_CACHE:SPECULATIVE_ACCESS_QUEUE_WAIT_LOAD_QUEUE;
975                _speculative_access_queue [index]._context_id           = (not _param->_have_port_context_id   )?0:PORT_READ(in_MEMORY_IN_CONTEXT_ID   [internal_MEMORY_IN_PORT]);
976                _speculative_access_queue [index]._front_end_id         = (not _param->_have_port_front_end_id )?0:PORT_READ(in_MEMORY_IN_FRONT_END_ID [internal_MEMORY_IN_PORT]);
977                _speculative_access_queue [index]._ooo_engine_id        = (not _param->_have_port_ooo_engine_id)?0:PORT_READ(in_MEMORY_IN_OOO_ENGINE_ID[internal_MEMORY_IN_PORT]);
978                _speculative_access_queue [index]._packet_id            = (not _param->_have_port_rob_ptr      )?0:PORT_READ(in_MEMORY_IN_PACKET_ID    [internal_MEMORY_IN_PORT]);
979
980                _speculative_access_queue [index]._operation            = operation;
981                _speculative_access_queue [index]._cancel               = cancel   ;
982                _speculative_access_queue [index]._load_queue_ptr_write = (not _param->_have_port_load_queue_ptr)?0:PORT_READ(in_MEMORY_IN_LOAD_QUEUE_PTR_WRITE[internal_MEMORY_IN_PORT]);
983                _speculative_access_queue [index]._store_queue_ptr_write= PORT_READ(in_MEMORY_IN_STORE_QUEUE_PTR_WRITE[internal_MEMORY_IN_PORT]);
984                _speculative_access_queue [index]._store_queue_ptr_read = PORT_READ(in_MEMORY_IN_STORE_QUEUE_PTR_READ [internal_MEMORY_IN_PORT]);
985                _speculative_access_queue [index]._store_queue_empty    = PORT_READ(in_MEMORY_IN_STORE_QUEUE_EMPTY    [internal_MEMORY_IN_PORT]);
986                _speculative_access_queue [index]._address              = address;
987                // NOTE : is operation is a load, then they are a result and must write in the register file
988                _speculative_access_queue [index]._write_rd             = is_operation_memory_load(operation);
989                _speculative_access_queue [index]._num_reg_rd           = PORT_READ(in_MEMORY_IN_NUM_REG_RD  [internal_MEMORY_IN_PORT]);
990
991                _speculative_access_queue [index]._exception            = exception;
992              }
993          }
994
995        //================================================================
996        // Interface "DCACHE_REQ"
997        //================================================================
998        if ((    internal_DCACHE_REQ_VAL  == 1) and
999            (PORT_READ(in_DCACHE_REQ_ACK[0]) == 1))
1000          {
1001            log_printf(TRACE,Load_store_unit,FUNCTION,"  * DCACHE_REQ [0]");
1002
1003            switch (internal_DCACHE_REQ_SELECT_QUEUE)
1004              {
1005              case SELECT_STORE_QUEUE :
1006                {
1007                  // =======================
1008                  // ===== STORE_QUEUE =====
1009                  // =======================
1010                 
1011                  // Entry flush and increase the read pointer
1012                 
1013                  _store_queue [reg_STORE_QUEUE_PTR_READ]._state = STORE_QUEUE_COMMIT;
1014
1015#if defined(DEBUG) and defined(DEBUG_Load_store_unit) and (DEBUG_Load_store_unit == true)
1016                  if (log_file_generate)
1017                    {
1018                      // log file
1019                      Tcontext_t num_thread    = get_num_thread(_store_queue [reg_STORE_QUEUE_PTR_READ]._context_id   , _param->_size_context_id   ,
1020                                                                _store_queue [reg_STORE_QUEUE_PTR_READ]._front_end_id , _param->_size_front_end_id ,
1021                                                                _store_queue [reg_STORE_QUEUE_PTR_READ]._ooo_engine_id, _param->_size_ooo_engine_id);
1022
1023                      memory_log_file [num_thread] 
1024                        << "[" << simulation_cycle() << "] "
1025                        << std::hex
1026                        << "@ 0x" << std::setfill('0') << std::setw(_param->_size_general_data/4) << _store_queue [reg_STORE_QUEUE_PTR_READ]._address << " -[ Write ]-> 0x" << std::setfill('0') << std::setw(_param->_size_general_data/4) << _store_queue [reg_STORE_QUEUE_PTR_READ]._wdata << " "
1027                        << std::dec
1028                        << "{" << toString(_store_queue [reg_STORE_QUEUE_PTR_READ]._operation) << "}";
1029                     
1030                      memory_log_file [num_thread] << std::endl;
1031                    }
1032#endif     
1033
1034
1035                  break;
1036                }
1037              case SELECT_LOAD_QUEUE_SPECULATIVE :
1038                {
1039                  // =========================================
1040                  // ===== SELECT_LOAD_QUEUE_SPECULATIVE =====
1041                  // =========================================
1042
1043                  load_queue_push = true;
1044                  break;
1045                }
1046              case SELECT_LOAD_QUEUE :
1047                {
1048                  throw ERRORMORPHEO(FUNCTION,_("Invalid selection"));
1049                  break;
1050                }
1051
1052                break;
1053              }
1054          }
1055
1056        if (load_queue_push)
1057          {
1058            log_printf(TRACE,Load_store_unit,FUNCTION,"  * load_queue_push");
1059
1060            Tlsq_ptr_t   ptr_write = _speculative_access_queue[internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._load_queue_ptr_write;
1061            Toperation_t operation = _speculative_access_queue[internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._operation;
1062            Texception_t exception = _speculative_access_queue[internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._exception;
1063            bool         have_exception = (exception != EXCEPTION_MEMORY_NONE);
1064            bool         need_check= false;
1065            Tlsq_ptr_t   store_queue_ptr_write = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._store_queue_ptr_write;
1066            Tlsq_ptr_t   store_queue_ptr_read  = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._store_queue_ptr_read ;
1067            Tcontrol_t   store_queue_empty     = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._store_queue_empty    ;
1068           
1069            if (have_exception)
1070              _load_queue [ptr_write]._state = LOAD_QUEUE_COMMIT;
1071            else
1072              {
1073                if (have_dcache_rsp(operation))
1074                  {
1075                    // load and synchronisation
1076                    if (must_check(operation) and not store_queue_empty)
1077                      {
1078                        // load
1079                        need_check = true;
1080                       
1081                        _load_queue [ptr_write]._state = LOAD_QUEUE_WAIT_CHECK;
1082                      }
1083                    else
1084                      {
1085                        // synchronisation
1086                        _load_queue [ptr_write]._state = LOAD_QUEUE_WAIT;
1087                      }
1088                  }
1089                else
1090                  {
1091                    // lock, prefecth, flush and invalidate
1092                    _load_queue [ptr_write]._state = LOAD_QUEUE_COMMIT;
1093                  }
1094              }
1095
1096            Tdcache_address_t address        = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._address;
1097            Tdcache_address_t address_lsb    = (address & _param->_mask_address_lsb);
1098            Tdcache_address_t check_hit_byte = gen_mask_not<Tdcache_address_t>(address_lsb+(memory_size(operation)>>3)-1,address_lsb) & _param->_mask_check_hit_byte;
1099
1100            log_printf(TRACE,Load_store_unit,FUNCTION,"    * address                 : 0x%.8x", address);
1101            log_printf(TRACE,Load_store_unit,FUNCTION,"    * address_lsb             : 0x%.8x", address_lsb);
1102            log_printf(TRACE,Load_store_unit,FUNCTION,"    * operation               : %d", operation);
1103            log_printf(TRACE,Load_store_unit,FUNCTION,"    * memory_size             : %d", memory_size(operation));
1104            log_printf(TRACE,Load_store_unit,FUNCTION,"    * check_hit_byte          : 0x%x", check_hit_byte);
1105
1106            _load_queue [ptr_write]._context_id            = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._context_id;
1107            _load_queue [ptr_write]._front_end_id          = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._front_end_id;
1108            _load_queue [ptr_write]._ooo_engine_id         = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._ooo_engine_id;
1109            _load_queue [ptr_write]._packet_id             = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._packet_id;
1110            _load_queue [ptr_write]._operation             = operation;
1111            _load_queue [ptr_write]._cancel                = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._cancel;
1112            _load_queue [ptr_write]._store_queue_ptr_write = store_queue_ptr_write;
1113            _load_queue [ptr_write]._store_queue_ptr_read  = store_queue_ptr_read ;
1114            _load_queue [ptr_write]._store_queue_empty     = store_queue_empty    ;
1115            _load_queue [ptr_write]._address               = address;
1116            _load_queue [ptr_write]._check_hit_byte        = check_hit_byte;
1117            _load_queue [ptr_write]._check_hit             = 0;
1118            _load_queue [ptr_write]._shift                 = address_lsb<<3;// *8
1119            _load_queue [ptr_write]._is_load_signed        = is_operation_memory_load_signed(operation);
1120            _load_queue [ptr_write]._access_size           = memory_size(operation);
1121            // NOTE : if have an exception, must write in register, because a depend instruction wait the load data.
1122            _load_queue [ptr_write]._write_rd              = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._write_rd             ;
1123            _load_queue [ptr_write]._num_reg_rd            = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._num_reg_rd           ;
1124            _load_queue [ptr_write]._exception             = exception;
1125            _load_queue [ptr_write]._rdata                 = address; // to the exception
1126
1127            switch (_param->_speculative_commit_predictor_scheme)
1128              {
1129
1130              case PREDICTOR_NEVER_TAKE  : {_load_queue [ptr_write]._can_speculative_commit = false; break;}
1131              case PREDICTOR_ALWAYS_TAKE : {_load_queue [ptr_write]._can_speculative_commit = true ; break;}
1132              case PREDICTOR_COUNTER     : {_load_queue [ptr_write]._can_speculative_commit = false; break;} // TODO
1133              default :
1134                {
1135                  // throw ERRORMORPHEO(FUNCTION,_("Invalid predictor scheme.\n"));
1136                  _load_queue [ptr_write]._can_speculative_commit = false;
1137                  break;
1138                }
1139              }
1140           
1141            log_printf(TRACE,Load_store_unit,FUNCTION,"    * speculative_access_queue");
1142            log_printf(TRACE,Load_store_unit,FUNCTION,"      * POP[%d]",(*_speculative_access_queue_control)[0]);
1143           
1144            _speculative_access_queue [(*_speculative_access_queue_control)[0]]._state = SPECULATIVE_ACCESS_QUEUE_EMPTY;
1145           
1146            _speculative_access_queue_control->pop();
1147
1148#ifdef STATISTICS
1149            if (usage_is_set(_usage,USE_STATISTICS))
1150              (*_stat_nb_inst_load) ++;
1151#endif
1152
1153            // Only load need check
1154            if (need_check//  and not store_queue_empty
1155                )
1156//             if (is_operation_memory_load(_load_queue [ptr_write]._operation))
1157              {
1158                log_printf(TRACE,Load_store_unit,FUNCTION,"    * update nb_check");
1159                log_printf(TRACE,Load_store_unit,FUNCTION,"      *     store_queue_ptr_write : %d",store_queue_ptr_write);
1160                log_printf(TRACE,Load_store_unit,FUNCTION,"      *     store_queue_ptr_read  : %d",store_queue_ptr_read );
1161                log_printf(TRACE,Load_store_unit,FUNCTION,"      *     store_queue_empty     : %d",store_queue_empty    );
1162                log_printf(TRACE,Load_store_unit,FUNCTION,"      * reg_STORE_QUEUE_PTR_READ  : %d",reg_STORE_QUEUE_PTR_READ);
1163               
1164                uint32_t i=store_queue_ptr_write;
1165                while (i!=store_queue_ptr_read)
1166                  {
1167                    i=((i==0)?_param->_size_store_queue:i)-1;
1168                   
1169                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * i                         : %d",i);
1170                   
1171                    reg_STORE_QUEUE_NB_CHECK [i] ++;
1172
1173                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * reg_STORE_QUEUE_NB_CHECK 3 [%d] <- %d", i,reg_STORE_QUEUE_NB_CHECK [i]);
1174                  }
1175              }
1176          }
1177
1178        //================================================================
1179        // Interface "DCACHE_RSP"
1180        //================================================================
1181        if ((PORT_READ(in_DCACHE_RSP_VAL[0])== 1) and
1182            (    internal_DCACHE_RSP_ACK == 1))
1183          {
1184            log_printf(TRACE,Load_store_unit,FUNCTION,"  * DCACHE_RSP [0]");
1185
1186            // don't use context_id : because there are one queue for all thread
1187            //Tcontext_t      context_id = PORT_READ(in_DCACHE_RSP_CONTEXT_ID[0]);
1188            Tpacket_t       packet_id  = PORT_READ(in_DCACHE_RSP_PACKET_ID [0]);
1189            Tdcache_data_t  rdata      = PORT_READ(in_DCACHE_RSP_RDATA     [0]);
1190            Tdcache_error_t error      = PORT_READ(in_DCACHE_RSP_ERROR     [0]);
1191
1192            log_printf(TRACE,Load_store_unit,FUNCTION,"    * original packet_id : %d"  , packet_id);
1193            log_printf(TRACE,Load_store_unit,FUNCTION,"    * packet_id          : %d"  , packet_id>>1);
1194            log_printf(TRACE,Load_store_unit,FUNCTION,"    * rdata              : %.8x", rdata);
1195            log_printf(TRACE,Load_store_unit,FUNCTION,"    * error              : %d"  , error);
1196           
1197            if (DCACHE_RSP_IS_LOAD(packet_id) == 1)
1198              {
1199                packet_id >>= 1;
1200
1201                log_printf(TRACE,Load_store_unit,FUNCTION,"    * packet is a LOAD");
1202 
1203#ifdef DEBUG_TEST
1204                if (not have_dcache_rsp(_load_queue [packet_id]._operation))
1205                  throw ERRORMORPHEO(FUNCTION,_("Receive of respons, but the corresponding operation don't wait a respons."));
1206#endif
1207
1208                Tdcache_data_t data = _load_queue [packet_id]._rdata;
1209
1210                log_printf(TRACE,Load_store_unit,FUNCTION,"    * data construction");
1211                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data from cache     : 0x%.8x",rdata);
1212                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data (before)       : 0x%.8x", data);
1213                log_printf(TRACE,Load_store_unit,FUNCTION,"      * check_hit_byte      : 0x%x"  ,_load_queue [packet_id]._check_hit_byte);
1214                for (uint32_t i=0;i<(_param->_size_general_data>>3)/*8*/; ++i)
1215                  // Test if this byte has been checked
1216                  if ((_load_queue [packet_id]._check_hit_byte & (1<<i)) == 0)
1217                    {
1218                      log_printf(TRACE,Load_store_unit,FUNCTION,"      * no previous check ]%d:%d]",(i+1)<<3,i<<3);
1219                      data = insert<Tdcache_data_t>(data,rdata,((i+1)<<3)-1,i<<3);
1220                    }
1221                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data (after)        : 0x%.8x", data);
1222               
1223                _load_queue [packet_id]._rdata = data;
1224               
1225#if defined(DEBUG) and defined(DEBUG_Load_store_unit) and (DEBUG_Load_store_unit == true)
1226                if (log_file_generate)
1227                  {
1228                    // log file
1229                    Tcontext_t num_thread    = get_num_thread(_load_queue [packet_id]._context_id   , _param->_size_context_id   ,
1230                                                              _load_queue [packet_id]._front_end_id , _param->_size_front_end_id ,
1231                                                              _load_queue [packet_id]._ooo_engine_id, _param->_size_ooo_engine_id);
1232                   
1233                    memory_log_file [num_thread] 
1234                      << "[" << simulation_cycle() << "] "
1235                      << std::hex
1236                      << "@ 0x" << std::setfill('0') << std::setw(_param->_size_general_data/4) << _load_queue [packet_id]._address << " -[ Read  ]-> 0x" << std::setfill('0') << std::setw(_param->_size_general_data/4) << _load_queue [packet_id]._rdata << " "
1237                      << std::dec
1238                      << "{" << toString(_load_queue [packet_id]._operation) << "}";
1239                   
1240                    memory_log_file [num_thread] << std::endl;
1241                  }
1242#endif     
1243
1244                if (error != DCACHE_ERROR_NONE)
1245                  {
1246                    log_printf(TRACE,Load_store_unit,FUNCTION,"    * have a bus error !!!");
1247
1248                    _load_queue [packet_id]._exception = EXCEPTION_MEMORY_BUS_ERROR;
1249                    _load_queue [packet_id]._state     = LOAD_QUEUE_COMMIT;
1250
1251                   
1252                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * store_queue_ptr_write : %d", _load_queue[packet_id]._store_queue_ptr_write);
1253                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * store_queue_ptr_read  : %d", _load_queue[packet_id]._store_queue_ptr_read );
1254                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * store_queue_empty     : %d", _load_queue[packet_id]._store_queue_empty    );
1255
1256                    if (not _load_queue[packet_id]._store_queue_empty)
1257                      {
1258                        uint32_t i=_load_queue[packet_id]._store_queue_ptr_write;
1259                       
1260                        while (i!=_load_queue[packet_id]._store_queue_ptr_read)
1261                          {
1262                            i=((i==0)?_param->_size_store_queue:i)-1;
1263                           
1264#ifdef DEBUG
1265                            if (reg_STORE_QUEUE_NB_CHECK [i] == 0)
1266                              throw ERRORMORPHEO(FUNCTION,_("reg_STORE_QUEUE_NB_CHECK must be > 0\n"));
1267#endif
1268                           
1269                            reg_STORE_QUEUE_NB_CHECK [i] --;
1270
1271                            log_printf(TRACE,Load_store_unit,FUNCTION,"              * reg_STORE_QUEUE_NB_CHECK 4 [%d] <- %d", i,reg_STORE_QUEUE_NB_CHECK [i]);
1272
1273                            //i=(i+1)%_param->_size_store_queue;
1274                          }
1275                        _load_queue[packet_id]._store_queue_empty = true; // end of check
1276
1277                      }
1278                  }
1279                else
1280                  {
1281                    log_printf(TRACE,Load_store_unit,FUNCTION,"    * have no bus error.");
1282                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * previous state : %s",toString(_load_queue [packet_id]._state).c_str());
1283
1284                    // FIXME : convention : if bus error, the cache return the fautive address !
1285                    // But, the load's address is aligned !
1286
1287                    switch (_load_queue [packet_id]._state)
1288                      {
1289                      case LOAD_QUEUE_WAIT_CHECK : _load_queue [packet_id]._state = LOAD_QUEUE_COMMIT_CHECK; break;
1290                      case LOAD_QUEUE_WAIT       : _load_queue [packet_id]._state = LOAD_QUEUE_COMMIT      ; break;
1291                      default : throw ERRORMORPHEO(FUNCTION,_("Illegal state (dcache_rsp).")); break;
1292                      }
1293                  }
1294              }
1295            else
1296              {
1297                log_printf(TRACE,Load_store_unit,FUNCTION,"    * packet is a STORE");
1298               
1299                // TODO : les stores ne génére pas de réponse sauf quand c'est un bus error !!!
1300                throw ERRORMORPHEO(FUNCTION,_("dcache_rsp : no respons to a write. (TODO : manage bus error to the store operation.)"));
1301              }
1302           
1303          }
1304       
1305        // this register is to manage the priority of check -> Round robin
1306        reg_LOAD_QUEUE_CHECK_PRIORITY = (reg_LOAD_QUEUE_CHECK_PRIORITY+1)%_param->_size_load_queue;
1307       
1308       
1309#if defined(DEBUG) and (DEBUG>=DEBUG_TRACE)
1310        // ***** dump store queue
1311        log_printf(TRACE,Load_store_unit,FUNCTION,"  * Dump STORE_QUEUE");
1312        log_printf(TRACE,Load_store_unit,FUNCTION,"    * ptr_read : %d",reg_STORE_QUEUE_PTR_READ);
1313       
1314        for (uint32_t i=0; i<_param->_size_store_queue; i++)
1315          {
1316            uint32_t j = (reg_STORE_QUEUE_PTR_READ+i)%_param->_size_store_queue;
1317
1318            log_printf(TRACE,Load_store_unit,FUNCTION,"    [%.4d] %.4d %.4d %.4d, %.4d, %.4d %.1d, %.4d, %.8x %.8x, %.2d %.1d, %.2d %s",
1319                       j,
1320                       _store_queue[j]._context_id          ,
1321                       _store_queue[j]._front_end_id        ,
1322                       _store_queue[j]._ooo_engine_id       ,
1323                       _store_queue[j]._packet_id           ,
1324                       _store_queue[j]._operation           ,
1325                       _store_queue[j]._cancel              ,
1326                       _store_queue[j]._load_queue_ptr_write,
1327                       _store_queue[j]._address             ,
1328                       _store_queue[j]._wdata               ,
1329                     //_store_queue[j]._write_rd            ,
1330                     //_store_queue[j]._num_reg_rd          ,
1331                       _store_queue[j]._exception           ,
1332                       _store_queue[j]._send_commit         ,
1333                       reg_STORE_QUEUE_NB_CHECK  [j]        ,
1334                       toString(_store_queue[j]._state).c_str());
1335          }
1336
1337        // ***** dump speculative_access queue
1338        log_printf(TRACE,Load_store_unit,FUNCTION,"  * Dump SPECULATIVE_ACCESS_QUEUE");
1339       
1340        for (uint32_t i=0; i<_param->_size_speculative_access_queue; i++)
1341          {
1342            uint32_t j = (*_speculative_access_queue_control)[i];
1343
1344            log_printf(TRACE,Load_store_unit,FUNCTION,"    [%.4d] %.4d %.4d %.4d, %.4d, %.4d %.1d, %.4d %.4d %.4d %.1d, %.8x, %.1d %.4d, %.2d, %s",
1345                       j,
1346                       _speculative_access_queue[j]._context_id          ,
1347                       _speculative_access_queue[j]._front_end_id        ,
1348                       _speculative_access_queue[j]._ooo_engine_id       ,
1349                       _speculative_access_queue[j]._packet_id           ,
1350                       _speculative_access_queue[j]._operation           ,
1351                       _speculative_access_queue[j]._cancel              ,
1352                       _speculative_access_queue[j]._load_queue_ptr_write,
1353                       _speculative_access_queue[j]._store_queue_ptr_write,
1354                       _speculative_access_queue[j]._store_queue_ptr_read ,
1355                       _speculative_access_queue[j]._store_queue_empty    ,
1356                       _speculative_access_queue[j]._address             ,
1357                       _speculative_access_queue[j]._write_rd            ,
1358                       _speculative_access_queue[j]._num_reg_rd          ,
1359                       _speculative_access_queue[j]._exception           ,
1360                       toString(_speculative_access_queue[j]._state).c_str());
1361          }
1362
1363        // ***** dump load queue
1364        log_printf(TRACE,Load_store_unit,FUNCTION,"  * Dump LOAD_QUEUE");
1365        log_printf(TRACE,Load_store_unit,FUNCTION,"    * ptr_read_check_priority : %d",reg_LOAD_QUEUE_CHECK_PRIORITY);
1366       
1367        for (uint32_t i=0; i<_param->_size_load_queue; i++)
1368          {
1369            uint32_t j = i;
1370
1371            log_printf(TRACE,Load_store_unit,FUNCTION,"    [%.4d] %.4d %.4d %.4d, %.4d, %.4d %.1d, %.4d %.4d %.1d, %.8x %.1x %.1d %.2d %.1d %.2d, %.8x, %.1d %.4d, %.2d, %s",
1372                       j,
1373                       _load_queue[j]._context_id          ,
1374                       _load_queue[j]._front_end_id        ,
1375                       _load_queue[j]._ooo_engine_id       ,
1376                       _load_queue[j]._packet_id           ,
1377                       _load_queue[j]._operation           ,
1378                       _load_queue[j]._cancel              ,
1379                       _load_queue[j]._store_queue_ptr_write,
1380                       _load_queue[j]._store_queue_ptr_read ,
1381                       _load_queue[j]._store_queue_empty    ,
1382                       _load_queue[j]._address             ,
1383                       _load_queue[j]._check_hit_byte      , 
1384                       _load_queue[j]._check_hit           ,
1385                       _load_queue[j]._shift               ,
1386                       _load_queue[j]._is_load_signed      ,
1387                       _load_queue[j]._access_size         ,
1388                       _load_queue[j]._rdata               ,
1389                       _load_queue[j]._write_rd            ,
1390                       _load_queue[j]._num_reg_rd          ,
1391                       _load_queue[j]._exception           ,
1392                       toString(_load_queue[j]._state).c_str());
1393          }
1394#endif
1395       
1396#ifdef STATISTICS
1397        if (usage_is_set(_usage,USE_STATISTICS))
1398          {
1399            for (uint32_t i=0; i<_param->_size_store_queue; i++)
1400              if (_store_queue[i]._state != STORE_QUEUE_EMPTY)
1401                (*_stat_use_store_queue) ++;
1402            for (uint32_t i=0; i<_param->_size_speculative_access_queue; i++)
1403              if (_speculative_access_queue[i]._state != SPECULATIVE_ACCESS_QUEUE_EMPTY)
1404                (*_stat_use_speculative_access_queue) ++;
1405            for (uint32_t i=0; i<_param->_size_load_queue; i++)
1406              if (_load_queue[i]._state != LOAD_QUEUE_EMPTY)
1407                (*_stat_use_load_queue) ++;
1408          }
1409#endif
1410      }
1411
1412    log_end(Load_store_unit,FUNCTION);
1413  };
1414
1415}; // end namespace load_store_unit
1416}; // end namespace execute_unit
1417}; // end namespace multi_execute_unit
1418}; // end namespace execute_loop
1419}; // end namespace multi_execute_loop
1420}; // end namespace core
1421
1422}; // end namespace behavioural
1423}; // end namespace morpheo             
1424#endif
Note: See TracBrowser for help on using the repository browser.