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     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     /* For the time being the following two functions are equivalent
00171        because the total input and output lengths are always
00172        identical. */
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 /*                                 AdaptiveMultiplexerT                                */
00186 /***************************************************************************************/
00187 /* Implementation is here in the header file because implementation in the source file */
00188 /* would result in undefined symbol errors.*/
00189 //template AdaptiveMultiplexerT<BitSeq>;
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   //std::vector< seqT* > iseqs (iports);
00265   std::vector<unsigned> iindex(iports), oindex(oports);
00266   /*if(oports==1)                                                     
00267     std::cout<<"Start receiver multiplexer processing"<<std::endl;
00268   else
00269     std::cout<<"Start transmitter multiplexer processing"<<std::endl; */
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     //std::cout<<"input length "<<i<<": "<<iseqs[i]->size()<<std::endl;                           
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      //std::cout<<"output length "<<i<<": "<<oseqs[i]->size()<<std::endl;
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                   std::cout<<"oport: "<<oport<<" onumber: "<<onumber<<" iport: "<<iport<<" n: "<<n<<std::endl ;
00344                   std::cout<<"oseqsize: "<<oseqs[oport]->size()<<" iseqsize: "<<iseqs[iport]->size()<<std::endl ;
00345                   std::cout<<"outcycle: "<<outCycle[oport]<<" incycle: "<<inCycle[iport]<<std::endl ;
00346                   
00347                   std::cout<<"oindex[oport]: "<<oindex[oport]<<" iindex[iport]: "<<iindex[iport]<<std::endl ;
00348 */
00349     oseqs[oport]->operator[](oindex[oport]++) =   iseqs[iport]->operator[](iindex[iport]++);              
00350     //oseqs[oport]->operator[](onumber) =   iseqs[iport]->operator[](n);
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 /*    if(oports==1)
00358       std::cout<<"Data from input "<<oport<<" written to multiplexer output "<<iport<<" ! "<<std::endl;
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         // Only compare on true greater, since
00384         // usually the comparison of the outer
00385         // for-loop will terminate just about now.
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         // Only compare on true greater, since
00399         // usually the comparison of the outer
00400         // for-loop will terminate just about now.
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     //std::cout<<"Data written to rx multiplexer output! ("<< onumber<<"bits)"<<std::endl;
00409   
00410   //std::cout<<"Leave multiplexer processing"<<std::endl;
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      //std::cout<<"elemperincycle: "<<elemPerInCycle<<"  elemperoutcycle: "<<elemPerOutCycle<<" totalInputLength: "<<totalInputLength<<std::endl;
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    //totalInputLength=totalOutputLength;
00441 
00442    for(unsigned int i=0;i<oports;i++)
00443    {
00444      outputInterface(i)->setSequenceLength(numOutputCycles*outCycle[i]);
00445      //std::cout<<"multiplexer output length: "<< numOutputCycles*outCycle[i]<<std::endl;
00446 
00447      //setOutputLength(numOutputCycles*outCycle[i],i);
00448    }
00449    for(unsigned int i=0;i<iports;i++)
00450    {
00451      inputInterface(i)->setSequenceLength(numInputCycles*inCycle[i]);
00452      //std::cout<<"multiplexer input length: "<< numInputCycles*inCycle[i]<<std::endl;
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   /* For this device, Input nd Output Lengths are jointly updated! */
00470   updateInOutLengths();
00471 /*   totalInputLength=totalOutputLength;
00472    unsigned numInputCycles=totalInputLength/elemPerInCycle;
00473    totalInputLength=numInputCycles* elemPerInCycle;
00474    if(totalInputLength%elemPerOutCycle)
00475    {
00476      std::cout<<"elemperincycle: "<<elemPerInCycle<<"  elemperoutcycle: "<<elemPerOutCycle<<" totalInputLength: "<<totalInputLength<<std::endl;
00477 
00478      throw std::runtime_error("AdaptiveMultiplexerT::updateInputLengths(): Incompatible in/out cycles!");
00479    }
00480    if(totalInputLength!=totalOutputLength)
00481    {
00482      updateOutputLengths();
00483    }
00484    
00485 
00486    for(unsigned int i=0;i<iports;i++)
00487    {
00488      inputInterface(i)->setSequenceLength(numInputCycles*inCycle[i]);
00489      std::cout<<"multiplexer input length: "<< numInputCycles*inCycle[i]<<std::endl;
00490 
00491    }
00492    */
00493 }
00494 
00495 template<class seqT>
00496 void AdaptiveMultiplexerT<seqT>::startOfSimulation()
00497 {
00498   setTotalInputLength(getProperty<int>("input_length"));
00499 }
00500 
00501 } // namespace
00502 
00503 #endif /* MULTIPLEXER_H */

Generated on Tue Aug 9 14:35:11 2005 for simtheticlib by  doxygen 1.4.1