OFDM学习
媒介
根据框图可以知道发射机这部门信号在DA转换之前,数据是两路,分别是实部和虚部8位信号。通过DA转换也是两路模拟信号,通过IQ调制搞到射频。
PPDU包罗3部门数据,长短序列是不须要举行ofdm操作的,signal和data的信号须要举行ofdm操作,也就是下面图中扰码、卷积编码、交错等等的操作,最后通过ifft和cp加窗后举行输出,最后将实部信号与虚部信号与训练序列的实部和虚部按照位置分别发送。
一、短序列
子载波有效数量是52个,短序列只用到了其中的12个子载波,每个载波之间的隔断为4,位置序号是:
{-24,-20,-16,-12,-8,-4, 4,8,12,16,20,24},直流分量不能使用。又因为短序列采用的是BPSK模式,因此可以通过载波位置以及调制方式决定他的数据格式。确定[9:0] STS_IM[8] 和[9:0] STS_RE[8],就实现了短序列的产生,按照位置依次将实部序列和虚部序列信号发送即可。
因此短序列在频域上就是
% STS频域表现
S=[0,0,0,0,0,0,0,0,1+i,0,0,0,-1-i,0,0,0,1+i,0,0,0,-1-i,0,0,0,-1-i,0,0,0,1+i,0,0,0,0,0,0,0,-1-i,0,0,0,-1-i,0,0,0,1+i,0,0,0,1+i,0,0,0,1+i,0,0,0,1+i,0,0,0,0,0,0,0];
但是最终须要发出去的是时域信号,以是这个频域信号理论上是要经过ifft模块处置惩罚之后发送出去,但是因为短序列都是固定的数值,因此时序信号的实部和虚部也是固定的,以是短训练序列的产生也就是通过MATLAB将频域转换为时域后,将固定的时域信号的实部值和虚部值直接使用。短训练序列的数据格式,1位符号位,1位整数位,6位小数位。
从时域上看,每一个短序列是16个采样点,也就是总共10*16=160点。
短序列的作用
吸收机举行分组检测、同步等
二、长序列
类似短序列,根本原理相同,各自作用不同。
三、PLCP/SIGNAL/DATA数据处置惩罚流程
训练序列直接按照时域产生实部信号和虚部信号,不须要举行ofdm调制。
SIGNAL信号和DATA信号须要从单比特流数据经过扰码、卷积编码、交错、符号调制、16QAM调制、导频插入、IFFT模块、CP加窗等步调最后与训练序列组合发送到DAC举行射频端的处置惩罚。
三、fpga实现
STS模块
- `timescale 1ns / 1ps
- ///
- // Company:
- // Engineer: YWang
- //
- // Create Date: 2023-03-10 14:53:45
- // Design Name:
- // Module Name: STS_generator.v
- // Project Name:
- // Target Devices:
- // Tool versions:
- // Description:
- //
- // Dependencies: 0
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- ///
- module STS_generator(
- input clk ,
- input rst_n ,
- input Tx_Clr ,
- input Start_En ,
- output reg [7:0] STS_Im ,
- output reg [7:0] STS_Re ,
- output reg STS_Vld ,
- output reg [7:0] STS_Index ,
- output reg STS_Done
- );
- reg [15:0] Short_Mem [15:0];
- reg [3:0] i,j;
- wire STS_Req;
- assign STS_Req = Start_En || (STS_Index>0);
- always @(posedge clk or negedge rst_n) begin
- if(~rst_n) begin
- Short_Mem[0] <= {8'b00001100,8'b00001100};
- Short_Mem[1] <= {8'b11011110,8'b00000001};
- Short_Mem[2] <= {8'b11111101,8'b11101100};
- Short_Mem[3] <= {8'b00100100,8'b11111101};
- Short_Mem[4] <= {8'b00011000,8'b00000000};
- Short_Mem[5] <= {8'b00100100,8'b11111101};
- Short_Mem[6] <= {8'b11111101,8'b11101100};
- Short_Mem[7] <= {8'b11011110,8'b00000001};
- Short_Mem[8] <= {8'b00001100,8'b00001100};
- Short_Mem[9] <= {8'b00000001,8'b11011110};
- Short_Mem[10] <= {8'b11101100,8'b11111101};
- Short_Mem[11] <= {8'b11111101,8'b00100100};
- Short_Mem[12] <= {8'b00000000,8'b00011000};
- Short_Mem[13] <= {8'b11111101,8'b00100100};
- Short_Mem[14] <= {8'b11101100,8'b11111101};
- Short_Mem[15] <= {8'b00000001,8'b11011110};
- STS_Vld <= 0;
- STS_Index <= 0;
- STS_Done <= 0;
- STS_Re <= 0;
- STS_Im <= 0;
- i <= 0;
- j <= 0;
- end
- else if( Tx_Clr ) begin
- i <= 0;
- j <= 0;
- STS_Vld <= 0;
- STS_Index <= 0;
- STS_Done <= 0;
- end
- else if( STS_Req && (STS_Index<161) ) begin
- STS_Index <= STS_Index + 1;
- STS_Vld <= 1'b1;
- if(i<10) begin
- if(j==15) begin
- j <= 0;
- i <= i+ 1;
- STS_Re <= Short_Mem[j][15:8];
- STS_Im <= Short_Mem[j][7:0];
- end
- else begin
- if(i==0 && j==0) begin
- STS_Re <= Short_Mem[j][15:8]>>1; //鍔犵獥锛屽乏绉讳竴
- STS_Im <= Short_Mem[j][7:0]>>1;//娉ㄦ剰锛歋hort_Mem銆�0銆戜负姝f暟
- end
- else begin
- STS_Re <= Short_Mem[j][15:8];
- STS_Im <= Short_Mem[j][7:0];
- end
- j <= j + 1;
- end
- end
- else begin //鏈�鍚庝竴浣�
- STS_Re <= Short_Mem[0][15:8]>>1; //鍔犵獥锛屽乏绉讳竴 绗竴涓��
- STS_Im <= Short_Mem[0][7:0]>>1;
- STS_Done <= 1'b1;
- end
- end
- else begin
- STS_Vld <= 1'b0;
- end
- end
-
- endmodule
复制代码 LTS模块
- `timescale 1ns / 1ps
- ///
- // Company:
- // Engineer: YWang
- //
- // Create Date: 2023-03-10 14:53:45
- // Design Name:
- // Module Name: LTS_generator.v
- // Project Name:
- // Target Devices:
- // Tool versions:
- // Description:
- //
- // Dependencies: 0
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- ///
- module LTS_generator(
- input clk ,
- input rst_n ,
- input Tx_Clr ,
- input Start_En ,
- output reg [7:0] LTS_Im ,
- output reg [7:0] LTS_Re ,
- output reg LTS_Vld ,
- output reg [7:0] LTS_Index ,
- output reg LTS_Done
- );
- reg [15:0] Long_Mem [63:0];
- reg [6:0] i,j;
- wire LTS_Req;
- assign LTS_Req = Start_En || (LTS_Index>0);
- always @(posedge clk or negedge rst_n) begin
- if(~rst_n) begin //鏃跺煙鏍峰�� Re Im
- Long_Mem[0] <= {8'b00101000 , 8'b00000000};
- Long_Mem[1] <= {8'b11111111 , 8'b11100001};
- Long_Mem[2] <= {8'b00001010 , 8'b11100100};
- Long_Mem[3] <= {8'b00011001 , 8'b00010101};
- Long_Mem[4] <= {8'b00000101 , 8'b00000111};
- Long_Mem[5] <= {8'b00001111 , 8'b11101010};
- Long_Mem[6] <= {8'b11100011 , 8'b11110010};
- Long_Mem[7] <= {8'b11110110 , 8'b11100101};
- Long_Mem[8] <= {8'b00011001 , 8'b11111001};
- Long_Mem[9] <= {8'b00001110 , 8'b00000001};
- Long_Mem[10] <= {8'b00000000 , 8'b11100011};
- Long_Mem[11] <= {8'b11011101 , 8'b11110100};
- Long_Mem[12] <= {8'b00000110 , 8'b11110001};
- Long_Mem[13] <= {8'b00001111 , 8'b11111100};
- Long_Mem[14] <= {8'b11111010 , 8'b00101001};
- Long_Mem[15] <= {8'b00011111 , 8'b11111111};
- Long_Mem[16] <= {8'b00010000 , 8'b11110000};
- Long_Mem[17] <= {8'b00001001 , 8'b00011001};
- Long_Mem[18] <= {8'b11110001 , 8'b00001010};
- Long_Mem[19] <= {8'b11011110 , 8'b00010001};
- Long_Mem[20] <= {8'b00010101 , 8'b00011000};
- Long_Mem[21] <= {8'b00010010 , 8'b00000100};
- Long_Mem[22] <= {8'b11110001 , 8'b00010101};
- Long_Mem[23] <= {8'b11110010 , 8'b11111010};
- Long_Mem[24] <= {8'b11110111 , 8'b11011001};
- Long_Mem[25] <= {8'b11100001 , 8'b11111100};
- Long_Mem[26] <= {8'b11011111 , 8'b11111011};
- Long_Mem[27] <= {8'b00010011 , 8'b11101101};
- Long_Mem[28] <= {8'b11111111 , 8'b00001110};
- Long_Mem[29] <= {8'b11101000 , 8'b00011101};
- Long_Mem[30] <= {8'b00010111 , 8'b00011011};
- Long_Mem[31] <= {8'b00000011 , 8'b00011001};
- Long_Mem[32] <= {8'b11011000 , 8'b00000000};
- Long_Mem[33] <= {8'b00000011 , 8'b11100111};
- Long_Mem[34] <= {8'b00010111 , 8'b11100101};
- Long_Mem[35] <= {8'b11101000 , 8'b11100011};
- Long_Mem[36] <= {8'b11111111 , 8'b11110010};
- Long_Mem[37] <= {8'b00010011 , 8'b00010011};
- Long_Mem[38] <= {8'b11011111 , 8'b00000101};
- Long_Mem[39] <= {8'b11100001 , 8'b00000100};
- Long_Mem[40] <= {8'b11110111 , 8'b00100111};
- Long_Mem[41] <= {8'b11110010 , 8'b00000110};
- Long_Mem[42] <= {8'b11110001 , 8'b11101011};
- Long_Mem[43] <= {8'b00010010 , 8'b11111100};
- Long_Mem[44] <= {8'b00010101 , 8'b11101000};
- Long_Mem[45] <= {8'b11011110 , 8'b11101111};
- Long_Mem[46] <= {8'b11110001 , 8'b11110110};
- Long_Mem[47] <= {8'b00001001 , 8'b11100111};
- Long_Mem[48] <= {8'b00010000 , 8'b00010000};
- Long_Mem[49] <= {8'b00011111 , 8'b00000001};
- Long_Mem[50] <= {8'b11111010 , 8'b11010111};
- Long_Mem[51] <= {8'b00001111 , 8'b00000100};
- Long_Mem[52] <= {8'b00000110 , 8'b00001111};
- Long_Mem[53] <= {8'b11011101 , 8'b00001100};
- Long_Mem[54] <= {8'b00000000 , 8'b00011101};
- Long_Mem[55] <= {8'b00001110 , 8'b11111111};
- Long_Mem[56] <= {8'b00011001 , 8'b00000111};
- Long_Mem[57] <= {8'b11110110 , 8'b00011011};
- Long_Mem[58] <= {8'b11100011 , 8'b00001110};
- Long_Mem[59] <= {8'b00001111 , 8'b00010110};
- Long_Mem[60] <= {8'b00000101 , 8'b11111001};
- Long_Mem[61] <= {8'b00011001 , 8'b11101011};
- Long_Mem[62] <= {8'b00001010 , 8'b00011100};
- Long_Mem[63] <= {8'b11111111 , 8'b00011111};
- LTS_Vld <= 0;
- LTS_Index <= 0;
- LTS_Done <= 0;
- LTS_Re <= 0;
- LTS_Im <= 0;
- i <= 0;
- j <= 0;
- end
- else if( Tx_Clr ) begin
- i <= 0;
- j <= 0;
- LTS_Vld <= 0;
- LTS_Index <= 0;
- LTS_Done <= 0;
- end
- else if( LTS_Req && (LTS_Index<161) ) begin
- LTS_Index <= LTS_Index + 1;
- LTS_Vld <= 1'b1;
- if(i==0) begin
- if(j==31) begin
- j <= 0;
- i <= i+ 1;
- LTS_Re <= Long_Mem[j+32][15:8];
- LTS_Im <= Long_Mem[j+32][7:0];
- end
- else begin
- if(i==0 && j==0) begin
- LTS_Re <= 8'b11101100; //鐭缁冨簭鍒楀埌闀胯缁冨簭鍒楃殑绐楀彛鍑芥暟
- LTS_Im <= Long_Mem[j+32][7:0];
- end
- else begin
- LTS_Re <= Long_Mem[j+32][15:8];
- LTS_Im <= Long_Mem[j+32][7:0];
- end
- j <= j + 1;
- end
- end
- else if( i==1 || i==2 ) begin
- if(j==63) begin
- j <= 0;
- i <= i+ 1;
- LTS_Re <= Long_Mem[j][15:8];
- LTS_Im <= Long_Mem[j][7:0];
- end
- else begin
- LTS_Re <= Long_Mem[j][15:8];
- LTS_Im <= Long_Mem[j][7:0];
- j <= j + 1;
- end
- end
- else begin // 鍔犵獥澶勭悊
- LTS_Re <= Long_Mem[0][15:8]>>1; //鍔犵獥锛屽乏绉讳竴浣�
- LTS_Im <= Long_Mem[0][7:0]>>1;
- LTS_Done <= 1'b1;
- end
- end
- else begin
- LTS_Vld <= 1'b0;
- end
- end
-
- endmodule
-
复制代码 训练序列模块
- `timescale 1ns / 1ps
- ///
- // Company:
- // Engineer: YWang
- //
- // Create Date: 2023-03-10 14:22:41
- // Design Name:
- // Module Name: symbol_train.v
- // Project Name:
- // Target Devices:
- // Tool versions:
- // Description:
- //
- // Dependencies: 0
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:????????????????
- //
- ///
- module symbol_train(
- input clk ,
- input rst_n ,
- input Tx_Clr ,
- input Start_En ,
- output [7:0] Train_Im ,
- output [7:0] Train_Re ,
- output Train_Vld ,
- output [8:0] Train_Index ,
- output Train_Done
- );
- wire STS_Start_En;
- wire [7:0] STS_Im ;
- wire [7:0] STS_Re ;
- wire STS_Vld ;
- wire [7:0] STS_Index ;
- wire STS_Done ;
- wire LTS_Start_En;
- wire [7:0] LTS_Im ;
- wire [7:0] LTS_Re ;
- wire LTS_Vld ;
- wire [7:0] LTS_Index ;
- wire LTS_Done ;
- STS_generator u_STS
- (
- .clk (clk ),
- .rst_n (rst_n ),
- .Tx_Clr (Tx_Clr ),
- .Start_En (STS_Start_En ),
- .STS_Im (STS_Im ),
- .STS_Re (STS_Re ),
- .STS_Vld (STS_Vld ),
- .STS_Index (STS_Index ),
- .STS_Done (STS_Done )
- );
- LTS_generator u_LTS
- (
- .clk (clk ),
- .rst_n (rst_n ),
- .Tx_Clr (Tx_Clr ),
- .Start_En (LTS_Start_En ),
- .LTS_Im (LTS_Im ),
- .LTS_Re (LTS_Re ),
- .LTS_Vld (LTS_Vld ),
- .LTS_Index (LTS_Index ),
- .LTS_Done (LTS_Done )
- );
- assign Train_Im = STS_Vld ? STS_Im : LTS_Vld ? LTS_Im : 8'b0 ;
- assign Train_Re = STS_Vld ? STS_Re : LTS_Vld ? LTS_Re : 8'b0 ;
- assign Train_Vld = STS_Vld ? 1'b1 : LTS_Vld ? 1'b1 : 1'b0;
- assign Train_Index = STS_Index + LTS_Index;
- assign Train_Done = LTS_Done;
- assign STS_Start_En = Start_En;
- assign LTS_Start_En = STS_Done;
-
- endmodule
复制代码 仿真波形
总结
训练序列的产生要明确:
频域上用了12个子载波,隔断为4,BPSK符号格式,功率因数1.4几来着?。
频域固定,因此时域实部和虚部也是固定,通过MATLAB就可以直接得到时域的训练序列的实部和虚部的数值,因此直接在步伐中写死循环即可。
数据格式:1位符号,1位整数,6位小数
代码参考:基于FPGA的OFDM基带发射机的计划与实现
训练模块代码未做修改。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |