基于FPGA的CFAR设计.docx
《基于FPGA的CFAR设计.docx》由会员分享,可在线阅读,更多相关《基于FPGA的CFAR设计.docx(23页珍藏版)》请在冰豆网上搜索。
基于FPGA的CFAR设计
基于FPGA的CFAR设计
基于FPGA的CFAR设计
摘要
恒虚警率(ConstantFalse-AlarmRate,CFAR)处理技术是雷达信号处理的重要组成部分。
在雷达信号检测中,当外界干扰强度变化时,雷达能自动调整其灵敏度,使雷达的虚警概率保持不变。
具有这种特性的接收机称为恒虚警接收机。
雷达信号的检测总是在干扰背景上进行的,干扰包括接收机内部的热噪声,以及地物、雨雪、海浪等杂波干扰。
其中,地杂波、海杂波、气象杂波和箔条杂波都是由天线波束照射区内的大量散射单元的散射信号叠加组成。
因此,在强干扰中提取信号,不仅要求有一定的信噪比,而且必须对信号作恒虚警处理。
在自动检测雷达中,必须具备恒虚警处理设备,使之在强杂波干扰下仍能继续工作。
本文首先介绍了恒虚警率(CFAR)的基本原理,然后利用FPGA方案对恒虚警率(CFAR)进行了实例设计,并对各子模块进行了详细说明,最后对整个模块进行仿真和验证。
关键词:
VerilogHDL、FPGA、恒虚警(CFAR)
一、绪论
恒虚警率(ConstantFalse-AlarmRate,CFAR)处理技术,用于在杂波环境变化时,防止雷达的虚警概率发生太大的变化,同时保证一定的检测概率。
为此,必须采用自适应门限检测电路。
利用自动检测电路来估测接收机的输出,以保持一个恒虚警率的系统便称为恒虚警率(CFAR)系统。
例如,PD雷达常用于机载下视或类似的条件下,因此由于不同的地物回波所形成的杂波强度分布情况十分复杂,为了在这样复杂的杂波环境中检测所关心的运动目标回波,则必须采用CFAR处理技术。
它是一种对杂波问题很有效的处理技术,可以随本地噪声能量信息设置门限。
雷达信号的检测总是在干扰背景上进行的,干扰包括接收机内部的热噪声,以及地物、雨雪、海浪等杂波干扰。
其中,地杂波、海杂波、气象杂波和箔条杂波都是由天线波束照射区内的大量散射单元的散射信号叠加组成。
因此,在强干扰中提取信号,不仅要求有一定的信噪比,而且必须对信号作恒虚警处理。
在自动检测雷达中,必须具备恒虚警处理设备,使之在强杂波干扰下仍能继续工作。
我们想要实现CFAR处理,传统方案是采用DSP加软件的方法实现,即用通用DSP芯片构造硬件处理机平台,通过编写处理软件实现CFAR算法。
这种方案对于距离分辨率不高的宽脉冲雷达来说,是一种简单可行的方法,但对于窄脉冲雷达,由于距离维采样频率很高,要求处理机硬件平台提供超高的运算速度,FPGA以其高的处理速度成为实现CFAR算法的一种好的选择。
本文提出一种基于FPGA的实现方案,该方案依据CFAR算法的独立性、规则性、算法的简单性和运算密集性等特点,顶层模块调用了一个CFAR算法模块和两个块存储器IP核,实现了数据长度为16bit,前、后窗长度为L=16位数据的ML类CFAR算法。
二、CFAR算法基本原理
一般通用的CFAR方案中,视频信号样本通过平方率包络检测器被送到滑窗寄存器中。
该寄存器长一般设定为N+1=2n+1,统计量Z是与噪声能量成比例的,而噪声能量是通过检测单元D周N个参考单元的某种处理而得到的。
U是一个恒量元素,在均匀背景下,与N、Pfa有关,给定参考单元数N及虚警概率Pfa对应的U是一个定值。
如果检测单元D的值大于门限U0,则该信号将被判决为目标信号。
根据μ的计算方式的不同,CFAR检测器分为均值(ML)类和有序统计量(OS)类两种典型的检测器,其原理图分别如图1和图2所示。
ML类CFAR包括单元平均(CA)CFAR、最大选择(GO)CFAR和最小选择(SO)CFAR等;OS类CFAR包括有序统计(OS)CFAR、削减平均(TM)CFAR等。
均值类CFAR适用于空间上统计平稳的背景,它在检测单元前、后沿各有一个覆盖若干距离单元的滑动窗,利用滑动窗中参考采样的均值,形成前、后沿局部估计,再对局部估计平均、选大、选小或加权平均,以确定检测单元的背景杂波平均功率估计。
鉴于信号可能会跨越到前后邻近单元中,检测单元及其临近前后距离单元一般不包括在平均窗内,若检测单元中信号幅度大于滑动窗内均值的K倍,则认为是信号。
图1ML类CFAR结构示意图
图2OS类CFAR结构示意图
本文利用如图1所示的CA-CFAR方法的FPGA来进行设计,在顶层模块调用了一个CFAR算法模块和两个块存储器IP核,实现了数据长度为16bit,前、后窗长度为L=16位数据的CA-CFAR算法。
三、FPGA设计与实现
CFAR电路由目标回波消除电路和恒虚警电路构成,下面分别介绍其VerilogHDL设计。
包括顶层模块设计、回波消除电路设计、恒虚警电路设计和块存储器IP核。
总框图如图3所示。
图3CFAR电路总结构示意图
3.1、顶层模块设计
对于CFAR电路首先要关注的是顶层模块的FPGA逻辑设计,其功能主要是对要实现的各子模块进行连接和统筹规划,使得各子模块能够正常运行从而实现所有功能。
顶层模块具体实现了数据连接、信号噪声的对比以及全局时钟缓存等功能。
设计程序如下所示:
`timescale1ns/1ps
moduletop(
inputclk,
inputrst,
input[15:
0]I_signal,
outputO_result
);
wire[15:
0]signal;
wire[15:
0]noise;
delu1(.clk(clk),
.rst(rst),
.I_signal(I_signal),
.O_signal(signal),
.O_noise(noise));
cfaru2(.clk(clk),
.rst(rst),
.I_signal(signal),
.I_noise(noise),
.O_result(O_result));
endmodule
3.2、回波消除电路设计
回波消除电路主要用来消除回波信号,以便后续电路计算噪声平均功率。
信号通过该模块后分为两路输出:
信号和回波消除后的噪声信号。
模块框图如图4所示。
图4回波消除电路框图
设计程序如下所示:
`timescale1ns/1ps
moduledel(
inputclk,
inputrst,
input[15:
0]I_signal,
output[15:
0]O_signal,
output[15:
0]O_noise
);
parameterpc=16'h0100;
reg[15:
0]O1_signal;
reg[15:
0]O1_noise;
reg[15:
0]R_signal;
reg[15:
0]R1_signal;
reg[17:
0]mult;
reg[15:
0]R_result;
reg[15:
0]compare;
//---------------signaloutput----------------
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
R_signal<=16'h0000;
R1_signal<=16'h0000;
O1_signal<=16'h0000;
end
else
begin
R_signal<=I_signal;
R1_signal<=R_signal;
O1_signal<=R1_signal;
end
end
assignO_signal=O1_signal;
//---------------noiseoutput-----------------
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
mult<=16'h0000;
end
else
begin
mult<=I_signal*3;
end
end
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
R_result<=16'h0000;
end
else
begin
if(R_signalbegin
R_result<=mult[17:
2]+{{2{R_result[15]}},R_result[15:
2]};
end
end
end
always@(*)
begin
compare<=R_result+pc;
end
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
O1_noise<=16'h0000;
end
else
begin
O1_noise<=R_result;
end
end
assignO_noise=O1_noise;
endmodule
3.3、恒虚警(CFAR)电路设计
恒虚警(CFAR)模块利用了移位寄存器实现恒虚警电路功能。
此模块是CFAR处理技术的核心,采样回波产生数据,并对这些数据进行定点化。
模块框图如图5所示。
图5恒虚警(CFAR)电路框图
设计程序如下所示:
`timescale1ns/1ps
modulecfar(
inputclk,
inputrst,
input[15:
0]I_signal,
input[15:
0]I_noise,
outputO_result
);
reg[15:
0]O1_result;
reg[15:
0]R_noise;
reg[15:
0]R1_noise;
reg[15:
0]R2_noise;
reg[15:
0]R3_noise;
reg[15:
0]R4_noise;
reg[15:
0]R5_noise;
reg[15:
0]R6_noise;
reg[15:
0]R7_noise;
reg[15:
0]R8_noise;
reg[15:
0]R9_noise;
reg[15:
0]R10_noise;
reg[15:
0]R11_noise;
reg[15:
0]R12_noise;
reg[15:
0]R13_noise;
reg[15:
0]R14_noise;
reg[19:
0]R_add;
reg[15:
0]R1_add;
reg[15:
0]R2_add;
reg[15:
0]R3_add;
reg[15:
0]R4_add;
reg[15:
0]R5_add;
reg[15:
0]R6_add;
reg[15:
0]R7_add;
reg[15:
0]R8_add;
reg[15:
0]R9_add;
reg[15:
0]R10_add;
reg[15:
0]R11_add;
reg[15:
0]R12_add;
reg[15:
0]R13_add;
reg[15:
0]R14_add;
reg[15:
0]R15_add;
reg[15:
0]R16_add;
reg[15:
0]R_average;
reg[15:
0]R_signal;
reg[15:
0]R1_signal;
reg[15:
0]R2_signal;
reg[15:
0]R3_signal;
reg[15:
0]R4_signal;
reg[15:
0]R5_signal;
reg[15:
0]R6_signal;
reg[15:
0]R7_signal;
reg[15:
0]R8_signal;
reg[15:
0]R9_signal;
reg[15:
0]R10_signal;
reg[15:
0]R11_signal;
reg[15:
0]R12_signal;
reg[15:
0]R13_signal;
reg[15:
0]R14_signal;
reg[15:
0]R15_signal;
reg[15:
0]R16_signal;
//---------------noiseshift----------------
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
R_noise<=16'h0000;
R1_noise<=16'h0000;
R2_noise<=16'h0000;
R3_noise<=16'h0000;
R4_noise<=16'h0000;
R5_noise<=16'h0000;
R6_noise<=16'h0000;
R7_noise<=16'h0000;
R8_noise<=16'h0000;
R9_noise<=16'h0000;
R10_noise<=16'h0000;
R11_noise<=16'h0000;
R12_noise<=16'h0000;
R13_noise<=16'h0000;
R14_noise<=16'h0000;
end
else
begin
R_noise<=I_noise;
R1_noise<=R_noise;
R2_noise<=R1_noise;
R3_noise<=R2_noise;
R4_noise<=R3_noise;
R5_noise<=R4_noise;
R6_noise<=R5_noise;
R7_noise<=R6_noise;
R8_noise<=R7_noise;
R9_noise<=R8_noise;
R10_noise<=R9_noise;
R11_noise<=R10_noise;
R12_noise<=R11_noise;
R13_noise<=R12_noise;
R14_noise<=R13_noise;
end
end
//---------------addnoise---------------
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
R_add<=20'h00000;
end
else
begin
R_add<=(((I_noise+R_noise)+(R1_noise+R2_noise))+
((R3_noise+R4_noise)+(R5_noise+R6_noise)))+
(((R7_noise+R8_noise)+(R9_noise+R10_noise))+
((R11_noise+R12_noise)+(R13_noise+R14_noise)));
end
end
//-------------noise_addshift-------------
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
R1_add<=16'h0000;
R2_add<=16'h0000;
R3_add<=16'h0000;
R4_add<=16'h0000;
R5_add<=16'h0000;
R6_add<=16'h0000;
R7_add<=16'h0000;
R8_add<=16'h0000;
R9_add<=16'h0000;
R10_add<=16'h0000;
R11_add<=16'h0000;
R12_add<=16'h0000;
R13_add<=16'h0000;
R14_add<=16'h0000;
R15_add<=16'h0000;
R16_add<=16'h0000;
end
else
begin
R1_add<=R_add[19:
4];
R2_add<=R1_add;
R3_add<=R2_add;
R4_add<=R3_add;
R5_add<=R4_add;
R6_add<=R5_add;
R7_add<=R6_add;
R8_add<=R7_add;
R9_add<=R8_add;
R10_add<=R9_add;
R11_add<=R10_add;
R12_add<=R11_add;
R13_add<=R12_add;
R14_add<=R13_add;
R15_add<=R14_add;
R16_add<=R15_add;
end
end
//--------------R_average-------------
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
R_average<=16'h0000;
end
else
begin
if(R_add[19:
4]>R16_add)
begin
R_average<=R_add[19:
4];
end
else
begin
R_average<=R16_add;
end
end
end
//--------------signalshift-------------
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
R_signal<=16'h0000;
R1_signal<=16'h0000;
R2_signal<=16'h0000;
R3_signal<=16'h0000;
R4_signal<=16'h0000;
R5_signal<=16'h0000;
R6_signal<=16'h0000;
R7_signal<=16'h0000;
R8_signal<=16'h0000;
R9_signal<=16'h0000;
R10_signal<=16'h0000;
R11_signal<=16'h0000;
R12_signal<=16'h0000;
R13_signal<=16'h0000;
R14_signal<=16'h0000;
R15_signal<=16'h0000;
R16_signal<=16'h0000;
end
else
begin
R_signal<=I_signal;
R1_signal<=R_signal;
R2_signal<=R1_signal;
R3_signal<=R2_signal;
R4_signal<=R3_signal;
R5_signal<=R4_signal;
R6_signal<=R5_signal;
R7_signal<=R6_signal;
R8_signal<=R7_signal;
R9_signal<=R8_signal;
R10_signal<=R9_signal;
R11_signal<=R10_signal;
R12_signal<=R11_signal;
R13_signal<=R12_signal;
R14_signal<=R13_signal;
R15_signal<=R14_signal;
R16_signal<=R15_signal;
end
end
//--------------output---------------
always@(posedgeclkornegedgerst)
begin
if(~rst)
begin
O1_result<=16'h0000;
end
else
begin
O1_result<=R16_signal-10*R_average;
end
end
assignO_result=~O1_result[15];
endmodule
3.4、块储存器设计
由于最后要通过得到信号与平均噪声的比值来判决CFAR归一化输出,而用数字电路实现除法运算比较复杂,故采用取对数的方法,将除法运算转化为减法运算,简化了电路实现。
通过调用Xilinx公司的BlockMemoryIP核,实现将信号和平均噪声取对数的运算。
四、仿真与测试
对CFAR电路初始化并复位后,输入预先生成的定点模拟回波。
然后编写Testbench程序对顶层模块进行仿真,用Modelsim工具对结果进行仿真,观察输出结果,与理论值对比,验证系统的正确性。
模块框图如图6所示。
图6Testbench激励框图
Testbench设计程序如下:
`timescale1ns/1ps
moduletop_test;
regclk;
regrst;
reg[15:
0]addr;
wire[15:
0]I_signal;
wireO_result;
always#5clk=~clk;
initial
begin
clk=0;
rst=0;
addr=0;
#103
rst=1;
end
always@(posedgeclk)
begin
if(rst)
begin
addr=addr+1;
end
end
romuut1(
.clka(clk),
.addra(addr),
.douta(I_signal)
);
topuut2(
.clk(clk),
.rst(rst),
.I_signal(I_signal),
.O_result(O_result)
);
endmodule
使用的输入数据为:
200,150,125,130,300,230,2100,215,230,230,115,235,130,210,110,230,
110,2500,270,240,210,130,115,130,110,220,205,220,115,230,125,230,
230,230,720,2400,270,250,215,120,120
仿真结果如图7、8所示:
图7仿真结果图1
图8仿真结果图2
从测试图可