mirror of
https://github.com/marqs85/ossc
synced 2025-04-18 19:12:40 +03:00
improve TVP7002 frontend sync detection
Store csync leading edge position so that field change timing can be calculated accurately upon VSYNC detection
This commit is contained in:
parent
a825bb048c
commit
df643ec742
@ -102,6 +102,7 @@ wire sys_reset_n = (po_reset_n & ~jtagm_reset_req);
|
|||||||
reg [7:0] TVP_R, TVP_G, TVP_B;
|
reg [7:0] TVP_R, TVP_G, TVP_B;
|
||||||
reg TVP_HS, TVP_VS, TVP_FID;
|
reg TVP_HS, TVP_VS, TVP_FID;
|
||||||
reg TVP_VS_sync1_reg, TVP_VS_sync2_reg;
|
reg TVP_VS_sync1_reg, TVP_VS_sync2_reg;
|
||||||
|
reg TVP_SOG_sync1_reg, TVP_SOG_sync2_reg, TVP_SOG_prev;
|
||||||
reg TVP_HSYNC_sync1_reg, TVP_HSYNC_sync2_reg;
|
reg TVP_HSYNC_sync1_reg, TVP_HSYNC_sync2_reg;
|
||||||
reg TVP_VSYNC_sync1_reg, TVP_VSYNC_sync2_reg;
|
reg TVP_VSYNC_sync1_reg, TVP_VSYNC_sync2_reg;
|
||||||
|
|
||||||
@ -157,6 +158,9 @@ always @(posedge TVP_PCLK_i) begin
|
|||||||
TVP_FID <= TVP_FID_i;
|
TVP_FID <= TVP_FID_i;
|
||||||
|
|
||||||
// sync to pclk
|
// sync to pclk
|
||||||
|
TVP_SOG_sync1_reg <= TVP_HSYNC_i;
|
||||||
|
TVP_SOG_sync2_reg <= TVP_SOG_sync1_reg;
|
||||||
|
TVP_SOG_prev <= TVP_SOG_sync2_reg;
|
||||||
TVP_VS_sync1_reg <= TVP_VSYNC_i;
|
TVP_VS_sync1_reg <= TVP_VSYNC_i;
|
||||||
TVP_VS_sync2_reg <= TVP_VS_sync1_reg;
|
TVP_VS_sync2_reg <= TVP_VS_sync1_reg;
|
||||||
end
|
end
|
||||||
@ -186,6 +190,7 @@ tvp7002_frontend u_tvp_frontend (
|
|||||||
.VSYNC_i(TVP_VSYNC_sync2_reg),
|
.VSYNC_i(TVP_VSYNC_sync2_reg),
|
||||||
.DE_i(1'b0),
|
.DE_i(1'b0),
|
||||||
.FID_i(1'b0),
|
.FID_i(1'b0),
|
||||||
|
.sogref_update_i(TVP_SOG_prev & ~TVP_SOG_sync2_reg),
|
||||||
.vsync_i_type(tvp_vsync_type),
|
.vsync_i_type(tvp_vsync_type),
|
||||||
.hv_in_config(hv_in_config),
|
.hv_in_config(hv_in_config),
|
||||||
.hv_in_config2(hv_in_config2),
|
.hv_in_config2(hv_in_config2),
|
||||||
|
@ -30,6 +30,7 @@ module tvp7002_frontend (
|
|||||||
input VSYNC_i,
|
input VSYNC_i,
|
||||||
input DE_i,
|
input DE_i,
|
||||||
input FID_i,
|
input FID_i,
|
||||||
|
input sogref_update_i,
|
||||||
input vsync_i_type,
|
input vsync_i_type,
|
||||||
input [31:0] hv_in_config,
|
input [31:0] hv_in_config,
|
||||||
input [31:0] hv_in_config2,
|
input [31:0] hv_in_config2,
|
||||||
@ -61,7 +62,7 @@ localparam VSYNC_RAW = 1'b1;
|
|||||||
localparam PP_PL_START = 1;
|
localparam PP_PL_START = 1;
|
||||||
localparam PP_PL_END = 4;
|
localparam PP_PL_END = 4;
|
||||||
|
|
||||||
reg [11:0] h_cnt;
|
reg [11:0] h_cnt, h_cnt_sogref;
|
||||||
reg [10:0] v_cnt;
|
reg [10:0] v_cnt;
|
||||||
reg [10:0] vmax_cnt;
|
reg [10:0] vmax_cnt;
|
||||||
reg HS_i_prev, VS_i_np_prev;
|
reg HS_i_prev, VS_i_np_prev;
|
||||||
@ -85,7 +86,7 @@ reg [10:0] ypos_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
|
|||||||
reg [20:0] pcnt_frame_ctr;
|
reg [20:0] pcnt_frame_ctr;
|
||||||
reg [17:0] syncpol_det_ctr, hsync_hpol_ctr, vsync_hpol_ctr;
|
reg [17:0] syncpol_det_ctr, hsync_hpol_ctr, vsync_hpol_ctr;
|
||||||
reg [3:0] sync_inactive_ctr;
|
reg [3:0] sync_inactive_ctr;
|
||||||
reg [11:0] pcnt_line, pcnt_line_ctr, meas_h_cnt;
|
reg [11:0] pcnt_line, pcnt_line_ctr, meas_h_cnt, meas_h_cnt_sogref;
|
||||||
reg pcnt_line_stored;
|
reg pcnt_line_stored;
|
||||||
reg [10:0] meas_v_cnt;
|
reg [10:0] meas_v_cnt;
|
||||||
reg meas_hl_det, meas_fid;
|
reg meas_hl_det, meas_fid;
|
||||||
@ -100,15 +101,13 @@ wire [10:0] V_ACTIVE = hv_in_config2[30:20];
|
|||||||
wire [3:0] V_SYNCLEN = hv_in_config3[3:0];
|
wire [3:0] V_SYNCLEN = hv_in_config3[3:0];
|
||||||
wire [8:0] V_BACKPORCH = hv_in_config3[12:4];
|
wire [8:0] V_BACKPORCH = hv_in_config3[12:4];
|
||||||
|
|
||||||
wire [11:0] even_min_thold_hv = (H_TOTAL / 12'd4);
|
wire [11:0] h_cnt_ref = (vsync_i_type == VSYNC_SEPARATED) ? h_cnt_sogref : h_cnt;
|
||||||
wire [11:0] even_max_thold_hv = (H_TOTAL / 12'd2) + (H_TOTAL / 12'd4);
|
wire [11:0] even_min_thold = (H_TOTAL / 12'd4);
|
||||||
wire [11:0] even_min_thold_ss = (H_TOTAL / 12'd2);
|
wire [11:0] even_max_thold = (H_TOTAL / 12'd2) + (H_TOTAL / 12'd4);
|
||||||
wire [11:0] even_max_thold_ss = H_TOTAL;
|
|
||||||
wire [11:0] even_min_thold = (vsync_i_type == VSYNC_SEPARATED) ? even_min_thold_ss : even_min_thold_hv;
|
|
||||||
wire [11:0] even_max_thold = (vsync_i_type == VSYNC_SEPARATED) ? even_max_thold_ss : even_max_thold_hv;
|
|
||||||
|
|
||||||
wire [11:0] meas_even_min_thold = (vsync_i_type == VSYNC_SEPARATED) ? (pcnt_line / 12'd2) : (pcnt_line / 12'd4);
|
wire [11:0] meas_h_cnt_ref = (vsync_i_type == VSYNC_SEPARATED) ? meas_h_cnt_sogref : meas_h_cnt;
|
||||||
wire [11:0] meas_even_max_thold = (vsync_i_type == VSYNC_SEPARATED) ? pcnt_line : (pcnt_line / 12'd2) + (pcnt_line / 12'd4);
|
wire [11:0] meas_even_min_thold = (pcnt_line / 12'd4);
|
||||||
|
wire [11:0] meas_even_max_thold = (pcnt_line / 12'd2) + (pcnt_line / 12'd4);
|
||||||
wire meas_vblank_region = ((pcnt_frame_ctr < (pcnt_frame/8)) | (pcnt_frame_ctr > (pcnt_frame - (pcnt_frame/8))));
|
wire meas_vblank_region = ((pcnt_frame_ctr < (pcnt_frame/8)) | (pcnt_frame_ctr > (pcnt_frame - (pcnt_frame/8))));
|
||||||
wire [11:0] glitch_filt_thold = meas_vblank_region ? (pcnt_line/4) : (pcnt_line/8);
|
wire [11:0] glitch_filt_thold = meas_vblank_region ? (pcnt_line/4) : (pcnt_line/8);
|
||||||
|
|
||||||
@ -176,10 +175,10 @@ always @(posedge PCLK_i) begin
|
|||||||
|
|
||||||
// vsync leading edge processing per quadrant
|
// vsync leading edge processing per quadrant
|
||||||
if (VS_i_np_prev & ~VS_i_np) begin
|
if (VS_i_np_prev & ~VS_i_np) begin
|
||||||
if (h_cnt < even_min_thold) begin
|
if (h_cnt_ref < even_min_thold) begin
|
||||||
fid_next <= FID_ODD;
|
fid_next <= FID_ODD;
|
||||||
fid_next_ctr <= 2'h1;
|
fid_next_ctr <= 2'h1;
|
||||||
end else if ((h_cnt > even_max_thold) | ~interlace_flag) begin
|
end else if ((h_cnt_ref > even_max_thold) | ~interlace_flag) begin
|
||||||
fid_next <= FID_ODD;
|
fid_next <= FID_ODD;
|
||||||
fid_next_ctr <= 2'h2;
|
fid_next_ctr <= 2'h2;
|
||||||
end else begin
|
end else begin
|
||||||
@ -188,6 +187,11 @@ always @(posedge PCLK_i) begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// record starting position of csync leading edge for later FID detection
|
||||||
|
if (sogref_update_i) begin
|
||||||
|
h_cnt_sogref <= (h_cnt > even_max_thold) ? 0 : h_cnt;
|
||||||
|
end
|
||||||
|
|
||||||
if (((fid_next == FID_ODD) & (HS_i_prev & ~HS_i)) | ((fid_next == FID_EVEN) & (h_cnt == (H_TOTAL/2)-1'b1))) begin
|
if (((fid_next == FID_ODD) & (HS_i_prev & ~HS_i)) | ((fid_next == FID_EVEN) & (h_cnt == (H_TOTAL/2)-1'b1))) begin
|
||||||
if (fid_next_ctr == 2'h1) begin
|
if (fid_next_ctr == 2'h1) begin
|
||||||
VSYNC_pp[1] <= 1'b0;
|
VSYNC_pp[1] <= 1'b0;
|
||||||
@ -308,6 +312,7 @@ always @(posedge CLK_MEAS_i) begin
|
|||||||
meas_h_cnt <= 0;
|
meas_h_cnt <= 0;
|
||||||
meas_v_cnt <= meas_v_cnt + 1'b1;
|
meas_v_cnt <= meas_v_cnt + 1'b1;
|
||||||
end
|
end
|
||||||
|
meas_h_cnt_sogref <= meas_h_cnt;
|
||||||
end else if (meas_vblank_region & (meas_h_cnt > pcnt_line)) begin
|
end else if (meas_vblank_region & (meas_h_cnt > pcnt_line)) begin
|
||||||
// hsync may be missing during vblank, force line change detect if pcnt_line is exceeded +-1/8 field around vsync edge
|
// hsync may be missing during vblank, force line change detect if pcnt_line is exceeded +-1/8 field around vsync edge
|
||||||
meas_hl_det <= 1'b0;
|
meas_hl_det <= 1'b0;
|
||||||
@ -318,7 +323,7 @@ always @(posedge CLK_MEAS_i) begin
|
|||||||
end
|
end
|
||||||
|
|
||||||
if (VSYNC_i_np_prev & ~VSYNC_i_np) begin
|
if (VSYNC_i_np_prev & ~VSYNC_i_np) begin
|
||||||
if ((meas_h_cnt < meas_even_min_thold) | (meas_h_cnt > meas_even_max_thold)) begin
|
if ((meas_h_cnt_ref < meas_even_min_thold) | (meas_h_cnt_ref > meas_even_max_thold)) begin
|
||||||
meas_fid <= FID_ODD;
|
meas_fid <= FID_ODD;
|
||||||
interlace_flag <= (meas_fid == FID_EVEN);
|
interlace_flag <= (meas_fid == FID_EVEN);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user