diff --git a/ossc.qsf b/ossc.qsf index b31ddb0..b610324 100644 --- a/ossc.qsf +++ b/ossc.qsf @@ -163,8 +163,6 @@ set_location_assignment PIN_129 -to btn[1] set_location_assignment PIN_128 -to btn[0] - - set_global_assignment -name USE_CONFIGURATION_DEVICE ON set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" @@ -220,20 +218,33 @@ set_global_assignment -name USE_SIGNALTAP_FILE output_files/ossc_new.stp set_global_assignment -name FITTER_EFFORT "AUTO FIT" set_global_assignment -name SEED 1 - - - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_BD[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_BD[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_BD[2] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_BD[3] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_BD[4] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_BD[5] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_BD[6] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_BD[7] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_GD[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_GD[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_GD[2] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_GD[3] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_GD[4] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_GD[5] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_GD[6] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_GD[7] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_RD[0] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_RD[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_RD[2] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_RD[3] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_RD[4] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_RD[5] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_RD[6] set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_RD[7] - - - - +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_HS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_VS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to HDMI_TX_DE set_global_assignment -name VERILOG_FILE rtl/videogen.v @@ -259,4 +270,6 @@ set_global_assignment -name SEARCH_PATH software/sys_controller/mem_init/ set_global_assignment -name SEARCH_PATH ip/ibex_qsys/rtl_extra set_global_assignment -name VERILOG_MACRO "SYNTHESIS=" set_global_assignment -name STRATIXIII_UPDATE_MODE REMOTE + + set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/ossc.sdc b/ossc.sdc index 042e97c..099501d 100644 --- a/ossc.sdc +++ b/ossc.sdc @@ -43,10 +43,10 @@ foreach_in_collection c [get_clocks "pclk_tvp*"] { set_input_delay -clock $c -max $TVP_dmax $critinputs -add_delay } -# output delay constraints as documented in the IT6613 datasheet -# -- increased IT_Tsu from 1.0 to 1.5 due to #52 -set IT_Tsu 1.5 -set IT_Th -0.5 +# output delay constraints based on params from IT6613 datasheet (S=1ns, H=0.5ns) +# shifted aperture window due to issues #52 and #56 +set IT_Tsu 2.0 +set IT_Th -0.2 set critoutputs_hdmi [get_ports {HDMI_TX_RD* HDMI_TX_GD* HDMI_TX_BD* HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}] foreach_in_collection c [get_clocks pclk_*_out] { set_output_delay -clock $c -min $IT_Th $critoutputs_hdmi -add diff --git a/software/sys_controller/inc/avconfig.h b/software/sys_controller/inc/avconfig.h index 6c81599..de6ed0c 100644 --- a/software/sys_controller/inc/avconfig.h +++ b/software/sys_controller/inc/avconfig.h @@ -107,6 +107,7 @@ typedef struct { alt_u8 fpga_pll_bw; alt_u8 panasonic_hack; alt_u8 o480p_pbox; + alt_u8 hdmi_pr2x_disable; /* Postprocessing settings */ alt_u8 sl_mode; diff --git a/software/sys_controller/src/menu.c b/software/sys_controller/src/menu.c index 87d7fb2..cf6a4bc 100644 --- a/software/sys_controller/src/menu.c +++ b/software/sys_controller/src/menu.c @@ -247,6 +247,7 @@ MENU(menu_compatibility, P99_PROTECT({ \ { "Full VSYNC bypas", OPT_AVCONFIG_SELECTION, { .sel = { &tc.full_vs_bypass, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, { "Default HDMI VIC", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.default_vic, OPT_NOWRAP, 0, HDMI_1080p50, value_disp } } }, { "Panasonic hack", OPT_AVCONFIG_SELECTION, { .sel = { &tc.panasonic_hack, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, + { "Disable PR2x", OPT_AVCONFIG_SELECTION, { .sel = { &tc.hdmi_pr2x_disable, OPT_WRAP, SETTING_ITEM(off_on_desc) } } }, })) MENU(menu_audio, P99_PROTECT({ \ diff --git a/software/sys_controller/src/userdata.c b/software/sys_controller/src/userdata.c index 1f244dd..0e2af27 100644 --- a/software/sys_controller/src/userdata.c +++ b/software/sys_controller/src/userdata.c @@ -143,6 +143,7 @@ const ude_item_map ude_profile_items[] = { UDE_ITEM(66, 120, tc.panasonic_hack), UDE_ITEM(67, 120, tc.o480p_pbox), UDE_ITEM(61, 122, tc.hdmi_ar), + UDE_ITEM(61, 122, tc.hdmi_pr2x_disable), }; int write_userdata(uint8_t entry) { diff --git a/software/sys_controller/src/video_modes.c b/software/sys_controller/src/video_modes.c index 63c3567..563af32 100644 --- a/software/sys_controller/src/video_modes.c +++ b/software/sys_controller/src/video_modes.c @@ -133,7 +133,7 @@ uint32_t calculate_pclk(uint32_t src_clk_hz, mode_data_t *vm_out, vm_proc_config int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t *vm_conf) { - int i, diff_lines, diff_v_hz_x100, mindiff_id=0, mindiff_lines=1000, mindiff_v_hz_x100=10000, x_rpt_decr=0; + int i, diff_lines, diff_v_hz_x100, mindiff_id=0, mindiff_lines=1000, mindiff_v_hz_x100=10000, x_rpt_decr=0, skip_hv_mult=0; mode_data_t *mode_preset; mode_flags valid_lm[] = { (MODE_PT | (cc->pt_mode ? (MODE_L5_GEN_4_3<<(cc->pt_mode-1)) : 0)), (MODE_L2 | (MODE_L2<l2_mode)), @@ -281,7 +281,6 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm while ((((vm_out->timings.v_hz_x100*vm_out->timings.v_total)/100)*vm_out->timings.h_total*(vm_conf->h_skip+1))>>vm_out->timings.interlaced < 25000000UL) { vm_conf->x_rpt = vm_conf->h_skip = 2*(vm_conf->h_skip+1)-1; } - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); break; case MODE_L2: // Upsample / pixel-repeat horizontal resolution of 384p/480p/960i modes @@ -289,16 +288,15 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm if (upsample2x) { vmode_hv_mult(vm_in, 2, 1); vmode_hv_mult(vm_out, 2, VM_OUT_YMULT); + skip_hv_mult = 1; } else { vm_conf->x_rpt = 1; - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); } } else { if (cc->o480p_pbox) { vm_conf->x_rpt = vm_conf->h_skip = 3; x_rpt_decr += 1; } - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); } break; case MODE_L3_GEN_16_9: @@ -307,12 +305,14 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm if (upsample2x) { vmode_hv_mult(vm_in, 2, 1); vmode_hv_mult(vm_out, 2, VM_OUT_YMULT); + skip_hv_mult = 1; } else { vm_conf->x_rpt = 1; - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); } - } else { - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); + } else if (cc->hdmi_pr2x_disable && ((mode_preset->group == GROUP_480P) || (mode_preset->group == GROUP_576P))) { + vmode_hv_mult(vm_in, 2, 1); + vmode_hv_mult(vm_out, 2, VM_OUT_YMULT); + skip_hv_mult = 1; } break; case MODE_L3_GEN_4_3: @@ -328,6 +328,7 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm vm_out->timings.h_total /= 3; vm_out->timings.h_total_adj = 0; vmode_hv_mult(vm_out, 4, VM_OUT_YMULT); + skip_hv_mult = 1; break; case MODE_L4_GEN_4_3: // Upsample / pixel-repeat horizontal resolution of 480i mode @@ -335,17 +336,30 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm if (upsample2x) { vmode_hv_mult(vm_in, 2, 1); vmode_hv_mult(vm_out, 2, VM_OUT_YMULT); + skip_hv_mult = 1; } else { vm_conf->x_rpt = 1; - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); } - } else { - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); } break; case MODE_L5_GEN_4_3: + if (cc->hdmi_pr2x_disable && mode_preset->group == GROUP_288P) { + vmode_hv_mult(vm_in, 2, 1); + vmode_hv_mult(vm_out, 2, VM_OUT_YMULT); + skip_hv_mult = 1; + } + break; case MODE_L6_GEN_4_3: - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); + if (cc->hdmi_pr2x_disable) { + if (mode_preset->group == GROUP_288P) { + // upsampled active would exceed 2048, must pixel-repeat + vm_conf->x_rpt = 1; + } else { + vmode_hv_mult(vm_in, 2, 1); + vmode_hv_mult(vm_out, 2, VM_OUT_YMULT); + skip_hv_mult = 1; + } + } break; case MODE_L2_512_COL: case MODE_L2_384_COL: @@ -356,13 +370,13 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm } else { vm_conf->x_rpt = vm_conf->h_skip = 1; } - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); break; case MODE_L3_512_COL: case MODE_L4_512_COL: - case MODE_L6_512_COL: vm_conf->x_rpt = vm_conf->h_skip = 1; - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); + break; + case MODE_L6_512_COL: + vm_conf->x_rpt = vm_conf->h_skip = cc->hdmi_pr2x_disable ? 3 : 1; break; case MODE_L2_256_COL: if (cc->o480p_pbox) { @@ -371,34 +385,35 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm } else { vm_conf->x_rpt = vm_conf->h_skip = 2; } - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); break; case MODE_L3_384_COL: case MODE_L4_384_COL: case MODE_L5_512_COL: + vm_conf->x_rpt = vm_conf->h_skip = 2; + break; case MODE_L6_384_COL: case MODE_L6_320_COL: - vm_conf->x_rpt = vm_conf->h_skip = 2; - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); + vm_conf->x_rpt = vm_conf->h_skip = cc->hdmi_pr2x_disable ? 5 : 2; break; case MODE_L3_240x360: + vm_conf->x_rpt = vm_conf->h_skip = 7; + break; case MODE_L3_320_COL: case MODE_L4_320_COL: case MODE_L5_384_COL: - case MODE_L6_256_COL: vm_conf->x_rpt = vm_conf->h_skip = 3; - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); + break; + case MODE_L6_256_COL: + vm_conf->x_rpt = vm_conf->h_skip = cc->hdmi_pr2x_disable ? 7 : 3; break; case MODE_L2_240x360: case MODE_L3_256_COL: case MODE_L4_256_COL: case MODE_L5_320_COL: vm_conf->x_rpt = vm_conf->h_skip = 4; - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); break; case MODE_L5_256_COL: vm_conf->x_rpt = vm_conf->h_skip = 5; - vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); break; default: printf("WARNING: invalid mindiff_lm\n"); @@ -406,6 +421,9 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm break; } + if (!skip_hv_mult) + vmode_hv_mult(vm_out, VM_OUT_XMULT, VM_OUT_YMULT); + // Set clock multiplication factor if (mindiff_lm == MODE_L3_GEN_4_3) vm_conf->si_pclk_mult = 4; @@ -415,11 +433,15 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm // Reduce x_rpt for 1:1 PAR 256col mode if (mindiff_lm & (MODE_L2_256_COL|MODE_L4_256_COL|MODE_L5_256_COL)) vm_conf->x_rpt -= cc->ar_256col; - else if (mindiff_lm & (MODE_L3_256_COL|MODE_L6_256_COL)) + else if (mindiff_lm & MODE_L3_256_COL) vm_conf->x_rpt = cc->ar_256col ? 2 : 3; + else if (mindiff_lm & MODE_L6_256_COL) + vm_conf->x_rpt = cc->ar_256col ? (cc->hdmi_pr2x_disable+1)*3-1 : (cc->hdmi_pr2x_disable+1)*4-1; - if (mindiff_lm & (MODE_L3_320_COL|MODE_L2_240x360|MODE_L3_240x360)) + if (mindiff_lm & (MODE_L3_320_COL|MODE_L2_240x360)) x_rpt_decr += 1; + else if (mindiff_lm & (MODE_L3_240x360)) + x_rpt_decr += 2; vm_conf->x_rpt -= x_rpt_decr; @@ -429,9 +451,9 @@ int get_pure_lm_mode(avconfig_t *cc, mode_data_t *vm_in, mode_data_t *vm_out, vm } // Force TX pixel-repeat for high bandwidth modes - if (((mindiff_lm == MODE_L5_GEN_4_3) && (mode_preset->group == GROUP_288P)) || + if (!cc->hdmi_pr2x_disable && (((mindiff_lm == MODE_L5_GEN_4_3) && (mode_preset->group == GROUP_288P)) || ((mindiff_lm == MODE_L3_GEN_16_9) && ((mode_preset->group == GROUP_480P) || (mode_preset->group == GROUP_576P))) || - (mindiff_lm == MODE_L3_240x360) || (mindiff_lm >= MODE_L6_GEN_4_3)) + (mindiff_lm >= MODE_L6_GEN_4_3))) vm_conf->tx_pixelrep = 1; sniprintf(vm_out->name, 11, "%s x%u", vm_in->name, vm_conf->y_rpt+1);