简易通信工程实现详解
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
第一章 数据源的产生(m序列)
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
m序列是最长线性反馈移位寄存器序列的简称。它是由带线性反馈的移存器产生的周期最长的序列。一般来说,一个n级线性反馈移存器可能产生的最长周期等于(2^n -1)。
m序列是一种典型的伪随机序列。在通信领域有着广泛的应用,如扩频通信、卫星通信的码分多址(CDMA),数字数据中的加密、加扰、同步、误码率测量等领域
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是m序列?
m序列是最长线性移位寄存器序列的简称,是一种伪随机序列、伪噪声(PN)码或伪随机码。可以预先确定并且可以重复实现的序列称为确定序列;既不能预先确定又不能重复实现的序列称随机序列;不能预先确定但可以重复产生的序列称伪随机序列。
二、伪随机序列
通过一定的算法对事先选定的随机种子(seed)做一定的运算可以得到一组人工生成的周期序列,在这组序列中以相同的概率选取其中一个数字,该数字称作伪随机数,由于所选数字并不具有完全的随机性,但是从实用的角度而言,其随机程度已足够了。这里的“伪”的含义是,由于该随机数是按照一定算法模拟产生的,其结果是确定的,是可见的,因此并不是真正的随机数。伪随机数的选择是从随机种子开始的,所以为了保证每次得到的伪随机数都足够地“随机”,随机种子的选择就显得非常重要,如果随机种子一样,那么同一个随机数发生器产生的随机数也会一样。
1. 由LFSR引出的产生方法
产生伪随机数的方法最常见的是利用一种线性反馈移位寄存器(LFSR),它是由n个D触发器和若干个异或门组成的,如下图:
其中,gn为反馈系数,取值只能为0或1,取为0时表明不存在该反馈之路,取为1时表明存在该反馈之路;n个D触发器最多可以提供2^n-1个状态(不包括全0的状态),为了保证这些状态没有重复,gn的选择必须满足一定的条件。下面以n=3,g0=1,g1=1,g2=0,g3=1为例,说明LFSR的特性,具有该参数的LFSR结构如下图:
假设在开始时,D2D1D0=111(seed),那么,当时钟到来时,有:
D2=D1_OUT=1;
D1=D0_OUT^D2_OUT=0;
D0=D2_OUT=1;
即D2D1D0=101;同理,又一个时钟到来时,可得D2D1D0=001. ………………
画出状态转移图如下:
从图可以看出,正好有2^3-1=7个状态,不包括全0;
如果您理解了上图,至少可以得到三条结论:
1)初始状态是由SEED提供的;
2)当反馈系数不同时,得到的状态转移图也不同;必须保证gn===1,否则哪来的反馈?
3)D触发器的个数越多,产生的状态就越多,也就越“随机”;
2.FPGA实现
基于以上原理,下面用verilog产生一个n=8,反馈系数为g0g1g2g3g4g5g6g7g8=101110001的伪随机数发生器,它共有2^8=255个状态,该LFSR的结构如下:
verilog源代码如下:
module RanGen(
input rst_n, /*rst_n is necessary to prevet locking up*/
input clk, /*clock signal*/
input load, /*load seed to rand_num,active high */
input [7:0] seed,
output reg [7:0] rand_num /*random number output*/
);
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
rand_num <=8'b0;
else if(load)
rand_num <=seed; /*load the initial value when load is active*/
else
begin
rand_num[0] <= rand_num[7];
rand_num[1] <= rand_num[0];
rand_num[2] <= rand_num[1];
rand_num[3] <= rand_num[2];
rand_num[4] <= rand_num[3]^rand_num[7];
rand_num[5] <= rand_num[4]^rand_num[7];
rand_num[6] <= rand_num[5]^rand_num[7];
rand_num[7] <= rand_num[6];
end
end
endmodule
3.MATLAB实现
function p=PnCode(ploynomial,reg)
% PN码产生器函数
% ploynomial和长度=reg的长度+1,ploynomial的值不能为全0
% ploynomial为本原多项式,从左到右依次为高位到低位,且最高位与最低位必须为1;低位表示延时一个周期,高位依次顺延
% reg为寄存器初始值,也相当于PN码的初始相位,左边为高位,如[10010]表示延时5个周期的寄器和2个周期的寄存器初值为1
% 如产生5级31位的PN码,则多项式形式为[1 * * * * 1]
% 例:从西安电子科技大学.查光明.著的《扩频通信]》中查出5级PN码45E,参数为[1 0 0 1 0 1],左边为高位
% PN:0 1 0 0 0 0 1 0 1 0 1 1 1 0 1 1 0 0 0 1 1 1 1 1 0 0 1 1 0 1 0
grade=length(ploynomial)-1;%根据多项式计算延时级数
PN_Length=(2^grade-1); %计算PN码一个周期的长度
pn=zeros(1,PN_Length); %设置PN码寄存器初值
%找出本原多项式中除最低位外为1的位,并依次存放在寄存器c中
%例如对于ploynomial=[1 0 0 1 0 1],则c(1)=2,c(2)=5
p=0;
c=zeros(1,grade);
for i=grade:-1:1
if ploynomial(i)==1
p=p+1;
c(p)=grade+1-i;
end
end
%产生一个周期的PN码
q=0;
for i=1:PN_Length
%从最高延时的寄存器中输出PN码
p(i)=reg(1);
%定位第一个抽头寄存器位置,并取值
m=reg(grade+1-c(1));
%完成各抽头寄存器取值的模2加
for q=2:grade
if (c(q)>0) & (reg(grade+1-c(q))==1)
m=~m;
end
end
%寄存器的值依次移位
for q=1:(grade-1)
reg(q)=reg(q+1);
end
reg(5)=m;
end
4.通信例程MATLAB代码展示
coef = [1 0 0 1 0 0 1 0 0 1 0 0 0 1 0]; %初始相位
m = length(coef);
len = 2^m-1;
backQ = 0;
seq = zeros(1,len);
registers = [1 zeros(1,m-2) 1];
for i = 1:len
seq(i) = registers(m);
backQ = mod(sum(coef.*registers),2);
registers(2:length(registers)) = registers(1:length(registers)-1);
registers(1) = backQ;
end