目录
欢迎订阅FPGA/MATLAB/Simulink系列教程
1.软件版本
vivado2019.2
2.基于FPGA的MMSE信道估计与均衡系统整体实现
通过前面几个章节的学习,我们完成了MMSE信道估计和均衡系统。为了进一步验证MMSE信道估计的性能,我们在系统的最后,增加一个信道估计误差计算程序。
2.1 信道估计误差计算模块
这里,我们使用的信道估计误差计算公式如下:
为了计算方便,我们使用m*mse,即:
这样方便FPGA中的误差计算。
然后m值,我们不考虑一个固定值,而是一直累加,直到所设置的仿真时间结束。
我们编写如下的verilog程序:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/04/22 20:05:37
// Design Name:
// Module Name: hmse
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module hmse(
input i_clk,
input i_rst,
input signed[1:0]ien,
input signed[15:0]i_hi,
input signed[15:0]i_hq,
input signed[15:0]i_HestI,
input signed[15:0]i_HestQ,
output signed[31:0]o_mse
);
reg signed[15:0]r1_X;
reg signed[15:0]r2_X;
reg signed[15:0]r3_X;
reg signed[15:0]r4_X;
reg signed[15:0]r5_X;
reg signed[15:0]r6_X;
reg signed[15:0]r7_X;
reg signed[15:0]r8_X;
reg signed[15:0]r9_X;
reg signed[15:0]r10_X;
reg signed[15:0]r11_X;
reg signed[15:0]r12_X;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
r1_X <= 16'd0;
r2_X <= 16'd0;
r3_X <= 16'd0;
r4_X <= 16'd0;
r5_X <= 16'd0;
r6_X <= 16'd0;
r7_X <= 16'd0;
r8_X <= 16'd0;
r9_X <= 16'd0;
r10_X <= 16'd0;
r11_X <= 16'd0;
r12_X <= 16'd0;
end
else begin
r1_X <= i_hi;
r2_X <= r1_X;
r3_X <= r2_X;
r4_X <= r3_X;
r5_X <= r4_X;
r6_X <= r5_X;
r7_X <= r6_X;
r8_X <= r7_X;
r9_X <= r8_X;
r10_X <= r9_X;
r11_X <= r10_X;
r12_X <= r11_X;
end
end
reg signed[15:0]r1_Xb;
reg signed[15:0]r2_Xb;
reg signed[15:0]r3_Xb;
reg signed[15:0]r4_Xb;
reg signed[15:0]r5_Xb;
reg signed[15:0]r6_Xb;
reg signed[15:0]r7_Xb;
reg signed[15:0]r8_Xb;
reg signed[15:0]r9_Xb;
reg signed[15:0]r10_Xb;
reg signed[15:0]r11_Xb;
reg signed[15:0]r12_Xb;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
r1_Xb <= 16'd0;
r2_Xb <= 16'd0;
r3_Xb <= 16'd0;
r4_Xb <= 16'd0;
r5_Xb <= 16'd0;
r6_Xb <= 16'd0;
r7_Xb <= 16'd0;
r8_Xb <= 16'd0;
r9_Xb <= 16'd0;
r10_Xb <= 16'd0;
r11_Xb <= 16'd0;
r12_Xb <= 16'd0;
end
else begin
r1_Xb <= i_hq;
r2_Xb <= r1_Xb;
r3_Xb <= r2_Xb;
r4_Xb <= r3_Xb;
r5_Xb <= r4_Xb;
r6_Xb <= r5_Xb;
r7_Xb <= r6_Xb;
r8_Xb <= r7_Xb;
r9_Xb <= r8_Xb;
r10_Xb <= r9_Xb;
r11_Xb <= r10_Xb;
r12_Xb <= r11_Xb;
end
end
reg signed[47:0]ww_sI;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
ww_sI <= 48'd0;
end
else begin
if(ien==0)
ww_sI<=ww_sI;
else
ww_sI<=ww_sI+$signed(r10_X-i_HestI) *$signed(r10_X-i_HestI)+$signed(r10_Xb-i_HestQ)*$signed(r10_Xb-i_HestQ);
end
end
assign o_mse=ww_sI[47:16];
endmodule
2.2 顶层模块修改
我们修改下顶层文件tops,调用2.1给出的信道估计误差计算模块:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/03/07 20:01:15
// Design Name:
// Module Name: tops
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tops(
input i_clk,
input i_rst,
input[5:0]i_SNR,
output signed[1:0]o_bitsI,
output signed[1:0]o_bitsQ,
output signed[1:0]o_politI,
output signed[1:0]o_politQ,
output [1:0]o_bit_politI,
output [1:0]o_bit_politQ,
output signed[15:0]o_hI,
output signed[15:0]o_hQ,
output signed[15:0]o_noiseI,
output signed[15:0]o_noiseQ,
output[15:0]o_bitshnI,
output[15:0]o_bitshnQ,
output signed[15:0]o_getpolitI,
output signed[15:0]o_getpolitQ,
output signed[15:0]o_HestI,
output signed[15:0]o_HestQ,
output signed[15:0]o_Hest_insertI,
output signed[15:0]o_Hest_insertQ,
output signed[15:0]o_YeqI,
output signed[15:0]o_YeqQ,
output reg signed[15:0]o_cnt_err,
output reg signed[15:0]o_cnt_all,
output signed[31:0]o_mse
);
//插入导频
Polit_insert Polit_insert_u(
.i_clk (i_clk),
.i_rst (i_rst),
.o_bitsI (o_bitsI),
.o_bitsQ (o_bitsQ),
.o_politI (o_politI),
.o_politQ (o_politQ),
.o_bit_politI (o_bit_politI),
.o_bit_politQ (o_bit_politQ)
);
通过信道
channel_tops channel_tops_u(
.i_clk (i_clk),
.i_rst (i_rst),
.i_SNR (i_SNR),
.i_bitsI (o_bit_politI),
.i_bitsQ (o_bit_politQ),
.o_hI (o_hI),
.o_hQ (o_hQ),
.o_noiseI (o_noiseI),
.o_noiseQ (o_noiseQ),
.o_bitshnI (o_bitshnI),
.o_bitshnQ (o_bitshnQ)
);
R_LS R_LS_u(
.i_clk (i_clk),
.i_rst (i_rst),
.i_bitshnI (o_bitshnI),
.i_bitshnQ (o_bitshnQ),
.o_getpolitI (o_getpolitI),
.o_getpolitQ (o_getpolitQ),
.o_HestI (o_HestI),
.o_HestQ (o_HestQ),
.o_Hest_insertI(o_Hest_insertI),
.o_Hest_insertQ(o_Hest_insertQ),
.o_YeqI (o_YeqI),
.o_YeqQ (o_YeqQ)
);
//统计误码
reg[31:0] dlyr1;
reg[31:0] dlyr2;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
dlyr1 <= 32'd0;
dlyr2 <= 32'd0;
end
else begin
dlyr1 <= {dlyr1[30:0],o_bit_politI[1]};
dlyr2 <= {dlyr2[30:0],o_bit_politI[0]};
end
end
reg[31:0] dlyr1b;
reg[31:0] dlyr2b;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
dlyr1b <= 32'd0;
dlyr2b <= 32'd0;
end
else begin
dlyr1b <= {dlyr1b[30:0],o_bit_politQ[1]};
dlyr2b <= {dlyr2b[30:0],o_bit_politQ[0]};
end
end
wire [1:0]bits1I={dlyr1[16],dlyr2[16]};
wire [1:0]bits2I={o_YeqI[15],1'b1};
wire [1:0]bits1Q={dlyr1b[16],dlyr2b[16]};
wire [1:0]bits2Q={o_YeqQ[15],1'b1};
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
begin
o_cnt_all <= 16'd0;
o_cnt_err <= 16'd0;
end
else begin
if(o_bit_politI==0 & o_bit_politQ==0)
begin
o_cnt_all <= o_cnt_all;
o_cnt_err <= o_cnt_err;
end
else begin
if(bits1I==bits2I & bits1Q==bits2Q)
begin
o_cnt_all <= o_cnt_all+1;
o_cnt_err <= o_cnt_err;
end
else
begin
o_cnt_all <= o_cnt_all+1;
o_cnt_err <= o_cnt_err+1;
end
end
end
end
//信道估计MSE误差统计
wire signed[31:0]o_mse;
hmse hmseu(
.i_clk (i_clk),
.i_rst (i_rst),
.ien (o_bit_politI),
.i_hi (o_hI),
.i_hq (o_hQ),
.i_HestI (o_Hest_insertI),
.i_HestQ (o_Hest_insertQ),
.o_mse (o_mse)
);
endmodule
2.3 testbench修改
由于2.2修改完顶层模块tops之后,我们增加了一个信道估计误差接口,所以需要修改下testbench:
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/03/02 03:31:40
// Design Name:
// Module Name: TEST
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module TEST();
reg i_clk;
reg i_rst;
reg[7:0]i_SNR;
wire[1:0]o_bitsI;
wire[1:0]o_bitsQ;
wire[1:0]o_politI;
wire[1:0]o_politQ;
wire[1:0]o_bit_politI;
wire[1:0]o_bit_politQ;
wire signed[15:0]o_hI;
wire signed[15:0]o_hQ;
wire signed[15:0]o_noiseI;
wire signed[15:0]o_noiseQ;
wire signed[15:0]o_bitshnI;
wire signed[15:0]o_bitshnQ;
wire signed[15:0]o_getpolitI;
wire signed[15:0]o_getpolitQ;
wire signed[15:0]o_HestI;
wire signed[15:0]o_HestQ;
wire signed[15:0]o_Hest_insertI;
wire signed[15:0]o_Hest_insertQ;
wire signed[15:0]o_YeqI;
wire signed[15:0]o_YeqQ;
wire signed[15:0]o_cnt_err;
wire signed[15:0]o_cnt_all;
wire signed[31:0]o_mse;
tops topsu(
.i_clk (i_clk),
.i_rst (i_rst),
.i_SNR (i_SNR),
.o_bitsI (o_bitsI),
.o_bitsQ (o_bitsQ),
.o_politI (o_politI),
.o_politQ (o_politQ),
.o_bit_politI (o_bit_politI),
.o_bit_politQ (o_bit_politQ),
.o_hI (o_hI),
.o_hQ (o_hQ),
.o_noiseI (o_noiseI),
.o_noiseQ (o_noiseQ),
.o_bitshnI (o_bitshnI),
.o_bitshnQ (o_bitshnQ),
.o_getpolitI (o_getpolitI),
.o_getpolitQ (o_getpolitQ),
.o_HestI (o_HestI),
.o_HestQ (o_HestQ),
.o_Hest_insertI(o_Hest_insertI),
.o_Hest_insertQ(o_Hest_insertQ),
.o_YeqI (o_YeqI),
.o_YeqQ (o_YeqQ),
.o_cnt_err (o_cnt_err),
.o_cnt_all (o_cnt_all),
.o_mse (o_mse)
);
initial
begin
i_clk=1'b1;
i_rst=1'b1;
i_SNR=2;//设置范围5~38
#1000
i_rst=1'b0;
end
always #5 i_clk=~i_clk;
integer fout1;
integer fout2;
integer fout3;
integer fout4;
initial begin
fout1 = $fopen("IT.txt","w");
fout2 = $fopen("QT.txt","w");
fout3 = $fopen("IR.txt","w");
fout4 = $fopen("QR.txt","w");
end
always @ (posedge i_clk)
begin
if(i_rst==1'b0)
begin
$fwrite(fout1,"%d\n",o_bitshnI);
$fwrite(fout2,"%d\n",o_bitshnQ);
$fwrite(fout3,"%d\n",o_YeqI);
$fwrite(fout4,"%d\n",o_YeqQ);
end
end
endmodule
2.4 MMSE信道估计整体工程
此时,我们完成了MMSE信道整个工程的FPGA实现,整个系统的代码如下:
3.基于FPGA的MMSE信道估计整体测试-对比LS信道估计
由于MMSE信道估计,其主要优势在SNR较小时提现,因此测试对比时,我们在testbench中,将SNR设置为2db。如下所示:
我们首先测试MMSE信道估计,对本系统进行行为仿真:
可以看到,当SNR=2db时,总共测试12880个符号,错误1519个,信道估计误差为3175974。
然后我们测试LS信道估计,我们可以直接打开MMSE信道估计这个工程,打开Hest这个程序:
把1部分注释,然后换为2部分,相当于把MMSE信道估计公式:
h_mmse= R_HH * inv(R_HH_LS_LS)* H_ls;
变为
h_mmse= H_ls;
这样就等效为LS信道估计,仿真测试结果如下:
可以看到,当SNR=2db时,总共测试12880个符号,错误1523个,信道估计误差为3317075。
通过对比可以看到,MMSE信道估计性能优于LS信道估计。
4.视频操作步骤演示
如果上述操作有什么不熟悉的地方,也可以参考如下的视频教程完成课程学习。
【教程4>第6章>第26节】基于FPGA的MMSE信道估计与均衡系统实现与整体测试,并对比LS信道估计_哔哩哔哩_bilibili