红外热成像技术交流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
导向滤波的Verilog (GuidedFilter.v)
于 2025-08-01 14:23:56 首次发布
4万+

被折叠的 条评论
为什么被折叠?



