From 434729c20f1849a3aa952f045e95e48cf23d0c44 Mon Sep 17 00:00:00 2001 From: Ludovic Apvrille <ludovic.apvrille@telecom-paristech.fr> Date: Wed, 14 Jan 2009 12:45:01 +0000 Subject: [PATCH] New simulator --- simulators/c++2/src_simulator/Bus.cpp | 8 ++++ simulators/c++2/src_simulator/Bus.h | 15 +------- simulators/c++2/src_simulator/CPU.cpp | 38 ++++++++++++++----- simulators/c++2/src_simulator/CPU.h | 15 ++------ simulators/c++2/src_simulator/Master.h | 37 +++++++++++++----- .../c++2/src_simulator/SchedulableDevice.h | 5 ++- simulators/c++2/src_simulator/TMLTask.cpp | 13 ++++++- simulators/c++2/src_simulator/TMLTask.h | 15 ++++---- .../c++2/src_simulator/TraceableDevice.h | 1 - simulators/c++2/src_simulator/definitions.h | 16 ++------ simulators/c++2/src_simulator/simkern.cpp | 6 +-- 11 files changed, 101 insertions(+), 68 deletions(-) diff --git a/simulators/c++2/src_simulator/Bus.cpp b/simulators/c++2/src_simulator/Bus.cpp index 3a30e13ab9..78f8d692ff 100644 --- a/simulators/c++2/src_simulator/Bus.cpp +++ b/simulators/c++2/src_simulator/Bus.cpp @@ -63,18 +63,26 @@ 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; diff --git a/simulators/c++2/src_simulator/Bus.h b/simulators/c++2/src_simulator/Bus.h index e2c5521e1a..de35553de7 100644 --- a/simulators/c++2/src_simulator/Bus.h +++ b/simulators/c++2/src_simulator/Bus.h @@ -48,13 +48,13 @@ Ludovic Apvrille, Renaud Pacalet class CPU; class TMLTransaction; -/*enum vcdBusVisState +enum vcdBusVisState { END_IDLE_BUS, END_READ_BUS, END_WRITE_BUS, INIT_BUS -};*/ +}; ///Simulates the bahavior of a bus shared by several master devices class Bus: public SchedulableCommDevice, public TraceableDevice { @@ -112,13 +112,6 @@ public: \param myfile Reference to the ofstream object representing the output file */ void schedule2TXT(std::ofstream& myfile); - ///Creates a string representation of the next signal change of the device (VCD format) - /** - \param iInit If init is true, the methods starts from the first transaction - \param oSigChange String representation of the signal change - \param oNoMoreTrans Is true if the last transaction is processed - \return Time when the signal change occurred - */ TMLTime getNextSignalChange(bool iInit, std::string& oSigChange, bool& oNoMoreTrans); virtual void streamBenchmarks(std::ostream& s); @@ -159,10 +152,6 @@ protected: TMLTime _previousTransEndTime; ///State variable for the VCD output vcdBusVisState _vcdOutputState; - - //int add; - //int remove; - //bool _schedulingBlocked; }; #endif diff --git a/simulators/c++2/src_simulator/CPU.cpp b/simulators/c++2/src_simulator/CPU.cpp index 313e6f40ee..238c8190ea 100644 --- a/simulators/c++2/src_simulator/CPU.cpp +++ b/simulators/c++2/src_simulator/CPU.cpp @@ -46,7 +46,7 @@ Ludovic Apvrille, Renaud Pacalet #include <Slave.h> #include <TMLChannel.h> -CPU::CPU(std::string iName, 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):_name(iName), _nextTransaction(0), _lastTransaction(0), _busNextTransaction(0), _timePerCycle(iTimePerCycle),_pipelineSize(iPipelineSize), _taskSwitchingCycles(iTaskSwitchingCycles),_brachingMissrate(iBranchingMissrate), _changeIdleModeCycles(iChangeIdleModeCycles), _cyclesBeforeIdle(iCyclesBeforeIdle), _cyclesPerExeci(iCyclesPerExeci), _busyCycles(0), _contentionDelay(0), _noBusTransactions(0), _timePerExeci(_cyclesPerExeci*_timePerCycle), _taskSwitchingTime(_taskSwitchingCycles*_timePerCycle), _timeBeforeIdle(_cyclesBeforeIdle*_timePerCycle), _changeIdleModeTime(_changeIdleModeCycles*_timePerCycle), _pipelineSizeTimesExeci(_pipelineSize * _timePerExeci),_missrateTimesPipelinesize(_brachingMissrate*_pipelineSize), _branchMissReminder(0), _branchMissTempReminder(0){ +CPU::CPU(std::string iName, 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):_name(iName), _nextTransaction(0), _lastTransaction(0), _busNextTransaction(0), _timePerCycle(iTimePerCycle),_pipelineSize(iPipelineSize), _taskSwitchingCycles(iTaskSwitchingCycles),_brachingMissrate(iBranchingMissrate), _changeIdleModeCycles(iChangeIdleModeCycles), _cyclesBeforeIdle(iCyclesBeforeIdle), _cyclesPerExeci(iCyclesPerExeci), _busyCycles(0), /*_busContentionDelay(0), _noBusTransactions(0),*/ _timePerExeci(_cyclesPerExeci*_timePerCycle), _taskSwitchingTime(_taskSwitchingCycles*_timePerCycle), _timeBeforeIdle(_cyclesBeforeIdle*_timePerCycle), _changeIdleModeTime(_changeIdleModeCycles*_timePerCycle), _pipelineSizeTimesExeci(_pipelineSize * _timePerExeci),_missrateTimesPipelinesize(_brachingMissrate*_pipelineSize), _branchMissReminder(0), _branchMissTempReminder(0){ _myid=++_id; _transactList.reserve(BLOCK_SIZE); } @@ -68,10 +68,25 @@ void CPU::registerTask(TMLTask* iTask){ TMLTransaction* CPU::getNextTransaction(){ #ifdef BUS_ENABLED - if (_busNextTransaction==0){ + if (_busNextTransaction==0 || _nextTransaction==0){ return _nextTransaction; }else{ - return (_busNextTransaction->getNextTransaction()==_nextTransaction)?_nextTransaction:0; +#ifdef DEBUG_CPU + std::cout << "CPU:getNT: " << _name << " has bus transacion on bus " << _busNextTransaction->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); + //std::cout << "1" << std::endl; + bool aResult = aTempBus->getNextTransaction()==_nextTransaction; + //std::cout << "2" << std::endl; + while (aResult && aTempBus!=_busNextTransaction){ + //std::cout << "3" << std::endl; + aTempBus =_nextTransaction->getChannel()->getNextBus(_nextTransaction); + //std::cout << "4" << std::endl; + aResult = aTempBus->getNextTransaction()==_nextTransaction; + } + return (aResult)?_nextTransaction:0; } #else return _nextTransaction; @@ -186,21 +201,22 @@ bool CPU::addTransaction(){ std::cout << _name << "CPU:addT: handling bus transaction" << std::endl; #endif Slave* aLastSlave=_nextTransaction->getChannel()->getNextSlave(_nextTransaction); - _busNextTransaction=_nextTransaction->getChannel()->getNextBus(_nextTransaction); - if (_busNextTransaction==0){ + SchedulableCommDevice* aFollowingBus =_nextTransaction->getChannel()->getNextBus(_nextTransaction); + if (aFollowingBus==0){ //std::cout << _name << " bus transaction finished" << std::endl; aFinish=true; //std::cout << _name << " before loop" << std::endl; - _contentionDelay+=_nextTransaction->getStartTime()-_nextTransaction->getRunnableTime(); - _noBusTransactions++; + //_busContentionDelay+=_nextTransaction->getStartTime()-max(_endSchedule,_nextTransaction->getRunnableTime()); + //_noBusTransactions++; SchedulableCommDevice* aTempBus =_nextTransaction->getChannel()->getFirstBus(_nextTransaction); + addBusContention(aTempBus, _nextTransaction->getStartTime()-max(_endSchedule,_nextTransaction->getRunnableTime())); while (aTempBus!=0){ aTempBus->addTransaction(); aTempBus =_nextTransaction->getChannel()->getNextBus(_nextTransaction); } - //std::cout << _name << " after loop" << std::endl; }else{ //std::cout << _name << " bus transaction next round" << std::endl; + _busNextTransaction=aFollowingBus; _busNextTransaction->registerTransaction(_nextTransaction,aLastSlave->getConnectedMaster()); aFinish=false; } @@ -288,6 +304,7 @@ void CPU::schedule2HTML(std::ofstream& myfile){ myfile << "<td class=\"t"<< aColor <<"\"></td><td>"<< (*j)->toString() << "</td><td class=\"space\"></td>\n"; } myfile << "</tr>"; +#ifdef ADD_COMMENTS while(aMoreComments){ aMoreComments=false; myfile << "<tr>"; @@ -305,6 +322,7 @@ void CPU::schedule2HTML(std::ofstream& myfile){ aInit=false; myfile << "</tr>\n"; } +#endif myfile << "</table>\n"; } @@ -392,5 +410,7 @@ TMLTransaction* CPU::getTransactions1By1(bool iInit){ void CPU::streamBenchmarks(std::ostream& s){ s << "*** CPU " << _name << " ***\n"; if (_simulatedTime!=0) s << "Utilization: " << ((float)_busyCycles)/((float)_simulatedTime) << std::endl; - if (_noBusTransactions!=0) s << "Average contention delay: " << ((float)_contentionDelay)/((float)_noBusTransactions) << std::endl; + Master::streamBenchmarks(s); + //if (_noBusTransactions!=0) s << "Average BUS contention delay: " << ((float)_busContentionDelay)/((float)_noBusTransactions) << std::endl; + } diff --git a/simulators/c++2/src_simulator/CPU.h b/simulators/c++2/src_simulator/CPU.h index 5ec35b3f6e..c72223b710 100644 --- a/simulators/c++2/src_simulator/CPU.h +++ b/simulators/c++2/src_simulator/CPU.h @@ -122,13 +122,6 @@ public: \param myfile Reference to the ofstream object representing the output file */ void schedule2HTML(std::ofstream& myfile); - ///Creates a string representation of the next signal change of the device (VCD format) - /** - \param iInit If init is true, the methods starts from the first transaction - \param oSigChange String representation of the signal change - \param oNoMoreTrans Is true if the last transaction is processed - \return Time when the signal change occurred - */ TMLTime getNextSignalChange(bool iInit, std::string& oSigChange, bool& oNoMoreTrans); ///Returns the scheduled transaction one after another /** @@ -181,10 +174,10 @@ protected: unsigned int _cyclesPerExeci; ///Busy cycles since simulation start unsigned long _busyCycles; - ///Contention delay of transactions (startTime-runnableTime) - unsigned long _contentionDelay; - ///Number of executed transactions which have accessed a bus - unsigned int _noBusTransactions; + /////Sum of contention delay of bus transactions + //unsigned long _busContentionDelay; + /////Number of executed transactions which have accessed a bus + //unsigned long _noBusTransactions; //values deduced from CPU parameters ///Time needed to execute one execi unit diff --git a/simulators/c++2/src_simulator/Master.h b/simulators/c++2/src_simulator/Master.h index eb3451239a..e7a333d65e 100644 --- a/simulators/c++2/src_simulator/Master.h +++ b/simulators/c++2/src_simulator/Master.h @@ -42,6 +42,8 @@ Ludovic Apvrille, Renaud Pacalet #define MasterH #include <definitions.h> +#include <SchedulableCommDevice.h> +#include <BusMasterInfo.h> class TMLTransaction; class SchedulableCommDevice; @@ -57,7 +59,8 @@ public: \return Bus priority */ unsigned int getBusPriority(SchedulableCommDevice* iDevice){ - return _masterPrioHashTab[iDevice]; + //return _masterPrioHashTab[iDevice]; + return _masterPrioHashTab[iDevice]->getPriority(); } ///Sets the priority of the master for a given bus /** @@ -65,17 +68,33 @@ public: \param iPrio Priority */ void addBusPriority(SchedulableCommDevice* iDevice, unsigned int iPrio){ - _masterPrioHashTab[iDevice]=iPrio; + //_masterPrioHashTab[iDevice]=iPrio; + _masterPrioHashTab[iDevice]= new BusMasterInfo(iPrio); } - /////Returns the current transaction if it needs to access the given bus - ////** - //\param iBus Pointer to the bus - //\return Pointer to the transaction - //*/ - //TMLTransaction* getNextBusTransaction(SchedulableCommDevice* iBus) const; ///Destructor - virtual ~Master(){} + virtual ~Master(){ + for(MasterPriorityHashTab::iterator i=_masterPrioHashTab.begin(); i != _masterPrioHashTab.end(); ++i){ + delete i->second; + } + } 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){ + _masterPrioHashTab[iDevice]->addContention(iContentionDelay); + } + ///Writes benchmarking data to a given stream + /** + \param s Reference to an output stream + */ + void streamBenchmarks(std::ostream& s){ + for(MasterPriorityHashTab::iterator i=_masterPrioHashTab.begin(); i != _masterPrioHashTab.end(); ++i){ + s << "Average contention delay for bus " << i->first->toString() << ": " << i->second->getContentionDelay() << std::endl; + } + } ///Map which associates the bus and the priority MasterPriorityHashTab _masterPrioHashTab; }; diff --git a/simulators/c++2/src_simulator/SchedulableDevice.h b/simulators/c++2/src_simulator/SchedulableDevice.h index a5b8747bf4..5a8525d45b 100644 --- a/simulators/c++2/src_simulator/SchedulableDevice.h +++ b/simulators/c++2/src_simulator/SchedulableDevice.h @@ -81,8 +81,6 @@ public: */ virtual void schedule2TXT(std::ofstream& myfile)=0; virtual std::string toString()=0; - ///Destructor - virtual ~SchedulableDevice(){} virtual std::istream& readObject(std::istream &is){ READ_STREAM(is,_endSchedule); return is; @@ -91,6 +89,9 @@ public: WRITE_STREAM(os,_endSchedule); return os; } + static TMLTime getSimulatedTime(){return _simulatedTime;} + ///Destructor + virtual ~SchedulableDevice(){} protected: ///Class variable holding the simulation time static TMLTime _simulatedTime; diff --git a/simulators/c++2/src_simulator/TMLTask.cpp b/simulators/c++2/src_simulator/TMLTask.cpp index f534192410..bb26ca30c4 100644 --- a/simulators/c++2/src_simulator/TMLTask.cpp +++ b/simulators/c++2/src_simulator/TMLTask.cpp @@ -42,18 +42,22 @@ Ludovic Apvrille, Renaud Pacalet #include <TMLCommand.h> #include <CPU.h> -TMLTask::TMLTask(unsigned int iPriority, std::string iName, CPU* iCPU):_name(iName), _priority(iPriority), _endLastTransaction(0), _currCommand(0), _cpu(iCPU), _previousTransEndTime(0), _comment(0), _busyCycles(0) { +TMLTask::TMLTask(unsigned int iPriority, std::string iName, CPU* iCPU):_name(iName), _priority(iPriority), _endLastTransaction(0), _currCommand(0), _cpu(iCPU), _previousTransEndTime(0), _comment(0), _busyCycles(0), _CPUContentionDelay(0), _noCPUTransactions(0) { _myid=++_id; _cpu->registerTask(this); +#ifdef ADD_COMMENTS _commentList.reserve(BLOCK_SIZE); +#endif _transactList.reserve(BLOCK_SIZE); } TMLTask::~TMLTask(){ CommentList::iterator i; +#ifdef ADD_COMMENTS for(i=_commentList.begin(); i != _commentList.end(); ++i){ delete *i; } +#endif if (_comment!=0) delete [] _comment; } @@ -92,6 +96,7 @@ unsigned int TMLTask::getID(){ return _myid; } +#ifdef ADD_COMMENTS void TMLTask::addComment(Comment* iComment){ _commentList.push_back(iComment); } @@ -108,11 +113,16 @@ std::string TMLTask::getNextComment(bool iInit, Comment*& oComment){ _posCommentList++; return ((oComment->_command==0)?_comment[oComment->_actionCode]:oComment->_command->getCommentString(oComment)); } +#endif void TMLTask::addTransaction(TMLTransaction* iTrans){ _transactList.push_back(iTrans); _endLastTransaction=iTrans->getEndTime(); _busyCycles+=iTrans->getOperationLength(); + if(iTrans->getChannel()==0){ + _noCPUTransactions++; + _CPUContentionDelay+=iTrans->getStartTime()-iTrans->getRunnableTime(); + } } TMLTime TMLTask::getNextSignalChange(bool iInit, std::string& oSigChange, bool& oNoMoreTrans){ @@ -203,5 +213,6 @@ std::istream& TMLTask::readObject(std::istream& s){ void TMLTask::streamBenchmarks(std::ostream& s){ s << "*** Task " << _name << " ***\n"; s << "Execution time: " << _busyCycles << std::endl; + if (_noCPUTransactions!=0) s << "Average CPU contention delay: " << ((float)_CPUContentionDelay)/((float)_noCPUTransactions) << std::endl; } diff --git a/simulators/c++2/src_simulator/TMLTask.h b/simulators/c++2/src_simulator/TMLTask.h index ba12590f64..baef90e228 100644 --- a/simulators/c++2/src_simulator/TMLTask.h +++ b/simulators/c++2/src_simulator/TMLTask.h @@ -107,6 +107,7 @@ public: \return Unique ID */ unsigned int getID(); +#ifdef ADD_COMMENTS ///Adds a new execution comment to the internal list /** \param iComment Pointer to the comment @@ -119,13 +120,7 @@ public: \return String representation of the comment */ std::string getNextComment(bool iInit, Comment*& oComment); - ///Returns the next signal change (for vcd output) - /** - \param iInit Indicates if the list iterator has to be reset to the beginning of the list - \param oSigChange This string representation of the signal change is returned to the callee - \param oNoMoreTrans This flag signals to the callee that no more signal changes are available - \return String representation of comment - */ +#endif TMLTime getNextSignalChange(bool iInit, std::string& oSigChange, bool& oNoMoreTrans); ///Adds a given transaction to the internal transaction list /** @@ -150,10 +145,12 @@ protected: unsigned int _myid; ///Class variable counting the number of task instances static unsigned int _id; +#ifdef ADD_COMMENTS ///Comment list CommentList _commentList; ///Actual position within comment list (used for HTML output) CommentList::iterator _posCommentList; +#endif ///List of scheduled transactions TransactionList _transactList; ///Actual position within transaction list (used for vcd output) @@ -166,6 +163,10 @@ protected: std::string* _comment; ///Busy cycles since simulation start unsigned long _busyCycles; + ///Sum of contention delay of CPU transactions + unsigned long _CPUContentionDelay; + ///Number of transactions which have been executed on a CPU + unsigned long _noCPUTransactions; }; #endif diff --git a/simulators/c++2/src_simulator/TraceableDevice.h b/simulators/c++2/src_simulator/TraceableDevice.h index e7a30bf563..6634508f9a 100644 --- a/simulators/c++2/src_simulator/TraceableDevice.h +++ b/simulators/c++2/src_simulator/TraceableDevice.h @@ -67,7 +67,6 @@ public: ///Writes benchmarking data to a given stream /** \param s Reference to an output stream - \param iSimulationTime Duration of the simulation in time units */ virtual void streamBenchmarks(std::ostream& s)=0; ///Destructor diff --git a/simulators/c++2/src_simulator/definitions.h b/simulators/c++2/src_simulator/definitions.h index bd9c615e25..f3d96bd49c 100644 --- a/simulators/c++2/src_simulator/definitions.h +++ b/simulators/c++2/src_simulator/definitions.h @@ -67,12 +67,11 @@ using std::max; #undef DEBUG_BUS #define BUS_ENABLED -//#define EVENTS_MAPPED_ON_BUS #define WAIT_SEND_VLEN 1 #define CPURRPB CPUPB #define CLOCK_INC 20 -#define BLOCK_SIZE 100000 -#define ADD_COMMENTS +#define BLOCK_SIZE 500000 +#undef ADD_COMMENTS #define NO_EVENTS_TO_LOAD 10 //Task VCD output @@ -90,14 +89,7 @@ class SchedulableDevice; template <typename T> class Parameter; class TraceableDevice; class Master; - -enum vcdBusVisState - { - END_IDLE_BUS, - END_READ_BUS, - END_WRITE_BUS, - INIT_BUS -}; +class BusMasterInfo; ///Datatype used for time measurements typedef unsigned int TMLTime; @@ -120,7 +112,7 @@ typedef std::map<Master*, TMLTransaction*> BusTransHashTab; /////Datatype establishing an association between a transaction and its priority, used by buses //typedef std::multimap<unsigned int, Master*> BusMasterPrioTab; ///Datatype establishing an association between a bus and a priority, used by Masters -typedef std::map<SchedulableCommDevice*, unsigned int> MasterPriorityHashTab; +typedef std::map<SchedulableCommDevice*, BusMasterInfo*> MasterPriorityHashTab; ///Datatype for event parameters typedef int ParamType; ///Datatype used in EventChannels to store parameters of events diff --git a/simulators/c++2/src_simulator/simkern.cpp b/simulators/c++2/src_simulator/simkern.cpp index 9d0920568b..e640675994 100644 --- a/simulators/c++2/src_simulator/simkern.cpp +++ b/simulators/c++2/src_simulator/simkern.cpp @@ -324,9 +324,9 @@ void simulate(SchedulingList& iSchedList, BusList& buslist){ } } } -#ifdef DEBUG_KERNEL - else std::cout << "kernel:simulate: *** this should never happen ***" << std::endl; -#endif +//#ifdef DEBUG_KERNEL +// else std::cout << "kernel:simulate: *** this should never happen ***" << std::endl; +//#endif transLET=getTransLowestEndTime(iSchedList,cpuLET); } gettimeofday(&aEnd,NULL); -- GitLab