4.4.3 符号同步(二)

4.4.3 符号同步(二)  

基本上 《XILINX FPGA的OFDM通信系统基带设计》一书已经带有各部分的代码,我做的工作就是将代码整合到一起,并按照仿真修改,让其能正常工作。本文将对实现中的重点部分做解释,并指出需要修改的地方。

 

time_sync 顶层

 

`timescale 1ns / 10ps
//////////////////////////////////////////////////////////////////////////////////
// Create Date: 11:41:18 10/30/2014
// Design Name: OFDM_rx_sync_top
// Module Name: Time_Syncronization
// Project Name: OFDM base on Xilinx KC705
// Description: OFDM 接收部分同步模块中【符号同步】子模块,用于接收OFDM符号的同步。
// 找到OFDM数据的起始点,然后除去CP。
// -------------------------------------------------------------
// 输入数据:补码格式 8位位宽 1位符号位 1位整数位 6位小数位
// 输出数据:补码格式 8位位宽 1位符号位 1位整数位 6位小数位
// -------------------------------------------------------------
// Revision: 1.0
// Copyright: 《基于xlinx FPGA的OFDM通信系统基带设计》
//////////////////////////////////////////////////////////////////////////////////
module Time_Syncronization(Clk, Rst_n, DataInEnable, DataInRe, DataInIm,
DataOutEnable, DataOutRe, DataOutIm, DataSymbol);
input Clk;
input Rst_n;
input DataInEnable;
input [7:0] DataInRe;
input [7:0] DataInIm;
output DataOutEnable;
output [7:0] DataOutRe;
output [7:0] DataOutIm;
output [7:0] DataSymbol; //the symbol counter
wire QuantizationEnable;
//the quantization results
wire [15:0] Quantization_Result_Real;
wire [15:0] Quantization_Result_Imag;
// Quantization Module 量化,为了简化计算,节省乘法器
Quantization Quantization ( .Clk(Clk),
.Rst_n(Rst_n),
.inEn(DataInEnable),
.bitInR(DataInRe),
.bitInI(DataInIm),
.QuantizationEnable(QuantizationEnable),
.Quantization_Result_Real(Quantization_Result_Real),
.Quantization_Result_Imag(Quantization_Result_Imag));
//the endness of the STS
wire PeakFinded;
// Mathc filter Module 匹配滤波,找到各个短训符号的结束点
Match_Filtering MatchFiltering ( .Clk(Clk),
.Rst_n(Rst_n),
.QuanEnable(QuantizationEnable),
.QuanDataRe(Quantization_Result_Real),
.QuanDataIm(Quantization_Result_Imag),
.PeakFinded(PeakFinded));
//Symbol Output Module OFDM 符号输出
Symbol_Output SymbolOutput ( .Clk(Clk),
.Rst_n(Rst_n),
.PeakFinded(PeakFinded),
.DataInRe(DataInRe),
.DataInIm(DataInIm),
.DataOutEnable(DataOutEnable),
.DataOutRe(DataOutRe),
.DataOutIm(DataOutIm),
.DataSymbol(DataSymbol));
endmodule

 

 


 

Quantization 量化

 

`timescale 1ns / 10ps
//////////////////////////////////////////////////////////////////////////////////
// Create Date: 13:32:27 10/30/2014
// Design Name: Time_Syncronization
// Module Name: Quantization
// Project Name: OFDM base on Xilinx KC705
// Description: OFDM 符号同步中 【量化】子模块。
// -------------------------------------------------------------
// 1、将接收到的短训符号的16个取样是复数类型,量化为{-1,1},
// 以节省复数乘法所需要的较多器件资源。
// 2、大于0的量化为1,小于0的量化为-1。
// 3、为降低高斯白噪声,在量化前持续累加接收到的短训取样。
// -------------------------------------------------------------
// 输入数据:补码格式 8位位宽 1位符号位 1位整数位 6位小数位
// -------------------------------------------------------------
// Revision: 1.0
// Copyright: 《基于xlinx FPGA的OFDM通信系统基带设计》
//////////////////////////////////////////////////////////////////////////////////
module Quantization(Clk, Rst_n, inEn, bitInR, bitInI, QuantizationEnable,
Quantization_Result_Real, Quantization_Result_Imag);

input Clk;
input Rst_n;
input inEn;
input [7:0] bitInR;
input [7:0] bitInI;
output QuantizationEnable;
output [15:0] Quantization_Result_Real;
output [15:0] Quantization_Result_Imag;
reg QuantizationEnable;
reg [15:0] Quantization_Result_Real;
reg [15:0] Quantization_Result_Imag;
//the enable signal buffer
reg BufferEnable;
//the input datas buffer
reg [7:0] BufferDataR;
reg [7:0] BufferDataI;
//*****************************保证输入数据同步*****************************//
always @(posedge Clk or negedge Rst_n) begin
if(!Rst_n)begin
BufferEnable <= 0;
BufferDataR <= 0;
BufferDataI <= 0;
end
else begin
if(inEn) begin
BufferEnable <= 1;
BufferDataR <= bitInR;
BufferDataI <= bitInI;
end
else begin
BufferEnable <= 0;
BufferDataR <= 0;
BufferDataI <= 0;
end
end
end
//持续累加用寄存器
reg [191:0] Continual_Accumulation_Real;
reg [191:0] Continual_Accumulation_Imag;
//持续累加有效信号/
reg AddEnable;
//********************************取得量化结果********************************//
always @ (posedge Clk or negedge Rst_n) begin
if (!Rst_n)
begin
Continual_Accumulation_Real <= 0;
Continual_Accumulation_Imag <= 0;
AddEnable <= 0;
end
else
begin
if(BufferEnable)
begin
/*持续累加移位寄存器左移一个单元*****//////
Continual_Accumulation_Real[191:12] <= Continual_Accumulation_Real[179:0];
Continual_Accumulation_Imag[191:12] <= Continual_Accumulation_Imag[179:0];
/*最高一个单元与输入数据的12位扩展相加赋值给最低一个单元****//////
Continual_Accumulation_Real[11:0] <= {{4{BufferDataR[7]}},BufferDataR} +

Continual_Accumulation_Real[191:180];
Continual_Accumulation_Imag[11:0] <= {{4{BufferDataI[7]}},BufferDataI} + 

Continual_Accumulation_Imag[191:180];
AddEnable <= 1;
end
else
begin
Continual_Accumulation_Real <= 0;
Continual_Accumulation_Imag <= 0;
AddEnable <= 0;
end
end
end
always @(posedge Clk or negedge Rst_n)
begin
if(!Rst_n)
begin
Quantization_Result_Real <= 0;
Quantization_Result_Imag <= 0;
QuantizationEnable <= 0;
end
else
begin
if(AddEnable)
begin
QuantizationEnable <= 1;
/*量化结果移位******//////
Quantization_Result_Real[14:0] <= Quantization_Result_Real[15:1];
Quantization_Result_Imag[14:0] <= Quantization_Result_Imag[15:1];
/*最高位为0,表正,量化为+1, 在此用0代替,下面语句只是用于判断******//////
Quantization_Result_Real[15] <= Continual_Accumulation_Real[11];
/*最高位为1,表负,量化为-1,在此用1表示******//////
Quantization_Result_Imag[15] <= Continual_Accumulation_Imag[11];
end
else
begin
Quantization_Result_Real <= 0;
Quantization_Result_Imag <= 0;
QuantizationEnable <= 0;
end
end
end
endmodule

 


 

MatchFiltering 匹配滤波

相关累加计算的实现结构框图:

4.4.3 符号同步(二) - fantasy - 南山悠然望夕阳

相关累加计算模块中: Simple_Correlating模块

将复数的乘法,直接转化为加减运算,大大的简化了计算量!

 

`timescale 1ns / 10ps
//////////////////////////////////////////////////////////////////////////////////
// Create Date: 14:25:50 10/30/2014
// Design Name: Correlating_and_Accumulating
// Module Name: Simple_Correlation
// Project Name: OFDM base on Xilinx KC705
// Description: OFDM 【单个数据相关系数的运算】模块。
// -------------------------------------------------------------
// Example:conjugate{(a + i*b)}= (a - i*b) conj是共轭的意思
// conj{(a+i*b)}*(1+i) = (a+b)+i*(a-b)
// conj{(a+i*b)}*(1-i) = (a-b)+i*(-a-b)
// conj{(a+i*b)}*(-1+i)= (-a+b)+i*(a+b)
// conj{(a+i*b)}*(-1-i)= (-a-b)+i*(-a+b)
// -------------------------------------------------------------
// Revision: 1.0
// Copyright: 《基于xlinx FPGA的OFDM通信系统基带设计》
// 参考《中山大学论文》,得将已知STS取共轭之后再与量化结果相乘
//////////////////////////////////////////////////////////////////////////////////
module Simple_Correlation(Clk, Rst_n, inEn, multiplier_Real, multiplier_Imag,
known_Real, known_Imag, output_Real, output_Imag, outputEnable);

input Clk;
input Rst_n;
input inEn;
input multiplier_Real; //移位寄存器实部
input multiplier_Imag; //移位寄存器虚部
input [15:0] known_Real; //本地已知短训练序列实部,二进制补码表示
input [15:0] known_Imag; //短训练序列虚部
output [16:0] output_Real; //输出实部,扩展为17位输出,输出为二进制补码表示
output [16:0] output_Imag; //输出虚部
output outputEnable;
reg [16:0] output_Real;
reg [16:0] output_Imag;
reg outputEnable;
//**********************输入的multiplier等于0表示正数,等于1表示负数**************************//
always @ (posedge Clk or negedge Rst_n)
begin
if (!Rst_n)
begin
output_Real <= 0;
output_Imag <= 0;
outputEnable <= 0;
end
else if (inEn)
begin
outputEnable <= 1;
if(multiplier_Real == 0 && multiplier_Imag == 0)
begin
output_Real <= {{1{known_Real[15]}},known_Real} + {{1{known_Imag[15]}},known_Imag};
output_Imag <= {{1{known_Real[15]}},known_Real} - {{1{known_Imag[15]}},known_Imag};
end
else if (multiplier_Real == 0 && multiplier_Imag == 1)
begin
output_Real <= {{1{known_Real[15]}},known_Real} - {{1{known_Imag[15]}},known_Imag};
output_Imag <= - {{1{known_Real[15]}},known_Real} - {{1{known_Imag[15]}},known_Imag};
end
else if (multiplier_Real == 1 && multiplier_Imag == 0)
begin
output_Real <= - {{1{known_Real[15]}},known_Real} + {{1{known_Imag[15]}},known_Imag};
output_Imag <= {{1{known_Real[15]}},known_Real} + {{1{known_Imag[15]}},known_Imag};
end
else //(buffer_multiplier_Real==1 && buffer_multiplier_Imag==1)
begin
output_Real <= - {{1{known_Real[15]}},known_Real} - {{1{known_Imag[15]}},known_Imag};
output_Imag <= - {{1{known_Real[15]}},known_Real} + {{1{known_Imag[15]}},known_Imag};
end
end
else
begin
output_Real <= 0;
output_Imag <= 0;
outputEnable <= 0;
end
end

endmodule

 

累加结果的幅值计算模块(Magnitude_Simplified_Computing):

 

`timescale 1ns / 10ps
//////////////////////////////////////////////////////////////////////////////////
// Create Date: 14:42:15 10/30/2014
// Design Name: Match_Filtering
// Module Name: Magnitude_Simplified_Computing
// Project Name: OFDM base on Xilinx KC705
// Description: OFDM 符号同步中 【相关累加计算】子模块。
// -------------------------------------------------------------
// 计算相关累加后的幅值,用以下一步的峰值判断。
// 如果直接计算幅值,需要乘法和开方运算,不利于硬件实现。
// 简化实现:c=a+jb (|C| ≈ |a| + |b|)
// 计算输入数据的实部和虚部之和,近似其幅值。
// 近似简化后的|C|比实际值要稍大,因此门限值必须要稍作调整
// -------------------------------------------------------------
// Revision: 1.0
// Copyright: 《基于xlinx FPGA的OFDM通信系统基带设计》
//////////////////////////////////////////////////////////////////////////////////
module Magnitude_Simplified_Computing(Clk, Rst_n, DataEnable, DataInRe, DataInIm, AbsoluteEnable, Absolute);
input Clk;
input Rst_n;
input DataEnable;
input [20:0] DataInRe; //输入实部,位宽21位,二进制补码表示
input [20:0] DataInIm; //输入虚部
output AbsoluteEnable;
output [21:0] Absolute; //绝对值输出,经一次加法后,位宽变为22位,绝对值为正数
reg [21:0] Absolute; //输出结果为22位位宽,操作数首先扩展为22位位宽
reg AbsoluteEnable;
reg BufferEnable;
reg [20:0] BufferDataRe;
reg [20:0] BufferDataIm;
//********************输入增加一级缓存,延迟一个时钟周期************************//
always @ (posedge Clk or negedge Rst_n) begin
if (!Rst_n)
begin
BufferEnable <= 0;
BufferDataRe <= 0;
BufferDataIm <= 0;
end
else
begin //缓存的数据为输入数据的绝对值
if(DataEnable) begin
BufferEnable <= 1;
if(DataInRe[20] == 0) //符号位为0,表示为正数,绝对值即为输入数
begin
BufferDataRe <= DataInRe;
end
else //符号位为1,表示为负数,绝对值为输入数取反加1
begin
BufferDataRe <= ~ DataInRe + 1;
end
if (DataInIm[20] == 0) //虚部运算同实部
begin
BufferDataIm <= DataInIm;
end
else
begin
BufferDataIm <= ~ DataInIm + 1;
end
end
else
begin
BufferEnable <= 0;
BufferDataRe <= 0;
BufferDataIm <= 0;
end
end
end
//************************幅值取实部与虚部的绝对值之和******************************//
always @ (posedge Clk or negedge Rst_n) begin
if (!Rst_n)
begin
Absolute <= 0;
AbsoluteEnable <= 0;
end
else
begin
if(BufferEnable)
begin
Absolute <= {BufferDataRe[20],BufferDataRe} + {BufferDataIm[20],BufferDataIm};
AbsoluteEnable <= 1;
end
else
begin
Absolute <= 0;
AbsoluteEnable <= 0;
end
end
end

endmodule

重点在于:简化实现:c=a+jb   (|C| ≈ |a| + |b|)

 

在Peak_Finding模块中,重点是门限值的选取(仿真可得):

4.4.3 符号同步(二) - fantasy - 南山悠然望夕阳

 

由于分组检测模块输出的第一组短训练符号是不完整的,所以峰值寻找只能连续检测到9个峰值点,所以STS_end_counter < 9即可。

4.4.3 符号同步(二) - fantasy - 南山悠然望夕阳

 

如果有条件可以用 modelsim 仿真或者VCS,可以看到 模拟波形 ,明显的9个峰值。

 

 


 

符号输出

  1. 送入的数据是16个循环前缀+64个有效数据,除去前缀CP。

  2. 后期不使用短训练符号,所以这里一并除去。

  3. 长训符号是32bit的前缀+2个64bit的样值,数据则是16个前缀+64个有效数据,所以在处理上,先输出第一个长训符号,然后第二个长训符号和16级的移位寄存器后输出,以保证,数据之间相隔16个clk的间隙。

  4. 如果接受数据不为OFDM符号长度的整数倍,在其后补零以满足整数倍条件。

 

 

代码的下列部分,是整个符号输出模块的核心:

 

if(PeakFinded)
begin
if(Counter1 <= 85) //鉴于量化、相关等处理需要延迟10个周期(可以数出来的),故32+64-10 = 86
begin
Counter2 <= 0;
Counter1 <= Counter1 + 1;
if(Counter1 >= 22 && Counter1 <= 85)//LTS的前缀长度32,延迟10个周期,故32-10 = 22开始
begin
DataOutEnable <= 1; //将第一个LTS直接输出
DataOutRe <= DataInRe;
DataOutIm <= DataInIm;
end
else
begin
DataOutEnable <= 0;
DataOutRe <= 0;
DataOutIm <= 0;
end
if(Counter1 == 22)
begin
DataSymbol <= DataSymbol + 1;
TempSymbol <= DataSymbol + 1;
end
end
else
begin//由于第一个LTS后面紧跟着第二个LTS,所以当count2值为0~63时,输入数据为所需数据;
//当count2值为64~79时,输入数据为下一个符号的循环前缀。
if(Counter2 == 79) //count2 64~79时,输入数据为signal域的循环前缀
begin
Counter2 <= 0;
TempSymbol <= TempSymbol + 1;
end
else
begin
Counter2 <= Counter2 + 1;
end
if(Counter2 >= 0 && Counter2 <= 63) //输入数据为第二个LTS
begin
BufferOutEnable[15] <= 1;
BufferDataOutRe[127:120] <= DataInRe;
BufferDataOutIm[127:120] <= DataInIm;
BufferDataSymbol[127:120] <= TempSymbol + 1;
end
else //循环前缀期间,送入0,也就是每个OFDM符号之间相隔16个0
begin
BufferOutEnable[15] <= 0;
BufferDataOutRe[127:120] <= 0;
BufferDataOutIm[127:120] <= 0;
BufferDataSymbol[127:120] <= 0;
end

BufferOutEnable[14:0] <= BufferOutEnable[15:1];
BufferDataOutRe[119:0] <= BufferDataOutRe[127:8];
BufferDataOutIm[119:0] <= BufferDataOutIm[127:8];
DataOutEnable <= BufferOutEnable[0];
DataOutRe <= BufferDataOutRe[7:0];
DataOutIm <= BufferDataOutIm[7:0];
BufferDataSymbol[119:0] <= BufferDataSymbol[127:8];
DataSymbol <= BufferDataSymbol[7:0];
end

猜你喜欢

转载自blog.csdn.net/weixin_40640020/article/details/83345335
今日推荐