【问题标题】:C++ : Shift register, SNRZI encoder/decoderC++:移位寄存器、SNRZI 编码器/解码器
【发布时间】:2011-06-18 16:58:11
【问题描述】:

编辑:已解决,感谢 Dialecticus,正确的代码在第二个“框架”(?)中。

我必须编写一个程序来编码和解码来自/到文件的大比特流。编码是加扰不归零反转,用于串行视频数据传输。首先,我必须在一些简短而简单的比特流上尝试我的算法的功能,例如一个前导码 3FF 000 000(10 位字),在写入二进制时表示 10 个 1 和 20 个 0。

这是扰频器图: http://i.stack.imgur.com/ef3XP.gif

我写了一个测试控制台程序,就像在图纸上应该编码这个前导码然后解码答案以获得起始前导码比特流。这不起作用,即解码器不返回前导码。这是它(我希望它是可读的):

类似Dysaster的代码提示:

#include "stdafx.h"
#include<iostream>
#include<vector>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
// Encoder -----------------------------------------------------------------------------------------------------------------------------------
cout<< endl <<" Encoder "<< endl;

// create an input vector and initialize it with 3FF 000 000
bool bInput[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
vector< bool > vbInput( bInput, bInput + sizeof( bInput ) / sizeof( bool ) );

// create the shift register
bool bShiftReg[10] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };

// create an output vector 
vector< bool > vbOutput(40);

// iterator for the input
vector<bool>::iterator itInput = vbInput.begin();
cout<<"\n Input: ";
for( itInput = vbInput.begin(); itInput < vbInput.end(); itInput++)
    cout << " " << *itInput;

cout<<endl<<endl;

// iterator for the output
vector<bool>::iterator itOutput = vbOutput.begin();

for( itInput = vbInput.begin(); itInput < vbInput.end(); itInput++)
{
    // handle first and last values separately
    bShiftReg[ 9 ] = bShiftReg[ 9 ] ^ bShiftReg[ 8 ];
    bShiftReg[ 0 ] = *itInput ^ ( bShiftReg[ 4 ] ^ bShiftReg[ 8 ] );

    bool bTempReg[2];
    bTempReg[0] = bShiftReg[0];
    bTempReg[1] = bShiftReg[9];

    // shift operation
    for( unsigned char ucIndex = 8; ucIndex > 0; ucIndex-- )
    {
        bShiftReg[ ucIndex ] = bShiftReg[ ucIndex - 1 ];
    }

    bShiftReg[0] = bTempReg[0];
    bShiftReg[9] = bTempReg[1];

    // write to output
    //*itOutput = static_cast< int > ( bShiftReg[ 9 ] );
    *itOutput = bShiftReg[ 9 ];

    cout<<"\n Schift Reg: ";
    for( int i=0;i<10;i++)
    { cout << " " << bShiftReg[i]; }

    cout<<" Output: " << *itOutput;

    itOutput++;
}
cout<<"\n Output: ";
for( itOutput = vbOutput.begin(); itOutput < vbOutput.end(); itOutput++)
    cout << " " << *itOutput;

cout<<endl<<endl;

// Decoder -----------------------------------------------------------------------------------------------------------------------------------

cout<< endl <<" Decoder "<< endl;

// load the old ouput to the new input but use only bits 10:40
itOutput = vbOutput.begin() + 10;
for( itInput = vbInput.begin(); itInput < vbInput.end() - 10; itInput++)
{
    *itInput = *itOutput;
    itOutput++;

}

cout<<"\n Input: ";
for( itInput = vbInput.begin(); itInput < vbInput.end(); itInput++)
    cout << " " << *itInput;

// reset the shift reg
for(int i = 0;i<10;i++) bShiftReg[i] = 1;

// set output iterator to the begin of the vector
itOutput = vbOutput.begin();

for( itInput = vbInput.begin(); itInput < vbInput.end(); itInput++)
{
    // shift operation
    for( unsigned char ucIndex = 9; ucIndex > 1; ucIndex-- )
    {
        bShiftReg[ ucIndex ] = bShiftReg[ ucIndex - 1 ];
    }

    // write to output
    *itOutput = ( ( *itInput ^ bShiftReg[0] ) ^ bShiftReg[5] ) ^ bShiftReg[9];

    // write the first and second values
    bShiftReg[ 1 ] = bShiftReg[ 0 ] ^ *itInput;
    bShiftReg[ 0 ] = *itInput;

    cout<<"\n Schift Reg: ";
    for( int i=0;i<10;i++)
    { cout << " " << bShiftReg[i]; }

    cout<<" Output: " << *itOutput;

    itOutput++;
}
cout<<"\n Output: ";
for( itOutput = vbOutput.begin(); itOutput < vbOutput.end(); itOutput++)
    cout << " " << *itOutput;

cout<<endl<<endl;


return 0;
}

控制台输出:

编码器

输入:1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

输出:0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 0 1

解码器

输入:0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0

输出:1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 0

-------------------结束控制台输出

像 Dialecticus 这样的代码建议:

#include "stdafx.h"

#include<iostream>
#include<vector>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
// Encoder -----------------------------------------------------------------------------------------------------------------------------------
cout<< endl <<" Encoder "<< endl;

// create an input vector
bool bInput[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//bool bInput[] = { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 };
vector< bool > vbInput( bInput, bInput + sizeof( bInput ) / sizeof( bool ) );

// create the shift register
//bool bShiftReg[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
bool bShiftReg[10] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };

// create an output vector 
vector< bool > vbOutput(40);

// iterator for the input
vector<bool>::iterator itInput = vbInput.begin();
cout<<"\n Input: ";
for( itInput = vbInput.begin(); itInput < vbInput.end(); itInput++)
    cout << " " << *itInput;

cout<<endl<<endl;

// iterator for the output
vector<bool>::iterator itOutput = vbOutput.begin();

for( itInput = vbInput.begin(); itInput < vbInput.end(); itInput++)
{
    // calculate values of every flipflop and the output and save them in a temp array
    bool bTempReg[10];
    bTempReg[0] = *itInput ^ ( bShiftReg[ 4 ] ^ bShiftReg[ 8 ] );
    bTempReg[1] = bShiftReg[0];
    bTempReg[2] = bShiftReg[1];
    bTempReg[3] = bShiftReg[2];
    bTempReg[4] = bShiftReg[3];
    bTempReg[5] = bShiftReg[4];
    bTempReg[6] = bShiftReg[5];
    bTempReg[7] = bShiftReg[6];
    bTempReg[8] = bShiftReg[7];
    bTempReg[9] = bShiftReg[8] ^ bShiftReg[9];
    *itOutput = bShiftReg[ 9 ];

    // assign values of the temp array to the flipflops
    for( unsigned char ucIndex = 0; ucIndex < 10; ucIndex++ )
    {
        bShiftReg[ ucIndex ] = bTempReg[ ucIndex ];
    }

    /*cout<<"\n Schift Reg: ";
    for( int i=0;i<10;i++)
    { cout << " " << bShiftReg[i]; }

    cout<<" Output: " << *itOutput;*/

    itOutput++;
}
cout<<"\n Output: ";
for( itOutput = vbOutput.begin(); itOutput < vbOutput.end(); itOutput++)
    cout << " " << *itOutput;

cout<<endl<<endl;

// Decoder -----------------------------------------------------------------------------------------------------------------------------------

cout<< endl <<" Decoder "<< endl;

// load the old ouput to the new input 
vbInput = vbOutput;

cout<<"\n Input: ";
for( itInput = vbInput.begin(); itInput < vbInput.end(); itInput++)
    cout << " " << *itInput;

// reset the shift reg
for(int i = 0;i<10;i++) bShiftReg[i] = 1;

// set output iterator to the begin of the vector
itOutput = vbOutput.begin();

for( itInput = vbInput.begin(); itInput < vbInput.end(); itInput++)
{
    // calculate values of every flipflop and the output and save them in a temp array
    bool bTempReg[10];
    bTempReg[0] = *itInput;
    bTempReg[1] = bShiftReg[ 0 ] ^ *itInput;
    bTempReg[2] = bShiftReg[1];
    bTempReg[3] = bShiftReg[2];
    bTempReg[4] = bShiftReg[3];
    bTempReg[5] = bShiftReg[4];
    bTempReg[6] = bShiftReg[5];
    bTempReg[7] = bShiftReg[6];
    bTempReg[8] = bShiftReg[7];
    bTempReg[9] = bShiftReg[8];
    *itOutput = ( ( *itInput ^ bShiftReg[0] ) ^ bShiftReg[5] ) ^ bShiftReg[9];

    // assign values of the temp array to the flipflops
    for( unsigned char ucIndex = 0; ucIndex < 10; ucIndex++ )
    {
        bShiftReg[ ucIndex ] = bTempReg[ ucIndex ];
    }

    /*cout<<"\n Schift Reg: ";
    for( int i=0;i<10;i++)
    { cout << " " << bShiftReg[i]; }
    cout<<" Output: " << *itOutput;*/

    itOutput++;
}
cout<<"\n Output: ";
for( itOutput = vbOutput.begin(); itOutput < vbOutput.end(); itOutput++)
    cout << " " << *itOutput;

cout<<endl<<endl;


return 0;
}

控制台输出:

编码器

输入:1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

输出:1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1

解码器

输入:1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 输出:0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0

我不确定转移和写入输出的顺序,但无论哪种方式都不起作用。非常感谢您的帮助,谢谢!

编辑:新版本的代码和控制台输出。现在解扰器的输出看起来与扰频器的输入相似,但它是旋转的,有 8 个而不是 10 个。如果我使输出向量更长,例如到 40 位。

【问题讨论】:

  • 我对如何调试的第一个想法是在纸上进行,并将结果与​​程序给出的结果进行比较。这工作很乏味,所以我把它委托给你。让我们知道进展...
  • 问题是为什么我在编码和解码后没有得到源序言=)。或者为什么它不起作用。我将尝试在纸上执行此操作。
  • 新版本效果不错。您只需要忽略解码器输出的前 10 位(正如 Dysaster 指出的那样),因为它们是初始化的一部分,并且对于任何输入都是相同的,只要初始化相同(在您的情况下都是相同的)。重要的是他们之后发生的事情。在每个给定的输入之后,您需要为(解)扰频器提供额外的 10 位,这样输入位就不会在寄存器中丢失。我想最后 10 个零只是为了这个目的,而真正的测试输入只有 10 个 1 和 10 个零。
  • 好吧,我在加扰器的输入中添加了额外的 10 位,并为解扰器提供了加扰器的 10:40 位和 10 个零(见主帖),但不幸的是没有成功。
  • 不要省略解码器输入的前 10 位。它们很重要。忽略解码器输出的前 10 位。

标签: c++ shift


【解决方案1】:

我还没有阅读代码的解码部分,但是在编码中,有一个大问题:您在执行移位之后 计算位 0 和 9,这是不正确的。您需要在移动主寄存器之前计算它们,将它们保存在临时变量中(实际上写 #9 是安全的,但不是 #0),移动 LFSR,将计算的位放回。

您现在所做的实际上是使用位 3 和 7 作为分接点,并将位 #9 计算为 bit#7 XOR bit#9 而不是指定的算法。

我预计解码端会出现类似错误,但没有检查。

【讨论】:

  • 谢谢!我试图实现你的想法,请参考我的问题中的代码,我还发布了新的控制台输出,看起来比昨天更好,但仍然不像我需要的那样。
  • 我没有看到您在解码时丢弃前 9 或 10 位。解码器的输出端会有一些随机数据,直到输入的第一位到达输出端。我将再次检查实现,看看是否能找到其他任何东西。
  • 在解码端,您在转换之前更新bShiftReg[1],除了所需的单元格之外,这实际上更新了bShiftReg[2]。由于还有临时文件,这可能是复制/粘贴错误。
  • 我确实在解码器部分的第二个 for 循环中重置了寄存器。我在解码时发现了另一个错误 - 在 bShiftReg[ 0 ] = *itInput; 之后计算输出使语句 *itOutput = ( ( *itInput ^ bShiftReg[0] ) ^ bShiftReg[5] ) ^ bShiftReg[9]; 在 XOR 关系中有两个相等的值,这是不正确的。我当前的解码器版本是这样的:cife.de/img/snrzi3.gif,解码器输出“1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0”,即 8 个与起始序列相比太多了。我试图移动计算但没有成功。
  • 我的意思是,由于您在开始时将所有寄存器位重置为 1,因此您的第一位编码数据应该需要 9 或 10 次迭代才能到达解码器输出。无论您编码什么,我都希望这些第一位是相同的,因为它们不依赖于您的编码数据。所以你需要在记录解码输出之前丢弃一些输出。实际上同样的事情也发生在编码器端。
【解决方案2】:

好的,我发现了一个可能的错误。解码时,您在移位所有寄存器后计算输出,但在编码时,您在移位之前计算输出。是哪一个?不,我错了,第二次尝试:

编辑:想象一下输出只是另一个寄存器。我认为您需要计算输出值作为每个循环中的第一个操作。之后,计算所有寄存器的值。之后将这些值分配给寄存器。在计算所有值之前不要分配值。

底线:首先计算所有值,然后才分配所有值。在一般情况下,这意味着使用临时变量。只有在没有循环的情况下,您才能避免使用 temps。

解决方案:引入另一组寄存器(bTempReg),有 11 行代码,您为每个 bTempReg[0..9] 和输出分配一个值,然后在 mini-loop[0..9]将 bTempReg 的值赋回 bShiftReg。

【讨论】:

  • 你的意思是在源代码中还是在图纸中?实际上我在解码和编码移位后计算输出。我之前也尝试过,但效果不佳。
  • 我的意思是在代码中。再看代码。在编码中,您在 mini-for 循环之前将值分配给 *itOutput,而在解码中,您在循环之后分配它。我不知道哪种方法是正确的,但编码和解码必须相同。
  • 是的,但是迷你 for 循环只包含一个 cout 控制台输出,而不是 shift 操作。
  • 哎呀,你是对的。我仍然认为操作顺序是这里的问题。考虑在解码时 reg(0) 从输入中获取值,然后 reg(0) 和输入在输出中都被异或。没有意义。
  • 这是一个很好的逻辑想法,谢谢!你的意思是这样的:cife.de/img/snrzi2.gif?然后加扰器输出“1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 0”这是不可能的,因为加扰器的想法是打破那些长的一和零序列。
猜你喜欢
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2018-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-11
  • 2020-11-21
相关资源
最近更新 更多