00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef MULTIPLEXER_H
00030 #define MULTIPLEXER_H
00031
00032 #include "basicdevicefactory.h"
00033 #include "basicdevice.h"
00034 #include "phbib.h"
00035 #include "signals.h"
00036
00037
00038 namespace simthlib
00039 {
00040
00063 class Multiplexer : public simth::Device
00064 {
00065 protected:
00066 unsigned int iports;
00067 unsigned int oports;
00068
00069 Multiplexer(int deviceID, simth::DeviceSystemIntf* system,
00070 const simth::PropertyList& pl,
00071 unsigned int _iports,
00072 unsigned int _oports);
00073
00074 public:
00075 virtual void updateInputLengths();
00076 virtual void updateOutputLengths();
00077
00078 template<class seqT>
00079 void process();
00080
00081 void print(std::ostream &os) const;
00082
00083 static void init(const std::string& fileName,
00084 simth::Device** dev,
00085 simth::DeviceSystemIntf* sysPtr,
00086 int ID,
00087 const std::string& regionQualifier);
00088
00089 static void init(simth::DeviceFactory& registration);
00090 };
00091
00092
00098 template<class seqT>
00099 class MultiplexerT : public Multiplexer
00100 {
00101 public:
00102 MultiplexerT(int deviceID, simth::DeviceSystemIntf* system,
00103 const simth::PropertyList& pl,
00104 unsigned int _iports,
00105 unsigned int _oports,
00106 typename seqT::value_type default_val =
00107 typename seqT::value_type() );
00108
00110 MultiplexerT(int deviceID, simth::DeviceSystemIntf* system,
00111 const simth::PropertyList& pl)
00112 : Multiplexer (deviceID, system, pl,
00113 pl.simth::PropertyList::getProperty<unsigned>("input_ports"),
00114 pl.simth::PropertyList::getProperty<unsigned>("output_ports"))
00115 {
00116 insertInputInterface< seqT >(iports);
00117 insertOutputInterface< seqT >(oports);
00118 };
00119
00120 void process()
00121 { Multiplexer::process<seqT>(); };
00122 };
00123
00124
00125
00126
00148 template<class seqT>
00149 class AdaptiveMultiplexerT : public Multiplexer
00150 {
00151 private:
00152 simth::checkedVector<unsigned int> inCycle;
00153 simth::checkedVector<unsigned int> outCycle;
00154
00155 unsigned int elemPerInCycle;
00156 unsigned int elemPerOutCycle;
00157 unsigned int desiredTotalLength;
00158 unsigned int totalInputLength;
00159 unsigned int totalOutputLength;
00160
00161 public:
00162 AdaptiveMultiplexerT(int deviceID, simth::DeviceSystemIntf* system,
00163 const simth::PropertyList& pl);
00164
00165
00166 void setInputCycle(simth::checkedVector<unsigned int> inputCycle);
00167 void setOutputCycle(simth::checkedVector<unsigned int> outputCycle);
00168
00169
00170
00171
00172 void setTotalInputLength(unsigned int length){desiredTotalLength=length;totalInputLength=length;updateInOutLengths();};
00173 void setTotalOutputLength(unsigned int length){setTotalInputLength(length);};
00174
00175 void process();
00176 void updateInputLengths();
00177 void updateOutputLengths();
00178 void updateInOutLengths();
00179 void startOfSimulation();
00180 };
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 template<class seqT>
00191 AdaptiveMultiplexerT<seqT>::AdaptiveMultiplexerT(
00192 int deviceID, simth::DeviceSystemIntf* system,
00193 const simth::PropertyList& pl)
00194 : Multiplexer (deviceID, system, pl,
00195 pl.simth::PropertyList::getProperty<unsigned>("input_ports"),
00196 pl.simth::PropertyList::getProperty<unsigned>("output_ports"))
00197 {
00198 insertInputInterface< seqT >(iports);
00199 insertOutputInterface< seqT >(oports);
00200
00201 inCycle.resize(iports);
00202 outCycle.resize(oports);
00203
00204 elemPerInCycle = iports;
00205 elemPerOutCycle = oports;
00206
00207
00208 for(unsigned int i=0;i<iports;i++)
00209 {
00210 inCycle[i]=1;
00211 }
00212 for(unsigned int i=0;i<oports;i++)
00213 {
00214 outCycle[i]=1;
00215 }
00216 }
00217
00218
00219 template<class seqT>
00220 void AdaptiveMultiplexerT<seqT>::setInputCycle(simth::checkedVector<unsigned int> inputCycle)
00221 {
00222 if(inputCycle.size()!=iports)
00223 {
00224 throw std::runtime_error("AdaptiveMultiplexerT::setInputCycle(): "
00225 "Number of cycles does not match number of input ports!");
00226 }
00227 else
00228 {
00229 inCycle=inputCycle;
00230 elemPerInCycle=0;
00231 for(unsigned int i=0;i<inCycle.size();i++)
00232 {
00233 elemPerInCycle+=inCycle[i];
00234 }
00235 }
00236 }
00237
00238 template<class seqT>
00239 void AdaptiveMultiplexerT<seqT>::setOutputCycle(simth::checkedVector<unsigned int> outputCycle)
00240 {
00241 if(outputCycle.size()!=oports)
00242 {
00243 throw std::runtime_error("AdaptiveMultiplexerT::setOutputCycle(): "
00244 "Number of cycles does not match number of output ports!");
00245 }
00246 else
00247 {
00248 outCycle=outputCycle;
00249 elemPerOutCycle=0;
00250 for(unsigned int i=0;i<outCycle.size();i++)
00251 {
00252 elemPerOutCycle+=outCycle[i];
00253 }
00254 }
00255 }
00256
00257
00258
00259
00260 template<class seqT>
00261 void AdaptiveMultiplexerT<seqT>::process()
00262 {
00263
00264 std::vector<unsigned> iindex(iports), oindex(oports);
00265
00266
00267
00268
00269
00270 if((elemPerOutCycle%elemPerInCycle!=0)&&(elemPerInCycle%elemPerOutCycle!=0))
00271 {
00272 throw std::runtime_error("AdaptiveMultiplexerT::process(): "
00273 "Incompatible input/output cycles!");
00274 }
00275
00276
00277 for (unsigned int i = 0; i < iports; i++)
00278 {
00279 if (!isInputInterfaceConnected (i))
00280 throw simth::ParameterErr("Multiplexer::process(): Input interface no. "+simth::i2string(i)+" is not connected in device "+simth::i2string(ID()));
00281 iindex[i]=0;
00282 if(!isInputSequence(i))
00283 {
00284 return;
00285 }
00286 }
00287 for (unsigned int i = 0; i < oports; i++)
00288 {
00289 if (!isOutputInterfaceConnected (i))
00290 throw simth::ParameterErr("Multiplexer::process(): "
00291 "Output interface no. "
00292 + simth::i2string(i) +
00293 " is not connected in device "
00294 +simth::i2string(ID()));
00295 oindex[i]=0;
00296 }
00297
00298 std::vector< seqT* > iseqs (iports);
00299 std::vector< seqT* > oseqs (oports);
00300
00301 for (unsigned i = 0; i < iports; i++)
00302 {
00303 iseqs[i] = getInputSequence< seqT >(i);
00304 if (iseqs[i]->rAttributes() != iseqs[0]->rAttributes())
00305 throw std::runtime_error("Multiplexer::process(): "
00306 "Attributes of input ports #"
00307 +simth::i2string(i)+
00308 " and #0 are different in device "
00309 +simth::i2string(ID()));
00310
00311 }
00312 for (unsigned i = 0; i < oports; i++)
00313 {
00314 oseqs[i] = getOutputSequence< seqT >(i);
00315 if (oseqs[i]->rAttributes() != iseqs[0]->rAttributes())
00316 oseqs[i]->wAttributes() = iseqs[0]->rAttributes();
00317
00318
00319 }
00320
00321 unsigned iLength = totalInputLength;
00322 unsigned oLength = totalOutputLength;
00323
00324 unsigned oport = 0, onumber = 0, iport=0, inumber=0;
00325 unsigned inRepCount=0, outRepCount=0;
00326 for (unsigned n = 0; n < iLength; n++)
00327 {
00328 while((inCycle[iport]==0)&&(iport<iports))
00329 {
00330 iport++;
00331 if(iport==iports)
00332 iport=0;
00333 }
00334
00335 while((outCycle[oport]==0)&&(oport<oports))
00336 {
00337 oport++;
00338 if(oport==oports)
00339 oport=0;
00340 }
00341
00342
00343
00344
00345
00346
00347
00348 oseqs[oport]->operator[](oindex[oport]++) = iseqs[iport]->operator[](iindex[iport]++);
00349
00350
00351 if((oindex[oport]>outputLength(oport))||(iindex[iport]>inputLength(iport)))
00352 {
00353 throw std::runtime_error("AdaptiveMultiplexerT::process(): Index exceeds sequence length! ");
00354 }
00355
00356
00357
00358
00359
00360 outRepCount++;
00361 inRepCount++;
00362 if(outRepCount==outCycle[oport])
00363 {
00364 oport++;
00365 outRepCount=0;
00366 }
00367
00368
00369 if(inRepCount==inCycle[iport])
00370 {
00371 iport++;
00372 inRepCount=0;
00373 }
00374
00375 if (oport >= oports)
00376 {
00377 oport = 0;
00378 onumber++;
00379
00380 if (onumber > oLength)
00381 {
00382
00383
00384
00385 throw std::runtime_error("AdaptiveMultiplexerT::process(): Oops, output length overflow in device "+simth::i2string(ID()));
00386 }
00387
00388 }
00389
00390
00391
00392 if (iport >= iports)
00393 {
00394 iport = 0;
00395 inumber++;
00396 if (inumber > iLength)
00397
00398
00399
00400 throw std::runtime_error("AdaptiveMultiplexerT::process(): Oops, oinput length overflow in device "+simth::i2string(ID()));
00401 }
00402 }
00403
00404 flushProcessedSequences();
00405 if(oports==1)
00406 std::cout<<"."<<std::flush;
00407
00408
00409
00410
00411 }
00412
00413
00414
00415 template<class seqT>
00416 void AdaptiveMultiplexerT<seqT>::updateInOutLengths()
00417 {
00418 totalInputLength=desiredTotalLength;
00419 totalOutputLength=totalInputLength;
00420 unsigned numOutputCycles=totalOutputLength/elemPerOutCycle;
00421 totalOutputLength=numOutputCycles* elemPerOutCycle;
00422
00423 totalInputLength=totalOutputLength;
00424 unsigned numInputCycles=totalInputLength/elemPerInCycle;
00425 totalInputLength=numInputCycles* elemPerInCycle;
00426 totalOutputLength=totalInputLength;
00427
00428
00429 if(totalInputLength%elemPerOutCycle)
00430 {
00431 std::cout<<"elemperincycle: "<<elemPerInCycle<<" elemperoutcycle: "<<elemPerOutCycle<<" totalInputLength: "<<totalInputLength<<std::endl;
00432
00433 throw std::runtime_error("AdaptiveMultiplexerT::updateInOutLengths(): Incompatible in/out cycles!");
00434 }
00435
00436 numOutputCycles=totalOutputLength/elemPerOutCycle;
00437 totalOutputLength=numOutputCycles* elemPerOutCycle;
00438
00439
00440
00441 for(unsigned int i=0;i<oports;i++)
00442 {
00443 outputInterface(i)->setSequenceLength(numOutputCycles*outCycle[i]);
00444
00445
00446
00447 }
00448 for(unsigned int i=0;i<iports;i++)
00449 {
00450 inputInterface(i)->setSequenceLength(numInputCycles*inCycle[i]);
00451
00452
00453 }
00454 }
00455
00456
00457
00458 template<class seqT>
00459 void AdaptiveMultiplexerT<seqT>::updateOutputLengths()
00460 {
00461 updateInOutLengths();
00462
00463 }
00464
00465 template<class seqT>
00466 void AdaptiveMultiplexerT<seqT>::updateInputLengths()
00467 {
00468
00469 updateInOutLengths();
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 }
00493
00494 template<class seqT>
00495 void AdaptiveMultiplexerT<seqT>::startOfSimulation()
00496 {
00497 setTotalInputLength(getProperty<int>("input_length"));
00498 }
00499
00500 }
00501
00502 #endif