📄 color_proc333.v
字号:
always @ (posedge RST or posedge CLK) if (RST) pd0 <= 8'b0; else pd0 <= p1[7:0]; // generates more effective than with 2-bit SRs (line above)
assign ppa[8:0]={1'b0,pd0}+{1'b0,p0};
always @ (posedge CLK) pa0 <=ppa[8:1]; //loosing 1 bit here!
// next - 2 pairs of 8 bit wide 16-bit long serial-in, serial out shift registers. Verify implementation - Should use 32 LUTs
// update 06/10/2004 - make an output pd_c[7:0] 2 cycles after pd_1[7:0] for color processing without additional resources
reg [17:0] pd_10,pd_11,pd_12,pd_13,pd_14,pd_15,pd_16,pd_17;
// reg [17:0] pd_20,pd_21,pd_22,pd_23,pd_24,pd_25,pd_26,pd_27;
reg [7:0] pd1_dly;
reg [7:0] pdc;
reg [15:0] pd_20,pd_21,pd_22,pd_23,pd_24,pd_25,pd_26,pd_27;
reg [17:0] pa_10,pa_11,pa_12,pa_13,pa_14,pa_15,pa_16,pa_17;
reg [17:0] pa_20,pa_21,pa_22,pa_23,pa_24,pa_25,pa_26,pa_27;
wire [7:0] pd1;
wire [7:0] pd2;
wire [7:0] pa1;
wire [7:0] pa2;
assign pd1={pd_17[17],pd_16[17],pd_15[17],pd_14[17],pd_13[17],pd_12[17],pd_11[17],pd_10[17]};
assign pd2={pd_27[15],pd_26[15],pd_25[15],pd_24[15],pd_23[15],pd_22[15],pd_21[15],pd_20[15]};
assign pa1={pa_17[17],pa_16[17],pa_15[17],pa_14[17],pa_13[17],pa_12[17],pa_11[17],pa_10[17]};
assign pa2={pa_27[17],pa_26[17],pa_25[17],pa_24[17],pa_23[17],pa_22[17],pa_21[17],pa_20[17]};
always @ (posedge CLK) pd_10 <= {pd_10[16:0],pd0[0]};
always @ (posedge CLK) pd_11 <= {pd_11[16:0],pd0[1]};
always @ (posedge CLK) pd_12 <= {pd_12[16:0],pd0[2]};
always @ (posedge CLK) pd_13 <= {pd_13[16:0],pd0[3]};
always @ (posedge CLK) pd_14 <= {pd_14[16:0],pd0[4]};
always @ (posedge CLK) pd_15 <= {pd_15[16:0],pd0[5]};
always @ (posedge CLK) pd_16 <= {pd_16[16:0],pd0[6]};
always @ (posedge CLK) pd_17 <= {pd_17[16:0],pd0[7]};
always @ (posedge CLK) pd1_dly[7:0] <= pd1[7:0];
always @ (posedge CLK) pdc[7:0] <= pd1_dly[7:0];
always @ (posedge CLK) pd_20 <= {pd_20[14:0],pdc[0]};
always @ (posedge CLK) pd_21 <= {pd_21[14:0],pdc[1]};
always @ (posedge CLK) pd_22 <= {pd_22[14:0],pdc[2]};
always @ (posedge CLK) pd_23 <= {pd_23[14:0],pdc[3]};
always @ (posedge CLK) pd_24 <= {pd_24[14:0],pdc[4]};
always @ (posedge CLK) pd_25 <= {pd_25[14:0],pdc[5]};
always @ (posedge CLK) pd_26 <= {pd_26[14:0],pdc[6]};
always @ (posedge CLK) pd_27 <= {pd_27[14:0],pdc[7]};
always @ (posedge CLK) pa_10 <= {pa_10[16:0],pa0[0]};
always @ (posedge CLK) pa_11 <= {pa_11[16:0],pa0[1]};
always @ (posedge CLK) pa_12 <= {pa_12[16:0],pa0[2]};
always @ (posedge CLK) pa_13 <= {pa_13[16:0],pa0[3]};
always @ (posedge CLK) pa_14 <= {pa_14[16:0],pa0[4]};
always @ (posedge CLK) pa_15 <= {pa_15[16:0],pa0[5]};
always @ (posedge CLK) pa_16 <= {pa_16[16:0],pa0[6]};
always @ (posedge CLK) pa_17 <= {pa_17[16:0],pa0[7]};
always @ (posedge CLK) pa_20 <= {pa_20[16:0],pa_10[17]};
always @ (posedge CLK) pa_21 <= {pa_21[16:0],pa_11[17]};
always @ (posedge CLK) pa_22 <= {pa_22[16:0],pa_12[17]};
always @ (posedge CLK) pa_23 <= {pa_23[16:0],pa_13[17]};
always @ (posedge CLK) pa_24 <= {pa_24[16:0],pa_14[17]};
always @ (posedge CLK) pa_25 <= {pa_25[16:0],pa_15[17]};
always @ (posedge CLK) pa_26 <= {pa_26[16:0],pa_16[17]};
always @ (posedge CLK) pa_27 <= {pa_27[16:0],pa_17[17]};
wire [7:0] pd_prev= pd2[7:0];
wire [7:0] pd_next= pd0[7:0];
wire [7:0] pa_prev= pa2[7:0];
wire [7:0] pa_next= pa0[7:0];
// now the result Y calculation depends on the pixel position (bx,by). It consists of 3 terms, each with different coefficient.
// first term always includes pd1[7:0]
// if (bx[1]==by[1]) // 00 or 11
// second term is pa1, third - (pd0+pd2)/2
// else
// second term is (pa1 + (pd0+pd2)/2)/2, third - (pa0+pa2)/2
reg [7:0] m1;
reg [7:0] m2;
reg [7:0] m3;
wire [8:0] pd02s= {1'b0,pd_prev[7:0]}+{1'b0,pd_next[7:0]}; // will use pd02s[8:1]
wire [8:0] pa1pd02s={1'b0,pa1[7:0]}+{1'b0,pd02s[8:1]}; // will use pa1pd02s[8:1]
wire [8:0] pa02s= {1'b0,pa_prev[7:0]}+{1'b0,pa_next[7:0]}; // will use pa02s[8:1]
always @ (posedge CLK) m1 <= pd1[7:0];
// always @ (posedge CLK) m2 <= (odd_pix==odd_line)? pa1[7:0] : pa1pd02s[8:1];
// always @ (posedge CLK) m3 <= (odd_pix==odd_line)? pd02s[8:1] : pa02s[8:1];
always @ (posedge CLK) m2 <= pix_green? pa1[7:0] : pa1pd02s[8:1];
always @ (posedge CLK) m3 <= pix_green? pd02s[8:1] : pa02s[8:1];
/*
Y[0,0]=(0x96*P[0,0]+ 0x4d*((P[0,-1]+P[0,1])/2) + 0x1d*((P[-1,0]+P[1,0])/2))>>8
Y[0,1]=(0x4d*P[0,1]+ 0x96*((P[-1,1]+P[0,0]+P[0,2]+P[1,1])/4)+ 0x1d*((P[-1,0]+P[-1,2]+P[1,0]+P[1,2])/4))>>8
Y[1,0]=(0x1d*P[1,0]+ 0x96*((P[0,0]+P[1,-1]+P[1,1]+P[2,0])/4)+ 0x4d*((P[0,-1]+P[0,1]+P[2,-1]+P[2,1])/4))>>8
Y[1,1]=(0x96*P[1,1]+ 0x1d*((P[1,0]+P[1,2])/2 + 0x4d*((P[0,1] +P[2,1])/2)))>>8
+-----+--------+-------+-------+-------+-------+-------+
| | (0) | | | * | * | * * |
| | G R | * | * + * | + | * + * | + |
| | B G | | | * | * | * * |
+-----+--------+-------+-------+-------+-------+-------+
| 0 | P[0,0] | 0x96 | 0x4d | 0x1d | | |
| +--------+-------+-------+-------+-------+-------+
| G R | P[0,1] | 0x4d | | | 0x96 | 0x1d |
| +--------+-------+-------+-------+-------+-------+
| B G | P[1,0] | 0x1d | | | 0x96 | 0x4d |
| +--------+-------+-------+-------+-------+-------+
| | P[1,1] | 0x96 | 0x1d | 0x4d | | |
+-----+--------+-------+-------+-------+-------+-------+
| 1 | P[0,0] | 0x4d | | | 0x96 | 0x1d |
| +--------+-------+-------+-------+-------+-------+
| R G | P[0,1] | 0x96 | 0x4d | 0x1d | | |
| +--------+-------+-------+-------+-------+-------+
| G B | P[1,0] | 0x96 | 0x1d | 0x4d | | |
| +--------+-------+-------+-------+-------+-------+
| | P[1,1] | 0x1d | | | 0x96 | 0x4d |
+-----+--------+-------+-------+-------+-------+-------+
| 2 | P[0,0] | 0x1d | | | 0x96 | 0x4d |
| +--------+-------+-------+-------+-------+-------+
| B G | P[0,1] | 0x96 | 0x1d | 0x4d | | |
| +--------+-------+-------+-------+-------+-------+
| G R | P[1,0] | 0x96 | 0x4d | 0x1d | | |
| +--------+-------+-------+-------+-------+-------+
| | P[1,1] | 0x4d | | | 0x96 | 0x1d |
+-----+--------+-------+-------+-------+-------+-------+
| 3 | P[0,0] | 0x96 | 0x1d | 0x4d | | |
| +--------+-------+-------+-------+-------+-------+
| G B | P[0,1] | 0x1d | | | 0x96 | 0x4d |
| +--------+-------+-------+-------+-------+-------+
| R G | P[1,0] | 0x4d | | | 0x96 | 0x1d |
| +--------+-------+-------+-------+-------+-------+
| | P[1,1] | 0x96 | 0x4d | 0x1d | | |
+-----+--------+-------+-------+-------+-------+-------+
*/
reg [7:0] k1;
reg [7:0] k2;
reg [7:0] k3;
always @ (posedge CLK) case ({bayer_phase[1:0],odd_line,odd_pix})
// 0 - GR/BG
4'b0000: begin
k1<=8'h96;
k2<=8'h4d;
k3<=8'h1d;
end
4'b0001: begin
k1<=8'h4d;
k2<=8'h96;
k3<=8'h1d;
end
4'b0010: begin
k1<=8'h1d;
k2<=8'h96;
k3<=8'h4d;
end
4'b0011: begin
k1<=8'h96;
k2<=8'h1d;
k3<=8'h4d;
end
// 1 - RG/GB
4'b0100: begin
k1<=8'h4d;
k2<=8'h96;
k3<=8'h1d;
end
4'b0101: begin
k1<=8'h96;
k2<=8'h4d;
k3<=8'h1d;
end
4'b0110: begin
k1<=8'h96;
k2<=8'h1d;
k3<=8'h4d;
end
4'b0111: begin
k1<=8'h1d;
k2<=8'h96;
k3<=8'h4d;
end
// 2 - BG/GR
4'b1000: begin
k1<=8'h1d;
k2<=8'h96;
k3<=8'h4d;
end
4'b1001: begin
k1<=8'h96;
k2<=8'h1d;
k3<=8'h4d;
end
4'b1010: begin
k1<=8'h96;
k2<=8'h4d;
k3<=8'h1d;
end
4'b1011: begin
k1<=8'h4d;
k2<=8'h96;
k3<=8'h1d;
end
// 3 - GB/RG
4'b1100: begin
k1<=8'h96;
k2<=8'h1d;
k3<=8'h4d;
end
4'b1101: begin
k1<=8'h1d;
k2<=8'h96;
k3<=8'h4d;
end
4'b1110: begin
k1<=8'h4d;
k2<=8'h96;
k3<=8'h1d;
end
4'b1111: begin
k1<=8'h96;
k2<=8'h4d;
k3<=8'h1d;
end
endcase
wire [15:0] mm1=m1[7:0]*k1[7:0];
wire [15:0] mm2=m2[7:0]*k2[7:0];
wire [15:0] mm3=m3[7:0]*k3[7:0];
reg [7:0] y;
reg [7:0] y0; // bypass in monochrome mode
// wire [7:0] y0; // bypass in monochrome mode
reg [15:0] y1,y2,y3;
wire [15:0] y_sum =y1+y2+y3;
always @ (posedge CLK) y0 <= m1;
always @ (posedge CLK) y1 <= mm1;
always @ (posedge CLK) y2 <= mm2;
always @ (posedge CLK) y3 <= mm3;
always @ (posedge CLK) y[7:0] <= mono ? y0 : (y_sum[15:8]+y_sum[7]);
// Try easier and hope better algorithm of color extractions that should perform better on gradients.
// It will rely on the fact that Y is already calculated, so instead of processing 4 pixels it will
// calculate Cb for "B" pixel, and Cr - for "R", subtracting calculated "Y" for that pixel.
//Cb = 0.564*(B-Y)+128
//Cr = 0.713*(R-Y)+128
// First - delay pd1[7:0] by 2 clock periods - to match "Y" output (one ahead, actually)
// It is better to implement it earlier - while calculating pd2 - anyway it had to be delayed by 18 (16+2) form pd1 - make it in 2 stages 2 +16
// pdc[7:0] - one cycle ahead of the "Y" for each pixel
// Try multiplication by constant without the register for that constant, just 2:1 mux. Still use aregister for the other operand (is it needed?)
reg [7:0] cbcrmult1;
wire [7:0] cbcrmult2; // 1 of 2 constants - should be valid during ywe and 1 more cycle ("use_cr"
wire [15:0] cbcrmulto; // output of 8x8 multiplier
reg [8:0] cbcrmultr; // 1 extra bit for precision (before subtraction)
reg [8:0] cbcr; // after subraction (with extra bit preserved)
reg sel_cbcrmult1; // 0 - use pdc[7:0], 1 - use y[7:0]. Should be valid 1 cycle ahead of ywe!
reg use_cr; // in this line cr is calculated. Valid during ywe and 1 cycle after
reg sub_y; // output accumulator/subtractor. 0 - load new data, 1 - subtract. Walid 2 cycles after ywe
wire cwe0; // preliminary cwe (to be modulated by odd/even pixels)
reg cstrt; //ystrt dealyed by 1
reg cnxt; // nxtline delayed by 1
always @ (posedge CLK) begin
if (~(ywe || ystrt || nxtline)) sel_cbcrmult1 <= ~(bayer_phase[1] ^ bayer_phase[0] ^ odd_line);
else sel_cbcrmult1 <= ~sel_cbcrmult1;
sub_y <= ~sel_cbcrmult1;
cbcrmult1 <= sel_cbcrmult1?y[7:0]:pdc[7:0];
if (~ywe) use_cr <= ~(bayer_phase[1] ^ odd_line);
end
assign cbcrmult2=use_cr?8'hb6:8'h90; // maybe will need a register? (use_cr will still be good as it is valid early)
assign cbcrmulto=cbcrmult1*cbcrmult2;
// will preserve extra bit, but do not need to add half of the truncated MSB - on average there will be no shift after subtraction
always @ (posedge CLK) begin
cbcrmultr[8:0] <= cbcrmulto[15:7];
cbcr[8:0] <= sub_y? (cbcr[8:0]-cbcrmultr[8:0]+ 1'b1):cbcrmultr[8:0];
end
assign q[7:0]= {~cbcr[8],cbcr[7:1]}; // -128, discarded extra bit (need truncating?)
SRL16 i_cwe0 (.D(ywe ), .Q(cwe0), .A0(1'b1), .A1(1'b0), .A2(1'b0), .A3(1'b0), .CLK(CLK)); // dly=2=1+1
always @ (posedge CLK) begin
cstrt <= ystrt;
cnxt <= nxtline;
cwe <= cwe0 && sub_y;
caddr[2:0]<= cwe0?(caddr[2:0]+cwe):3'b0;
if (cstrt) caddr[6:3] <={~bayer_phase[1],3'b0};
else if (cnxt) caddr[6:3] <={~caddr[6],caddr[5:3]+(bayer_phase[1]^caddr[6])};
end
always @ (posedge CLK) begin
y_eq_0 <= (y0[7:0] == 8'h0);
y_eq_255 <= (y0[7:0] == 8'hff);
if (strt) n000[7:0] <= 8'h0;
else if ((n000[7:0]!=8'hff) && y_eq_0 && ywe) n000[7:0] <= n000[7:0]+1;
if (strt) n255[7:0] <= 8'h0;
else if ((n255[7:0]!=8'hff) && y_eq_255 && ywe) n255[7:0] <= n255[7:0]+1;
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -