diff --git a/simulators/c++2/src_simulator/Bridge.cpp b/simulators/c++2/src_simulator/Bridge.cpp index afd7ffbe9dfecc67cf34a9af7dba0df62b89c81b..3a02e9773032eb1c9b649a0796a1c95d51406028 100644 --- a/simulators/c++2/src_simulator/Bridge.cpp +++ b/simulators/c++2/src_simulator/Bridge.cpp @@ -50,93 +50,15 @@ Bridge::Bridge(unsigned int iID, std::string iName, TMLTime iTimePerCycle, unsig void Bridge::CalcTransactionLength(TMLTransaction* iTrans) const{ } -//TMLTransaction* Bridge::getNextBusTransaction(SchedulableCommDevice* iBus) const{ -// return 0; +//Master* Bridge::getConnectedMaster(){ +// return dynamic_cast<Master*>(this); //} -Master* Bridge::getConnectedMaster(){ - return dynamic_cast<Master*>(this); -} - Bridge::~Bridge(){ - //BridgeTransactionListHash::iterator i; - //for(i=_transListHash.begin(); i != _transListHash.end(); ++i){ - // delete i->second; - //} } -//void ForwardTransactionToMaster(TMLTransaction* iTrans){ - //registerTransaction(aNewTrans); -//} - -//Belongs to Master Interface -//TMLTransaction* Bridge::getNextBusTransaction(SchedulableCommDevice* iBus) const{ - //use hash table to find all transactions for the bus which is polling - //return transaction which is runnable first - /*if (_schedulingNeeded) schedule(); - FutureTransactionQueue* aTransQueue = _transListHash[iBus]; - if (aTransQueue==0) return 0; - return aTransQueue->top();*/ -//} - -//void Bridge::schedule(){ - //call getNextTransaction on all buses to which a transaction has been forwarded - //look up in transaction list of the given bus if returned transaction == transaction which finishes first - //select transaction which finishes first _nextTransaction - /*BridgeTransactionListHash::iterator i; - SchedulableCommDevice* aTempBus; - TMLTransaction* aTempTransaction; - TMLTime aRunnableTime=-1; - _nextBus=0; - for(i=_transListHash.begin(); i != _transListHash.end(); ++i){ - aTempBus = i->first; - aTempTransaction = i->second->top(); - if (aTempTransaction == aTempBus->getNextTransaction() && aTempTransaction->getRunnableTime() < aRunnableTime){ - aRunnableTime = aTempTransaction->getRunnableTime(); - _nextBus = aTempBus; - } - } - _schedulingNeeded=false;*/ -//} - -//void Bridge::addTransaction(){ - //delete transaction from hash table - //FutureTransactionQueue* aTransQueue = _transListHash[_nextBus]; - //if (aTransQueue!=0) aTransQueue->pop(); -//} - -//TMLTransaction* Bridge::getNextTransaction(){ - //return next transaction - //if (_schedulingNeeded) schedule(); - //FutureTransactionQueue* aTransQueue = _transListHash[_nextBus]; - //if (aTransQueue==0) return 0; - //return aTransQueue->top(); -//} - -//void Bridge::registerTransaction(TMLTransaction* iTrans){ -//void Bridge::registerTransaction(TMLTransaction* iTrans, Master* iSourceDevice){ - /*SchedulableCommDevice* aNextBus; - TMLChannel* aChannel = iTrans->getChannel(); - if (iTrans->getCommand()->getTask() == aChannel->getBlockedWriteTask()){ - //write transaction - aNextBus = aChannel->getBus(iTrans->getHop()); - - }else{ - //read transaction - aNextBus = aChannel->getBus(aChannel->getNumberOfHops()-iTrans->getHop()-1); - } - // add Transaction to HashTable (based on destination bus) - FutureTransactionQueue* aTransQueue = _transListHash[aNextBus]; - if (aTransQueue==0){ - aTransQueue = new FutureTransactionQueue(); - _transListHash[aNextBus] = aTransQueue; - } - - aTransQueue->push(aNewTrans); - aNextBus->registerTransaction(aNewTrans); - _schedulingNeeded=true; - }*/ -//} +void Bridge::addBusMaster(BusMaster* iMaster){ +} //void Bridge::schedule2HTML(std::ofstream& myfile){ //} diff --git a/simulators/c++2/src_simulator/Bridge.h b/simulators/c++2/src_simulator/Bridge.h index 1619687caee9a943b61f7fb0e61e4a94972710fb..fb6f43f9ba6961f2d6adc84e53d406cb7a1a28d9 100644 --- a/simulators/c++2/src_simulator/Bridge.h +++ b/simulators/c++2/src_simulator/Bridge.h @@ -42,14 +42,13 @@ Ludovic Apvrille, Renaud Pacalet #define BridgeH #include <Slave.h> -#include <Master.h> #include <SchedulableDevice.h> #include <definitions.h> class TMLTransaction; ///Bridge component -class Bridge: public Slave, public Master{ +class Bridge: public Slave{ public: ///Constructor /** @@ -64,26 +63,18 @@ public: \param iTrans Pointer to the transaction to be processed */ void CalcTransactionLength(TMLTransaction* iTrans) const; - ///Returns a pointer to the connected master device if any - /** - \return Pointer to the master device - */ - Master* getConnectedMaster(); - //void schedule(); - //void addTransaction(); - //TMLTransaction* getNextTransaction(); - /////Returns the current transaction if it needs to access the given bus + /////Returns a pointer to the connected master device if any ////** - //\param iBus Pointer to the bus - //\return Pointer to the transaction + //\return Pointer to the master device //*/ - //TMLTransaction* getNextBusTransaction(SchedulableCommDevice* iBus) const; - //TMLTransaction* getScheduleResult() const; - //void registerTransaction(TMLTransaction* iTrans); - //void registerTransaction(TMLTransaction* iTrans, Master* iSourceDevice); - //void ForwardTransactionToMaster(TMLTransaction* iTrans); + //Master* getConnectedMaster(); //void schedule2HTML(std::ofstream& myfile); //void schedule2TXT(std::ofstream& myfile); + ///Adds a new bus master to the internal list + /** + \param iMaster Pointer to bus master + */ + void addBusMaster(BusMaster* iMaster); ///Destructor ~Bridge(); protected: @@ -91,10 +82,6 @@ protected: TMLTime _timePerCycle; ///Buffer size unsigned int _bufferSize; - //mutable BridgeTransactionListHash _transListHash; - //SchedulableCommDevice* _nextBus; - ////Dirty flag of the current scheduling decision - //bool schedulingNeeded; }; #endif diff --git a/simulators/c++2/src_simulator/Bus.cpp b/simulators/c++2/src_simulator/Bus.cpp index 7830250d4bbf6b955026d619d6770f3bbd21fa67..9dc67c3b46cfa146893b0848d4963eec241cba19 100644 --- a/simulators/c++2/src_simulator/Bus.cpp +++ b/simulators/c++2/src_simulator/Bus.cpp @@ -45,121 +45,67 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLTask.h> #include <TMLChannel.h> #include <TransactionListener.h> +#include <WorkloadSource.h> -Bus::Bus(unsigned int iID, std::string iName, TMLLength iBurstSize, unsigned int ibusWidth, TMLTime iTimePerSample): SchedulableCommDevice(iID, iName), _burstSize(iBurstSize), _nextTransaction(_transactionHash.end()), _schedulingNeeded(true), _timePerSample(iTimePerSample), _busWidth(ibusWidth), _busyCycles(0){ - //_myid=++_id; +Bus::Bus(unsigned int iID, std::string iName, WorkloadSource* iScheduler, TMLLength iBurstSize, unsigned int ibusWidth, TMLTime iTimePerSample): SchedulableCommDevice(iID, iName), _scheduler(iScheduler), _burstSize(iBurstSize), _nextTransaction(0), _schedulingNeeded(true), _timePerSample(iTimePerSample), _busWidth(ibusWidth), _busyCycles(0){ _transactList.reserve(BLOCK_SIZE); } Bus::~Bus(){ - /*BusTransPrioTab::iterator i; - std::cout << "Remaining transactions in list of bus " << _name << ": " << _transactionQueue.size() << "\n"; - for (i=_transactionQueue.begin(); i!= _transactionQueue.end(); ++i){ - std::cout << i->second->toString() << "\n" ; - } - std::cout << "added: " << add << " removed: " << remove << " max size: " << _transactionHash.max_size() << std::endl;*/ + delete _scheduler; } void Bus::schedule(){ - TMLTransaction *aTempTrans; - TMLTime aTransTimeFuture=-1; - BusTransHashTab::iterator i, aTransToExecute=_transactionHash.end(), aFutureTrans=_transactionHash.end(); -#ifdef DEBUG_BUS - std::cout << "Bus:schedule: start" << std::endl; -#endif - unsigned int aTransPrio=-1,aTempPrio; - for (i=_transactionHash.begin(); i != _transactionHash.end(); ++i){ - //std::cout << "0" << std::endl; - aTempTrans=i->second; - //std::cout << "1" << std::endl; - if (aTempTrans->getStartTimeOperation()<=_endSchedule){ - //demand in the past - //std::cout << "2" << std::endl; - aTempPrio=i->first->getBusPriority(this); - //std::cout << "2a" << std::endl; - if (aTempPrio<aTransPrio){ - aTransToExecute=i; - aTransPrio=aTempPrio; - } - }else{ - //demand in the future - //std::cout << "3" << std::endl; - if (aTempTrans->getStartTimeOperation()<aTransTimeFuture){ - aTransTimeFuture=aTempTrans->getStartTimeOperation(); - aFutureTrans=i; - } - } - } - if (aTransToExecute==_transactionHash.end()) aTransToExecute=aFutureTrans; - if (aTransToExecute!=_transactionHash.end()){ - _nextTransaction=aTransToExecute; - calcStartTimeLength(); - //FOR_EACH_TRANSLISTENER (*i)->transScheduled(_nextTransaction->second); - } + TMLTime aTimeSlice = _scheduler->schedule(_endSchedule); + _nextTransaction=_scheduler->getNextTransaction(); + if (_nextTransaction!=0) calcStartTimeLength(aTimeSlice); _schedulingNeeded=false; #ifdef DEBUG_BUS - if (_nextTransaction==_transactionHash.end()) + if (_nextTransaction==0) std::cout << "Bus:schedule: decision of BUS " << _name << ": no transaction" << std::endl; else - std::cout << "Bus:schedule: decision of BUS " << _name << ": " << _nextTransaction->second->toString() << std::endl; + std::cout << "Bus:schedule: decision of BUS " << _name << ": " << _nextTransaction->toString() << std::endl; #endif } -void Bus::registerTransaction(TMLTransaction* iTrans, Master* iSourceDevice){ - //std::cout << "within Bus::registerTransaction " << std::endl; - if (iTrans==0){ - _transactionHash.erase(iSourceDevice); - }else{ - _transactionHash[iSourceDevice]=iTrans; - } +void Bus::registerTransaction(){ _schedulingNeeded=true; -#ifdef DEBUG_BUS - std::cout << "Bus:registerTrans: registered at bus " << _name << ": " << iTrans->toString() << std::endl; -#endif - /*std::cout << "Remaining transactions in list of bus " << _name << ": " << _transactionQueue.size() << "\n"; - for (BusMasterPrioTab::iterator i=_transactionQueue.begin(); i!= _transactionQueue.end(); ++i){ - std::cout << i->second->toString() << "\n"; - }*/ } bool Bus::addTransaction(){ - TMLTransaction* aNextTrans=_nextTransaction->second; - _endSchedule = aNextTrans->getEndTime(); - _transactList.push_back(aNextTrans); - _busyCycles += aNextTrans->getOperationLength(); + _endSchedule = _nextTransaction->getEndTime(); + //std::cout << "set end time to " << _endSchedule << "\n"; + _transactList.push_back(_nextTransaction); + _busyCycles += _nextTransaction->getOperationLength(); #ifdef DEBUG_BUS - std::cout << "Bus::addTrans: add trans at bus " << _name << ": " << aNextTrans->toString() << std::endl; + std::cout << "Bus::addTrans: add trans at bus " << _name << ": " << _nextTransaction->toString() << std::endl; #endif - _transactionHash.erase(_nextTransaction); - _nextTransaction = _transactionHash.end(); - /*std::cout << " size: " << _transactionQueue.size() << std::endl; - std::cout << "Remaining transactions in list of bus " << _name << ": " << _transactionQueue.size() << "\n"; - for (BusTransPrioTab::iterator i=_transactionQueue.begin(); i!= _transactionQueue.end(); ++i){ - std::cout << i->second->toString() << "\n"; - }*/ + NOTIFY_TRANS_EXECUTED(_nextTransaction); + _nextTransaction = 0; _schedulingNeeded=true; - //FOR_EACH_TRANSLISTENER (*i)->transExecuted(aNextTrans); - NOTIFY_TRANS_EXECUTED(aNextTrans); return true; } -void Bus::calcStartTimeLength() const{ - TMLTransaction* aNextTrans=_nextTransaction->second; - //aNextTrans->setStartTime(max(((int)_endSchedule)-((int)aNextTrans->getPenalties()),(int)aNextTrans->getStartTime())); - aNextTrans->setStartTime(max(static_cast<int>(_endSchedule)-static_cast<int>(aNextTrans->getPenalties()),static_cast<int>(aNextTrans->getStartTime()))); - //TMLTime aLength = aNextTrans->getVirtualLength()*_timePerSample; - //aLength = (aLength%_busWidth == 0)? aLength/_busWidth : aLength/_busWidth+1; - TMLTime aLength = aNextTrans->getVirtualLength(); +void Bus::calcStartTimeLength(TMLTime iTimeSlice) const{ + _nextTransaction->setStartTime(max(static_cast<int>(_endSchedule)-static_cast<int>(_nextTransaction->getPenalties()),static_cast<int>(_nextTransaction->getStartTime()))); + + //if (_nextTransaction->getOperationLength()!=-1){ + if (iTimeSlice!=0){ + _nextTransaction->setVirtualLength(min(_nextTransaction->getVirtualLength(), iTimeSlice *_busWidth/_timePerSample)); + } + TMLTime aLength = _nextTransaction->getVirtualLength(); + aLength = (aLength%_busWidth == 0)? (aLength/_busWidth)*_timePerSample : (aLength/_busWidth + 1)*_timePerSample; - aNextTrans->setLength(max(aLength, aNextTrans->getOperationLength())); - Slave* aSlave = aNextTrans->getChannel()->getNextSlave(aNextTrans); - if (aSlave!=0) aSlave->CalcTransactionLength(aNextTrans); - //_nextTransaction->setLength(max(_endSchedule,_nextTransaction->getStartTime())-_nextTransaction->getStartTime()+_nextTransaction->getVirtualLength()); + _nextTransaction->setLength(max(aLength, _nextTransaction->getOperationLength())); + //_nextTransaction->setLength(aLength); //TODO: this is not correct if speed of buses differ, max should be taken + + Slave* aSlave = _nextTransaction->getChannel()->getNextSlave(_nextTransaction); + if (aSlave!=0) aSlave->CalcTransactionLength(_nextTransaction); } TMLTransaction* Bus::getNextTransaction(){ if (_schedulingNeeded) schedule(); - return (_nextTransaction==_transactionHash.end())?0:_nextTransaction->second; + return _nextTransaction; } TMLLength Bus::getBurstSize() const{ @@ -288,10 +234,10 @@ TMLTime Bus::getNextSignalChange(bool iInit, std::string& oSigChange, bool& oNoM void Bus::reset(){ //std::cout << "Bus reset" << std::endl; + _scheduler->reset(); SchedulableDevice::reset(); - _nextTransaction=_transactionHash.end(); + _nextTransaction=0; _schedulingNeeded=true; - _transactionHash.clear(); _transactList.clear(); _busyCycles=0; } @@ -304,4 +250,28 @@ void Bus::streamBenchmarks(std::ostream& s) const{ void Bus::streamStateXML(std::ostream& s) const{ streamBenchmarks(s); -} \ No newline at end of file +} + +void Bus::setScheduler(WorkloadSource* iScheduler){ + _scheduler=iScheduler; +} + +std::istream& Bus::readObject(std::istream &is){ + SchedulableDevice::readObject(is); + _scheduler->readObject(is); +#ifdef SAVE_BENCHMARK_VARS + READ_STREAM(is,_busyCycles); + std::cout << "Read: Bus " << _name << " busyCycles: " << _busyCycles << std::endl; +#endif + return is; +} + +std::ostream& Bus::writeObject(std::ostream &os){ + SchedulableDevice::writeObject(os); + _scheduler->writeObject(os); +#ifdef SAVE_BENCHMARK_VARS + WRITE_STREAM(os,_busyCycles); + std::cout << "Write: Bus " << _name << " busyCycles: " << _busyCycles << std::endl; +#endif + return os; +} diff --git a/simulators/c++2/src_simulator/Bus.h b/simulators/c++2/src_simulator/Bus.h index e7853c85edfb3ea1995ff093ae3f8c70dcc3f921..e135739695f7bbb3b4d23c28663dfb27f8712f7c 100644 --- a/simulators/c++2/src_simulator/Bus.h +++ b/simulators/c++2/src_simulator/Bus.h @@ -63,9 +63,10 @@ public: /** \param iID ID of the bus \param iName Name of the bus + \param iScheduler Pointer to the scheduler object \param iBurstSize Size of an atomic bus transaction */ - Bus(unsigned int iID, std::string iName, TMLLength iBurstSize, unsigned int ibusWidth=1, TMLTime iTimePerSample=1); + Bus(unsigned int iID, std::string iName, WorkloadSource* iScheduler, TMLLength iBurstSize, unsigned int ibusWidth=1, TMLTime iTimePerSample=1); ///Destructor virtual ~Bus(); ///Add a transaction waiting for execution to the internal list @@ -73,7 +74,7 @@ public: \param iTrans Pointer to the transaction to add \param iSourceDevice Source device */ - void registerTransaction(TMLTransaction* iTrans, Master* iSourceDevice); + void registerTransaction(); ///Determines the next bus transaction to be executed void schedule(); ///Adds the transaction determined by the scheduling algorithm to the internal list of scheduled transactions @@ -117,24 +118,27 @@ public: virtual void streamBenchmarks(std::ostream& s) const; virtual void reset(); void streamStateXML(std::ostream& s) const; + ///Sets the scheduler object + /** + \param iScheduler Pointer to the scheduler object + */ + void setScheduler(WorkloadSource* iScheduler); + std::istream& readObject(std::istream &is); + std::ostream& writeObject(std::ostream &os); protected: ///Calculates the start time and the length of the next transaction - void calcStartTimeLength() const; - /////Class variable counting the number of Bus instances - //static unsigned int _id; + /** + \param iTimeSlice Bus time slice granted by the scheduler + */ + void calcStartTimeLength(TMLTime iTimeSlice) const; + ///Scheduler + WorkloadSource* _scheduler; ///Size of an atomic bus transaction TMLLength _burstSize; - /////End time of the last scheduled transaction - //TMLTime _endSchedule; ///Pointer to the next transaction to be executed - BusTransHashTab::iterator _nextTransaction; - /////Pointer to the CPU on which the next transaction will be executed - //Master* _nextTransOnCPU; + TMLTransaction* _nextTransaction; ///Dirty flag of the current scheduling decision bool _schedulingNeeded; - ///List containing all queued transactions - //BusMasterPrioTab _masterQueue; - BusTransHashTab _transactionHash; ///List containing all already scheduled transactions TransactionList _transactList; ///Inverse bus speed diff --git a/simulators/c++2/src_simulator/BusMaster.h b/simulators/c++2/src_simulator/BusMaster.h new file mode 100644 index 0000000000000000000000000000000000000000..3e096de4f817f4e9f3081a44d2636a1a2ec512d7 --- /dev/null +++ b/simulators/c++2/src_simulator/BusMaster.h @@ -0,0 +1,162 @@ +/*Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Daniel Knorreck, +Ludovic Apvrille, Renaud Pacalet + * + * ludovic.apvrille AT telecom-paristech.fr + * + * This software is a computer program whose purpose is to allow the + * edition of TURTLE analysis, design and deployment diagrams, to + * allow the generation of RT-LOTOS or Java code from this diagram, + * and at last to allow the analysis of formal validation traces + * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP + * from INRIA Rhone-Alpes. + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. + * + */ + +#ifndef BusMasterH +#define BusMasterH + +#include <definitions.h> +#include <WorkloadSource.h> + +class TMLTransaction; +class SchedulableCommDevice; + +///Class serving as interface between CPUs and buses (more precisely bus schedulers) +class BusMaster: public WorkloadSource{ +public: + ///Constructor + /** + \param iName Name of the bus master + \param iPriority Priority of the bus master + \param iBus Pointer to the bus the master is connected to + */ + BusMaster(const std::string& iName, unsigned int iPriority, SchedulableCommDevice* iBus): WorkloadSource(iPriority), _name(iName), _bus(iBus), _nextTransaction(0){ + } + + ///Destructor + ~BusMaster(){ + std::cout << _name << ": Bus Master deleted\n"; + } + + void reset(){ + _nextTransaction=0; + _contentionDelay=0; + _noTransactions=0; + } + + void registerTransaction(TMLTransaction* iTrans){ + if (iTrans!=_nextTransaction){ + _bus->truncateToBurst(iTrans); + _bus->registerTransaction(); + _nextTransaction=iTrans; + } + } + + TMLTransaction* getNextTransaction() const{ + return _nextTransaction; + } + + void addTransaction(){ + _bus->addTransaction(); + _nextTransaction=0; + } + + ///Indicates whether bus access has been granted + /** + \return Returns true if access has been granted + */ + bool accessGranted(){ + return (_nextTransaction!=0 && _bus->getNextTransaction()==_nextTransaction); + } + + ///Returns the pointer to the bus the master is connected to + /** + \return Pointer to bus + */ + SchedulableCommDevice* getBus(){ + return _bus; + } + + ///Updates the bus contention statistics whenever a new bus transaction is executed + /** + \param iContentionDelay Contention delay of the transaction + */ + void addBusContention(unsigned long iContentionDelay){ + _contentionDelay+=iContentionDelay; + _noTransactions++; + } + + ///Writes benchmarking data to a given stream + /** + \param s Reference to an output stream + */ + void streamBenchmarks(std::ostream& s) const{ + if (_noTransactions!=0) + s << TAG_CONTDELo << " busID=\"" << _bus->getID()<< "\" busName=\"" << _bus->toString() << "\">" << (static_cast<float>(_contentionDelay)/static_cast<float>(_noTransactions)) << TAG_CONTDELc << std::endl; + } + + std::string toString() const{ + return _name; + } + + std::istream& readObject(std::istream &is){ + WorkloadSource::readObject(is); +#ifdef SAVE_BENCHMARK_VARS + READ_STREAM(is,_contentionDelay); + std::cout << "Read: BusMaster " << _name << " contentionDelay: " << _contentionDelay << std::endl; + READ_STREAM(is,_noTransactions); + std::cout << "Read: BusMaster " << _name << " noTransactions: " << _noTransactions << std::endl; +#endif + return is; + } + std::ostream& writeObject(std::ostream &os){ + WorkloadSource::writeObject(os); +#ifdef SAVE_BENCHMARK_VARS + WRITE_STREAM(os,_contentionDelay); + std::cout << "Write: BusMaster " << _name << " contentionDelay: " << _contentionDelay << std::endl; + WRITE_STREAM(os,_noTransactions); + std::cout << "Write: BusMaster " << _name << " noTransactions: " << _noTransactions << std::endl; +#endif + return os; + } + +protected: + ///Name + std::string _name; + ///Pointer to the bus the master is connected to + SchedulableCommDevice* _bus; + ///Transaction + TMLTransaction* _nextTransaction; + ///Sum of the contention delay of all registered transactions + unsigned long _contentionDelay; + ///Number of registered transactions + unsigned long _noTransactions; +}; + +#endif diff --git a/simulators/c++2/src_simulator/BusMasterInfo.h b/simulators/c++2/src_simulator/BusMasterInfo.h deleted file mode 100644 index f16b6cf4f3fb0332563fe98c338ad5265ca9eb05..0000000000000000000000000000000000000000 --- a/simulators/c++2/src_simulator/BusMasterInfo.h +++ /dev/null @@ -1,86 +0,0 @@ -/*Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Daniel Knorreck, -Ludovic Apvrille, Renaud Pacalet - * - * ludovic.apvrille AT telecom-paristech.fr - * - * This software is a computer program whose purpose is to allow the - * edition of TURTLE analysis, design and deployment diagrams, to - * allow the generation of RT-LOTOS or Java code from this diagram, - * and at last to allow the analysis of formal validation traces - * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP - * from INRIA Rhone-Alpes. - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - * - */ - -#ifndef BusMasterInfoH -#define BusMasterInfoH - -///Structure encapsulating information about a bus master and bus accesses it has performed -class BusMasterInfo{ - public: - ///Constructor - /** - \param iPrio Priority of the bus master - */ - BusMasterInfo(unsigned int iPrio):_priority(iPrio), _contentionDelay(0), _noTransactions(0){} - ///Calculates the average contention delay of all registered bus transactions - /** - \return Average contention delay - */ - float getContentionDelay() const{ - return (_noTransactions==0)?0:(static_cast<float>(_contentionDelay)/static_cast<float>(_noTransactions)); - } - ///Updates the internal variables used to calculate the statistics for the average contention delay of a bus master - /** - \param iContentionDelay Contention delay of a recently executed transaction - */ - void addContention(unsigned long iContentionDelay){ - _contentionDelay+=iContentionDelay; - _noTransactions++; - } - ///Returns the priority of the bus master - /** - \return Priority of the bus master - */ - unsigned int getPriority() const{ - return _priority; - } - void reset(){ - _contentionDelay=0; - _noTransactions=0; - } - protected: - ///Priority of the bus master - unsigned int _priority; - ///Sum of the contention delay of all registered transactions - unsigned long _contentionDelay; - ///Number of registered transactions - unsigned long _noTransactions; -}; -#endif diff --git a/simulators/c++2/src_simulator/CPU.cpp b/simulators/c++2/src_simulator/CPU.cpp index f1482594f7634c5f9d777b8a0490385869b38c51..8731901aaa45c62008da098ff668da06fe798e6b 100644 --- a/simulators/c++2/src_simulator/CPU.cpp +++ b/simulators/c++2/src_simulator/CPU.cpp @@ -47,29 +47,21 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLChannel.h> #include <TransactionListener.h> -CPU::CPU(unsigned int iID, std::string iName, WorkloadSource* iScheduler, TMLTime iTimePerCycle, unsigned int iCyclesPerExeci, unsigned int iCyclesPerExecc, unsigned int iPipelineSize, unsigned int iTaskSwitchingCycles, unsigned int iBranchingMissrate, unsigned int iChangeIdleModeCycles, unsigned int iCyclesBeforeIdle, unsigned int ibyteDataSize): SchedulableDevice(iID, iName), _scheduler(iScheduler), _nextTransaction(0), _lastTransaction(0), _busNextTransaction(0), _timePerCycle(iTimePerCycle), +CPU::CPU(unsigned int iID, std::string iName, WorkloadSource* iScheduler, TMLTime iTimePerCycle, unsigned int iCyclesPerExeci, unsigned int iCyclesPerExecc, unsigned int iPipelineSize, unsigned int iTaskSwitchingCycles, unsigned int iBranchingMissrate, unsigned int iChangeIdleModeCycles, unsigned int iCyclesBeforeIdle, unsigned int ibyteDataSize): SchedulableDevice(iID, iName), _scheduler(iScheduler), _nextTransaction(0), _lastTransaction(0), _masterNextTransaction(0), _timePerCycle(iTimePerCycle), #ifdef PENALTIES_ENABLED _pipelineSize(iPipelineSize), _taskSwitchingCycles(iTaskSwitchingCycles),_brachingMissrate(iBranchingMissrate), _changeIdleModeCycles(iChangeIdleModeCycles), _cyclesBeforeIdle(iCyclesBeforeIdle), #endif _cyclesPerExeci(iCyclesPerExeci), _busyCycles(0), _timePerExeci(_cyclesPerExeci*_timePerCycle) #ifdef PENALTIES_ENABLED - ,_taskSwitchingTime(_taskSwitchingCycles*_timePerCycle), _timeBeforeIdle(_cyclesBeforeIdle*_timePerCycle), _changeIdleModeTime(_changeIdleModeCycles*_timePerCycle), _pipelineSizeTimesExeci(_pipelineSize * _timePerExeci),_missrateTimesPipelinesize(_brachingMissrate*_pipelineSize) /*,_branchMissReminder(0), _branchMissTempReminder(0)*/ + ,_taskSwitchingTime(_taskSwitchingCycles*_timePerCycle), _timeBeforeIdle(_cyclesBeforeIdle*_timePerCycle), _changeIdleModeTime(_changeIdleModeCycles*_timePerCycle), _pipelineSizeTimesExeci(_pipelineSize * _timePerExeci),_missrateTimesPipelinesize(_brachingMissrate*_pipelineSize) #endif { - //_myid=++_id; _transactList.reserve(BLOCK_SIZE); } CPU::~CPU(){ - //unsigned int a=0; - TransactionList::iterator i; std::cout << _transactList.size() << " elements in List of " << _name << std::endl; delete _scheduler; - /*for(i=_transactList.begin(); i != _transactList.end(); ++i){ - //std::cout << a++ << ", "; - //delete (*i); - } - std::cout << std::endl;*/ } void CPU::registerTask(TMLTask* iTask){ @@ -79,23 +71,21 @@ void CPU::registerTask(TMLTask* iTask){ TMLTransaction* CPU::getNextTransaction(){ #ifdef BUS_ENABLED - if (_busNextTransaction==0 || _nextTransaction==0){ + if (_masterNextTransaction==0 || _nextTransaction==0){ return _nextTransaction; }else{ #ifdef DEBUG_CPU - std::cout << "CPU:getNT: " << _name << " has bus transacion on bus " << _busNextTransaction->toString() << std::endl; + std::cout << "CPU:getNT: " << _name << " has bus transacion on master " << _masterNextTransaction->toString() << std::endl; #endif - //std::cout << "0" << std::endl; - //if (_nextTransaction==0 || _nextTransaction->getChannel()==0) std::cout << "NULLINGER!!!!!!!!!!!!!!!!!!!!" << std::endl; - SchedulableCommDevice* aTempBus =_nextTransaction->getChannel()->getFirstBus(_nextTransaction); + BusMaster* aTempMaster =_nextTransaction->getChannel()->getFirstMaster(_nextTransaction); //std::cout << "1" << std::endl; - bool aResult = aTempBus->getNextTransaction()==_nextTransaction; + bool aResult = aTempMaster->accessGranted(); //std::cout << "2" << std::endl; - while (aResult && aTempBus!=_busNextTransaction){ + while (aResult && aTempMaster!=_masterNextTransaction){ //std::cout << "3" << std::endl; - aTempBus =_nextTransaction->getChannel()->getNextBus(_nextTransaction); + aTempMaster =_nextTransaction->getChannel()->getNextMaster(_nextTransaction); //std::cout << "4" << std::endl; - aResult = aTempBus->getNextTransaction()==_nextTransaction; + aResult = aTempMaster->accessGranted(); } return (aResult)?_nextTransaction:0; } @@ -104,59 +94,7 @@ TMLTransaction* CPU::getNextTransaction(){ #endif } -/*void CPU::calcStartTimeLength(){ -#ifdef DEBUG_CPU - std::cout << "CPU:calcSTL: scheduling decision of CPU " << _name << ": " << _nextTransaction->toString() << std::endl; -#endif -#ifdef BUS_ENABLED - //std::cout << "get channel " << std::endl; - TMLChannel* aChannel=_nextTransaction->getCommand()->getChannel(); - //std::cout << "after get channel " << std::endl; - if(aChannel==0){ - //std::cout << "no channel " << std::endl; - _busNextTransaction=0; - }else{ - //std::cout << "get bus " << std::endl; - _busNextTransaction=aChannel->getFirstBus(_nextTransaction); - //std::cout << "after get first bus " << std::endl; - if (_busNextTransaction!=0){ - //std::cout << "before register transaction at bus " << std::endl; - _busNextTransaction->registerTransaction(_nextTransaction,this); - //std::cout << "Transaction registered at bus " << std::endl; - } - } -#endif - //round to full cycles!!! - TMLTime aStartTime = max(_endSchedule,_nextTransaction->getRunnableTime()); - TMLTime aReminder = aStartTime % _timePerCycle; - if (aReminder!=0) aStartTime+=_timePerCycle - aReminder; - _nextTransaction->setStartTime(aStartTime); - -#ifdef BUS_ENABLED - if (_busNextTransaction==0){ - _nextTransaction->setLength(_nextTransaction->getVirtualLength()*_timePerExeci); - }else{ - _busNextTransaction->truncateToBurst(_nextTransaction); - } -#else - _nextTransaction->setLength(_nextTransaction->getVirtualLength()*_timePerExeci); -#endif -#ifdef PENALTIES_ENABLED - if (_lastTransaction==0 || _lastTransaction->getCommand()->getTask()!=_nextTransaction->getCommand()->getTask()){ - _nextTransaction->setTaskSwitchingPenalty(_taskSwitchingTime); - } - if ((_nextTransaction->getStartTime()-_endSchedule) >=_timeBeforeIdle){ - _nextTransaction->setIdlePenalty(_changeIdleModeTime); - } - - if (_brachingMissrate!=0){ - _nextTransaction->setBranchingPenalty((_nextTransaction->getVirtualLength()+_branchMissReminder) * _brachingMissrate / 100 *_pipelineSizeTimesExeci); - _branchMissTempReminder = (_nextTransaction->getVirtualLength()+_branchMissReminder) % (100/_brachingMissrate); - } -#endif -}*/ - -void CPU::calcStartTimeLength(){ +void CPU::calcStartTimeLength(TMLTime iTimeSlice){ #ifdef DEBUG_CPU std::cout << "CPU:calcSTL: scheduling decision of CPU " << _name << ": " << _nextTransaction->toString() << std::endl; #endif @@ -166,14 +104,14 @@ void CPU::calcStartTimeLength(){ //std::cout << "after get channel " << std::endl; if(aChannel==0){ //std::cout << "no channel " << std::endl; - _busNextTransaction=0; + _masterNextTransaction=0; }else{ //std::cout << "get bus " << std::endl; - _busNextTransaction=aChannel->getFirstBus(_nextTransaction); + _masterNextTransaction=aChannel->getFirstMaster(_nextTransaction); //std::cout << "after get first bus " << std::endl; - if (_busNextTransaction!=0){ + if (_masterNextTransaction!=0){ //std::cout << "before register transaction at bus " << std::endl; - _busNextTransaction->registerTransaction(_nextTransaction,this); + _masterNextTransaction->registerTransaction(_nextTransaction); //std::cout << "Transaction registered at bus " << std::endl; } } @@ -185,91 +123,39 @@ void CPU::calcStartTimeLength(){ _nextTransaction->setStartTime(aStartTime); #ifdef BUS_ENABLED - if (_busNextTransaction==0){ + if (_masterNextTransaction==0){ #endif //calculate length of transaction - if (_nextTransaction->getOperationLength()!=-1){ + //if (_nextTransaction->getOperationLength()!=-1){ + if (iTimeSlice!=0){ #ifdef PENALTIES_ENABLED - _nextTransaction->setVirtualLength(min(_nextTransaction->getVirtualLength(), 100 * _nextTransaction->getOperationLength()/((_missrateTimesPipelinesize+100) * _timePerExeci))); + _nextTransaction->setVirtualLength(min(_nextTransaction->getVirtualLength(), 100 * iTimeSlice /((_missrateTimesPipelinesize+100) * _timePerExeci))); #else - _nextTransaction->setVirtualLength(min(_nextTransaction->getVirtualLength(),_nextTransaction->getOperationLength() /_timePerExeci)); + _nextTransaction->setVirtualLength(min(_nextTransaction->getVirtualLength(), iTimeSlice /_timePerExeci)); #endif } _nextTransaction->setLength(_nextTransaction->getVirtualLength()*_timePerExeci); #ifdef BUS_ENABLED - }else{ - _busNextTransaction->truncateToBurst(_nextTransaction); } #endif #ifdef PENALTIES_ENABLED + if (_brachingMissrate!=0 && _masterNextTransaction==0){ + _nextTransaction->setBranchingPenalty(_nextTransaction->getVirtualLength() * _brachingMissrate / 100 *_pipelineSizeTimesExeci); + } + if (_lastTransaction==0 || _lastTransaction->getCommand()->getTask()!=_nextTransaction->getCommand()->getTask()){ _nextTransaction->setTaskSwitchingPenalty(_taskSwitchingTime); } + if ((_nextTransaction->getStartTime()-_endSchedule) >=_timeBeforeIdle){ _nextTransaction->setIdlePenalty(_changeIdleModeTime); } - - if (_brachingMissrate!=0){ - //_nextTransaction->setBranchingPenalty((_nextTransaction->getVirtualLength()+_branchMissReminder) * _brachingMissrate / 100 *_pipelineSizeTimesExeci); - _nextTransaction->setBranchingPenalty(_nextTransaction->getVirtualLength() * _brachingMissrate / 100 *_pipelineSizeTimesExeci); - //_branchMissTempReminder = (_nextTransaction->getVirtualLength()+_branchMissReminder) % (100/_brachingMissrate); - } #endif } -/*TMLTime CPU::truncateNextTransAt(TMLTime iTime){ - if (_busNextTransaction==0){ - if (iTime < _nextTransaction->getStartTime()) return 0; - TMLTime aNewDuration = iTime - _nextTransaction->getStartTime(); -#ifdef PENALTIES_ENABLED - TMLTime aStaticPenalty = _nextTransaction->getIdlePenalty() + _nextTransaction->getTaskSwitchingPenalty(); - if (aNewDuration<=aStaticPenalty){ - _nextTransaction->setLength(_timePerExeci); - _nextTransaction->setVirtualLength(1); - if (_brachingMissrate!=0){ - _nextTransaction->setBranchingPenalty((1+ _branchMissReminder) * _brachingMissrate / 100 *_pipelineSizeTimesExeci); - _branchMissTempReminder = (1 +_branchMissReminder) % (100/_brachingMissrate); - } -//#ifdef DEBUG_CPU - std::cout << "CPU:truncateNTA: transaction truncated once\n"; -//#endif - }else{ - int test=0; - aNewDuration-=aStaticPenalty; - std::cout << _name << " virtual length before cut: " << _nextTransaction->getVirtualLength() << std::endl; - _nextTransaction->setVirtualLength(100* aNewDuration /((_missrateTimesPipelinesize+100) * _timePerExeci)); - _nextTransaction->setLength(_nextTransaction->getVirtualLength() *_timePerExeci); - if (_brachingMissrate!=0){ - _nextTransaction->setBranchingPenalty((_nextTransaction->getVirtualLength()+_branchMissReminder) * _brachingMissrate / 100 *_pipelineSizeTimesExeci); - _branchMissTempReminder = (_nextTransaction->getVirtualLength()+_branchMissReminder) % (100/_brachingMissrate); - //std::cout << _name << " wants to cut transaction: " << _nextTransaction->toShortString() << std::endl; - //std::cout << "While loop begin, new duration: " << aNewDuration << " iTime: " << iTime << " startTime: " << _nextTransaction->getStartTime() << std::endl; - while (_nextTransaction->getOperationLength()+_nextTransaction->getBranchingPenalty() < aNewDuration){ - test++; - _nextTransaction->setVirtualLength(_nextTransaction->getVirtualLength()+1); - _nextTransaction->setLength(_nextTransaction->getOperationLength() +_timePerExeci); - _nextTransaction->setBranchingPenalty((_nextTransaction->getVirtualLength()+_branchMissReminder) * _brachingMissrate / 100 *_pipelineSizeTimesExeci); - _branchMissTempReminder = (_nextTransaction->getVirtualLength()+_branchMissReminder) % (100/_brachingMissrate); - } - } -//#ifdef DEBUG_CPU - std::cout << "CPU:truncateNTA: truncate loop executed: " << test << " times.\n"; -//#endif - } -#else - _nextTransaction->setVirtualLength(aNewDuration /_timePerExeci); - _nextTransaction->setLength(_nextTransaction->getVirtualLength() *_timePerExeci); -#endif -#ifdef DEBUG_CPU - std::cout << "CPU:truncateNTA: ### cut transaction at " << _nextTransaction->getVirtualLength() << std::endl; -#endif - } - return _nextTransaction->getOverallLength(); -}*/ - TMLTime CPU::truncateNextTransAt(TMLTime iTime){ - if (_busNextTransaction==0){ + if (_masterNextTransaction==0){ if (iTime < _nextTransaction->getStartTime()) return 0; TMLTime aNewDuration = iTime - _nextTransaction->getStartTime(); #ifdef PENALTIES_ENABLED @@ -302,8 +188,7 @@ TMLTime CPU::truncateNextTransAt(TMLTime iTime){ bool CPU::addTransaction(){ bool aFinish; - //flag=false; - if (_busNextTransaction==0){ + if (_masterNextTransaction==0){ aFinish=true; #ifdef DEBUG_CPU std::cout << _name << "CPU:addT: non bus transaction added" << std::endl; @@ -312,27 +197,23 @@ bool CPU::addTransaction(){ #ifdef DEBUG_CPU std::cout << _name << "CPU:addT: handling bus transaction" << std::endl; #endif - Slave* aLastSlave=_nextTransaction->getChannel()->getNextSlave(_nextTransaction); - SchedulableCommDevice* aFollowingBus =_nextTransaction->getChannel()->getNextBus(_nextTransaction); - if (aFollowingBus==0){ - //std::cout << _name << " bus transaction finished" << std::endl; + //Slave* aLastSlave=_nextTransaction->getChannel()->getNextSlave(_nextTransaction); + BusMaster* aFollowingMaster =_nextTransaction->getChannel()->getNextMaster(_nextTransaction); + if (aFollowingMaster==0){ aFinish=true; - //std::cout << _name << " before loop" << std::endl; - //_busContentionDelay+=_nextTransaction->getStartTime()-max(_endSchedule,_nextTransaction->getRunnableTime()); - //_noBusTransactions++; - SchedulableCommDevice* aTempBus =_nextTransaction->getChannel()->getFirstBus(_nextTransaction); - Slave* aTempSlave= _nextTransaction->getChannel()->getNextSlave(_nextTransaction); //NEW!!! - addBusContention(aTempBus, _nextTransaction->getStartTime()-max(_endSchedule,_nextTransaction->getRunnableTime())); - while (aTempBus!=0){ - aTempBus->addTransaction(); - aTempSlave->addTransaction(_nextTransaction); //NEW!!! - aTempBus =_nextTransaction->getChannel()->getNextBus(_nextTransaction); - aTempSlave= _nextTransaction->getChannel()->getNextSlave(_nextTransaction); //NEW!!! + BusMaster* aTempMaster =_nextTransaction->getChannel()->getFirstMaster(_nextTransaction); + Slave* aTempSlave= _nextTransaction->getChannel()->getNextSlave(_nextTransaction); + aTempMaster->addBusContention(_nextTransaction->getStartTime()-max(_endSchedule,_nextTransaction->getRunnableTime())); + while (aTempMaster!=0){ + aTempMaster->addTransaction(); + aTempSlave->addTransaction(_nextTransaction); + aTempMaster =_nextTransaction->getChannel()->getNextMaster(_nextTransaction); + aTempSlave= _nextTransaction->getChannel()->getNextSlave(_nextTransaction); } }else{ //std::cout << _name << " bus transaction next round" << std::endl; - _busNextTransaction=aFollowingBus; - _busNextTransaction->registerTransaction(_nextTransaction,aLastSlave->getConnectedMaster()); + _masterNextTransaction=aFollowingMaster; + _masterNextTransaction->registerTransaction(_nextTransaction); aFinish=false; } } @@ -342,15 +223,11 @@ bool CPU::addTransaction(){ #endif _nextTransaction->getCommand()->execute(); _endSchedule=_nextTransaction->getEndTime(); + //std::cout << "set end schedule CPU: " << _endSchedule << "\n"; _simulatedTime=max(_simulatedTime,_endSchedule); _transactList.push_back(_nextTransaction); _lastTransaction=_nextTransaction; -//#ifdef PENALTIES_ENABLED -// _branchMissReminder=_branchMissTempReminder; -//#endif _busyCycles+=_nextTransaction->getOverallLength(); - //std::cout << "busyCycles: " << _busyCycles << std::endl; - //FOR_EACH_TRANSLISTENER (*i)->transExecuted(_nextTransaction); NOTIFY_TRANS_EXECUTED(_nextTransaction); _nextTransaction=0; return true; @@ -358,15 +235,11 @@ bool CPU::addTransaction(){ } void CPU::schedule(){ - _scheduler->schedule(_endSchedule); + TMLTime aTimeSlice = _scheduler->schedule(_endSchedule); TMLTransaction* aOldTransaction = _nextTransaction; _nextTransaction=_scheduler->getNextTransaction(); - //if (_nextTransaction!=0) std::cout << "next trans found!!!\n"; - if (aOldTransaction!=0 && aOldTransaction!=_nextTransaction && _busNextTransaction!=0) _busNextTransaction->registerTransaction(0,this); - if (_nextTransaction!=0) calcStartTimeLength(); -} - -void CPU::registerTransaction(TMLTransaction* iTrans, Master* iSourceDevice){ + if (aOldTransaction!=0 && aOldTransaction!=_nextTransaction && _masterNextTransaction!=0) _masterNextTransaction->registerTransaction(0); + if (_nextTransaction!=0) calcStartTimeLength(aTimeSlice); } std::string CPU::toString() const{ @@ -531,27 +404,20 @@ TMLTransaction* CPU::getTransactions1By1(bool iInit){ } void CPU::reset(){ - //std::cout << "CPU reset" << std::endl; - Master::reset(); SchedulableDevice::reset(); + _scheduler->reset(); _transactList.clear(); _nextTransaction=0; _lastTransaction=0; - _busNextTransaction=0; + _masterNextTransaction=0; _busyCycles=0; -//#ifdef PENALTIES_ENABLED -// _branchMissReminder=0; -// _branchMissTempReminder=0; -//#endif } void CPU::streamBenchmarks(std::ostream& s) const{ s << TAG_CPUo << " id=\"" << _ID << "\" name=\"" << _name << "\">" << std::endl; if (_simulatedTime!=0) s << TAG_UTILo << (static_cast<float>(_busyCycles)/static_cast<float>(_simulatedTime)) << TAG_UTILc; - Master::streamBenchmarks(s); + for(BusMasterList::const_iterator i=_busMasterList.begin(); i != _busMasterList.end(); ++i) (*i)->streamBenchmarks(s); s << TAG_CPUc; - //if (_noBusTransactions!=0) s << "Average BUS contention delay: " << ((float)_busContentionDelay)/((float)_noBusTransactions) << std::endl; - } void CPU::streamStateXML(std::ostream& s) const{ @@ -561,3 +427,29 @@ void CPU::streamStateXML(std::ostream& s) const{ void CPU::setScheduler(WorkloadSource* iScheduler){ _scheduler=iScheduler; } + +void CPU::registerTransaction(){ +} + +void CPU::addBusMaster(BusMaster* iMaster){ + _busMasterList.push_back(iMaster); +} + +std::istream& CPU::readObject(std::istream &is){ + SchedulableDevice::readObject(is); + _scheduler->readObject(is); +#ifdef SAVE_BENCHMARK_VARS + READ_STREAM(is,_busyCycles); + std::cout << "Read: CPU " << _name << " busy cycles: " << _busyCycles << std::endl; +#endif + return is; +} +std::ostream& CPU::writeObject(std::ostream &os){ + SchedulableDevice::writeObject(os); + _scheduler->writeObject(os); +#ifdef SAVE_BENCHMARK_VARS + WRITE_STREAM(os,_busyCycles); + std::cout << "Write: CPU " << _name << " busy cycles: " << _busyCycles << std::endl; +#endif + return os; +} diff --git a/simulators/c++2/src_simulator/CPU.h b/simulators/c++2/src_simulator/CPU.h index a5f02b46300730ef7b73f2cb1a4907176001f602..755915c94e9190442f0c077adf4aaf7ca7d0c347 100644 --- a/simulators/c++2/src_simulator/CPU.h +++ b/simulators/c++2/src_simulator/CPU.h @@ -45,7 +45,7 @@ Ludovic Apvrille, Renaud Pacalet #include <SchedulableDevice.h> #include <SchedulableCommDevice.h> #include <TraceableDevice.h> -#include <Master.h> +#include <BusMaster.h> class TMLTask; class TMLTransaction; @@ -59,7 +59,7 @@ enum vcdCPUVisState }; ///Simulates the bahavior of a CPU and an operating system -class CPU: public SchedulableDevice, public TraceableDevice, public Master{ +class CPU: public SchedulableDevice, public TraceableDevice{ public: ///Constructor /** @@ -91,7 +91,7 @@ public: \param iTrans Pointer to the transaction to add \param iSourceDevice Source device */ - virtual void registerTransaction(TMLTransaction* iTrans, Master* iSourceDevice); + void registerTransaction(); ///Adds the transaction determined by the scheduling algorithm to the internal list of scheduled transactions virtual bool addTransaction(); ///Returns a pointer to the transaction determined by the scheduling algorithm @@ -139,9 +139,19 @@ public: \param iScheduler Pointer to the scheduler object */ void setScheduler(WorkloadSource* iScheduler); + ///Adds a new bus master to the internal list + /** + \param iMaster Pointer to bus master + */ + void addBusMaster(BusMaster* iMaster); + std::istream& readObject(std::istream &is); + std::ostream& writeObject(std::ostream &os); protected: ///Calculates the start time and the length of the next transaction - void calcStartTimeLength(); + /** + \param iTimeSlice CPU Time slice granted by the scheduler + */ + void calcStartTimeLength(TMLTime iTimeSlice); ///List of all tasks running on the CPU TaskList _taskList; ///List containing all already scheduled transactions @@ -153,10 +163,11 @@ protected: ///Pointer to the last transaction which has been executed TMLTransaction* _lastTransaction; ///Pointer to the bus which will be accessed by the next transaction - SchedulableCommDevice* _busNextTransaction; - + BusMaster* _masterNextTransaction; ///1/Processor frequency TMLTime _timePerCycle; + ///List of bus masters + BusMasterList _busMasterList; #ifdef PENALTIES_ENABLED ///Pipeline size unsigned int _pipelineSize; diff --git a/simulators/c++2/src_simulator/Master.h b/simulators/c++2/src_simulator/Master.h deleted file mode 100644 index 00294c3f30b29360a65275f212c2b9e437a8f06d..0000000000000000000000000000000000000000 --- a/simulators/c++2/src_simulator/Master.h +++ /dev/null @@ -1,110 +0,0 @@ -/*Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Daniel Knorreck, -Ludovic Apvrille, Renaud Pacalet - * - * ludovic.apvrille AT telecom-paristech.fr - * - * This software is a computer program whose purpose is to allow the - * edition of TURTLE analysis, design and deployment diagrams, to - * allow the generation of RT-LOTOS or Java code from this diagram, - * and at last to allow the analysis of formal validation traces - * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP - * from INRIA Rhone-Alpes. - * - * This software is governed by the CeCILL license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * As a counterpart to the access to the source code and rights to copy, - * modify and redistribute granted by the license, users are provided only - * with a limited warranty and the software's author, the holder of the - * economic rights, and the successive licensors have only limited - * liability. - * - * In this respect, the user's attention is drawn to the risks associated - * with loading, using, modifying and/or developing or reproducing the - * software by the user in light of its specific status of free software, - * that may mean that it is complicated to manipulate, and that also - * therefore means that it is reserved for developers and experienced - * professionals having in-depth computer knowledge. Users are therefore - * encouraged to load and test the software's suitability as regards their - * requirements in conditions enabling the security of their systems and/or - * data to be ensured and, more generally, to use and operate it in the - * same conditions as regards security. - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL license and that you accept its terms. - * - */ - -#ifndef MasterH -#define MasterH - -#include <definitions.h> -#include <SchedulableCommDevice.h> -#include <BusMasterInfo.h> - -class TMLTransaction; -class SchedulableCommDevice; - -///Base class for Bus masters -class Master{ -public: - ///Constructor - Master(){} - ///Retrieves the priority of the master for the given bus - /** - \param iDevice - \return Bus priority - */ - unsigned int getBusPriority(SchedulableCommDevice* iDevice) const{ - //return _masterPrioHashTab[iDevice]; - //return _masterPrioHashTab[iDevice]->getPriority(); - return _masterPrioHashTab.find(iDevice)->second->getPriority(); - } - ///Sets the priority of the master for a given bus - /** - \param iDevice Pointer to the bus - \param iPrio Priority - */ - void addBusPriority(SchedulableCommDevice* iDevice, unsigned int iPrio){ - //_masterPrioHashTab[iDevice]=iPrio; - _masterPrioHashTab[iDevice]= new BusMasterInfo(iPrio); - } - ///Destructor - virtual ~Master(){ - for(MasterPriorityHashTab::iterator i=_masterPrioHashTab.begin(); i != _masterPrioHashTab.end(); ++i){ - delete i->second; - } - } - void reset(){ - for(MasterPriorityHashTab::iterator i=_masterPrioHashTab.begin(); i != _masterPrioHashTab.end(); ++i){ - i->second->reset(); - } - } -protected: - ///Updates the bus contention statistics when a new bus transaction has been executed - /** - \param iDevice Pointer to the bus - \param iContentionDelay Contention delay of the transaction - */ - void addBusContention(SchedulableCommDevice* iDevice, unsigned long iContentionDelay) const{ - //_masterPrioHashTab[iDevice]->addContention(iContentionDelay); - _masterPrioHashTab.find(iDevice)->second->addContention(iContentionDelay); - } - ///Writes benchmarking data to a given stream - /** - \param s Reference to an output stream - */ - void streamBenchmarks(std::ostream& s) const{ - for(MasterPriorityHashTab::const_iterator i=_masterPrioHashTab.begin(); i != _masterPrioHashTab.end(); ++i){ - //s << "Average contention delay for bus " << i->first->toString() << ": " << i->second->getContentionDelay() << std::endl; - s << TAG_CONTDELo << " busID=\"" << i->first->getID()<< "\" busName=\"" << i->first->toString() << "\">" << i->second->getContentionDelay() << TAG_CONTDELc << std::endl; - } - } - ///Map which associates the bus and the priority - MasterPriorityHashTab _masterPrioHashTab; -}; - -#endif diff --git a/simulators/c++2/src_simulator/PrioScheduler.cpp b/simulators/c++2/src_simulator/PrioScheduler.cpp index deba10ba345b23d5f36ab4a5ea719c23cb7c933b..0d5ca22a67a70d64e46b36a338fae3642f2bb069 100644 --- a/simulators/c++2/src_simulator/PrioScheduler.cpp +++ b/simulators/c++2/src_simulator/PrioScheduler.cpp @@ -40,19 +40,18 @@ Ludovic Apvrille, Renaud Pacalet #include<PrioScheduler.h> #include <TMLTransaction.h> -PrioScheduler::PrioScheduler(const std::string& iName, unsigned int iPrio): WorkloadSource(iPrio), _name(iName), _nextTransaction(0), _lastSourceIndex(0){ +PrioScheduler::PrioScheduler(const std::string& iName, unsigned int iPrio): WorkloadSource(iPrio), _name(iName), _nextTransaction(0) /*,_lastSourceIndex(0)*/{ } -PrioScheduler::PrioScheduler(const std::string& iName, unsigned int iPrio, WorkloadSource** aSourceArray, unsigned int iNbOfSources): WorkloadSource(iPrio, aSourceArray, iNbOfSources), _name(iName), _nextTransaction(0), _lastSourceIndex(0){ +PrioScheduler::PrioScheduler(const std::string& iName, unsigned int iPrio, WorkloadSource** aSourceArray, unsigned int iNbOfSources): WorkloadSource(iPrio, aSourceArray, iNbOfSources), _name(iName), _nextTransaction(0) /*._lastSourceIndex(0)*/ { } -void PrioScheduler::schedule(TMLTime iEndSchedule){ +TMLTime PrioScheduler::schedule(TMLTime iEndSchedule){ TaskList::iterator i; TMLTransaction *aMarkerPast=0, *aMarkerFuture=0,*aTempTrans, *anOldTrans; unsigned int aHighestPrioPast=-1; TMLTime aTransTimeFuture=-1,aRunnableTime; - _lastSourceIndex=0; - for(WorkloadList::iterator i=_workloadList.begin(); i != _workloadList.end(); ++i, _lastSourceIndex++){ + for(WorkloadList::iterator i=_workloadList.begin(); i != _workloadList.end(); ++i){ (*i)->schedule(iEndSchedule); //std::cout << _name << " schedules, before getCurrTransaction " << std::endl; aTempTrans=(*i)->getNextTransaction(); @@ -79,6 +78,7 @@ void PrioScheduler::schedule(TMLTime iEndSchedule){ _nextTransaction=aMarkerFuture; else _nextTransaction=aMarkerPast; + return 0; } TMLTransaction* PrioScheduler::getNextTransaction() const{ @@ -88,3 +88,12 @@ TMLTransaction* PrioScheduler::getNextTransaction() const{ std::string PrioScheduler::toString() const{ return _name; } + +PrioScheduler::~PrioScheduler(){ + std::cout << _name << ": Scheduler deleted\n"; +} + +void PrioScheduler::reset(){ + WorkloadSource::reset(); + _nextTransaction=0; +} diff --git a/simulators/c++2/src_simulator/PrioScheduler.h b/simulators/c++2/src_simulator/PrioScheduler.h index 9bf0d139b7e3a31a1fecf7a56e16abf56f98f82f..8914585f89e928133c2c465553f40b9db344174a 100644 --- a/simulators/c++2/src_simulator/PrioScheduler.h +++ b/simulators/c++2/src_simulator/PrioScheduler.h @@ -43,16 +43,32 @@ Ludovic Apvrille, Renaud Pacalet class TMLTransaction; +///Fixed priority based scheduler class PrioScheduler: public WorkloadSource{ public: + ///Constructor + /** + \param iName Name of the scheduler + \param iPriority Priority of the scheduler + */ PrioScheduler(const std::string& iName, unsigned int iPrio); + ///Constructor + /** + \param iName Name of the scheduler + \param iPriority Priority of the scheduler + \param aSourceArray Array of pointers to workload ressources from which transactions may be received + \param iNbOfSources Length of the array + */ PrioScheduler(const std::string& iName, unsigned int iPrio, WorkloadSource** aSourceArray, unsigned int iNbOfSources); - void schedule(TMLTime iEndSchedule); + ~PrioScheduler(); + TMLTime schedule(TMLTime iEndSchedule); TMLTransaction* getNextTransaction() const; std::string toString() const; + void reset(); protected: + ///Name of the scheduler std::string _name; + ///Next transaction to be executed TMLTransaction* _nextTransaction; - unsigned int _lastSourceIndex; }; #endif diff --git a/simulators/c++2/src_simulator/RRScheduler.cpp b/simulators/c++2/src_simulator/RRScheduler.cpp index a75cc5ae3bf63881de7fd85eefef17d112cbf52c..3028ae38fc2fa0fdc3bc76fec777eaad7bcddc6f 100644 --- a/simulators/c++2/src_simulator/RRScheduler.cpp +++ b/simulators/c++2/src_simulator/RRScheduler.cpp @@ -48,18 +48,19 @@ RRScheduler::RRScheduler(const std::string& iName, unsigned int iPrio, TMLTime i RRScheduler::RRScheduler(const std::string& iName, unsigned int iPrio, TMLTime iTimeSlice, TMLTime iMinSliceSize, WorkloadSource** aSourceArray, unsigned int iNbOfSources): WorkloadSource(iPrio, aSourceArray, iNbOfSources), _name(iName), _nextTransaction(0), _timeSlice(iTimeSlice), _minSliceSize(iMinSliceSize), _elapsedTime(0), _lastSource(0){ } -void RRScheduler::schedule(TMLTime iEndSchedule){ +TMLTime RRScheduler::schedule(TMLTime iEndSchedule){ TaskList::iterator i; //std::cout << _name << ": Schedule called \n"; TMLTransaction *anOldTransaction=_nextTransaction, *aTempTrans; TMLTime aLowestRunnableTimeFuture=-1,aRunnableTime, aLowestRunnableTimePast=-1; WorkloadSource *aSourcePast=0, *aSourceFuture=0, *aScheduledSource=0; bool aSameTaskFound=false; - if (anOldTransaction!=0){ + //if (anOldTransaction!=0){ + if (_lastSource!=0){ aScheduledSource=_lastSource; _lastSource->schedule(iEndSchedule); if (_lastSource->getNextTransaction()!=0 && _lastSource->getNextTransaction()->getVirtualLength()!=0){ - if (_lastSource->getNextTransaction()==anOldTransaction || _timeSlice >=_elapsedTime + anOldTransaction->getBranchingPenalty() + anOldTransaction->getOperationLength() + _minSliceSize){ + if (anOldTransaction==0 || _lastSource->getNextTransaction()==anOldTransaction || _timeSlice >=_elapsedTime + anOldTransaction->getBranchingPenalty() + anOldTransaction->getOperationLength() + _minSliceSize){ aSourcePast=_lastSource; aSameTaskFound=true; } @@ -102,7 +103,8 @@ void RRScheduler::schedule(TMLTime iEndSchedule){ } if (aSameTaskFound){ //std::cout << _name << ": Same source found " << _lastSource->toString() << "\n"; - if (_nextTransaction!=anOldTransaction){ + //if (_nextTransaction!=anOldTransaction){ + if (_nextTransaction!=anOldTransaction && anOldTransaction!=0){ //std::cout << _name << ": Elapsed time increased by " << anOldTransaction->getBranchingPenalty() + anOldTransaction->getOperationLength() << "\n"; _elapsedTime += anOldTransaction->getBranchingPenalty() + anOldTransaction->getOperationLength(); } @@ -114,10 +116,11 @@ void RRScheduler::schedule(TMLTime iEndSchedule){ //std::cout << _name << ": New source found " << _lastSource->toString() << "\n"; _elapsedTime=0; } - if (_nextTransaction!=0){ - _nextTransaction->setLength(min(_nextTransaction->getOperationLength(), _timeSlice-_elapsedTime)); - } + //if (_nextTransaction!=0){ + // _nextTransaction->setLength(min(_nextTransaction->getOperationLength(), _timeSlice-_elapsedTime)); + //} //std::cout << "End schedule\n" ; + return _timeSlice-_elapsedTime; } TMLTransaction* RRScheduler::getNextTransaction() const{ @@ -125,6 +128,7 @@ TMLTransaction* RRScheduler::getNextTransaction() const{ } void RRScheduler::reset(){ + WorkloadSource::reset(); _nextTransaction=0; _elapsedTime=0; _lastSource=0; @@ -137,3 +141,42 @@ std::string RRScheduler::toString() const{ RRScheduler::~RRScheduler(){ std::cout << _name << ": Scheduler deleted\n"; } + +std::istream& RRScheduler::readObject(std::istream &is){ + WorkloadSource::readObject(is); + READ_STREAM(is,_elapsedTime); + std::cout << "Read: RRScheduler " << _name << " elapsedTime: " << _elapsedTime << std::endl; + int aLastSourceIndex; + READ_STREAM(is, aLastSourceIndex); + std::cout << "Read: RRScheduler " << _name << " lastSourceIndex: " << aLastSourceIndex << std::endl; + if (aLastSourceIndex==-1){ + _lastSource=0; + }else{ + WorkloadList::iterator i=_workloadList.begin(); + std::advance(i, aLastSourceIndex); + _lastSource=*i; + } + return is; +} + +std::ostream& RRScheduler::writeObject(std::ostream &os){ + WorkloadSource::writeObject(os); + WRITE_STREAM(os,_elapsedTime); + std::cout << "Write: RRScheduler " << _name << " elapsedTime: " << _elapsedTime << std::endl; + int aLastSourceIndex; + if (_lastSource==0){ + aLastSourceIndex=-1; + }else{ + aLastSourceIndex=0; + for(WorkloadList::iterator i=_workloadList.begin(); i != _workloadList.end(); ++i){ + if (*i==_lastSource) + break; + else + aLastSourceIndex++; + } + } + WRITE_STREAM(os, aLastSourceIndex); + std::cout << "Write: RRScheduler " << _name << " lastSourceIndex: " << aLastSourceIndex << std::endl; + return os; +} + diff --git a/simulators/c++2/src_simulator/RRScheduler.h b/simulators/c++2/src_simulator/RRScheduler.h index 1718eb3508e4709927715daf7fb5fbcf5f44ec93..1a4f5d9cbae1486f61790e612b744d28829a6a3e 100644 --- a/simulators/c++2/src_simulator/RRScheduler.h +++ b/simulators/c++2/src_simulator/RRScheduler.h @@ -43,21 +43,47 @@ Ludovic Apvrille, Renaud Pacalet class TMLTransaction; +///Round Robin scheduler class RRScheduler: public WorkloadSource{ public: + ///Constructor + /** + \param iName Name of the scheduler + \param iPriority Priority of the scheduler + \param iTimeSlice Time slice which is granted to clients + \param iMinSliceSize Minimum size of a time slice + */ RRScheduler(const std::string& iName, unsigned int iPrio, TMLTime iTimeSlice, TMLTime iMinSliceSize); + ///Constructor + /** + \param iName Name of the scheduler + \param iPriority Priority of the scheduler + \param iTimeSlice Time slice which is granted to clients + \param iMinSliceSize Minimum size of a time slice + \param aSourceArray Array of pointers to workload ressources from which transactions may be received + \param iNbOfSources Length of the array + */ RRScheduler(const std::string& iName, unsigned int iPrio, TMLTime iTimeSlice, TMLTime iMinSliceSize, WorkloadSource** aSourceArray, unsigned int iNbOfSources); + ///Destructor ~RRScheduler(); - void schedule(TMLTime iEndSchedule); + TMLTime schedule(TMLTime iEndSchedule); TMLTransaction* getNextTransaction() const; void reset(); + std::istream& readObject(std::istream &is); + std::ostream& writeObject(std::ostream &os); std::string toString() const; protected: + ///Name of the scheduler std::string _name; + ///Next transaction to be executed TMLTransaction* _nextTransaction; + ///Time slice which is granted to ressources TMLTime _timeSlice; + ///Minimum size of a time slice TMLTime _minSliceSize; + ///Consumed portion of a time slice TMLTime _elapsedTime; + ///Last workload source to which ressource access was granted WorkloadSource* _lastSource; }; #endif diff --git a/simulators/c++2/src_simulator/SchedulableDevice.h b/simulators/c++2/src_simulator/SchedulableDevice.h index f30a80ccd59ed37af6f16dad58419490e65e60ed..82640ff5b3f75faf1d37eeeb9846915bad201eb3 100644 --- a/simulators/c++2/src_simulator/SchedulableDevice.h +++ b/simulators/c++2/src_simulator/SchedulableDevice.h @@ -77,7 +77,7 @@ public: \param iTrans Pointer to the transaction to add \param iSourceDevice Source device */ - virtual void registerTransaction(TMLTransaction* iTrans, Master* iSourceDevice)=0; + virtual void registerTransaction()=0; ///Writes a HTML representation of the schedule to an output file /** \param myfile Reference to the ofstream object representing the output file @@ -91,7 +91,7 @@ public: virtual std::string toString() const =0; virtual std::istream& readObject(std::istream &is){ READ_STREAM(is,_endSchedule); - _simulatedTime=max(_simulatedTime,_endSchedule); + //_simulatedTime=max(_simulatedTime,_endSchedule); ???????????? std::cout << "Read: Schedulable Device " << _name << ": " << _endSchedule << std::endl; return is; } @@ -109,6 +109,11 @@ public: \return Number of simulated clock cycles */ static TMLTime getSimulatedTime() {return _simulatedTime;} + ///Sets the number of simulated clock cycles + /** + \param iSimulatedTime Number of simulated clock cycles + */ + static void setSimulatedTime(TMLTime iSimulatedTime) {_simulatedTime=iSimulatedTime;} ///Returns the unique ID of the device /** \return Unique ID diff --git a/simulators/c++2/src_simulator/SimComponents.cpp b/simulators/c++2/src_simulator/SimComponents.cpp index 41f173c9bed246768d4b2ff5e69be22e9733bb6b..0b06d0394db1fd7b203f68e23876538de1787029 100644 --- a/simulators/c++2/src_simulator/SimComponents.cpp +++ b/simulators/c++2/src_simulator/SimComponents.cpp @@ -66,7 +66,7 @@ SimComponents::~SimComponents(){ void SimComponents::addTask(TMLTask* iTask){ _vcdList.push_back(dynamic_cast<TraceableDevice*>(iTask)); - _serList.push_back(dynamic_cast<Serializable*>(iTask)); + //_serList.push_back(dynamic_cast<Serializable*>(iTask)); _taskList.push_back(iTask); //std::cout << iTask->toString() << std::endl; } @@ -120,6 +120,9 @@ std::ostream& SimComponents::writeObject(std::ostream& s){ for(SerializableList::const_iterator i=_serList.begin(); i != _serList.end(); ++i){ (*i)->writeObject(s); } + TMLTime aSimulatedTime = SchedulableDevice::getSimulatedTime(); + WRITE_STREAM(s, aSimulatedTime); + std::cout << "Write: SimComponents simulatedTime: " << aSimulatedTime << std::endl; std::cout << "----------------------------------------------------\n"; return s; } @@ -130,8 +133,12 @@ std::istream& SimComponents::readObject(std::istream& s){ //std::cout << "SimComponents --> next Device" << std::endl; (*i)->readObject(s); } - return s; + TMLTime aSimulatedTime; + READ_STREAM(s, aSimulatedTime); + SchedulableDevice::setSimulatedTime(aSimulatedTime); + std::cout << "Read: SimComponents simulatedTime: " << aSimulatedTime << std::endl; std::cout << "----------------------------------------------------\n"; + return s; } void SimComponents::reset(){ diff --git a/simulators/c++2/src_simulator/Simulator.cpp b/simulators/c++2/src_simulator/Simulator.cpp index ed3d6f12f20047c68635bf02001df6b313bed08f..cb3c7ee7a49dc43ac33499643ef16230ae022d30 100644 --- a/simulators/c++2/src_simulator/Simulator.cpp +++ b/simulators/c++2/src_simulator/Simulator.cpp @@ -972,14 +972,14 @@ void Simulator::printVariablesOfTask(TMLTask* iTask, std::ostream& ioMessage){ bool Simulator::runToNextBreakpoint(TMLTransaction*& oLastTrans){ TestListener myListener(_simComp); - _simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->registerListener(&myListener); - _simComp->getChannelByName("DIPLODOCUSDesign__evt")->registerListener(&myListener); - _simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->getCommandByID(17)->registerListener(&myListener); + //_simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->registerListener(&myListener); + //_simComp->getChannelByName("DIPLODOCUSDesign__evt")->registerListener(&myListener); + //_simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->getCommandByID(17)->registerListener(&myListener); bool erg=simulate(oLastTrans); //return simulate(oLastTrans); - _simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->removeListener(&myListener); - _simComp->getChannelByName("DIPLODOCUSDesign__evt")->removeListener(&myListener); - _simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->getCommandByID(17)->removeListener(&myListener); + //_simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->removeListener(&myListener); + //_simComp->getChannelByName("DIPLODOCUSDesign__evt")->removeListener(&myListener); + //_simComp->getTaskByName("DIPLODOCUSDesign__TMLTask_0")->getCommandByID(17)->removeListener(&myListener); return erg; } diff --git a/simulators/c++2/src_simulator/Slave.h b/simulators/c++2/src_simulator/Slave.h index 40f02646cbba053483f3982d5ad024b6df267551..9fec9ce1506653a6c317c1dc9edd4eb7689ff3fd 100644 --- a/simulators/c++2/src_simulator/Slave.h +++ b/simulators/c++2/src_simulator/Slave.h @@ -60,11 +60,11 @@ public: \param iTrans Pointer to the transaction to process */ virtual void CalcTransactionLength(TMLTransaction* iTrans) const =0; - ///Returns a pointer to the connected master device if any - /** - \return Pointer to the master device - */ - virtual Master* getConnectedMaster()=0; + /////Returns a pointer to the connected master device if any + ////** + //\return Pointer to the master device + ////*/ + //virtual Master* getConnectedMaster()=0; std::string toString() {return _name;} ///Adds the transaction determined by the scheduling algorithm to the internal list of scheduled transactions virtual void addTransaction(TMLTransaction* iTrans){ diff --git a/simulators/c++2/src_simulator/TMLChannel.cpp b/simulators/c++2/src_simulator/TMLChannel.cpp index 1e9b4feee47753d4c526ca56b5518d071437669d..bfb01120162934ac527f692f3d8c5d4e727e7c2f 100644 --- a/simulators/c++2/src_simulator/TMLChannel.cpp +++ b/simulators/c++2/src_simulator/TMLChannel.cpp @@ -39,15 +39,15 @@ Ludovic Apvrille, Renaud Pacalet */ #include <TMLChannel.h> -#include <Bus.h> +#include <BusMaster.h> #include <TMLCommand.h> #include <TMLTransaction.h> -TMLChannel::TMLChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves): _ID(iID), _name(iName), _readTask(0), _writeTask(0), _writeTrans(0), _readTrans(0),_numberOfHops(iNumberOfHops), _buses(iBuses), _slaves(iSlaves), _writeTransCurrHop(0), _readTransCurrHop(iNumberOfHops-1){ +TMLChannel::TMLChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves): _ID(iID), _name(iName), _readTask(0), _writeTask(0), _writeTrans(0), _readTrans(0),_numberOfHops(iNumberOfHops), _masters(iMasters), _slaves(iSlaves), _writeTransCurrHop(0), _readTransCurrHop(iNumberOfHops-1){ } TMLChannel::~TMLChannel(){ - if (_buses!=0) delete[] _buses; + if (_masters!=0) delete[] _masters; if (_slaves!=0) delete[] _slaves; } @@ -59,28 +59,28 @@ void TMLChannel::setBlockedWriteTask(TMLTask* iWriteTask){ _writeTask=iWriteTask; } -SchedulableCommDevice* TMLChannel::getNextBus(TMLTransaction* iTrans){ +BusMaster* TMLChannel::getNextMaster(TMLTransaction* iTrans){ //if (iTrans->getCommand()->getTask()==_writeTask){ if (iTrans==_writeTrans){ _writeTransCurrHop++; - if (_writeTransCurrHop>0 && _buses[_writeTransCurrHop]==_buses[_writeTransCurrHop-1]) return 0; - return _buses[_writeTransCurrHop]; + if (_writeTransCurrHop>0 && _masters[_writeTransCurrHop]->getBus()==_masters[_writeTransCurrHop-1]->getBus()) return 0; + return _masters[_writeTransCurrHop]; }else{ _readTransCurrHop--; - if (_readTransCurrHop<_numberOfHops-1 && _buses[_readTransCurrHop]==_buses[_readTransCurrHop+1]) return 0; - return _buses[_readTransCurrHop]; + if (_readTransCurrHop<_numberOfHops-1 && _masters[_readTransCurrHop]->getBus()==_masters[_readTransCurrHop+1]->getBus()) return 0; + return _masters[_readTransCurrHop]; } } -SchedulableCommDevice* TMLChannel::getFirstBus(TMLTransaction* iTrans){ +BusMaster* TMLChannel::getFirstMaster(TMLTransaction* iTrans){ //if (iTrans->getCommand()->getTask()==_writeTask){ - if (_buses==0 || _slaves==0 || _numberOfHops==0) return 0; + if (_masters==0 || _slaves==0 || _numberOfHops==0) return 0; if (iTrans==_writeTrans){ _writeTransCurrHop=0; - return _buses[_writeTransCurrHop]; + return _masters[_writeTransCurrHop]; }else{ _readTransCurrHop=_numberOfHops-1; - return _buses[_readTransCurrHop]; + return _masters[_readTransCurrHop]; } } diff --git a/simulators/c++2/src_simulator/TMLChannel.h b/simulators/c++2/src_simulator/TMLChannel.h index 98d91549a4c90306e1e9b2e26c1f4c7658e8aaf8..6943399936c25007f8c7a2de734093230f669ae4 100644 --- a/simulators/c++2/src_simulator/TMLChannel.h +++ b/simulators/c++2/src_simulator/TMLChannel.h @@ -51,7 +51,7 @@ Ludovic Apvrille, Renaud Pacalet class TMLTransaction; class TMLCommand; class TMLTask; -class Bus; +class BusMaster; ///This class defines the basic interfaces and functionalites of a TML channel. All specific channels are derived from this base class. A channel is able to convey data and events. class TMLChannel: public Serializable, public ListenerSubject <ChannelListener> { @@ -64,7 +64,7 @@ public: \param iBuses Pointer to the buses on which the channel is mapped \param iSlaves Pointer to the slaves on which the channel is mapped */ - TMLChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves); + TMLChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves); ///Destructor virtual ~TMLChannel(); ///Prepares a write operation @@ -101,18 +101,18 @@ public: \return Pointer to the task */ virtual TMLTask* getBlockedWriteTask()const=0; - ///Returns the next communication link on which the given transaction is conveyed + ///Returns the next communication master on which the given transaction is conveyed /** \param iTrans Transaction - \return Pointer to the communication link + \return Pointer to the communication master */ - SchedulableCommDevice* getNextBus(TMLTransaction* iTrans); - ///Returns the first communication link on which the given transaction is conveyed + BusMaster* getNextMaster(TMLTransaction* iTrans); + ///Returns the first communication master on which the given transaction is conveyed /** \param iTrans Transaction - \return Pointer to the communication link + \return Pointer to the communication master */ - SchedulableCommDevice* getFirstBus(TMLTransaction* iTrans); + BusMaster* getFirstMaster(TMLTransaction* iTrans); ///Returns the next slave component to which the given transaction is sent /** \param iTrans Transaction @@ -183,7 +183,7 @@ protected: ///Number of Buses/Slave devices on which the channel is mapped unsigned int _numberOfHops; ///List of buses on which the channel is mapped - SchedulableCommDevice** _buses; + BusMaster** _masters; ///List of slaves on which the channel is mapped Slave** _slaves; ///Keeps track of the current Hop of a write Transaction diff --git a/simulators/c++2/src_simulator/TMLEventBChannel.cpp b/simulators/c++2/src_simulator/TMLEventBChannel.cpp index d1896fe6afa816aabd1f342de675e0a647bf3945..fa93447b2b1b76a623cb57bf06de43883269b627 100644 --- a/simulators/c++2/src_simulator/TMLEventBChannel.cpp +++ b/simulators/c++2/src_simulator/TMLEventBChannel.cpp @@ -42,7 +42,7 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLTransaction.h> #include <TMLCommand.h> -TMLEventBChannel::TMLEventBChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iContent, bool iRequestChannel, bool iSourceIsFile):TMLEventChannel(iID, iName, iNumberOfHops, iBuses, iSlaves, iContent), _requestChannel(iRequestChannel), _sourceIsFile(iSourceIsFile),_eventFile(0) { +TMLEventBChannel::TMLEventBChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iContent, bool iRequestChannel, bool iSourceIsFile):TMLEventChannel(iID, iName, iNumberOfHops, iMasters, iSlaves, iContent), _requestChannel(iRequestChannel), _sourceIsFile(iSourceIsFile),_eventFile(0) { _overflow = false; if (_sourceIsFile){ std::cout << "try to open Event file " << _name.c_str() << std::endl; diff --git a/simulators/c++2/src_simulator/TMLEventBChannel.h b/simulators/c++2/src_simulator/TMLEventBChannel.h index f1689d682d17d97f87e4a367a641230a54591e5c..1d06cc1b44860f39ef194eedabd578efd19eba5a 100644 --- a/simulators/c++2/src_simulator/TMLEventBChannel.h +++ b/simulators/c++2/src_simulator/TMLEventBChannel.h @@ -61,7 +61,7 @@ public: \param iRequestChannel Flag indicating if channel is used by a request \param iSourceIsFile Flag indicating if events are read from a file */ - TMLEventBChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iContent, bool iRequestChannel=false, bool iSourceIsFile=false); + TMLEventBChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iContent, bool iRequestChannel=false, bool iSourceIsFile=false); ~TMLEventBChannel(); void testWrite(TMLTransaction* iTrans); void testRead(TMLTransaction* iTrans); diff --git a/simulators/c++2/src_simulator/TMLEventChannel.cpp b/simulators/c++2/src_simulator/TMLEventChannel.cpp index 0050fdf03f6b76a1d5d8daa100df08a79bfbd73a..860ae7b7daca9973d3ba30d3a5b2ba00e4c9539e 100644 --- a/simulators/c++2/src_simulator/TMLEventChannel.cpp +++ b/simulators/c++2/src_simulator/TMLEventChannel.cpp @@ -40,7 +40,7 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLEventChannel.h> -TMLEventChannel::TMLEventChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iContent): TMLStateChannel(iID, iName, iNumberOfHops, iBuses, iSlaves, iContent),_tmpParam(0,0,0){ +TMLEventChannel::TMLEventChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iContent): TMLStateChannel(iID, iName, iNumberOfHops, iMasters, iSlaves, iContent),_tmpParam(0,0,0){ } TMLEventChannel::~TMLEventChannel(){ diff --git a/simulators/c++2/src_simulator/TMLEventChannel.h b/simulators/c++2/src_simulator/TMLEventChannel.h index 526bdc4e7fe543c3a5ad600732f784ac7030b95f..083bf66b9b0b03d5f4112d29dce06921e1c160f1 100644 --- a/simulators/c++2/src_simulator/TMLEventChannel.h +++ b/simulators/c++2/src_simulator/TMLEventChannel.h @@ -59,7 +59,7 @@ public: \param iSlaves Pointer to the slaves on which the channel is mapped \param iContent Initial content of the channel */ - TMLEventChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iContent); + TMLEventChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iContent); ///Destructor virtual ~TMLEventChannel(); ///Cancels a pending read operation diff --git a/simulators/c++2/src_simulator/TMLEventFBChannel.cpp b/simulators/c++2/src_simulator/TMLEventFBChannel.cpp index 6f7ec45f37a853f3b579f97797da505a039c53a9..cf2f2a61e90706106090019fca8fb10f352556e8 100644 --- a/simulators/c++2/src_simulator/TMLEventFBChannel.cpp +++ b/simulators/c++2/src_simulator/TMLEventFBChannel.cpp @@ -42,7 +42,7 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLTransaction.h> #include <TMLCommand.h> -TMLEventFBChannel::TMLEventFBChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iLength, TMLLength iContent): TMLEventChannel(iID, iName, iNumberOfHops, iBuses, iSlaves, iContent),_length(iLength){ +TMLEventFBChannel::TMLEventFBChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iLength, TMLLength iContent): TMLEventChannel(iID, iName, iNumberOfHops, iMasters, iSlaves, iContent),_length(iLength){ } void TMLEventFBChannel::testWrite(TMLTransaction* iTrans){ diff --git a/simulators/c++2/src_simulator/TMLEventFBChannel.h b/simulators/c++2/src_simulator/TMLEventFBChannel.h index 8c9d74dc2210b84023eaab7ea9353c20af18cafa..51f322053c3ac5fd6ced8fb5308ff7b1b506d452 100644 --- a/simulators/c++2/src_simulator/TMLEventFBChannel.h +++ b/simulators/c++2/src_simulator/TMLEventFBChannel.h @@ -60,7 +60,7 @@ public: \param iLength Length of the channel \param iContent Initial content of the channel */ - TMLEventFBChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iLength, TMLLength iContent); + TMLEventFBChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iLength, TMLLength iContent); void testWrite(TMLTransaction* iTrans); void testRead(TMLTransaction* iTrans); void write(); diff --git a/simulators/c++2/src_simulator/TMLEventFChannel.cpp b/simulators/c++2/src_simulator/TMLEventFChannel.cpp index e1c95306e3919b8d33dbcca87a1352df199dfb02..de5ed14b0b655dbdd1c0545d826fa420577339bb 100644 --- a/simulators/c++2/src_simulator/TMLEventFChannel.cpp +++ b/simulators/c++2/src_simulator/TMLEventFChannel.cpp @@ -42,7 +42,7 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLTransaction.h> #include <TMLCommand.h> -TMLEventFChannel::TMLEventFChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iLength, TMLLength iContent): TMLEventChannel(iID, iName, iNumberOfHops, iBuses, iSlaves, iContent),_length(iLength){ +TMLEventFChannel::TMLEventFChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iLength, TMLLength iContent): TMLEventChannel(iID, iName, iNumberOfHops, iMasters, iSlaves, iContent),_length(iLength){ } void TMLEventFChannel::testWrite(TMLTransaction* iTrans){ diff --git a/simulators/c++2/src_simulator/TMLEventFChannel.h b/simulators/c++2/src_simulator/TMLEventFChannel.h index 8efbd7ded092b192589583575bd2009b7ff616d4..9c22bb4718310fdbf78f57158944fdc2db4a2620 100644 --- a/simulators/c++2/src_simulator/TMLEventFChannel.h +++ b/simulators/c++2/src_simulator/TMLEventFChannel.h @@ -60,7 +60,7 @@ public: \param iLength Length of the channel \param iContent Initial content of the channel */ - TMLEventFChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iLength, TMLLength iContent); + TMLEventFChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iLength, TMLLength iContent); void testWrite(TMLTransaction* iCommand); void testRead(TMLTransaction* iCommand); void write(); diff --git a/simulators/c++2/src_simulator/TMLReadCommand.cpp b/simulators/c++2/src_simulator/TMLReadCommand.cpp index 6e7c31404f50f779dc69e3ee637b725561014bc0..cea51b714159fbfd21ec445c0780ae1de408a2cf 100644 --- a/simulators/c++2/src_simulator/TMLReadCommand.cpp +++ b/simulators/c++2/src_simulator/TMLReadCommand.cpp @@ -51,6 +51,7 @@ void TMLReadCommand::execute(){ _channel->read(); _progress+=_currTransaction->getVirtualLength(); //_task->setEndLastTransaction(_currTransaction->getEndTime()); + //std::cout << "ReadCommand progress: " << _progress << std::endl; _task->addTransaction(_currTransaction); TMLCommand* aNextCommand = prepare(false); //if (aNextCommand==0) _currTransaction->setTerminatedFlag(); diff --git a/simulators/c++2/src_simulator/TMLStateChannel.cpp b/simulators/c++2/src_simulator/TMLStateChannel.cpp index d7b5c4044bdb97ce6a7d82a7f9146ad2ab5dc4c3..75c1fecf65a1876e139914fe1c0879a278ca462d 100644 --- a/simulators/c++2/src_simulator/TMLStateChannel.cpp +++ b/simulators/c++2/src_simulator/TMLStateChannel.cpp @@ -40,7 +40,7 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLStateChannel.h> -TMLStateChannel::TMLStateChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iContent): TMLChannel(iID, iName, iNumberOfHops, iBuses, iSlaves), _content(iContent), _nbToWrite(0), _nbToRead(0), _overflow(false), _underflow(false){ +TMLStateChannel::TMLStateChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iContent): TMLChannel(iID, iName, iNumberOfHops, iMasters, iSlaves), _content(iContent), _nbToWrite(0), _nbToRead(0), _overflow(false), _underflow(false){ } TMLStateChannel::~TMLStateChannel(){} diff --git a/simulators/c++2/src_simulator/TMLStateChannel.h b/simulators/c++2/src_simulator/TMLStateChannel.h index 2b6da28dec686fa2669e398510f530d67f2d6c75..c193f170c623b8d5d4651d543bcf0523e1c88a61 100644 --- a/simulators/c++2/src_simulator/TMLStateChannel.h +++ b/simulators/c++2/src_simulator/TMLStateChannel.h @@ -58,7 +58,7 @@ public: \param iSlaves Pointer to the slaves on which the channel is mapped \param iContent Initial content of the channel */ - TMLStateChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves ,TMLLength iContent); + TMLStateChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves ,TMLLength iContent); ///Destructor virtual ~TMLStateChannel(); virtual std::ostream& writeObject(std::ostream& s); diff --git a/simulators/c++2/src_simulator/TMLTask.cpp b/simulators/c++2/src_simulator/TMLTask.cpp index 561ff69624f27b2a7707da2cf85765ba7ddb045c..b520dcb7ad186459a973cd75b99a3261cfd83777 100644 --- a/simulators/c++2/src_simulator/TMLTask.cpp +++ b/simulators/c++2/src_simulator/TMLTask.cpp @@ -212,6 +212,14 @@ std::ostream& TMLTask::writeObject(std::ostream& s){ std::cout << "Write: TMLTask " << _name << " aCurrCmd: " << aCurrCmd << std::endl; _currCommand->writeObject(s); } +#ifdef SAVE_BENCHMARK_VARS + WRITE_STREAM(s, _busyCycles); + std::cout << "Write: TMLTask " << _name << " busyCycles: " << _busyCycles << std::endl; + WRITE_STREAM(s, _CPUContentionDelay); + std::cout << "Write: TMLTask " << _name << " CPUContentionDelay: " << _CPUContentionDelay << std::endl; + WRITE_STREAM(s, _noCPUTransactions); + std::cout << "Write: TMLTask " << _name << " noCPUTransactions: " << _noCPUTransactions << std::endl; +#endif return s; } @@ -233,6 +241,14 @@ std::istream& TMLTask::readObject(std::istream& s){ //_currCommand->prepare(); } //std::cout << "End Read Object TMLTask " << _name << std::endl; +#ifdef SAVE_BENCHMARK_VARS + READ_STREAM(s, _busyCycles); + std::cout << "Read: TMLTask " << _name << " busyCycles: " << _busyCycles << std::endl; + READ_STREAM(s, _CPUContentionDelay); + std::cout << "Read: TMLTask " << _name << " CPUContentionDelay: " << _CPUContentionDelay << std::endl; + READ_STREAM(s, _noCPUTransactions); + std::cout << "Read: TMLTask " << _name << " noCPUTransactions: " << _noCPUTransactions << std::endl; +#endif _justStarted=false; return s; } diff --git a/simulators/c++2/src_simulator/TMLTask.h b/simulators/c++2/src_simulator/TMLTask.h index a1dbcdd151926b766d69cc91811d79eb6018b19d..26082e0fd6d2de059c7fdf5b8a668eabeccaf992 100644 --- a/simulators/c++2/src_simulator/TMLTask.h +++ b/simulators/c++2/src_simulator/TMLTask.h @@ -62,7 +62,7 @@ enum vcdTaskVisState START_TRANS }; -class TMLTask: public TraceableDevice, public Serializable, public ListenerSubject <TaskListener>, public WorkloadSource{ +class TMLTask: public TraceableDevice, public ListenerSubject <TaskListener>, public WorkloadSource{ public: ///Constructor /** diff --git a/simulators/c++2/src_simulator/TMLTransaction.cpp b/simulators/c++2/src_simulator/TMLTransaction.cpp index b509d33984f7d462dcae21e6b5a5eaa4b595414c..ee1560024e1ec044f6c9f1309b14ab160442af5b 100644 --- a/simulators/c++2/src_simulator/TMLTransaction.cpp +++ b/simulators/c++2/src_simulator/TMLTransaction.cpp @@ -45,7 +45,7 @@ Ludovic Apvrille, Renaud Pacalet MemPool<TMLTransaction> TMLTransaction::memPool; -TMLTransaction::TMLTransaction(TMLCommand* iCommand, TMLLength iVirtualLength, TMLTime iRunnableTime, TMLChannel* iChannel):_runnableTime(iRunnableTime), _startTime(0), _length(-1), _virtualLength(iVirtualLength), _command(iCommand), +TMLTransaction::TMLTransaction(TMLCommand* iCommand, TMLLength iVirtualLength, TMLTime iRunnableTime, TMLChannel* iChannel):_runnableTime(iRunnableTime), _startTime(0), _length(0), _virtualLength(iVirtualLength), _command(iCommand), #ifdef PENALTIES_ENABLED _idlePenalty(0), _taskSwitchingPenalty(0), _branchingPenalty(0), #endif diff --git a/simulators/c++2/src_simulator/TMLbrbwChannel.cpp b/simulators/c++2/src_simulator/TMLbrbwChannel.cpp index 80c36ad16b882ffa50b5d5cca178a2c863e63a04..f6ec996b0048872eb42f6b05a301ccff89de5f35 100644 --- a/simulators/c++2/src_simulator/TMLbrbwChannel.cpp +++ b/simulators/c++2/src_simulator/TMLbrbwChannel.cpp @@ -42,7 +42,7 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLTransaction.h> #include <TMLCommand.h> -TMLbrbwChannel::TMLbrbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iLength,TMLLength iContent):TMLStateChannel(iID, iName, iNumberOfHops, iBuses, iSlaves, iContent),_length(iLength){ +TMLbrbwChannel::TMLbrbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iLength,TMLLength iContent):TMLStateChannel(iID, iName, iNumberOfHops, iMasters, iSlaves, iContent),_length(iLength){ } void TMLbrbwChannel::testWrite(TMLTransaction* iTrans){ diff --git a/simulators/c++2/src_simulator/TMLbrbwChannel.h b/simulators/c++2/src_simulator/TMLbrbwChannel.h index ad58befc5a1c3cfe00b56cecdd55dc84a0e6cd52..e9135eab3e39486d2050df645d1f06c2dc833e01 100644 --- a/simulators/c++2/src_simulator/TMLbrbwChannel.h +++ b/simulators/c++2/src_simulator/TMLbrbwChannel.h @@ -60,7 +60,7 @@ public: \param iLength Length of the channel \param iContent Initial content of the channel */ - TMLbrbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iLength, TMLLength iContent); + TMLbrbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iLength, TMLLength iContent); void testWrite(TMLTransaction* iTrans); void testRead(TMLTransaction* iTrans); void write(); diff --git a/simulators/c++2/src_simulator/TMLbrnbwChannel.cpp b/simulators/c++2/src_simulator/TMLbrnbwChannel.cpp index 5f945df3e4167c24521ee45313619d6ea7b91853..6942f7de0171fed11ff8aca812005d19ffffb76f 100644 --- a/simulators/c++2/src_simulator/TMLbrnbwChannel.cpp +++ b/simulators/c++2/src_simulator/TMLbrnbwChannel.cpp @@ -41,7 +41,7 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLbrnbwChannel.h> #include <TMLTransaction.h> -TMLbrnbwChannel::TMLbrnbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iContent):TMLStateChannel(iID, iName, iNumberOfHops, iBuses, iSlaves, iContent){ +TMLbrnbwChannel::TMLbrnbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iContent):TMLStateChannel(iID, iName, iNumberOfHops, iMasters, iSlaves, iContent){ _overflow=false; } diff --git a/simulators/c++2/src_simulator/TMLbrnbwChannel.h b/simulators/c++2/src_simulator/TMLbrnbwChannel.h index bd0b657b91626712fd2044ba8bf6a11f9735ff31..da232d86973fa341c0ada2e4793b357feea75f34 100644 --- a/simulators/c++2/src_simulator/TMLbrnbwChannel.h +++ b/simulators/c++2/src_simulator/TMLbrnbwChannel.h @@ -59,7 +59,7 @@ public: \param iSlaves Pointer to the slaves on which the channel is mapped \param iContent Initial content of the channel */ - TMLbrnbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves, TMLLength iContent); + TMLbrnbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves, TMLLength iContent); void testWrite(TMLTransaction* iTrans); void testRead(TMLTransaction* iTrans); void write(); diff --git a/simulators/c++2/src_simulator/TMLnbrnbwChannel.cpp b/simulators/c++2/src_simulator/TMLnbrnbwChannel.cpp index 6f25a0c987ffc78b49d3111fb275ffad1da0cf3d..828dc69adbc3036a4bb168b04d3d16fedad07e51 100644 --- a/simulators/c++2/src_simulator/TMLnbrnbwChannel.cpp +++ b/simulators/c++2/src_simulator/TMLnbrnbwChannel.cpp @@ -41,7 +41,7 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLnbrnbwChannel.h> #include <TMLTransaction.h> -TMLnbrnbwChannel::TMLnbrnbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves): TMLChannel(iID, iName, iNumberOfHops, iBuses, iSlaves){ +TMLnbrnbwChannel::TMLnbrnbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves): TMLChannel(iID, iName, iNumberOfHops, iMasters, iSlaves){ } void TMLnbrnbwChannel::testWrite(TMLTransaction* iTrans){ diff --git a/simulators/c++2/src_simulator/TMLnbrnbwChannel.h b/simulators/c++2/src_simulator/TMLnbrnbwChannel.h index 9ffe51beeeaffd90abb72f41d1181399ca0eef26..282bbe618b9780c8fe465f359cbd7a3898a34600 100644 --- a/simulators/c++2/src_simulator/TMLnbrnbwChannel.h +++ b/simulators/c++2/src_simulator/TMLnbrnbwChannel.h @@ -58,7 +58,7 @@ public: \param iBuses Pointer to the buses on which the channel is mapped \param iSlaves Pointer to the slaves on which the channel is mapped */ - TMLnbrnbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, SchedulableCommDevice** iBuses, Slave** iSlaves); + TMLnbrnbwChannel(unsigned int iID, std::string iName, unsigned int iNumberOfHops, BusMaster** iMasters, Slave** iSlaves); void testWrite(TMLTransaction* iCommand); void testRead(TMLTransaction* iCommand); void write(); diff --git a/simulators/c++2/src_simulator/WorkloadSource.h b/simulators/c++2/src_simulator/WorkloadSource.h index af58a6c6d781cd8a2006765f8319635cde85b419..07cce9dc8ef06fe3fd2d0bc8004e0cc141b6ed00 100644 --- a/simulators/c++2/src_simulator/WorkloadSource.h +++ b/simulators/c++2/src_simulator/WorkloadSource.h @@ -40,15 +40,26 @@ Ludovic Apvrille, Renaud Pacalet #ifndef WorkloadSourceH #define WorkloadSourceH #include <definitions.h> -//#include <TMLTask.h> +#include <Serializable.h> class TMLTransaction; class Master; class TMLTask; -class WorkloadSource{ +///Base class for components providing workload like tasks and schedulers +class WorkloadSource: public Serializable{ public: + ///Constructor + /** + \param iPriority Priority of the workload source + */ WorkloadSource(unsigned int iPriority): _priority(iPriority), _srcArraySpecified(false) {} + ///Constructor + /** + \param iPriority Priority of the scheduler + \param aSourceArray Array of pointers to workload ressources from which transactions may be received + \param iNbOfSources Length of the array + */ WorkloadSource(unsigned int iPriority, WorkloadSource** aSourceArray, unsigned int iNbOfSources): _priority(iPriority), _srcArraySpecified(true){ for (unsigned int i=0;i<iNbOfSources;i++){ addWorkloadSource(aSourceArray[i]); @@ -56,19 +67,45 @@ public: } delete[] aSourceArray; } + ///Destruktor virtual ~WorkloadSource(); + ///Returns the next transaction to be executed by the ressource + /** + \return Pointer to the transaction to be executed + */ virtual TMLTransaction* getNextTransaction() const=0; + ///Returns the priority of the workload source + /** + \return Priority of the workload source + */ inline unsigned int getPriority() const{return _priority;} + ///Add a source which provides transactions to the scheduler + /** + \param iSource Pointer to workload source + */ inline void addWorkloadSource(WorkloadSource* iSource){_workloadList.push_back(iSource);} - virtual void registerTransaction(TMLTransaction* iTrans, Master* iSourceDevice){ - for(WorkloadList::iterator i=_workloadList.begin(); i != _workloadList.end(); ++i) (*i)->registerTransaction(iTrans, iSourceDevice); + ///Perform scheduling + /** + \param iEndSchedule Current time of the ressource + \return Time slice granted by the scheduler + */ + virtual TMLTime schedule(TMLTime iEndSchedule){return 0;} + virtual void reset(){for(WorkloadList::iterator i=_workloadList.begin(); i != _workloadList.end(); ++i) (*i)->reset();} + virtual std::istream& readObject(std::istream &is){ + for(WorkloadList::iterator i=_workloadList.begin(); i != _workloadList.end(); ++i) (*i)->readObject(is); + return is; + } + virtual std::ostream& writeObject(std::ostream &os){ + for(WorkloadList::iterator i=_workloadList.begin(); i != _workloadList.end(); ++i) (*i)->writeObject(os); + return os; } - virtual void schedule(TMLTime iEndSchedule){}; - virtual void reset(){} virtual std::string toString() const =0; protected: + ///List of sources which provide transactions to the scheduler WorkloadList _workloadList; + ///Priority of the workload source unsigned int _priority; + ///Indicates whether sources contained in workload list have to be deleted bool _srcArraySpecified; }; #endif diff --git a/simulators/c++2/src_simulator/definitions.h b/simulators/c++2/src_simulator/definitions.h index fea94eef488cf241bd76ee2081cf215f029bcaaf..9838d1297a15e49d8ac201dd3f0a40e6cc74413a 100644 --- a/simulators/c++2/src_simulator/definitions.h +++ b/simulators/c++2/src_simulator/definitions.h @@ -76,18 +76,18 @@ using std::max; #define BUS_ENABLED #define WAIT_SEND_VLEN 1 -#undef PENALTIES_ENABLED -//#define CPURRPB CPUPB +#define PENALTIES_ENABLED + #define CLOCK_INC 20 #define BLOCK_SIZE 500000 #define PARAMETER_BLOCK_SIZE 1000 #define ADD_COMMENTS #define NO_EVENTS_TO_LOAD 10 -#undef REGISTER_TRANS_AT_CPU +#undef REGISTER_TRANS_AT_CPU +#define SAVE_BENCHMARK_VARS #define PORT "3490" #define BACKLOG 10 #define VCD_PREFIX "b" -//#define SERVER_MODE //Task VCD output #define UNKNOWN 4 @@ -179,6 +179,7 @@ class TMLChannel; class Slave; class Comment; class WorkloadSource; +class BusMaster; ///Datatype used for time measurements typedef unsigned int TMLTime; @@ -204,10 +205,6 @@ typedef std::list<TMLChannel*> ChannelList; typedef std::vector<Comment*> CommentList; ///Datatype used in Tasks in order to associate a command with an ID typedef std::map<unsigned int, TMLCommand*> CommandHashTab; -///Datatype establishing an association between a CPU and a transaction, used by the bus -typedef std::map<Master*, TMLTransaction*> BusTransHashTab; -///Datatype establishing an association between a bus and a priority, used by Masters -typedef std::map<SchedulableCommDevice*, BusMasterInfo*> MasterPriorityHashTab; ///Datatype for event parameters typedef int ParamType; ///Datatype used in EventChannels to store parameters of events @@ -230,6 +227,8 @@ typedef std::set<TMLCommand*> BreakpointSet; typedef std::deque<std::string*> CommandQueue; ///Workload list used by Workload sources typedef std::list<WorkloadSource*> WorkloadList; +///List of bus masters used by CPUs +typedef std::list<BusMaster*> BusMasterList; struct ltstr{ bool operator()(const char* s1, const char* s2) const{