OFDM802.11a的FPGA实现(十)导频插入(含verilog和matlab代码)

原文链接(相关文章合集)OFDM 802.11a的xilinx FPGA实现

1.前言

前面一篇文章完成了星座图的映射,今天继续设计后面的模块。在接收机当中,虽然利用接收到的短/长训练序列,能够进行信道均衡,频偏校正,但符号还会存在一定的剩余频率偏差,并且偏差会随着时间的积累而累积,会造成所有子载波产生一定的剩余相位偏转。因此,还需要不断的对参考相位进行跟踪。要实现这一功能,需要在 52 个非零子载波中插入 4 个导频符号。

2.插入导频原理

Data 域的数据经过星座图映射后形成对应的复数值,每个 OFDM 符号周期可以通过 48 个子信道发出 48 个调制后的数据,所以把这些值每 48 个分成一组,每一组将对应一个 OFDM 符号。

OFDM子载波

子载波的数量一共有 53 个,每个子载波的标号为-26,-25,…,-1,0,1,…,26。其中 48 个复数数据分别对应到-26 至-22,-20 至-8,-6至-1,1 至 6,8 至 20,以及 20 至 26 这些子载波上,四个导频子信道分别对应到-21,-7,7 和 21 这 4 个子载波上。0 号子载波上填充零值(直流)。

导频所在位置

导频所处位置的值,是根据一个循环的导频的极性控制序列来完成的,该极性控制序列如下:

导频极性

每个导频极性对应一个OFDM符号,比如第一个OFDM符号也就是signal域的符号,其导频极性控制为1,那么其输出导频位置所给的值就位1 1 1 -1,又比如第5个OFDM符号,也就是第4个data域的OFDM符号,其极性控制为-1,那么其导频位置所给的值就位-1 -1 -1 1。依此类推。当p为“一1”时,对应的OFDM符号的导频符号需要改变极性(-1→+1;+1→-1);当p 为“1”时,对应的OFDM符号的导频符号不需要改变极性。p可以通过标准中所规定的扰码器(Scrambler)来产生。

扰码器

只不过,此模块扰码器的初始状态设为{1,1,1,1,1,1,1}。

3.硬件实现

导频插入模块的硬件实现框图

图中,SPI_DIN为导频模块输入数据,INDEX_IN为输入数据标号,从0到47。扰码器(Scrambler)产生导频的极性控制信号,扰码器初始状态设为7’b1111111。4个导频依次为1,1,1,-1。输入数据标号INDEX_IN通过LUT模块进行变换生成写入RAM 的地址,输入计数0到47映射为52个子载波,中间插入4个导频符号。因为导频插入模块输出到一个64位的 IFFT模块,一个模64的计数器用来生成输出地址。双口 RAM 暂时存放输入的信号。

由于导频插入模块之后是IFFT模块,因此本模块在具体实现时通过ROM 进行了数据顺序变换,使得数据输出时顺序变为符合IFFT输入的要求。例如,当使用64点的IFFT时,输入的48个数据(标号为0至47)的标号首先按照如下公式进行变换,映射为-26至26,其中标号-21,-7,7,21即为插入导频处(k为输入数据标号):

M ( k ) = { k − 26 , 0 ≤ k ≤ 4 k − 25 , 5 ≤ k ≤ 17 k − 24 , 18 ≤ k ≤ 23 k − 23 , 24 ≤ k ≤ 29 k − 22 , 30 ≤ k ≤ 42 k − 21 , 43 ≤ k ≤ 47 M(k) = \begin{cases} k-26,0 \leq k \leq 4 \\ \\k-25 ,5\leq k\leq 17\\ \\k-24 ,18\leq k\leq 23\\ \\k-23 ,24\leq k\leq 29\\ \\k-22 ,30\leq k\leq 42\\ \\k-21 ,43\leq k\leq 47 \end{cases} M(k)= k26,0k4k25,5k17k24,18k23k23,24k29k22,30k42k21,43k47
根据协议中对IFFT输入端口映射的规定,将变换后M(k)为1至26的子载波映射到IFFT的输入端口1至26,M(k)为一26至一1的子载波映射到IFFT的端口38到63,而剩下的端口27至37和0则置为零值。此映射的描述如下图所示。

IDFT输入与输出

相应的,插入导频的位置-21,-7,7,21分别对应到IFFT的输入端口43,57,21,7。编程实现时,根据导频极性,在这4个位置上插入导频。因此,结合上述两步,写入RAM中的数据标号的变换可直接用下式实现:
M ( k ) = { k + 38 , 0 ≤ k ≤ 4 k + 39 , 5 ≤ k ≤ 17 k + 40 , 18 ≤ k ≤ 23 k − 23 , 24 ≤ k ≤ 29 k − 22 , 30 ≤ k ≤ 42 k − 21 , 43 ≤ k ≤ 47 M(k) = \begin{cases} k+38,0 \leq k \leq 4 \\ \\k+39 ,5\leq k\leq 17\\ \\k+40 ,18\leq k\leq 23\\ \\k-23 ,24\leq k\leq 29\\ \\k-22 ,30\leq k\leq 42\\ \\k-21 ,43\leq k\leq 47 \end{cases} M(k)= k+38,0k4k+39,5k17k+40,18k23k23,24k29k22,30k42k21,43k47

在设计上,采用乱序写,顺序读的方式。先定义1个位宽为16的RAM,对输入数据的实数和虚数按Index序号通过上面公式变换后,存入RAM中。再通过扰码器产生的极性控制信号,对导频是否极性变换做处理,极性处理后,将导频信号写入对应RAM地址空间中。最后,以顺序方式从RAM中读取数据。为保证流水线处理,以及写入写出不发生冲突,RAM的深度需设置为2个OFDM符号的长度,使用乒乓缓存操作(前面文章乒乓缓存操作的链接)。

在对数据域进行调制的时候,导频控制序列是从地址1开始累加,直到处理完126个OFDM符号是,这是导频控制序列读取到第126个,然后才会回到0,然后从0~126循环,因为在802.11a当中,第一个OFDM符号是signal域的符号,data域是从第二个符号开始。

插入导频模块的输入输出如下图所示:

4.Matlab仿真

  以2个OFDM符号,16-QAM调制,编码效率为3/4,进行仿真,生成测试数据共计288个,如下:

test_data =

  列 1 至 27

     0     0     0     0     1     1     1     0     0     0     1     1     1     1     1     1     0     0     1     1     1     1     0     0     0     0     1

  列 28 至 54

     0     1     1     1     0     0     1     0     0     1     0     1     1     0     0     1     1     0     0     1     0     1     0     1     0     1     0

  列 55 至 81

     1     0     0     0     1     0     1     1     1     0     1     0     0     1     1     1     1     0     1     1     1     0     1     1     0     0     0

  列 82 至 108

     0     0     1     1     0     0     1     0     0     1     1     1     1     0     0     1     1     0     1     0     1     0     0     1     1     0     0

  列 109 至 135

     1     0     1     1     0     1     0     1     1     1     0     0     1     1     1     0     1     0     1     0     1     0     1     0     1     0     1

  列 136 至 162

     1     0     0     0     0     1     1     0     0     0     1     0     1     1     1     0     1     0     0     1     1     1     1     0     1     0     0

  列 163 至 189

     0     1     0     0     0     0     0     1     0     1     0     0     1     1     1     1     1     0     1     1     1     0     0     1     0     1     1

  列 190 至 216

     1     1     1     1     0     0     0     0     0     1     0     1     1     0     0     1     0     1     0     1     0     1     1     1     1     0     0

  列 217 至 243

     1     1     1     1     0     0     1     0     0     1     1     1     0     1     0     0     0     0     1     1     1     0     0     0     1     1     1

  列 244 至 270

     1     1     0     1     1     0     1     1     0     0     1     0     0     0     0     1     1     0     0     0     0     1     1     0     0     0     1

  列 271 至 288

     0     0     0     0     0     1     1     0     0     1     1     1     0     0     1     1     1     0

  测试数据经过前面章节的扰码、编码、删余、交织、调制映射,然后进行如下的插入导频:

%% 插入导频到7,21,43,57,由于matlab下标从1开始,这里插入导频位置为8,22,44,58
%插入导频极性控制,扰码
scram_seed2 = [1,1,1,1,1,1,1];
scram_reg = scram_seed2;
scram_out = zeros(1,k);
for m = 1:k
    scram_out(m) = mod(scram_reg(1) + scram_reg(4), 2);
    scram_reg(:,1:end) = [scram_reg(:,2:end), mod(scram_reg(1) + scram_reg(4), 2)];     %扰码寄存器移位,最低位为7+4
    if(m==127)
        scram_reg = scram_seed2;%127个OFDM符号之后,扰码器恢复初始状态
    end    
end
rx_interFrq = mod_out;
interFrq_out = zeros(1,64*k);
for m = 1:k
    reg48 = rx_interFrq((m-1)*48+1:m*48);
    reg_pn = scram_out(m);
        if(reg_pn)              %当 scram_out== 0 时,不需要极性取反, 当 scram_out==1 时,需要极性取反。
            reg_interFrq = [-1,1,-1,-1];%极性取反
        else
            reg_interFrq = [1,-1,1,1];
        end
        reg64 = zeros(1,64);
        %端口映射为IFFT输入
        reg64(1+38:5+38) = reg48(1:5);
        reg64(6+39:18+39) = reg48(6:18);
        reg64(19+40:24+40) = reg48(19:24);
        reg64(25-23:30-23) = reg48(25:30);
        reg64(31-22:43-22) = reg48(31:43);
        reg64(44-21:48-21) = reg48(44:48);
        %剩下的1,28-38端口置0
        reg64(28:38) = 0;
        reg64(1) = 0;
        %插入导频8,22,44,58
        reg64(8) = reg_interFrq(1);
        reg64(22) = reg_interFrq(2);
        reg64(44) = reg_interFrq(3);
        reg64(58) = reg_interFrq(4);
        interFrq_out((m-1)*64+1:m*64) = reg64;
end

  插入导频之后输出如下:

interFrq_out =

  列 1 至 8

   0.0000 + 0.0000i  -0.9531 - 0.9531i  -0.3125 + 0.9531i   0.9531 - 0.9531i   0.3125 + 0.3125i   0.9531 + 0.3125i   0.9531 - 0.3125i   1.0000 + 0.0000i

  列 9 至 16

  -0.9531 + 0.9531i   0.3125 - 0.9531i  -0.3125 + 0.9531i  -0.9531 + 0.9531i   0.3125 - 0.9531i  -0.9531 - 0.9531i   0.3125 + 0.3125i   0.9531 + 0.9531i

  列 17 至 24

  -0.3125 - 0.9531i  -0.3125 + 0.3125i  -0.3125 + 0.3125i  -0.3125 + 0.9531i   0.9531 - 0.9531i  -1.0000 + 0.0000i   0.9531 + 0.9531i   0.9531 + 0.3125i

  列 25 至 32

  -0.3125 - 0.3125i   0.9531 - 0.3125i  -0.9531 - 0.3125i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i

  列 33 至 40

   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i  -0.9531 + 0.9531i   0.9531 + 0.3125i

  列 41 至 48

   0.3125 + 0.9531i  -0.9531 + 0.3125i  -0.9531 + 0.9531i   1.0000 + 0.0000i   0.3125 + 0.3125i   0.9531 + 0.9531i   0.9531 + 0.3125i  -0.3125 + 0.9531i

  列 49 至 56

  -0.9531 + 0.9531i   0.9531 + 0.9531i  -0.9531 - 0.3125i   0.9531 + 0.9531i  -0.3125 + 0.3125i   0.9531 + 0.3125i  -0.9531 - 0.9531i   0.3125 + 0.9531i

  列 57 至 64

   0.3125 + 0.3125i   1.0000 + 0.0000i  -0.9531 + 0.9531i  -0.9531 - 0.3125i  -0.9531 + 0.3125i  -0.3125 + 0.9531i   0.9531 + 0.9531i  -0.3125 + 0.3125i

  列 65 至 72

   0.0000 + 0.0000i  -0.9531 - 0.9531i   0.3125 + 0.3125i  -0.9531 - 0.9531i   0.3125 + 0.3125i  -0.9531 - 0.3125i  -0.3125 - 0.9531i   1.0000 + 0.0000i

  列 73 至 80

  -0.3125 + 0.3125i   0.3125 + 0.3125i  -0.3125 + 0.3125i  -0.3125 + 0.3125i   0.9531 - 0.9531i  -0.3125 - 0.3125i  -0.9531 - 0.9531i   0.3125 - 0.3125i

  列 81 至 88

  -0.9531 + 0.3125i   0.9531 + 0.3125i   0.3125 - 0.9531i   0.3125 - 0.9531i  -0.9531 + 0.9531i  -1.0000 + 0.0000i  -0.9531 - 0.3125i   0.3125 - 0.9531i

  列 89 至 96

   0.3125 - 0.9531i  -0.9531 - 0.3125i  -0.3125 + 0.3125i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i

  列 97 至 104

   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i  -0.9531 + 0.9531i   0.9531 + 0.9531i

  列 105 至 112

  -0.3125 + 0.3125i  -0.9531 - 0.3125i  -0.3125 + 0.9531i   1.0000 + 0.0000i  -0.3125 - 0.3125i  -0.9531 + 0.3125i  -0.3125 - 0.3125i   0.3125 - 0.9531i

  列 113 至 120

  -0.9531 - 0.3125i  -0.9531 + 0.9531i   0.9531 + 0.9531i  -0.9531 + 0.9531i   0.3125 - 0.3125i  -0.3125 + 0.3125i  -0.3125 + 0.9531i   0.9531 - 0.9531i

  列 121 至 128

   0.9531 + 0.9531i   1.0000 + 0.0000i   0.3125 + 0.9531i   0.9531 - 0.3125i   0.9531 + 0.3125i  -0.3125 - 0.3125i  -0.9531 + 0.3125i   0.9531 - 0.3125i

5.ModelSim仿真

硬件按照如下图所示连接进行仿真:

将前面提到的测试数据作为输入,对硬件进行测试,仿真结果如下图:

导频插入

如上图所示,在没有数据输入的空隙,将导频写入RAM对应位置。

乱序写入

如上图所示,输入数据根据标号,进行乱序写入RAM。

顺序输出

如上图所示,输出数据从RAM中顺序输出,并且另外一个缓存区可以进行数据输入,实现了乒乓缓存,以保证流水线操作。

全局仿真图

6.结果对比验证

  将ModelSim仿真结果存为txt文件,在Matlab里面读出来与Matlab的仿真结果进行比较,代码如下:

%% 插入导频
FPGA_pilot_dout = readlines('D:/FPGA/OFDM_802.11a_my/TX/matlab/pilot_data_out.txt','EmptyLineRule','skip')';
display(FPGA_pilot_dout);
FPGA_Re_pilot_dout = extractBefore(FPGA_pilot_dout,9);
FPGA_Im_pilot_dout = extractAfter(FPGA_pilot_dout,8);
display(FPGA_Re_pilot_dout);
display(FPGA_Im_pilot_dout);
q = quantizer('fixed','round','saturate',[8,6]);
FPGA_Re_pilot_dout = bin2num(q,FPGA_Re_pilot_dout);
FPGA_Im_pilot_dout = bin2num(q,FPGA_Im_pilot_dout);
FPGA_Re_pilot_dout = cell2mat(FPGA_Re_pilot_dout);
FPGA_Im_pilot_dout = cell2mat(FPGA_Im_pilot_dout);
FPGA_pilot_dout = FPGA_Re_pilot_dout + 1j*FPGA_Im_pilot_dout;
display(interFrq_out);
display(FPGA_pilot_dout);
check_pilot = FPGA_pilot_dout == interFrq_out;
display(check_pilot);

FPGA插入导频之后的输出如下:

FPGA_pilot_dout =

  列 1 至 8

   0.0000 + 0.0000i  -0.9531 - 0.9531i  -0.3125 + 0.9531i   0.9531 - 0.9531i   0.3125 + 0.3125i   0.9531 + 0.3125i   0.9531 - 0.3125i   1.0000 + 0.0000i

  列 9 至 16

  -0.9531 + 0.9531i   0.3125 - 0.9531i  -0.3125 + 0.9531i  -0.9531 + 0.9531i   0.3125 - 0.9531i  -0.9531 - 0.9531i   0.3125 + 0.3125i   0.9531 + 0.9531i

  列 17 至 24

  -0.3125 - 0.9531i  -0.3125 + 0.3125i  -0.3125 + 0.3125i  -0.3125 + 0.9531i   0.9531 - 0.9531i  -1.0000 + 0.0000i   0.9531 + 0.9531i   0.9531 + 0.3125i

  列 25 至 32

  -0.3125 - 0.3125i   0.9531 - 0.3125i  -0.9531 - 0.3125i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i

  列 33 至 40

   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i  -0.9531 + 0.9531i   0.9531 + 0.3125i

  列 41 至 48

   0.3125 + 0.9531i  -0.9531 + 0.3125i  -0.9531 + 0.9531i   1.0000 + 0.0000i   0.3125 + 0.3125i   0.9531 + 0.9531i   0.9531 + 0.3125i  -0.3125 + 0.9531i

  列 49 至 56

  -0.9531 + 0.9531i   0.9531 + 0.9531i  -0.9531 - 0.3125i   0.9531 + 0.9531i  -0.3125 + 0.3125i   0.9531 + 0.3125i  -0.9531 - 0.9531i   0.3125 + 0.9531i

  列 57 至 64

   0.3125 + 0.3125i   1.0000 + 0.0000i  -0.9531 + 0.9531i  -0.9531 - 0.3125i  -0.9531 + 0.3125i  -0.3125 + 0.9531i   0.9531 + 0.9531i  -0.3125 + 0.3125i

  列 65 至 72

   0.0000 + 0.0000i  -0.9531 - 0.9531i   0.3125 + 0.3125i  -0.9531 - 0.9531i   0.3125 + 0.3125i  -0.9531 - 0.3125i  -0.3125 - 0.9531i   1.0000 + 0.0000i

  列 73 至 80

  -0.3125 + 0.3125i   0.3125 + 0.3125i  -0.3125 + 0.3125i  -0.3125 + 0.3125i   0.9531 - 0.9531i  -0.3125 - 0.3125i  -0.9531 - 0.9531i   0.3125 - 0.3125i

  列 81 至 88

  -0.9531 + 0.3125i   0.9531 + 0.3125i   0.3125 - 0.9531i   0.3125 - 0.9531i  -0.9531 + 0.9531i  -1.0000 + 0.0000i  -0.9531 - 0.3125i   0.3125 - 0.9531i

  列 89 至 96

   0.3125 - 0.9531i  -0.9531 - 0.3125i  -0.3125 + 0.3125i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i

  列 97 至 104

   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i  -0.9531 + 0.9531i   0.9531 + 0.9531i

  列 105 至 112

  -0.3125 + 0.3125i  -0.9531 - 0.3125i  -0.3125 + 0.9531i   1.0000 + 0.0000i  -0.3125 - 0.3125i  -0.9531 + 0.3125i  -0.3125 - 0.3125i   0.3125 - 0.9531i

  列 113 至 120

  -0.9531 - 0.3125i  -0.9531 + 0.9531i   0.9531 + 0.9531i  -0.9531 + 0.9531i   0.3125 - 0.3125i  -0.3125 + 0.3125i  -0.3125 + 0.9531i   0.9531 - 0.9531i

  列 121 至 128

   0.9531 + 0.9531i   1.0000 + 0.0000i   0.3125 + 0.9531i   0.9531 - 0.3125i   0.9531 + 0.3125i  -0.3125 - 0.3125i  -0.9531 + 0.3125i   0.9531 - 0.3125i

FPGA输出与Matlab仿真结果进行对比结果如下:

check_pilot =

  1×128 logical 数组

  列 1 至 41

   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

  列 42 至 82

   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

  列 83 至 123

   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1

  列 124 至 128

   1   1   1   1   1

  两个OFDM符号插入导频之后为128个输出,对比逻辑结果全为‘1’,说明FPGA该模块设计完全正确,作者测试了其他调制方案和数据速率都是正确的,这里不再重复赘述。感兴趣的可以自行进行测试。

原文连接(相关文章合集)OFDM 802.11a的xilinx FPGA实现

7.verilog代码

需要verilog代码,点此链接即可获取!!!!

  • 39
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值