Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

multiplexer.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  ** @file multiplexer.h General multiplexer
00003                              -------------------
00004     begin                : Wed December 11 2002
00005     copyright            : (C) 2002 by Christian Stimming
00006     email                : stimming@tuhh.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU Lesser General Public            *
00013  *   License as published by the Free Software Foundation; either          *
00014  *   version 2.1 of the License, or (at your option) any later version.    *
00015  *                                                                         *
00016  *   This library is distributed in the hope that it will be useful,       *
00017  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00019  *   Lesser General Public License for more details.                       *
00020  *                                                                         *
00021  *   You should have received a copy of the GNU Lesser General Public      *
00022  *   License along with this library; if not, write to the Free Software   *
00023  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00024  *   MA  02111-1307  USA                                                   *
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     /* For the time being the following two functions are equivalent
00170        because the total input and output lengths are always
00171        identical. */
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 /*                                 AdaptiveMultiplexerT                                */
00185 /***************************************************************************************/
00186 /* Implementation is here in the header file because implementation in the source file */
00187 /* would result in undefined symbol errors.*/
00188 //template AdaptiveMultiplexerT<BitSeq>;
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   //std::vector< seqT* > iseqs (iports);
00264   std::vector<unsigned> iindex(iports), oindex(oports);
00265   /*if(oports==1)                                                     
00266     std::cout<<"Start receiver multiplexer processing"<<std::endl;
00267   else
00268     std::cout<<"Start transmitter multiplexer processing"<<std::endl; */
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     //std::cout<<"input length "<<i<<": "<<iseqs[i]->size()<<std::endl;                           
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      //std::cout<<"output length "<<i<<": "<<oseqs[i]->size()<<std::endl;
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                   std::cout<<"oport: "<<oport<<" onumber: "<<onumber<<" iport: "<<iport<<" n: "<<n<<std::endl ;
00343                   std::cout<<"oseqsize: "<<oseqs[oport]->size()<<" iseqsize: "<<iseqs[iport]->size()<<std::endl ;
00344                   std::cout<<"outcycle: "<<outCycle[oport]<<" incycle: "<<inCycle[iport]<<std::endl ;
00345                   
00346                   std::cout<<"oindex[oport]: "<<oindex[oport]<<" iindex[iport]: "<<iindex[iport]<<std::endl ;
00347 */
00348     oseqs[oport]->operator[](oindex[oport]++) =   iseqs[iport]->operator[](iindex[iport]++);              
00349     //oseqs[oport]->operator[](onumber) =   iseqs[iport]->operator[](n);
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 /*    if(oports==1)
00357       std::cout<<"Data from input "<<oport<<" written to multiplexer output "<<iport<<" ! "<<std::endl;
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         // Only compare on true greater, since
00383         // usually the comparison of the outer
00384         // for-loop will terminate just about now.
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         // Only compare on true greater, since
00398         // usually the comparison of the outer
00399         // for-loop will terminate just about now.
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     //std::cout<<"Data written to rx multiplexer output! ("<< onumber<<"bits)"<<std::endl;
00408   
00409   //std::cout<<"Leave multiplexer processing"<<std::endl;
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      //std::cout<<"elemperincycle: "<<elemPerInCycle<<"  elemperoutcycle: "<<elemPerOutCycle<<" totalInputLength: "<<totalInputLength<<std::endl;
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    //totalInputLength=totalOutputLength;
00440 
00441    for(unsigned int i=0;i<oports;i++)
00442    {
00443      outputInterface(i)->setSequenceLength(numOutputCycles*outCycle[i]);
00444      //std::cout<<"multiplexer output length: "<< numOutputCycles*outCycle[i]<<std::endl;
00445 
00446      //setOutputLength(numOutputCycles*outCycle[i],i);
00447    }
00448    for(unsigned int i=0;i<iports;i++)
00449    {
00450      inputInterface(i)->setSequenceLength(numInputCycles*inCycle[i]);
00451      //std::cout<<"multiplexer input length: "<< numInputCycles*inCycle[i]<<std::endl;
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   /* For this device, Input nd Output Lengths are jointly updated! */
00469   updateInOutLengths();
00470 /*   totalInputLength=totalOutputLength;
00471    unsigned numInputCycles=totalInputLength/elemPerInCycle;
00472    totalInputLength=numInputCycles* elemPerInCycle;
00473    if(totalInputLength%elemPerOutCycle)
00474    {
00475      std::cout<<"elemperincycle: "<<elemPerInCycle<<"  elemperoutcycle: "<<elemPerOutCycle<<" totalInputLength: "<<totalInputLength<<std::endl;
00476 
00477      throw std::runtime_error("AdaptiveMultiplexerT::updateInputLengths(): Incompatible in/out cycles!");
00478    }
00479    if(totalInputLength!=totalOutputLength)
00480    {
00481      updateOutputLengths();
00482    }
00483    
00484 
00485    for(unsigned int i=0;i<iports;i++)
00486    {
00487      inputInterface(i)->setSequenceLength(numInputCycles*inCycle[i]);
00488      std::cout<<"multiplexer input length: "<< numInputCycles*inCycle[i]<<std::endl;
00489 
00490    }
00491    */
00492 }
00493 
00494 template<class seqT>
00495 void AdaptiveMultiplexerT<seqT>::startOfSimulation()
00496 {
00497   setTotalInputLength(getProperty<int>("input_length"));
00498 }
00499 
00500 } // namespace
00501 
00502 #endif /* MULTIPLEXER_H */

Generated on Fri Jul 15 16:16:45 2005 for simtheticlib by  doxygen 1.4.1