OFDM802.11a的FPGA实现(九)星座图映射(含verilog和matlab代码)


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

1. 前言

  在上一篇博客当中,已经完成了数据域的交织,数据域的数据经过交织之后,下一步就是需要对交织之后的bit进行星座图的映射了。

2. 调制

  在 OFDM 通信系统中根据不同的速率要求,其子载波需要用二进制相移键控(BPSK)、正交相移键控(QPSK)、或正交幅度调制(QAM)方式进行调制。数据经过卷积编码和交织后,串行比特流每 1、2、4 或 6 个比特被分为一组,用一定的规律将比特流映射成为复数,形成 BPSK,QPSK,16-QAM,64-QAM 调制。

BPSK_QPSK_16-QAM

64-QAM

  在传输过程中调制方式可能发生变化,如 signal 域的数据采用的是 bpsk 调制,而 data 域采用的是另一种调制方式,为了使所有的映射有一样的平均功率,需要对映射进行归一化。映射后的复数值乘上一个归一化的量 Kmod,即可得到输出数据。Kmod 的值根据不同的调制模式而不同。

归一化因子

2.1 QAM调制

  QAM 与其他调制技术相比,能得到更高的频谱效率,且具有抗噪声能力强等优点,因此得到了广泛的应用。QAM调制中,数据信号由相互正交的两个载波的幅度变化表示。QAM 是一种矢量调制,将输入比特先映射(一般采用格雷码)到一个复平面(星座图)上,形成复数调制符号,然后将该符号的 i、q 分量(即该复数的实部和虚部)分别对应调制在相互正交(时域正交)的两个载波cos 和 sin 上。
  正交振幅调制可以表示为:
s ( t ) = A m c o s ( w t ) + B m c o s ( w t ) ( 0 ≤ t ≤ T s ) s(t)=A_{m}cos(wt)+B_{m}cos(wt) (0 \leq t\leq Ts) s(t)=Amcos(wt)+Bmcos(wt)(0tTs)
  上述式子当中 A m , B m A{m}, B{m} Am,Bm就是调制之后得到的实部和虚部的数据。

正交调制

2.2 64-QAM 调制

  64-QAM在星座图上具有64个星座点,每个星座点代表一种状态,每6个bit表示一个星座点,其映射关系如下:

64QAM

  串行输入的bit,每6个bit构成一个星座点,第一个进来的是b0,进入的顺序依次排列为b0b1b2b3b4b5,根据映射表,可以得到虚部和实部的映射结果:

QAM64映射表

  b0b1b2对应I路,b3b4b5对应Q路数据,再乘以归一化因子,得到调制之后的IQ路的值。

2.3 16-QAM 调制

  16-QAM在星座图上具有16个星座点,每个星座点代表一种状态,每4个bit表示一个星座点,其映射关系如下:

16-QAM 调制

  串行输入的bit,每4个bit构成一个星座点,第一个进来的是b0,进入的顺序依次排列为b0b1b2b3,根据映射表,可以得到虚部和实部的映射结果:

b0b1Re/Ib2b3Im/Q
00-300-3
01-101-1
111111
103103

3.模块实现

  设计上,通过调制方式不同,将串行数据流以1、2、4或6比特分成一组,缓存在一个6比特寄存器中,等到比特数据达到一组时,通过该组数据映射方式进行映射并归一化得到调制的I和Q两路数据。复数以8位定点数形式进行输出,格式为:1位符号位,一位整数位,6位小数位,负数以补码形式表示。与上下游端口数据交互依然采用valid-ready握手机制,不必又去跨时钟域。
  输出实部和虚部各8位,一位符号位,一位整数位,六位小数位;高8位为实部,低8位为虚部。Index_Out为输出标号。端口示意图如下:

4.Matlab仿真

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

test_data =

  列 1 至 27

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

  列 28 至 54

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

  列 55 至 81

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

  列 82 至 108

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

  列 109 至 135

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

  列 136 至 162

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

  列 163 至 189

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

  列 190 至 216

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

  列 217 至 243

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

  列 244 至 270

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

  列 271 至 288

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

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

%% 调制映射
mod_out = qammod(int_lea_2_out', 2^M, 'InputType', 'bit', 'UnitAveragePower', true, 'PlotConstellation', true)';%复数以8位定点数形式进行输出,格式为:1位符号位,一位整数位,6位小数位,负数以补码形式表示。
q = quantizer('fixed','round','saturate',[8,6]);
mod_out_q = num2bin(q,mod_out);%量化
mod_out = bin2num(q,mod_out_q);%反量化

  调制映射结果如下:

mod_out =

列 1 至 8

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

  列 9 至 16

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

  列 17 至 24

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

  列 25 至 32

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

  列 33 至 40

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

  列 41 至 48

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

  列 49 至 56

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

  列 57 至 64

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

  列 65 至 72

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

  列 73 至 80

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

  列 81 至 88

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

  列 89 至 96

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

5.ModelSim仿真

  按照如下图所示进行连接,输入测试数据进行仿真:

  仿真结果如下图所示:

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

clc;
%% 串并转换
test_data = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/test_data.txt')';
display(test_data);
FPGA_S2P2S = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/u2_data_out.txt')';
display(FPGA_S2P2S);
check_S2P = test_data == FPGA_S2P2S; 
display(check_S2P);
%% 扰码
FPGA_scram_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/scram_data_out.txt')';
display(scram_out0);
display(FPGA_scram_dout);
check_scram = FPGA_scram_dout == scram_out0;
display(check_scram);
%% 卷积编码
FPGA_conv_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/conv_data_out.txt')';
display(conv_out0);
display(FPGA_conv_dout);
check_conv = FPGA_conv_dout == conv_out0;
display(check_conv);
%% 删余
FPGA_punt_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/punt_data_out.txt')';
display(conv_out);
display(FPGA_punt_dout);
check_punt = FPGA_punt_dout == conv_out;
display(check_punt);
%% 一级交织
FPGA_intv1_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/intv1_data_out.txt')';
display(int_lea_1_out);
display(FPGA_intv1_dout);
check_intv1 = FPGA_intv1_dout == int_lea_1_out;
display(check_intv1);
%% 二级交织
FPGA_intv2_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/intv2_data_out.txt')';
display(int_lea_2_out);
display(FPGA_intv2_dout);
check_intv2 = FPGA_intv2_dout == int_lea_2_out;
display(check_intv2);
%% 调制映射
FPGA_Re_map_dout = readlines('D:/FPGA/OFDM_802.11a_my/TX/matlab/map_Re_data_out.txt','EmptyLineRule','skip')';
FPGA_Im_map_dout = readlines('D:/FPGA/OFDM_802.11a_my/TX/matlab/map_Im_data_out.txt','EmptyLineRule','skip')';
% FPGA_Re_map_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/map_Re_data_out.txt')';
% FPGA_Im_map_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/map_Im_data_out.txt')';
% display(FPGA_Re_map_dout);
% display(FPGA_Im_map_dout);
q = quantizer('fixed','round','saturate',[8,6]);
FPGA_Re_map_dout = bin2num(q,FPGA_Re_map_dout);
FPGA_Im_map_dout = bin2num(q,FPGA_Im_map_dout);
FPGA_Re_map_dout = cell2mat(FPGA_Re_map_dout);
FPGA_Im_map_dout = cell2mat(FPGA_Im_map_dout);
FPGA_map_dout = FPGA_Re_map_dout + 1j*FPGA_Im_map_dout;
display(mod_out.');
display(FPGA_map_dout);
check_map = FPGA_map_dout == mod_out.';
display(check_map);

  FPGA调制映射的输出为:

FPGA_map_dout =

  列 1 至 8

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

  列 9 至 16

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

  列 17 至 24

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

  列 25 至 32

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

  列 33 至 40

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

  列 41 至 48

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

  列 49 至 56

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

  列 57 至 64

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

  列 65 至 72

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

  列 73 至 80

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

  列 81 至 88

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

  列 89 至 96

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

  与Matlab仿真结果对比如下:

check_map =

  1×96 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 至 96

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

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

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

6.verilog代码

verilog代码链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值