Ignore:
Timestamp:
Jan 21, 2009, 10:53:13 PM (15 years ago)
Author:
rosiere
Message:

Fix Bug :
1) Load Store Unit : check big endian
2) Commit unit & RAT : add retire_event interface

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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

    r101 r104  
    5757        for (uint32_t i=0, nb_check=0; (nb_check<_param->_nb_port_check) and (i<_param->_size_load_queue); i++)
    5858          {
     59            // Get an index from load queue
    5960            uint32_t index_load = (i + reg_LOAD_QUEUE_CHECK_PRIORITY)%_param->_size_load_queue;
    60            
    61             if (((_load_queue[index_load]._state == LOAD_QUEUE_WAIT_CHECK)   or
     61
     62            // Test if this load must ckecked store queue
     63            if (((_load_queue[index_load]._state == LOAD_QUEUE_WAIT_CHECK) or
    6264                 (_load_queue[index_load]._state == LOAD_QUEUE_COMMIT_CHECK) or
    6365                 (_load_queue[index_load]._state == LOAD_QUEUE_CHECK)) and
     
    6971
    7072                // find a entry that it need a check
    71 
    7273                Tlsq_ptr_t index_store  = _load_queue[index_load]._store_queue_ptr_write;
     74                // Init variable
    7375                bool       end_check    = false;
    7476                bool       change_state = false;
     
    9597                    log_printf(TRACE,Load_store_unit,FUNCTION,"      * index_store : %d",index_store);
    9698                   
     99                    // switch on store_queue state
    97100                    switch (_store_queue[index_store]._state)
    98101                      {
     
    107110                          bool test_thread_id = true;
    108111                         
    109                           // Test thread id.
     112                          // Test thread id
    110113                          if (_param->_have_port_context_id)
    111114                            test_thread_id &= (_load_queue[index_load]._context_id    == _store_queue[index_store]._context_id);
     
    117120                          if (test_thread_id)
    118121                            {
     122                              // the load and store are in the same thread. Now, we must test address.
     123
    119124                              log_printf(TRACE,Load_store_unit,FUNCTION,"        * load and store is the same thread.");
    120                               // the load and store are in the same thread. Now, we must test address.
    121125                              Tdcache_address_t load_addr  = _load_queue [index_load ]._address;
    122126                              Tdcache_address_t store_addr = _store_queue[index_store]._address;
     
    126130                              log_printf(TRACE,Load_store_unit,FUNCTION,"          * load_addr  & mask_address_msb : %.8x.",load_addr  & _param->_mask_address_msb);
    127131                              log_printf(TRACE,Load_store_unit,FUNCTION,"          * store_addr & mask_address_msb : %.8x.",store_addr & _param->_mask_address_msb);
    128                               // Test if the both address target the same word
     132                              // Test if the both address target the same "word"
    129133                              if ((load_addr  & _param->_mask_address_msb) ==
    130134                                  (store_addr & _param->_mask_address_msb))
     
    143147                                  // the only case is (4)
    144148                                 
     149                                  // Read data
    145150                                  Tgeneral_data_t load_data  = _load_queue [index_load ]._rdata  ;
    146151                                  Tgeneral_data_t store_data = _store_queue[index_store]._wdata  ;
    147152                                 
    148                                   log_printf(TRACE,Load_store_unit,FUNCTION,"              * load_data  (init) : %.8x",load_data);
    149                                   log_printf(TRACE,Load_store_unit,FUNCTION,"              * store_data (init) : %.8x",store_data);
     153                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * load_data  (before): 0x%.8x",load_data);
     154                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_data (before): 0x%.8x",store_data);
     155
     156                                  uint32_t store_nb_byte     = (1<<memory_access(_store_queue[index_store]._operation));
     157
     158                                  // Take interval to the store
    150159                                  uint32_t store_num_byte_min = (store_addr & _param->_mask_address_lsb);
    151                                   uint32_t store_num_byte_max = store_num_byte_min+(1<<memory_access(_store_queue[index_store]._operation));
     160                                  uint32_t store_num_byte_max = store_num_byte_min+store_nb_byte;
     161
    152162                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_num_byte_min : %d",store_num_byte_min);
    153163                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * store_num_byte_max : %d",store_num_byte_max);
     
    155165                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit_byte     : %x",_load_queue[index_load]._check_hit_byte);
    156166                                  // The bypass is checked byte per byte
    157                                   for (uint32_t byte=store_num_byte_min; byte<store_num_byte_max; byte ++)
     167                                  // Is same endianness : because to change endianness, we must write in special register. Also the pipeline is flushed.
     168                                  bool is_big_endian = true;
     169
     170                                  for (uint32_t num_store_byte=store_num_byte_min; num_store_byte<store_num_byte_max; num_store_byte ++)
    158171                                    {
    159                                       uint32_t mask  = 1<<byte;
    160                                       uint32_t index = byte<<3;
    161                                       log_printf(TRACE,Load_store_unit,FUNCTION,"              * byte  : %d",byte);
    162                                       log_printf(TRACE,Load_store_unit,FUNCTION,"              * mask  : %d",mask);
    163                                       log_printf(TRACE,Load_store_unit,FUNCTION,"              * index : %d",index);
    164                                       // Accept the bypass if they had not a previous bypass with an another store
     172                                      // Make a mask
     173                                      uint32_t num_load_byte;
     174
     175                                      if (is_big_endian)
     176                                        {
     177                                          // sd 0 : 0 1 2 3 4 5 6 7
     178                                          // ld 0 : 0 1 2 3 4 5 6 7 >>  0
     179                                          // lw 0 :         0 1 2 3 >>  0 -4
     180                                          // lw 4 : 4 5 6 7         >> 32 +4
     181                                          // lh 0 :             0 1 >>  0 -6
     182                                          // lh 2 :         2 3     >> 16 -2
     183                                          // lh 4 :     4 5         >> 32 +2
     184                                          // lh 6 : 6 7             >> 48 +6
     185                                          // lb 0 :               0 >>  0 -7
     186                                          // lb 1 :             1   >>  8 -5
     187                                          // lb 2 :           2     >> 16 -3
     188                                          // lb 3 :         3       >> 24 -1
     189                                          // lb 4 :       4         >> 32 +1
     190                                          // lb 5 :     5           >> 40 +3
     191                                          // lb 6 :   6             >> 48 +5
     192                                          // lb 7 : 7               >> 56 +7
     193
     194                                          // diff : (store_nb_byte + load_nb_byte) - 2*nb_load_byte*((num_store_byte+1)
     195
     196                                          // store duplicate = all store access can be see as full size_data store
     197                                          uint32_t load_nb_byte = (1<<memory_access(_load_queue [index_load ]._operation));
     198
     199//                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * num_store_byte       : %d",num_store_byte);
     200//                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * size_general_data>>3 : %d",(_param->_size_general_data>>3));
     201//                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * load_nb_byte         : %d",load_nb_byte);
     202//                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * x = ((_param->_size_general_data>>3)+load_nb_byte-2*load_nb_byte*(num_store_byte/load_nb_byte+1)) = %d+%d-%d*%d = %d"
     203//                                                      , (_param->_size_general_data>>3)
     204//                                                      , load_nb_byte
     205//                                                      , 2*load_nb_byte
     206//                                                      ,((num_store_byte/load_nb_byte)+1)
     207//                                                      ,((_param->_size_general_data>>3)+load_nb_byte-2*load_nb_byte*((num_store_byte/load_nb_byte)+1)));
     208                                         
     209
     210                                          num_load_byte =num_store_byte+((_param->_size_general_data>>3)+load_nb_byte-2*load_nb_byte*((num_store_byte/load_nb_byte)+1));
     211                                        }
     212                                      else
     213                                        {
     214                                          // sd 0 : 0 1 2 3 4 5 6 7
     215                                          // ld 0 : 0 1 2 3 4 5 6 7 >>  0
     216                                          // lw 0 :         4 5 6 7 >>  0
     217                                          // lw 4 : 0 1 2 3         >> 32
     218                                          // lh 0 :             6 7 >>  0
     219                                          // lh 2 :         4 5     >> 16
     220                                          // lh 4 :     2 3         >> 32
     221                                          // lh 6 : 0 1             >> 48
     222                                          // lb 0 :               7 >>  0
     223                                          // lb 1 :             6   >>  8
     224                                          // lb 2 :           5     >> 16
     225                                          // lb 3 :         4       >> 24
     226                                          // lb 4 :       3         >> 32
     227                                          // lb 5 :     2           >> 40
     228                                          // lb 6 :   1             >> 48
     229                                          // lb 7 : 0               >> 56
     230                                         
     231                                          num_load_byte = num_store_byte;
     232                                        }
     233                                     
     234                                      uint32_t mask  = 1<<num_load_byte;
     235
     236                                      log_printf(TRACE,Load_store_unit,FUNCTION,"              * num_store_byte : %d",num_store_byte);
     237                                      log_printf(TRACE,Load_store_unit,FUNCTION,"              * num_load_byte  : %d",num_load_byte);
     238                                      log_printf(TRACE,Load_store_unit,FUNCTION,"              * mask           : %d",mask);
     239
     240                                      // Accept the bypass if :
     241                                      //   * they have not a previous bypass with an another store
     242                                      //   * it's a valid request of load
    165243                                      if ((_load_queue[index_load]._check_hit_byte&mask)==0)
    166244                                        {
     245                                          // Note : Store is duplicate = all store access can be see as full size_data store
     246
     247                                          uint32_t num_store_bit_min = num_store_byte<<3; //*8
     248//                                         uint32_t num_store_bit_max = num_store_bit_min+8-1;
     249                                          uint32_t num_load_bit_min  = num_load_byte <<3; //*8
     250                                          uint32_t num_load_bit_max  = num_load_bit_min+8-1;
     251
    167252                                          log_printf(TRACE,Load_store_unit,FUNCTION,"              * bypass !!!");
    168                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_old : %.8x", load_data);
    169                                           load_data = insert<Tdcache_data_t>(load_data, store_data, index+8-1, index);
     253//                                        log_printf(TRACE,Load_store_unit,FUNCTION,"              * interval store : [%d:%d]",num_store_bit_max,num_store_bit_min);
     254                                          log_printf(TRACE,Load_store_unit,FUNCTION,"              * interval store : [..:%d]",num_store_bit_min);
     255                                          log_printf(TRACE,Load_store_unit,FUNCTION,"              * interval load  : [%d:%d]",num_load_bit_max,num_load_bit_min);
     256                                          log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_old : 0x%.8x", load_data);
     257
     258                                          load_data = ((((store_data>>num_store_bit_min) & 0xff) << num_load_bit_min) |
     259                                                       mask_not<Tdcache_data_t>(load_data,num_load_bit_max,num_load_bit_min));
     260
    170261                                          _load_queue[index_load]._check_hit_byte |= mask;
    171262                                          _load_queue[index_load]._check_hit       = 1;
    172263                                          change_state = true;
    173264
    174                                           log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_new : %.8x", load_data);
     265                                          log_printf(TRACE,Load_store_unit,FUNCTION,"                * rdata_new : 0x%.8x", load_data);
    175266                                        }
    176267                                    }
    177268
    178269                                  _load_queue[index_load]._rdata = load_data;
     270                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * load_data  (after) : 0x%.8x",load_data);
    179271
    180272                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * check_hit          : %x",_load_queue[index_load]._check_hit);
     
    182274
    183275                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * mask_end_check     : %x",(-1& _param->_mask_address_lsb));
     276                                  log_printf(TRACE,Load_store_unit,FUNCTION,"            * mask_check_hit_byte: %x",_param->_mask_check_hit_byte);
    184277                                  // The check is finish if all bit is set
    185                                   end_check = (_load_queue[index_load]._check_hit_byte == MASK_CHECK_BYTE_HIT);
     278                                  end_check = (_load_queue[index_load]._check_hit_byte == _param->_mask_check_hit_byte);
    186279                                }
    187280                            }
     
    387480
    388481                    // reordering data
    389                     _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);
     482                    _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); 
    390483//                  _store_queue [index]._num_reg_rd           = PORT_READ(in_MEMORY_IN_NUM_REG_RD  [internal_MEMORY_IN_PORT]);
    391484                  }
     
    500593            (PORT_READ(in_DCACHE_REQ_ACK[0]) == 1))
    501594          {
    502             log_printf(TRACE,Load_store_unit,FUNCTION,"  * DCACHE_REQ[0]");
     595            log_printf(TRACE,Load_store_unit,FUNCTION,"  * DCACHE_REQ [0]");
    503596
    504597            switch (internal_DCACHE_REQ_SELECT_QUEUE)
     
    542635            bool         have_exception = (exception != EXCEPTION_MEMORY_NONE);
    543636           
    544            
    545637            if (have_exception)
    546638              _load_queue [ptr_write]._state = LOAD_QUEUE_COMMIT;
     
    570662            Tdcache_address_t address        = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._address;
    571663            Tdcache_address_t address_lsb    = (address & _param->_mask_address_lsb);
    572             Tdcache_address_t check_hit_byte = gen_mask_not<Tdcache_address_t>(address_lsb+memory_access(operation)+1,address_lsb);
    573             _load_queue [ptr_write]._context_id        = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._context_id           ;
    574             _load_queue [ptr_write]._front_end_id      = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._front_end_id         ;
    575             _load_queue [ptr_write]._ooo_engine_id     = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._ooo_engine_id        ;
    576             _load_queue [ptr_write]._packet_id         = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._packet_id            ;
    577             _load_queue [ptr_write]._operation         = operation;
     664            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;
     665
     666            log_printf(TRACE,Load_store_unit,FUNCTION,"    * address                 : 0x%.8x", address);
     667            log_printf(TRACE,Load_store_unit,FUNCTION,"    * address_lsb             : 0x%.8x", address_lsb);
     668            log_printf(TRACE,Load_store_unit,FUNCTION,"    * operation               : %d", operation);
     669            log_printf(TRACE,Load_store_unit,FUNCTION,"    * memory_size             : %d", memory_size(operation));
     670            log_printf(TRACE,Load_store_unit,FUNCTION,"    * check_hit_byte          : 0x%x", check_hit_byte);
     671
     672            _load_queue [ptr_write]._context_id            = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._context_id;
     673            _load_queue [ptr_write]._front_end_id          = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._front_end_id;
     674            _load_queue [ptr_write]._ooo_engine_id         = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._ooo_engine_id;
     675            _load_queue [ptr_write]._packet_id             = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._packet_id;
     676            _load_queue [ptr_write]._operation             = operation;
    578677            _load_queue [ptr_write]._store_queue_ptr_write = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._store_queue_ptr_write;
    579             _load_queue [ptr_write]._address           = address;
    580             _load_queue [ptr_write]._check_hit_byte    = check_hit_byte;
    581             _load_queue [ptr_write]._check_hit         = 0;
    582             _load_queue [ptr_write]._shift             = address<<3;
    583             _load_queue [ptr_write]._is_load_signed    = is_operation_memory_load_signed(operation);
    584             _load_queue [ptr_write]._access_size       = memory_size(operation);
     678            _load_queue [ptr_write]._address               = address;
     679            _load_queue [ptr_write]._check_hit_byte        = check_hit_byte;
     680            _load_queue [ptr_write]._check_hit             = 0;
     681            _load_queue [ptr_write]._shift                 = address_lsb<<3;// *8
     682            _load_queue [ptr_write]._is_load_signed        = is_operation_memory_load_signed(operation);
     683            _load_queue [ptr_write]._access_size           = memory_size(operation);
    585684            // NOTE : if have an exception, must write in register, because a depend instruction wait the load data.
    586             _load_queue [ptr_write]._write_rd          = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._write_rd             ;
     685            _load_queue [ptr_write]._write_rd              = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._write_rd             ;
    587686           
    588             _load_queue [ptr_write]._num_reg_rd        = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._num_reg_rd           ;
    589             _load_queue [ptr_write]._exception         = exception;
    590             _load_queue [ptr_write]._rdata             = address; // to the exception
     687            _load_queue [ptr_write]._num_reg_rd            = _speculative_access_queue [internal_SPECULATIVE_ACCESS_QUEUE_PTR_READ]._num_reg_rd           ;
     688            _load_queue [ptr_write]._exception             = exception;
     689            _load_queue [ptr_write]._rdata                 = address; // to the exception
    591690           
    592691            log_printf(TRACE,Load_store_unit,FUNCTION,"    * speculative_access_queue");
     
    628727#endif
    629728
    630                 _load_queue [packet_id]._rdata = rdata;
     729                Tdcache_data_t data = _load_queue [packet_id]._rdata;
     730
     731                log_printf(TRACE,Load_store_unit,FUNCTION,"    * data construction");
     732                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data from cache     : 0x%.8x",rdata);
     733                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data (before)       : 0x%.8x", data);
     734                log_printf(TRACE,Load_store_unit,FUNCTION,"      * check_hit_byte      : 0x%x"  ,_load_queue [packet_id]._check_hit_byte);
     735                for (uint32_t i=0;i<(_param->_size_general_data>>3)/*8*/; ++i)
     736                  // Test if this byte has been checked
     737                  if ((_load_queue [packet_id]._check_hit_byte & (1<<i)) == 0)
     738                    {
     739                      log_printf(TRACE,Load_store_unit,FUNCTION,"      * no previous check ]%d:%d]",(i+1)<<3,i<<3);
     740                      data = insert<Tdcache_data_t>(data,rdata,((i+1)<<3)-1,i<<3);
     741                    }
     742                log_printf(TRACE,Load_store_unit,FUNCTION,"      * data (after)        : 0x%.8x", data);
     743               
     744                _load_queue [packet_id]._rdata = data;
    631745               
    632746                if (error != DCACHE_ERROR_NONE)
Note: See TracChangeset for help on using the changeset viewer.