论文《基于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

  1. 实现流程整体参考论文《基于FPGA的CFAR设计与实现_高亚军》
    在这里插入图片描述

  2. 设计输入与输出
    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; //若检测不到目标,则输出信号最大值坐标值

  3. 代码详细步骤
    (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<={{5{din_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后的结果
在这里插入图片描述

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值