restore hybrid scanlines and reverse LPF functions

This commit is contained in:
marqs 2023-08-07 18:18:53 +03:00
parent b2998355c8
commit 31851f372d
14 changed files with 8917 additions and 8753 deletions

View File

@ -141,7 +141,8 @@ typedef union {
uint32_t sl_c_overlay:10;
uint8_t sl_iv_y:3;
uint8_t sl_iv_x:4;
uint32_t sl_rsv:7;
uint8_t sl_hybr_str:5;
uint32_t sl_rsv:2;
} __attribute__((packed, __may_alias__));
uint32_t data;
} sl_config3_reg;

View File

@ -243,9 +243,9 @@ set_global_assignment -name QIP_FILE software/sys_controller/mem_init/meminit.qi
set_global_assignment -name QIP_FILE rtl/linebuf.qip
set_global_assignment -name QIP_FILE rtl/char_rom.qip
set_global_assignment -name QIP_FILE rtl/pll_2x.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_4_hybr_ref_pre.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_4_hybr_ref.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_4_sl.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_hybr_ref_pre.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_hybr_ref.qip
set_global_assignment -name QIP_FILE rtl/lpm_mult_sl.qip
set_global_assignment -name SDC_FILE ossc.sdc
set_global_assignment -name CDF_FILE output_files/Chain1.cdf
set_global_assignment -name SIGNALTAP_FILE output_files/ossc_la.stp
@ -254,4 +254,5 @@ set_global_assignment -name QIP_FILE rtl/char_array.qip
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@ -1,5 +1,4 @@
set_global_assignment -name IP_TOOL_NAME "LPM_MULT"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_4_sl.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_mult_4_sl_bb.v"]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_hybr_ref.v"]

View File

@ -4,7 +4,7 @@
// MODULE: lpm_mult
// ============================================================
// File Name: lpm_mult_4_hybr_ref.v
// File Name: lpm_mult_hybr_ref.v
// Megafunction Name(s):
// lpm_mult
//
@ -37,7 +37,7 @@
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module lpm_mult_4_hybr_ref (
module lpm_mult_hybr_ref (
clock,
dataa,
datab,
@ -108,10 +108,10 @@ endmodule
// Retrieval info: CONNECT: @dataa 0 0 9 0 dataa 0 0 9 0
// Retrieval info: CONNECT: @datab 0 0 8 0 datab 0 0 8 0
// Retrieval info: CONNECT: result 0 0 9 0 @result 0 0 9 0
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_bb.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_bb.v FALSE
// Retrieval info: LIB_FILE: lpm

View File

@ -1,5 +1,4 @@
set_global_assignment -name IP_TOOL_NAME "LPM_MULT"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref_bb.v"]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_hybr_ref_pre.v"]

View File

@ -4,7 +4,7 @@
// MODULE: lpm_mult
// ============================================================
// File Name: lpm_mult_4_hybr_ref_pre.v
// File Name: lpm_mult_hybr_ref_pre.v
// Megafunction Name(s):
// lpm_mult
//
@ -37,7 +37,7 @@
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module lpm_mult_4_hybr_ref_pre (
module lpm_mult_hybr_ref_pre (
clock,
dataa,
datab,
@ -108,10 +108,10 @@ endmodule
// Retrieval info: CONNECT: @dataa 0 0 8 0 dataa 0 0 8 0
// Retrieval info: CONNECT: @datab 0 0 5 0 datab 0 0 5 0
// Retrieval info: CONNECT: result 0 0 9 0 @result 0 0 9 0
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_hybr_ref_pre_bb.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_hybr_ref_pre_bb.v FALSE
// Retrieval info: LIB_FILE: lpm

View File

@ -1,5 +1,4 @@
set_global_assignment -name IP_TOOL_NAME "LPM_MULT"
set_global_assignment -name IP_TOOL_VERSION "21.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone IV E}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref_pre.v"]
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "lpm_mult_4_hybr_ref_pre_bb.v"]
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "lpm_mult_sl.v"]

View File

@ -4,7 +4,7 @@
// MODULE: lpm_mult
// ============================================================
// File Name: lpm_mult_4_sl.v
// File Name: lpm_mult_sl.v
// Megafunction Name(s):
// lpm_mult
//
@ -37,7 +37,7 @@
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module lpm_mult_4_sl (
module lpm_mult_sl (
clock,
dataa,
datab,
@ -108,10 +108,10 @@ endmodule
// Retrieval info: CONNECT: @dataa 0 0 8 0 dataa 0 0 8 0
// Retrieval info: CONNECT: @datab 0 0 8 0 datab 0 0 8 0
// Retrieval info: CONNECT: result 0 0 8 0 @result 0 0 8 0
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_4_sl_bb.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mult_sl_bb.v FALSE
// Retrieval info: LIB_FILE: lpm

View File

@ -193,6 +193,7 @@ tvp7002_frontend u_tvp_frontend (
.hv_in_config(hv_in_config),
.hv_in_config2(hv_in_config2),
.hv_in_config3(hv_in_config3),
.misc_config(misc_config),
.R_o(TVP_R_post),
.G_o(TVP_G_post),
.B_o(TVP_B_post),

View File

@ -1,5 +1,5 @@
//
// Copyright (C) 2019-2022 Markus Hiienkari <mhiienka@niksula.hut.fi>
// Copyright (C) 2019-2023 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
@ -89,8 +89,11 @@ localparam PP_LINEBUF_END = PP_LINEBUF_START + PP_LINEBUF_LENGTH;
localparam PP_SRCSEL_START = PP_LINEBUF_END;
localparam PP_SRCSEL_LENGTH = 1;
localparam PP_SRCSEL_END = PP_SRCSEL_START + PP_SRCSEL_LENGTH;
localparam PP_SLGEN_START = PP_SRCSEL_START;
localparam PP_SLGEN_LENGTH = 3;
localparam PP_Y_CALC_START = PP_SRCSEL_END;
localparam PP_Y_CALC_LENGTH = 2;
localparam PP_Y_CALC_END = PP_Y_CALC_START + PP_Y_CALC_LENGTH;
localparam PP_SLGEN_START = PP_Y_CALC_END;
localparam PP_SLGEN_LENGTH = 5;
localparam PP_SLGEN_END = PP_SLGEN_START + PP_SLGEN_LENGTH;
localparam PP_TP_START = PP_SLGEN_END;
localparam PP_TP_LENGTH = 1;
@ -134,11 +137,10 @@ wire SL_BOB_ALTERN = sl_config[31];
wire [9:0] SL_C_OVERLAY = sl_config3[17:8];
wire [2:0] SL_IV_Y = sl_config3[20:18];
wire [3:0] SL_IV_X = sl_config3[24:21];
wire [4:0] SL_HYBRSTR = sl_config3[29:25];
wire [3:0] MISC_MASK_BR = misc_config[3:0];
wire [2:0] MISC_MASK_COLOR = misc_config[6:4];
wire [5:0] MISC_REV_LPF_STR = (misc_config[11:7] + 6'd16);
wire MISC_REV_LPF_ENABLE = (misc_config[11:7] != 5'h0);
wire MISC_LM_DEINT_MODE = misc_config[12];
wire MISC_NIR_EVEN_OFFSET = misc_config[13];
wire [3:0] MISC_BFI_STR = misc_config[19:16];
@ -165,17 +167,22 @@ reg [3:0] y_ctr;
reg line_id;
reg ypos_pp_init;
reg [7:0] sl_str;
reg sl_method;
reg [7:0] Y_sl_str, R_sl_str, G_sl_str, B_sl_str;
wire [7:0] R_sl_mult, G_sl_mult, B_sl_mult;
wire bfi_frame;
wire [7:0] R_sl_mult, G_sl_mult, B_sl_mult;
reg [8:0] Y_rb_tmp;
reg [9:0] Y;
wire [8:0] Y_sl_hybr_ref_pre, R_sl_hybr_ref_pre, G_sl_hybr_ref_pre, B_sl_hybr_ref_pre;
wire [8:0] Y_sl_hybr_ref, R_sl_hybr_ref, G_sl_hybr_ref, B_sl_hybr_ref;
wire [7:0] R_linebuf, G_linebuf, B_linebuf;
// Pipeline registers
reg [7:0] R_pp[PP_LINEBUF_END:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [7:0] G_pp[PP_LINEBUF_END:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [7:0] B_pp[PP_LINEBUF_END:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [7:0] R_pp[PP_SRCSEL_END:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [7:0] G_pp[PP_SRCSEL_END:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [7:0] B_pp[PP_SRCSEL_END:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg HSYNC_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg VSYNC_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg DE_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
@ -183,30 +190,90 @@ reg [11:0] xpos_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [10:0] ypos_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg mask_enable_pp[PP_LINEBUF_START:PP_TP_START] /* synthesis ramstyle = "logic" */;
reg draw_sl_pp[(PP_SLGEN_START+1):(PP_SLGEN_END-1)] /* synthesis ramstyle = "logic" */;
reg [7:0] sl_str_pp[(PP_SLGEN_START+1):(PP_SLGEN_START+2)] /* synthesis ramstyle = "logic" */;
reg [3:0] x_ctr_sl_pp[PP_PL_START:PP_SLGEN_START] /* synthesis ramstyle = "logic" */;
reg [2:0] y_ctr_sl_pp[PP_PL_START:PP_SLGEN_START] /* synthesis ramstyle = "logic" */;
assign PCLK_o = PCLK_OUT_i;
lpm_mult_4_sl R_sl_mult_u
lpm_mult_hybr_ref_pre Y_sl_hybr_ref_pre_u
(
.clock(PCLK_OUT_i),
.dataa(R_pp[PP_SLGEN_START+1]),
.datab(~sl_str),
.dataa(Y[9:2]),
.datab(SL_HYBRSTR),
.result(Y_sl_hybr_ref_pre)
);
lpm_mult_hybr_ref_pre R_sl_hybr_ref_pre_u
(
.clock(PCLK_OUT_i),
.dataa(R_pp[PP_SLGEN_START]),
.datab(SL_HYBRSTR),
.result(R_sl_hybr_ref_pre)
);
lpm_mult_hybr_ref_pre G_sl_hybr_ref_pre_u
(
.clock(PCLK_OUT_i),
.dataa(G_pp[PP_SLGEN_START]),
.datab(SL_HYBRSTR),
.result(G_sl_hybr_ref_pre)
);
lpm_mult_hybr_ref_pre B_sl_hybr_ref_pre_u
(
.clock(PCLK_OUT_i),
.dataa(B_pp[PP_SLGEN_START]),
.datab(SL_HYBRSTR),
.result(B_sl_hybr_ref_pre)
);
lpm_mult_hybr_ref Y_sl_hybr_ref_u
(
.clock(PCLK_OUT_i),
.dataa(Y_sl_hybr_ref_pre),
.datab(sl_str_pp[PP_SLGEN_START+1]),
.result(Y_sl_hybr_ref)
);
lpm_mult_hybr_ref R_sl_hybr_ref_u
(
.clock(PCLK_OUT_i),
.dataa(R_sl_hybr_ref_pre),
.datab(sl_str_pp[PP_SLGEN_START+1]),
.result(R_sl_hybr_ref)
);
lpm_mult_hybr_ref G_sl_hybr_ref_u
(
.clock(PCLK_OUT_i),
.dataa(G_sl_hybr_ref_pre),
.datab(sl_str_pp[PP_SLGEN_START+1]),
.result(G_sl_hybr_ref)
);
lpm_mult_hybr_ref B_sl_hybr_ref_u
(
.clock(PCLK_OUT_i),
.dataa(B_sl_hybr_ref_pre),
.datab(sl_str_pp[PP_SLGEN_START+1]),
.result(B_sl_hybr_ref)
);
lpm_mult_sl R_sl_mult_u
(
.clock(PCLK_OUT_i),
.dataa(R_pp[PP_SLGEN_START+3]),
.datab(~Y_sl_str),
.result(R_sl_mult)
);
lpm_mult_4_sl G_sl_mult_u
lpm_mult_sl G_sl_mult_u
(
.clock(PCLK_OUT_i),
.dataa(G_pp[PP_SLGEN_START+1]),
.datab(~sl_str),
.dataa(G_pp[PP_SLGEN_START+3]),
.datab(~Y_sl_str),
.result(G_sl_mult)
);
lpm_mult_4_sl B_sl_mult_u
lpm_mult_sl B_sl_mult_u
(
.clock(PCLK_OUT_i),
.dataa(B_pp[PP_SLGEN_START+1]),
.datab(~sl_str),
.dataa(B_pp[PP_SLGEN_START+3]),
.datab(~Y_sl_str),
.result(B_sl_mult)
);
@ -295,15 +362,16 @@ always @(posedge PCLK_OUT_i) begin
end
// Postprocess pipeline structure
// 1 2 3 4 5 6 7
// |----------|----------|---------|---------|---------|---------|--------|
// | SYNC/DE | | | | | | |
// | X/Y POS | | | | | | |
// | | MASK | | | | | |
// | | LB_SETUP | LINEBUF | | | | |
// | | | | SRCSEL | | | |
// | | | | SLGEN | SLGEN | SLGEN | |
// | | | | | | | TP |
// 1 2 3 4 5 6 7 8 9 10 11 12
// |----------|----------|---------|---------|---------|---------|---------|---------|---------|---------|---------|---------|
// | SYNC/DE | | | | | | | | | | | |
// | X/Y POS | | | | | | | | | | | |
// | | MASK | | | | | | | | | | |
// | | LB_SETUP | LINEBUF | | | | | | | | | |
// | | | | SRCSEL | | | | | | | | |
// | | | | | Y | Y | | | | | | |
// | | | | | | | SLGEN | SLGEN | SLGEN | SLGEN | SLGEN | |
// | | | | | | | | | | | | TP |
// Pipeline stage 1
@ -398,6 +466,12 @@ always @(posedge PCLK_OUT_i) begin
x_ctr_sl_pp[pp_idx] <= x_ctr_sl_pp[pp_idx-1];
y_ctr_sl_pp[pp_idx] <= y_ctr_sl_pp[pp_idx-1];
end
// Overridden later where necessary
for (pp_idx = PP_SRCSEL_END+1; pp_idx <= PP_PL_END; pp_idx = pp_idx+1) begin
R_pp[pp_idx] <= R_pp[pp_idx-1];
G_pp[pp_idx] <= G_pp[pp_idx-1];
B_pp[pp_idx] <= B_pp[pp_idx-1];
end
if (($signed({1'b0, xpos_pp[PP_LINEBUF_START-1]}) >= X_OFFSET) &
($signed({1'b0, xpos_pp[PP_LINEBUF_START-1]}) < X_OFFSET+X_SIZE) &
@ -412,21 +486,26 @@ always @(posedge PCLK_OUT_i) begin
mask_enable_pp[pp_idx] <= mask_enable_pp[pp_idx-1];
end
/* ---------- Source selection (1 cycle) ---------- */
R_pp[PP_SRCSEL_END] <= ext_sync_mode ? ext_R_i : R_linebuf;
G_pp[PP_SRCSEL_END] <= ext_sync_mode ? ext_G_i : G_linebuf;
B_pp[PP_SRCSEL_END] <= ext_sync_mode ? ext_B_i : B_linebuf;
// Scanlines (3 cycles)
/* ---------- Calculate Y from RGB for hybrid scanlines (2 cycles) ---------- */
Y_rb_tmp <= {1'b0, R_pp[PP_Y_CALC_START]} + {1'b0, B_pp[PP_Y_CALC_START]};
Y <= {1'b0, Y_rb_tmp} + {1'b0, G_pp[PP_Y_CALC_START+1], 1'b0};
/* ---------- Scanline generation (5 cycles) ---------- */
if (MISC_BFI_ENABLE & bfi_frame) begin
sl_str <= ((MISC_BFI_STR+8'h01)<<4)-1'b1;
sl_str_pp[PP_SLGEN_START+1] <= ((MISC_BFI_STR+8'h01)<<4)-1'b1;
sl_method <= 1'b1;
draw_sl_pp[PP_SLGEN_START+1] <= 1'b1;
end else if (|(SL_L_OVERLAY & (6'h1<<y_ctr_sl_pp[PP_SLGEN_START]))) begin
sl_str <= ((SL_L_STR[y_ctr_sl_pp[PP_SLGEN_START]]+8'h01)<<4)-1'b1;
sl_str_pp[PP_SLGEN_START+1] <= ((SL_L_STR[y_ctr_sl_pp[PP_SLGEN_START]]+8'h01)<<4)-1'b1;
sl_method <= ~SL_METHOD_PRE;
draw_sl_pp[PP_SLGEN_START+1] <= 1'b1;
end else if (|(SL_C_OVERLAY & (10'h1<<x_ctr_sl_pp[PP_SLGEN_START]))) begin
sl_str <= ((SL_C_STR[x_ctr_sl_pp[PP_SLGEN_START]]+8'h01)<<4)-1'b1;
sl_str_pp[PP_SLGEN_START+1] <= ((SL_C_STR[x_ctr_sl_pp[PP_SLGEN_START]]+8'h01)<<4)-1'b1;
sl_method <= ~SL_METHOD_PRE;
draw_sl_pp[PP_SLGEN_START+1] <= 1'b1;
end else begin
@ -436,14 +515,27 @@ always @(posedge PCLK_OUT_i) begin
draw_sl_pp[pp_idx] <= draw_sl_pp[pp_idx-1];
end
R_pp[PP_SLGEN_START+2] <= draw_sl_pp[PP_SLGEN_START+1] ? ((R_pp[PP_SLGEN_START+1] > sl_str) ? (R_pp[PP_SLGEN_START+1] - sl_str) : 8'h00) : R_pp[PP_SLGEN_START+1];
G_pp[PP_SLGEN_START+2] <= draw_sl_pp[PP_SLGEN_START+1] ? ((G_pp[PP_SLGEN_START+1] > sl_str) ? (G_pp[PP_SLGEN_START+1] - sl_str) : 8'h00) : G_pp[PP_SLGEN_START+1];
B_pp[PP_SLGEN_START+2] <= draw_sl_pp[PP_SLGEN_START+1] ? ((B_pp[PP_SLGEN_START+1] > sl_str) ? (B_pp[PP_SLGEN_START+1] - sl_str) : 8'h00) : B_pp[PP_SLGEN_START+1];
// Cycle 2
sl_str_pp[PP_SLGEN_START+2] <= sl_str_pp[PP_SLGEN_START+1];
R_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+2] & sl_method) ? R_sl_mult : R_pp[PP_SLGEN_START+2];
G_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+2] & sl_method) ? G_sl_mult : G_pp[PP_SLGEN_START+2];
B_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+2] & sl_method) ? B_sl_mult : B_pp[PP_SLGEN_START+2];
// Cycle 3
Y_sl_str <= {1'b0, sl_str_pp[PP_SLGEN_START+2]} < Y_sl_hybr_ref ? 8'h0 : sl_str_pp[PP_SLGEN_START+2] - Y_sl_hybr_ref[7:0];
R_sl_str <= {1'b0, sl_str_pp[PP_SLGEN_START+2]} < R_sl_hybr_ref ? 8'h0 : sl_str_pp[PP_SLGEN_START+2] - R_sl_hybr_ref[7:0];
G_sl_str <= {1'b0, sl_str_pp[PP_SLGEN_START+2]} < G_sl_hybr_ref ? 8'h0 : sl_str_pp[PP_SLGEN_START+2] - G_sl_hybr_ref[7:0];
B_sl_str <= {1'b0, sl_str_pp[PP_SLGEN_START+2]} < B_sl_hybr_ref ? 8'h0 : sl_str_pp[PP_SLGEN_START+2] - B_sl_hybr_ref[7:0];
// Cycle 4
// store subtraction based scanlined RGB into pipeline registers
R_pp[PP_SLGEN_START+4] <= draw_sl_pp[PP_SLGEN_START+3] ? ((R_pp[PP_SLGEN_START+3] > R_sl_str) ? (R_pp[PP_SLGEN_START+3] - R_sl_str) : 8'h00) : R_pp[PP_SLGEN_START+3];
G_pp[PP_SLGEN_START+4] <= draw_sl_pp[PP_SLGEN_START+3] ? ((G_pp[PP_SLGEN_START+3] > G_sl_str) ? (G_pp[PP_SLGEN_START+3] - G_sl_str) : 8'h00) : G_pp[PP_SLGEN_START+3];
B_pp[PP_SLGEN_START+4] <= draw_sl_pp[PP_SLGEN_START+3] ? ((B_pp[PP_SLGEN_START+3] > B_sl_str) ? (B_pp[PP_SLGEN_START+3] - B_sl_str) : 8'h00) : B_pp[PP_SLGEN_START+3];
// Cycle 5
R_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+4] & sl_method) ? R_sl_mult : R_pp[PP_SLGEN_START+4];
G_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+4] & sl_method) ? G_sl_mult : G_pp[PP_SLGEN_START+4];
B_pp[PP_SLGEN_END] <= (draw_sl_pp[PP_SLGEN_START+4] & sl_method) ? B_sl_mult : B_pp[PP_SLGEN_START+4];
/* ---------- Testpattern / mask generation ---------- */
R_pp[PP_TP_END] <= testpattern_enable ? (xpos_pp[PP_TP_START] ^ ypos_pp[PP_TP_START]) : (mask_enable_pp[PP_TP_START] ? MASK_R : R_pp[PP_TP_START]);
G_pp[PP_TP_END] <= testpattern_enable ? (xpos_pp[PP_TP_START] ^ ypos_pp[PP_TP_START]) : (mask_enable_pp[PP_TP_START] ? MASK_G : G_pp[PP_TP_START]);
B_pp[PP_TP_END] <= testpattern_enable ? (xpos_pp[PP_TP_START] ^ ypos_pp[PP_TP_START]) : (mask_enable_pp[PP_TP_START] ? MASK_B : B_pp[PP_TP_START]);

View File

@ -35,6 +35,7 @@ module tvp7002_frontend (
input [31:0] hv_in_config,
input [31:0] hv_in_config2,
input [31:0] hv_in_config3,
input [31:0] misc_config,
output [7:0] R_o,
output [7:0] G_o,
output [7:0] B_o,
@ -60,8 +61,11 @@ localparam FID_ODD = 1'b1;
localparam VSYNC_SEPARATED = 1'b0;
localparam VSYNC_RAW = 1'b1;
localparam PP_PL_START = 1;
localparam PP_PL_END = 4;
localparam PP_PL_START = 1;
localparam PP_RLPF_START = PP_PL_START + 1;
localparam PP_RLPF_LENGTH = 3;
localparam PP_RLPF_END = PP_RLPF_START + PP_RLPF_LENGTH;
localparam PP_PL_END = PP_RLPF_END;
reg [11:0] h_cnt, h_cnt_sogref;
reg [10:0] v_cnt;
@ -83,6 +87,11 @@ reg datavalid_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [10:0] xpos_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
reg [10:0] ypos_pp[PP_PL_START:PP_PL_END] /* synthesis ramstyle = "logic" */;
// Reverse LPF
wire rlpf_trigger_act;
reg signed [14:0] R_diff_s15_pre, G_diff_s15_pre, B_diff_s15_pre, R_diff_s15, G_diff_s15, B_diff_s15;
reg [7:0] R_pp_prev_rlpf, G_pp_prev_rlpf, B_pp_prev_rlpf;
// Measurement registers
reg [20:0] pcnt_frame_ctr;
reg [17:0] syncpol_det_ctr, hsync_hpol_ctr, vsync_hpol_ctr;
@ -103,6 +112,9 @@ wire [10:0] V_ACTIVE = hv_in_config2[30:20];
wire [3:0] V_SYNCLEN = hv_in_config3[3:0];
wire [8:0] V_BACKPORCH = hv_in_config3[12:4];
wire [5:0] MISC_REV_LPF_STR = (misc_config[11:7] + 6'd16);
wire MISC_REV_LPF_ENABLE = (misc_config[11:7] != 5'h0);
wire [11:0] h_cnt_ref = (vsync_i_type == VSYNC_SEPARATED) ? h_cnt_sogref : h_cnt;
wire [11:0] even_min_thold = (H_TOTAL / 12'd4);
wire [11:0] even_max_thold = (H_TOTAL / 12'd2) + (H_TOTAL / 12'd4);
@ -125,6 +137,17 @@ wire [3:0] H_SAMPLE_SEL = hv_in_config3[31:28];
// SOF position for scaler
wire [10:0] V_SOF_LINE = hv_in_config3[23:13];
function [7:0] apply_reverse_lpf;
input [7:0] data_prev;
input signed [14:0] diff;
reg signed [10:0] result;
begin
result = {3'b0,data_prev} + ~diff[14:4]; // allow for a small error to reduce adder length
apply_reverse_lpf = result[10] ? 8'h00 : |result[9:8] ? 8'hFF : result[7:0];
end
endfunction
always @(posedge PCLK_i) begin
R_pp[1] <= R_i;
@ -206,19 +229,13 @@ always @(posedge PCLK_i) begin
end
end
// Pipeline stages 1-
// Pipeline stages 2-
integer pp_idx;
always @(posedge PCLK_i) begin
for(pp_idx = PP_PL_START+1; pp_idx <= PP_PL_END-1; pp_idx = pp_idx+1) begin
for(pp_idx = PP_PL_START+1; pp_idx <= PP_PL_END; pp_idx = pp_idx+1) begin
R_pp[pp_idx] <= R_pp[pp_idx-1];
G_pp[pp_idx] <= G_pp[pp_idx-1];
B_pp[pp_idx] <= B_pp[pp_idx-1];
end
R_pp[PP_PL_END] <= R_pp[PP_PL_END-1];
G_pp[PP_PL_END] <= G_pp[PP_PL_END-1];
B_pp[PP_PL_END] <= B_pp[PP_PL_END-1];
for(pp_idx = PP_PL_START+1; pp_idx <= PP_PL_END; pp_idx = pp_idx+1) begin
HSYNC_pp[pp_idx] <= HSYNC_pp[pp_idx-1];
VSYNC_pp[pp_idx] <= VSYNC_pp[pp_idx-1];
FID_pp[pp_idx] <= FID_pp[pp_idx-1];
@ -227,6 +244,36 @@ always @(posedge PCLK_i) begin
xpos_pp[pp_idx] <= xpos_pp[pp_idx-1];
ypos_pp[pp_idx] <= ypos_pp[pp_idx-1];
end
/* ---------- Reverse LPF (3 cycles) ---------- */
// Store a copy of valid sample data
if (datavalid_pp[PP_RLPF_START]) begin
R_pp_prev_rlpf <= R_pp[PP_RLPF_START];
G_pp_prev_rlpf <= G_pp[PP_RLPF_START];
B_pp_prev_rlpf <= B_pp[PP_RLPF_START];
end
// Push previous valid data into pipeline when RLPF enabled
if (MISC_REV_LPF_ENABLE) begin
R_pp[PP_RLPF_START+1] <= R_pp_prev_rlpf;
G_pp[PP_RLPF_START+1] <= G_pp_prev_rlpf;
B_pp[PP_RLPF_START+1] <= B_pp_prev_rlpf;
end
// Calculate diff to previous valid data
R_diff_s15_pre <= (R_pp_prev_rlpf - R_pp[PP_RLPF_START]);
G_diff_s15_pre <= (G_pp_prev_rlpf - G_pp[PP_RLPF_START]);
B_diff_s15_pre <= (B_pp_prev_rlpf - B_pp[PP_RLPF_START]);
// Cycle 2
R_diff_s15 <= (R_diff_s15_pre * MISC_REV_LPF_STR);
G_diff_s15 <= (G_diff_s15_pre * MISC_REV_LPF_STR);
B_diff_s15 <= (B_diff_s15_pre * MISC_REV_LPF_STR);
// Cycle 3
if (MISC_REV_LPF_ENABLE) begin
R_pp[PP_RLPF_END] <= apply_reverse_lpf(R_pp[PP_RLPF_START+2], R_diff_s15);
G_pp[PP_RLPF_END] <= apply_reverse_lpf(G_pp[PP_RLPF_START+2], G_diff_s15);
B_pp[PP_RLPF_END] <= apply_reverse_lpf(B_pp[PP_RLPF_START+2], B_diff_s15);
end
end
// Output

File diff suppressed because it is too large Load Diff

View File

@ -523,6 +523,7 @@ void update_sc_config(mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t
}
sl_config.sl_method = avconfig->sl_method;
sl_config.sl_altern = avconfig->sl_altern;
sl_config3.sl_hybr_str = avconfig->sl_hybr_str;
// disable scanlines if configured so
if (((avconfig->sl_mode == 1) && (!vm_conf->y_rpt)) || (avconfig->sl_mode == 0)) {

View File

@ -139,6 +139,7 @@ MENU(menu_cust_sl, P99_PROTECT({ \
MENU(menu_vinputproc, P99_PROTECT({ \
{ LNG("Video LPF","ビデオ LPF"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.video_lpf, OPT_WRAP, SETTING_ITEM(video_lpf_desc) } } },
{ LNG("Reverse LPF","ギャクLPF"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.reverse_lpf, OPT_NOWRAP, 0, REVERSE_LPF_MAX, value_disp } } },
{ LNG("YPbPr in ColSpa","イロクウカンニYPbPr"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.ypbpr_cs, OPT_WRAP, SETTING_ITEM(ypbpr_cs_desc) } } },
{ LNG("R/Pr offset","R/Pr オフセット"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.col.r_f_off, OPT_NOWRAP, 0, 0xFF, value_disp } } },
{ LNG("G/Y offset","G/Y オフセット"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.col.g_f_off, OPT_NOWRAP, 0, 0xFF, value_disp } } },
@ -188,7 +189,7 @@ MENU(menu_output, P99_PROTECT({ \
MENU(menu_scanlines, P99_PROTECT({ \
{ LNG("Scanlines","スキャンライン"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_mode, OPT_WRAP, SETTING_ITEM(sl_mode_desc) } } },
{ LNG("Sl. strength","スキャンラインツヨサ"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_str, OPT_NOWRAP, 0, SCANLINESTR_MAX, sl_str_disp } } },
//{ "Sl. hybrid str.", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_hybr_str, OPT_NOWRAP, 0, SL_HYBRIDSTR_MAX, sl_hybr_str_disp } } },
{ "Sl. hybrid str.", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.sl_hybr_str, OPT_NOWRAP, 0, SL_HYBRIDSTR_MAX, sl_hybr_str_disp } } },
{ "Sl. method", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_method, OPT_WRAP, SETTING_ITEM(sl_method_desc) } } },
{ "Sl. alternating", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_altern, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("Sl. alignment","スキャンラインポジション"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_id, OPT_WRAP, SETTING_ITEM(sl_id_desc) } } },
@ -199,7 +200,6 @@ MENU(menu_scanlines, P99_PROTECT({ \
MENU(menu_postproc, P99_PROTECT({ \
{ "Mask color", OPT_AVCONFIG_SELECTION, { .sel = { &tc.mask_color, OPT_NOWRAP, SETTING_ITEM(mask_color_desc) } } },
{ LNG("Mask brightness","マスクアカルサ"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.mask_br, OPT_NOWRAP, 0, HV_MASK_MAX_BR, value_disp } } },
//{ LNG("Reverse LPF","ギャクLPF"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.reverse_lpf, OPT_NOWRAP, 0, REVERSE_LPF_MAX, value_disp } } },
//{ LNG("<DIY lat. test>","DIYチエンテスト"), OPT_FUNC_CALL, { .fun = { latency_test, &lt_arg_info } } },
}))