FPGA.cpp 47.2 KB
Newer Older
Siyuan Niu's avatar
Siyuan Niu committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Niu Siyuan,
  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.
  *
  */

#include <FPGA.h>
#include <TMLTask.h>
#include <TMLCommand.h>
#include <TMLTransaction.h>
#include <Bus.h>
#include <Slave.h>
#include <TMLChannel.h>


FPGA::FPGA(    ID iID, 
Siyuan Niu's avatar
Siyuan Niu committed
51
	       std::string iName,  
Siyuan Niu's avatar
Siyuan Niu committed
52
	       WorkloadSource* iScheduler,
53
54
	       TMLTime iReconfigTime,
	       TMLTime iTimePerCycle,
Siyuan Niu's avatar
Siyuan Niu committed
55
56
57
	       unsigned int iChangeIdleModeCycles, 
	       unsigned int iCyclesBeforeIdle,
	       unsigned int iCyclesPerExeci, 
Siyuan Niu's avatar
Siyuan Niu committed
58
	       unsigned int iCyclesPerExecc ) : SchedulableDevice(iID, iName, iScheduler)
Siyuan Niu's avatar
Siyuan Niu committed
59
					      ,_reconfigTime(iReconfigTime)
60
					      ,_timePerCycle(iTimePerCycle)
Le Van Truong's avatar
Le Van Truong committed
61
					      ,_masterNextTransaction(0)
Siyuan Niu's avatar
Siyuan Niu committed
62
					      ,_lastTransaction(0)
63
64
65
66
					      ,_changeIdleModeCycles(iChangeIdleModeCycles * _timePerCycle)
					      ,_cyclesBeforeIdle(iCyclesBeforeIdle * _timePerCycle)
					      ,_cyclesPerExeci(iCyclesPerExeci * _timePerCycle)
					      ,_cyclesPerExecc(iCyclesPerExecc * _timePerCycle)
Siyuan Niu's avatar
Siyuan Niu committed
67
68
69
					      ,_reconfigNumber(0)
					      ,_maxEndTime(0)
					     
Siyuan Niu's avatar
Siyuan Niu committed
70
					     
Siyuan Niu's avatar
Siyuan Niu committed
71
72
73
74
75
76
77
78
79
{}

FPGA::~FPGA(){}


void FPGA::streamBenchmarks(std::ostream& s) const{
  std::cout<<"test fpga stramBenchmarks"<<std::endl;
  s << TAG_FPGAo << " id=\"" << _ID << "\" name=\"" << _name << "\">" << std::endl;
  if (_simulatedTime!=0) s << TAG_UTILo << (static_cast<float>(_busyCycles)/static_cast<float>(_simulatedTime)) << TAG_UTILc;
80
//  s << TAG_ENERGYo << ( (_simulatedTime)*_static_consumPerCycle) + ((_busyCycles)*_dynamic_consumPerCycle) << TAG_ENERGYc;
Siyuan Niu's avatar
Siyuan Niu committed
81
  std::cout<< "power consumption "<< ((_simulatedTime)*_static_consumPerCycle) + ((_busyCycles)*_dynamic_consumPerCycle)<< std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
82
83
84
85
86
  for(BusMasterList::const_iterator i=_busMasterList.begin(); i != _busMasterList.end(); ++i) (*i)->streamBenchmarks(s);
  s << TAG_FPGAc;
}

TMLTransaction* FPGA::getNextTransaction(){
Siyuan Niu's avatar
Siyuan Niu committed
87
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
88
 std::cout<<"fpga getNextTransaction"<<_name<<" ";
Siyuan Niu's avatar
Siyuan Niu committed
89
90
#endif
#ifdef BUS_ENABLED
Siyuan Niu's avatar
Siyuan Niu committed
91
  if (_masterNextTransaction==0 || _nextTransaction==0){
Siyuan Niu's avatar
Siyuan Niu committed
92
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
93
94
    if(_masterNextTransaction == 0) std::cout<<"master is 0"<<std::endl;
    if(_nextTransaction==0) std::cout<<"nexttrans is 0"<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
95
#endif
Siyuan Niu's avatar
Siyuan Niu committed
96
97
98
99
100
    //if(_nextTransaction)  std::cout<<_nextTransaction->toString()<<std::endl;
     return _nextTransaction;
     //return 0;
  }else{
    //std::cout << "CRASH Trans:" << _nextTransaction->toString() << std::endl << "Channel: " << _nextTransaction->getChannel() << "\n";
Siyuan Niu's avatar
Siyuan Niu committed
101
    BusMaster* aTempMaster = getMasterForBus(_nextTransaction->getChannel()->getFirstMaster(_nextTransaction));
Siyuan Niu's avatar
Siyuan Niu committed
102
    std::cout << "1  aTempMaster: " << aTempMaster << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
103
    bool aResult = aTempMaster->accessGranted();
Siyuan Niu's avatar
Siyuan Niu committed
104
    // std::cout << "2" << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
105
    while (aResult && aTempMaster!=_masterNextTransaction){
Siyuan Niu's avatar
Siyuan Niu committed
106
      // std::cout << "3" << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
107
      aTempMaster =_nextTransaction->getChannel()->getNextMaster(_nextTransaction);
Siyuan Niu's avatar
Siyuan Niu committed
108
      // std::cout << "4" << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
109
      aResult = aTempMaster->accessGranted();
Siyuan Niu's avatar
Siyuan Niu committed
110
      // std::cout << "5" << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
111
    }
Siyuan Niu's avatar
Siyuan Niu committed
112
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
113
    if(_nextTransaction)std::cout<<"haha1"<<_nextTransaction->toString()<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
114
#endif
Sophie Coudert's avatar
Sophie Coudert committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
    if (aResult){
    	    if (_nextTransaction->getChannel()->isLastMaster(_nextTransaction) && _nextTransaction->getTransType()==BUS_TRANS_NoLength){
    	    	    _nextTransaction->setLength(0);
    	    	    aTempMaster = getMasterForBus(_nextTransaction->getChannel()->getFirstMaster(_nextTransaction));
    	    	    while (aTempMaster!=_masterNextTransaction){
    	    	    	    aTempMaster->getNextBus()->calcLength();
    	    	            aTempMaster =_nextTransaction->getChannel()->getNextMaster(_nextTransaction);
    	    	    }
    	    	    _masterNextTransaction->getNextBus()->calcLength();
    	    	    _nextTransaction->setTransType(BUS_TRANS_Length);
    	    }
    	    return _nextTransaction;
    } else 
    	    return 0;
Siyuan Niu's avatar
Siyuan Niu committed
129
130
  }
#else
Siyuan Niu's avatar
Siyuan Niu committed
131
132
  if(_nextTransaction)std::cout<<"haha2"<<_nextTransaction->toString()<<std::endl;

Siyuan Niu's avatar
Siyuan Niu committed
133
134
135
136
  return _nextTransaction;
#endif
 }

Siyuan Niu's avatar
Siyuan Niu committed
137
void FPGA::calcStartTimeLength(){
Siyuan Niu's avatar
Siyuan Niu committed
138
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
139
  std::cout<<"fpga calStartTimeLength "<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
140
#endif
Siyuan Niu's avatar
Siyuan Niu committed
141
142
143
144
145
146
147
  
#ifdef BUS_ENABLED
  
  std::cout << "FPGA:calcSTL: scheduling decision of FPGA " << _name << ": " << _nextTransaction->toString() << std::endl;
  TMLChannel* aChannel=_nextTransaction->getCommand()->getChannel(0);
  if (aChannel==0) {
    _masterNextTransaction=0;
Sophie Coudert's avatar
Sophie Coudert committed
148
    _nextTransaction->setTransType(NOCOMM_TRANS);
Siyuan Niu's avatar
Siyuan Niu committed
149
150
151
152
153
154
  } else {
    _masterNextTransaction= getMasterForBus(aChannel->getFirstMaster(_nextTransaction));
    if (_masterNextTransaction!=0){
      std::cout << "before register transaction at bus " << _masterNextTransaction->toString() << std::endl;
      _masterNextTransaction->registerTransaction(_nextTransaction);
      std::cout << "Transaction registered at bus " << _masterNextTransaction->toString() << std::endl;
Sophie Coudert's avatar
Sophie Coudert committed
155
      _nextTransaction->setTransType(BUS_TRANS_NoLength);
Siyuan Niu's avatar
Siyuan Niu committed
156
157
    } else {
      std::cout << "                          NO MASTER NEXT TRANSACTION " << std::endl;
Sophie Coudert's avatar
Sophie Coudert committed
158
      _nextTransaction->setTransType(CHANNEL_TRANS);
Siyuan Niu's avatar
Siyuan Niu committed
159
160
161
162
    }
  }
#endif
  //round to full cycles!!!
163

Siyuan Niu's avatar
Siyuan Niu committed
164
165
  TMLTime aStartTime = max(_endSchedule,_nextTransaction->getRunnableTime());
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
166
  std::cout<<"start time !!!!!!!!!!"<<_nextTransaction->toShortString()<<"is "<<aStartTime<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
167
#endif
Siyuan Niu's avatar
Siyuan Niu committed
168
  //or setStartTime(0)???
Siyuan Niu's avatar
Siyuan Niu committed
169
170
171
  _nextTransaction->setStartTime(aStartTime);
#ifdef BUS_ENABLED
  if (_masterNextTransaction==0){
Siyuan Niu's avatar
Siyuan Niu committed
172
#endif  
173
174
175
176
177
178
  
    if( (_nextTransaction->getCommand() != 0) && (_nextTransaction->getCommand()->getExecType() == 1) ) {
      _nextTransaction->setLength(max(_nextTransaction->getVirtualLength() * _cyclesPerExecc,(TMLTime)1));
    } else {
      _nextTransaction->setLength(max(_nextTransaction->getVirtualLength() * _cyclesPerExeci,(TMLTime)1));
    }
179
#ifdef BUS_ENABLED
Siyuan Niu's avatar
Siyuan Niu committed
180
  }
181
#endif
Siyuan Niu's avatar
Siyuan Niu committed
182
183
}

Siyuan Niu's avatar
Siyuan Niu committed
184

Siyuan Niu's avatar
Siyuan Niu committed
185
186
187
188
189
190
void FPGA::truncateAndAddNextTransAt(TMLTime iTime){
std::cout<<"fpga truncateAndAddNextTransAt"<<std::endl;
  //std::cout << "CPU:schedule BEGIN " << _name << "+++++++++++++++++++++++++++++++++\n";
  //return truncateNextTransAt(iTime);
  //not a problem if scheduling does not take place at time when transaction is actually truncated, tested
  //std::cout << "CPU:truncateAndAddNextTransAt " << _name << "time: +++++++++++++++++++++" << iTime << "\n";
Siyuan Niu's avatar
Siyuan Niu committed
191
//  TMLTime aTimeSlice = _scheduler->schedule(iTime);
Siyuan Niu's avatar
Siyuan Niu committed
192
  //_schedulingNeeded=false;  05/05/11
Sophie Coudert's avatar
Sophie Coudert committed
193
194
195
  if (_nextTransaction->getTransType()==NOCOMM_TRANS){
    TMLTransaction* aNewTransaction =_scheduler->getNextTransaction(iTime);
    //std::cout << "before if\n";
Siyuan Niu's avatar
Siyuan Niu committed
196

Sophie Coudert's avatar
Sophie Coudert committed
197
    //_scheduler->transWasScheduled(this); //NEW  was in if before 05/05/11
Siyuan Niu's avatar
Siyuan Niu committed
198

Sophie Coudert's avatar
Sophie Coudert committed
199
200
201
202
203
204
205
206
    if (aNewTransaction!=_nextTransaction){
      //std::cout << "in if\n";
      if (truncateNextTransAt(iTime)!=0) addTransaction(0);
      //if (_nextTransaction!=0 && truncateNextTransAt(iTime)!=0) addTransaction(); //NEW!!!!
      if (_nextTransaction!=0 && _masterNextTransaction!=0) _masterNextTransaction->registerTransaction(0);
      _nextTransaction = aNewTransaction;
      if (_nextTransaction!=0) calcStartTimeLength();
    }
Siyuan Niu's avatar
Siyuan Niu committed
207
208
209
210
211
212
213
214
  }
  //std::cout << "CPU:schedule END " << _name << "+++++++++++++++++++++++++++++++++\n";
}

TMLTime FPGA::truncateNextTransAt(TMLTime iTime){
std::cout<<"fpga truncateNextTransAt"<<std::endl;
  if (_masterNextTransaction==0){
    if (iTime <= _nextTransaction->getStartTime()) return 0;  //before: <=
215
    unsigned int timeExec = _cyclesPerExeci;
216
217
218
     //std::cout << "CPU: EXECI or EXECC??" << "\n";
    if( (_nextTransaction->getCommand() != 0) && (_nextTransaction->getCommand()->getExecType() == 1) ) {
      //std::cout << "CPU: EXECC" << "\n";
219
      timeExec = _cyclesPerExecc;
220
    }
Siyuan Niu's avatar
Siyuan Niu committed
221
    TMLTime aNewDuration = iTime - _nextTransaction->getStartTime();
Siyuan Niu's avatar
Siyuan Niu committed
222
    _nextTransaction->setVirtualLength(max((TMLTime)(aNewDuration), (TMLTime)1));
223
    _nextTransaction->setLength(_nextTransaction->getVirtualLength() * timeExec);
Siyuan Niu's avatar
Siyuan Niu committed
224
225
226
227
228
229
230
  }
  return _nextTransaction->getOverallLength();
}



bool FPGA::addTransaction(TMLTransaction* iTransToBeAdded){
Siyuan Niu's avatar
Siyuan Niu committed
231
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
232
std::cout<<"fpga addTransaction"<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
233
#endif
Siyuan Niu's avatar
Siyuan Niu committed
234
235
236
237
238
239
240
  bool aFinish;
  std::cout << "*************** LOOKING for master of" << _nextTransaction->toString() << std::endl;
  if (_masterNextTransaction==0){
    aFinish=true;
  }else{
    BusMaster* aFollowingMaster =_nextTransaction->getChannel()->getNextMaster(_nextTransaction);
    if (aFollowingMaster==0){
Siyuan Niu's avatar
Siyuan Niu committed
241
      //std::cout << "1\n";
Siyuan Niu's avatar
Siyuan Niu committed
242
243
      aFinish=true;
      BusMaster* aTempMaster = getMasterForBus(_nextTransaction->getChannel()->getFirstMaster(_nextTransaction));
Siyuan Niu's avatar
Siyuan Niu committed
244
      // std::cout << "2\n";
Siyuan Niu's avatar
Siyuan Niu committed
245
      Slave* aTempSlave= _nextTransaction->getChannel()->getNextSlave(_nextTransaction);
Siyuan Niu's avatar
Siyuan Niu committed
246
      //std::cout << "3\n";
Siyuan Niu's avatar
Siyuan Niu committed
247
      while (aTempMaster!=0){
Siyuan Niu's avatar
Siyuan Niu committed
248
	// std::cout << "3a\n";
Siyuan Niu's avatar
Siyuan Niu committed
249
        aTempMaster->addTransaction(_nextTransaction);
Siyuan Niu's avatar
Siyuan Niu committed
250
	// std::cout << "3b\n";
Siyuan Niu's avatar
Siyuan Niu committed
251
252
        //if (aTempSlave!=0) aTempSlave->addTransaction(_nextTransaction);
        if (aTempSlave!=0) aTempSlave->addTransaction(_nextTransaction);  //NEW
Siyuan Niu's avatar
Siyuan Niu committed
253
        //std::cout << "4\n";
Siyuan Niu's avatar
Siyuan Niu committed
254
        aTempMaster =_nextTransaction->getChannel()->getNextMaster(_nextTransaction);
Siyuan Niu's avatar
Siyuan Niu committed
255
        //std::cout << "5\n";
Siyuan Niu's avatar
Siyuan Niu committed
256
257
        aTempSlave= _nextTransaction->getChannel()->getNextSlave(_nextTransaction);
      }
Siyuan Niu's avatar
Siyuan Niu committed
258
      // std::cout << "6\n";
Siyuan Niu's avatar
Siyuan Niu committed
259
260
261
    } else {
      std::cout << _name << " bus transaction next round" << std::endl;
      _masterNextTransaction=aFollowingMaster;
Siyuan Niu's avatar
Siyuan Niu committed
262
      // std::cout << "7\n";
Siyuan Niu's avatar
Siyuan Niu committed
263
264
265
266
267
      _masterNextTransaction->registerTransaction(_nextTransaction);
      aFinish=false;
    }
    //std::cout << "8\n";
  }
Siyuan Niu's avatar
Siyuan Niu committed
268
 
Siyuan Niu's avatar
Siyuan Niu committed
269
  if (aFinish){
Siyuan Niu's avatar
Siyuan Niu committed
270
271
272
#ifdef DEBUG_FPGA
    std::cout<<"I am in finish!!!"<<std::endl;
#endif
Siyuan Niu's avatar
Siyuan Niu committed
273
274
275
276
277
    //_endSchedule=0;
    // _maxEndTime=max(_maxEndTime,_nextTransaction->getEndTime())
    //std::cout<<"end schedule is ~~~~~~~"<<_endSchedule<<std::endl;
    if(_endSchedule == 0 && (!(_nextTransaction->getCommand()->getTask()->getIsDaemon()==true && _nextTransaction->getCommand()->getTask()->getNextTransaction(0)==0))) 
      _maxEndTime=max(_maxEndTime,_nextTransaction->getEndTime());
278
279
280
281
282
283
284
285
286
287

    unsigned int _highestRank = 1000;
    for(TaskList::const_iterator i = _taskList.begin(); i!= _taskList.end(); ++i){
          if((*i)->getPriority() < _highestRank) {
              _highestRank = (*i)->getPriority();
              if(_highestRank == 0)
                  break;
          }
    }
    unsigned int _tempReconfigNumber = _reconfigNumber - _highestRank;
288
    unsigned int timeExec = _cyclesPerExeci;
289
290
291
     //std::cout << "CPU: EXECI or EXECC??" << "\n";
    if( (_nextTransaction->getCommand() != 0) && (_nextTransaction->getCommand()->getExecType() == 1) ) {
      //std::cout << "CPU: EXECC" << "\n";
292
      timeExec = _cyclesPerExecc;
293
    }
294
295
296
297
298
    if(_tempReconfigNumber == 0 && _reconfigNumber > 0) {
        std::string _tempTranName = _nextTransaction->toShortString();
        if(!_nextTransaction->getCommand()->getTask()->getIsFirstTranExecuted() && (_tempTranName.find("Read") == std::string::npos
        && _tempTranName.find("Wait") == std::string::npos && _tempTranName.find("Notified") == std::string::npos)) {
            unsigned int _tempStartTime = _nextTransaction->getStartTime();
299
            _nextTransaction->setStartTime(_tempStartTime + _reconfigNumber * _reconfigTime * timeExec);
300
            _maxEndTime=max(_maxEndTime,_nextTransaction->getEndTime());
301
            _transactListReconfig.push_back(_nextTransaction);
302
303
304
        }
        _nextTransaction->getCommand()->getTask()->setIsFirstTranExecuted(true);
    } else if(_tempReconfigNumber>0) {
Le Van Truong's avatar
Le Van Truong committed
305
        if(!_nextTransaction->getCommand()->getTask()->getIsFirstTranExecuted()) {
306
            _nextTransaction->setStartTime(_maxEndTime + _tempReconfigNumber * _reconfigTime * timeExec);
Le Van Truong's avatar
Le Van Truong committed
307
            _nextTransaction->getCommand()->getTask()->setIsFirstTranExecuted(true);
308
            _transactListReconfig.push_back(_nextTransaction);
Le Van Truong's avatar
Le Van Truong committed
309
310
        }
    }
Siyuan Niu's avatar
Siyuan Niu committed
311
312
    else{
      _endSchedule=0;
Siyuan Niu's avatar
Siyuan Niu committed
313
      
Siyuan Niu's avatar
Siyuan Niu committed
314
315
    }
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
316
317
318
    
    std::cout<<"_maxEndTime is "<<_maxEndTime<<std::endl;
    
Siyuan Niu's avatar
Siyuan Niu committed
319
    std::cout<<"endschedule is!! "<<_endSchedule<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
320
    if(_nextTransaction==0) std::cout<<"000"<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
321
#endif
Siyuan Niu's avatar
Siyuan Niu committed
322
    _simulatedTime=max(_simulatedTime,_nextTransaction->getEndTime());
Siyuan Niu's avatar
Siyuan Niu committed
323
324
325
    _overallTransNo++; //NEW!!!!!!!!
    _overallTransSize+=_nextTransaction->getOperationLength();  //NEW!!!!!!!!
    //std::cout << "lets crash execute\n";
Siyuan Niu's avatar
Siyuan Niu committed
326
327
    // std::cout<<_nextTransaction->toString()<<std::endl;
     _nextTransaction->getCommand()->execute();  //NEW!!!!
Siyuan Niu's avatar
Siyuan Niu committed
328
329
330
331
332
333
334
335
336
    //std::cout << "not crashed\n";
#ifdef TRANSLIST_ENABLED
    _transactList.push_back(_nextTransaction);
#endif
    _lastTransaction=_nextTransaction;
    _busyCycles+=_nextTransaction->getOverallLength();
#ifdef LISTENERS_ENABLED
    NOTIFY_TRANS_EXECUTED(_nextTransaction);
#endif
Siyuan Niu's avatar
Siyuan Niu committed
337
  
Siyuan Niu's avatar
Siyuan Niu committed
338
    _nextTransaction=0;
Siyuan Niu's avatar
Siyuan Niu committed
339

Siyuan Niu's avatar
Siyuan Niu committed
340
341
342
343
344
345
    return true;
  } else return false;
}

void FPGA::schedule(){ 
  std::cout << "fpga:schedule BEGIN " << _name << "+++++++++++++++++++++++++++++++++\n";
Siyuan Niu's avatar
Siyuan Niu committed
346
347
  _reconfigNumber=_scheduler->schedule(_endSchedule);
  TMLTransaction* aOldTransaction = _nextTransaction; 
Siyuan Niu's avatar
Siyuan Niu committed
348
  _nextTransaction=_scheduler->getNextTransaction(_endSchedule);
Siyuan Niu's avatar
Siyuan Niu committed
349
  
Siyuan Niu's avatar
Siyuan Niu committed
350
  if (aOldTransaction!=0 && aOldTransaction!=_nextTransaction){ //NEW 
Siyuan Niu's avatar
Siyuan Niu committed
351
352
353
354
355
    if (_masterNextTransaction!=0) {
      _masterNextTransaction->registerTransaction(0);

    }
  }
Siyuan Niu's avatar
Siyuan Niu committed
356
  //if(_nextTransaction!=0) std::cout<<"nextTransaction is~~~~ "<< _nextTransaction->toShortString()<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
357
  if (_nextTransaction!=0 && aOldTransaction != _nextTransaction)  calcStartTimeLength();
Siyuan Niu's avatar
Siyuan Niu committed
358
359
360
361
  std::cout << "fpga:schedule END " << _name << "+++++++++++++++++++++++++++++++++\n";
}

void FPGA::getNextSignalChange(bool iInit, SignalChangeData* oSigData){
Siyuan Niu's avatar
Siyuan Niu committed
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  std::cout<<"getNextSignalChangemulticore!!!---------"<<std::endl;
  for( TransactionList::iterator i = _transactList.begin(); i != _transactList.end(); ++i ) {
    
    // std::cout<<"transaction core number is "<<  (*i)->getTransFpgaNumber()<<std::endl;
    // std::cout<<"cpu core number "<< oSigData->_transNumberVcd<<std::endl;
    if((*i)-> getCommand()->getTask() == oSigData->_taskFPGA){
      
      std::cout<<"bingo!!"<<(*i)->toShortString()<<std::endl;

      if (iInit){
	_posTrasactListVCD= i;
	_previousTransEndTime=0;
	std::cout<<"init start time "<<(*_posTrasactListVCD)->getStartTime()<<std::endl;
	if (_posTrasactListVCD != _transactList.end() && (*_posTrasactListVCD)->getStartTime()!=0){
	  std::cout<<"next idle"<<std::endl;
	  new (oSigData) SignalChangeData(END_IDLE_TRANS, 0, this);
	  (*i)->setTransVcdOutPutState(END_IDLE_TRANS);
	  return;
	}
Siyuan Niu's avatar
Siyuan Niu committed
381
      }
Siyuan Niu's avatar
Siyuan Niu committed
382
383
384
385
      if ((*i)->getEndState() == true){
        std::cout<<"end trans"<<(*i)->getEndTime()<<std::endl;
	new (oSigData) SignalChangeData(END_IDLE_TRANS, (*i)->getEndTime(), this);
        break;
Siyuan Niu's avatar
Siyuan Niu committed
386
      }else{
Siyuan Niu's avatar
Siyuan Niu committed
387
388
389
390
391
	_posTrasactListVCD = i;
	TMLTransaction* aCurrTrans=*_posTrasactListVCD;
       switch (aCurrTrans->getTransVcdOutPutState()){
	case END_TASK_TRANS: 
          
Siyuan Niu's avatar
vcd ok    
Siyuan Niu committed
392
	  std::cout<<"END_TASK_FPGA"<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
	  do{
	    _previousTransEndTime=(*_posTrasactListVCD)->getEndTime();
	    _posTrasactListVCD++;	  
	    while(_posTrasactListVCD != _transactList.end()){
	      if((*_posTrasactListVCD)->getCommand()->getTask() == oSigData->_taskFPGA)
		  break;
		else
		  _posTrasactListVCD++;
	      }
	  }while (_posTrasactListVCD != _transactList.end() && (*_posTrasactListVCD)->getStartTimeOperation()==_previousTransEndTime);
	 
	  aCurrTrans->setTransVcdOutPutState(END_IDLE_TRANS);
	  std::cout<<"what is previous time "<<_previousTransEndTime<<std::endl;
	  std::cout<<"and this??"<<oSigData->_time<<std::endl;
	  new (oSigData) SignalChangeData(END_IDLE_TRANS, _previousTransEndTime, this); 
	  if (_posTrasactListVCD == _transactList.end()) {aCurrTrans->setEndState(true);std::cout<<"hahaha"<<std::endl;}
	  
          _transactList.erase(i);
	  break;
	case END_IDLE_TRANS:
Siyuan Niu's avatar
vcd ok    
Siyuan Niu committed
413
	  std::cout<<"END_IDLE_FPGA"<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
414
415
416
417
418
419
	  
	  aCurrTrans->setTransVcdOutPutState(END_TASK_TRANS);
	  new (oSigData) SignalChangeData(END_TASK_TRANS, aCurrTrans->getStartTime(), this);
	
	  break;
       }
Siyuan Niu's avatar
Siyuan Niu committed
420
421
422
      }
      break;
    }
Siyuan Niu's avatar
Siyuan Niu committed
423
   
Siyuan Niu's avatar
Siyuan Niu committed
424
  }
Siyuan Niu's avatar
Siyuan Niu committed
425
   
Siyuan Niu's avatar
Siyuan Niu committed
426
427
428
429
430
431
432
433
434
}


std::string FPGA::toShortString() const{
  std::ostringstream outp;
  outp << "fpga" << _ID;
  return outp.str();
}

Le Van Truong's avatar
Le Van Truong committed
435
436
437
438
void FPGA::reset(){
  SchedulableDevice::reset();
  _scheduler->reset();
  _transactList.clear();
439
  if (!_transactListReconfig.empty()) _transactListReconfig.clear();
Le Van Truong's avatar
Le Van Truong committed
440
441
442
443
  _nextTransaction=0;
  _lastTransaction=0;
  _masterNextTransaction=0;
  _busyCycles=0;
Le Van Truong's avatar
Le Van Truong committed
444
  _maxEndTime = 0;
Le Van Truong's avatar
Le Van Truong committed
445
  maxScale = 0;
Le Van Truong's avatar
Le Van Truong committed
446
447
448
  for(TaskList::const_iterator i = _taskList.begin(); i!= _taskList.end(); ++i){
    (*i)->setIsFirstTranExecuted(false);
  }
Le Van Truong's avatar
Le Van Truong committed
449
450
}

Siyuan Niu's avatar
Siyuan Niu committed
451
452
453
454
455
456
457
458
459
void FPGA::schedule2TXT(std::ofstream& myfile) const{
  myfile << "========= Scheduling for device: "<< _name << " =========\n" ;
  for(TransactionList::const_iterator i=_transactList.begin(); i != _transactList.end(); ++i){
   std::cout<<"my transaction================================="<<std::endl;
    myfile << (*i)->toShortString() << std::endl;
  }
  std::cout<<"txt end========================"<<std::endl;
}

460
461
462
463
464
465
466
467
void FPGA::schedule2XML(std::ostringstream& glob,std::ofstream& myfile) const{
  for(TransactionList::const_iterator i=_transactList.begin(); i != _transactList.end(); ++i){
      (*i)->toXML(glob, 0, _name, _ID);
   //   myfile << glob.str() << std::endl;

  }
}

Siyuan Niu's avatar
Siyuan Niu committed
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
BusMaster* FPGA::getMasterForBus(BusMaster* iDummy){
  if (iDummy!=0){
    SchedulableCommDevice* aBus = iDummy->getBus();
    for(BusMasterList::iterator i=_busMasterList.begin(); i != _busMasterList.end(); ++i){
      if ((*i)->getBus()==aBus) return *i;
    }
    std::cout << "cry!!!!!!!!!!!!! no bus master found\n";
    exit(1);
  }
  return 0;
}

int FPGA::allTrans2XML(std::ostringstream& glob, int maxNbOfTrans) const {
  int size = _transactList.size();
  int begining = size - maxNbOfTrans;
  if (begining <0) {
    begining = 0;
  }
  int cpt =0;
  int total = 0;
  for(TransactionList::const_iterator i=_transactList.begin(); i != _transactList.end(); ++i){
    if (cpt >= begining) {
apvrille's avatar
apvrille committed
490
      (*i)->toXML(glob, 0, _name, _ID);
Siyuan Niu's avatar
Siyuan Niu committed
491
492
493
494
495
496
497
      total ++;
    }
    cpt ++;
  }
  return total;
}

498
499
500
501
502
503
504
505
int FPGA::allTrans2XMLByTask(std::ostringstream& glob, std::string taskName) const {
  int total = 0;
  for(TransactionList::const_iterator i=_transactList.begin(); i != _transactList.end(); ++i){
      (*i)->toXMLByTask(glob, 0, _name, _ID, taskName);
      total ++;
  }
  return total;
}
Siyuan Niu's avatar
Siyuan Niu committed
506

Le Van Truong's avatar
Le Van Truong committed
507
508
void FPGA::removeTrans(int numberOfTrans) {
    if (numberOfTrans == 1) {
509
510
511
512
        _transactList.clear();
    }
}

Siyuan Niu's avatar
Siyuan Niu committed
513
514
515
516
void FPGA::latencies2XML(std::ostringstream& glob, unsigned int id1, unsigned int id2) {
  for(TransactionList::const_iterator i=_transactList.begin(); i != _transactList.end(); ++i){
    if ((*i)->getCommand() !=NULL){
      if ((*i)->getCommand()->getID() == id1 || (*i)->getCommand()->getID() == id2){
apvrille's avatar
apvrille committed
517
        (*i)->toXML(glob, 0, _name, _ID);
Siyuan Niu's avatar
Siyuan Niu committed
518
519
520
521
522
523
      }
    }
  }

  return;
}
Siyuan Niu's avatar
Siyuan Niu committed
524

Siyuan Niu's avatar
Siyuan Niu committed
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

double FPGA::averageLoad (TMLTask* currTask) const{
  double _averageLoad=0;
  TMLTime _maxEndTime=0;
  for( TransactionList::const_iterator i = _transactList.begin(); i != _transactList.end(); ++i ) {
    if( (*i)-> getCommand()->getTask() == currTask ){
      TMLTime _endTime= (*i)->getEndTime();
      _maxEndTime=max(_maxEndTime,_endTime);
    }
  }
  for( TransactionList::const_iterator i = _transactList.begin(); i != _transactList.end(); ++i ) {
     if( (*i)-> getCommand()->getTask() == currTask ){
      _averageLoad += (*i)->getEndTime() - (*i)->getStartTime();
    }
  }
  if(_maxEndTime == 0)
    return 0;
  else {
    _averageLoad = (double)_averageLoad/_maxEndTime;
    return _averageLoad;
  }
  /*if( _maxEndTime == 0 ) 
    myfile << "average load is 0" << "<br>";
  else
  myfile<<" average load is "<<(double)_averageLoad/_maxEndTime<<"<br>";*/
 
}


Siyuan Niu's avatar
Siyuan Niu committed
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
void FPGA::drawPieChart(std::ofstream& myfile) const {      
  TMLTime _maxEndTime=0;

  for( TransactionList::const_iterator i = _transactList.begin(); i != _transactList.end(); ++i ) {
    if( (*i)-> getCommand()->getTask() ==  _htmlCurrTask ){
      TMLTime _endTime= (*i)->getEndTime();
      _maxEndTime=max(_maxEndTime,_endTime);
    }
  }
  std::map <TMLTask*, double > transPercentage;
  for( TransactionList::const_iterator i = _transactList.begin(); i!= _transactList.end(); ++i){
    if( (*i)-> getCommand()->getTask() ==  _htmlCurrTask ){
      transPercentage[(*i)-> getCommand()->getTask()]+=(double)((*i)->getEndTime()-(*i)->getStartTime())/_maxEndTime;      
    }
  }
  std::map <TMLTask*, double>::iterator iter = transPercentage.begin();
  myfile << "   var ctx" << _ID << "_"  << _htmlCurrTask->toShortString() << "= $(\"#pie-chartcanvas-" << _ID << "_" << _htmlCurrTask->toShortString() << "\");\n";
    
  double idle=1;
Siyuan Niu's avatar
html ok    
Siyuan Niu committed
573
  myfile << "   var data" << _ID << "_" << _htmlCurrTask->toShortString() << " = new Array (";
Siyuan Niu's avatar
Siyuan Niu committed
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
  while( iter != transPercentage.end()){
    myfile << "\"" << iter->second << "\",";
    idle-=iter->second;
    ++iter;
  }
  myfile << "\"" << idle << "\");\n";
    
  myfile << "    var efficiency" << _ID << "_" << _htmlCurrTask->toShortString() << " = [];" << std::endl;
  myfile << "    var coloR" << _ID << "_" << _htmlCurrTask->toShortString() << " = [];" << std::endl;
  myfile << "    var dynamicColors" << _ID << "_" << _htmlCurrTask->toShortString() << SCHED_HTML_JS_FUNCTION;
    
  myfile << "    for (var i in data" << _ID << "_" << _htmlCurrTask->toShortString() << "){\n";
  myfile << "             efficiency" << _ID << "_" << _htmlCurrTask->toShortString() << ".push(data" << _ID << "_" << _htmlCurrTask->toShortString() << "[i]);\n";
  myfile << "             coloR" << _ID << "_" << _htmlCurrTask->toShortString() << ".push(dynamicColors" << _ID << "_" << _htmlCurrTask->toShortString() << "());\n";
  myfile << "}" << std::endl;
    
  myfile << "   var data" << _ID << "_" << _htmlCurrTask->toShortString() << " = { \n";
  myfile << "           labels : [";
  iter = transPercentage.begin();
  while( iter != transPercentage.end()){
    myfile << " \"" << iter->first->toString() << "\",";
    idle-=iter->second;
    ++iter;
  }        
  myfile << "\"idle time\"],\n";
  myfile << "          datasets : [\n \
                                     {\n \
                                           data : efficiency" << _ID << "_" << _htmlCurrTask->toShortString() << ",\n";
  myfile << "                            backgroundColor : coloR" << _ID << "_" << _htmlCurrTask->toShortString() << std::endl;
Siyuan Niu's avatar
html ok    
Siyuan Niu committed
603
604
605
  // myfile << SCHED_HTML_JS_CONTENT1 << "Average load is " << averageLoad(_htmlCurrTask) << SCHED_HTML_JS_CONTENT2 << std::endl; 
  myfile << SCHED_HTML_JS_CONTENT1;
  myfile << "  var options" << _ID << "_" << _htmlCurrTask->toShortString() << SCHED_HTML_JS_CONTENT3;
Siyuan Niu's avatar
Siyuan Niu committed
606
  myfile << _name << "_" << _htmlCurrTask->toShortString() << ": Average load is " << std::setprecision(2) << averageLoad(_htmlCurrTask) << SCHED_HTML_JS_CONTENT2 << std::endl; 
Siyuan Niu's avatar
Siyuan Niu committed
607
     
Siyuan Niu's avatar
Siyuan Niu committed
608
609
}

Siyuan Niu's avatar
Siyuan Niu committed
610
void FPGA::buttonPieChart(std::ofstream& myfile) const{
Siyuan Niu's avatar
html ok    
Siyuan Niu committed
611
  //  myfile << "$(\"#" << _ID << "\").click(function() {\n";
Siyuan Niu's avatar
Siyuan Niu committed
612
613
614
615
616
  for(TaskList::const_iterator i = _taskList.begin(); i!= _taskList.end(); ++i){ 
    myfile << "    var chart" << _ID << "_" << (*i)->toShortString() << " = new Chart( "<<
      "ctx" << _ID << "_" << (*i)->toShortString() << ", {\n \
              type : \"pie\",\n";
    myfile << "               data : data" << _ID << "_" << (*i)->toShortString() <<",\n";
Siyuan Niu's avatar
html ok    
Siyuan Niu committed
617
618
    myfile << "               options : options" << _ID << "_" << (*i)->toShortString() << std::endl;
    myfile << "                   });" << std::endl;
619
620
621
622
623
624
625
    // myfile << "   chart" << _ID << "_" << (*i)->toShortString() << SCHED_HTML_JS_HIDE;
    myfile << "   if(!" << SHOW_PIE_CHART << "){\n \t"
        << "      document.getElementById(\"pie-chartcanvas-" << _ID << "_" << (*i)->toShortString() << "\"" << ").style.display = \"none\";\n \t"
        << "   }\n \t"
        << "   else {\n \t"
        << "      document.getElementById(\"pie-chartcanvas-" << _ID << "_" << (*i)->toShortString() << "\"" << ").style.display = \"block\";\n \t"
        << "   }\n \t";
Siyuan Niu's avatar
Siyuan Niu committed
626
    myfile << "   chart" << _ID << "_" << (*i)->toShortString() << ".update();" << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
627
628
629
630
  
  }
}

Siyuan Niu's avatar
Siyuan Niu committed
631
632

void FPGA::showPieChart(std::ofstream& myfile) const{
Siyuan Niu's avatar
html ok    
Siyuan Niu committed
633
  myfile << SCHED_HTML_JS_DIV_BEGIN2 << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
634
635
  myfile << SCHED_HTML_JS_BEGIN_CANVAS << _ID << "_" << _htmlCurrTask->toShortString() << SCHED_HTML_JS_END_CANVAS <<std::endl;
  myfile << SCHED_HTML_JS_DIV_END << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
636
637
}

Siyuan Niu's avatar
Siyuan Niu committed
638
639
640
641
642
643
644
645
646
647
648
649
650
651
std::string FPGA::determineHTMLCellClass(unsigned int &nextColor ) {
	std::map<TMLTask*, std::string>::const_iterator it = taskCellClasses.find( _htmlCurrTask );

	if ( it == taskCellClasses.end() ) {
		unsigned int aColor = nextColor % NB_HTML_COLORS;
		std::ostringstream cellClass;
		cellClass << "t" << aColor;
		taskCellClasses[  _htmlCurrTask ] = cellClass.str();
		nextColor++;
	}

	return taskCellClasses[  _htmlCurrTask ];
}

652
653
654
655
656
657
658
659
660
661
662
663
664
665
std::string FPGA::determineHTMLCellClass(std::map<TMLTask*, std::string> &taskColors, TMLTask* task, unsigned int &nextColor) {
	std::map<TMLTask*, std::string>::const_iterator it = taskColors.find( task );

	if ( it == taskColors.end() ) {
		unsigned int aColor = nextColor % NB_HTML_COLORS;
		std::ostringstream cellClass;
		cellClass << "t" << aColor;
		taskColors[ task ] = cellClass.str();
		nextColor++;
	}

	return taskColors[ task ];
}

666
std::map<TMLTask*, std::string> FPGA::HWTIMELINE2HTML(std::ostringstream& myfile,std::map<TMLTask*, std::string> taskCellClasses1,unsigned int nextCellClassIndex1, std::string& iTracetaskList, bool isScalable, double start, double end) {
667
668
    TransactionList _transactListClone;
    std::string taskList = iTracetaskList.c_str();
669
    maxScale = 0;
670
671
672
    for (int z = 0; z < _transactList.size(); z++) {
        std::string taskName = _transactList[z]->getCommand()->getTask()->toString();
        std::size_t pos = taskList.find(taskName); /*pos1 = position of "bin" if we working with open model*/
673
        if(pos != std::string::npos && start <= (double)_transactList[z]->getStartTime() && (double)_transactList[z]->getEndTime() <= end){
674
675
676
677
678
679
680
            _transactListClone.push_back(_transactList[z]);
        }
    }
    if ( _transactListClone.size() == 0 ) {
        std::cout << "Device never activated" << std::endl;
    } else {
        if(_startFlagHTML == true){
681
            myfile << "<tr><td title = \"Average load: " << std::setprecision(2) << averageLoad(_htmlCurrTask) << "; Utilization: " << (static_cast<float>(_busyCycles)/static_cast<float>(_simulatedTime)) << "\" width=\"170px\" style=\"max-width: unset;min-width: 170px;background-color: aqua;\">" <<  _name << "</td><td class=\"notfirst\"></td><td class=\"notlast\"></td>";
Le Van Truong's avatar
Le Van Truong committed
682
        } else if (_htmlCurrTask->getEndLastTransaction() > 0) {
683
            myfile << "<tr><td title = \"Average load: " << std::setprecision(2) << averageLoad(_htmlCurrTask) << "; Utilization: " << (static_cast<float>(_busyCycles)/static_cast<float>(_simulatedTime)) << "\" width=\"170px\" style=\"max-width: unset;min-width: 170px;border-style: none none none none;\"></td><td class=\"notfirst\"></td><td class=\"notlast\"></td>";
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
        }
        TMLTime aCurrTime = 0;
        unsigned int taskOccurTime = 0;
        unsigned int tempReduce = 0;
        std::vector<unsigned int> listScale;
        std::vector<unsigned int> listScaleTime;
        listScale.push_back(0);
        listScaleTime.push_back(0);
        bool changeCssClass = false;
        for( TransactionList::const_iterator i = _transactListClone.begin(); i != _transactListClone.end(); ++i ) {
        #ifdef DEBUG_FPGA
          std::cout <<  (*i)-> getCommand()->getTask()->toString() <<std::endl;
          std::cout<< _htmlCurrTask->toString()<<std::endl;
        #endif
          if( (*i)-> getCommand()->getTask() == _htmlCurrTask ){
        if(taskOccurTime==0){
          taskOccurTime++;
        }
        #ifdef DEBUG_FPGA
        std::cout<<"in!!"<<_htmlCurrTask->toString()<<std::endl;
        #endif
        TMLTransaction* aCurrTrans = *i;
706
707
708
709
710
711
712
713
        bool reconfigCheck = false;
        if (!_transactListReconfig.empty()) {
            std::vector<TMLTransaction*>::iterator it = std::find (_transactListReconfig.begin(), _transactListReconfig.end(), aCurrTrans);
                if (it != _transactListReconfig.end()) {
                    reconfigCheck = true;
                }
        }

714
715
        unsigned int aBlanks = aCurrTrans->getStartTime() - aCurrTime;
        bool isBlankTooBig = false;
716
        std::ostringstream tempString, tempReconfigIdle;
717
        int tempBlanks;
718
        if(isScalable && _htmlCurrTask->getEndLastTransaction() >= MIN_RESIZE_THRESHOLD && aBlanks > MIN_RESIZE_TRANS) {
Le Van Truong's avatar
Le Van Truong committed
719
720
721
722
723
724
725
726
            int newBlanks = 0;
            if (aBlanks > 100000) {
                newBlanks = (int) aBlanks/100;
            } else if (aBlanks > 250) {
                newBlanks = (int) aBlanks/20;
            } else {
                newBlanks = 10;
            }
727
728
729
730
731
732
            tempBlanks = aBlanks;
            tempReduce += aBlanks - newBlanks;
            aBlanks = newBlanks;
            isBlankTooBig = true;
            changeCssClass = true;
        }
733
        if (reconfigCheck) {
734
            tempReconfigIdle << "dynamic reconfiguration";
735
        } else {
736
            tempReconfigIdle << " ";
737
        }
738
739
740
741
742
743
744
        if ( aBlanks >= 0 && (!(aCurrTrans->getCommand()->getActiveDelay()) && aCurrTrans->getCommand()->isDelayTransaction()) ){
            listScale.push_back(aBlanks+1);
            tempString << tempBlanks+1;
            if(aCurrTrans->getStartTime()+1 > listScaleTime.back()){
                listScaleTime.push_back(aCurrTrans->getStartTime()+1);
            }
            if (isBlankTooBig){
745
                myfile << "<td colspan=\""<< aBlanks+1 <<"\" title=\"idle time " + tempReconfigIdle.str() + "\" class=\"not\">" << "<- idle " + tempString.str() + " ->" << "</td>";
746
            } else {
747
                myfile << "<td colspan=\""<< aBlanks+1 <<"\" title=\"idle time " + tempReconfigIdle.str() + "\" class=\"not\"></td>";
748
            }
749
        } else if ( aBlanks > 0 ){
750
751
752
753
754
755
            listScale.push_back(aBlanks);
            tempString << tempBlanks;
            if(aCurrTrans->getStartTime() > listScaleTime.back()){
                listScaleTime.push_back(aCurrTrans->getStartTime());
            }
            if (isBlankTooBig){
756
                myfile << "<td colspan=\""<< aBlanks <<"\" title=\"idle time " + tempReconfigIdle.str() + "\" class=\"not\">" << "<- idle " + tempString.str() + " ->" << "</td>";
757
            } else {
758
                myfile << "<td colspan=\""<< aBlanks <<"\" title=\"idle time " + tempReconfigIdle.str() + "\" class=\"not\"></td>";
759
760
761
762
763
764
765
            }
        }

        unsigned int aLength = aCurrTrans->getOperationLength();
        const std::string cellClass = determineHTMLCellClass( taskCellClasses1, _htmlCurrTask, nextCellClassIndex1);
        std::string aCurrTransName=aCurrTrans->toShortString();
        unsigned int indexTrans=aCurrTransName.find_first_of(":");
766
767
768
769
770
771
772
773
774
775
	std::string aNextCont = aCurrTransName.substr(indexTrans+2,3);
	std::string aCurrContent;
	std::string a = "a";
	//std::cout << "aNextCont:" << aNextCont<< ": " << a << std::endl;
	if (aNextCont[1] == a[0]) {
	  aCurrContent=aCurrTransName.substr(indexTrans+1,3);
	} else {
	  aCurrContent=aCurrTransName.substr(indexTrans+1,2);
	}
        
776
        if(!(!(aCurrTrans->getCommand()->getActiveDelay()) && aCurrTrans->getCommand()->isDelayTransaction())){
777
          if(isScalable && _htmlCurrTask->getEndLastTransaction() >= MIN_RESIZE_THRESHOLD && aLength > MIN_RESIZE_TRANS){
Le Van Truong's avatar
Le Van Truong committed
778
779
780
781
782
783
784
785
786
787
              int tempLength = 0;
              if (aLength > 100000) {
                  tempLength = (int) aLength/100;
              } else if (aLength > 250) {
                  tempLength = (int) aLength/20;
              } else {
                  tempLength = 10;
              }
              tempReduce += aLength - tempLength;
              aLength = tempLength;
788
          }
Le Van Truong's avatar
Le Van Truong committed
789
790
791
792
793
          std::string aCurrFullTransName = aCurrTrans->toString();
          unsigned int indexTrans1 = aCurrFullTransName.find("len:");
          unsigned int indexTrans2 = aCurrFullTransName.find("params");
          std::string transName = aCurrTransName.substr(0, indexTrans + 1) + " " + aCurrFullTransName.substr(0, indexTrans1) + " --Attributes " + aCurrFullTransName.substr(indexTrans2, aCurrFullTransName.length());
          myfile << "<td colspan=\"" << aLength << "\" title=\"" << transName << "\" class=\""<< cellClass <<"\">"<< aCurrContent <<"</td>";
794
//          writeHTMLColumn( myfile, aLength, cellClass, aCurrTrans->toShortString(), aCurrContent );
795
796
797
798
799
800
801
802
803
804
805
806
807
808
          listScale.push_back(aLength);
          if(aCurrTrans->getStartTime() > listScaleTime.back()){
             listScaleTime.push_back(aCurrTrans->getStartTime());
          }
          if(aCurrTrans->getEndTime() > listScaleTime.back()){
             listScaleTime.push_back(aCurrTrans->getEndTime());
          }
        }
        if(aCurrTrans->getCommand()->getTask()->getIsDaemon() == true && aCurrTrans->getEndTime() > _simulatedTime)
          aCurrTime = _simulatedTime;
        else
          aCurrTime = aCurrTrans->getEndTime();
          }
        }
Le Van Truong's avatar
Le Van Truong committed
809
        if(listScale.size() > 1) {
810
811
                    myfile << "</tr>" << "<tr>";
                    myfile << "<td width=\"170px\" style=\"max-width: unset;min-width: 170px;border-style: none none none none;\"></td><td class=\"notfirst\"></td><td class=\"notlast\"></td>";
Le Van Truong's avatar
Le Van Truong committed
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835

                    for ( unsigned int aLength = 0; aLength < listScale.size(); aLength += 1 ) {
                      std::ostringstream spanVal;
                      if(aLength < listScaleTime.size())
                        spanVal << listScaleTime[aLength];
                      else
                        spanVal << "";
                      if(aLength+1 >= listScale.size()){

                        if(changeCssClass){
                             myfile << "<td colspan=\"5\" class=\"sc1\">" << spanVal.str() << "</td>";
            //                 writeHTMLColumn( myfile, 5, "sc1",  spanVal.str(), spanVal.str(), false );
                        } else
                             myfile << "<td colspan=\"5\" class=\"sc\">" << spanVal.str() << "</td>";
            //                 writeHTMLColumn( myfile, 5, "sc", spanVal.str(), spanVal.str(), false );
                      } else {
                            if(changeCssClass){
                                myfile << "<td colspan=\"" << listScale[aLength+1] << "\" class=\"sc1\">" << spanVal.str() << "</td>";
            //                    writeHTMLColumn( myfile, listScale[aLength+1], "sc1", spanVal.str(), spanVal.str(), false );
                            } else
                                myfile << "<td colspan=\"" << listScale[aLength+1] << "\" class=\"sc\">" << spanVal.str() << "</td>";
            //                     writeHTMLColumn( myfile, listScale[aLength+1], "sc", spanVal.str(), spanVal.str(), false );
                      }
                    }
836
                    myfile << "</tr>" << "<tr>";
Le Van Truong's avatar
Le Van Truong committed
837

838
                    for ( unsigned int aLength = 0; aLength < 3; aLength++ ) {
Le Van Truong's avatar
Le Van Truong committed
839
840
841
842
843
844
                        if( aLength == 1) {
                          myfile << "<th class=\"notfirst\">";
                        } else {
                          myfile << "<th></th>";
                        }
                    }
845
846
847
848
                    if (aCurrTime - tempReduce + 2 > maxScale) {
                        maxScale = aCurrTime - tempReduce + 2;
                    }
                    myfile << "</tr>";
Le Van Truong's avatar
Le Van Truong committed
849
                    myfile << SCHED_HTML_JS_CLEAR << std::endl;
850
        }
Le Van Truong's avatar
Le Van Truong committed
851

852
853
854
855
    }
    return taskCellClasses1;
}

Siyuan Niu's avatar
Siyuan Niu committed
856
void FPGA::HW2HTML(std::ofstream& myfile)  {    
Siyuan Niu's avatar
Siyuan Niu committed
857
  if(_startFlagHTML == true){
Siyuan Niu's avatar
html ok    
Siyuan Niu committed
858
    //myfile << "<h2><span>Scheduling for device: "<< _name << "</span></h2>" << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
859
    myfile << SCHED_HTML_BOARD;
Siyuan Niu's avatar
html ok    
Siyuan Niu committed
860
    myfile << _name << END_TD << "</tr>" << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
861
    myfile << SCHED_HTML_JS_TABLE_END << std::endl;
Siyuan Niu's avatar
html ok    
Siyuan Niu committed
862
    myfile << SCHED_HTML_JS_DIV_BEGIN3  << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
863
  }
Siyuan Niu's avatar
Siyuan Niu committed
864
865
866

  if ( _transactList.size() == 0 ) {
    myfile << "<h4>Device never activated</h4>" << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
867
    myfile << SCHED_HTML_JS_TABLE_END << std::endl << SCHED_HTML_JS_CLEAR << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
868
869
  }
   else {
Siyuan Niu's avatar
html ok    
Siyuan Niu committed
870
     myfile << "<table>" << std::endl << "<tr>";
Siyuan Niu's avatar
Siyuan Niu committed
871
    TMLTime aCurrTime = 0;
Siyuan Niu's avatar
Siyuan Niu committed
872
    unsigned int taskOccurTime = 0;
873
874
875
876
877
    unsigned int tempReduce = 0;
    std::vector<unsigned int> listScale;
    std::vector<unsigned int> listScaleTime;
    listScale.push_back(0);
    listScaleTime.push_back(0);
878
    bool changeCssClass = false;
Siyuan Niu's avatar
Siyuan Niu committed
879
    for( TransactionList::const_iterator i = _transactList.begin(); i != _transactList.end(); ++i ) {
Siyuan Niu's avatar
Siyuan Niu committed
880
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
881
882
      std::cout <<  (*i)-> getCommand()->getTask()->toString() <<std::endl;
      std::cout<< _htmlCurrTask->toString()<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
883
#endif
Siyuan Niu's avatar
Siyuan Niu committed
884
      if( (*i)-> getCommand()->getTask() == _htmlCurrTask ){
Siyuan Niu's avatar
Siyuan Niu committed
885
	if(taskOccurTime==0){ 
Siyuan Niu's avatar
Siyuan Niu committed
886
887
	  taskOccurTime++;
	}
Siyuan Niu's avatar
Siyuan Niu committed
888
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
889
	std::cout<<"in!!"<<_htmlCurrTask->toString()<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
890
#endif
Siyuan Niu's avatar
Siyuan Niu committed
891
892
	TMLTransaction* aCurrTrans = *i;
	unsigned int aBlanks = aCurrTrans->getStartTime() - aCurrTime;
893
894
895
	bool isBlankTooBig = false;
	std::ostringstream tempString;
	int tempBlanks;
896
897
	if(_htmlCurrTask->getEndLastTransaction() >= 250 && aBlanks >10) {
	    int newBlanks = 10;
898
899
900
901
	    tempBlanks = aBlanks;
	    tempReduce += aBlanks - newBlanks;
	    aBlanks = newBlanks;
	    isBlankTooBig = true;
902
	    changeCssClass = true;
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
	}
	if ( aBlanks >= 0 && (!(aCurrTrans->getCommand()->getActiveDelay()) && aCurrTrans->getCommand()->isDelayTransaction()) ){
	    listScale.push_back(aBlanks+1);
	    tempString << tempBlanks+1;
	    if(aCurrTrans->getStartTime()+1 > listScaleTime.back()){
            listScaleTime.push_back(aCurrTrans->getStartTime()+1);
        }
	    if (isBlankTooBig){
	        writeHTMLColumn( myfile, aBlanks+1, "not", "idle time", "<- idle " + tempString.str() + " ->", false );
	    } else {
	        writeHTMLColumn( myfile, aBlanks+1, "not", "idle time" );
	    }
	}
	else if ( aBlanks > 0 ){
	    listScale.push_back(aBlanks);
	    tempString << tempBlanks;
	    if(aCurrTrans->getStartTime() > listScaleTime.back()){
            listScaleTime.push_back(aCurrTrans->getStartTime());
        }
	    if (isBlankTooBig){
            writeHTMLColumn( myfile, aBlanks, "not", "idle time", "<- idle " + tempString.str() + " ->", false );
        } else {
            writeHTMLColumn( myfile, aBlanks, "not", "idle time" );
        }
	}
Siyuan Niu's avatar
Siyuan Niu committed
928
929
930
931
932

	unsigned int aLength = aCurrTrans->getOperationLength();


	// Issue #4
Siyuan Niu's avatar
Siyuan Niu committed
933
	//	std::cout<<"what is this task?"<<task->toString()<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
934
	const std::string cellClass = determineHTMLCellClass(  nextCellClassIndex );
Siyuan Niu's avatar
Siyuan Niu committed
935
936
937
	std::string aCurrTransName=aCurrTrans->toShortString();
	unsigned int indexTrans=aCurrTransName.find_first_of(":");
	std::string aCurrContent=aCurrTransName.substr(indexTrans+1,2);
Le Van Truong's avatar
Le Van Truong committed
938
	if(!(!(aCurrTrans->getCommand()->getActiveDelay()) && aCurrTrans->getCommand()->isDelayTransaction())){
939
940
941
942
      if(_htmlCurrTask->getEndLastTransaction() >= 250 && aLength >10){
          tempReduce += aLength - 10;
          aLength = 10;
      }
Le Van Truong's avatar
Le Van Truong committed
943
      writeHTMLColumn( myfile, aLength, cellClass, aCurrTrans->toShortString(), aCurrContent );
944
945
946
947
948
949
950
      listScale.push_back(aLength);
      if(aCurrTrans->getStartTime() > listScaleTime.back()){
         listScaleTime.push_back(aCurrTrans->getStartTime());
      }
      if(aCurrTrans->getEndTime() > listScaleTime.back()){
         listScaleTime.push_back(aCurrTrans->getEndTime());
      }
Le Van Truong's avatar
Le Van Truong committed
951
    }
Siyuan Niu's avatar
Siyuan Niu committed
952
953
954
955
	if(aCurrTrans->getCommand()->getTask()->getIsDaemon() == true && aCurrTrans->getEndTime() > _simulatedTime)
	  aCurrTime = _simulatedTime;
	else
	  aCurrTime = aCurrTrans->getEndTime();
Siyuan Niu's avatar
Siyuan Niu committed
956
      }
957
    }
Siyuan Niu's avatar
Siyuan Niu committed
958
959

    myfile << "</tr>" << std::endl << "<tr>";
960
    for ( unsigned int aLength = 0; aLength < aCurrTime - tempReduce; aLength++ ) {
Siyuan Niu's avatar
Siyuan Niu committed
961
962
963
964
      myfile << "<th></th>";
    }

    myfile << "</tr>" << std::endl << "<tr>";
965
    for ( unsigned int aLength = 0; aLength < listScale.size(); aLength += 1 ) {
Siyuan Niu's avatar
Siyuan Niu committed
966
      std::ostringstream spanVal;
967
968
969
970
971
      if(aLength < listScaleTime.size())
        spanVal << listScaleTime[aLength];
      else
        spanVal << "";
      if(aLength+1 >= listScale.size()){
972
973
974
975
976

        if(changeCssClass){
             writeHTMLColumn( myfile, 5, "sc1",  spanVal.str(), spanVal.str(), false );
        } else
             writeHTMLColumn( myfile, 5, "sc", spanVal.str(), spanVal.str(), false );
977
      }else {
978
979
980
981
        if(changeCssClass){
            writeHTMLColumn( myfile, listScale[aLength+1], "sc1", spanVal.str(), spanVal.str(), false );
        } else
             writeHTMLColumn( myfile, listScale[aLength+1], "sc", spanVal.str(), spanVal.str(), false );
982
      }
Siyuan Niu's avatar
Siyuan Niu committed
983
984
      //myfile << "<td colspan=\"5\" class=\"sc\">" << aLength << "</td>";
    }
Siyuan Niu's avatar
Siyuan Niu committed
985
986
   }
}
Siyuan Niu's avatar
Siyuan Niu committed
987

Siyuan Niu's avatar
Siyuan Niu committed
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
void FPGA::schedule2HTML(std::ofstream& myfile)  {    
  std::cout<<"*********FPGA scheduling***********"<<std::endl;
  if(_startFlagHTML == true){
    myfile << "<h2><span>Scheduling for device: "<< _name << "</span></h2>" << std::endl;
  }

  if ( _transactList.size() == 0 ) {
    myfile << "<h4>Device never activated</h4>" << std::endl;
  }
   else {
    myfile << "<table>" << std::endl << "<tr>";

    TMLTime aCurrTime = 0;
    unsigned int taskOccurTime = 0;
1002
1003
1004
1005
1006
    unsigned int tempReduce = 0;
    std::vector<unsigned int> listScale;
    std::vector<unsigned int> listScaleTime;
    listScale.push_back(0);
    listScaleTime.push_back(0);
1007
    bool changeCssClass = false;
Siyuan Niu's avatar
Siyuan Niu committed
1008
1009
1010
1011
1012
1013
1014
1015
1016
    for( TransactionList::const_iterator i = _transactList.begin(); i != _transactList.end(); ++i ) {
      //#ifdef DEBUG_FPGA
      std::cout <<  (*i)-> getCommand()->getTask()->toString() <<std::endl;
      std::cout<< _htmlCurrTask->toString()<<std::endl;
      //#endif
      if( (*i)-> getCommand()->getTask() == _htmlCurrTask ){
	if(taskOccurTime==0){
	  taskOccurTime++;
	}
1017
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
1018
	std::cout<<"in!!"<<_htmlCurrTask->toString()<<std::endl;
1019
#endif
Siyuan Niu's avatar
Siyuan Niu committed
1020
1021
1022
	TMLTransaction* aCurrTrans = *i;
	unsigned int aBlanks = aCurrTrans->getStartTime() - aCurrTime;
	//std::cout<<"blank is "<<aBlanks<<std::endl;
1023
1024
1025
    bool isBlankTooBig = false;
    std::ostringstream tempString;
    int tempBlanks;
1026
1027
    if(_htmlCurrTask->getEndLastTransaction() >= 250 && aBlanks >10) {
        int newBlanks = 10;
1028
1029
1030
1031
        tempBlanks = aBlanks;
        tempReduce += aBlanks - newBlanks;
        aBlanks = newBlanks;
        isBlankTooBig = true;
1032
        changeCssClass = true;
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
    }

	if ( aBlanks >= 0 && (!(aCurrTrans->getCommand()->getActiveDelay()) && aCurrTrans->getCommand()->isDelayTransaction()) ){
	    listScale.push_back(aBlanks+1);
	    tempString << tempBlanks+1;
	    if(aCurrTrans->getStartTime()+1 > listScaleTime.back()){
            listScaleTime.push_back(aCurrTrans->getStartTime()+1);
        }
	    if (isBlankTooBig){
	        writeHTMLColumn( myfile, aBlanks+1, "not", "idle time", "<- idle " + tempString.str() + " ->", false );
	    } else {
	        writeHTMLColumn( myfile, aBlanks+1, "not", "idle time" );
	    }
	}
	else if ( aBlanks > 0 ){
	    listScale.push_back(aBlanks);
	    tempString << tempBlanks;
	    if(aCurrTrans->getStartTime() > listScaleTime.back()){
            listScaleTime.push_back(aCurrTrans->getStartTime());
        }
	    if (isBlankTooBig){
            writeHTMLColumn( myfile, aBlanks, "not", "idle time", "<- idle " + tempString.str() + " ->", false );
        } else {
            writeHTMLColumn( myfile, aBlanks, "not", "idle time" );
        }
	}
Siyuan Niu's avatar
Siyuan Niu committed
1059
1060
1061
1062
1063
1064
1065
1066

	unsigned int aLength = aCurrTrans->getOperationLength();


	// Issue #4
	TMLTask* task = aCurrTrans->getCommand()->getTask();
	//	std::cout<<"what is this task?"<<task->toString()<<std::endl;
	const std::string cellClass = determineHTMLCellClass(  nextCellClassIndex );
Le Van Truong's avatar
Le Van Truong committed
1067
    if(!(!(aCurrTrans->getCommand()->getActiveDelay()) && aCurrTrans->getCommand()->isDelayTransaction())){
1068
1069
1070
1071
      if(_htmlCurrTask->getEndLastTransaction() >= 250 && aLength >10){
          tempReduce += aLength - 10;
          aLength = 10;
      }
Le Van Truong's avatar
Le Van Truong committed
1072
      writeHTMLColumn( myfile, aLength, cellClass, aCurrTrans->toShortString() );
1073
1074
1075
1076
1077
1078
1079
      listScale.push_back(aLength);
      if(aCurrTrans->getStartTime() > listScaleTime.back()){
         listScaleTime.push_back(aCurrTrans->getStartTime());
      }
      if(aCurrTrans->getEndTime() > listScaleTime.back()){
        listScaleTime.push_back(aCurrTrans->getEndTime());
      }
Le Van Truong's avatar
Le Van Truong committed
1080
    }
Siyuan Niu's avatar
Siyuan Niu committed
1081

Siyuan Niu's avatar
Siyuan Niu committed
1082
1083
1084
1085
	if(aCurrTrans->getCommand()->getTask()->getIsDaemon() == true && aCurrTrans->getEndTime() > _simulatedTime)
	  aCurrTime = _simulatedTime;
	else
	  aCurrTime = aCurrTrans->getEndTime();
Siyuan Niu's avatar
Siyuan Niu committed
1086
1087
      }
    }
Siyuan Niu's avatar
Siyuan Niu committed
1088
1089
1090
		

    myfile << "</tr>" << std::endl << "<tr>";
1091

1092
    for ( unsigned int aLength = 0; aLength < aCurrTime - tempReduce; aLength++ ) {
Siyuan Niu's avatar
Siyuan Niu committed
1093
1094
1095
1096
      myfile << "<th></th>";
    }

    myfile << "</tr>" << std::endl << "<tr>";
1097
    for ( unsigned int aLength = 0; aLength < listScale.size(); aLength += 1 ) {
Siyuan Niu's avatar
Siyuan Niu committed
1098
      std::ostringstream spanVal;
1099
1100
1101
1102
1103
      if(aLength < listScaleTime.size())
        spanVal << listScaleTime[aLength];
      else
        spanVal << "";
      if(aLength+1 >= listScale.size()){
1104
1105
1106
1107
1108

        if(changeCssClass){
            writeHTMLColumn( myfile, 5, "sc1",  spanVal.str(), spanVal.str(), false );
        } else
         writeHTMLColumn( myfile, 5, "sc", spanVal.str(), spanVal.str(), false );
1109
      }else {
1110
1111
1112
1113
1114
        if(changeCssClass){
            writeHTMLColumn( myfile, listScale[aLength+1], "sc1", spanVal.str(), spanVal.str(), false );
        } else
           writeHTMLColumn( myfile, listScale[aLength+1], "sc", spanVal.str(), spanVal.str(), false );
        }
Siyuan Niu's avatar
Siyuan Niu committed
1115
1116
1117
1118
      //myfile << "<td colspan=\"5\" class=\"sc\">" << aLength << "</td>";
    }

    myfile << "</tr>" << std::endl << "</table>" << std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
1119
   
Siyuan Niu's avatar
Siyuan Niu committed
1120
   }
Siyuan Niu's avatar
Siyuan Niu committed
1121
#ifdef DEBUG_FPGA
Siyuan Niu's avatar
Siyuan Niu committed
1122
  std::cout<<"end in!!!"<<std::endl;
Siyuan Niu's avatar
Siyuan Niu committed
1123
#endif
Siyuan Niu's avatar
Siyuan Niu committed
1124
}
Siyuan Niu's avatar
Siyuan Niu committed
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135

void FPGA::scheduleBlank(std::ofstream& myfile){ 
  myfile  << "<table>" << std::endl << "<tr>" << std::endl;
  for( std::map<TMLTask*, std::string>::iterator taskColIt = taskCellClasses.begin(); taskColIt != taskCellClasses.end(); ++taskColIt ) {
    TMLTask* task = (*taskColIt).first;
    // Unset the default td max-width of 5px. For some reason setting the max-with on a specific t style does not work
    myfile << "<td class=\"" << taskCellClasses[ task ] << "\"></td><td style=\"max-width: unset;\">" << task->toString() << "</td><td class=\"space\"></td>";
  }
  myfile << "</tr>" << std::endl;
  myfile << "</table>" << std::endl;
}