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 INTERLEAVER_HEADER
00030 #define INTERLEAVER_HEADER
00031
00032 #include <string>
00033 #include <stdexcept>
00034 #include <cmath>
00035 #include <memory>
00036
00037 #include <simthetic/signals.h>
00038 #include <simthetic/misc.h>
00039 #include <simthetic/phbib.h>
00040 #include <simthetic/basicdevice.h>
00041 #include <simthetic/basicdevicefactory.h>
00042
00043
00044 namespace simthlib
00045 {
00046
00047 class Interleaving;
00048
00049 std::ostream& operator<<(std::ostream &os, const Interleaving &cod);
00050
00051
00052 class Interleaving
00053 {
00054 private:
00055
00056 size_t memLen;
00057 int deinterleavedLength_;
00058
00059 bool fitMemLengthToInputLength;
00060
00061
00062 mutable size_t origSize;
00063 mutable int numParts;
00064 mutable int dummyBits;
00065 mutable int remBits;
00066 mutable size_t intlSize;
00067
00068
00069 mutable int deinterleavingInSize;
00070 mutable int deinterleavingNumParts;
00071 mutable int deinterDummyBits;
00072 mutable int deinterRemBits;
00073
00074
00075 protected:
00076
00077 simth::checkedVector<int> interleavingVector;
00078 simth::checkedVector<int> deinterleavingVector;
00079
00080
00081
00082
00083 public:
00085 Interleaving(int memoryLen);
00086
00087
00089 virtual ~Interleaving(){}
00090
00091 size_t interleavedLength(size_t inputLength) const;
00092
00093 void adjustMemoryLength(int newMemLength);
00094
00096 void setDeinterleavedLength(int deInterLen);
00097
00099 int deinterleavedLength( ) const;
00100
00102 template<class Seq> void interleave(const Seq &orig, Seq* inter) const;
00103
00105 template<class Seq_in, class Seq_out>
00106 void deinterleave(const Seq_in &inter, Seq_out* deInter) const;
00107
00109 int interleaveIndex(size_t index) const;
00110
00112 int deinterleaveIndex(size_t index) const;
00113
00114
00115
00116
00117
00118
00119
00121 int memoryLength() const {return memLen;}
00122
00123
00124
00125
00126
00127 virtual void print(std::ostream &os, bool debugInfo = false) const;
00128
00130 static void init(std::ifstream& is, Interleaving** intlv,
00131 const std::string& regionQualifier);
00132
00136 static std::auto_ptr<simthlib::Interleaving>
00137 init(std::ifstream& is,
00138 const std::string& regionQualifier);
00139
00145 static std::auto_ptr<simthlib::Interleaving>
00146 init(const std::string& type, const simth::PropertyList& pl);
00147
00153 static void register_init(simth::DeviceFactory& registration);
00154 };
00155
00156
00157
00158 inline void Interleaving::setDeinterleavedLength(int deInterLen)
00159 {
00160 if(DEBUG) {
00161 if(deInterLen < 0) {
00162 throw std::runtime_error("inline int Interleaving::setdeinterleavedLength(int newMemLen) : error 1");
00163 }
00164 }
00165 deinterleavedLength_ = deInterLen;
00166 }
00167
00168 inline int Interleaving::deinterleavedLength( ) const
00169 {
00170 if(DEBUG) {
00171 if(deinterleavedLength_ < 0) {
00172 throw std::runtime_error("inline int Interleaving::deinterleavedLength(int newMemLen) : error 1");
00173 }
00174 }
00175 return deinterleavedLength_;
00176 }
00177
00178
00179
00180 inline int Interleaving::interleaveIndex(size_t index) const
00181 {
00182 if(DEBUG) {
00183 if( int(index) >= memoryLength() ) {
00184 throw std::logic_error("int Interleaving::interleaveIndex(int index) : "
00185 " index == " + simth::i2string(index) +
00186 " > memoryLength() or < 0");
00187 }
00188 }
00189 return interleavingVector[index];
00190 }
00191
00192 inline int Interleaving::deinterleaveIndex(size_t index) const
00193 {
00194 if(DEBUG) {
00195 if( int(index) >= memoryLength() ) {
00196 throw std::logic_error("int Interleaving::deinterleaveIndex(int index) : "
00197 " index == " + simth::i2string(index) +
00198 " > memoryLength() or < 0");
00199 }
00200 }
00201 return deinterleavingVector[index];
00202 }
00203
00204
00205
00206 inline size_t Interleaving::interleavedLength(size_t inputLength) const
00207 {
00208
00209 size_t remBits = inputLength % memoryLength();
00210 size_t dummyBits = 0;
00211 if(remBits != 0) {
00212
00213 dummyBits = memoryLength() - remBits;
00214 }
00215 size_t intlSize = inputLength + dummyBits;
00216 return intlSize;
00217 }
00218
00219
00220 template<class Seq>
00221 void Interleaving::interleave(const Seq &orig, Seq* inter) const
00222 {
00223 if(memoryLength()==1) {
00224 (*inter)=orig;
00225 return;
00226 }
00227
00228 if(DEBUG) {
00229 if(memoryLength()==0) {
00230 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq& inter) : "
00231 "error 1 ");
00232 }
00233 if(inter == NULL) {
00234 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq& inter) : "
00235 "inter == NULL ");
00236 }
00237 if(orig.size() <= 0) {
00238 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq& inter) : "
00239 "orig.size() == "+simth::i2string(orig.size()));
00240 }
00241 }
00242
00243
00244 if(origSize != orig.size()) {
00245 origSize = orig.size();
00246
00247
00248 numParts = origSize / memoryLength();
00249
00250
00251 remBits = origSize % memoryLength();
00252 dummyBits = 0;
00253 if(remBits != 0) {
00254 dummyBits = memoryLength() - remBits;
00255 }
00256 intlSize = origSize + dummyBits;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 if( inter->size() != intlSize) {
00268 inter->resize(intlSize);
00269 }
00270
00271
00272 int partOffset = 0;
00273
00274 for(int partCounter =0; partCounter < numParts; partCounter++) {
00275
00276
00277 for(int counterInPart=0; counterInPart < memoryLength(); counterInPart++) {
00278
00279
00280 int helpIndex = interleaveIndex(counterInPart);
00281
00282 if(DEBUG) {
00283 if( (helpIndex) >= memoryLength()) {
00284 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq* inter) : "
00285 "helpIndex == "+
00286 simth::i2string(helpIndex)+
00287 " >= memLen");
00288 }
00289 if( (partOffset + helpIndex) >= int(intlSize) ) {
00290 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq* inter) : "
00291 "partOffset + helpIndex == "+
00292 simth::i2string(partOffset+helpIndex)+
00293 " >= seqLenOut");
00294 }
00295 if( (partOffset + counterInPart) >= int(origSize) ) {
00296 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq* inter) : "
00297 "partOffset + counterInPart == "+
00298 simth::i2string(partOffset+counterInPart)+
00299 " >= seqLenIn");
00300 }
00301 }
00302
00303 (*inter)[partOffset + helpIndex] = orig[partOffset + counterInPart];
00304 }
00305 partOffset+=memoryLength();
00306 }
00307
00308 if(dummyBits > 0) {
00309 int lastPartOffset = intlSize - memoryLength();
00310 int pos = 0;
00311 for( ; pos < remBits; pos++) {
00312 int helpIndex = interleaveIndex(pos);
00313 if(DEBUG) {
00314 if( (helpIndex) >= memoryLength()) {
00315 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq* inter) : "
00316 "helpIndex == "+
00317 simth::i2string(helpIndex)+
00318 " >= memLen");
00319 }
00320 if( (lastPartOffset + helpIndex) >= int(intlSize) ) {
00321 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq* inter) : "
00322 "partOffset + helpIndex == "+
00323 simth::i2string(lastPartOffset+helpIndex)+
00324 " >= seqLenOut");
00325 }
00326 }
00327 (*inter)[lastPartOffset + helpIndex] = orig[lastPartOffset + pos];;
00328 }
00329 if(DEBUG) {
00330 if(pos != remBits) {
00331 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq* inter) : "
00332 "error 1");
00333 }
00334 }
00335 for( ; pos < memoryLength(); pos++) {
00336 int helpIndex = interleaveIndex(pos);
00337 if(DEBUG) {
00338 if( (helpIndex) >= memoryLength()) {
00339 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq* inter) : "
00340 "helpIndex == "+
00341 simth::i2string(helpIndex)+
00342 " >= memLen");
00343 }
00344 if( (lastPartOffset + helpIndex) >= int(intlSize) ) {
00345 throw std::logic_error("void Interleaving::interleave(llrSeq &orig, llrSeq* inter) : "
00346 "partOffset + helpIndex == "+
00347 simth::i2string(lastPartOffset+helpIndex)+
00348 " >= seqLenOut");
00349 }
00350 }
00351 typedef typename Seq::value_type T;
00352 (*inter)[lastPartOffset + helpIndex] = T();
00353 }
00354 }
00355 }
00356
00357
00358 template<class Seq_in, class Seq_out>
00359 void Interleaving::deinterleave(const Seq_in &orig, Seq_out* deinter) const
00360 {
00361 if(memoryLength()==1) {
00362 (*deinter)=orig;
00363 return;
00364 }
00365
00366
00367 if(SECURITY){
00368 if(memoryLength()==0) {
00369 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq& inter) : "
00370 "error 1 ");
00371 }
00372 if(deinter == NULL) {
00373 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq& inter) : "
00374 "deinter == NULL ");
00375 }
00376 if(int(orig.size()) < deinterleavedLength() ||
00377 int(orig.size()) >= deinterleavedLength() + memoryLength()) {
00378 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq& deinter) : "
00379 "origSize()<deinterleavedLength() || origSize>=deinterleavedLength + memoryLength()"
00380 " (orig.size() == "+simth::i2string(orig.size())+"), "
00381 " (deinterleavedLength() == "+simth::i2string(deinterleavedLength())+"), "
00382 " (memoryLength() == "+simth::i2string(memoryLength())+")");
00383 }
00384 if(orig.size() % memoryLength() != 0) {
00385 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq& deinter) : "
00386 "origSize() % memoryLength() != 0"
00387 " (orig.size() == "+simth::i2string(orig.size())+")");
00388 }
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399 if( int(deinter->size()) != deinterleavedLength()) {
00400 deinter->resize(deinterleavedLength());
00401 }
00402
00403 if(deinterleavingInSize != int(orig.size()) ) {
00404 deinterleavingInSize = orig.size();
00405 deinterleavingNumParts = deinterleavingInSize / memoryLength();
00406
00407
00408 deinterDummyBits = deinterleavingInSize - deinterleavedLength();
00409 if(DEBUG) {
00410 if(deinterDummyBits < 0 || deinterDummyBits >= memoryLength()) {
00411 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq& deinter) : error 1a");
00412 }
00413 }
00414 if(deinterDummyBits != 0) {
00415 deinterRemBits = memoryLength()-deinterDummyBits;
00416 deinterleavingNumParts--;
00417 }
00418 else {
00419 deinterRemBits = 0;
00420 }
00421 if(DEBUG) {
00422 if(deinterleavingNumParts < 0) {
00423 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq& deinter) : error 1");
00424 }
00425 if(deinterDummyBits == 0 && deinterleavingNumParts == 0) {
00426 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq& deinter) : error 2");
00427 }
00428 }
00429 }
00430
00431 int partOffset = 0;
00432
00433 for(int partCounter =0; partCounter < deinterleavingNumParts; partCounter++) {
00434
00435
00436 for(int counterInPart=0; counterInPart < memoryLength(); counterInPart++) {
00437
00438
00439 int helpIndex = deinterleaveIndex(counterInPart);
00440
00441 if(DEBUG) {
00442 if( (helpIndex) >= memoryLength()) {
00443 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq* deinter) : "
00444 "helpIndex == "+
00445 simth::i2string(helpIndex)+
00446 " >= memLen");
00447 }
00448 if( (partOffset + helpIndex) >= deinterleavingInSize) {
00449 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq* deinter) : "
00450 "partOffset + helpIndex == "+
00451 simth::i2string(partOffset+helpIndex)+
00452 " >= seqLenOut");
00453 }
00454 if( (partOffset + counterInPart) >= deinterleavingInSize) {
00455 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq* deinter) : "
00456 "partOffset + counterInPart == "+
00457 simth::i2string(partOffset+counterInPart)+
00458 " >= seqLenIn");
00459 }
00460 }
00461 (*deinter)[partOffset + helpIndex] = orig[partOffset + counterInPart];
00462 }
00463 partOffset+=memoryLength();
00464 }
00465
00466
00467 for(int counterInPart=0; counterInPart < deinterRemBits; counterInPart++) {
00468
00469
00470 int interHelpIndex = interleaveIndex(counterInPart);
00471 if(DEBUG) {
00472 if( (interHelpIndex) >= memoryLength()) {
00473 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq* deinter) : "
00474 "helpIndex == "+
00475 simth::i2string(interHelpIndex)+
00476 " >= memLen");
00477 }
00478 if( (partOffset + interHelpIndex) >= deinterleavingInSize) {
00479 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq* deinter) : "
00480 "partOffset + helpIndex == "+
00481 simth::i2string(partOffset+interHelpIndex)+
00482 " >= seqLenOut");
00483 }
00484 if( (partOffset + counterInPart) >= deinterleavedLength()) {
00485 throw std::logic_error("void Interleaving::deinterleave(llrSeq &orig, llrSeq* deinter) : "
00486 "partOffset + deinterLeavedLength() == "+
00487 simth::i2string(partOffset+deinterleavedLength())+
00488 " >= seqLenIn");
00489 }
00490 }
00491 (*deinter)[partOffset + counterInPart] = orig[partOffset + interHelpIndex];
00492 }
00493 }
00494
00495
00496
00497 class NoInterleaving : public Interleaving
00498 {
00499 protected:
00500
00501 public:
00502 NoInterleaving() : Interleaving(1){};
00503
00504 virtual void print(std::ostream &os, bool debugInfo = false) const;
00505 };
00506
00507
00508
00509 class BlockInterleaving : public Interleaving
00510 {
00511 private:
00512
00513
00514 protected:
00515 void initMappingVectors();
00516
00517 public:
00522 BlockInterleaving(int blockLength);
00523
00524 virtual void print(std::ostream &os, bool debugInfo = false) const;
00525 };
00526
00527 class SymbolInterleaving : public Interleaving
00528 {
00529 private:
00530
00531 int blockLength_;
00532 int symbolLength_;
00533
00534 protected:
00535 void initMappingVectors();
00536
00537
00538 public:
00543 SymbolInterleaving(int blockLength, int symbolLength,
00544 int forcedMemLength_ = -1);
00545
00546 virtual void print(std::ostream &os, bool debugInfo = false) const;
00547 };
00548
00549
00550 class Interleaving3d : public Interleaving
00551 {
00552 private:
00553
00555 int num_columns;
00556
00558 int num_rows;
00559
00561 int num_planes;
00562
00563 protected:
00564 void initMappingVectors();
00565
00566 public:
00571 Interleaving3d(int cols, int rows, int planes);
00572
00573 virtual void print(std::ostream &os, bool debugInfo = false) const;
00574 };
00575
00576
00577
00578 class Interleaving3dModified : public Interleaving
00579 {
00580 private:
00581
00583 int num_columns;
00584
00586 int num_rows;
00587
00589 int num_planes;
00590
00591 bool planeScramble;
00592
00593 simth::checkedVector<int> bitPosMapping;
00594
00595 void initBitPositionMapping();
00596
00597 static bool isPlaneStillFree(int infoInteger, int bitPos);
00598
00601 int getPlane(int dataBitPos) const;
00602
00603 protected:
00604 void initMappingVectors();
00605
00606 public:
00611 Interleaving3dModified(int cols, int rows, int planes, bool planeScrambling);
00612
00613 virtual void print(std::ostream &os, bool debugInfo = false) const;
00614
00615 };
00616
00617
00618 inline int Interleaving3dModified::getPlane(int dataBitPos) const
00619 {
00620 if(planeScramble == true) {
00621 return bitPosMapping[dataBitPos];
00622 }
00623 else {
00624 return dataBitPos;
00625 }
00626 }
00627
00628 inline bool Interleaving3dModified::isPlaneStillFree(int infoValue, int bitPos)
00629 {
00630 return (infoValue & 1<<bitPos) ? false : true;
00631 }
00632
00633
00634
00657 class PolyphaseInterleaving3d : public Interleaving
00658 {
00659 private:
00660
00662 int num_columns;
00663
00665 int num_rows;
00666
00668 int num_planes;
00669
00670 protected:
00671 void initMappingVectors();
00672
00673 public:
00678 PolyphaseInterleaving3d(int cols, int rows, int planes);
00679
00680 virtual void print(std::ostream &os, bool debugInfo = false) const;
00681 };
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 class PseudoRandomInterleaving : public Interleaving
00695 {
00696 private:
00697
00698 int a;
00699 int b;
00700
00701 protected:
00702 void initMappingVectors();
00703
00704 public:
00713 PseudoRandomInterleaving(int N, int a, int b);
00714
00715 virtual void print(std::ostream &os, bool debugInfo = false) const;
00716 };
00717
00720 class PseudoRandom3dInterleaving : public PseudoRandomInterleaving
00721 {
00722 private:
00723
00724 int planes;
00725
00726 protected:
00727 void sortMappingVectors();
00728
00729 public:
00740 PseudoRandom3dInterleaving(int N, int a, int b, int planes);
00741
00742 virtual void print(std::ostream &os, bool debugInfo = false) const;
00743 };
00744
00745
00746
00749 class PseudoRandomSymbolInterleaving : public Interleaving
00750 {
00751 private:
00752
00753 int symbolLength;
00754 PseudoRandomInterleaving pseudoIntlv;
00755
00756 protected:
00757 void initMappingVectors();
00758
00759 public:
00770 PseudoRandomSymbolInterleaving(int N, int a, int b, int symbolLength);
00771
00772 virtual void print(std::ostream &os, bool debugInfo = false) const;
00773 };
00774
00775
00776
00777
00778
00780 class Interleaver : public simth::Device
00781 {
00782 friend void initMSDDDecoder(const std::string, simth::Device**, simth::DeviceSystemIntf*, int ID,
00783 const std::string& regionQualifier = "");
00784
00785 protected:
00786
00787 Interleaving* interl;
00788
00789 public:
00790 Interleaver(int deviceID, simth::DeviceSystemIntf* system,
00791 const simth::PropertyList& pl,
00792 std::auto_ptr<Interleaving> interl_);
00793 ~Interleaver();
00794
00795 virtual void updateInputLengths();
00796 virtual void updateOutputLengths();
00797
00799 int memoryLength() const {return interl->memoryLength();}
00800
00801 void adjustMemoryLength(int newMemLength);
00802
00803 void print(std::ostream &os) const;
00804
00807 void startOfSimulation();
00808
00810 static void init(const std::string fileName, simth::Device** dev, simth::DeviceSystemIntf* sysPtr, int ID,
00811 const std::string& regionQualifier = "");
00812
00818 static simth::Device*
00819 init(int ID,
00820 simth::DeviceSystemIntf* sysPtr,
00821 const simth::PropertyList& _pl,
00822 const std::string& cpptype);
00823 };
00824
00825
00826
00828 template<class T>
00829 class InterleaverT : public Interleaver
00830 {
00831
00832
00833 public:
00834 InterleaverT(int deviceID, simth::DeviceSystemIntf* system,
00835 const simth::PropertyList& pl,
00836 std::auto_ptr<Interleaving> interl_);
00837
00838 virtual void process();
00839 };
00840
00841 template<class T>
00842 InterleaverT<T>::InterleaverT(int deviceID, simth::DeviceSystemIntf* system,
00843 const simth::PropertyList& pl,
00844 std::auto_ptr<Interleaving> interl_)
00845 : Interleaver(deviceID, system, pl, interl_)
00846 {
00847 insertInputInterface<T>();
00848 insertOutputInterface<T>();
00849 }
00850
00851
00852
00853 template<class T>
00854 void InterleaverT<T>::process()
00855 {
00856
00857 while(isInputSequence(0)) {
00858 T* in = getInputSequence<T>(0);
00859 T* out = getOutputSequence<T>(0);
00860 if(out->rAttributes() != in->rAttributes()) {
00861 out->wAttributes() = in->rAttributes();
00862 }
00863 interl->interleave(*in,out);
00864 flushProcessedSequences();
00865 }
00866
00867
00868
00869 }
00870
00871
00873 class Deinterleaver : public simth::Device
00874 {
00875 private:
00876
00877 protected:
00878
00879 Interleaving* interl;
00880
00881 public:
00882
00883 Deinterleaver(int deviceID, simth::DeviceSystemIntf* system,
00884 const simth::PropertyList& pl,
00885 std::auto_ptr<Interleaving> interl_);
00886 ~Deinterleaver();
00887
00888 virtual void updateInputLengths();
00889 virtual void updateOutputLengths();
00890
00892 int memoryLength() const {return interl->memoryLength();}
00893
00894 void adjustMemoryLength(int newMemLength);
00895
00896 void print(std::ostream &os) const;
00897
00900 void startOfSimulation();
00901
00903 static void init(const std::string fileName, simth::Device** dev, simth::DeviceSystemIntf* sysPtr, int ID,
00904 const std::string& regionQualifier = "");
00905
00911 static simth::Device*
00912 init(int ID,
00913 simth::DeviceSystemIntf* sysPtr,
00914 const simth::PropertyList& _pl,
00915 const std::string& cpptype);
00916 };
00917
00918
00919
00920
00922 template<class T>
00923 class DeinterleaverT : public Deinterleaver
00924 {
00925
00926
00927 public:
00928
00929 DeinterleaverT(int deviceID, simth::DeviceSystemIntf* system,
00930 const simth::PropertyList& pl,
00931 std::auto_ptr<Interleaving> interl_);
00932
00933 virtual void process();
00934 };
00935
00936 template<class T>
00937 inline DeinterleaverT<T>::DeinterleaverT(int deviceID, simth::DeviceSystemIntf* system,
00938 const simth::PropertyList& pl,
00939 std::auto_ptr<Interleaving> interl_)
00940 : Deinterleaver(deviceID, system, pl, interl_)
00941 {
00942 insertInputInterface<T>();
00943 insertOutputInterface<T>();
00944 }
00945
00946
00947 template<class T>
00948 void DeinterleaverT<T>::process()
00949 {
00950
00951 while(isInputSequence(0)) {
00952 interl->deinterleave(*getInputSequence<T>(0),getOutputSequence<T>(0));
00953 flushProcessedSequences();
00954 }
00955
00956
00957
00958 }
00959
00960
00961 }
00962
00963 #endif
00964
00965