论文《基于FPGA 的CFAR 设计与实现》复现
Posted 者乎之类的
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了论文《基于FPGA 的CFAR 设计与实现》复现相关的知识,希望对你有一定的参考价值。
论文+代码链接:https://download.csdn.net/download/weixin_44884357/81425464
书接上回,老师让做czt后,再做一cfar
cfar算法原理:均值类CFAR 适用于空间上统计平稳的背景,它在检测单元前、后沿各有一个覆盖若干距离单元的滑动窗,利用滑动窗中参考采样的均值,形成前、后沿局部估计,再对局部估计平均、选大、选小或加权平均,以确定检测单元的背景杂波平均功率估计。 鉴于信号可能会跨越到前后邻近单元中,检测单元及其临近前后距离单元一般不包括在平均窗内,若检测单元中信号幅度大于滑动窗内均值的K 倍,则认为是信号。
*
matlab仿真
%% 程序初始化
clc;clear all;close all;
%% 杂波边缘背景噪声(单目标&多目标)
shape=[800,1000];
variance=200;
noise_db=[20,30];
noise_p=10.^(noise_db./10);
show_out=0;
[ xc ] = env_edge(variance, shape, noise_db,show_out);
% 多目标
SNR1=15;signal1_p=10.^(SNR1./10).*noise_p(1,end);
% SNR2=12;signal2_p=10.^(SNR2./10).*noise_p(1,end);
% SNR3=8;signal3_p=10.^(SNR3./10).*noise_p(1,end);
% SNR4=5;signal4_p=10.^(SNR4./10).*noise_p(1,end);
loc1=randi([43,44],1,1);
xc(1,100:100)=signal1_p;
% loc2=randi([46,48],1,1);
% xc(1,loc2)=signal3_p;
% loc3=randi([50,53],1,1);
% xc(1,loc3)=signal2_p;
% loc4=randi([55,58],1,1);
% xc(1,loc4)=signal1_p;
% % loc5=randi([90,93],1,1); %接近杂波区,但是依然在
% % xc(1,loc5)=signal1_p;
% % xc(1,loc5)=signal2_p; %这种杂波边缘有目标的情况,还需要优化
% % xc(1,loc5)=signal3_p;
%
% loc6=randi([102,108],1,1);
% xc(1,loc6)=signal3_p;
%% 算法结果&图谱显示
N=40;
pro_N=6;
PAD=10^(-4);
[ index, XT,cc ] = cfar_go( abs(xc), N, pro_N, PAD);
figure;
plot(10.*log(abs(xc))./log(10)),hold on;
plot(index,10.*log(abs(XT))./log(10)),hold on;
N=20;
xc=abs(xc./max(abs(xc)));
y_n1=round(xc*(2^(N-2))); %N比特量化;如果有n个信号相加,则设置(N-n)
%=============写入外部文件==============%
y_n=y_n1;
y_n(find(y_n<0))=y_n(find(y_n<0))+2^32;
% y_n=dec2bin(y_n);
%=============写入外部文件==============%
fid=fopen('C:\\Users\\lcy\\Desktop\\cfar\\input_data.txt','wt');
for ii=1:1000
B=dec2bin(y_n(ii),32);
for jj=1:32
if B(jj)=='1'
tb=1;
else
tb=0;
end
fprintf(fid,'%d',tb);
end
fprintf(fid,'\\n');
end
% fprintf(fid,';');
fclose(fid);
function [ index, XT,cc ] = cfar_go( xc, N, pro_N, PAD)
% 假设回波服从高斯分布
alpha=N.*(PAD.^(-1./N)-1);
index=1+N/2+pro_N/2:length(xc)-N/2-pro_N/2;
XT=zeros(1,length(index));
for i=index
cell_left=xc(1,i-N/2-pro_N/2:i-pro_N/2-1);
cell_right=xc(1,i+pro_N/2+1:i+N/2+pro_N/2);
Z=max([mean(cell_left),mean(cell_right)]);
cc(i)=mean(cell_left);
XT(1,i-N/2-pro_N/2)=Z.*alpha;
end
end
verilog
-
实现流程整体参考论文《基于FPGA的CFAR设计与实现_高亚军》
-
设计输入与输出
input [7:0] Y; //用以控制门限
input clk_in;
input rst_n;
input [31:0] din_r; //输入信号
input strt; //输入信号起始标志,在strt为一个时钟宽度脉冲后,din_r连续512个数据有效
output reg [8:0]xlabel; //检测目标坐标值
output endcfar; // cfar模块工作结束标志
output [8:0]max_addr; //若检测不到目标,则输出信号最大值坐标值 -
代码详细步骤
(1) 通过cnt计数得到vld信号,vld信号指示din_r信号有效,得到用于运算的512点din数据;即控制只进行512点数据的CFAR运算;
(2) din信号延迟latency_a;延迟时间量为窗宽度WIN_L个clk(原理参考论文)
(3) 加法器得到窗值
(4) 前后窗距离延迟latency_c;延迟时间量为WIN_L+PROTECTION_UNIT+1+PROTECTION_UNIT(原理参考论文)
(5) 被检测单元延迟latency_b;延迟时间量理论应为PROTECTION_UNIT+1,但代码中窗与基础门限相乘耗费了4个clk周期以及选窗耗费了1个clk周期;因此latency_b共延迟PROTECTION_UNIT+1+5
(6) 窗计算:窗值乘以系数Y得到参考门限;这里:为使系数效果可以为非整数倍,将窗值右移2位(即缩小4倍)2’b0,front_window_in[31:2]后再乘以系数Y;移位与乘系数Y配合使用得到最终缩放比例。例如若代码中输入Y=10;则实际放大倍数为10/4=2.5。
(7) gate_en信号指示输出坐标计数器cnt_gate有效,并因此得到cfar停止工作标志信号endcfar
(8) 比较判决。flag<=1; //发现目标
flag<=0; //没有发现目标
取flag信号上边沿,得到trig信号;trig信号触发输出坐标计数器得到目标输出坐标值xlabel
max_addr信号一直输出最大值坐标,
module CFAR(
clk_in,
rst_n,
din_r,
strt,
Y,
xlabel,
endcfar,
max_addr
);
parameter PROTECTION_UNIT = 3 ; //保护单元 3
parameter WIN_L = 30 ; //门限参考窗长
//parameter Y = 5;// //基础门限
input [7:0] Y;
input clk_in;
input rst_n;
input [31:0] din_r;
input strt;
output reg [8:0]xlabel;
output endcfar;
output [8:0]max_addr;
reg [8:0]cnt;
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
cnt<=9'd511;
end
else if(strt)begin
cnt<=9'd0;
end
else begin
cnt<=cnt+1'b1;
end
end
//vld指示din_r
reg vld;
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
vld<=1'b0;
end
else if(strt)begin
vld<=1'b1;
end
else if(cnt==9'd511) begin
vld<=1'b0;
end
end
reg[31:0]din;
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
din<=32'b0;
end
else if(!vld)begin
din<=32'b0;
end
else begin
din<=5din_r[31],din_r[31:5];
end
end
//latency_a 窗长度
reg [31:0] late_a[WIN_L-1:0];
genvar i;
generate for(i=0;i<WIN_L;i=i+1)begin:latency_a
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n) begin
late_a[i]<=10'b0;
end
else if(i==0)begin
late_a[i]<=din;
end
else begin
late_a[i]<=late_a[i-1];
end
end
end
endgenerate
//加法器
reg [31:0] SYNTHESIZED_WIRE_A;
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n) begin
SYNTHESIZED_WIRE_A<=32'b0;
end
else begin
SYNTHESIZED_WIRE_A<=SYNTHESIZED_WIRE_A + din - late_a[WIN_L-1];
end
end
//latency_c 前后窗距离=w+p+1+p
reg [31:0] late_c[WIN_L+PROTECTION_UNIT+1+PROTECTION_UNIT-1:0];
generate for(i=0;i<=WIN_L+PROTECTION_UNIT+1+PROTECTION_UNIT-1;i=i+1)begin:latency_c
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n) begin
late_c[i]<=32'b0;
end
else if(i==0)begin
late_c[i]<=SYNTHESIZED_WIRE_A;
end
else begin
late_c[i]<=late_c[i-1];
end
end
end
endgenerate
//latency_b,被检测单元,延迟p+1
reg [31:0]late_b[PROTECTION_UNIT+1+5-1:0];
generate for(i=0;i<PROTECTION_UNIT+1+5;i=i+1)begin:latency_b
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n) begin
late_b[i]<=10'b0;
end
else if(i==0)begin
late_b[i]<=late_a[WIN_L-1];
end
else begin
late_b[i]<=late_b[i-1];
end
end
end
endgenerate
//窗
wire [31:0]front_window_in,rear_window_in;
assign front_window_in=SYNTHESIZED_WIRE_A;
assign rear_window_in=late_c[WIN_L+PROTECTION_UNIT+1+PROTECTION_UNIT-1];
//gate_sc delay 4+1
wire [31:0] gate_sc_front,gate_sc_rear;
mul_Y mul_Y_front (
.clk(clk_in),
.a(2'b0,front_window_in[31:2]),
.b(Y),
.p(gate_sc_front)
);
mul_Y mul_Y_rear (
.clk(clk_in),
.a(2'b0,rear_window_in[31:2]),
.b(Y),
.p(gate_sc_rear)
);
reg [31:0] gate_sc;
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n) begin
gate_sc<=32'b0;
end
else if(front_window_in<rear_window_in)begin
gate_sc<=gate_sc_rear;
end
else begin
gate_sc<=gate_sc_front;
end
end
//gate_en
wire gate_en;
reg [1+WIN_L+PROTECTION_UNIT+1+5-1:0]gate_en_r;//延迟1+w+p+1+5
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
gate_en_r<=(1+WIN_L+PROTECTION_UNIT+1+5)1'b0;
end
else begin
gate_en_r<=gate_en_r[1+WIN_L+PROTECTION_UNIT+1+3:0],vld;
end
end
assign gate_en=gate_en_r[1+WIN_L+PROTECTION_UNIT+1+4];
//endcfar
reg gate_en_d;
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
gate_en_d<=1'b0;
end
else begin
gate_en_d<=gate_en;
end
end
assign endcfar=!gate_en &gate_en_d;
reg [8:0]cnt_gate;
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
cnt_gate<=9'b0;
end
else if(strt)begin
cnt_gate<=9'b0;
end
else if(gate_en)begin
cnt_gate<=cnt_gate+1'b1;
end
end
//比较器
wire [31:0]test_in;
assign test_in=late_b[PROTECTION_UNIT+1+5-1];
reg flag;
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n) begin
flag<=1'b0;
end
else if(strt)begin
flag<=1'b0;
end
else if (test_in > gate_sc) begin
flag<=1; //发现目标
end
else begin
flag<=0; //没有发现目标
end
end
reg flag_d;
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
flag_d<=1'b0;
end
else begin
flag_d<=flag;
end
end
wire trig;
assign trig=flag&!flag_d;
always@(posedge clk_in or negedge rst_n) begin
if(!rst_n)begin
xlabel<=9'b0;
end
else if(strt)begin
xlabel<=9'b0;
end
else if(trig)begin
xlabel<=cnt_gate-1;
end
end
reg[31:0] max;
reg [8:0]max_addr;
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
max<=32'b0;
max_addr<=9'b0;
end
else if(strt)begin
max<=32'b0;
max_addr<=9'b0;
end
else if(max<test_in)begin
max<=test_in;
max_addr<=cnt_gate;
end
end
endmodule
用的fft后的结果
以上是关于论文《基于FPGA 的CFAR 设计与实现》复现的主要内容,如果未能解决你的问题,请参考以下文章
基于OMAPL138 +FPGA 48通道采集器的设计与实现