Main Page | Modules | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages | Examples

ac_cache.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 
00003 /*  ArchC Cache Library for ArchC architecture simulators
00004     Copyright (C) 2002-2004  The ArchC Team
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 2.1 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Lesser General Public License for more details.
00015 */
00016 
00017 /********************************************************/
00018 /* The ArchC cache simulation class.                    */
00019 /* Author:  Pablo Viana (CIn-UFPE)                      */
00020 /* Contact: pvs@cin.ufpe.br                             */
00021 /*                                                      */
00022 /* The ArchC Team                                       */
00023 /* Computer Systems Laboratory (LSC)                    */
00024 /* IC-UNICAMP                                           */
00025 /* http://www.lsc.ic.unicamp.br                         */
00026 /********************************************************/
00028 
00032 
00033 
00034 
00035 #include "ac_cache.H"
00036 #include "ac_resources.H"
00037 
00039   void ac_cache::tracing(unsigned address, unsigned type)
00040   {
00041 #ifdef  AC_TRACE  
00042       access_type = type;
00043       size_ref = 1;
00044       char * buffer;
00045       buffer = new char [8];
00046       for (int b = 0; b < 8; b++)
00047           buffer[b]=0;
00048       buffer[0] = address;
00049       buffer[4] = size_ref;
00050       buffer[6] = access_type;
00051       buffer[7] = padding;
00052 //      trace.write(buffer, 8);
00053       trace << address << endl;
00054       delete[] buffer;
00055 #endif
00056   }
00057 
00059   void ac_cache::addressing(unsigned address)
00060   {
00062       unsigned offset_field = (AC_WORDSIZE/8) * this->block_size;
00063       unsigned index_field = this->num_sets;
00064       unsigned tag_field = offset_field*index_field;
00065       this->offset = address % offset_field;
00066       this->set = (address/offset_field) % index_field;
00067       this->address_tag = address/tag_field;
00068 //      cout << "ADDRESS TAG: " << address_tag << endl;
00070       slot_tag = (unsigned *)(this->tag + (this->set * this->set_size));
00071       slot_valid = (bool *)(this->valid + (this->set * this->set_size));
00072       hit = -1;                           // reset the hit event
00073       unsigned *test_tag;                 // tag to compare
00074       bool *test_valid;                   // bit_valid to compare
00075 
00076       //Scan the set searching for the tag desired
00077       for(this->element = 0; this->element < this->set_size ; this->element++)
00078       {
00079         test_tag = (unsigned *)(slot_tag + element);
00080         test_valid = (bool *)(slot_valid + element);
00081 
00082         if((*test_tag == address_tag)&&(*test_valid))
00083         {
00084           hit = element;   //It has found the reference in the set. Gets the line number.
00085 //                cout << "Hit at TAG: " << *test_tag << endl;
00086         }
00087       }
00088       //Points to the correct mapped cache line
00089       if(hit!=-1) //Whether had got a hit.
00090       {
00091          slot_data = (char *)(this->Data + (hit + this->set * this->set_size) *this->block_size * AC_WORDSIZE/8);
00092          slot_tag = (unsigned *)(this->tag + (hit + this->set * this->set_size));
00093          slot_valid = (bool *)(this->valid + (hit + this->set * this->set_size));
00094          slot_dirty = (bool *)(this->dirty + (hit + this->set * this->set_size));
00095       }
00096       else    //The data was not found in the set
00097       {
00098          this->element = get_chosen(set);  //chooses the element to be replaced
00099          slot_data = (char *)(this->Data + (this->element + set * this->set_size) *this->block_size * AC_WORDSIZE/8);
00100          slot_tag = (unsigned *)(this->tag + (this->element + set * this->set_size));
00101          slot_valid = (bool *)(this->valid + (this->element + set * this->set_size));
00102          slot_dirty = (bool *)(this->dirty + (this->element + set * this->set_size));
00103       }
00104   }
00105 
00106 
00108   void ac_cache::replaceBlockWrite()
00109   {
00110 
00111            unsigned base_address, f;
00112            switch(replace_status)
00113            {
00114                     case 0:
00115 
00116                          if((isWriteBack())&&(isWriteAllocate())&&(this->next_level != NULL)&&(*slot_valid==true)&&(*slot_dirty==true))
00117                          {
00118 //                              cout << "writingback" << endl;
00119                         this->writingBack();
00120                         break;
00121                          }
00122                          else
00123                          {
00124 //                                  cout << "nao precisa wb" << endl;
00125                                 replace_status++;
00126                          }
00127 
00128 
00129 
00130                     case 1:
00131 //                       cout << "entrando no CASE 1 com status = " << (int)replace_status << endl;
00132 
00133                  if(isWriteAllocate())
00134                  {
00135                         f = ~(0);  //0xFFFFFFF...FFF
00136                         f = (unsigned) (f * block_size * AC_WORDSIZE/8); //0xFFFFFFF...F00 //works as a shift << LOG(blocksize*word size in Bytes)
00137                         base_address = requested_address & f; //cut off the least significant (offset) bits
00138 //                        cout << "Requested address: " << requested_address << endl;
00139                         if(this->next_level != NULL)
00140                         {
00141 //                            cout << "address em replaceWrite: " << hex << base_address << endl;
00142                             this->next_level->request_block(this, base_address, block_size*AC_WORDSIZE/8);
00143                             break;
00144                         }
00145                  }
00146                 else
00147                 {
00148                             replace_status++;
00149                 }
00150 
00151             case 2:
00152 //                       cout << "entrando no CASE 2 com status = " << (int)replace_status << endl;
00153 
00154                  //WRITE LOCAL
00155                  if(isWriteAllocate())
00156                  {
00157                             if(write_size == W_WORD)
00158                             this->ac_storage::write(slot_data + offset - Data, *(ac_word*)datum_ref);
00159                         else if(write_size == W_HALF)
00160                             this->ac_storage::write_half(slot_data + offset - Data, *(unsigned short*)datum_ref);
00161                         else if(write_size == W_BYTE)
00162                             this->ac_storage::write_byte(slot_data + offset - Data, *(char*)datum_ref);
00163                         //DIRTY SUJO
00164                         if(isWriteBack())
00165                         {
00166                             *(slot_dirty) = true;
00167                             this->ready();
00168 //                            replace_status++;
00169                             break;
00170                         }
00171                         else
00172                         {
00173                             replace_status++;
00174                         }
00175                  }
00176                  else
00177                  {
00178                      replace_status++;
00179                  }
00180 
00181             case 3:
00182 //                       cout << "entrando no CASE 3 com status = " << (int)replace_status << endl;
00183 
00184                  if(this->next_level != NULL)
00185                  {
00186                             if(write_size == W_WORD)
00187                             {
00188                             this->next_level->request_write(this, requested_address, *(ac_word*)datum_ref);
00189                             break;
00190                         }
00191                         else if(write_size == W_HALF)
00192                         {
00193                             this->next_level->request_write_half(this, requested_address, *(unsigned short*)datum_ref);
00194                             break;
00195                         }
00196                         else if(write_size == W_BYTE)
00197                         {
00198                             this->next_level->request_write_byte(this, requested_address, *(char*)datum_ref);
00199                             break;
00200                         }
00201                  }
00202 
00203          }
00204   }
00205 
00207   void ac_cache::replaceBlockRead(unsigned address)
00208   {
00209 
00210            unsigned base_address, f;
00211            switch(replace_status)
00212            {
00213                     case 0:
00214                          if((isWriteBack())&&(this->next_level != NULL)&&(*slot_valid==true)&&(*slot_dirty==true))
00215                          {
00216 //                                  cout << "address before WB: " << address << endl;
00217                          this->writingBack();
00218 //                                  cout << "address after WB: " << address << endl;
00219                          break;
00220                  }
00221                          else
00222                          {
00223                                 replace_status++;
00224                          }
00225 
00226                     case 1:
00227 //                       cout << "entrei no case 1 com status = " << (int)replace_status << endl;
00228                  f = ~(0);  //0xFFFFFFF...FFF
00229                  f = (unsigned) (f * block_size * AC_WORDSIZE/8); //0xFFFFFFF...F00 //works as a shift << LOG(blocksize*word size in Bytes)
00230 //                 cout << "f: " << f << endl;
00231 //                 base_address = address & f; //cut off the least significant (offset) bits
00232                  base_address = requested_address & f; //cut off the least significant (offset) bits
00233                  if(this->next_level != NULL)
00234                  {
00235 //                       cout << "address_base em replaceRead: " << hex << base_address << "address: " << address << endl;
00236 //                       cout << "requested address: " << requested_address << endl;
00237                        this->next_level->request_block(this, base_address, block_size*AC_WORDSIZE/8);
00238                        break;
00239                  }
00240 
00241             case 2:
00242                  this->ready();
00243            }
00244   }
00245 
00247   void ac_cache::writingBack()
00248   {
00249               //rebuilding the reference to be stored back in the lower level
00250               unsigned index_shift  = ((AC_WORDSIZE/8) * this->block_size);
00251               unsigned tag_shift = index_shift*this->num_sets;
00252               unsigned base_address = (*slot_tag)*tag_shift + set*index_shift;
00253 //              cout << "tag_shift: " << tag_shift << "index_shift: " << index_shift << endl;
00254 //              cout << "buffer enviado: " << (int)slot_data << endl;
00255               this->next_level->request_write_block(this, base_address, this->slot_data, this->block_size*AC_WORDSIZE/8);
00256 //              cout << "data sent: " << hex << *(unsigned *)(slot_data)  << " Address: " << base_address << endl;
00257               *slot_dirty = false;
00258 
00259   }
00260 
00261 
00262   bool ac_cache::isWriteThrough()
00263   {
00264        if(write_policy & 0x01)
00265            return true;
00266        else
00267            return false;
00268   }
00269 
00270   bool ac_cache::isWriteBack()
00271   {
00272        if(write_policy & 0x02)
00273            return true;
00274        else
00275            return false;
00276   }
00277 
00278   bool ac_cache::isWriteAllocate()
00279   {
00280        if(write_policy & 0x10)
00281            return true;
00282        else
00283            return false;
00284   }
00285 
00286   bool ac_cache::isWriteAround()
00287   {
00288        if(write_policy & 0x20)
00289            return true;
00290        else
00291            return false;
00292   }
00293 
00294 
00296   ac_word ac_cache::read( unsigned address ) /*const*/
00297   {
00298       read_access_type = true;
00299       ac_word data_out;                    //hold the requested Data
00300       this->ac_cache::addressing(address); //slicing the address field
00301 #ifdef  AC_TRACE                           
00302       this->ac_cache::tracing(address, 0); //access trace file registering a read operation
00303 #endif
00304       //Read hit
00305       if(hit != -1){
00306 //         data_out = ac_storage::read(slot_data + offset - Data);
00307       }
00308       //Read Miss
00309       else if (this->next_level != NULL)
00310       {
00311 #ifdef AC_STATS
00312          ac_resources::ac_sim_stats.add_miss(name);
00313 #endif
00314          this->stall();    //Stalls the processor, while the data is being provided
00315 //         replace_status = 0;
00316          requested_address = address;
00317          this->replaceBlockRead(requested_address); // imitando o write, original address
00318       }
00319       data_out = ac_storage::read(slot_data + offset - Data);
00320       //Updates the tracking for replacement policies
00321       this->update(set, element);
00322       return (data_out);
00323   }
00324 
00326   unsigned char ac_cache::read_byte( unsigned address )
00327   {
00328       read_access_type = true;
00329       unsigned char data_out;                    //hold the requested Data
00330       this->ac_cache::addressing(address); //slicing the address field
00331 #ifdef  AC_TRACE                           
00332       this->ac_cache::tracing(address, 0); //access trace file registering a read operation
00333 #endif
00334       //Read hit
00335       if(hit != -1){
00336       }
00337       //Read Miss
00338       else if (this->next_level != NULL)
00339       {
00340 #ifdef AC_STATS
00341          ac_resources::ac_sim_stats.add_miss(name);
00342 #endif
00343          this->stall();    //Stalls the processor, while the data is being provided
00344 //         replace_status = 0;
00345          requested_address = address;
00346          this->replaceBlockRead(requested_address);
00347       }
00348       data_out = ac_storage::read_byte(slot_data + offset - Data);
00349       //Updates the tracking for replacement policies
00350       this->update(set, element);
00351       return (data_out);
00352   }
00353 
00355   ac_Hword ac_cache::read_half( unsigned address )
00356   {
00357       read_access_type = true;
00358       ac_Hword data_out;                    //hold the requested Data
00359       this->ac_cache::addressing(address); //slicing the address field
00360 #ifdef  AC_TRACE                           
00361       this->ac_cache::tracing(address, 0); //access trace file registering a read operation
00362 #endif
00363       //Read hit
00364       if(hit != -1){
00365       }
00366       //Read Miss
00367       else if (this->next_level != NULL)
00368       {
00369 #ifdef AC_STATS
00370          ac_resources::ac_sim_stats.add_miss(name);
00371 #endif
00372          this->stall();    //Stalls the processor, while the data is being provided
00373 //         replace_status = 0;
00374          requested_address = address;
00375          this->replaceBlockRead(requested_address);
00376       }
00377       data_out = ac_storage::read_half(slot_data + offset - Data);
00378       //Updates the tracking for replacement policies
00379       this->update(set, element);
00380       return (data_out);
00381   }
00382 
00383 
00385   void ac_cache::write( unsigned address, ac_word datum )
00386   {
00387       read_access_type = false;
00388       this->ac_cache::addressing(address);        //slicing the address field
00389 #ifdef  AC_TRACE                                  
00390       this->ac_cache::tracing(address, 1);        //access trace file registering a write operation
00391 #endif
00392       //Write hit
00393       if(hit != -1){
00394         //DIRTY SUJO
00395          if(isWriteBack())
00396          {
00397             *(slot_dirty) = true;
00398          }
00399          else if(isWriteThrough())
00400          {
00401             if(this->next_level != NULL)
00402             {
00403                 //WAIT
00404                 this->stall();
00405                 //REQUEST WRITE
00406 //                cout << "datum: " << datum << " slot_data+offset: " << *(ac_word*)(slot_data + offset) << endl;
00407                 if(datum != *(ac_word*)(slot_data + offset))
00408                     this->next_level->request_write(this, address, datum);
00409                 else
00410                     this->ready();
00411             }
00412             //RESPONSE WRITE
00413             //QUANDO CHEGAR, DESATIVA O WAIT
00414          }
00415         //WRITE LOCAL
00416         this->ac_storage::write(slot_data + offset - Data, datum);
00417 //        cout << "escrevendo em " << (slot_data + offset - Data) << endl;
00418       }
00419       //Write Miss
00420       else
00421       {
00422 //              cout << "Miss Write" << endl;
00423 #ifdef AC_STATS
00424          ac_resources::ac_sim_stats.add_miss(name);
00425 #endif
00426          if(this->next_level != NULL)
00427          {
00428             //WAIT
00429             if(!isWriteAround()) //Only if the data must be locally writen
00430                 this->stall();
00431             //ENTRA NA FSM
00432 //            replace_status = 0; //reset FSM
00433             write_size = W_WORD;
00434             *(ac_word*)datum_ref = datum;
00435                 requested_address = address;
00436 //              cout << "FSM" << endl;
00437             this->replaceBlockWrite(); //FSM
00438          }
00439          else
00440          {
00441              *(slot_tag) = address_tag;
00442              *(slot_valid) = true;
00443              *(slot_dirty) = true;
00444              this->ac_storage::write(slot_data + offset - Data, datum);
00445 //             cout << "write local" << endl;
00446          }
00447       }
00448       this->update(set, element);
00449   }
00450 
00451 
00453   void ac_cache::write_byte( unsigned address, unsigned char datum )
00454   {
00455       read_access_type = false;
00456       this->ac_cache::addressing(address);        //slicing the address field
00457 #ifdef  AC_TRACE                                  
00458       this->ac_cache::tracing(address, 1);        //access trace file registering a write operation
00459 #endif
00460       //Write hit
00461       if(hit != -1){
00462         //DIRTY SUJO
00463          if(isWriteBack())
00464          {
00465             *(slot_dirty) = true;
00466          }
00467          else if(isWriteThrough())
00468          {
00469             if(this->next_level != NULL)
00470             {
00471                 //WAIT
00472                 this->stall();
00473                 //REQUEST WRITE
00474                 unsigned char tmp= ac_storage::read_byte(slot_data + offset - Data);
00475                 if(datum != tmp)
00476                     this->next_level->request_write_byte(this, address, datum);
00477                 else
00478                     this->ready();
00479             }
00480          }
00481         //WRITE LOCAL
00482         this->ac_storage::write_byte(slot_data + offset - Data, datum);
00483       }
00484       //Write Miss
00485       else
00486       {
00487 #ifdef AC_STATS
00488          ac_resources::ac_sim_stats.add_miss(name);
00489 #endif
00490          if(this->next_level != NULL)
00491          {
00492             //WAIT
00493             if(!isWriteAround()) //Only if the data must be locally writen
00494                this->stall();
00495             //ENTRA NA FSM
00496 //            replace_status = 0; //reset FSM
00497             write_size = W_BYTE;
00498             *(unsigned char*)datum_ref = datum;
00499                 requested_address = address;
00500             this->replaceBlockWrite(); //FSM
00501          }
00502          else
00503          {
00504              *(slot_tag) = address_tag;
00505              *(slot_valid) = true;
00506              *(slot_dirty) = true;
00507              this->ac_storage::write_byte(slot_data + offset - Data, datum);
00508          }
00509       }
00510       this->update(set, element);
00511   }
00512 
00513 
00515   void ac_cache::write_half( unsigned address, unsigned short datum )
00516   {
00517       read_access_type = false;
00518       this->ac_cache::addressing(address);        //slicing the address field
00519 #ifdef  AC_TRACE                                  
00520       this->ac_cache::tracing(address, 1);        //access trace file registering a write operation
00521 #endif
00522       //Write hit
00523       if(hit != -1){
00524         //DIRTY SUJO
00525          if(isWriteBack())
00526          {
00527             *(slot_dirty) = true;
00528          }
00529          else if(isWriteThrough())
00530          {
00531             if(this->next_level != NULL)
00532             {
00533                 //WAIT
00534                 this->stall();
00535                 //REQUEST WRITE
00536                 unsigned short tmp= ac_storage::read_half(slot_data + offset - Data);
00537                 if(datum != tmp)
00538                     this->next_level->request_write_half(this, address, datum);
00539                 else
00540                     this->ready();
00541             }
00542             //RESPONSE WRITE
00543             //QUANDO CHEGAR, DESATIVA O WAIT
00544          }
00545         //WRITE LOCAL
00546         this->ac_storage::write_half(slot_data + offset - Data, datum);
00547       }
00548       //Write Miss
00549       else
00550       {
00551 #ifdef AC_STATS
00552          ac_resources::ac_sim_stats.add_miss(name);
00553 #endif
00554          if(this->next_level != NULL)
00555          {
00556             //WAIT
00557             if(!isWriteAround()) //Only if the data must be locally writen
00558                 this->stall();
00559             //ENTRA NA FSM
00560 //            replace_status = 0; //reset FSM
00561             write_size = W_HALF;
00562             *(unsigned short*)datum_ref = datum;
00563                 requested_address = address;
00564             this->replaceBlockWrite(); //FSM
00565          }
00566          else
00567          {
00568              *(slot_tag) = address_tag;
00569              *(slot_valid) = true;
00570              *(slot_dirty) = true;
00571              this->ac_storage::write_half(slot_data + offset - Data, datum);
00572          }
00573       }
00574       this->update(set, element);
00575   }
00576 
00582   ac_cache::ac_cache( char *n, unsigned bs, unsigned nb, unsigned ss, unsigned st, unsigned char wp) :
00583     ac_storage(n, bs*nb*(AC_WORDSIZE/8)),
00584     block_size(bs),
00585     num_blocks (nb),
00586     set_size (ss),
00587     num_sets (nb/ss),
00588     strategy (st),
00589     write_policy (wp)
00590   {
00591     request_block_event = false;
00592     request_write_block_event = false;
00593     request_write_event = false;
00594 //      SC_METHOD(process_request);
00595 //    sensitive << *bhv_pc;
00596 
00597         next_level = NULL;
00598         previous_level = NULL;
00599     tag = new unsigned[this->num_blocks];
00600     valid = new bool[this->num_blocks];
00601     dirty = new bool[this->num_blocks];
00602     chosen = new unsigned[this->num_sets];
00603 //    cout << "Chosen reference" << chosen << endl;
00604     tracker = new unsigned[this->num_blocks];
00605 
00606 
00607 //    cout << "Valid reference" << valid << endl;
00608     *valid = false;
00609 
00610     *dirty = false;
00611 //    request_buffer = new char[block_size*(AC_WORDSIZE/8)];
00612     datum_ref = new char[4];
00613 #ifdef AC_TRACE
00614     ac_cache::trace.open(n, ofstream::out);
00615 //        ac_cache::trace.open(n, ofstream::binary);
00616 #endif
00617   }
00618 
00619 
00620 
00621 
00623   ac_cache::~ac_cache(){
00624 
00625 //      fprintf(stderr, "Destruindo a memoria %s \n", this->get_name());
00626 //      fprintf(stderr, "Antes de detonar next 0x%x \n", next_level);
00627 //      next_level = NULL;
00628 //      fprintf(stderr, "Depois de detonar next 0x%x \n", next_level);
00629 //      fprintf(stderr, "Antes de detonar tag 0x%x \n", tag);
00630       delete[] tag;
00631 //      fprintf(stderr, "Antes de detonar Valid 0x%x \n", valid);
00632       delete[] valid;
00633 //      fprintf(stderr, "Antes de detonar dirty 0x%x \n", dirty);
00634       delete[] dirty;
00635 //      fprintf(stderr, "Antes de detonar chosen 0x%x \n", chosen);
00636       delete[] chosen;
00637 //      fprintf(stderr, "Antes de detonar tracker 0x%x \n", tracker);
00638       delete[] tracker;
00639 #ifdef AC_TRACE
00640 //      closing the trace file generated
00641       ac_cache::trace.close();
00642 #endif
00643 //      delete[] request_buffer;
00644 //      fprintf(stderr, "Memoria %s Destruida \n", this->get_name());
00645       delete[] datum_ref;
00646 
00647   }
00648 
00649   void ac_cache::bindTo(ac_cache& lower){  //were ac_cache
00650        this->next_level = &lower;
00651 //       lower.previous_level = this;
00652   }
00653 
00654 
00655   void ac_cache::set_codeSize( unsigned s){
00656     codeSize = s;
00657   }
00658 
00659   unsigned ac_cache::get_chosen(unsigned s){
00660       unsigned maximum = 0;    //initiates the maximum
00661       long double norm;
00662       switch(this->strategy)
00663       {
00664           case LRU:      
00665             for (unsigned t = 0 ; t < (unsigned)this->set_size ; t = t + sizeof(unsigned)) //searches for the maximum age
00666             {
00667                if( *(tracker + s*this->set_size + t) > maximum )
00668                {
00669                    maximum = *(tracker + s*this->set_size + t);
00670                    *(chosen + s) = t;                  //select the entry to be replaced
00671                }
00672                if(*(chosen + s) > this->set_size)
00673                    *(chosen + s) = 0;
00674             }
00675             break;
00676 
00677           case RANDOM:   
00678             srand((int)(chosen + s));
00679             norm = rand();
00680             norm = norm * (this->set_size - 1);
00681             *(chosen + s) = (unsigned)((set_size-1)*(rand()/(double)RAND_MAX));
00682             break;
00683 
00684           default:
00685             *(chosen + s) += 1;
00686             if((*(chosen + s))>=set_size)
00687                 *(chosen + s) = 0;
00688       }
00689 #ifdef AC_DETAIL
00690       printf("Strategia %d: escolhido o %d \n",this->strategy, *(chosen + s));
00691 #endif
00692       return *(chosen + s); 
00693   }
00694 
00696   void ac_cache::update(unsigned s, unsigned e)
00697   {
00698       for (unsigned t = 0 ; t < (unsigned)this->set_size ; t++)
00699       {
00700           *(tracker + s*this->set_size + t) += 1; //incremets all Tracker's entries inside the set
00701       }
00702       *(tracker + s*this->set_size + e) = 0;     //registering the last access
00703   }
00704 
00705   unsigned ac_cache::get_codeSize(){
00706     return codeSize;
00707   }
00708 /*
00709 ################################################################################
00710 ##############           PROCESSOR STALLING              #######################
00711 ################################################################################
00712 */
00713   void ac_cache::stall(){
00714       ac_resources::ac_wait();
00715 //       cout << "Wait "<< this->get_name() << endl;
00716   }
00717 
00718 
00719   void ac_cache::ready(){
00720       ac_resources::ac_release();
00721       this->replace_status = 0;
00722 //       cout << "Ready "<< this->get_name() << endl;
00723   }
00724 
00725 
00726 /*
00727 ################################################################################
00728 ##############                 INTERFACE                 #######################
00729 ################################################################################
00730 */
00731 
00732   void ac_cache::request_block(ac_cache_if* client, unsigned address, unsigned size_bytes)
00733   {
00734 //         cout << "requesting from" << this->get_name() << endl;
00735            // cout << "size in bytes: " << dec << size << endl;
00736        client_global = client;
00737        request_buffer = new char[size_bytes*(AC_WORDSIZE/8)];
00738        for (unsigned offset_word = 0; offset_word < size_bytes; offset_word+=AC_WORDSIZE/8)
00739        {
00740           *(ac_word *)(request_buffer + offset_word) = this->read(address + offset_word);
00741            //cout << "bloco requisitado" << *(ac_word *)(request_buffer + offset_word) << endl;
00742        }
00743        request_block_event = true;
00744        //client->response_block(request_buffer);
00745 
00746    }
00747 
00748   void ac_cache::process_request() {
00749        if (request_write_block_event) {
00750           request_write_block_event = false;
00751           client_global->response_write_block();
00752        }else if (request_block_event) {
00753           request_block_event = false;
00754           client_global->response_block(request_buffer);
00755        }else if (request_write_event) {
00756           request_write_event = false;
00757           client_global->response_write();
00758        }
00759        //while (true)
00760        //{
00761        //            wait(request_block_event);
00762        //      client_global->response_block(request_buffer);
00763        //}
00764   }
00765 
00766   void ac_cache::request_write_byte(ac_cache_if* client, unsigned address, unsigned char datum)
00767   {
00768            client_global = client;
00769        ac_cache::write_byte(address, datum);
00770        request_write_event = true;
00771        //notify(SC_ZERO_TIME, request_write_event);
00772        //client->response_write();
00773   }
00774 
00775   void ac_cache::request_write_half(ac_cache_if* client, unsigned address, unsigned short datum)
00776   {
00777            client_global = client;
00778        ac_cache::write_half(address, datum);
00779        request_write_event = true;
00780        //notify(SC_ZERO_TIME, request_write_event);
00781        //client->response_write();
00782   }
00783 
00784   void ac_cache::request_write(ac_cache_if* client, unsigned address, ac_word datum)
00785   {
00786            client_global = client;
00787        ac_cache::write(address, datum);
00788        request_write_event = true;
00789        //client->response_write();
00790   }
00791 
00792   void ac_cache::request_write_block(ac_cache_if* client, unsigned address, char* datum, unsigned size_bytes)
00793   {
00794            client_global = client;
00795            for (unsigned offset_word = 0; offset_word < size_bytes; offset_word+=AC_WORDSIZE/8)
00796            {
00797            write(address + offset_word, *(ac_word*)(datum + offset_word));
00798 //           cout << "Data stored: " << read(address + offset_word) << endl;
00799        }
00800 
00801        request_write_block_event = true;
00802        //client->response_write_block();
00803   }
00804 
00805   void ac_cache::response_block(char* block)
00806   {
00807        *(slot_tag) = address_tag;
00808 //       cout << "address tag: " << address_tag << endl;
00809        *(slot_valid) = true;
00810        *(slot_dirty) = false;
00811        for (unsigned offset_word = 0; offset_word < block_size; offset_word++)
00812        {
00813            *(ac_word *)(slot_data + offset_word*AC_WORDSIZE/8) = *(ac_word *)(block + offset_word*(AC_WORDSIZE/8));
00814 //           cout << "dado: " << hex << *(ac_word *)(slot_data + offset_word*AC_WORDSIZE/8) << endl;
00815        }
00816        replace_status++;
00817        if(read_access_type)
00818        {
00819             this->replaceBlockRead(requested_address);
00820        }
00821        else
00822        {
00823             this->replaceBlockWrite();
00824        }
00825        delete[] block;
00826   }
00827 
00828 
00829   void ac_cache::response_write_byte()
00830   {
00831 //       this->ready(requested_address);
00832   }
00833 
00834   void ac_cache::response_write_half()
00835   {
00836 //       this->ready(requested_address);
00837   }
00838 
00839   void ac_cache::response_write()
00840   {
00841        this->ready();
00842   }
00843 
00844   void ac_cache::response_write_block()
00845   {
00846         replace_status++;
00847        if(read_access_type)
00848             this->replaceBlockRead(requested_address);
00849        else
00850             this->replaceBlockWrite();
00851   }
00852 
00853 
00854 
00855 
00856 
00857   void ac_cache::bindToNext(ac_cache_if& next)
00858   {
00859        this->next_level = &next;
00860   }
00861 
00862   void ac_cache::bindToPrevious(ac_cache_if& previous)
00863   {
00864 //       this->previous_level = (ac_cache&)&previous;
00865   }
00866 
00867 
00868 

Generated on Thu Jun 24 08:30:05 2004 for ArchC by doxygen 1.3.4