导向滤波的Verilog (GuidedFilter.v)

红外热成像技术交流QQ群 : 1051855150

/**********************************************************************************************************************
 *FileName          : GuidedFilter.sv  
 *Version           : D20230616R1321V01 
 *Description       : GuidedFilter
 *History           :
 *      Date          Author    Modification
 *  1.  2023.06.16    Y.L       
 **********************************************************************************************************************/
 
`timescale 1ns/1ps

module GuidedFilter #( 
	parameter IMAGE_WIDTH   = 640   ,
	parameter IMAGE_HEIGHT  = 512   ,
    parameter DATA_WIDTH    = 14    ,
    parameter NUMTAPS       = 5
)(
	input   wire                                			clock				, 
	input   wire                                			rstn            	, 
										
	input	wire											GuidedFilterEn		,
	input	wire    [15:0]            						GuidedEps			,
									
    input   wire                                			video_ifval	    	,
    input   wire                                			vedeo_ilval	    	,
    input   wire    [DATA_WIDTH-1:0]            			video_idata	    	,
									
    output  reg                                 			video_ofval	    	,
    output  reg                                 			vedeo_olval	    	,
    output  reg     [DATA_WIDTH-1:0]            			video_odata			,
    output  reg     [DATA_WIDTH-1:0]            			Shifter_DataO		
); 
reg   	[15:0]												GuidedEps_r; 
	
wire                                     					guide_ofval, guide_olval, guide_odval;
wire    [DATA_WIDTH*NUMTAPS*NUMTAPS-1:0]					guide_odat2;   
wire    [DATA_WIDTH-1:0]                 					guide_odat2_w  [NUMTAPS*NUMTAPS-1:0];
	
reg		[39:0]												guide_ofval_r, guide_olval_r, guide_odval_r;
reg		[DATA_WIDTH-1:0] 									guide_odat1_r [39:0];
	
reg		[DATA_WIDTH+$clog2(NUMTAPS)-1:0]					guide_meanI_w1sum1, guide_meanI_w1sum2, guide_meanI_w1sum3, guide_meanI_w1sum4, guide_meanI_w1sum5/*synthesis preserve*/;
reg		[DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS)-1:0]			guide_meanI_w2sum1, guide_meanI_w2sum2; 
reg		[DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS)-1:0]			sum_I; 
reg		[DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS)-1:0]			sum_I_d  [35:0];
	
wire	[39:0]												dsp48_out1	[(NUMTAPS*NUMTAPS)-1:0];
reg		[DATA_WIDTH*2+$clog2(NUMTAPS)-1:0]					guide_meanIP_w1sum1, guide_meanIP_w1sum2, guide_meanIP_w1sum3, guide_meanIP_w1sum4, guide_meanIP_w1sum5/*synthesis preserve*/;
reg		[DATA_WIDTH*2+$clog2(NUMTAPS*NUMTAPS)-1:0]			sum_Ip;
	
wire	[(DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS))*2-1:0]		sum_I_w;
reg		[(DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS))*2-1:0]		sum_I_r;
reg		[DATA_WIDTH*2+$clog2(NUMTAPS*NUMTAPS)+6:0]			sum_Ip_r;
	
reg   	[(DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS))*2-1:0]		cov_Ip;
	
reg 	[55:0]												numer;
reg		[39:0]												denom;
wire	[55:0]												quotient;
reg		[DATA_WIDTH-1:0]									ax, ax1, ax_; 
reg		[47:0]												dsp48_out3;
wire	[47:0]												dsp48_out3_w;
reg		[DATA_WIDTH-1:0]									a, b; 
wire	[DATA_WIDTH-1:0]									a_w, b_w; 

wire														mean_a_ofval, mean_a_olval, mean_a_odval; 
wire    [DATA_WIDTH*NUMTAPS*NUMTAPS-1:0]					mean_a_odat2;
wire    [DATA_WIDTH-1:0]                 					mean_a_odat2_w  [NUMTAPS*NUMTAPS-1:0];
		
wire    [DATA_WIDTH*NUMTAPS*NUMTAPS-1:0]					mean_b_odat2;
wire    [DATA_WIDTH-1:0]                 					mean_b_odat2_w  [NUMTAPS*NUMTAPS-1:0];
		
reg		[7:0]												mean_a_ofval_r, mean_a_olval_r, mean_a_odval_r;
		
reg		[DATA_WIDTH+$clog2(NUMTAPS):0]						mean_a_w1sum1, mean_a_w1sum2, mean_a_w1sum3, mean_a_w1sum4, mean_a_w1sum5; 
reg		[DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS):0]				mean_a_w2sum1, mean_a_w2sum2;
reg		[DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS):0]				mean_a_w3sum1; 
		
reg		[DATA_WIDTH+$clog2(NUMTAPS)-1:0]					mean_b_w1sum1, mean_b_w1sum2, mean_b_w1sum3, mean_b_w1sum4, mean_b_w1sum5; 
reg		[DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS)-1:0]			mean_b_w2sum1, mean_b_w2sum2;
reg		[DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS)-1:0]			mean_b_w3sum1;
reg		[DATA_WIDTH+$clog2(NUMTAPS*NUMTAPS)+7:0]			mean_b_w3sum1_r; 
		
wire  	[DATA_WIDTH-1:0]  									taps;
reg		[DATA_WIDTH-1:0]  									taps_r1 	[9:0]	; 
reg		[47:0]												result1, result2	;	
wire	[47:0]												result1_w, result2_w;

reg     [3:0]												video_ifval_r;
reg															video_ifval_pos;

reg		[3:0]												video_ifval_r1;
reg		[3:0]												vedeo_ilval_r1;
reg    	[DATA_WIDTH-1:0]            						video_idata_r1 	[3:0];
 
always @(posedge clock) begin
	video_ifval_r1 <= {video_ifval_r1[2:0], video_ifval};
    vedeo_ilval_r1 <= {vedeo_ilval_r1[2:0], vedeo_ilval};
end 

generate
genvar SRCDLY;
for(SRCDLY=0; SRCDLY<4; SRCDLY=SRCDLY+1) begin
	if (SRCDLY == 0) begin
		always @(posedge clock) begin 
			video_idata_r1[0] <= video_idata;
		end 
	end else begin 
		always @(posedge clock) begin
			video_idata_r1[SRCDLY] <= video_idata_r1[SRCDLY-1];
		end 
	end 
end
endgenerate

always @(posedge clock) begin
	video_ifval_r   <= {video_ifval_r[2:0], video_ifval};
	video_ifval_pos <= (/*video_ifval_r == 4'h3 || */ !rstn) ? 1'b1 : 1'b0;
end

always @(posedge clock) begin
	GuidedEps_r <= GuidedEps;
end 

Matrix5x5 #(
	.IMAGE_WIDTH   ( IMAGE_WIDTH 	),
	.IMAGE_HEIGHT  ( IMAGE_HEIGHT 	),
	.DATA_WIDTH    ( DATA_WIDTH    	),
	.NUMTAPS       ( NUMTAPS  		)
)u_Matrix5x5(
/*input   wire                                      */.clock           	( clock				), 
/*input   wire                                      */.rstn            	( !video_ifval_pos	), 
/*													*/
/*input   wire                                      */.video_ifval	    ( video_ifval_r1[3]	),
/*input   wire                                      */.vedeo_ilval	    ( vedeo_ilval_r1[3]	),
/*input   wire    [DATA_WIDTH-1:0]                  */.video_idata	    ( video_idata_r1[3]	),
/*													*/	
/*output  wire                                      */.video_ofval	    ( guide_ofval		),
/*output  wire                                      */.vedeo_olval	    ( guide_olval		), 
/*output  wire                                      */.vedeo_odval	    ( guide_odval		), 
/*output  wire    [DATA_WIDTH-1:0]                  */.video_odat1     	( 					),
/*output  wire    [DATA_WIDTH*NUMTAPS*NUMTAPS-1:0]  */.video_odat2      ( guide_odat2		)
);

generate
genvar m;
    for(m=0; m<=(NUMTAPS*NUMTAPS-1); m=m+1) begin
		assign guide_odat2_w[m] = guide_odat2[m*DATA_WIDTH+:DATA_WIDTH];
    end
endgenerate

always @(posedge clock) begin 
	guide_ofval_r <= {guide_ofval_r[38:0], guide_ofval};
	guide_olval_r <= {guide_olval_r[38:0], guide_olval};
	guide_odval_r <= {guide_odval_r[38:0], guide_odval};
end

generate
genvar dly;
for(dly=0; dly<40; dly=dly+1) begin
	if (dly == 0) begin
		always @(posedge clock) begin 
			guide_odat1_r[0] <= guide_odat2_w[(NUMTAPS*NUMTAPS-1)/2];
		end 
	end else begin 
		always @(posedge clock) begin
			guide_odat1_r[dly] <= guide_odat1_r[dly-1];
		end 
	end 
end
endgenerate

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* mean_p、mean_I & mean_Ip */ 
// DLY0
always @(posedge clock) begin 
	guide_meanI_w1sum1 <= guide_odat2_w[23] + guide_odat2_w[22] + guide_odat2_w[21] + guide_odat2_w[20];
	guide_meanI_w1sum2 <= guide_odat2_w[19] + guide_odat2_w[18] + guide_odat2_w[17] + guide_odat2_w[16] + guide_odat2_w[15];
	guide_meanI_w1sum3 <= guide_odat2_w[14] + guide_odat2_w[13] + guide_odat2_w[12] + guide_odat2_w[11] + guide_odat2_w[10];
	guide_meanI_w1sum4 <= guide_odat2_w[9]  + guide_odat2_w[8]  + guide_odat2_w[7]  + guide_odat2_w[6]  + guide_odat2_w[5];
	guide_meanI_w1sum5 <= guide_odat2_w[4]  + guide_odat2_w[3]  + guide_odat2_w[2]  + guide_odat2_w[1]  + guide_odat2_w[0];
end

generate
genvar num;
for(num=0; num<NUMTAPS*NUMTAPS; num=num+1) begin
	 multidsp48 u_mean_Ip(.sysclk(clock),.dsp48_inA1({5'b0, guide_odat2_w[num]}),.dsp48_inB1({4'b0, guide_odat2_w[num]}),.dsp48_out1(dsp48_out1[num]));
end
endgenerate 

// DLY1
always @(posedge clock) begin 
	guide_meanI_w2sum1 <= guide_meanI_w1sum1 + guide_meanI_w1sum2;
	guide_meanI_w2sum2 <= guide_meanI_w1sum3 + guide_meanI_w1sum4 + guide_meanI_w1sum5;
end

always @(posedge clock) begin 
	guide_meanIP_w1sum1 <= dsp48_out1[20] + dsp48_out1[21] + dsp48_out1[22] + dsp48_out1[23];	
	guide_meanIP_w1sum2 <= dsp48_out1[15] + dsp48_out1[16] + dsp48_out1[17] + dsp48_out1[18] + dsp48_out1[19];
	guide_meanIP_w1sum3 <= dsp48_out1[10] + dsp48_out1[11] + dsp48_out1[12] + dsp48_out1[13] + dsp48_out1[14];
	guide_meanIP_w1sum4 <= dsp48_out1[ 5] + dsp48_out1[ 6] + dsp48_out1[ 7] + dsp48_out1[ 8] + dsp48_out1[ 9];
	guide_meanIP_w1sum5 <= dsp48_out1[ 0] + dsp48_out1[ 1] + dsp48_out1[ 2] + dsp48_out1[ 3] + dsp48_out1[ 4];			
end

// DLY2
always @(posedge clock) begin
	sum_I <= guide_meanI_w2sum1 + guide_meanI_w2sum2;
end

generate
genvar MDLY;
for(MDLY=0; MDLY<36; MDLY=MDLY+1) begin
	if (MDLY == 0) begin
		always @(posedge clock) begin
			sum_I_d[0] <= sum_I;
		end
	end else begin
		always @(posedge clock) begin
			sum_I_d[MDLY] <= sum_I_d[MDLY-1];
		end
	end
end
endgenerate

always @(posedge clock) begin
	sum_Ip <= guide_meanIP_w1sum1 + guide_meanIP_w1sum2 + guide_meanIP_w1sum3 + guide_meanIP_w1sum4 + guide_meanIP_w1sum5;
end

// DLY3
assign sum_I_w = sum_I * sum_I;

always @(posedge clock) begin
	sum_I_r <= sum_I_w;
end

always @(posedge clock) begin
	sum_Ip_r <= {sum_Ip, 4'b0} + {sum_Ip, 3'b0}; 
end

// DLY4
always @(posedge clock) begin
	cov_Ip <= ( sum_Ip_r > sum_I_r) ? ( sum_Ip_r - sum_I_r) : 0; 
end

assign numer = cov_Ip * 16383;
assign denom = cov_Ip + GuidedEps_r*576;   //

div_covIp u_div_covIp //DLY32 
(    
    .reset  	( 1'b0  	), //( cov_Ip * 16384) / (cov_Ip + GuidedEps_r*25)    
	.clk 		( clock 	),
    .clken  	( 1'b1  	),
    .numer  	( numer 	),//56
    .denom  	( denom 	),//40
    .quotient 	( quotient 	),
    .remain 	(   		)
);

//DLY29 
always @(posedge clock) begin
	ax  <= (quotient >= 16383) ? 16383 : quotient[13:0];
	ax_ <= (quotient >= 16383) ? 0     : (16383 - quotient[13:0]);
end

//DLY30
always @(posedge clock) begin
	ax1 <= ax;
end 

always @(posedge clock) begin
	dsp48_out3 <= sum_I_d[34] * ax_;
end

assign dsp48_out3_w = (dsp48_out3[47:3] + dsp48_out3[2]) / 3;

//DLY31
always @(posedge clock) begin
	a <= ax1;
	b <= (dsp48_out3_w[47:14] > 16383) ? 16383 : (dsp48_out3_w[47:14] + dsp48_out3_w[13]);
end

assign a_w = (guide_odval_r[39]) ? a : 0;
assign b_w = (guide_odval_r[39]) ? b : guide_odat1_r[39];

/*********************************************************************************************************************************/
//
/*********************************************************************************************************************************/

// `define _TEST
 
myshift_taps #(
    .number_of_taps ( 1     			),
    .tap_distance   ( IMAGE_WIDTH*2   	),
    .width          ( DATA_WIDTH    	)
)u_myshift_taps(                    	
    .aclr           ( video_ifval_pos	),
    .clock          ( clock         	),
`ifdef _TEST
    .clken          ( vedeo_ilval	  	),
    .shiftin        ( video_idata	  	),
`else
    .clken         	( guide_olval_r[39]	),
    .shiftin       	( guide_odat1_r[39]	),
`endif
    .shiftout       (               	),
    .taps           ( taps          	) //0:new  IMAGE_WIDTH:old
);

generate
genvar n;
for(n=0; n<=9; n=n+1) begin : DLY1
	if (n == 0) begin
		always @(posedge clock) begin 
			taps_r1[0] <= taps;
		end 
	end else begin 
		always @(posedge clock) begin 
			taps_r1[n] <= taps_r1[n-1];
		end 
	end 
end
endgenerate
 
Matrix5x5 #(
	.IMAGE_WIDTH   ( IMAGE_WIDTH 	),
	.IMAGE_HEIGHT  ( IMAGE_HEIGHT 	),
	.DATA_WIDTH    ( DATA_WIDTH    	),
	.NUMTAPS       ( NUMTAPS  		)
)u_mean_a(
/*input   wire                                      */.clock           	( clock				), 
/*input   wire                                      */.rstn            	( !video_ifval_pos	), 
`ifdef _TEST
/*input   wire                                      */.video_ifval	    ( video_ifval	  	),
/*input   wire                                      */.vedeo_ilval	    ( vedeo_ilval	  	),
/*input   wire    [DATA_WIDTH-1:0]                  */.video_idata	    ( video_idata	  	),
`else
/*input   wire                                      */.video_ifval	    ( guide_ofval_r[39]	),
/*input   wire                                      */.vedeo_ilval	    ( guide_olval_r[39]	),
/*input   wire    [DATA_WIDTH-1:0]                  */.video_idata	    ( a_w 				),
`endif
/*output  wire                                      */.video_ofval	    ( mean_a_ofval		), // 与 taps_r1[3]
/*output  wire                                      */.vedeo_olval	    ( mean_a_olval		), 
/*output  wire                                      */.vedeo_odval	    ( mean_a_odval		), 
/*output  wire    [DATA_WIDTH-1:0]                  */.video_odat1     	(  					),
/*output  wire    [DATA_WIDTH*NUMTAPS*NUMTAPS-1:0]  */.video_odat2      ( mean_a_odat2		)
);

Matrix5x5 #(
	.IMAGE_WIDTH   ( IMAGE_WIDTH 	),
	.IMAGE_HEIGHT  ( IMAGE_HEIGHT 	),
	.DATA_WIDTH    ( DATA_WIDTH    	),
	.NUMTAPS       ( NUMTAPS  		)
)u_mean_b(
/*input   wire                                      */.clock           	( clock				), 
/*input   wire                                      */.rstn            	( !video_ifval_pos	), 
`ifdef _TEST	
/*input   wire                                      */.video_ifval	    ( video_ifval	  	),
/*input   wire                                      */.vedeo_ilval	    ( vedeo_ilval	  	),
/*input   wire    [DATA_WIDTH-1:0]                  */.video_idata	    ( video_idata	  	),
`else
/*input   wire                                      */.video_ifval	   	( guide_ofval_r[39]	),
/*input   wire                                      */.vedeo_ilval	   	( guide_olval_r[39]	),
/*input   wire    [DATA_WIDTH-1:0]                  */.video_idata	   	( b_w 				),
`endif
/*output  wire                                      */.video_ofval	    (  					),
/*output  wire                                      */.vedeo_olval	    (  					), 
/*output  wire                                      */.vedeo_odval	    (  					), 
/*output  wire    [DATA_WIDTH-1:0]                  */.video_odat1     	(  					),
/*output  wire    [DATA_WIDTH*NUMTAPS*NUMTAPS-1:0]  */.video_odat2      ( mean_b_odat2		) 
);

always @(posedge clock) begin 
	mean_a_ofval_r <= {mean_a_ofval_r[6:0], mean_a_ofval};
	mean_a_olval_r <= {mean_a_olval_r[6:0], mean_a_olval};
	mean_a_odval_r <= {mean_a_odval_r[6:0], mean_a_odval};
end

generate
genvar i;
    for(i=0; i<=(NUMTAPS*NUMTAPS-1); i=i+1) begin : col_11
		assign mean_a_odat2_w[i] = mean_a_odat2[i*DATA_WIDTH+:DATA_WIDTH];
		assign mean_b_odat2_w[i] = mean_b_odat2[i*DATA_WIDTH+:DATA_WIDTH];
    end
endgenerate

//DLY1
always @(posedge clock) begin 
	mean_a_w1sum1 <= mean_a_odat2_w[23] + mean_a_odat2_w[22] + mean_a_odat2_w[21] + mean_a_odat2_w[20];
	mean_a_w1sum2 <= mean_a_odat2_w[19] + mean_a_odat2_w[18] + mean_a_odat2_w[17] + mean_a_odat2_w[16] + mean_a_odat2_w[15];
	mean_a_w1sum3 <= mean_a_odat2_w[14] + mean_a_odat2_w[13] + mean_a_odat2_w[12] + mean_a_odat2_w[11] + mean_a_odat2_w[10];
	mean_a_w1sum4 <= mean_a_odat2_w[9]  + mean_a_odat2_w[8]  + mean_a_odat2_w[7]  + mean_a_odat2_w[6]  + mean_a_odat2_w[5];
	mean_a_w1sum5 <= mean_a_odat2_w[4]  + mean_a_odat2_w[3]  + mean_a_odat2_w[2]  + mean_a_odat2_w[1]  + mean_a_odat2_w[0];
end

always @(posedge clock) begin 
	mean_b_w1sum1 <= mean_b_odat2_w[23] + mean_b_odat2_w[22] + mean_b_odat2_w[21] + mean_b_odat2_w[20];
	mean_b_w1sum2 <= mean_b_odat2_w[19] + mean_b_odat2_w[18] + mean_b_odat2_w[17] + mean_b_odat2_w[16] + mean_b_odat2_w[15];
	mean_b_w1sum3 <= mean_b_odat2_w[14] + mean_b_odat2_w[13] + mean_b_odat2_w[12] + mean_b_odat2_w[11] + mean_b_odat2_w[10];
	mean_b_w1sum4 <= mean_b_odat2_w[9]  + mean_b_odat2_w[8]  + mean_b_odat2_w[7]  + mean_b_odat2_w[6]  + mean_b_odat2_w[5];
	mean_b_w1sum5 <= mean_b_odat2_w[4]  + mean_b_odat2_w[3]  + mean_b_odat2_w[2]  + mean_b_odat2_w[1]  + mean_b_odat2_w[0];
end

//DLY2
always @(posedge clock) begin 
	mean_a_w2sum1 <= mean_a_w1sum1 + mean_a_w1sum5;
	mean_a_w2sum2 <= mean_a_w1sum2 + mean_a_w1sum3 + mean_a_w1sum4;
end

always @(posedge clock) begin 
	mean_b_w2sum1 <= mean_b_w1sum1 + mean_b_w1sum5;
	mean_b_w2sum2 <= mean_b_w1sum2 + mean_b_w1sum3 + mean_b_w1sum4;
end

//DLY3
always @(posedge clock) begin 
	mean_a_w3sum1 <= mean_a_w2sum1 + mean_a_w2sum2;
end

always @(posedge clock) begin 
	mean_b_w3sum1   <= mean_b_w2sum1 + mean_b_w2sum2; 
end

//DLY4 
assign result1_w = mean_a_w3sum1 * taps_r1[6];

always @(posedge clock) begin 
	result1 <= result1_w;
end

always @(posedge clock) begin  
	mean_b_w3sum1_r <= mean_b_w3sum1;
end

//DLY5
always @(posedge clock) begin 
	result2 <= result1 + {mean_b_w3sum1_r, 14'b0};
end 

assign result2_w = (result2[47:3] + result2[2]) / 3;

always @(posedge clock) begin
	video_ofval 	<= mean_a_ofval_r[6] | mean_a_ofval_r[7];	
	vedeo_olval 	<= mean_a_olval_r[4];
	video_odata 	<= ( mean_a_odval_r[4] & GuidedFilterEn) ? ((result2_w[47:14] > 16383) ? 16383 : (result2_w[47:14] + result2_w[13])) : taps_r1[8]; 
	Shifter_DataO 	<= taps_r1[8];		
end

endmodule

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#>木易

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值