我在为序列(模式)获取正确的LFSR时遇到一些问题,当我将其实现为LFSR和相应的点击时,它不会生成序列,是否有任何建议?目标patt是{1,1,0,0,0,0,1,0,1,0,0,1,1};
我的代码遵循维基百科的二进制字段版本(https://en.wikipedia.org/wiki/Berlekamp%E2%80%93Massey_algorithm):
#include <stdio.h>
int main()
{
int patt[]={1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1};
int n=sizeof(patt)/sizeof(int);
int N=0, L=0, m=-1, b[n], c[n], d=0, t[n], j;
b[0]=1;
c[0]=1;
float val;
for(int i=1; i<n; i++){
b[i]=0;
c[i]=0;
//printf("b[%d]=%d, c[%d]=%d; ",i,b[i],i,c[i]);
}
while (N < n){
printf("N=%d, ",N);
d=c[0]*patt[N];//initializing the value of d
for(int i=1; i<=L; i++){
//printf("d = %d + %d*%d, ",d,c[i],patt[N-L]);
d=d ^ c[i]*patt[N-L];
//printf("d=%d \n",d);
}
printf("d=%d\n", d);
if (d==0){
printf("c=c\n\n");
}
else{
for(int i=0; i<n; i++){
t[i]=c[i];
}
j=0;
while(N-m+j<=n-1){
printf("c[%d-%d+%d]=c[%d-%d+%d]^b[%d]; c[%d]=c[%d]^b[%d], %d=%d^%d; ", N, m, j, N, m, j, j, N-m+j, N-m+j, j, c[N-m+j], c[N-m+j], b[j]);
c[N-m+j]=c[N-m+j]^b[j];//XOR operator: ^
printf("c=%d\n",c[N-m+j]);
j++;
}
printf("\n");
val=N;
val=val/2;
printf("L=%d, N=%d, N/2=%f \n",L, N, val);
if(L<= val){
printf("updating L, m & b\n\n");
L=N+1-L;
m=N;
for(int i=0; i<n; i++){
b[i]=t[i];
}
}
}
N++;
}
int CiSi=c[L]*patt[0];;
for(int i=1; i<L; i++){
CiSi=CiSi ^ c[L-i]*patt[i];//XORing
}
printf("CiSi = %d;", CiSi);
printf("c=");
for(int i=0; i<n; i++){
printf("%d ",c[i]);
}
return 0;
}
每个周期的答案:
N=0, d=1
c[0--1+0]=c[0--1+0]^b[0]; c[1]=c[1]^b[0], 0=0^1; c=1
c[0--1+1]=c[0--1+1]^b[1]; c[2]=c[2]^b[1], 0=0^0; c=0
c[0--1+2]=c[0--1+2]^b[2]; c[3]=c[3]^b[2], 0=0^0; c=0
c[0--1+3]=c[0--1+3]^b[3]; c[4]=c[4]^b[3], 0=0^0; c=0
c[0--1+4]=c[0--1+4]^b[4]; c[5]=c[5]^b[4], 0=0^0; c=0
c[0--1+5]=c[0--1+5]^b[5]; c[6]=c[6]^b[5], 0=0^0; c=0
c[0--1+6]=c[0--1+6]^b[6]; c[7]=c[7]^b[6], 0=0^0; c=0
c[0--1+7]=c[0--1+7]^b[7]; c[8]=c[8]^b[7], 0=0^0; c=0
c[0--1+8]=c[0--1+8]^b[8]; c[9]=c[9]^b[8], 0=0^0; c=0
c[0--1+9]=c[0--1+9]^b[9]; c[10]=c[10]^b[9], 0=0^0; c=0
c[0--1+10]=c[0--1+10]^b[10]; c[11]=c[11]^b[10], 0=0^0; c=0
c[0--1+11]=c[0--1+11]^b[11]; c[12]=c[12]^b[11], 0=0^0; c=0
L=0, N=0, N/2=0.000000
updating L, m & b
N=1, d=0
c=c
N=2, d=1
c[2-0+0]=c[2-0+0]^b[0]; c[2]=c[2]^b[0], 0=0^1; c=1
c[2-0+1]=c[2-0+1]^b[1]; c[3]=c[3]^b[1], 0=0^0; c=0
c[2-0+2]=c[2-0+2]^b[2]; c[4]=c[4]^b[2], 0=0^0; c=0
c[2-0+3]=c[2-0+3]^b[3]; c[5]=c[5]^b[3], 0=0^0; c=0
c[2-0+4]=c[2-0+4]^b[4]; c[6]=c[6]^b[4], 0=0^0; c=0
c[2-0+5]=c[2-0+5]^b[5]; c[7]=c[7]^b[5], 0=0^0; c=0
c[2-0+6]=c[2-0+6]^b[6]; c[8]=c[8]^b[6], 0=0^0; c=0
c[2-0+7]=c[2-0+7]^b[7]; c[9]=c[9]^b[7], 0=0^0; c=0
c[2-0+8]=c[2-0+8]^b[8]; c[10]=c[10]^b[8], 0=0^0; c=0
c[2-0+9]=c[2-0+9]^b[9]; c[11]=c[11]^b[9], 0=0^0; c=0
c[2-0+10]=c[2-0+10]^b[10]; c[12]=c[12]^b[10], 0=0^0; c=0
L=1, N=2, N/2=1.000000
updating L, m & b
N=3, d=0
c=c
N=4, d=0
c=c
N=5, d=0
c=c
N=6, d=1
c[6-2+0]=c[6-2+0]^b[0]; c[4]=c[4]^b[0], 0=0^1; c=1
c[6-2+1]=c[6-2+1]^b[1]; c[5]=c[5]^b[1], 0=0^1; c=1
c[6-2+2]=c[6-2+2]^b[2]; c[6]=c[6]^b[2], 0=0^0; c=0
c[6-2+3]=c[6-2+3]^b[3]; c[7]=c[7]^b[3], 0=0^0; c=0
c[6-2+4]=c[6-2+4]^b[4]; c[8]=c[8]^b[4], 0=0^0; c=0
c[6-2+5]=c[6-2+5]^b[5]; c[9]=c[9]^b[5], 0=0^0; c=0
c[6-2+6]=c[6-2+6]^b[6]; c[10]=c[10]^b[6], 0=0^0; c=0
c[6-2+7]=c[6-2+7]^b[7]; c[11]=c[11]^b[7], 0=0^0; c=0
c[6-2+8]=c[6-2+8]^b[8]; c[12]=c[12]^b[8], 0=0^0; c=0
L=2, N=6, N/2=3.000000
updating L, m & b
N=7, d=0
c=c
N=8, d=1
c[8-6+0]=c[8-6+0]^b[0]; c[2]=c[2]^b[0], 1=1^1; c=0
c[8-6+1]=c[8-6+1]^b[1]; c[3]=c[3]^b[1], 0=0^1; c=1
c[8-6+2]=c[8-6+2]^b[2]; c[4]=c[4]^b[2], 1=1^1; c=0
c[8-6+3]=c[8-6+3]^b[3]; c[5]=c[5]^b[3], 1=1^0; c=1
c[8-6+4]=c[8-6+4]^b[4]; c[6]=c[6]^b[4], 0=0^0; c=0
c[8-6+5]=c[8-6+5]^b[5]; c[7]=c[7]^b[5], 0=0^0; c=0
c[8-6+6]=c[8-6+6]^b[6]; c[8]=c[8]^b[6], 0=0^0; c=0
c[8-6+7]=c[8-6+7]^b[7]; c[9]=c[9]^b[7], 0=0^0; c=0
c[8-6+8]=c[8-6+8]^b[8]; c[10]=c[10]^b[8], 0=0^0; c=0
c[8-6+9]=c[8-6+9]^b[9]; c[11]=c[11]^b[9], 0=0^0; c=0
c[8-6+10]=c[8-6+10]^b[10]; c[12]=c[12]^b[10], 0=0^0; c=0
L=5, N=8, N/2=4.000000
N=9, d=0
c=c
N=10, d=0
c=c
N=11, d=0
c=c
N=12, d=1
c[12-6+0]=c[12-6+0]^b[0]; c[6]=c[6]^b[0], 0=0^1; c=1
c[12-6+1]=c[12-6+1]^b[1]; c[7]=c[7]^b[1], 0=0^1; c=1
c[12-6+2]=c[12-6+2]^b[2]; c[8]=c[8]^b[2], 0=0^1; c=1
c[12-6+3]=c[12-6+3]^b[3]; c[9]=c[9]^b[3], 0=0^0; c=0
c[12-6+4]=c[12-6+4]^b[4]; c[10]=c[10]^b[4], 0=0^0; c=0
c[12-6+5]=c[12-6+5]^b[5]; c[11]=c[11]^b[5], 0=0^0; c=0
c[12-6+6]=c[12-6+6]^b[6]; c[12]=c[12]^b[6], 0=0^0; c=0
L=5, N=12, N/2=6.000000
updating L, m & b
CiSi = 0;
CiSi = 0;测试作为算法结果提到的值看起来是正确的,因为它等于零,但是
c=1 1 0 1 0 1 1 1 1; excluding the last 4 zeros due to their values as zeros
c = 1 1 0 1 0 1 1 1 1,这是从左到右开始的多项式的系数:C0,...,Ck:1 + x ^ 2 + x ^ 4 + x ^ 5 + x ^ 6 + x ^ 7
当我实现此值时,结果不正确
LFSR的实施与相应位置的抽头,x0被排除在https://en.wikipedia.org/wiki/Linear-feedback_shift_register以及王颂泰,吴承文和W.小青,&#34; VLSI测试原理和架构之外 - 可测试性设计&#34;,2006:
%Matlab source code
clear all;
seed=[1 1 0 0 0 0 1 0];
seed_sz=size(seed);
%Loop to initialize a array
for i=1:50
A{i}=1:seed_sz(1,2);
A{i}(1,1:end)=0;
end
filename='LFSR rightshift no x0 c program.xlsx';
for i=1:50
A{i}=seed;
xlswrite(filename,A{i},'1',['A',int2str(i)]);
XOR_output=xor(seed(1,8),seed(1,7));
XOR_output=xor(XOR_output,seed(1,6));
XOR_output=xor(XOR_output,seed(1,5));
XOR_output=xor(XOR_output,seed(1,3));
XOR_output=xor(XOR_output,seed(1,1));
%Right shift the seed
seed=circshift(seed,1);
seed(1,1)=XOR_output;
end
答案 0 :(得分:3)
与它旨在实现的Wikipedia pseudocode相比,问题的代码有两个明显的差异(至少第二个是致命的错误):
d=c[0]*patt[N]
应为d=patt[N]
以匹配 d←s N ... d=d ^ c[i]*patt[N-L]
应为d=d ^ c[i]*patt[N-i]
以匹配 d←s N ⊕c 1 s N的其他项-1 子>⊕ç<子> 2 子>取值<子> N-2 子>⊕...⊕ç<子>→子>取值<子> N-L 子> 除此之外,代码不会显示最终的L
,即流的最小LFSR的长度。但是L
也是输出中最后1
的索引,所以我们可以省略这些遗漏。
通过这些更改,代码输出c=1 0 1 0 1 1 0 0 0 0 0 0 0
,即L
= 5位的LFSR和重复 s i ←s i- 2 ⊕s i-4 ⊕s i-5 ,或等效 s i + 5 ←小号<子> i + 3中子>⊕小号<子> i + 1的子>⊕小号<子> I 子> 的。这确实符合序列!应用于5个第一个给定的术语,它计算接下来的8个术语:
s[ 0] := 1
s[ 1] := 1
s[ 2] := 0
s[ 3] := 0
s[ 4] := 0
s[ 5] := s[ 3] ^ s[ 1] ^ s[ 0] = 0 ^ 1 ^ 1 = 0
s[ 6] := s[ 4] ^ s[ 2] ^ s[ 1] = 0 ^ 0 ^ 1 = 1
s[ 7] := s[ 5] ^ s[ 3] ^ s[ 2] = 0 ^ 0 ^ 0 = 0
s[ 8] := s[ 6] ^ s[ 4] ^ s[ 3] = 1 ^ 0 ^ 0 = 1
s[ 9] := s[ 7] ^ s[ 5] ^ s[ 4] = 0 ^ 0 ^ 0 = 0
s[10] := s[ 8] ^ s[ 6] ^ s[ 5] = 1 ^ 1 ^ 0 = 0
s[11] := s[ 9] ^ s[ 7] ^ s[ 6] = 0 ^ 0 ^ 1 = 1
s[12] := s[10] ^ s[ 8] ^ s[ 7] = 0 ^ 1 ^ 0 = 1
解释程序的输出:
1
告诉LFSR的宽度,其余的应该被忽略; 1
数字(最左边的数字)对应于Fibonnaci LFSR中从最新到最旧的XOR条款; 1
,对应于下一个计算的术语; 1
数字对应于从 1 到 x L 的斐波那契多项式项(这里, 1 + x 2 + x 4 + x 5 ),或等效于来自Galois多项式的项 x L 到 1 (此处, x 5 + x 3 + X 1 1 ) Fibonacci惯例中的初始状态只是给定 s i 的第一个L
项,即问题代码中的patt[i]
以下是代码的简化版本,输出更少且更清晰,仔细阅读for
以澄清意图,坚持原始伪代码中的变量名称,与更多C编译器兼容, 使用尽可能使用布尔运算符,远离浮点,并使用最小化结束条件进行循环 。在我做的几个测试中似乎工作得很好。
// Berlekamp-Massey algorithm per https://en.wikipedia.org/w/index.php?title=Berlekamp%E2%80%93Massey_algorithm&oldid=808089047#The_algorithm_for_the_binary_field
#include <stdio.h>
int main(void) {
int s[]={1,1,0,0,0,0,1,0,1,0,0,1,1}; // bits of the stream to analyse
#define n (sizeof(s)/sizeof(*s)) // how many bits there are
int b[n], c[n], t[n], d, j, N, L=0, m=-1;
for(j=n; --j>0;)
b[j]=c[j]=0;
b[0]=c[0]=1;
for(N=0; N<n; ++N) { // For N=0 step 1 while N<n
d=s[N]; // first term of discrepancy
for(j=L; j>0; --j) // other terms of discrepancy
d ^= c[j]&s[N-j];
if (d!=0) { // non-zero discrepancy
for(j=n; --j>=0;) // copy c to t
t[j]=c[j];
for(j=n-N+m; --j>=0;) // XOR b (reversed) into c
c[N-m+j] ^= b[j];
if(L+L<=N) { // if L<=N/2
L=N+1-L;
m=N;
for(j=n; --j>=0;) // copy t to b
b[j]=t[j];
}
}
}
printf("s ="); // show input
for(j=0; j<n; j++)
printf(" %d",s[j]);
printf("\nc =");
for(j=0; j<=L; j++) // show result
printf(" %d",c[j]);
printf("\nL = %d\n",L); // show degree of polynomial
return 0;
}
// The above code outputs the following:
// s = 1 1 0 0 0 0 1 0 1 0 0 1 1
// c = 1 0 1 0 1 1
// L = 5
我对维基百科的伪代码及其对代码的转录有一个批评:在分析 s i 的序列中,索引正朝着相反的方向运行,正在构造的多项式< EM> C <子> I 子> 的;这似乎只会造成并发症。
答案 1 :(得分:1)
补充fgrieu的答案。 Fibonacci和Galois LFSR的代码,显示左移和右移算法。这些将产生原始字符串加上2位(0 1),这是一个15位重复模式。起始LFSR值不同,以使输出模式与原始字符串模式匹配。
// Fibonacci LFSR right shift
printf("fr=");
d = 0x03;
do {
printf(" %1x", d & 1);
m = ((d>>3)^(d>>1)^(d>>0))&1;
d = (d >> 1)|(m << 4);
} while (d != 0x3);
printf("\n");
// Fibonacci LFSR left shift
printf("fl=");
d = 0x18;
do {
printf(" %1x", d >> 4);
m = ((d>>4)^(d>>3)^(d>>1)) & 1;
d = ((d << 1)&0x1e) | m;
} while (d != 0x18);
printf("\n");
// Galios LFSR right shift
printf("gr=");
d = 0x1f;
do {
printf(" %1x", d & 1);
m = d & 1;
d >>= 1;
if (m)
d ^= 0x1a;
} while (d != 0x1f);
printf("\n");
// Galios LFSR left shift
printf("gl=");
d = 0x1f;
do {
printf(" %1x", d >> 4);
d <<= 1;
if (d & 0x20)
d ^= 0x2b;
} while (d != 0x1f);
printf("\n");
输出:
fr= 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1
fl= 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1
gr= 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1
gl= 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1