赞
踩
原文链接(相关文章合集):OFDM 802.11a的xilinx FPGA实现
前面一篇文章完成了星座图的映射,今天继续设计后面的模块。在接收机当中,虽然利用接收到的短/长训练序列,能够进行信道均衡,频偏校正,但符号还会存在一定的剩余频率偏差,并且偏差会随着时间的积累而累积,会造成所有子载波产生一定的剩余相位偏转。因此,还需要不断的对参考相位进行跟踪。要实现这一功能,需要在 52 个非零子载波中插入 4 个导频符号。
Data 域的数据经过星座图映射后形成对应的复数值,每个 OFDM 符号周期可以通过 48 个子信道发出 48 个调制后的数据,所以把这些值每 48 个分成一组,每一组将对应一个 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}。
图中,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) =
根据协议中对IFFT输入端口映射的规定,将变换后M(k)为1至26的子载波映射到IFFT的输入端口1至26,M(k)为一26至一1的子载波映射到IFFT的端口38到63,而剩下的端口27至37和0则置为零值。此映射的描述如下图所示。
相应的,插入导频的位置-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) =
在设计上,采用乱序写,顺序读的方式。先定义1个位宽为16的RAM,对输入数据的实数和虚数按Index序号通过上面公式变换后,存入RAM中。再通过扰码器产生的极性控制信号,对导频是否极性变换做处理,极性处理后,将导频信号写入对应RAM地址空间中。最后,以顺序方式从RAM中读取数据。为保证流水线处理,以及写入写出不发生冲突,RAM的深度需设置为2个OFDM符号的长度,使用乒乓缓存操作(前面文章乒乓缓存操作的链接)。
在对数据域进行调制的时候,导频控制序列是从地址1开始累加,直到处理完126个OFDM符号是,这是导频控制序列读取到第126个,然后才会回到0,然后从0~126循环,因为在802.11a当中,第一个OFDM符号是signal域的符号,data域是从第二个符号开始。
插入导频模块的输入输出如下图所示:
以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
硬件按照如下图所示连接进行仿真:
将前面提到的测试数据作为输入,对硬件进行测试,仿真结果如下图:
如上图所示,在没有数据输入的空隙,将导频写入RAM对应位置。
如上图所示,输入数据根据标号,进行乱序写入RAM。
如上图所示,输出数据从RAM中顺序输出,并且另外一个缓存区可以进行数据输入,实现了乒乓缓存,以保证流水线操作。
将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实现
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。