47 F2(x,y)=p*(x-x0)^2 + q(y-yo)^2 + c= 48 p*x^2 - (2*p*x0) * x + p* (x0*x0) + q*y^2 - (2*q*y0) * y + q* (y0*y0) + c= 49 p* x^2 - (2*p*x0) * x + q* y^2 -(2*q)* y + (p* (x0*x0)+q* (y0*y0) + c) 51 F2(X,Y)=p* x^2 - (2*p*x0) * x + q* y^2 -(2*q)* y + (p* (x0*x0)+q* (y0*y0) + c): 54 F(0,Y)= q*y^2 - (2*q*y0) * y + (q* (y0*y0) + c + p* (x0*x0)) 55 C= (q* (y0*y0) + c + p* (x0*x0)); 63 // Vignetting correction / pixel value scaling - controlled via single data word (same as in 252), some of bits [23:16] 64 // are used to select register, bits 25:24 - select sub-frame 67 // parameter SENS_LENS_HEIGHTS = 'h0, // .. 'h2 set frame heights (all that is not SENS_LENS_COEFF) 87 parameter SENS_NUM_SUBCHN =
3,
// number of subchannels on the same sensor port (<=4) 91 parameter SENS_LENS_B_SHIFT =
12,
//(<=F_SHIFT) shift b- coeff (12 is 2^12 - good for lines <4096, 1 output count per width) 92 parameter SENS_LENS_A_WIDTH =
19,
// AF2015 18, // number of bits in a-coefficient (unsigned). Just to match the caller - MSBs will be anyway discarded 96 input prst,
// @pclk sync reset 97 input pclk,
// global clock input, pixel rate (96MHz for MT9P006) 98 // programming interface 99 input mrst,
// @mclk sync reset 100 input mclk,
// global clock, half DDR3 clock, synchronizes all I/O through the command port 101 input [
7:
0]
cmd_ad,
// byte-serial command address/data (up to 6 bytes: AL-AH-D0-D1-D2-D3 102 input cmd_stb,
// strobe (with first byte) for the command a/d 106 input sof_in,
// start of frame, single pclk, input 107 input eof_in,
// end of frame, single pclk, input 109 output reg [
15:
0]
pxd_out,
// pixel data out, 16 bit unsigned 115 output [
1:
0]
subchannel,
// for gamma correction (valid before/at start of line, may be invalid at the end) 116 output last_in_sub // last line in subchannel (valid before/at start of line, may be invalid at the end) 119 // AF2015 new signals 125 reg [
15:
0]
heights_m1_ram[
0:
3];
// set @ posedge mclk, used at pclk, but should be OK (change before first hact) 126 reg [
15:
0]
line_cntr;
// count image lines to switch to next subchannels 127 reg [
1:
0]
sub_frame_early;
// valid before/at newline to provide coefficients to lens_flat393_line 133 reg [
13:
0]
hact_d;
// lens_corr_out; /// lens correction out valid (first clock from column0 ) 134 wire [
15:
0]
pxd_d;
// pxd_in delayed buy 4 clocks 138 reg we_scales;
/// write additional individual per-color scales (17 bits each) 141 //F(x,y)=Ax*x^2+Bx*x+Ay*y^2+By*y+C 143 // small rams to store per-subframe parameters, they will be registered at each subframe start 151 reg [
16:
0]
scales_ram[
0:
15];
// per-color coefficients (parallel-combined fro all colors) 152 // reg [16:0] scales_r; 155 reg [
3:
0]
post_scale_ram[
0:
3];
/// shift product after first multiplier - maybe needed when using decimation 160 wire [
18:
0]
FY;
/// F(0,y) 161 wire [
23:
0]
ERR_Y;
/// running error for the first column 162 wire [
18:
0]
FXY;
/// F(x,y) 163 // reg [18:0] FXY_sat; // Not used, add extra cycle in calculations? 164 /// copied form sensorpix353.v 169 reg [
17:
0]
mult_first_scaled;
/// scaled multiplication result (to use with decimation to make parabola 'sharper') 172 // Use sub_frame_late? 176 // wire sync_bayer=linerun && ~lens_corr_out[0]; 177 // wire sync_bayer=hact_d[2] && ~hact_d[3]; 180 // sub_frame_late_d[3:2] sets 1 cycle ahead of needed, OK to ease timing (there is always >=1 hact gap) 183 // Writing to register files @mclk (4 per-subframe registers for coefficients, 4x4 - for per-subframe per-color scales) 184 // these registers will be read out at other clock (pclk) 220 // newline <= {newline[1:0], hact_in && !hact_d[0]}; 222 // line_start <= newline; // make it SR? 234 // adjust when to switch? 238 // if (newline[2]) sub_frame_late <= sub_frame; 250 // bayer_nset <= !sof_in && (bayer_nset || hact_d[1]); 256 /// now scale the result (normally post_scale[2:0] ==1) 273 // Replacing MULT18X18SIO of x353, registers on both inputs, outputs 279 // wire [17:0] mul2_b = mult_first_scaled[17:0]; // TODO - delay to have a register! 316 .
dly (
4'd12),
// input[3:0] 326 .
dly (
4'd10),
// input[3:0] 334 .clk (pclk), // input 335 .rst (prst), // input 336 .dly (4'd8), // input[3:0] 337 .din (sof_in), // input[0:0] 338 .dout (sosf) // output[0:0] 344 .
B_SHIFT (
SENS_LENS_B_SHIFT),
//(<=F_SHIFT) shift b- coeff (12 is 2^12 - good for lines <4096, 1 output count per width) 345 .
A_WIDTH (
SENS_LENS_A_WIDTH),
// number of bits in a-coefficient (signed). Just to match the caller - MSBs will be anyway discarded 349 // wrong - need to restart for each sub-frame 350 .
first (
sosf),
// initialize running parameters from the inputs (first column). Should be at least 1-cycle gap between "first" and first "next" 352 .
F0 (
C_ram[
sub_frame_early]),
// value of the output in the first column (before saturation), 18 bit, unsigned 353 .
ERR0 (
24'b0),
// initial value of the running error (-2.0<err<+2.0), scaled by 2^22, so 24 bits 362 .
B_SHIFT (
SENS_LENS_B_SHIFT),
// (<=F_SHIFT) shift b- coeff (12 is 2^12 - good for lines <4096, 1 output count per width) 363 .
A_WIDTH (
SENS_LENS_A_WIDTH),
// number of bits in a-coefficient (signed). Just to match the caller - MSBs will be anyway discarded 367 .
first (
newline[
0]),
// initialize running parameters from the inputs (first column). Should be at least 1-cycle gap between "first" and first "next" 369 .
F0 (
FY),
// value of the output in the first column (before saturation), 18 bit, unsigned 370 .
ERR0 (
ERR_Y),
// initial value of the running error (-2.0<err<+2.0), scaled by 2^22, so 24 bits 373 .
F (
FXY),
// valid 2 clocks after next (for the second pixel), next cycle after next - for the first pixel 395 parameter F_WIDTH =
19,
// AF2015 18, /// number of bits in the output result 396 parameter F_SHIFT =
22,
/// shift ~2*log2(width/2), for 4K width 397 parameter B_SHIFT =
12,
///(<=F_SHIFT) shift b- coeff (12 is 2^12 - good for lines <4096, 1 output count per width) 398 parameter A_WIDTH =
19,
// AF2015 18, /// number of bits in a-coefficient (unsigned). Just to match the caller - MSBs will be anyway discarded 399 parameter B_WIDTH =
21 // number of bits in b-coefficient (signed). 402 input first,
/// initialize running parameters from the inputs (first column). Should be at least 1-cycle gap between "first" and first "next" 403 input next,
/// calcualte next pixel 404 input [
F_WIDTH-
1:
0]
F0,
/// value of the output in the first column (before saturation), 18 bit, unsigned 405 input [
F_SHIFT+
1:
0]
ERR0,
/// initial value of the running error (-2.0<err<+2.0), scaled by 2^22, so 24 bits 406 input [
A_WIDTH-
1:
0]
A0,
/// a - fixed for negative values 409 output reg [
F_SHIFT+
1:
0]
ERR);
/// running difference between ax^2+bx+c and y, scaled by 2^22, signed, should never overflow 410 // output - 18 bits, unsigned (not saturated) 413 reg [
F_SHIFT+
1:
0]
ApB;
// a+b, scaled by 2 ^22, high bits ignored (not really needed - can use ApB0 414 reg [
F_SHIFT+
1:
1]
A2X;
// running value for 2*a*x, scaled by 2^22, high bits ignored 415 reg [(
DF_WIDTH)-
1:
0]
dF;
// or [9:0] - anyway only lower bits will be used in comparison operations 423 /// Increment can be 0 or +/-1, depending on the required correction 424 /// It relies on the facts that: 425 /// - the output F(x) is integer 426 /// - dF/dx does not chnage by more than +/-1 when x is incremented (abs (d2f/dx2)<1), so the algorithm to get 427 /// y=round(F(x)) is simple : 428 /// At each step x, try to chnage y by the same amount as was done at the previous step, adding/subtracting 1 if needed 429 /// and updating the new running error (difference between the current (integer) value of y and the precise value of F(x) 430 /// This error is calculated here with the 22 binary digits after the point. 435 /// err+= (2ax+a+b-df) -1 437 /// err+= (2ax+a+b-df) 440 /// err+= (2ax+a+b-df) +1 462 //AF2015 {B0[B_WIDTH-1:0],{F_SHIFT-B_SHIFT{1'b0}}}; /// high bits from B will be discarded 465 end else if (
next)
begin 466 //AF2015 dF[(DF_WIDTH)-1:0] <= dF[(DF_WIDTH)-1:0]+{{((DF_WIDTH)-1){inc[1]}},inc[1:0]}; 474 //AF2015 if (first_d) A2X[F_SHIFT+1:1] <= {{F_SHIFT+2-A_WIDTH{A[A_WIDTH-1]}},A[A_WIDTH-1:0]}; 475 //AF2015 else if (next) A2X[F_SHIFT+1:1] <= A2X[F_SHIFT+1:1] + {{F_SHIFT+2-A_WIDTH{A[A_WIDTH-1]}},A[A_WIDTH-1:0]}; 6674SENS_LENS_BY_MASK'he0
6663SENS_LENS_ADDR_MASK'h7fc
[0:15] 6736scales_ramreg[16:0]
6676SENS_LENS_SCALES_MASK'hf8
6678SENS_LENS_FAT0_IN_MASK'hff
6715sub_frame_late_dreg[3:0]
[0:3] 6734BY_ramreg[20:0]
[0:3] 6732AY_ramreg[18:0]
[0:3] 6739post_scale_ramreg[3:0]
[0:3] 6710heights_m1_ramreg[15:0]
reg [F_SHIFT+1:0] 6777ERR
6714sub_frame_latereg[1:0]
6668SENS_LENS_AY_MASK'hf8
[ADDR_MASK2!=0?2:ADDR_MASK1!=0?1:0:0] 9935we
6666SENS_LENS_AX_MASK'hf8
func_cmd_wecmd_datapatternmask
6746mult_first_reswire[35:0]
6677SENS_LENS_FAT0_IN'h68
6672SENS_LENS_BX_MASK'he0
6747mult_first_scaledreg[17:0]
[DATA_WIDTH-1:0] 9934data
6748mult_second_reswire[35:0]
6682SENS_LENS_POST_SCALE_MASK'hff
[0:3] 6733BX_ramreg[20:0]
6680SENS_LENS_FAT0_OUT_MASK'hff
[ADDR_WIDTH-1:0] 9933addr
6679SENS_LENS_FAT0_OUT'h69
6787preERRwire[F_SHIFT+1:0]
[0:3] 6737fatzero_in_ramreg[15:0]
[0:3] 6738fatzero_out_ramreg[15:0]
6681SENS_LENS_POST_SCALE'h6a
6778DF_WIDTHB_WIDTH - F_SHIFT + B_SHIFT
[0:3] 6731AX_ramreg[18:0]
cmd_deser_lens_i cmd_deser
6712sub_frame_earlyreg[1:0]
6749pre_pixdo_with_zerowire[20:0]