OFDM802.11a的FPGA实现(四)扰码
1.前言
上一节详细讲述下发射机基带系统的整体构架,从这一节开始,挨个实现发射机基带的这些模块。
该系统分为训练序列生成器、MCU、OFDM符号频域调制、IFFT和循环前缀、加窗。 序列主要为后续接收端的时域同步和信道估计及均衡提供算法支撑,训练序列包括长、短训练序列两部分,短训练序列主要用来进行信号检测帧同步,长训练序列用来进行信道估计从而对接收信号进行补偿。PLL模块主要负责各种频率的时钟信号生成,MCU主要负责产生发射机所需要的各种控制信号,保证各个子模块按照一定的时序进行工作,并且能彼此协调和同步。MCU主要控制整个系统时序的对齐,以及保证各个子模块的正常工作,同时还与MAC层交互,向MAC层请求数据等。最终的OFDM符号存在严格的时序要求,训练序列后紧跟Signal域和Data域,Data域OFDM符号之间不能存在空闲时序。
接下来按照下图所示的流程,使用随机二进制bit流作为输入,用matlab和FPGA分别对系统各个模块进行实现,最终对比matlab和FPGA的结果。
2扰码器
2.1扰码器的原理
数字通信中,若经常出现长的0或1序列,将会影响位同步的建立和保持。在发射机中使用扰码,可以避免这种数据对于接收机定时的不利影响。同时,为了限制电路中存在的不后程度的非线性特性对其他电路通信造成的串扰,要求数字信号的最小周期足够长。将数字信号变换成具有近似于白噪声统计特性的数字序列即可满足要求,这通常用加扰来实现。所谓加扰,就是不用增加冗余而搅乱信号,改变数字信号统计特性,使其具有近似白噪声统计特性的一种技术。这种技术的基础是建立在反馈移位寄存器序列(或伪随机序列)理论上的。
采用加扰技术的通信系统组成原理,如图下图所示。在发送端用加扰器来改变原始数字信号的统计特性,而在接收端用解扰器恢复出原始数字信号。
scramble 的生成多项式和硬件结构如下图所示:
2.3扰码器的实现
扰码模块的硬件实现框图如图:
PSDU 数据帧是以字节为单位并行传输的,因此在加扰前,需要先将并行数据转为串行数据。在电路实现中,需要先完成并串转换。前几节,已经实现了并串转换。发送比特的扰码和接收比特的解码使用的扰码器完全一致。当发送时,扰码器通常将被设置为伪随机非零状态。同时,在扰码前Service域的最低7位将设为零,以便在接收端估计扰码器的初始状态。设计上,通过一个7位移位寄存器,在输入信号有效时,每个时钟周期扰码状态左移位一次,并且第7位与第4位进行异或运算,再作为移位寄存器的输入,另一方面与输入的信号进行加扰处理,后输出数据,数据流依然采用前面所讲的vaild-ready协议。扰码模块代码如下,需要注意的是Signal符号只进行卷积编码、交织、BPSK映射、插入导频,不扰码、删余。
assign scram_dout_rdy = scram_din_rdy ;
assign scram_en = scram_dout_rdy & scram_din_vld ;
always@(posedge clk or negedge rst_n ) begin
if(!rst_n) begin
shift_reg <= 0;
scram_dout <= 0;
scram_dout_vld <= 0;
end
else if( scram_load ) begin
shift_reg <= scram_seed;
scram_dout_vld <= 0;
end
else if( scram_en) begin
scram_dout <= shift_reg[6] + shift_reg[3] + scram_din;
//s(x) = x^7 + x^4 + 1
scram_dout_vld <= 1;
shift_reg <= {shift_reg[5:0],(shift_reg[6]+shift_reg[3])};
end
else begin
scram_dout_vld <= 0;
end
end
2.3modelsim仿真
将模块按照下图方式连接:
用matlab生成随机二进制bit流作为输入,由于输入8bit的并行数据还需要额外编写代码,此处使用之前设计的串并转换模块,即可得到并行的8bit数据流。然后将其输出依次连接,并串转换模块,扰码模块。
仿真结果如图所示:
将并串转换输出和扰码器输出,存为txt。
2.4仿真结果与matlab比较
matlab实现扰码器的代码如下:
%% 扰码
scram_seed0 = [1,0,1,1,1,0,1]; %扰码寄存器初值
scramnler = scram_seed0; %扰码寄存器
scram_in = num_in; %产生输入随机序列
%scram_in = [1 1 0 1];
scram_out0 = zeros(1,length(scram_in)); %初始化输出序列
for m = 1:length(scram_in)
scram_out0(m) = mod(scramnler(7) + scramnler(4) + scram_in(m), 2);%扰码:7+4+输入数据
scramnler = [mod(scramnler(7) + scramnler(4), 2), scramnler(:,1:6)];%扰码寄存器移位,最低位为7+4
end
测试数据如下:
test_data = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/test_data.txt')';
display(test_data);
FPGA并串转换结果如下:
FPGA_S2P2S = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/u2_data_out.txt')';
display(FPGA_S2P2S);
由于肉眼看0和1实在头疼,直接用代码比较是否一样更方便:
check_S2P = test_data == FPGA_S2P2S;
display(check_S2P);
全为1,说明设计正确。
FPGA_scram_dout = load('D:/FPGA/OFDM_802.11a_my/TX/matlab/scram_data_out.txt')';
display(scram_out0);
display(FPGA_scram_dout);
FPGA的扰码输出:
matlab的扰码输出:
对比:
check_scram = FPGA_scram_dout == scram_out0;
display(check_scram);
原文连接(相关文章合集):OFDM的xilinx FPGA实现