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 @ 145

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

1) add test with SPECINT2K
2) new config of Selftest
3) modif RAT to support multiple depth_save ... but not finish (need fix Update Prediction Table)
4) add Function_pointer but need fix

  • Property svn:keywords set to Id
File size: 67.1 KB
Line 
1#ifdef SYSTEMC
2/*
3 * $Id: Load_store_unit_function_speculative_load_commit_transition.cpp 145 2010-10-13 18:15:51Z 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//          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                                  // TODO : autoriser l'envoie de la donnée !
663                                }
664                            }
665                         
666                          next = true;
667                          break;
668                        }
669                      case STORE_QUEUE_EMPTY :
670                        {
671                          log_printf(TRACE,Load_store_unit,FUNCTION,"      * store is empty ... wait.");
672                          break;
673                        }
674
675                      case STORE_QUEUE_NO_VALID_NO_SPECULATIVE :
676                        {
677                          log_printf(TRACE,Load_store_unit,FUNCTION,"      * store have an invalid entry");
678
679                          if (test_thread_id)
680                            {
681                              end_check    = true; // previous store is invalid -> exception
682                              change_state = true;
683                            }
684                          else
685                            next = true;
686                           
687                          break;
688                        }
689                      }
690                  }
691
692                if (next)
693                  {
694                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * next");
695                    log_printf(TRACE,Load_store_unit,FUNCTION,"                * new store_queue_ptr_write : %d",store_queue_ptr_write);
696
697                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * update reg_STORE_QUEUE_NB_CHECK");
698#ifdef DEBUG
699                    if (reg_STORE_QUEUE_NB_CHECK [store_queue_ptr_write] == 0)
700                      throw ERRORMORPHEO(FUNCTION,_("reg_STORE_QUEUE_NB_CHECK must be > 0\n"));
701#endif
702
703                    reg_STORE_QUEUE_NB_CHECK [store_queue_ptr_write] --;
704
705                    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]);
706
707                    if ((store_queue_ptr_write ==     store_queue_ptr_read) or
708                        (store_queue_ptr_write == reg_STORE_QUEUE_PTR_READ))
709                      {
710//                      store_queue_empty = true;
711                        end_check         = true;
712                        change_state      = true;
713                      }
714
715//                  if (_load_queue[index_load_queue]._store_queue_ptr_write == 0)
716//                    _load_queue[index_load_queue]._store_queue_ptr_write = _param->_size_store_queue-1;
717//                  else
718//                    _load_queue[index_load_queue]._store_queue_ptr_write --;
719                    _load_queue[index_load_queue]._store_queue_ptr_write = store_queue_ptr_write; // because the index store have be decrease
720                    _load_queue[index_load_queue]._store_queue_empty     = store_queue_empty; // because the index store have be decrease
721
722                    // 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"
723                  }
724
725                if (change_state)
726                  {
727                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * change_state");
728                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * end_check : %d",end_check);
729
730                    log_printf(TRACE,Load_store_unit,FUNCTION,"                * state old : %s",toString(_load_queue[index_load_queue]._state).c_str());
731
732                    switch (_load_queue[index_load_queue]._state)
733                      {
734                      case LOAD_QUEUE_WAIT_CHECK   : 
735                        {
736                          if (end_check)
737                            _load_queue[index_load_queue]._state = LOAD_QUEUE_WAIT  ; 
738                          break;
739                        }
740                      case LOAD_QUEUE_COMMIT_CHECK : 
741                        {
742                          if (end_check)
743                            _load_queue[index_load_queue]._state = LOAD_QUEUE_COMMIT; 
744                          else
745                            _load_queue[index_load_queue]._state = LOAD_QUEUE_CHECK; // No commit : check hit and no end
746                          break;
747                        }
748                      case LOAD_QUEUE_CHECK        : 
749                        {
750                          if (end_check)
751                            _load_queue[index_load_queue]._state     = LOAD_QUEUE_COMMIT;
752
753                          // check find a bypass. A speculative load have been committed : report a speculation miss.
754                          if ((_load_queue[index_load_queue]._check_hit != 0) and
755                              (_load_queue[index_load_queue]._write_rd  == 0) // is commit
756                              )
757                            {
758                              _load_queue[index_load_queue]._exception = EXCEPTION_MEMORY_MISS_SPECULATION;
759                              _load_queue[index_load_queue]._write_rd  = 1; // write the good result
760
761#ifdef STATISTICS
762                              if (usage_is_set(_usage,USE_STATISTICS))
763                                (*_stat_nb_inst_load_commit_miss) ++;
764#endif
765                            }
766                         
767                          break;
768                        }
769                      default : break;
770                      }
771                    log_printf(TRACE,Load_store_unit,FUNCTION,"                * state new : %s",toString(_load_queue[index_load_queue]._state).c_str());
772                    log_printf(TRACE,Load_store_unit,FUNCTION,"                * exception : %d",_load_queue[index_load_queue]._exception);
773
774                    if (end_check//  and not store_queue_empty
775                        )
776                      {
777                        log_printf(TRACE,Load_store_unit,FUNCTION,"                * end check, decrease all nb_check");
778                       
779                        uint32_t i=store_queue_ptr_write;
780                        while (i!=store_queue_ptr_read)
781                          {
782                            i=((i==0)?_param->_size_store_queue:i)-1;
783                           
784#ifdef DEBUG
785                            if (reg_STORE_QUEUE_NB_CHECK [i] == 0)
786                              throw ERRORMORPHEO(FUNCTION,_("reg_STORE_QUEUE_NB_CHECK must be > 0\n"));
787#endif
788                           
789                            reg_STORE_QUEUE_NB_CHECK [i] --;
790
791                            log_printf(TRACE,Load_store_unit,FUNCTION,"              * reg_STORE_QUEUE_NB_CHECK 2 [%d] <- %d", i,reg_STORE_QUEUE_NB_CHECK [i]);
792
793                            //i=(i+1)%_param->_size_store_queue;
794                          }
795                       
796                        _load_queue[index_load_queue]._store_queue_empty = true; // end of check
797                      }
798                  }
799              }
800            // else : don't use a port
801          }
802       
803        //================================================================
804        // Interface "MEMORY_IN"
805        //================================================================
806       
807        if ((PORT_READ(in_MEMORY_IN_VAL [internal_MEMORY_IN_PORT]) == 1) and
808            (    internal_MEMORY_IN_ACK  == 1))
809          {
810            log_printf(TRACE,Load_store_unit,FUNCTION,"  * MEMORY_IN [%d]",internal_MEMORY_IN_PORT);
811
812            // Test operation :
813            //~~~~~~~~~~~~~~~~~
814            //  store  in store_queue
815            //  load   in speculation_access_queue
816            //  others in speculation_access_queue
817
818#ifdef DEBUG_TEST
819            if (PORT_READ(in_MEMORY_IN_TYPE [internal_MEMORY_IN_PORT]) != TYPE_MEMORY)
820              throw ERRORMORPHEO(FUNCTION,"The type is different at 'TYPE_MEMORY'");
821#endif
822            Toperation_t    operation            = PORT_READ(in_MEMORY_IN_OPERATION[internal_MEMORY_IN_PORT]);
823            Tcontrol_t      cancel               = PORT_READ(in_MEMORY_IN_CANCEL   [internal_MEMORY_IN_PORT]);
824            Tgeneral_data_t address              = (PORT_READ(in_MEMORY_IN_IMMEDIAT[internal_MEMORY_IN_PORT]) +
825                                                    PORT_READ(in_MEMORY_IN_DATA_RA [internal_MEMORY_IN_PORT]));
826            bool            exception_alignement = (mask_memory_access(operation) & address) != 0;
827                                                   
828            if (is_operation_memory_store(operation) == true)
829              {
830                // =======================
831                // ===== STORE_QUEUE =====
832                // =======================
833                // There a two store request type :
834                //   - first is operation with address and data
835                //   - second is the information of re order buffer : the store become not speculative and can access at the data cache
836
837                log_printf(TRACE,Load_store_unit,FUNCTION,"    * store_queue");
838                log_printf(TRACE,Load_store_unit,FUNCTION,"      * PUSH");
839               
840                // Write pointer is define in rename stage :
841                Tlsq_ptr_t           index         = PORT_READ(in_MEMORY_IN_STORE_QUEUE_PTR_WRITE[internal_MEMORY_IN_PORT]);
842                log_printf(TRACE,Load_store_unit,FUNCTION,"      * index         : %d",index);
843               
844                // Need read : state and exception.
845                Tstore_queue_state_t old_state     = _store_queue [index]._state;
846                Tstore_queue_state_t new_state     = old_state;
847                bool                 update_info   = false;
848
849                Texception_t         old_exception = _store_queue [index]._exception;
850                Texception_t         new_exception = old_exception;
851
852                // Compute next state
853                switch (old_state)
854                  {
855                  case STORE_QUEUE_EMPTY                   :
856                    {
857//                    reg_STORE_QUEUE_INVALID [index] = false; // new first store instruction
858
859                      if (is_operation_memory_store_head(operation) == true)
860                        {
861                          new_state = STORE_QUEUE_NO_VALID_NO_SPECULATIVE;
862
863                          // test if is a speculation
864                          if (operation == OPERATION_MEMORY_STORE_HEAD_KO)
865                            {
866                              new_exception = EXCEPTION_MEMORY_MISS_SPECULATION;
867//                            reg_STORE_QUEUE_INVALID [index] = true;
868                            }
869                          else
870                            new_exception = EXCEPTION_MEMORY_NONE;
871                        }
872                      else
873                        {
874                          new_state = STORE_QUEUE_VALID_SPECULATIVE;
875
876                          // Test if have an exception
877                          if (exception_alignement == true)
878                            new_exception = EXCEPTION_MEMORY_ALIGNMENT;
879                          else
880                            new_exception = EXCEPTION_MEMORY_NONE;
881
882                          update_info = true;
883                        }
884                      break;
885                    }
886                  case STORE_QUEUE_NO_VALID_NO_SPECULATIVE :
887                    {
888#ifdef DEBUG_TEST
889                      if (is_operation_memory_store_head(operation) == true)
890                        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."));
891#endif
892                      // Test if have a new exception (priority : miss_speculation)
893                      if ((exception_alignement == true) and (old_exception == EXCEPTION_MEMORY_NONE))
894                        new_exception = EXCEPTION_MEMORY_ALIGNMENT;
895                     
896                      if (new_exception != EXCEPTION_MEMORY_NONE)
897                        new_state = STORE_QUEUE_COMMIT;
898                      else
899                        new_state = STORE_QUEUE_VALID_NO_SPECULATIVE;
900                     
901                      update_info = true;
902                      break;
903                    }
904                  case STORE_QUEUE_VALID_SPECULATIVE       :
905                    {
906#ifdef DEBUG_TEST
907                      if (is_operation_memory_store_head(operation) == false)
908                        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."));
909#endif
910                      if (operation == OPERATION_MEMORY_STORE_HEAD_KO)
911                        {
912                          new_exception = EXCEPTION_MEMORY_MISS_SPECULATION; // great prioritary
913//                        reg_STORE_QUEUE_INVALID [index] = true;
914                        }
915
916                      if (new_exception != EXCEPTION_MEMORY_NONE)
917                        new_state = STORE_QUEUE_COMMIT;
918                      else
919                        new_state = STORE_QUEUE_VALID_NO_SPECULATIVE;
920                     
921                      break;
922                    }
923                  case STORE_QUEUE_VALID_NO_SPECULATIVE    :
924                  case STORE_QUEUE_COMMIT                  :
925                    {
926                      throw ERRORMORPHEO(FUNCTION,"Invalid state and operation");
927                    }
928                  }
929
930                _store_queue [index]._state     = new_state;
931                _store_queue [index]._exception = new_exception;
932               
933                if (update_info == true)
934                  {
935                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * Update information");
936
937                    _store_queue [index]._context_id           = (not _param->_have_port_context_id   )?0:PORT_READ(in_MEMORY_IN_CONTEXT_ID   [internal_MEMORY_IN_PORT]);
938                    _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]);
939                    _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]);
940                    _store_queue [index]._packet_id            = (not _param->_have_port_rob_ptr      )?0:PORT_READ(in_MEMORY_IN_PACKET_ID    [internal_MEMORY_IN_PORT]);
941                    _store_queue [index]._operation            = operation;
942                    _store_queue [index]._cancel               = cancel   ;
943                    _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]);
944                    _store_queue [index]._address              = address;
945                    _store_queue [index]._send_commit          = false;
946
947                    // reordering data
948                    _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); 
949//                  _store_queue [index]._num_reg_rd           = PORT_READ(in_MEMORY_IN_NUM_REG_RD  [internal_MEMORY_IN_PORT]);
950                  }
951              }
952            else
953              {
954                // ====================================
955                // ===== SPECULATIVE_ACCESS_QUEUE =====
956                // ====================================
957
958                // In speculative access queue, they are many type's request
959                log_printf(TRACE,Load_store_unit,FUNCTION,"    * speculative_access_queue");
960                log_printf(TRACE,Load_store_unit,FUNCTION,"      * PUSH");
961               
962                // Write in reservation station
963                uint32_t     index = _speculative_access_queue_control->push();
964
965                log_printf(TRACE,Load_store_unit,FUNCTION,"      * index : %d", index);
966
967                Texception_t exception;
968
969                if (exception_alignement == true)
970                  exception = EXCEPTION_MEMORY_ALIGNMENT;
971                else
972                  exception = EXCEPTION_MEMORY_NONE;
973                               
974                // if exception, don't access at the cache
975                // NOTE : type "other" (lock, invalidate, flush and sync) can't make an alignement exception (access is equivalent at a 8 bits)
976                _speculative_access_queue [index]._state                = (exception == EXCEPTION_MEMORY_NONE)?SPECULATIVE_ACCESS_QUEUE_WAIT_CACHE:SPECULATIVE_ACCESS_QUEUE_WAIT_LOAD_QUEUE;
977                _speculative_access_queue [index]._context_id           = (not _param->_have_port_context_id   )?0:PORT_READ(in_MEMORY_IN_CONTEXT_ID   [internal_MEMORY_IN_PORT]);
978                _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]);
979                _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]);
980                _speculative_access_queue [index]._packet_id            = (not _param->_have_port_rob_ptr      )?0:PORT_READ(in_MEMORY_IN_PACKET_ID    [internal_MEMORY_IN_PORT]);
981
982                _speculative_access_queue [index]._operation            = operation;
983                _speculative_access_queue [index]._cancel               = cancel   ;
984                _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]);
985                _speculative_access_queue [index]._store_queue_ptr_write= PORT_READ(in_MEMORY_IN_STORE_QUEUE_PTR_WRITE[internal_MEMORY_IN_PORT]);
986                _speculative_access_queue [index]._store_queue_ptr_read = PORT_READ(in_MEMORY_IN_STORE_QUEUE_PTR_READ [internal_MEMORY_IN_PORT]);
987                _speculative_access_queue [index]._store_queue_empty    = PORT_READ(in_MEMORY_IN_STORE_QUEUE_EMPTY    [internal_MEMORY_IN_PORT]);
988                _speculative_access_queue [index]._address              = address;
989                // NOTE : is operation is a load, then they are a result and must write in the register file
990                _speculative_access_queue [index]._write_rd             = is_operation_memory_load(operation);
991                _speculative_access_queue [index]._num_reg_rd           = PORT_READ(in_MEMORY_IN_NUM_REG_RD  [internal_MEMORY_IN_PORT]);
992
993                _speculative_access_queue [index]._exception            = exception;
994              }
995          }
996
997        //================================================================
998        // Interface "DCACHE_REQ"
999        //================================================================
1000        if ((    internal_DCACHE_REQ_VAL  == 1) and
1001            (PORT_READ(in_DCACHE_REQ_ACK[0]) == 1))
1002          {
1003            log_printf(TRACE,Load_store_unit,FUNCTION,"  * DCACHE_REQ [0]");
1004
1005            switch (internal_DCACHE_REQ_SELECT_QUEUE)
1006              {
1007              case SELECT_STORE_QUEUE :
1008                {
1009                  // =======================
1010                  // ===== STORE_QUEUE =====
1011                  // =======================
1012                 
1013                  // Entry flush and increase the read pointer
1014                 
1015                  _store_queue [reg_STORE_QUEUE_PTR_READ]._state = STORE_QUEUE_COMMIT;
1016
1017#if defined(DEBUG) and defined(DEBUG_Load_store_unit) and (DEBUG_Load_store_unit == true)
1018                  if (log_file_generate)
1019                    {
1020                      // log file
1021                      Tcontext_t num_thread    = get_num_thread(_store_queue [reg_STORE_QUEUE_PTR_READ]._context_id   , _param->_size_context_id   ,
1022                                                                _store_queue [reg_STORE_QUEUE_PTR_READ]._front_end_id , _param->_size_front_end_id ,
1023                                                                _store_queue [reg_STORE_QUEUE_PTR_READ]._ooo_engine_id, _param->_size_ooo_engine_id);
1024
1025                      memory_log_file [num_thread] 
1026                        << "[" << simulation_cycle() << "] "
1027                        << std::hex
1028                        << "@ 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 << " "
1029                        << std::dec
1030                        << "{" << toString(_store_queue [reg_STORE_QUEUE_PTR_READ]._operation) << "}";
1031                     
1032                      memory_log_file [num_thread] << std::endl;
1033                    }
1034#endif     
1035
1036
1037                  break;
1038                }
1039              case SELECT_LOAD_QUEUE_SPECULATIVE :
1040                {
1041                  // =========================================
1042                  // ===== SELECT_LOAD_QUEUE_SPECULATIVE =====
1043                  // =========================================
1044
1045                  load_queue_push = true;
1046                  break;
1047                }
1048              case SELECT_LOAD_QUEUE :
1049                {
1050                  throw ERRORMORPHEO(FUNCTION,_("Invalid selection"));
1051                  break;
1052                }
1053
1054                break;
1055              }
1056          }
1057
1058        if (load_queue_push)
1059          {
1060            log_printf(TRACE,Load_store_unit,FUNCTION,"  * load_queue_push");
1061
1062            Tlsq_ptr_t   ptr_write = _speculative_access_queue[internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._load_queue_ptr_write;
1063            Toperation_t operation = _speculative_access_queue[internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._operation;
1064            Texception_t exception = _speculative_access_queue[internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._exception;
1065            bool         have_exception = (exception != EXCEPTION_MEMORY_NONE);
1066            bool         need_check= false;
1067            Tlsq_ptr_t   store_queue_ptr_write = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._store_queue_ptr_write;
1068            Tlsq_ptr_t   store_queue_ptr_read  = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._store_queue_ptr_read ;
1069            Tcontrol_t   store_queue_empty     = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._store_queue_empty    ;
1070           
1071            if (have_exception)
1072              _load_queue [ptr_write]._state = LOAD_QUEUE_COMMIT;
1073            else
1074              {
1075                if (have_dcache_rsp(operation))
1076                  {
1077                    // load and synchronisation
1078                    if (must_check(operation) and not store_queue_empty)
1079                      {
1080                        // load
1081                        need_check = true;
1082                       
1083                        _load_queue [ptr_write]._state = LOAD_QUEUE_WAIT_CHECK;
1084                      }
1085                    else
1086                      {
1087                        // synchronisation
1088                        _load_queue [ptr_write]._state = LOAD_QUEUE_WAIT;
1089                      }
1090                  }
1091                else
1092                  {
1093                    // lock, prefecth, flush and invalidate
1094                    _load_queue [ptr_write]._state = LOAD_QUEUE_COMMIT;
1095                  }
1096              }
1097
1098            Tdcache_address_t address        = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._address;
1099            Tdcache_address_t address_lsb    = (address & _param->_mask_address_lsb);
1100            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;
1101
1102            log_printf(TRACE,Load_store_unit,FUNCTION,"    * address                 : 0x%.8x", address);
1103            log_printf(TRACE,Load_store_unit,FUNCTION,"    * address_lsb             : 0x%.8x", address_lsb);
1104            log_printf(TRACE,Load_store_unit,FUNCTION,"    * operation               : %d", operation);
1105            log_printf(TRACE,Load_store_unit,FUNCTION,"    * memory_size             : %d", memory_size(operation));
1106            log_printf(TRACE,Load_store_unit,FUNCTION,"    * check_hit_byte          : 0x%x", check_hit_byte);
1107
1108            _load_queue [ptr_write]._context_id            = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._context_id;
1109            _load_queue [ptr_write]._front_end_id          = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._front_end_id;
1110            _load_queue [ptr_write]._ooo_engine_id         = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._ooo_engine_id;
1111            _load_queue [ptr_write]._packet_id             = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._packet_id;
1112            _load_queue [ptr_write]._operation             = operation;
1113            _load_queue [ptr_write]._cancel                = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._cancel;
1114            _load_queue [ptr_write]._store_queue_ptr_write = store_queue_ptr_write;
1115            _load_queue [ptr_write]._store_queue_ptr_read  = store_queue_ptr_read ;
1116            _load_queue [ptr_write]._store_queue_empty     = store_queue_empty    ;
1117            _load_queue [ptr_write]._address               = address;
1118            _load_queue [ptr_write]._check_hit_byte        = check_hit_byte;
1119            _load_queue [ptr_write]._check_hit             = 0;
1120            _load_queue [ptr_write]._shift                 = address_lsb<<3;// *8
1121            _load_queue [ptr_write]._is_load_signed        = is_operation_memory_load_signed(operation);
1122            _load_queue [ptr_write]._access_size           = memory_size(operation);
1123            // NOTE : if have an exception, must write in register, because a depend instruction wait the load data.
1124            _load_queue [ptr_write]._write_rd              = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._write_rd             ;
1125            _load_queue [ptr_write]._num_reg_rd            = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._num_reg_rd           ;
1126            _load_queue [ptr_write]._exception             = exception;
1127            _load_queue [ptr_write]._rdata                 = address; // to the exception
1128
1129            switch (_param->_speculative_commit_predictor_scheme)
1130              {
1131
1132              case PREDICTOR_NEVER_TAKE  : {_load_queue [ptr_write]._can_speculative_commit = false; break;}
1133              case PREDICTOR_ALWAYS_TAKE : {_load_queue [ptr_write]._can_speculative_commit = true ; break;}
1134              case PREDICTOR_COUNTER     : {_load_queue [ptr_write]._can_speculative_commit = false; break;} // TODO
1135              default :
1136                {
1137                  // throw ERRORMORPHEO(FUNCTION,_("Invalid predictor scheme.\n"));
1138                  _load_queue [ptr_write]._can_speculative_commit = false;
1139                  break;
1140                }
1141              }
1142           
1143            log_printf(TRACE,Load_store_unit,FUNCTION,"    * speculative_access_queue");
1144            log_printf(TRACE,Load_store_unit,FUNCTION,"      * POP[%d]",(*_speculative_access_queue_control)[0]);
1145           
1146            _speculative_access_queue [(*_speculative_access_queue_control)[0]]._state = SPECULATIVE_ACCESS_QUEUE_EMPTY;
1147           
1148            _speculative_access_queue_control->pop();
1149
1150#ifdef STATISTICS
1151            if (usage_is_set(_usage,USE_STATISTICS))
1152              (*_stat_nb_inst_load) ++;
1153#endif
1154
1155            // Only load need check
1156            if (need_check//  and not store_queue_empty
1157                )
1158//             if (is_operation_memory_load(_load_queue [ptr_write]._operation))
1159              {
1160                log_printf(TRACE,Load_store_unit,FUNCTION,"    * update nb_check");
1161                log_printf(TRACE,Load_store_unit,FUNCTION,"      *     store_queue_ptr_write : %d",store_queue_ptr_write);
1162                log_printf(TRACE,Load_store_unit,FUNCTION,"      *     store_queue_ptr_read  : %d",store_queue_ptr_read );
1163                log_printf(TRACE,Load_store_unit,FUNCTION,"      *     store_queue_empty     : %d",store_queue_empty    );
1164                log_printf(TRACE,Load_store_unit,FUNCTION,"      * reg_STORE_QUEUE_PTR_READ  : %d",reg_STORE_QUEUE_PTR_READ);
1165               
1166                uint32_t i=store_queue_ptr_write;
1167                while (i!=store_queue_ptr_read)
1168                  {
1169                    i=((i==0)?_param->_size_store_queue:i)-1;
1170                   
1171                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * i                         : %d",i);
1172                   
1173                    reg_STORE_QUEUE_NB_CHECK [i] ++;
1174
1175                    log_printf(TRACE,Load_store_unit,FUNCTION,"              * reg_STORE_QUEUE_NB_CHECK 3 [%d] <- %d", i,reg_STORE_QUEUE_NB_CHECK [i]);
1176                  }
1177              }
1178          }
1179
1180        //================================================================
1181        // Interface "DCACHE_RSP"
1182        //================================================================
1183        if ((PORT_READ(in_DCACHE_RSP_VAL[0])== 1) and
1184            (    internal_DCACHE_RSP_ACK == 1))
1185          {
1186            log_printf(TRACE,Load_store_unit,FUNCTION,"  * DCACHE_RSP [0]");
1187
1188            // don't use context_id : because there are one queue for all thread
1189            //Tcontext_t      context_id = PORT_READ(in_DCACHE_RSP_CONTEXT_ID[0]);
1190            Tpacket_t       packet_id  = PORT_READ(in_DCACHE_RSP_PACKET_ID [0]);
1191            Tdcache_data_t  rdata      = PORT_READ(in_DCACHE_RSP_RDATA     [0]);
1192            Tdcache_error_t error      = PORT_READ(in_DCACHE_RSP_ERROR     [0]);
1193
1194            log_printf(TRACE,Load_store_unit,FUNCTION,"    * original packet_id : %d"  , packet_id);
1195            log_printf(TRACE,Load_store_unit,FUNCTION,"    * packet_id          : %d"  , packet_id>>1);
1196            log_printf(TRACE,Load_store_unit,FUNCTION,"    * rdata              : %.8x", rdata);
1197            log_printf(TRACE,Load_store_unit,FUNCTION,"    * error              : %d"  , error);
1198           
1199            if (DCACHE_RSP_IS_LOAD(packet_id) == 1)
1200              {
1201                packet_id >>= 1;
1202
1203                log_printf(TRACE,Load_store_unit,FUNCTION,"    * packet is a LOAD");
1204 
1205#ifdef DEBUG_TEST
1206                if (not have_dcache_rsp(_load_queue [packet_id]._operation))
1207                  throw ERRORMORPHEO(FUNCTION,_("Receive of respons, but the corresponding operation don't wait a respons."));
1208#endif
1209
1210                Tdcache_data_t data = _load_queue [packet_id]._rdata;
1211
1212                log_printf(TRACE,Load_store_unit,FUNCTION,"    * data construction");
1213                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data from cache     : 0x%.8x",rdata);
1214                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data (before)       : 0x%.8x", data);
1215                log_printf(TRACE,Load_store_unit,FUNCTION,"      * check_hit_byte      : 0x%x"  ,_load_queue [packet_id]._check_hit_byte);
1216                for (uint32_t i=0;i<(_param->_size_general_data>>3)/*8*/; ++i)
1217                  // Test if this byte has been checked
1218                  if ((_load_queue [packet_id]._check_hit_byte & (1<<i)) == 0)
1219                    {
1220                      log_printf(TRACE,Load_store_unit,FUNCTION,"      * no previous check ]%d:%d]",(i+1)<<3,i<<3);
1221                      data = insert<Tdcache_data_t>(data,rdata,((i+1)<<3)-1,i<<3);
1222                    }
1223                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data (after)        : 0x%.8x", data);
1224               
1225                _load_queue [packet_id]._rdata = data;
1226               
1227#if defined(DEBUG) and defined(DEBUG_Load_store_unit) and (DEBUG_Load_store_unit == true)
1228                if (log_file_generate)
1229                  {
1230                    // log file
1231                    Tcontext_t num_thread    = get_num_thread(_load_queue [packet_id]._context_id   , _param->_size_context_id   ,
1232                                                              _load_queue [packet_id]._front_end_id , _param->_size_front_end_id ,
1233                                                              _load_queue [packet_id]._ooo_engine_id, _param->_size_ooo_engine_id);
1234                   
1235                    memory_log_file [num_thread] 
1236                      << "[" << simulation_cycle() << "] "
1237                      << std::hex
1238                      << "@ 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 << " "
1239                      << std::dec
1240                      << "{" << toString(_load_queue [packet_id]._operation) << "}";
1241                   
1242                    memory_log_file [num_thread] << std::endl;
1243                  }
1244#endif     
1245
1246                if (error != DCACHE_ERROR_NONE)
1247                  {
1248                    log_printf(TRACE,Load_store_unit,FUNCTION,"    * have a bus error !!!");
1249
1250                    _load_queue [packet_id]._exception = EXCEPTION_MEMORY_BUS_ERROR;
1251                    _load_queue [packet_id]._state     = LOAD_QUEUE_COMMIT;
1252
1253                   
1254                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * store_queue_ptr_write : %d", _load_queue[packet_id]._store_queue_ptr_write);
1255                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * store_queue_ptr_read  : %d", _load_queue[packet_id]._store_queue_ptr_read );
1256                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * store_queue_empty     : %d", _load_queue[packet_id]._store_queue_empty    );
1257
1258                    if (not _load_queue[packet_id]._store_queue_empty)
1259                      {
1260                        uint32_t i=_load_queue[packet_id]._store_queue_ptr_write;
1261                       
1262                        while (i!=_load_queue[packet_id]._store_queue_ptr_read)
1263                          {
1264                            i=((i==0)?_param->_size_store_queue:i)-1;
1265                           
1266#ifdef DEBUG
1267                            if (reg_STORE_QUEUE_NB_CHECK [i] == 0)
1268                              throw ERRORMORPHEO(FUNCTION,_("reg_STORE_QUEUE_NB_CHECK must be > 0\n"));
1269#endif
1270                           
1271                            reg_STORE_QUEUE_NB_CHECK [i] --;
1272
1273                            log_printf(TRACE,Load_store_unit,FUNCTION,"              * reg_STORE_QUEUE_NB_CHECK 4 [%d] <- %d", i,reg_STORE_QUEUE_NB_CHECK [i]);
1274
1275                            //i=(i+1)%_param->_size_store_queue;
1276                          }
1277                        _load_queue[packet_id]._store_queue_empty = true; // end of check
1278
1279                      }
1280                  }
1281                else
1282                  {
1283                    log_printf(TRACE,Load_store_unit,FUNCTION,"    * have no bus error.");
1284                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * previous state : %s",toString(_load_queue [packet_id]._state).c_str());
1285
1286                    // FIXME : convention : if bus error, the cache return the fautive address !
1287                    // But, the load's address is aligned !
1288
1289                    switch (_load_queue [packet_id]._state)
1290                      {
1291                      case LOAD_QUEUE_WAIT_CHECK : _load_queue [packet_id]._state = LOAD_QUEUE_COMMIT_CHECK; break;
1292                      case LOAD_QUEUE_WAIT       : _load_queue [packet_id]._state = LOAD_QUEUE_COMMIT      ; break;
1293                      default : throw ERRORMORPHEO(FUNCTION,_("Illegal state (dcache_rsp).")); break;
1294                      }
1295                  }
1296              }
1297            else
1298              {
1299                log_printf(TRACE,Load_store_unit,FUNCTION,"    * packet is a STORE");
1300               
1301                // TODO : les stores ne génére pas de réponse sauf quand c'est un bus error !!!
1302                throw ERRORMORPHEO(FUNCTION,_("dcache_rsp : no respons to a write. (TODO : manage bus error to the store operation.)"));
1303              }
1304           
1305          }
1306       
1307        // this register is to manage the priority of check -> Round robin
1308        reg_LOAD_QUEUE_CHECK_PRIORITY = (reg_LOAD_QUEUE_CHECK_PRIORITY+1)%_param->_size_load_queue;
1309       
1310       
1311#if defined(DEBUG) and (DEBUG>=DEBUG_TRACE)
1312        // ***** dump store queue
1313        log_printf(TRACE,Load_store_unit,FUNCTION,"  * Dump STORE_QUEUE");
1314        log_printf(TRACE,Load_store_unit,FUNCTION,"    * ptr_read : %d",reg_STORE_QUEUE_PTR_READ);
1315       
1316        for (uint32_t i=0; i<_param->_size_store_queue; i++)
1317          {
1318            uint32_t j = (reg_STORE_QUEUE_PTR_READ+i)%_param->_size_store_queue;
1319
1320            log_printf(TRACE,Load_store_unit,FUNCTION,"    [%.4d] %.4d %.4d %.4d, %.4d, %.4d %.1d, %.4d, %.8x %.8x, %.2d %.1d, %.2d %s",
1321                       j,
1322                       _store_queue[j]._context_id          ,
1323                       _store_queue[j]._front_end_id        ,
1324                       _store_queue[j]._ooo_engine_id       ,
1325                       _store_queue[j]._packet_id           ,
1326                       _store_queue[j]._operation           ,
1327                       _store_queue[j]._cancel              ,
1328                       _store_queue[j]._load_queue_ptr_write,
1329                       _store_queue[j]._address             ,
1330                       _store_queue[j]._wdata               ,
1331                     //_store_queue[j]._write_rd            ,
1332                     //_store_queue[j]._num_reg_rd          ,
1333                       _store_queue[j]._exception           ,
1334                       _store_queue[j]._send_commit         ,
1335                       reg_STORE_QUEUE_NB_CHECK  [j]        ,
1336                       toString(_store_queue[j]._state).c_str());
1337          }
1338
1339        // ***** dump speculative_access queue
1340        log_printf(TRACE,Load_store_unit,FUNCTION,"  * Dump SPECULATIVE_ACCESS_QUEUE");
1341       
1342        for (uint32_t i=0; i<_param->_size_speculative_access_queue; i++)
1343          {
1344            uint32_t j = (*_speculative_access_queue_control)[i];
1345
1346            log_printf(TRACE,Load_store_unit,FUNCTION,"    [%.4d] %.4d %.4d %.4d, %.4d, %.4d %.1d, %.4d %.4d %.4d %.1d, %.8x, %.1d %.4d, %.2d, %s",
1347                       j,
1348                       _speculative_access_queue[j]._context_id          ,
1349                       _speculative_access_queue[j]._front_end_id        ,
1350                       _speculative_access_queue[j]._ooo_engine_id       ,
1351                       _speculative_access_queue[j]._packet_id           ,
1352                       _speculative_access_queue[j]._operation           ,
1353                       _speculative_access_queue[j]._cancel              ,
1354                       _speculative_access_queue[j]._load_queue_ptr_write,
1355                       _speculative_access_queue[j]._store_queue_ptr_write,
1356                       _speculative_access_queue[j]._store_queue_ptr_read ,
1357                       _speculative_access_queue[j]._store_queue_empty    ,
1358                       _speculative_access_queue[j]._address             ,
1359                       _speculative_access_queue[j]._write_rd            ,
1360                       _speculative_access_queue[j]._num_reg_rd          ,
1361                       _speculative_access_queue[j]._exception           ,
1362                       toString(_speculative_access_queue[j]._state).c_str());
1363          }
1364
1365        // ***** dump load queue
1366        log_printf(TRACE,Load_store_unit,FUNCTION,"  * Dump LOAD_QUEUE");
1367        log_printf(TRACE,Load_store_unit,FUNCTION,"    * ptr_read_check_priority : %d",reg_LOAD_QUEUE_CHECK_PRIORITY);
1368       
1369        for (uint32_t i=0; i<_param->_size_load_queue; i++)
1370          {
1371            uint32_t j = i;
1372
1373            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",
1374                       j,
1375                       _load_queue[j]._context_id          ,
1376                       _load_queue[j]._front_end_id        ,
1377                       _load_queue[j]._ooo_engine_id       ,
1378                       _load_queue[j]._packet_id           ,
1379                       _load_queue[j]._operation           ,
1380                       _load_queue[j]._cancel              ,
1381                       _load_queue[j]._store_queue_ptr_write,
1382                       _load_queue[j]._store_queue_ptr_read ,
1383                       _load_queue[j]._store_queue_empty    ,
1384                       _load_queue[j]._address             ,
1385                       _load_queue[j]._check_hit_byte      , 
1386                       _load_queue[j]._check_hit           ,
1387                       _load_queue[j]._shift               ,
1388                       _load_queue[j]._is_load_signed      ,
1389                       _load_queue[j]._access_size         ,
1390                       _load_queue[j]._rdata               ,
1391                       _load_queue[j]._write_rd            ,
1392                       _load_queue[j]._num_reg_rd          ,
1393                       _load_queue[j]._exception           ,
1394                       toString(_load_queue[j]._state).c_str());
1395          }
1396#endif
1397       
1398#ifdef STATISTICS
1399        if (usage_is_set(_usage,USE_STATISTICS))
1400          {
1401            for (uint32_t i=0; i<_param->_size_store_queue; i++)
1402              if (_store_queue[i]._state != STORE_QUEUE_EMPTY)
1403                (*_stat_use_store_queue) ++;
1404            for (uint32_t i=0; i<_param->_size_speculative_access_queue; i++)
1405              if (_speculative_access_queue[i]._state != SPECULATIVE_ACCESS_QUEUE_EMPTY)
1406                (*_stat_use_speculative_access_queue) ++;
1407            for (uint32_t i=0; i<_param->_size_load_queue; i++)
1408              if (_load_queue[i]._state != LOAD_QUEUE_EMPTY)
1409                (*_stat_use_load_queue) ++;
1410          }
1411#endif
1412      }
1413
1414    log_end(Load_store_unit,FUNCTION);
1415  };
1416
1417}; // end namespace load_store_unit
1418}; // end namespace execute_unit
1419}; // end namespace multi_execute_unit
1420}; // end namespace execute_loop
1421}; // end namespace multi_execute_loop
1422}; // end namespace core
1423
1424}; // end namespace behavioural
1425}; // end namespace morpheo             
1426#endif
Note: See TracBrowser for help on using the repository browser.