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_commit_transition.cpp @ 136

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

1) Add new algo in ifetch queue
2) Add Cancel bit
3) new config

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