天天看點

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];

/

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];

/

Quantization_Result_Real[15] <= Continual_Accumulation_Real[11];

/

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 符号同步(二)

相關累加計算子產品中: 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;

//

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 符号同步(二)

由于分組檢測子產品輸出的第一組短訓練符号是不完整的,是以峰值尋找隻能連續檢測到9個峰值點,是以STS_end_counter < 9即可。

4.4.3 符号同步(二)

如果有條件可以用 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