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