From b04c6c7eec079632a38b83ea9e5688c4e1353a4a Mon Sep 17 00:00:00 2001 From: sorgelig Date: Fri, 12 Jul 2019 06:22:16 +0800 Subject: [PATCH] Update sys. --- MacPlus.qpf | 29 - MacPlus.qsf | 377 +-------- MacPlus.sv | 11 +- files.qip | 18 + sys/alsa.sv | 21 +- sys/ascal.vhd | 801 ++++++++++-------- sys/fbpal.sv | 86 ++ sys/hdmi_config.sv | 435 +++++----- sys/hps_io.v | 223 +++-- sys/hq2x.sv | 22 +- sys/ltc2308.sv | 162 ++++ sys/osd.v | 87 +- sys/pll.13.qip | 13 + sys/pll/pll_0002_q13.qip | 4 + sys/pll_cfg.qip | 44 + sys/{pll_hdmi_cfg.v => pll_cfg.v} | 14 +- .../altera_pll_reconfig_core.v | 0 .../altera_pll_reconfig_top.v | 0 sys/{pll_hdmi_q13.qip => pll_hdmi.13.qip} | 0 sys/pll_hdmi_adj.vhd | 123 ++- sys/pll_hdmi_cfg.qip | 44 - sys/pll_q13.qip | 5 + sys/pll_q17.qip | 3 + sys/scandoubler.v | 102 ++- sys/sys.qip | 8 +- sys/sys.tcl | 254 ++++++ sys/sys_analog.tcl | 71 ++ sys/sys_dual_sdram.tcl | 53 ++ sys/sys_q13.qip | 30 - sys/sys_top.sdc | 6 +- sys/sys_top.v | 496 +++++++---- 31 files changed, 2186 insertions(+), 1356 deletions(-) create mode 100644 files.qip create mode 100644 sys/fbpal.sv create mode 100644 sys/ltc2308.sv create mode 100644 sys/pll.13.qip create mode 100644 sys/pll/pll_0002_q13.qip create mode 100644 sys/pll_cfg.qip rename sys/{pll_hdmi_cfg.v => pll_cfg.v} (92%) rename sys/{pll_hdmi_cfg => pll_cfg}/altera_pll_reconfig_core.v (100%) rename sys/{pll_hdmi_cfg => pll_cfg}/altera_pll_reconfig_top.v (100%) rename sys/{pll_hdmi_q13.qip => pll_hdmi.13.qip} (100%) delete mode 100644 sys/pll_hdmi_cfg.qip create mode 100644 sys/pll_q13.qip create mode 100644 sys/pll_q17.qip create mode 100644 sys/sys.tcl create mode 100644 sys/sys_analog.tcl create mode 100644 sys/sys_dual_sdram.tcl delete mode 100644 sys/sys_q13.qip diff --git a/MacPlus.qpf b/MacPlus.qpf index 300eb86..fae2ab0 100644 --- a/MacPlus.qpf +++ b/MacPlus.qpf @@ -1,31 +1,2 @@ -# -------------------------------------------------------------------------- # -# -# Copyright (C) 2017 Intel Corporation. All rights reserved. -# Your use of Intel Corporation's design tools, logic functions -# and other software and tools, and its AMPP partner logic -# functions, and any output files from any of the foregoing -# (including device programming or simulation files), and any -# associated documentation or information are expressly subject -# to the terms and conditions of the Intel Program License -# Subscription Agreement, the Intel Quartus Prime License Agreement, -# the Intel MegaCore Function License Agreement, or other -# applicable license agreement, including, without limitation, -# that your use is for the sole purpose of programming logic -# devices manufactured by Intel and sold by Intel or its -# authorized distributors. Please refer to the applicable -# agreement for further details. -# -# -------------------------------------------------------------------------- # -# -# Quartus Prime -# Version 17.0.1 Build 598 06/07/2017 SJ Standard Edition -# Date created = 04:04:47 October 16, 2017 -# -# -------------------------------------------------------------------------- # - QUARTUS_VERSION = "17.0" -DATE = "04:04:47 October 16, 2017" - -# Revisions - PROJECT_REVISION = "MacPlus" diff --git a/MacPlus.qsf b/MacPlus.qsf index 8a6fcc8..56d2347 100644 --- a/MacPlus.qsf +++ b/MacPlus.qsf @@ -1,46 +1,25 @@ -# -------------------------------------------------------------------------- # +# -------------------------------------------------------------------------- # -# Copyright (C) 2017 Intel Corporation. All rights reserved. -# Your use of Intel Corporation's design tools, logic functions -# and other software and tools, and its AMPP partner logic -# functions, and any output files from any of the foregoing -# (including device programming or simulation files), and any -# associated documentation or information are expressly subject -# to the terms and conditions of the Intel Program License -# Subscription Agreement, the Intel Quartus Prime License Agreement, -# the Intel MegaCore Function License Agreement, or other -# applicable license agreement, including, without limitation, -# that your use is for the sole purpose of programming logic -# devices manufactured by Intel and sold by Intel or its -# authorized distributors. Please refer to the applicable -# agreement for further details. +# MiSTer project # -# -------------------------------------------------------------------------- # +# WARNING WARNING WARNING: +# Do not add files to project in Quartus IDE! It will mess this file! +# Add the files manually to files.qip file. # -# Quartus Prime -# Version 16.1.2 Build 203 01/18/2017 SJ Standard Edition -# Date created = 01:53:32 April 20, 2017 -# -# -------------------------------------------------------------------------- # +# -------------------------------------------------------------------------- -set_global_assignment -name FAMILY "Cyclone V" -set_global_assignment -name DEVICE 5CSEBA6U23I7 set_global_assignment -name TOP_LEVEL_ENTITY sys_top -set_global_assignment -name ORIGINAL_QUARTUS_VERSION 16.1.2 +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top + set_global_assignment -name LAST_QUARTUS_VERSION "17.0.2 Standard Edition" -set_global_assignment -name PROJECT_CREATION_TIME_DATE "01:53:30 APRIL 20, 2017" -set_global_assignment -name DEVICE_FILTER_PACKAGE UFBGA -set_global_assignment -name DEVICE_FILTER_PIN_COUNT 672 -set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 7 set_global_assignment -name GENERATE_RBF_FILE ON set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL set_global_assignment -name SAVE_DISK_SPACE OFF set_global_assignment -name SMART_RECOMPILE ON -set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top -set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top -set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40" set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100 set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" @@ -50,324 +29,28 @@ set_global_assignment -name OPTIMIZE_POWER_DURING_FITTING OFF set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION ALWAYS set_global_assignment -name FITTER_EFFORT "STANDARD FIT" set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT" +set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON +set_global_assignment -name QII_AUTO_PACKED_REGISTERS NORMAL +set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED +set_global_assignment -name MUX_RESTRUCTURE ON +set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON +set_global_assignment -name AUTO_DELAY_CHAINS_FOR_HIGH_FANOUT_INPUT_PINS ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON +set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON +set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON +set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON +set_global_assignment -name ECO_OPTIMIZE_TIMING ON +set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON +set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW set_global_assignment -name SEED 1 -#============================================================ -# ADC -#============================================================ -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ADC_CONVST -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ADC_SCK -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ADC_SDI -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ADC_SDO -set_location_assignment PIN_U9 -to ADC_CONVST -set_location_assignment PIN_V10 -to ADC_SCK -set_location_assignment PIN_AC4 -to ADC_SDI -set_location_assignment PIN_AD4 -to ADC_SDO - -#============================================================ -# ARDUINO -#============================================================ -set_location_assignment PIN_AG9 -to ARDUINO_IO[3] -set_location_assignment PIN_U14 -to ARDUINO_IO[4] -set_location_assignment PIN_U13 -to ARDUINO_IO[5] -set_location_assignment PIN_AG8 -to ARDUINO_IO[6] -set_location_assignment PIN_AH8 -to ARDUINO_IO[7] -set_location_assignment PIN_AF17 -to ARDUINO_IO[8] -set_location_assignment PIN_AE15 -to ARDUINO_IO[9] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[*] -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to ARDUINO_IO[*] -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to ARDUINO_IO[*] - -#============================================================ -# USER PORT -#============================================================ -set_location_assignment PIN_AF15 -to USER_IO[5] -set_location_assignment PIN_AG16 -to USER_IO[4] -set_location_assignment PIN_AH11 -to USER_IO[3] -set_location_assignment PIN_AH12 -to USER_IO[2] -set_location_assignment PIN_AH9 -to USER_IO[1] -set_location_assignment PIN_AG11 -to USER_IO[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to USER_IO[*] -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to USER_IO[*] -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to USER_IO[*] - -#============================================================ -# SDIO -#============================================================ -set_location_assignment PIN_AF25 -to SDIO_DAT[0] -set_location_assignment PIN_AF23 -to SDIO_DAT[1] -set_location_assignment PIN_AD26 -to SDIO_DAT[2] -set_location_assignment PIN_AF28 -to SDIO_DAT[3] -set_location_assignment PIN_AF27 -to SDIO_CMD -set_location_assignment PIN_AH26 -to SDIO_CLK -set_location_assignment PIN_AH7 -to SDIO_CD - -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDIO_* - -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDIO_* -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDIO_DAT[*] -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDIO_CMD -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDIO_CD - -#============================================================ -# VGA -#============================================================ -set_location_assignment PIN_AE17 -to VGA_R[0] -set_location_assignment PIN_AE20 -to VGA_R[1] -set_location_assignment PIN_AF20 -to VGA_R[2] -set_location_assignment PIN_AH18 -to VGA_R[3] -set_location_assignment PIN_AH19 -to VGA_R[4] -set_location_assignment PIN_AF21 -to VGA_R[5] - -set_location_assignment PIN_AE19 -to VGA_G[0] -set_location_assignment PIN_AG15 -to VGA_G[1] -set_location_assignment PIN_AF18 -to VGA_G[2] -set_location_assignment PIN_AG18 -to VGA_G[3] -set_location_assignment PIN_AG19 -to VGA_G[4] -set_location_assignment PIN_AG20 -to VGA_G[5] - -set_location_assignment PIN_AG21 -to VGA_B[0] -set_location_assignment PIN_AA20 -to VGA_B[1] -set_location_assignment PIN_AE22 -to VGA_B[2] -set_location_assignment PIN_AF22 -to VGA_B[3] -set_location_assignment PIN_AH23 -to VGA_B[4] -set_location_assignment PIN_AH21 -to VGA_B[5] - -set_location_assignment PIN_AH22 -to VGA_HS -set_location_assignment PIN_AG24 -to VGA_VS - -set_location_assignment PIN_AH27 -to VGA_EN -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to VGA_EN - -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_* -set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_* - -#============================================================ -# AUDIO -#============================================================ -set_location_assignment PIN_AC24 -to AUDIO_L -set_location_assignment PIN_AE25 -to AUDIO_R -set_location_assignment PIN_AG26 -to AUDIO_SPDIF -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to AUDIO_* -set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to AUDIO_* - -#============================================================ -# SDRAM -#============================================================ -set_location_assignment PIN_Y11 -to SDRAM_A[0] -set_location_assignment PIN_AA26 -to SDRAM_A[1] -set_location_assignment PIN_AA13 -to SDRAM_A[2] -set_location_assignment PIN_AA11 -to SDRAM_A[3] -set_location_assignment PIN_W11 -to SDRAM_A[4] -set_location_assignment PIN_Y19 -to SDRAM_A[5] -set_location_assignment PIN_AB23 -to SDRAM_A[6] -set_location_assignment PIN_AC23 -to SDRAM_A[7] -set_location_assignment PIN_AC22 -to SDRAM_A[8] -set_location_assignment PIN_C12 -to SDRAM_A[9] -set_location_assignment PIN_AB26 -to SDRAM_A[10] -set_location_assignment PIN_AD17 -to SDRAM_A[11] -set_location_assignment PIN_D12 -to SDRAM_A[12] -set_location_assignment PIN_Y17 -to SDRAM_BA[0] -set_location_assignment PIN_AB25 -to SDRAM_BA[1] - -set_location_assignment PIN_E8 -to SDRAM_DQ[0] -set_location_assignment PIN_V12 -to SDRAM_DQ[1] -set_location_assignment PIN_D11 -to SDRAM_DQ[2] -set_location_assignment PIN_W12 -to SDRAM_DQ[3] -set_location_assignment PIN_AH13 -to SDRAM_DQ[4] -set_location_assignment PIN_D8 -to SDRAM_DQ[5] -set_location_assignment PIN_AH14 -to SDRAM_DQ[6] -set_location_assignment PIN_AF7 -to SDRAM_DQ[7] -set_location_assignment PIN_AE24 -to SDRAM_DQ[8] -set_location_assignment PIN_AD23 -to SDRAM_DQ[9] -set_location_assignment PIN_AE6 -to SDRAM_DQ[10] -set_location_assignment PIN_AE23 -to SDRAM_DQ[11] -set_location_assignment PIN_AG14 -to SDRAM_DQ[12] -set_location_assignment PIN_AD5 -to SDRAM_DQ[13] -set_location_assignment PIN_AF4 -to SDRAM_DQ[14] -set_location_assignment PIN_AH3 -to SDRAM_DQ[15] -set_location_assignment PIN_AG13 -to SDRAM_DQML -set_location_assignment PIN_AF13 -to SDRAM_DQMH - -set_location_assignment PIN_AD20 -to SDRAM_CLK -set_location_assignment PIN_AG10 -to SDRAM_CKE - -set_location_assignment PIN_AA19 -to SDRAM_nWE -set_location_assignment PIN_AA18 -to SDRAM_nCAS -set_location_assignment PIN_Y18 -to SDRAM_nCS -set_location_assignment PIN_W14 -to SDRAM_nRAS - -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_* -set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_* -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A* -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA* -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQM* -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_n* -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] -set_instance_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF -to *|SDRAM_* - -#============================================================ -# I/O -#============================================================ -set_location_assignment PIN_Y15 -to LED_USER -set_location_assignment PIN_AA15 -to LED_HDD -set_location_assignment PIN_AG28 -to LED_POWER - -set_location_assignment PIN_AH24 -to BTN_USER -set_location_assignment PIN_AG25 -to BTN_OSD -set_location_assignment PIN_AG23 -to BTN_RESET - -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED_* -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to BTN_* -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to BTN_* - -#============================================================ -# CLOCK -#============================================================ -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to FPGA_CLK1_50 -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to FPGA_CLK2_50 -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to FPGA_CLK3_50 -set_location_assignment PIN_V11 -to FPGA_CLK1_50 -set_location_assignment PIN_Y13 -to FPGA_CLK2_50 -set_location_assignment PIN_E11 -to FPGA_CLK3_50 - -#============================================================ -# HDMI -#============================================================ -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2C_SCL -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2C_SDA -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2S -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_LRCLK -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_MCLK -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_SCLK -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_CLK -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_DE -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[1] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[2] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[3] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[7] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[8] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[9] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[10] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[11] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[12] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[13] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[14] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[15] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[16] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[17] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[18] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[19] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[20] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[21] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[22] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[23] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_HS -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_INT -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_VS -set_location_assignment PIN_U10 -to HDMI_I2C_SCL -set_location_assignment PIN_AA4 -to HDMI_I2C_SDA -set_location_assignment PIN_T13 -to HDMI_I2S -set_location_assignment PIN_T11 -to HDMI_LRCLK -set_location_assignment PIN_U11 -to HDMI_MCLK -set_location_assignment PIN_T12 -to HDMI_SCLK -set_location_assignment PIN_AG5 -to HDMI_TX_CLK -set_location_assignment PIN_AD19 -to HDMI_TX_DE -set_location_assignment PIN_AD12 -to HDMI_TX_D[0] -set_location_assignment PIN_AE12 -to HDMI_TX_D[1] -set_location_assignment PIN_W8 -to HDMI_TX_D[2] -set_location_assignment PIN_Y8 -to HDMI_TX_D[3] -set_location_assignment PIN_AD11 -to HDMI_TX_D[4] -set_location_assignment PIN_AD10 -to HDMI_TX_D[5] -set_location_assignment PIN_AE11 -to HDMI_TX_D[6] -set_location_assignment PIN_Y5 -to HDMI_TX_D[7] -set_location_assignment PIN_AF10 -to HDMI_TX_D[8] -set_location_assignment PIN_Y4 -to HDMI_TX_D[9] -set_location_assignment PIN_AE9 -to HDMI_TX_D[10] -set_location_assignment PIN_AB4 -to HDMI_TX_D[11] -set_location_assignment PIN_AE7 -to HDMI_TX_D[12] -set_location_assignment PIN_AF6 -to HDMI_TX_D[13] -set_location_assignment PIN_AF8 -to HDMI_TX_D[14] -set_location_assignment PIN_AF5 -to HDMI_TX_D[15] -set_location_assignment PIN_AE4 -to HDMI_TX_D[16] -set_location_assignment PIN_AH2 -to HDMI_TX_D[17] -set_location_assignment PIN_AH4 -to HDMI_TX_D[18] -set_location_assignment PIN_AH5 -to HDMI_TX_D[19] -set_location_assignment PIN_AH6 -to HDMI_TX_D[20] -set_location_assignment PIN_AG6 -to HDMI_TX_D[21] -set_location_assignment PIN_AF9 -to HDMI_TX_D[22] -set_location_assignment PIN_AE8 -to HDMI_TX_D[23] -set_location_assignment PIN_T8 -to HDMI_TX_HS -set_location_assignment PIN_AF11 -to HDMI_TX_INT -set_location_assignment PIN_V13 -to HDMI_TX_VS - -#============================================================ -# KEY -#============================================================ -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[1] -set_location_assignment PIN_AH17 -to KEY[0] -set_location_assignment PIN_AH16 -to KEY[1] - -#============================================================ -# LED -#============================================================ -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[1] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[2] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[3] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[7] -set_location_assignment PIN_W15 -to LED[0] -set_location_assignment PIN_AA24 -to LED[1] -set_location_assignment PIN_V16 -to LED[2] -set_location_assignment PIN_V15 -to LED[3] -set_location_assignment PIN_AF26 -to LED[4] -set_location_assignment PIN_AE26 -to LED[5] -set_location_assignment PIN_Y16 -to LED[6] -set_location_assignment PIN_AA23 -to LED[7] - -#============================================================ -# SW -#============================================================ -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[1] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[2] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[3] -set_location_assignment PIN_Y24 -to SW[0] -set_location_assignment PIN_W24 -to SW[1] -set_location_assignment PIN_W21 -to SW[2] -set_location_assignment PIN_W20 -to SW[3] - -set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:sys/build_id.tcl" - -set_global_assignment -name CDF_FILE jtag.cdf -set_global_assignment -name QIP_FILE sys/sys.qip -set_global_assignment -name QIP_FILE sdram.qip -set_global_assignment -name VERILOG_FILE scsi.v -set_global_assignment -name VERILOG_FILE ncr5380.v -set_global_assignment -name VERILOG_FILE floppy_track_encoder.v -set_global_assignment -name VERILOG_FILE floppy.v -set_global_assignment -name SYSTEMVERILOG_FILE ps2_kbd.sv -set_global_assignment -name VERILOG_FILE ps2_mouse.v -set_global_assignment -name VHDL_FILE TG68K_Pack.vhd -set_global_assignment -name VHDL_FILE TG68K_ALU.vhd -set_global_assignment -name VHDL_FILE TG68KdotC_Kernel.vhd -set_global_assignment -name VERILOG_FILE scc.v -set_global_assignment -name VERILOG_FILE iwm.v -set_global_assignment -name VERILOG_FILE via.v -set_global_assignment -name VERILOG_FILE addrDecoder.v -set_global_assignment -name VERILOG_FILE addrController_top.v -set_global_assignment -name VERILOG_FILE dataController_top.v -set_global_assignment -name VERILOG_FILE video.v -set_global_assignment -name SYSTEMVERILOG_FILE MacPlus.sv +source sys/sys.tcl +source sys/sys_analog.tcl +source files.qip set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/MacPlus.sv b/MacPlus.sv index 8281b58..4fee853 100644 --- a/MacPlus.sv +++ b/MacPlus.sv @@ -2,7 +2,7 @@ // Macintosh Plus // // Port to MiSTer -// Copyright (C) 2017,2018 Sorgelig +// Copyright (C) 2017-2019 Sorgelig // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free @@ -29,7 +29,7 @@ module emu input RESET, //Must be passed to hps_io module - inout [44:0] HPS_BUS, + inout [45:0] HPS_BUS, //Base video clock. Usually equals to CLK_SYS. output CLK_VIDEO, @@ -63,7 +63,9 @@ module emu output [15:0] AUDIO_R, output AUDIO_S, // 1 - signed audio samples, 0 - unsigned output [1:0] AUDIO_MIX, // 0 - no mix, 1 - 25%, 2 - 50%, 3 - 100% (mono) - input TAPE_IN, + + //ADC + inout [3:0] ADC_BUS, // SD-SPI output SD_SCK, @@ -115,7 +117,8 @@ module emu input OSD_STATUS ); - + +assign ADC_BUS = 'Z; assign USER_OUT = '1; assign {UART_RTS, UART_TXD, UART_DTR} = 0; assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = 0; diff --git a/files.qip b/files.qip new file mode 100644 index 0000000..cb829e1 --- /dev/null +++ b/files.qip @@ -0,0 +1,18 @@ +set_global_assignment -name QIP_FILE sdram.qip +set_global_assignment -name VERILOG_FILE scsi.v +set_global_assignment -name VERILOG_FILE ncr5380.v +set_global_assignment -name VERILOG_FILE floppy_track_encoder.v +set_global_assignment -name VERILOG_FILE floppy.v +set_global_assignment -name SYSTEMVERILOG_FILE ps2_kbd.sv +set_global_assignment -name VERILOG_FILE ps2_mouse.v +set_global_assignment -name VHDL_FILE TG68K_Pack.vhd +set_global_assignment -name VHDL_FILE TG68K_ALU.vhd +set_global_assignment -name VHDL_FILE TG68KdotC_Kernel.vhd +set_global_assignment -name VERILOG_FILE scc.v +set_global_assignment -name VERILOG_FILE iwm.v +set_global_assignment -name VERILOG_FILE via.v +set_global_assignment -name VERILOG_FILE addrDecoder.v +set_global_assignment -name VERILOG_FILE addrController_top.v +set_global_assignment -name VERILOG_FILE dataController_top.v +set_global_assignment -name VERILOG_FILE video.v +set_global_assignment -name SYSTEMVERILOG_FILE MacPlus.sv diff --git a/sys/alsa.sv b/sys/alsa.sv index 9ed448e..e3aaa50 100644 --- a/sys/alsa.sv +++ b/sys/alsa.sv @@ -23,6 +23,9 @@ module alsa ( input reset, + output reg en_out, + input en_in, + input ram_clk, output reg [28:0] ram_address, output reg [7:0] ram_burstcount, @@ -30,11 +33,11 @@ module alsa input [63:0] ram_readdata, input ram_readdatavalid, output reg ram_read, - + input spi_ss, input spi_sck, input spi_mosi, - + output reg [15:0] pcm_l, output reg [15:0] pcm_r ); @@ -44,7 +47,7 @@ reg [127:0] spi_data; always @(posedge spi_sck, posedge spi_ss) begin reg [7:0] mosi; reg [6:0] spicnt = 0; - + if(spi_ss) spicnt <= 0; else begin mosi <= {mosi[6:0],spi_mosi}; @@ -68,10 +71,10 @@ always @(posedge ram_clk) begin n1 <= spi_new; n2 <= n1; n3 <= n2; - + data1 <= spi_data; data2 <= data1; - + if(~n3 & n2) {buf_wptr,buf_len,buf_addr} <= data2[95:0]; end @@ -79,7 +82,7 @@ reg [31:0] buf_rptr = 0; always @(posedge ram_clk) begin reg got_first = 0; reg ready = 0; - reg ud; + reg ud = 0; reg [31:0] readdata; if(~ram_waitrequest) ram_read <= 0; @@ -90,7 +93,7 @@ always @(posedge ram_clk) begin if(buf_rptr[31:2] >= buf_len[31:2]) buf_rptr <= 0; end - if(reset) {ready, got_first} <= 0; + if(reset) {ready, got_first, ram_burstcount} <= 0; else if(buf_rptr[31:2] != buf_wptr[31:2]) begin if(~got_first) begin @@ -98,7 +101,7 @@ always @(posedge ram_clk) begin got_first <= 1; end else - if(!ram_burstcount && ~ram_waitrequest && ~ready) begin + if(!ram_burstcount && ~ram_waitrequest && ~ready && en_out == en_in) begin ram_address <= buf_addr[31:3] + buf_rptr[31:3]; ud <= buf_rptr[2]; ram_burstcount <= 1; @@ -111,6 +114,8 @@ always @(posedge ram_clk) begin {pcm_r,pcm_l} <= readdata; ready <= 0; end + + if(ce_48k) en_out <= ~en_out; end reg ce_48k; diff --git a/sys/ascal.vhd b/sys/ascal.vhd index 651ee6d..23336d7 100644 --- a/sys/ascal.vhd +++ b/sys/ascal.vhd @@ -30,14 +30,19 @@ -- below 1x) them. -------------------------------------------- --- 4 asynchronous clock domains : +-- 5 clock domains : -- i_xxx : Input video -- o_xxx : Output video -- avl_xxx : Avalon memory bus -- poly_xxx : Polyphase filters memory +-- pal_xxx : Framebuffer mode 8bpp palette. -------------------------------------------- --- Mode 24bits +-- O_FB_FORMAT : Framebuffer format +-- [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp +-- [3] : 0=16bits 565 1=16bits 1555 +-- [4] : 0=RGB 1=BGR (for 16/24/32 modes) +-- [5] : TBD -------------------------------------------- -- Image header. When HEADER = TRUE @@ -47,7 +52,9 @@ -- Header (Bytes. Big Endian.) -- 0 : Type = 1 -- 1 : Pixel format --- 1 : 24 bits/pixel, packed RGB. Big Endian +-- 0 : 16 bits/pixel, RGB : RRRRRGGGGGGBBBBB +-- 1 : 24 bits/pixel, RGB +-- 2 : 32 bits/pixels RGB0 -- 3:2 : Header size : Offset to start of picture (= N_BURST). 12 bits -- 5:4 : Attributes. TBD @@ -91,10 +98,10 @@ USE ieee.numeric_std.ALL; -- Must be a power of two -- INTER : True=Autodetect interlaced video False=Force progressive scan -- HEADER : True=Add image properties header +-- PALETTE : Enable palette for framebuffer -8bpp mode -- DOWNSCALE : True=Support downscaling False=Downscaling disabled -- BYTESWAP : Little/Big endian byte swap -- FRAC : Fractional bits, subpixel resolution --- FORMAT : TBD -- OHRES : Max. output horizontal resolution. Must be a power of two. -- (Used for sizing line buffers) -- IHRES : Max. input horizontal resolution. Must be a power of two. @@ -112,8 +119,8 @@ ENTITY ascal IS HEADER : boolean := true; DOWNSCALE : boolean := true; BYTESWAP : boolean := true; + PALETTE : boolean := true; FRAC : natural RANGE 4 TO 6 :=4; - FORMAT : natural RANGE 1 TO 8 :=1; OHRES : natural RANGE 1 TO 4096 :=2048; IHRES : natural RANGE 1 TO 2048 :=2048; N_DW : natural RANGE 64 TO 128 := 128; @@ -143,7 +150,25 @@ ENTITY ascal IS o_de : OUT std_logic; -- Display Enable o_ce : IN std_logic; -- Clock Enable o_clk : IN std_logic; -- Output clock + + -- Border colour R G B + o_border : IN unsigned(23 DOWNTO 0) := x"000000"; + + ------------------------------------ + -- Framebuffer mode + o_fb_ena : IN std_logic :='0'; -- Enable Framebuffer Mode + o_fb_hsize : IN natural RANGE 0 TO 4095 :=0; + o_fb_vsize : IN natural RANGE 0 TO 4095 :=0; + o_fb_format : IN unsigned(5 DOWNTO 0) :="000100"; + o_fb_base : IN unsigned(31 DOWNTO 0) :=x"0000_0000"; + -- Framebuffer palette in 8bpp mode + pal_clk : IN std_logic :='0'; + pal_dw : IN unsigned(23 DOWNTO 0) :=x"000000"; -- R G B + pal_dr : OUT unsigned(23 DOWNTO 0) :=x"000000"; + pal_a : IN unsigned(7 DOWNTO 0) :=x"00"; -- Colour index + pal_wr : IN std_logic :='0'; + ------------------------------------ -- Low lag PLL tuning o_lltune : OUT unsigned(15 DOWNTO 0); @@ -157,13 +182,13 @@ ENTITY ascal IS vimax : IN natural RANGE 0 TO 4095; -- Output video parameters - run : IN std_logic; -- 1=Enable output image. 0=No image - freeze : IN std_logic; -- 1=Disable framebuffer writes + run : IN std_logic :='1'; -- 1=Enable output image. 0=No image + freeze : IN std_logic :='0'; -- 1=Disable framebuffer writes mode : IN unsigned(4 DOWNTO 0); - -- SYNC |________________________/"""""""""\______| - -- DE |""""""""""""""""""\______________________| - -- RGB | <#IMAGE#> ^HDISP | - -- ^HMIN ^HMAX ^HSSTART ^HSEND ^HTOTAL + -- SYNC |_________________________/"""""""""\_______| + -- DE |""""""""""""""""""\________________________| + -- RGB | <#IMAGE#> ^HDISP | + -- ^HMIN ^HMAX ^HSSTART ^HSEND ^HTOTAL htotal : IN natural RANGE 0 TO 4095; hsstart : IN natural RANGE 0 TO 4095; hsend : IN natural RANGE 0 TO 4095; @@ -177,6 +202,9 @@ ENTITY ascal IS vmin : IN natural RANGE 0 TO 4095; vmax : IN natural RANGE 0 TO 4095; -- 0 <= vmin < vmax < vdisp + -- Scaler format. 00=16bpp 565, 01=24bpp 10=32bpp + format : IN unsigned(1 DOWNTO 0) :="01"; + ------------------------------------ -- Polyphase filter coefficients -- Order : @@ -200,7 +228,7 @@ ENTITY ascal IS avl_write : OUT std_logic; avl_read : OUT std_logic; avl_byteenable : OUT std_logic_vector(N_DW/8-1 DOWNTO 0); - + ------------------------------------ reset_na : IN std_logic ); @@ -242,8 +270,7 @@ ARCHITECTURE rtl OF ascal IS CONSTANT NB_BURST : natural :=ilog2(N_BURST); CONSTANT NB_LA : natural :=ilog2(N_DW/8); -- Low address bits CONSTANT BLEN : natural :=N_BURST / N_DW * 8; -- Burst length - CONSTANT NP : natural :=24; - + ---------------------------------------------------------- TYPE arr_dw IS ARRAY (natural RANGE <>) OF unsigned(N_DW-1 DOWNTO 0); @@ -256,6 +283,11 @@ ARCHITECTURE rtl OF ascal IS SUBTYPE uint12 IS natural RANGE 0 TO 4095; SUBTYPE uint13 IS natural RANGE 0 TO 8191; + TYPE arr_uv24 IS ARRAY (natural RANGE <>) OF unsigned(23 DOWNTO 0); + TYPE arr_uv36 IS ARRAY (natural RANGE <>) OF unsigned(35 DOWNTO 0); + TYPE arr_int9 IS ARRAY (natural RANGE <>) OF integer RANGE -256 TO 255; + TYPE arr_uint12 IS ARRAY (natural RANGE <>) OF uint12; + ---------------------------------------------------------- -- Input image SIGNAL i_pvs,i_pfl,i_pde,i_pce : std_logic; @@ -268,30 +300,34 @@ ARCHITECTURE rtl OF ascal IS SIGNAL i_vsize,i_vmaxmin,i_vmin,i_vmax,i_vcpt : uint12; SIGNAL i_iauto : std_logic; SIGNAL i_mode : unsigned(4 DOWNTO 0); + SIGNAL i_format : unsigned(1 DOWNTO 0); SIGNAL i_ven,i_sof : std_logic; SIGNAL i_wr : std_logic; SIGNAL i_divstart,i_divrun : std_logic; SIGNAL i_de_pre,i_vs_pre,i_fl_pre : std_logic; - SIGNAL i_hs_delay : natural RANGE 0 TO 31; + SIGNAL i_de_delay : natural RANGE 0 TO 31; SIGNAL i_intercnt : natural RANGE 0 TO 3; SIGNAL i_inter,i_half,i_flm : std_logic; - SIGNAL i_write,i_walt,i_wline : std_logic; - SIGNAL i_push,i_pushend,i_pushend2,i_eol,i_eol2,i_eol3 : std_logic; - SIGNAL i_pushhead,i_pushhead2,i_pushhead3,i_hbfix : std_logic; + SIGNAL i_write,i_wreq,i_alt,i_line,i_wline,i_wline_mem : std_logic; + SIGNAL i_walt,i_walt_mem,i_wreq_mem : std_logic; + SIGNAL i_wdelay : natural RANGE 0 TO 7; + SIGNAL i_push,i_pushend,i_pushend2 : std_logic; + SIGNAL i_eol : std_logic; + SIGNAL i_pushhead,i_pushhead2,i_pushhead3 : std_logic; SIGNAL i_hburst,i_hbcpt : natural RANGE 0 TO 31; SIGNAL i_shift : unsigned(0 TO 119) := (OTHERS =>'0'); SIGNAL i_head : unsigned(127 DOWNTO 0); SIGNAL i_acpt : natural RANGE 0 TO 15; SIGNAL i_dpram : arr_dw(0 TO BLEN*2-1); ATTRIBUTE ramstyle OF i_dpram : SIGNAL IS "no_rw_check"; - SIGNAL i_endframe0,i_endframe1,i_syncline : std_logic; + SIGNAL i_endframe0,i_endframe1,i_vss : std_logic; SIGNAL i_wad : natural RANGE 0 TO BLEN*2-1; SIGNAL i_dw : unsigned(N_DW-1 DOWNTO 0); - SIGNAL i_adrs,i_adrsi : unsigned(31 DOWNTO 0); -- Avalon address + SIGNAL i_adrs,i_adrsi,i_wadrs,i_wadrs_mem : unsigned(31 DOWNTO 0); SIGNAL i_reset_na : std_logic; SIGNAL i_hnp,i_vnp : std_logic; - SIGNAL i_line : arr_pix(0 TO IHRES-1); -- Downscale line buffer - ATTRIBUTE ramstyle OF i_line : SIGNAL IS "no_rw_check"; + SIGNAL i_mem : arr_pix(0 TO IHRES-1); -- Downscale line buffer + ATTRIBUTE ramstyle OF i_mem : SIGNAL IS "no_rw_check"; SIGNAL i_ohsize,i_ovsize : uint12; SIGNAL i_vdivi : unsigned(12 DOWNTO 0); SIGNAL i_vdivr : unsigned(24 DOWNTO 0); @@ -307,7 +343,7 @@ ARCHITECTURE rtl OF ascal IS SIGNAL i_hpixp,i_hpix0,i_hpix1,i_hpix2,i_hpix3,i_hpix4 : type_pix; SIGNAL i_hpix,i_pix : type_pix; SIGNAL i_hnp1,i_hnp2,i_hnp3,i_hnp4 : std_logic; - SIGNAL i_ven1,i_ven2,i_ven3,i_ven4,i_ven5,i_ven6,i_ven7 : std_logic; + SIGNAL i_ven1,i_ven2,i_ven3,i_ven4,i_ven5,i_ven6 : std_logic; ---------------------------------------------------------- -- Avalon @@ -316,19 +352,18 @@ ARCHITECTURE rtl OF ascal IS SIGNAL avl_write_i,avl_write_sync,avl_write_sync2 : std_logic; SIGNAL avl_read_i,avl_read_sync,avl_read_sync2 : std_logic; SIGNAL avl_read_pulse,avl_write_pulse : std_logic; - SIGNAL avl_reading : std_logic; SIGNAL avl_read_sr,avl_write_sr,avl_read_clr,avl_write_clr : std_logic; SIGNAL avl_rad,avl_rad_c,avl_wad : natural RANGE 0 TO 2*BLEN-1; SIGNAL avl_walt,avl_wline,avl_rline : std_logic; SIGNAL avl_dw,avl_dr : unsigned(N_DW-1 DOWNTO 0); SIGNAL avl_wr : std_logic; - SIGNAL avl_readack : std_logic; + SIGNAL avl_readdataack,avl_readack : std_logic; SIGNAL avl_radrs,avl_wadrs : unsigned(31 DOWNTO 0); - SIGNAL avl_rbib : std_logic; SIGNAL avl_i_offset0,avl_o_offset0 : unsigned(31 DOWNTO 0); SIGNAL avl_i_offset1,avl_o_offset1 : unsigned(31 DOWNTO 0); SIGNAL avl_reset_na : std_logic; SIGNAL avl_o_vs_sync,avl_o_vs : std_logic; + SIGNAL avl_fb_ena : std_logic; FUNCTION buf_next(a,b : natural RANGE 0 TO 2) RETURN natural IS BEGIN @@ -336,17 +371,22 @@ ARCHITECTURE rtl OF ascal IS IF (a=1 AND b=2) OR (a=2 AND b=1) THEN RETURN 0; END IF; RETURN 1; END FUNCTION; - FUNCTION buf_offset(b : natural RANGE 0 TO 2) RETURN unsigned IS + FUNCTION buf_offset(b : natural RANGE 0 TO 2; + base : unsigned(31 DOWNTO 0); + size : unsigned(31 DOWNTO 0)) RETURN unsigned IS BEGIN - IF b=1 THEN RETURN RAMSIZE; END IF; - IF b=2 THEN RETURN RAMSIZE(30 DOWNTO 0) & '0'; END IF; - RETURN x"00000000"; + IF b=1 THEN RETURN base+size; END IF; + IF b=2 THEN RETURN base+(size(30 DOWNTO 0) & '0'); END IF; + RETURN base; END FUNCTION; ---------------------------------------------------------- -- Output SIGNAL o_run : std_logic; SIGNAL o_mode,o_hmode,o_vmode : unsigned(4 DOWNTO 0); + SIGNAL o_format : unsigned(5 DOWNTO 0); + SIGNAL o_fb_pal_dr : unsigned(23 DOWNTO 0); + SIGNAL pal_mem : arr_uv24(0 TO 255); SIGNAL o_htotal,o_hsstart,o_hsend : uint12; SIGNAL o_hmin,o_hmax,o_hdisp : uint12; SIGNAL o_hsize,o_vsize : uint12; @@ -359,7 +399,8 @@ ARCHITECTURE rtl OF ascal IS TYPE type_o_state IS (sDISP,sHSYNC,sREAD,sWAITREAD); SIGNAL o_state : type_o_state; SIGNAL o_copy,o_readack,o_readack_sync,o_readack_sync2 : std_logic; - SIGNAL o_copyv : unsigned(0 TO 7); + SIGNAL o_readdataack,o_readdataack_sync,o_readdataack_sync2 : std_logic; + SIGNAL o_copyv : unsigned(0 TO 8); SIGNAL o_adrs : unsigned(31 DOWNTO 0); -- Avalon address SIGNAL o_adrs_pre : natural RANGE 0 TO 32*4096-1; SIGNAL o_adrsa,o_rline : std_logic; @@ -367,7 +408,7 @@ ARCHITECTURE rtl OF ascal IS SIGNAL o_adturn : std_logic; SIGNAL o_dr : unsigned(N_DW-1 DOWNTO 0); SIGNAL o_shift : unsigned(0 TO N_DW+15); - SIGNAL o_sh,o_sh1,o_sh2,o_sh3 : std_logic; + SIGNAL o_sh,o_sh1,o_sh2,o_sh3,o_sh4 : std_logic; SIGNAL o_reset_na : std_logic; SIGNAL o_dpram : arr_dw(0 TO BLEN*2-1); ATTRIBUTE ramstyle OF o_dpram : SIGNAL IS "no_rw_check"; @@ -382,7 +423,7 @@ ARCHITECTURE rtl OF ascal IS SIGNAL o_hcpt,o_vcpt,o_vcpt_pre,o_vcpt_pre2,o_vcpt_pre3 : uint12; SIGNAL o_ihsize,o_ivsize : uint12; - SIGNAL o_vfrac,o_hfrac,o_hfrac1,o_hfrac2,o_hfrac3 : unsigned(11 DOWNTO 0); + SIGNAL o_vfrac,o_hfrac,o_hfrac1,o_hfrac2,o_hfrac3,o_hfrac4 : unsigned(11 DOWNTO 0); SIGNAL o_hacc,o_hacc_ini,o_hacc_next,o_vacc,o_vacc_next,o_vacc_ini : natural RANGE 0 TO 4*OHRES-1; SIGNAL o_hsv,o_vsv,o_dev,o_pev : unsigned(0 TO 5); SIGNAL o_hsp,o_vss : std_logic; @@ -394,12 +435,13 @@ ARCHITECTURE rtl OF ascal IS SIGNAL o_dshi : natural RANGE 0 TO 3; SIGNAL o_first,o_last,o_last1,o_last2,o_last3 : std_logic; SIGNAL o_lastt1,o_lastt2,o_lastt3 : std_logic; - SIGNAL o_alt : unsigned(3 DOWNTO 0); + SIGNAL o_alt,o_altx : unsigned(3 DOWNTO 0); SIGNAL o_hdown,o_vdown : std_logic; SIGNAL o_primv,o_lastv,o_bibv : unsigned(0 TO 2); - SIGNAL o_bibu,o_bib : std_logic :='0'; - SIGNAL o_dcpt,o_dcpt1,o_dcpt2,o_dcpt3,o_dcpt4,o_dcpt5,o_dcpt6,o_dcpt7 : uint12; - SIGNAL o_hpix0,o_hpix1,o_hpix2,o_hpix3 : type_pix; + SIGNAL o_bibu : std_logic :='0'; + SIGNAL o_dcptv : arr_uint12(1 TO 8); + SIGNAL o_dcpt : uint12; + SIGNAL o_hpixs,o_hpix0,o_hpix1,o_hpix2,o_hpix3 : type_pix; SIGNAL o_hpixq,o_vpixq,o_vpixq1 : arr_pix(0 TO 3); SIGNAL o_vpe : std_logic; @@ -412,132 +454,165 @@ ARCHITECTURE rtl OF ascal IS SIGNAL o_hacpt,o_vacpt : unsigned(11 DOWNTO 0); ----------------------------------------------------------------------------- - -- ACPT 012345678901234--- 128bits DATA - -- 0 ...............RGB - -- 1 ............RGBrgb - -- 2 .........RGBrgbRGB - -- 3 ......RGBrgbRGBrgb - -- 4 ...RGBrgbRGBrgbRGB - -- 5 RGBrgbRGBrgbRGBrgb => PUSH RGBrgbRGBrgbRGBr - -- 6 .............gbRGB - -- 7 ..........gbRGBrgb - -- 8 .......gbRGBrgbRGB - -- 9 ....gbRGBrgbRGBrgb - -- 10 .gbRGBrgbRGBrgbRGB => PUSH gbRGBrgbRGBrgbRG - -- 11 ..............Brgb - -- 12 ...........BrgbRGB - -- 13 ........BrgbRGBrgb - -- 14 .....BrgbRGBrgbRGB - -- 15 ..BrgbRGBrgbRGBrgb => PUSH BrgbRGBrgbRGBrgb + FUNCTION shift_ishift(shift : unsigned(0 TO 119); + pix : type_pix; + format : unsigned(1 DOWNTO 0)) RETURN unsigned IS + BEGIN + CASE format IS + WHEN "01" => -- 24bpp + RETURN shift(24 TO 119) & pix.r & pix.g & pix.b; + WHEN "10" => -- 32bpp + RETURN shift(32 TO 119) & pix.r & pix.g & pix.b & x"00"; + WHEN OTHERS => -- 16bpp 565 + RETURN shift(16 TO 119) & + pix.g(4 DOWNTO 2) & pix.r(7 DOWNTO 3) & + pix.b(7 DOWNTO 3) & pix.g(7 DOWNTO 5); + END CASE; + END FUNCTION; - -- ACPT 012345678901234--- 64bits DATA - -- 0 ...............RGB - -- 1 ............RGBrgb - -- 2 .........RGBrgbRGB => PUSH RGBrgbRG - -- 3 ..............Brgb - -- 4 ...........BrgbRGB - -- 5 ........BrgbRGBrgb => PUSH BrgbRGBr - -- 6 .............gbRGB - --- 7 ..........gbRGBrgb => PUSH gbRGBrgb - - FUNCTION shift24_ipack(i_dw : unsigned(N_DW-1 DOWNTO 0); - acpt : natural RANGE 0 TO 15; - shift : unsigned(0 TO 119); - pix : type_pix) RETURN unsigned IS + FUNCTION shift_ipack(i_dw : unsigned(N_DW-1 DOWNTO 0); + acpt : natural RANGE 0 TO 15; + shift : unsigned(0 TO 119); + pix : type_pix; + format : unsigned(1 DOWNTO 0)) RETURN unsigned IS VARIABLE dw : unsigned(N_DW-1 DOWNTO 0); BEGIN - IF N_DW=128 THEN - IF acpt=5 THEN dw:=shift(0 TO 119) & pix.r; - ELSIF acpt=10 THEN dw:=shift(8 TO 119) & pix.r & pix.g; - ELSIF acpt=15 THEN dw:=shift(16 TO 119) & pix.r & pix.g & pix.b; - ELSE dw:=i_dw; - END IF; - ELSE -- N_DW=64 - IF (acpt MOD 8)=2 THEN dw:=shift(72 TO 119) & pix.r & pix.g; - ELSIF (acpt MOD 8)=5 THEN dw:=shift(64 TO 119) & pix.r; - ELSIF (acpt MOD 8)=7 THEN dw:=shift(80 TO 119) & pix.r & pix.g & pix.b; - ELSE dw:=i_dw; - END IF; - END IF; + dw:=i_dw; + CASE format IS + WHEN "01" => -- 24bpp + IF N_DW=128 THEN + IF acpt=5 THEN dw:=shift(0 TO 119) & pix.r; + ELSIF acpt=10 THEN dw:=shift(8 TO 119) & pix.r & pix.g; + ELSIF acpt=15 THEN dw:=shift(16 TO 119) & pix.r & pix.g & pix.b; + END IF; + ELSE -- N_DW=64 + IF (acpt MOD 8)=2 THEN dw:=shift(72 TO 119) & pix.r & pix.g; + ELSIF (acpt MOD 8)=5 THEN dw:=shift(64 TO 119) & pix.r; + ELSIF (acpt MOD 8)=7 THEN dw:=shift(80 TO 119) & pix.r & pix.g & pix.b; + END IF; + END IF; + WHEN "10" => -- 32bpp + IF (N_DW=128 AND (acpt MOD 4)=3) OR (N_DW=64 AND (acpt MOD 8)=7) THEN + dw:=shift(128-N_DW+24 TO 119) & pix.r & pix.g & pix.b & x"00"; + END IF; + WHEN OTHERS => -- 16bpp 565 + IF (N_DW=128 AND (acpt MOD 8)=7) OR (N_DW=64 AND (acpt MOD 4)=3) THEN + dw:=shift(128-N_DW+8 TO 119) & pix.g(4 DOWNTO 2) & pix.r(7 DOWNTO 3) & + pix.b(7 DOWNTO 3) & pix.g(7 DOWNTO 5); + END IF; + END CASE; RETURN dw; END FUNCTION; - FUNCTION shift24_inext (acpt : natural RANGE 0 TO 15) RETURN boolean IS + FUNCTION shift_inext (acpt : natural RANGE 0 TO 15; + format : unsigned(1 DOWNTO 0)) RETURN boolean IS BEGIN - IF N_DW=128 THEN - RETURN (acpt=5 OR acpt=10 OR acpt=15); - ELSE -- N_DW=64 - RETURN ((acpt MOD 8)=2 OR (acpt MOD 8)=5 OR (acpt MOD 8)=7); - END IF; + CASE format IS + WHEN "01" => -- 24bpp + RETURN (N_DW=128 AND (acpt=5 OR acpt=10 OR acpt=15)) OR + (N_DW=64 AND ((acpt MOD 8)=2 OR (acpt MOD 8)=5 OR (acpt MOD 8)=7)); + WHEN "10" => -- 32bpp + RETURN (N_DW=128 AND ((acpt MOD 4)=3)) OR + (N_DW=64 AND ((acpt MOD 2)=1)); + WHEN OTHERS => -- 16bpp + RETURN (N_DW=128 AND ((acpt MOD 8)=7)) OR + (N_DW=64 AND ((acpt MOD 4)=3)); + END CASE; END FUNCTION; - ---------------------- - -- ACPT 0123456789012345 128bits DATA - -- 0 >RGBrgbRGBrgbRGBr - -- 1 rgbRGBrgbRGBr - -- 2 RGBrgbRGBr - -- 3 rgbRGBr - -- 4 RGBr - -- 5 >r gbRGBrgbRGBrgbRG - -- 6 RGBrgbRGBrgbRG - -- 7 rgbRGBrgbRG - -- 8 RGBrgbRG - -- 9 rgbRG - -- 10 >RG BrgbRGBrgbRGBrgb - -- 11 rgbRGBrgbRGBrgb - -- 12 RGBrgbRGBrgb - -- 13 rgbRGBrgb - -- 14 RGBrgb - -- 15 rgb - - -- ACPT 01234567 64bits DATA - -- 0 >RGBrgbRG - -- 1 rgbRG - -- 2 >RG BrgbRGBr - -- 3 rgbRGBr - -- 4 RGBr - -- 5 >r gbRGBrgb - -- 6 RGBrgb - -- 7 rgb - - FUNCTION shift24_opack(acpt : natural RANGE 0 TO 15; - shift : unsigned(0 TO N_DW+15); - dr : unsigned(N_DW-1 DOWNTO 0)) RETURN unsigned IS + FUNCTION shift_opack(acpt : natural RANGE 0 TO 15; + shift : unsigned(0 TO N_DW+15); + dr : unsigned(N_DW-1 DOWNTO 0); + format : unsigned(5 DOWNTO 0)) RETURN unsigned IS VARIABLE shift_v : unsigned(0 TO N_DW+15); BEGIN - IF N_DW=128 THEN - IF acpt=0 THEN - shift_v:=dr & dr(15 DOWNTO 0); - ELSIF acpt=5 THEN - shift_v:=shift(24 TO 31) & dr & dr(7 DOWNTO 0); - ELSIF acpt=10 THEN - shift_v:=shift(24 TO 39) & dr; - ELSE - shift_v:=shift(24 TO N_DW+15) & dr(23 DOWNTO 0); - END IF; - ELSE -- N_DW=64 - IF (acpt MOD 8)=0 THEN - shift_v:=dr & dr(15 DOWNTO 0); - ELSIF (acpt MOD 8)=2 THEN - shift_v:=shift(24 TO 39) & dr; - ELSIF (acpt MOD 8)=5 THEN - shift_v:=shift(24 TO 31) & dr & dr(7 DOWNTO 0); - ELSE - shift_v:=shift(24 TO N_DW+15) & dr(23 DOWNTO 0); - END IF; - END IF; + CASE format(2 DOWNTO 0) IS + WHEN "011" => -- 8bpp + IF (N_DW=128 AND acpt=0) OR (N_DW=64 AND (acpt MOD 8)=0) THEN + shift_v:=dr & dr(15 DOWNTO 0); + ELSE + shift_v:=shift(8 TO N_DW+15) & dr(7 DOWNTO 0); + END IF; + + WHEN "100" => -- 16bpp + IF (N_DW=128 AND (acpt MOD 8)=0) OR (N_DW=64 AND (acpt MOD 4)=0) THEN + shift_v:=dr & dr(15 DOWNTO 0); + ELSE + shift_v:=shift(16 TO N_DW+15) & dr(15 DOWNTO 0); + END IF; + + WHEN "101" => -- 24bpp + IF N_DW=128 THEN + IF acpt=0 THEN + shift_v:=dr & dr(15 DOWNTO 0); + ELSIF acpt=5 THEN + shift_v:=shift(24 TO 31) & dr & dr(7 DOWNTO 0); + ELSIF acpt=10 THEN + shift_v:=shift(24 TO 39) & dr; + ELSE + shift_v:=shift(24 TO N_DW+15) & dr(23 DOWNTO 0); + END IF; + ELSE -- N_DW=64 + IF (acpt MOD 8)=0 THEN + shift_v:=dr & dr(15 DOWNTO 0); + ELSIF (acpt MOD 8)=2 THEN + shift_v:=shift(24 TO 39) & dr; + ELSIF (acpt MOD 8)=5 THEN + shift_v:=shift(24 TO 31) & dr & dr(7 DOWNTO 0); + ELSE + shift_v:=shift(24 TO N_DW+15) & dr(23 DOWNTO 0); + END IF; + END IF; + WHEN OTHERS => -- 32bpp + IF (N_DW=128 AND (acpt MOD 4)=0) OR (N_DW=64 AND (acpt MOD 2)=0) THEN + shift_v:=dr & dr(15 DOWNTO 0); + ELSE + shift_v:=shift(32 TO N_DW+15) & dr(31 DOWNTO 0); + END IF; + END CASE; RETURN shift_v; END FUNCTION; - FUNCTION shift24_onext (acpt : natural RANGE 0 TO 15) RETURN boolean IS + FUNCTION shift_onext (acpt : natural RANGE 0 TO 15; + format : unsigned(5 DOWNTO 0)) RETURN boolean IS BEGIN - IF N_DW=128 THEN - RETURN (acpt=0 OR acpt=5 OR acpt=10); - ELSE -- N_DW=64 - RETURN ((acpt MOD 8)=0 OR (acpt MOD 8)=2 OR (acpt MOD 8)=5); - END IF; + CASE format(2 DOWNTO 0) IS + WHEN "011" => -- 8bpp + RETURN (N_DW=128 AND acpt=0) OR + (N_DW=64 AND ((acpt MOD 8)=0)); + WHEN "100" => -- 16bpp + RETURN (N_DW=128 AND ((acpt MOD 8)=0)) OR + (N_DW=64 AND ((acpt MOD 4)=0)); + WHEN "101" => -- 24bpp + RETURN (N_DW=128 AND (acpt=0 OR acpt=5 OR acpt=10)) OR + (N_DW=64 AND ((acpt MOD 8)=0 OR (acpt MOD 8)=2 OR (acpt MOD 8)=5)); + WHEN OTHERS => -- 32bpp + RETURN (N_DW=128 AND ((acpt MOD 4)=0)) OR + (N_DW=64 AND ((acpt MOD 2)=0)); + END CASE; END FUNCTION; + FUNCTION shift_opix (shift : unsigned(0 TO N_DW+15); + format : unsigned(5 DOWNTO 0)) RETURN type_pix IS + BEGIN + CASE format(3 DOWNTO 0) IS + WHEN "0100" => -- 16bpp 565 + RETURN (b=>shift(8 TO 12) & shift(8 TO 10), + g=>shift(13 TO 15) & shift(0 TO 2) & shift(13 TO 14), + r=>shift(3 TO 7) & shift(3 TO 5)); + WHEN "1100" => -- 16bpp 1555 + RETURN (b=>shift(9 TO 13) & shift(9 TO 11), + g=>shift(14 TO 15) & shift(0 TO 2) & shift(14 TO 15) & shift(0), + r=>shift(3 TO 7) & shift(3 TO 5)); + WHEN "0101" | "0110" => -- 24bpp / 32bpp + RETURN (r=>shift(0 TO 7),g=>shift(8 TO 15),b=>shift(16 TO 23)); + + WHEN OTHERS => + RETURN (r=>shift(0 TO 7),g=>shift(8 TO 15),b=>shift(16 TO 23)); + + END CASE; + END FUNCTION; + FUNCTION swap(d : unsigned(N_DW-1 DOWNTO 0)) RETURN unsigned IS VARIABLE e : unsigned(N_DW-1 DOWNTO 0); BEGIN @@ -787,9 +862,6 @@ ARCHITECTURE rtl OF ascal IS ----------------------------------------------------------------------------- -- Polyphase - TYPE arr_uv36 IS ARRAY (natural RANGE <>) OF unsigned(35 DOWNTO 0); - TYPE arr_int9 IS ARRAY (natural RANGE <>) OF integer RANGE -256 TO 255; - CONSTANT POLY16 : arr_int9 := ( -24,-21,-15,-9,-5,-1,4,8,6,8,5,4,3,1,0,0, 176,174,169,160,150,131,115,85,58,27,4,-6,-20,-24,-26,-25, @@ -886,13 +958,16 @@ BEGIN ELSIF rising_edge(i_clk) THEN i_push<='0'; + i_pushhead<='0'; i_eol<='0'; -- End Of Line i_freeze <=freeze; -- i_iauto<=iauto; -- + i_wreq<='0'; + i_wr<='0'; ------------------------------------------------------ i_head(127 DOWNTO 120)<=x"01"; -- Header type - i_head(119 DOWNTO 112)<=x"01"; -- 24bits/pixels, packed RGB, big endian + i_head(119 DOWNTO 112)<="000000" & i_format; -- Header format i_head(111 DOWNTO 96)<="0000" & to_unsigned(N_BURST,12); -- Header size i_head(95 DOWNTO 80)<=x"0000"; -- Attributes. TBD i_head(80)<=i_inter; @@ -938,36 +1013,33 @@ BEGIN i_sof<='1'; END IF; + IF i_pde='1' AND i_de_pre='0' THEN + i_flm<=i_pfl; + END IF; + IF i_pde='1' AND i_sof='1' THEN i_sof<='0'; i_vcpt<=0; - IF i_inter='1' AND i_flm='1' AND i_half='0' AND INTER THEN - i_wline<='1'; + IF i_inter='1' AND i_flm='0' AND i_half='0' AND INTER THEN + i_line<='1'; i_adrsi<=to_unsigned(N_BURST * i_hburst,32) + to_unsigned(N_BURST * to_integer( unsigned'("00") & to_std_logic(HEADER)),32); ELSE - i_wline<='0'; + i_line<='0'; i_adrsi<=to_unsigned(N_BURST * to_integer( unsigned'("00") & to_std_logic(HEADER)),32); END IF; END IF; - IF i_pde='1' THEN - i_flm<=NOT i_pfl; - END IF; - i_ven<=to_std_logic(i_hcpt>=i_hmin AND i_hcpt<=i_hmax AND i_vcpt>=i_vmin AND i_vcpt<=i_vmax); -- Detects end of frame for triple buffering. - i_endframe0<=to_std_logic(i_vcpt=i_vmax + 1 AND - (i_inter='0' OR i_flm='0')); - i_endframe1<=to_std_logic(i_vcpt=i_vmax + 1 AND - (i_inter='0' OR i_flm='1')); + i_endframe0<=i_vs AND (NOT i_inter OR i_flm); + i_endframe1<=i_vs AND (NOT i_inter OR NOT i_flm); - -- Detects third line for low lag mode - i_syncline<=to_std_logic(i_vcpt=i_vmin + 4); + i_vss<=to_std_logic(i_vcpt>=i_vmin AND i_vcpt<=i_vmax); ---------------------------------------------------- IF i_pde='1' AND i_de_pre='0' THEN @@ -996,9 +1068,17 @@ BEGIN i_vmin<=vimin; -- i_vmax<=vimax; -- END IF; - + + IF i_format="00" OR i_format="11" THEN -- 16bpp + i_hburst<=(i_hrsize*2 + N_BURST - 1) / N_BURST; + ELSIF i_format="01" THEN -- 24bpp + i_hburst<=(i_hrsize*3 + N_BURST - 1) / N_BURST; + ELSE -- 32bpp + i_hburst<=(i_hrsize*4 + N_BURST - 1) / N_BURST; + END IF; ---------------------------------------------------- i_mode<=mode; -- + i_format<=format; -- -- Downscaling : Nearest or bilinear i_bil<=to_std_logic(i_mode(2 DOWNTO 0)/="000" AND DOWNSCALE); @@ -1013,15 +1093,15 @@ BEGIN IF i_inter='0' THEN -- Non interlaced i_vsize<=i_vmaxmin; - i_half<='0'; + i_half <='0'; ELSIF i_ovsize<2*i_vmaxmin THEN -- Interlaced, but downscaling, use only half frames i_vsize<=i_vmaxmin; - i_half<='1'; + i_half <='1'; ELSE -- Interlaced : Double image height i_vsize<=2*i_vmaxmin; - i_half<='0'; + i_half <='0'; END IF; i_ohsize<=o_hsize; -- @@ -1030,7 +1110,7 @@ BEGIN ---------------------------------------------------- -- Downscaling vertical i_divstart<='0'; - IF i_hs_delay=7 THEN + IF i_de_delay=16 THEN IF (i_vacc + 2*i_ovsize) < 2*i_vsize THEN i_vacc<=(i_vacc + 2*i_ovsize) MOD 8192; i_vnp<='0'; @@ -1046,9 +1126,9 @@ BEGIN END IF; END IF; - --IF i_vdown='0' THEN - -- i_vnp<='1'; - --END IF; + IF i_vdown='0' THEN + i_vnp<='1'; + END IF; -- Downscaling horizontal IF i_ven='1' THEN @@ -1073,9 +1153,9 @@ BEGIN i_hpix3<=i_hpix2; i_hpix4<=i_hpix3; - i_hnp1<=i_hnp; i_hnp2<=i_hnp1; i_hnp3<=i_hnp2; i_hnp4<=i_hnp3; - i_ven1<=i_ven; i_ven2<=i_ven1; i_ven3<=i_ven2; i_ven4<=i_ven3; - i_ven5<=i_ven4; i_ven6<=i_ven5; i_ven7<=i_ven6; + i_hnp1<=i_hnp; i_hnp2<=i_hnp1; i_hnp3<=i_hnp2; i_hnp4<=i_hnp3; + i_ven1<=i_ven; i_ven2<=i_ven1; i_ven3<=i_ven2; i_ven4<=i_ven3; + i_ven5<=i_ven4; i_ven6<=i_ven5; -- C1 : DIV 1. Pipelined 4 bits non-restoring divider dir_v:=x"000"; @@ -1148,62 +1228,46 @@ BEGIN -- VEN : Enable pixel within displayed window IF (i_hnp4='1' AND i_ven6='1') OR i_pushend='1' THEN - i_shift<=i_shift(24 TO 119) & i_pix.r & i_pix.g & i_pix.b; - i_dw<=shift24_ipack(i_dw,i_acpt,i_shift,i_pix); + i_shift<=shift_ishift(i_shift,i_pix,i_format); + i_dw<=shift_ipack(i_dw,i_acpt,i_shift,i_pix,i_format); - IF shift24_inext(i_acpt) AND i_vnp='1' THEN + IF shift_inext(i_acpt,i_format) AND i_vnp='1' THEN i_push<='1'; i_pushend<='0'; END IF; i_acpt<=(i_acpt+1) MOD 16; END IF; - IF i_pushhead='1' THEN - i_dw<=i_head; - i_pushhead2<='1'; - i_pushhead<='0'; - i_count<=i_count+1; - END IF; - IF i_ven6='1' AND i_ven5='0' AND i_vnp='1' THEN i_pushend<='1'; END IF; i_pushend2<=i_pushend; - IF ((i_ven7='1' AND i_ven6='0') OR i_pushend2='1') - AND i_pushend='0' THEN - -- EOL après fin PUSHEND. - -- - Soit il n'y a pas eu de pushend (à cause de VNP) - -- - Soit front descendant pushend + IF i_pushend2='1' AND i_pushend='0' THEN i_eol<='1'; END IF; - - IF i_pde='0' AND i_de_pre='1' THEN - i_hs_delay<=0; - ELSIF i_hs_delay<18 THEN - i_hs_delay<=i_hs_delay+1; - END IF; - IF i_hs_delay=7 THEN + IF i_pde='0' AND i_de_pre='1' THEN + i_de_delay<=0; + ELSIF i_de_delay<18 THEN + i_de_delay<=i_de_delay+1; + END IF; + + IF i_de_delay=16 THEN i_lwad<=0; i_lrad<=0; i_vcpt<=i_vcpt+1; i_hacc<=(i_hsize - i_ohsize + 8192) MOD 8192; + i_hbcpt<=0; END IF; - IF i_hs_delay=17 THEN + IF i_de_delay=17 THEN i_acpt<=0; i_wad<=2*BLEN-1; - i_hbcpt<=0; -- Bursts per line counter - IF i_vnp='1' AND i_hbcpt>0 AND i_hbfix='0' THEN - i_hburst<=i_hbcpt; - i_hbfix<='1'; - END IF; END IF; IF i_pvs='0' AND i_vs_pre='1' THEN -- Push header i_pushhead<=to_std_logic(HEADER); - i_hbfix<='0'; END IF; END IF; -- IF i_pce='1' @@ -1221,45 +1285,54 @@ BEGIN END IF; ------------------------------------------------------ - -- Push pixels to DPRAM - i_wr<='0'; + -- Write image properties header + i_pushhead2<=i_pushhead; i_pushhead3<=i_pushhead2; - IF i_push='1' AND i_freeze='0' THEN + IF i_pushhead='1' AND i_freeze='0' THEN + i_dw<=i_head(127 DOWNTO 128-N_DW); + i_count<=i_count+1; i_wr<='1'; - i_wad<=(i_wad+1) MOD (BLEN*2); - IF (i_wad+1) MOD BLEN=BLEN-1 THEN - i_hbcpt<=(i_hbcpt+1) MOD 32; - i_write<=i_write XOR NOT i_freeze; - i_walt<=to_std_logic((i_wad+1)/BLEN /= 0); - i_adrs<=i_adrsi; - i_adrsi<=i_adrsi+N_BURST; + i_wad<=0; + IF N_DW=128 THEN + i_alt<='0'; + i_wreq<=NOT i_freeze; + i_adrs<=(OTHERS =>'0'); END IF; END IF; - i_pushhead3<=i_pushhead2; - - IF i_pushhead2='1' AND i_freeze='0' THEN + IF i_pushhead2='1' AND i_freeze='0' AND N_DW=64 THEN + i_dw<=i_head(N_DW-1 DOWNTO 0); i_wr<='1'; - i_wad<=0; - i_write<=i_write XOR NOT i_freeze; - i_walt<='0'; + i_wad<=1; + i_wreq<=NOT i_freeze; + i_alt<='0'; i_adrs<=(OTHERS =>'0'); - i_pushhead2<='0'; END IF; IF i_pushhead3='1' THEN i_wad<=BLEN-1; END IF; - -- Delay a bit EOL : Async. AVL/I clocks... - i_eol2<=i_eol; i_eol3<=i_eol2; + ------------------------------------------------------ + -- Push pixels to DPRAM + IF i_push='1' AND i_freeze='0' THEN + i_wr<='1'; + i_wad<=(i_wad+1) MOD (BLEN*2); + IF (i_wad+1) MOD BLEN=BLEN-1 AND i_hbcpt avl_write_sync2<=avl_write_sync; avl_write_pulse<=avl_write_sync XOR avl_write_sync2; - avl_wadrs <=i_adrs AND (RAMSIZE - 1); -- - avl_wline <=i_wline; -- - avl_walt <=i_walt; -- + IF avl_write_pulse='1' THEN + avl_wadrs <=i_wadrs AND (RAMSIZE - 1); -- + avl_wline <=i_wline; -- + avl_walt <=i_walt; -- + END IF; ---------------------------------- avl_read_sync<=o_read; -- avl_read_sync2<=avl_read_sync; avl_read_pulse<=avl_read_sync XOR avl_read_sync2; - avl_rbib <=o_bib; avl_radrs <=o_adrs AND (RAMSIZE - 1); -- avl_rline <=o_rline; -- -------------------------------------------- - avl_o_offset0<=buf_offset(o_obuf0); -- - avl_o_offset1<=buf_offset(o_obuf1); -- - avl_i_offset0<=buf_offset(o_ibuf0); -- - avl_i_offset1<=buf_offset(o_ibuf1); -- - - avl_o_vs_sync<=o_vsv(0); -- + avl_o_vs_sync<=o_vsv(0); -- avl_o_vs<=avl_o_vs_sync; + avl_fb_ena<=o_fb_ena; -- + IF avl_fb_ena='0' THEN + IF HEADER THEN + avl_o_offset0<=buf_offset(o_obuf0,RAMBASE,RAMSIZE) + N_BURST; -- + avl_o_offset1<=buf_offset(o_obuf1,RAMBASE,RAMSIZE) + N_BURST; -- + ELSE + avl_o_offset0<=buf_offset(o_obuf0,RAMBASE,RAMSIZE); -- + avl_o_offset1<=buf_offset(o_obuf1,RAMBASE,RAMSIZE); -- + END IF; + ELSIF avl_o_vs_sync='0' AND avl_o_vs='1' THEN + -- Copy framebuffer base address at VS falling edge + avl_o_offset0<=o_fb_base; -- + avl_o_offset1<=o_fb_base; -- + END IF; + + avl_i_offset0<=buf_offset(o_ibuf0,RAMBASE,RAMSIZE); -- + avl_i_offset1<=buf_offset(o_ibuf1,RAMBASE,RAMSIZE); -- + -------------------------------------------- avl_dw<=swap(unsigned(avl_readdata)); avl_read_i<='0'; avl_write_i<='0'; avl_write_sr<=(avl_write_sr OR avl_write_pulse) AND NOT avl_write_clr; - avl_read_sr <=(avl_read_sr OR avl_read_pulse) AND NOT avl_read_clr; + avl_read_sr <=(avl_read_sr OR avl_read_pulse) AND NOT avl_read_clr; avl_write_clr<='0'; avl_read_clr <='0'; @@ -1401,9 +1507,6 @@ BEGIN -------------------------------------------- CASE avl_state IS WHEN sIDLE => - IF avl_o_vs='0' AND avl_o_vs_sync='1' THEN - avl_wad<=0; - END IF; IF avl_write_sr='1' THEN avl_state<=sWRITE; avl_write_clr<='1'; @@ -1412,27 +1515,22 @@ BEGIN ELSE avl_rad<=BLEN; END IF; - ELSIF avl_read_sr='1' AND avl_reading='0' THEN - IF avl_rbib='0' THEN - avl_wad<=2*BLEN-1; + IF avl_wline='0' THEN + avl_address<=std_logic_vector( + avl_wadrs(N_AW+NB_LA-1 DOWNTO NB_LA) + + avl_i_offset0(N_AW+NB_LA-1 DOWNTO NB_LA)); ELSE - avl_wad<=BLEN-1; + avl_address<=std_logic_vector( + avl_wadrs(N_AW+NB_LA-1 DOWNTO NB_LA) + + avl_i_offset1(N_AW+NB_LA-1 DOWNTO NB_LA)); END IF; + + ELSIF avl_read_sr='1' THEN avl_state<=sREAD; avl_read_clr<='1'; END IF; WHEN sWRITE => - IF avl_wline='0' THEN - avl_address<=std_logic_vector(RAMBASE(N_AW+NB_LA-1 DOWNTO NB_LA) + - avl_wadrs(N_AW+NB_LA-1 DOWNTO NB_LA) + - avl_i_offset0(N_AW+NB_LA-1 DOWNTO NB_LA)); - ELSE - avl_address<=std_logic_vector(RAMBASE(N_AW+NB_LA-1 DOWNTO NB_LA) + - avl_wadrs(N_AW+NB_LA-1 DOWNTO NB_LA) + - avl_i_offset1(N_AW+NB_LA-1 DOWNTO NB_LA)); - END IF; - avl_write_i<='1'; IF avl_write_i='1' AND avl_waitrequest='0' THEN IF (avl_rad MOD BLEN)=BLEN-1 THEN @@ -1443,19 +1541,19 @@ BEGIN WHEN sREAD => IF avl_rline='0' THEN - avl_address<=std_logic_vector(RAMBASE(N_AW+NB_LA-1 DOWNTO NB_LA) + + avl_address<=std_logic_vector( avl_radrs(N_AW+NB_LA-1 DOWNTO NB_LA) + avl_o_offset0(N_AW+NB_LA-1 DOWNTO NB_LA)); ELSE - avl_address<=std_logic_vector(RAMBASE(N_AW+NB_LA-1 DOWNTO NB_LA) + + avl_address<=std_logic_vector( avl_radrs(N_AW+NB_LA-1 DOWNTO NB_LA) + avl_o_offset1(N_AW+NB_LA-1 DOWNTO NB_LA)); END IF; avl_read_i<='1'; - avl_reading<='1'; IF avl_read_i='1' AND avl_waitrequest='0' THEN avl_state<=sIDLE; avl_read_i<='0'; + avl_readack<=NOT avl_readack; END IF; END CASE; @@ -1466,10 +1564,13 @@ BEGIN avl_wr<='1'; avl_wad<=(avl_wad+1) MOD (2*BLEN); IF (avl_wad MOD BLEN)=BLEN-2 THEN - avl_reading<='0'; - avl_readack<=NOT avl_readack; + avl_readdataack<=NOT avl_readdataack; END IF; END IF; + + IF avl_o_vs_sync='0' AND avl_o_vs='1' THEN + avl_wad<=2*BLEN-1; + END IF; -------------------------------------------- END IF; @@ -1539,6 +1640,7 @@ BEGIN VARIABLE lev_inc_v,lev_dec_v : std_logic; VARIABLE prim_v,last_v,bib_v : std_logic; VARIABLE shift_v : unsigned(0 TO N_DW+15); + VARIABLE hpix_v : type_pix; VARIABLE hcarry_v,vcarry_v : boolean; VARIABLE dif_v : natural RANGE 0 TO 8*OHRES-1; BEGIN @@ -1553,6 +1655,8 @@ BEGIN ELSIF rising_edge(o_clk) THEN ------------------------------------------------------ o_mode <=mode; -- ? + o_format <="0001" & format; -- ? + o_run <=run; -- ? o_htotal <=htotal; -- ? @@ -1561,7 +1665,7 @@ BEGIN o_hdisp <=hdisp; -- ? o_hmin <=hmin; -- ? o_hmax <=hmax; -- ? - + o_vtotal <=vtotal; -- ? o_vsstart<=vsstart; -- ? o_vsend <=vsend; -- ? @@ -1593,12 +1697,21 @@ BEGIN IF o_vsv(1)='1' AND o_vsv(0)='0' AND o_bufup1='1' THEN o_obuf1<=buf_next(o_obuf1,o_ibuf1); o_bufup1<='0'; - o_hburst <=i_hburst; -- Bursts per line o_ihsize<=i_hrsize; -- o_ivsize<=i_vrsize; -- o_hdown<=i_hdown; -- o_vdown<=i_vdown; -- END IF; + -- Framebuffer mode. + IF o_fb_ena='1' THEN + o_ihsize<=o_fb_hsize; + o_ivsize<=o_fb_vsize; + o_format<=o_fb_format; + END IF; + + o_hburst<=(o_ihsize * (to_integer(o_format(2 DOWNTO 0)) - 2) + + N_BURST - 1) / N_BURST; + IF o_vsv(1)='1' AND o_vsv(0)='0' AND o_bufup0='1' THEN o_obuf0<=buf_next(o_obuf0,o_ibuf0); o_bufup0<='0'; @@ -1636,18 +1749,22 @@ BEGIN o_readack_sync2<=o_readack_sync; o_readack<=o_readack_sync XOR o_readack_sync2; + o_readdataack_sync<=avl_readdataack; -- + o_readdataack_sync2<=o_readdataack_sync; + o_readdataack<=o_readdataack_sync XOR o_readdataack_sync2; + ------------------------------------------------------ lev_inc_v:='0'; lev_dec_v:='0'; -- acpt : Pixel position within current data word -- dcpt : Destination image position - -- hpos : Source image position, fixed point 12.12 -- Force preload 2 lines at top of screen IF o_hsv(0)='1' AND o_hsv(1)='0' THEN IF o_vcpt_pre3=o_vmin THEN o_fload<=2; + o_bibu<='0'; END IF; o_hsp<='1'; END IF; @@ -1659,6 +1776,9 @@ BEGIN o_vacc_ini<=(o_vsize - o_ivsize + 8192) MOD 8192; o_hacc_ini<=(o_hsize + o_ihsize + 8192) MOD 8192; + --o_vacc_ini<=o_ivsize; + --o_hacc_ini<=(2*o_hsize - o_ihsize + 8192) MOD 8192; + CASE o_state IS -------------------------------------------------- WHEN sDISP => @@ -1708,7 +1828,6 @@ BEGIN prim_v:=to_std_logic(o_hbcpt=0); last_v:=to_std_logic(o_hbcpt=o_hburst-1); bib_v :=o_bibu; - o_bib <=o_bibu; o_adrsa<='1'; WHEN sWAITREAD => @@ -1733,28 +1852,15 @@ BEGIN o_adrs_pre<=to_integer(o_vacpt) * o_hburst; o_rline<=o_vacpt(0); -- Even/Odd line for interlaced video IF o_adrsa='1' THEN - IF HEADER THEN - IF o_fload=2 THEN - o_adrs<=to_unsigned((o_hbcpt + 1) * N_BURST,32); - o_alt<="1111"; - ELSIF o_fload=1 THEN - o_adrs<=to_unsigned((o_hburst + o_hbcpt + 1) * N_BURST,32); - o_alt<="0100"; - ELSE - o_adrs<=to_unsigned((o_adrs_pre + o_hbcpt + 1) * N_BURST,32); - o_alt<=altx(o_vacpt(1 DOWNTO 0) + 1); - END IF; + IF o_fload=2 THEN + o_adrs<=to_unsigned(o_hbcpt * N_BURST,32); + o_alt<="1111"; + ELSIF o_fload=1 THEN + o_adrs<=to_unsigned((o_hburst + o_hbcpt) * N_BURST,32); + o_alt<="0100"; ELSE - IF o_fload=2 THEN - o_adrs<=to_unsigned(o_hbcpt * N_BURST,32); - o_alt<="1111"; - ELSIF o_fload=1 THEN - o_adrs<=to_unsigned((o_hburst + o_hbcpt) * N_BURST,32); - o_alt<="0100"; - ELSE - o_adrs<=to_unsigned((o_adrs_pre + o_hbcpt) * N_BURST,32); - o_alt<=altx(o_vacpt(1 DOWNTO 0) + 1); - END IF; + o_adrs<=to_unsigned((o_adrs_pre + o_hbcpt) * N_BURST,32); + o_alt<=altx(o_vacpt(1 DOWNTO 0) + 1); END IF; END IF; @@ -1765,12 +1871,12 @@ BEGIN o_copyv(0)<='0'; IF o_copylev>0 AND o_copyv(0)='0' THEN o_copy<='1'; + o_altx<=o_alt; END IF; o_adturn<='0'; IF o_primv(0)='1' THEN -- First memcopy of a horizontal line, carriage return ! - -- HPOS starts at 1 for the first input image pix,to keep it positive o_hacc <=o_hacc_ini; o_hacc_next<=o_hacc_ini + 2*o_ihsize; o_hacpt <=x"000"; @@ -1786,6 +1892,7 @@ BEGIN ELSE o_ad<=BLEN; END IF; + ELSE -- dshi : Force shift first two or three pixels of each line IF o_dshi=0 THEN @@ -1820,11 +1927,11 @@ BEGIN o_last1<=o_last; o_last2<=o_last1; - IF shift24_onext(o_acpt) THEN + IF shift_onext(o_acpt,o_format) THEN o_ad<=(o_ad+1) MOD (2*BLEN); END IF; - IF o_adturn='1' AND (shift24_onext((o_acpt+1) MOD 16)) AND + IF o_adturn='1' AND (shift_onext((o_acpt+1) MOD 16,o_format)) AND (((o_ad MOD BLEN=0) AND o_lastv(0)='0') OR o_last2='1') THEN o_copy<='0'; lev_dec_v:='1'; @@ -1838,23 +1945,35 @@ BEGIN o_acpt1<=o_acpt; o_acpt2<=o_acpt1; o_acpt3<=o_acpt2; o_acpt4<=o_acpt3; o_ad1<=o_ad; o_ad2<=o_ad1; o_ad3<=o_ad2; - o_sh1<=o_sh; o_sh2<=o_sh1; o_sh3<=o_sh2; + o_sh1<=o_sh; o_sh2<=o_sh1; o_sh3<=o_sh2; o_sh4<=o_sh3; o_lastt1<=o_last; o_lastt2<=o_lastt1; o_lastt3<=o_lastt2; ------------------------------------------------------ IF o_sh3='1' THEN - shift_v:=shift24_opack(o_acpt4,o_shift,o_dr); + shift_v:=shift_opack(o_acpt4,o_shift,o_dr,o_format); o_shift<=shift_v; - - o_hpix0<=(r=>shift_v(0 TO 7),g=>shift_v(8 TO 15),b=>shift_v(16 TO 23)); + o_hpixs<=shift_opix(shift_v,o_format); + END IF; + + IF o_sh4='1' THEN + hpix_v:=o_hpixs; + IF o_format(4)='1' THEN -- Swap B <-> R + hpix_v:=(r=>o_hpixs.b,g=>o_hpixs.g,b=>o_hpixs.r); + END IF; + IF o_format(2 DOWNTO 0)="011" THEN + -- 8bpp indexed colour mode + hpix_v:=(r=>o_fb_pal_dr(23 DOWNTO 16),g=>o_fb_pal_dr(15 DOWNTO 8), + b=>o_fb_pal_dr(7 DOWNTO 0)); + END IF; + o_hpix0<=hpix_v; o_hpix1<=o_hpix0; o_hpix2<=o_hpix1; o_hpix3<=o_hpix2; IF o_first='1' THEN -- Left edge. Duplicate first pixel - o_hpix1<=(r=>shift_v(0 TO 7),g=>shift_v(8 TO 15),b=>shift_v(16 TO 23)); - o_hpix2<=(r=>shift_v(0 TO 7),g=>shift_v(8 TO 15),b=>shift_v(16 TO 23)); + o_hpix1<=hpix_v; + o_hpix2<=hpix_v; o_first<='0'; END IF; IF o_lastt3='1' THEN @@ -1864,17 +1983,19 @@ BEGIN END IF; ------------------------------------------------------ + -- lev_inc : read start + -- lev_dec : end of copy -- READLEV : Number of ongoing Avalon Reads - IF lev_dec_v='1' AND lev_inc_v='0' THEN - o_readlev<=o_readlev-1; - ELSIF lev_dec_v='0' AND lev_inc_v='1' THEN + IF lev_dec_v='0' AND lev_inc_v='1' THEN o_readlev<=o_readlev+1; + ELSIF lev_dec_v='1' AND lev_inc_v='0' THEN + o_readlev<=o_readlev-1; END IF; -- COPYLEV : Number of ongoing copies to line buffers - IF lev_dec_v='1' AND o_readack='0' THEN + IF lev_dec_v='1' AND o_readdataack='0' THEN o_copylev<=o_copylev-1; - ELSIF lev_dec_v='0' AND o_readack='1' THEN + ELSIF lev_dec_v='0' AND o_readdataack='1' THEN o_copylev<=o_copylev+1; END IF; @@ -1905,12 +2026,33 @@ BEGIN END IF; END PROCESS Scalaire; - o_h_poly_a<=to_integer(o_hfrac(11 DOWNTO 12-FRAC)); + o_h_poly_a<=to_integer(o_hfrac1(11 DOWNTO 12-FRAC)); o_v_poly_a<=to_integer(o_vfrac(11 DOWNTO 12-FRAC)); o_h_poly_dr<=o_h_poly(o_h_poly_a) WHEN rising_edge(o_clk); o_v_poly_dr<=o_v_poly(o_v_poly_a) WHEN rising_edge(o_clk); + -- Framebuffer palette + GenPal:IF PALETTE GENERATE + Tempera:PROCESS(pal_clk) IS + BEGIN + IF rising_edge(pal_clk) THEN + IF pal_wr='1' THEN + pal_mem(to_integer(pal_a))<=pal_dw; + END IF; + pal_dr<=pal_mem(to_integer(pal_a)); + END IF; + END PROCESS; + + o_fb_pal_dr<= + pal_mem(to_integer(shift_opack(o_acpt4,o_shift,o_dr,o_format)(0 TO 7))) + WHEN rising_edge(o_clk); + END GENERATE GenPal; + + GenNoPal:IF NOT PALETTE GENERATE + o_fb_pal_dr<=x"000000"; + END GENERATE GenNoPal; + ----------------------------------------------------------------------------- -- Polyphase ROMs Polikarpov:PROCESS(poly_clk) IS @@ -1997,38 +2139,38 @@ BEGIN ----------------------------------- o_hfrac<=dir_v; - o_hfrac1<=o_hfrac; o_hfrac2<=o_hfrac1; o_hfrac3<=o_hfrac2; + o_hfrac1<=o_hfrac; o_hfrac2<=o_hfrac1; + o_hfrac3<=o_hfrac2; o_hfrac4<=o_hfrac3; - o_copyv(1 TO 7)<=o_copyv(0 TO 6); + o_copyv(1 TO 8)<=o_copyv(0 TO 7); - o_dcpt1<=o_dcpt; - IF o_dcpt1>o_hsize THEN + o_dcptv(1)<=o_dcpt; + IF o_dcptv(1)>o_hsize THEN o_copyv(2)<='0'; END IF; - o_dcpt2<=o_dcpt1 MOD OHRES; - o_dcpt3<=o_dcpt2; o_dcpt4<=o_dcpt3; o_dcpt5<=o_dcpt4; - o_dcpt6<=o_dcpt5; o_dcpt7<=o_dcpt6; + o_dcptv(2)<=o_dcptv(1) MOD OHRES; + o_dcptv(3 TO 8)<=o_dcptv(2 TO 7); o_hpixq<=(o_hpix3,o_hpix2,o_hpix1,o_hpix0); -- NEAREST / BILINEAR / SHARP BILINEAR --------------- -- C1 : Pre-calc Sharp Bilinear - o_h_sbil_t<=sbil_frac1(o_hfrac); + o_h_sbil_t<=sbil_frac1(o_hfrac1); -- C2 : Select o_h_frac2<=(OTHERS =>'0'); CASE o_hmode(1 DOWNTO 0) IS WHEN "00" => -- Nearest IF MASK(MASK_NEAREST)='1' THEN - o_h_frac2<=near_frac(o_hfrac1); + o_h_frac2<=near_frac(o_hfrac2); END IF; WHEN "01" => -- Bilinear IF MASK(MASK_BILINEAR)='1' THEN - o_h_frac2<=bil_frac(o_hfrac1); + o_h_frac2<=bil_frac(o_hfrac2); END IF; WHEN "10" => -- Sharp Bilinear IF MASK(MASK_SHARP_BILINEAR)='1' THEN - o_h_frac2<=sbil_frac2(o_hfrac1,o_h_sbil_t); + o_h_frac2<=sbil_frac2(o_hfrac2,o_h_sbil_t); END IF; WHEN OTHERS => NULL; @@ -2046,16 +2188,16 @@ BEGIN -- C1 : Bicubic coefficients A,B,C,D -- C2 : Bicubic calc T1 = X.D + C - o_h_bic_abcd1<=bic_calc0(o_hfrac1,(o_hpix3,o_hpix2,o_hpix1,o_hpix0)); - o_h_bic_tt1<=bic_calc1(o_hfrac1, - bic_calc0(o_hfrac1,(o_hpix3,o_hpix2,o_hpix1,o_hpix0))); + o_h_bic_abcd1<=bic_calc0(o_hfrac2,(o_hpix3,o_hpix2,o_hpix1,o_hpix0)); + o_h_bic_tt1<=bic_calc1(o_hfrac2, + bic_calc0(o_hfrac2,(o_hpix3,o_hpix2,o_hpix1,o_hpix0))); -- C3 : Bicubic calc T2 = X.T1 + B o_h_bic_abcd2<=o_h_bic_abcd1; - o_h_bic_tt2<=bic_calc2(o_hfrac2,o_h_bic_tt1,o_h_bic_abcd1); + o_h_bic_tt2<=bic_calc2(o_hfrac3,o_h_bic_tt1,o_h_bic_abcd1); -- C4 : Bicubic final Y = X.T2 + A - o_h_bic_pix<=bic_calc3(o_hfrac3,o_h_bic_tt2,o_h_bic_abcd2); + o_h_bic_pix<=bic_calc3(o_hfrac4,o_h_bic_tt2,o_h_bic_abcd2); -- POLYPHASE ----------------------------------------- -- C1 : Read memory @@ -2070,8 +2212,8 @@ BEGIN o_h_poly_pix<=poly_calc2(o_h_poly_t); -- C5 : Select interpoler ---------------------------- - o_wadl<=o_dcpt7; - o_wr<=o_alt AND (o_copyv(7) & o_copyv(7) & o_copyv(7) & o_copyv(7)); + o_wadl<=o_dcptv(8); + o_wr<=o_altx AND (o_copyv(8) & o_copyv(8) & o_copyv(8) & o_copyv(8)); o_ldw<=(x"00",x"00",x"00"); CASE o_hmode(2 DOWNTO 0) IS @@ -2142,12 +2284,11 @@ BEGIN (o_vcpt>o_vsstart AND o_vcpt=o_vmin AND o_vcpt_pre2<=o_vmax); o_hsv(1 TO 5)<=o_hsv(0 TO 4); o_vsv(1 TO 5)<=o_vsv(0 TO 4); o_dev(1 TO 5)<=o_dev(0 TO 4); o_pev(1 TO 5)<=o_pev(0 TO 4); - IF o_run='0' THEN o_hsv(2)<='0'; @@ -2282,9 +2423,9 @@ BEGIN END CASE; IF o_pev(5)='0' THEN - o_r<=x"00"; -- Border colour - o_g<=x"00"; - o_b<=x"00"; + o_r<=o_border(23 DOWNTO 16); -- Copy border colour + o_g<=o_border(15 DOWNTO 8); + o_b<=o_border(7 DOWNTO 0); END IF; ---------------------------------------------------- @@ -2295,14 +2436,12 @@ BEGIN ----------------------------------------------------------------------------- -- Low Lag syntoniser interface - -- i_syncline falling edge shall be aligned with o_vss raising edge. - - o_lltune<=(0 => NOT i_syncline, - 1 => '0', + o_lltune<=(0 => i_vss, + 1 => i_pde, 2 => i_inter, 3 => i_flm, 4 => o_vss, - 5 => '0', + 5 => i_pce, 6 => i_clk, 7 => o_clk, OTHERS =>'0'); diff --git a/sys/fbpal.sv b/sys/fbpal.sv new file mode 100644 index 0000000..30a7512 --- /dev/null +++ b/sys/fbpal.sv @@ -0,0 +1,86 @@ +//============================================================================ +// +// Framebuffer Palette support for MiSTer +// (c)2019 Sorgelig +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +//============================================================================ + +module fbpal +( + input reset, + + input en_in, + output reg en_out, + + input ram_clk, + output reg [28:0] ram_address, + output reg [7:0] ram_burstcount, + input ram_waitrequest, + input [63:0] ram_readdata, + input ram_readdatavalid, + output reg ram_read, + + input [31:0] fb_address, + + input pal_en, + output reg [7:0] pal_a, + output reg [23:0] pal_d, + output reg pal_wr +); + +reg [31:0] base_addr; +always @(posedge ram_clk) base_addr <= fb_address - 4096; + +reg [6:0] buf_rptr = 0; +always @(posedge ram_clk) begin + reg [23:0] odd_d; + + if(~pal_a[0] & pal_wr) {pal_a[0], pal_d} <= {1'b1, odd_d}; + else pal_wr <= 0; + + if(~ram_waitrequest) ram_read <= 0; + + if(pal_en & ~reset) begin + if(ram_burstcount) begin + if(ram_readdatavalid) begin + ram_burstcount <= 0; + + odd_d <= ram_readdata[55:32]; + pal_d <= ram_readdata[23:0]; + pal_a <= {buf_rptr, 1'b0}; + pal_wr <= 1; + + en_out <= en_in; + buf_rptr <= buf_rptr + 1'd1; + end + end + else begin + if(~ram_waitrequest && en_out != en_in) begin + ram_address <= base_addr[31:3] + buf_rptr; + ram_burstcount <= 1; + ram_read <= 1; + end + end + end + else begin + en_out <= en_in; + buf_rptr <= 0; + ram_burstcount <= 0; + end +end + +endmodule diff --git a/sys/hdmi_config.sv b/sys/hdmi_config.sv index 476d72d..8cbad8b 100644 --- a/sys/hdmi_config.sv +++ b/sys/hdmi_config.sv @@ -1,202 +1,235 @@ - -module hdmi_config -( - // Host Side - input iCLK, - input iRST_N, - - input dvi_mode, - input audio_96k, - - // I2C Side - output I2C_SCL, - inout I2C_SDA -); - -// Internal Registers/Wires -reg mI2C_GO = 0; -wire mI2C_END; -wire mI2C_ACK; -reg [15:0] LUT_DATA; -reg [7:0] LUT_INDEX = 0; - -i2c #(50_000_000, 20_000) i2c_av -( - .CLK(iCLK), - - .I2C_SCL(I2C_SCL), // I2C CLOCK - .I2C_SDA(I2C_SDA), // I2C DATA - - .I2C_DATA({8'h72,init_data[LUT_INDEX]}), // DATA:[SLAVE_ADDR,SUB_ADDR,DATA]. 0x72 is the Slave Address of the ADV7513 chip! - .START(mI2C_GO), // START transfer - .END(mI2C_END), // END transfer - .ACK(mI2C_ACK) // ACK -); - -////////////////////// Config Control //////////////////////////// -always@(posedge iCLK or negedge iRST_N) begin - reg [1:0] mSetup_ST = 0; - - if(!iRST_N) begin - LUT_INDEX <= 0; - mSetup_ST <= 0; - mI2C_GO <= 0; - end else begin - if(init_data[LUT_INDEX] != 16'hFFFF) begin - case(mSetup_ST) - 0: begin - mI2C_GO <= 1; - mSetup_ST <= 1; - end - 1: if(~mI2C_END) mSetup_ST <= 2; - 2: begin - mI2C_GO <= 0; - if(mI2C_END) begin - mSetup_ST <= 0; - if(!mI2C_ACK) LUT_INDEX <= LUT_INDEX + 8'd1; - end - end - endcase - end - end -end - -//////////////////////////////////////////////////////////////////// -///////////////////// Config Data LUT ////////////////////////// - -wire [15:0] init_data[58] = -'{ - 16'h9803, // ADI required Write. - - {8'hD6, 8'b1100_0000}, // [7:6] HPD Control... - // 00 = HPD is from both HPD pin or CDC HPD - // 01 = HPD is from CDC HPD - // 10 = HPD is from HPD pin - // 11 = HPD is always high - - 16'h4110, // Power Down control - 16'h9A70, // ADI required Write. - 16'h9C30, // ADI required Write. - {8'h9D, 8'b0110_0001}, // [7:4] must be b0110!. - // [3:2] b00 = Input clock not divided. b01 = Clk divided by 2. b10 = Clk divided by 4. b11 = invalid! - // [1:0] must be b01! - 16'hA2A4, // ADI required Write. - 16'hA3A4, // ADI required Write. - 16'hE0D0, // ADI required Write. - - - 16'h35_40, - 16'h36_D9, - 16'h37_0A, - 16'h38_00, - 16'h39_2D, - 16'h3A_00, - - {8'h16, 8'b0011_1000}, // Output Format 444 [7]=0. - // [6] must be 0! - // Colour Depth for Input Video data [5:4] b11 = 8-bit. - // Input Style [3:2] b10 = Style 1 (ignored when using 444 input). - // DDR Input Edge falling [1]=0 (not using DDR atm). - // Output Colour Space RGB [0]=0. - - {8'h17, 8'b01100010}, // Aspect ratio 16:9 [1]=1, 4:3 [1]=0 - - {8'h18, 8'b0100_0110}, // CSC disabled [7]=0. - // CSC Scaling Factor [6:5] b10 = +/- 4.0, -16384 - 16380. - // CSC Equation 3 [4:0] b00110. - - - {8'h3B, 8'b0000_0000}, // Pixel repetition [6:5] b00 AUTO. [4:3] b00 x1 mult of input clock. [2:1] b00 x1 pixel rep to send to HDMI Rx. - - 16'h4000, // General Control Packet Enable - - {8'h48, 8'b0000_1000}, // [6]=0 Normal bus order! - // [5] DDR Alignment. - // [4:3] b01 Data right justified (for YCbCr 422 input modes). - - 16'h49A8, // ADI required Write. - 16'h4C00, // ADI required Write. - - {8'h55, 8'b0001_0000}, // [7] must be 0!. Set RGB444 in AVinfo Frame [6:5], Set active format [4]. - // AVI InfoFrame Valid [4]. - // Bar Info [3:2] b00 Bars invalid. b01 Bars vertical. b10 Bars horizontal. b11 Bars both. - // Scan Info [1:0] b00 (No data). b01 TV. b10 PC. b11 None. - - 16'h7301, - - {8'h94, 8'b1000_0000}, // [7]=1 HPD Interrupt ENabled. - - 16'h9902, // ADI required Write. - 16'h9B18, // ADI required Write. - - 16'h9F00, // ADI required Write. - - {8'hA1, 8'b0000_0000}, // [6]=1 Monitor Sense Power Down DISabled. - - 16'hA408, // ADI required Write. - 16'hA504, // ADI required Write. - 16'hA600, // ADI required Write. - 16'hA700, // ADI required Write. - 16'hA800, // ADI required Write. - 16'hA900, // ADI required Write. - 16'hAA00, // ADI required Write. - 16'hAB40, // ADI required Write. - - {8'hAF, 6'b0000_01,~dvi_mode,1'b0}, // [7]=0 HDCP Disabled. - // [6:5] must be b00! - // [4]=0 Current frame is unencrypted - // [3:2] must be b01! - // [1]=1 HDMI Mode. - // [0] must be b0! - - 16'hB900, // ADI required Write. - - {8'hBA, 8'b0110_0000}, // [7:5] Input Clock delay... - // b000 = -1.2ns. - // b001 = -0.8ns. - // b010 = -0.4ns. - // b011 = No delay. - // b100 = 0.4ns. - // b101 = 0.8ns. - // b110 = 1.2ns. - // b111 = 1.6ns. - - 16'hBB00, // ADI required Write. - - 16'hDE9C, // ADI required Write. - 16'hE460, // ADI required Write. - 16'hFA7D, // Nbr of times to search for good phase - - - // (Audio stuff on Programming Guide, Page 66)... - - {8'h0A, 8'b0000_0000}, // [6:4] Audio Select. b000 = I2S. - // [3:2] Audio Mode. (HBR stuff, leave at 00!). - - {8'h0B, 8'b0000_1110}, // - - {8'h0C, 8'b0000_0100}, // [7] 0 = Use sampling rate from I2S stream. 1 = Use samp rate from I2C Register. - // [6] 0 = Use Channel Status bits from stream. 1 = Use Channel Status bits from I2C register. - // [2] 1 = I2S0 Enable. - // [1:0] I2S Format: 00 = Standard. 01 = Right Justified. 10 = Left Justified. 11 = AES. - - {8'h0D, 8'b0001_0000}, // [4:0] I2S Bit (Word) Width for Right-Justified. - {8'h14, 8'b0000_0010}, // [3:0] Audio Word Length. b0010 = 16 bits. - {8'h15, audio_96k, 7'b010_0000}, // I2S Sampling Rate [7:4]. b0000 = (44.1KHz). b0010 = 48KHz. - // Input ID [3:1] b000 (0) = 24-bit RGB 444 or YCrCb 444 with Separate Syncs. - - // Audio Clock Config - 16'h0100, // - audio_96k ? 16'h0230 : 16'h0218, // Set N Value 12288/6144 - 16'h0300, // - - 16'h0701, // - 16'h0822, // Set CTS Value 74250 - 16'h090A, // - - 16'hFFFF // END -}; - -//////////////////////////////////////////////////////////////////// - + +module hdmi_config +( + // Host Side + input iCLK, + input iRST_N, + + input dvi_mode, + input audio_96k, + input hdmi_limited, + output reg done, + + // I2C Side + output I2C_SCL, + inout I2C_SDA +); + +// Internal Registers/Wires +reg mI2C_GO = 0; +wire mI2C_END; +wire mI2C_ACK; +reg [15:0] LUT_DATA; +reg [7:0] LUT_INDEX = 0; + +i2c #(50_000_000, 20_000) i2c_av +( + .CLK(iCLK), + + .I2C_SCL(I2C_SCL), // I2C CLOCK + .I2C_SDA(I2C_SDA), // I2C DATA + + .I2C_DATA({8'h72,init_data[LUT_INDEX]}), // DATA:[SLAVE_ADDR,SUB_ADDR,DATA]. 0x72 is the Slave Address of the ADV7513 chip! + .START(mI2C_GO), // START transfer + .END(mI2C_END), // END transfer + .ACK(mI2C_ACK) // ACK +); + +////////////////////// Config Control //////////////////////////// +always@(posedge iCLK or negedge iRST_N) begin + reg [1:0] mSetup_ST = 0; + + if(!iRST_N) begin + LUT_INDEX <= 0; + mSetup_ST <= 0; + mI2C_GO <= 0; + done <= 0; + end else begin + if(init_data[LUT_INDEX] != 16'hFFFF) begin + case(mSetup_ST) + 0: begin + mI2C_GO <= 1; + mSetup_ST <= 1; + end + 1: if(~mI2C_END) mSetup_ST <= 2; + 2: begin + mI2C_GO <= 0; + if(mI2C_END) begin + mSetup_ST <= 0; + if(!mI2C_ACK) LUT_INDEX <= LUT_INDEX + 8'd1; + end + end + endcase + end + else done <= 1; + end +end + +//////////////////////////////////////////////////////////////////// +///////////////////// Config Data LUT ////////////////////////// + +wire [15:0] init_data[82] = +'{ + 16'h9803, // ADI required Write. + + {8'hD6, 8'b1100_0000}, // [7:6] HPD Control... + // 00 = HPD is from both HPD pin or CDC HPD + // 01 = HPD is from CDC HPD + // 10 = HPD is from HPD pin + // 11 = HPD is always high + + 16'h4110, // Power Down control + 16'h9A70, // ADI required Write. + 16'h9C30, // ADI required Write. + {8'h9D, 8'b0110_0001}, // [7:4] must be b0110!. + // [3:2] b00 = Input clock not divided. b01 = Clk divided by 2. b10 = Clk divided by 4. b11 = invalid! + // [1:0] must be b01! + 16'hA2A4, // ADI required Write. + 16'hA3A4, // ADI required Write. + 16'hE0D0, // ADI required Write. + + + 16'h35_40, + 16'h36_D9, + 16'h37_0A, + 16'h38_00, + 16'h39_2D, + 16'h3A_00, + + {8'h16, 8'b0011_1000}, // Output Format 444 [7]=0. + // [6] must be 0! + // Colour Depth for Input Video data [5:4] b11 = 8-bit. + // Input Style [3:2] b10 = Style 1 (ignored when using 444 input). + // DDR Input Edge falling [1]=0 (not using DDR atm). + // Output Colour Space RGB [0]=0. + + {8'h17, 8'b01100010}, // Aspect ratio 16:9 [1]=1, 4:3 [1]=0 + + {8'h18, hdmi_limited, // CSC enable [7]. 0 - Off. 1 - On. + 7'h0D}, // CSC Scaling Factors and Coefficients for RGB Full->Limited. + {8'h19, 8'hBC}, // Taken from table in ADV7513 Programming Guide. + {8'h1A, 8'h00}, // CSC Channel A. + {8'h1B, 8'h00}, + {8'h1C, 8'h00}, + {8'h1D, 8'h00}, + {8'h1E, 8'h01}, + {8'h1F, 8'h00}, + + {8'h20, 8'h00}, // CSC Channel B. + {8'h21, 8'h00}, + {8'h22, 8'h0D}, + {8'h23, 8'hBC}, + {8'h24, 8'h00}, + {8'h25, 8'h00}, + {8'h26, 8'h01}, + {8'h27, 8'h00}, + + {8'h28, 8'h00}, // CSC Channel C. + {8'h29, 8'h00}, + {8'h2A, 8'h00}, + {8'h2B, 8'h00}, + {8'h2C, 8'h0D}, + {8'h2D, 8'hBC}, + {8'h2E, 8'h01}, + {8'h2F, 8'h00}, + + + {8'h3B, 8'b0000_0000}, // Pixel repetition [6:5] b00 AUTO. [4:3] b00 x1 mult of input clock. [2:1] b00 x1 pixel rep to send to HDMI Rx. + + 16'h4000, // General Control Packet Enable + + {8'h48, 8'b0000_1000}, // [6]=0 Normal bus order! + // [5] DDR Alignment. + // [4:3] b01 Data right justified (for YCbCr 422 input modes). + + 16'h49A8, // ADI required Write. + 16'h4C00, // ADI required Write. + + {8'h55, 8'b0001_0000}, // [7] must be 0!. Set RGB444 in AVinfo Frame [6:5], Set active format [4]. + // AVI InfoFrame Valid [4]. + // Bar Info [3:2] b00 Bars invalid. b01 Bars vertical. b10 Bars horizontal. b11 Bars both. + // Scan Info [1:0] b00 (No data). b01 TV. b10 PC. b11 None. + + {8'h57, 1'b0, // [7] IT Content. 0 - No. 1 - Yes (type set in register h59). + 3'b000, // [6:4] Color space (ignored for RGB) + hdmi_limited ? 2'b01 : 2'b10, // [3:2] RGB Quantization range + 2'b00}, // [1:0] Non-Uniform Scaled: 00 - None. 01 - Horiz. 10 - Vert. 11 - Both. + + 16'h7301, + + {8'h94, 8'b1000_0000}, // [7]=1 HPD Interrupt ENabled. + + 16'h9902, // ADI required Write. + 16'h9B18, // ADI required Write. + + 16'h9F00, // ADI required Write. + + {8'hA1, 8'b0000_0000}, // [6]=1 Monitor Sense Power Down DISabled. + + 16'hA408, // ADI required Write. + 16'hA504, // ADI required Write. + 16'hA600, // ADI required Write. + 16'hA700, // ADI required Write. + 16'hA800, // ADI required Write. + 16'hA900, // ADI required Write. + 16'hAA00, // ADI required Write. + 16'hAB40, // ADI required Write. + + {8'hAF, 6'b0000_01,~dvi_mode,1'b0}, // [7]=0 HDCP Disabled. + // [6:5] must be b00! + // [4]=0 Current frame is unencrypted + // [3:2] must be b01! + // [1]=1 HDMI Mode. + // [0] must be b0! + + 16'hB900, // ADI required Write. + + {8'hBA, 8'b0110_0000}, // [7:5] Input Clock delay... + // b000 = -1.2ns. + // b001 = -0.8ns. + // b010 = -0.4ns. + // b011 = No delay. + // b100 = 0.4ns. + // b101 = 0.8ns. + // b110 = 1.2ns. + // b111 = 1.6ns. + + 16'hBB00, // ADI required Write. + + 16'hDE9C, // ADI required Write. + 16'hE460, // ADI required Write. + 16'hFA7D, // Nbr of times to search for good phase + + + // (Audio stuff on Programming Guide, Page 66)... + + {8'h0A, 8'b0000_0000}, // [6:4] Audio Select. b000 = I2S. + // [3:2] Audio Mode. (HBR stuff, leave at 00!). + + {8'h0B, 8'b0000_1110}, // + + {8'h0C, 8'b0000_0100}, // [7] 0 = Use sampling rate from I2S stream. 1 = Use samp rate from I2C Register. + // [6] 0 = Use Channel Status bits from stream. 1 = Use Channel Status bits from I2C register. + // [2] 1 = I2S0 Enable. + // [1:0] I2S Format: 00 = Standard. 01 = Right Justified. 10 = Left Justified. 11 = AES. + + {8'h0D, 8'b0001_0000}, // [4:0] I2S Bit (Word) Width for Right-Justified. + {8'h14, 8'b0000_0010}, // [3:0] Audio Word Length. b0010 = 16 bits. + {8'h15, audio_96k, 7'b010_0000}, // I2S Sampling Rate [7:4]. b0000 = (44.1KHz). b0010 = 48KHz. + // Input ID [3:1] b000 (0) = 24-bit RGB 444 or YCrCb 444 with Separate Syncs. + + // Audio Clock Config + 16'h0100, // + audio_96k ? 16'h0230 : 16'h0218, // Set N Value 12288/6144 + 16'h0300, // + + 16'h0701, // + 16'h0822, // Set CTS Value 74250 + 16'h090A, // + + 16'hFFFF // END +}; + +//////////////////////////////////////////////////////////////////// + endmodule \ No newline at end of file diff --git a/sys/hps_io.v b/sys/hps_io.v index 1003bbd..013ac75 100644 --- a/sys/hps_io.v +++ b/sys/hps_io.v @@ -30,20 +30,20 @@ // WIDE=1 for 16 bit file I/O // VDNUM 1-4 -module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0) +module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0) ( input clk_sys, - inout [44:0] HPS_BUS, + inout [45:0] HPS_BUS, // parameter STRLEN and the actual length of conf_str have to match input [(8*STRLEN)-1:0] conf_str, - output reg [15:0] joystick_0, - output reg [15:0] joystick_1, - output reg [15:0] joystick_2, - output reg [15:0] joystick_3, - output reg [15:0] joystick_4, - output reg [15:0] joystick_5, + output reg [31:0] joystick_0, + output reg [31:0] joystick_1, + output reg [31:0] joystick_2, + output reg [31:0] joystick_3, + output reg [31:0] joystick_4, + output reg [31:0] joystick_5, output reg [15:0] joystick_analog_0, output reg [15:0] joystick_analog_1, output reg [15:0] joystick_analog_2, @@ -57,6 +57,7 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0) output reg [31:0] status, input [31:0] status_in, input status_set, + input [15:0] status_menumask, //toggle to force notify of video mode change input new_vmode, @@ -121,7 +122,8 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0) output reg [10:0] ps2_key = 0, // [24] - toggles with every event - output reg [24:0] ps2_mouse = 0 + output reg [24:0] ps2_mouse = 0, + output reg [15:0] ps2_mouse_ext = 0 // 15:8 - reserved(additional buttons), 7:0 - wheel movements ); localparam DW = (WIDE) ? 15 : 7; @@ -173,15 +175,18 @@ wire de = HPS_BUS[40]; wire hs = HPS_BUS[39]; wire vs = HPS_BUS[38]; wire vs_hdmi = HPS_BUS[44]; +wire f1 = HPS_BUS[45]; reg [31:0] vid_hcnt = 0; reg [31:0] vid_vcnt = 0; reg [7:0] vid_nres = 0; +reg [1:0] vid_int = 0; integer hcnt; always @(posedge clk_vid) begin integer vcnt; reg old_vs= 0, old_de = 0, old_vmode = 0; + reg [3:0] resto = 0; reg calch = 0; if(ce_pix) begin @@ -193,15 +198,22 @@ always @(posedge clk_vid) begin if(old_de & ~de) calch <= 0; if(old_vs & ~vs) begin - if(hcnt && vcnt) begin - old_vmode <= new_vmode; - if(vid_hcnt != hcnt || vid_vcnt != vcnt || old_vmode != new_vmode) vid_nres <= vid_nres + 1'd1; - vid_hcnt <= hcnt; - vid_vcnt <= vcnt; + vid_int <= {vid_int[0],f1}; + if(~f1) begin + if(hcnt && vcnt) begin + old_vmode <= new_vmode; + + //report new resolution after timeout + if(resto) resto <= resto + 1'd1; + if(vid_hcnt != hcnt || vid_vcnt != vcnt || old_vmode != new_vmode) resto <= 1; + if(&resto) vid_nres <= vid_nres + 1'd1; + vid_hcnt <= hcnt; + vid_vcnt <= vcnt; + end + vcnt <= 0; + hcnt <= 0; + calch <= 1; end - vcnt <= 0; - hcnt <= 0; - calch <= 1; end end end @@ -288,7 +300,7 @@ always@(posedge clk_sys) begin if(b_wr[2] && (~&sd_buff_addr)) sd_buff_addr <= sd_buff_addr + 1'b1; b_wr <= (b_wr<<1); - {kbd_rd,kbd_we,mouse_rd,mouse_we} <= 0; + if(PS2DIV) {kbd_rd,kbd_we,mouse_rd,mouse_we} <= 0; if(~io_enable) begin if(cmd == 4 && !ps2skip) ps2_mouse[24] <= ~ps2_mouse[24]; @@ -321,6 +333,7 @@ always@(posedge clk_sys) begin 'h18: sd_ack <= 1; 'h29: io_dout <= {4'hA, stflg}; 'h2B: io_dout <= 1; + 'h2F: io_dout <= 1; endcase sd_buff_addr <= 0; @@ -330,18 +343,20 @@ always@(posedge clk_sys) begin case(cmd) // buttons and switches - 'h01: cfg <= io_din[7:0]; - 'h02: joystick_0 <= io_din; - 'h03: joystick_1 <= io_din; - 'h10: joystick_2 <= io_din; - 'h11: joystick_3 <= io_din; - 'h12: joystick_4 <= io_din; - 'h13: joystick_5 <= io_din; + 'h01: cfg <= io_din[7:0]; + 'h02: if(byte_cnt==1) joystick_0[15:0] <= io_din; else joystick_0[31:16] <= io_din; + 'h03: if(byte_cnt==1) joystick_1[15:0] <= io_din; else joystick_1[31:16] <= io_din; + 'h10: if(byte_cnt==1) joystick_2[15:0] <= io_din; else joystick_2[31:16] <= io_din; + 'h11: if(byte_cnt==1) joystick_3[15:0] <= io_din; else joystick_3[31:16] <= io_din; + 'h12: if(byte_cnt==1) joystick_4[15:0] <= io_din; else joystick_4[31:16] <= io_din; + 'h13: if(byte_cnt==1) joystick_5[15:0] <= io_din; else joystick_5[31:16] <= io_din; // store incoming ps2 mouse bytes 'h04: begin - mouse_data <= io_din[7:0]; - mouse_we <= 1; + if(PS2DIV) begin + mouse_data <= io_din[7:0]; + mouse_we <= 1; + end if(&io_din[15:8]) ps2skip <= 1; if(~&io_din[15:8] & ~ps2skip) begin case(byte_cnt) @@ -349,6 +364,11 @@ always@(posedge clk_sys) begin 2: ps2_mouse[15:8] <= io_din[7:0]; 3: ps2_mouse[23:16] <= io_din[7:0]; endcase + case(byte_cnt) + 1: ps2_mouse_ext[7:0] <= {io_din[14], io_din[14:8]}; + 2: ps2_mouse_ext[11:8] <= io_din[11:8]; + 3: ps2_mouse_ext[15:12]<= io_din[11:8]; + endcase end end @@ -356,8 +376,10 @@ always@(posedge clk_sys) begin 'h05: begin if(&io_din[15:8]) ps2skip <= 1; if(~&io_din[15:8] & ~ps2skip) ps2_key_raw[31:0] <= {ps2_key_raw[23:0], io_din[7:0]}; - kbd_data <= io_din[7:0]; - kbd_we <= 1; + if(PS2DIV) begin + kbd_data <= io_din[7:0]; + kbd_we <= 1; + end end // reading config string, returning a byte from string @@ -418,21 +440,24 @@ always@(posedge clk_sys) begin 'h1f: io_dout <= {|PS2WE, 2'b01, ps2_kbd_led_status[2], ps2_kbd_led_use[2], ps2_kbd_led_status[1], ps2_kbd_led_use[1], ps2_kbd_led_status[0], ps2_kbd_led_use[0]}; // reading ps2 keyboard/mouse control - 'h21: if(byte_cnt == 1) begin - io_dout <= kbd_data_host; - kbd_rd <= 1; - end - else - if(byte_cnt == 2) begin - io_dout <= mouse_data_host; - mouse_rd <= 1; + 'h21: if(PS2DIV) begin + if(byte_cnt == 1) begin + io_dout <= kbd_data_host; + kbd_rd <= 1; + end + else + if(byte_cnt == 2) begin + io_dout <= mouse_data_host; + mouse_rd <= 1; + end end + //RTC 'h22: RTC[(byte_cnt-6'd1)<<4 +:16] <= io_din; //Video res. 'h23: case(byte_cnt) - 1: io_dout <= vid_nres; + 1: io_dout <= {|vid_int, vid_nres}; 2: io_dout <= vid_hcnt[15:0]; 3: io_dout <= vid_hcnt[31:16]; 4: io_dout <= vid_vcnt[15:0]; @@ -458,6 +483,9 @@ always@(posedge clk_sys) begin 1: io_dout <= status_req[15:0]; 2: io_dout <= status_req[31:16]; endcase + + //menu mask + 'h2E: if(byte_cnt == 1) io_dout <= status_menumask; endcase end end @@ -466,62 +494,71 @@ end /////////////////////////////// PS2 /////////////////////////////// -reg clk_ps2; -always @(negedge clk_sys) begin - integer cnt; - cnt <= cnt + 1'd1; - if(cnt == PS2DIV) begin - clk_ps2 <= ~clk_ps2; - cnt <= 0; +generate + if(PS2DIV) begin + reg clk_ps2; + always @(negedge clk_sys) begin + integer cnt; + cnt <= cnt + 1'd1; + if(cnt == PS2DIV) begin + clk_ps2 <= ~clk_ps2; + cnt <= 0; + end + end + + reg [7:0] kbd_data; + reg kbd_we; + wire [8:0] kbd_data_host; + reg kbd_rd; + + ps2_device keyboard + ( + .clk_sys(clk_sys), + + .wdata(kbd_data), + .we(kbd_we), + + .ps2_clk(clk_ps2), + .ps2_clk_out(ps2_kbd_clk_out), + .ps2_dat_out(ps2_kbd_data_out), + + .ps2_clk_in(ps2_kbd_clk_in || !PS2WE), + .ps2_dat_in(ps2_kbd_data_in || !PS2WE), + + .rdata(kbd_data_host), + .rd(kbd_rd) + ); + + reg [7:0] mouse_data; + reg mouse_we; + wire [8:0] mouse_data_host; + reg mouse_rd; + + ps2_device mouse + ( + .clk_sys(clk_sys), + + .wdata(mouse_data), + .we(mouse_we), + + .ps2_clk(clk_ps2), + .ps2_clk_out(ps2_mouse_clk_out), + .ps2_dat_out(ps2_mouse_data_out), + + .ps2_clk_in(ps2_mouse_clk_in || !PS2WE), + .ps2_dat_in(ps2_mouse_data_in || !PS2WE), + + .rdata(mouse_data_host), + .rd(mouse_rd) + ); end -end - -reg [7:0] kbd_data; -reg kbd_we; -wire [8:0] kbd_data_host; -reg kbd_rd; - -ps2_device keyboard -( - .clk_sys(clk_sys), - - .wdata(kbd_data), - .we(kbd_we), - - .ps2_clk(clk_ps2), - .ps2_clk_out(ps2_kbd_clk_out), - .ps2_dat_out(ps2_kbd_data_out), - - .ps2_clk_in(ps2_kbd_clk_in || !PS2WE), - .ps2_dat_in(ps2_kbd_data_in || !PS2WE), - - .rdata(kbd_data_host), - .rd(kbd_rd) -); - -reg [7:0] mouse_data; -reg mouse_we; -wire [8:0] mouse_data_host; -reg mouse_rd; - -ps2_device mouse -( - .clk_sys(clk_sys), - - .wdata(mouse_data), - .we(mouse_we), - - .ps2_clk(clk_ps2), - .ps2_clk_out(ps2_mouse_clk_out), - .ps2_dat_out(ps2_mouse_data_out), - - .ps2_clk_in(ps2_mouse_clk_in || !PS2WE), - .ps2_dat_in(ps2_mouse_data_in || !PS2WE), - - .rdata(mouse_data_host), - .rd(mouse_rd) -); - + else begin + assign ps2_kbd_clk_out = 0; + assign ps2_kbd_data_out = 0; + assign ps2_mouse_clk_out = 0; + assign ps2_mouse_data_out = 0; + end +endgenerate /////////////////////////////// DOWNLOADING /////////////////////////////// diff --git a/sys/hq2x.sv b/sys/hq2x.sv index ece54f9..d7c58f9 100644 --- a/sys/hq2x.sv +++ b/sys/hq2x.sv @@ -15,12 +15,15 @@ module Hq2x #(parameter LENGTH, parameter HALF_DEPTH) ( input clk, - input ce_x4, + + input ce_in, input [DWIDTH:0] inputpixel, input mono, input disable_hq2x, input reset_frame, input reset_line, + + input ce_out, input [1:0] read_y, input hblank, output [DWIDTH:0] outpixel @@ -129,6 +132,14 @@ hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH+1), .DWIDTH(DWIDTH1*4-1)) hq2x_ou .wren(wrout_en) ); +always @(posedge clk) begin + if(ce_out) begin + if(read_x[0]) outpixel_x2 <= read_y[0] ? outpixel_x4[DWIDTH1*4-1:DWIDTH1*2] : outpixel_x4[DWIDTH1*2-1:0]; + if(~hblank & ~&read_x) read_x <= read_x + 1'd1; + if(hblank) read_x <= 0; + end +end + wire [DWIDTH:0] blend_result = HALF_DEPTH ? rgb2h(blend_result_pre) : blend_result_pre[DWIDTH:0]; reg [AWIDTH:0] offs; @@ -139,10 +150,7 @@ always @(posedge clk) begin wrout_en <= 0; wrin_en <= 0; - if(ce_x4) begin - - pattern <= new_pattern; - if(read_x[0]) outpixel_x2 <= read_y[0] ? outpixel_x4[DWIDTH1*4-1:DWIDTH1*2] : outpixel_x4[DWIDTH1*2-1:0]; + if(ce_in) begin if(~&offs) begin if (cyc == 1) begin @@ -168,6 +176,7 @@ always @(posedge clk) begin end end + pattern <= new_pattern; if(cyc==3) begin nextpatt <= {new_pattern[7:6], new_pattern[3], new_pattern[5], new_pattern[2], new_pattern[4], new_pattern[1:0]}; {A, G} <= {Prev0, Next0}; @@ -194,9 +203,6 @@ always @(posedge clk) begin end end - if(~hblank & ~&read_x) read_x <= read_x + 1'd1; - if(hblank) read_x <= 0; - old_reset_line <= reset_line; end end diff --git a/sys/ltc2308.sv b/sys/ltc2308.sv new file mode 100644 index 0000000..33134fd --- /dev/null +++ b/sys/ltc2308.sv @@ -0,0 +1,162 @@ +//============================================================================ +// +// LTC2308 controller +// Copyright (C) 2019 Sorgelig +// +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +//============================================================================ + + +// NUM_CH 1..8 +// Sampling rate = ADC_RATE/NUM_CH +// ADC_RATE max is ~500KHz +// CLK_RATE max is ~80MHz +module ltc2308 #(parameter NUM_CH = 2, ADC_RATE = 96000, CLK_RATE = 50000000) +( + input reset, + input clk, + + inout [3:0] ADC_BUS, + + output reg dout_sync, // toggle with every ADC round + output reg [(NUM_CH*12)-1:0] dout // 12 bits per channel (unsigned) +); + +localparam TCONV = CLK_RATE/625000; + +reg sck; +wire sdo = cfg[5]; + +assign ADC_BUS[3] = sck; +wire sdi = ADC_BUS[2]; +assign ADC_BUS[1] = sdo; +assign ADC_BUS[0] = convst; + +reg convst; +reg [5:0] cfg; + +reg [31:0] sum; +wire [31:0] next_sum = sum + ADC_RATE; + +reg [2:0] pin; +wire [2:0] next_pin = (pin == (NUM_CH-1)) ? 3'd0 : (pin + 1'd1); + +always @(posedge clk) begin + reg [7:0] tconv; + reg [3:0] bitcnt; + reg [10:0] adcin; + + convst <= 0; + + if(reset) begin + sum <= 0; + tconv <= 0; + bitcnt <= 0; + sck <= 0; + cfg <= 0; + dout <= 0; + pin <= NUM_CH[2:0]-1'd1; + end + else begin + sum <= next_sum; + if(next_sum >= CLK_RATE) begin + sum <= next_sum - CLK_RATE; + tconv <= TCONV[7:0]; + convst <= 1; + bitcnt <= 12; + cfg <= {1'b1, next_pin[0], next_pin[2:1], 1'b1, 1'b0}; + if(!next_pin) dout_sync <= ~dout_sync; + end + + if(tconv) tconv <= tconv - 1'd1; + else if(bitcnt) begin + sck <= ~sck; + + if(sck) cfg <= cfg<<1; + else begin + adcin <= {adcin[9:0],sdi}; + bitcnt <= bitcnt - 1'd1; + if(bitcnt == 1) begin + dout[pin*12 +:12] <= {adcin,sdi}; + pin <= next_pin; + end + end + end + else sck <= 0; + end +end + +endmodule + +module ltc2308_tape #(parameter HIST_LOW = 16, HIST_HIGH = 64, ADC_RATE = 48000, CLK_RATE = 50000000) +( + input reset, + input clk, + + inout [3:0] ADC_BUS, + output reg dout, + output active +); + +wire [11:0] adc_data; +wire adc_sync; +ltc2308 #(1, ADC_RATE, CLK_RATE) adc +( + .reset(reset), + .clk(clk), + + .ADC_BUS(ADC_BUS), + .dout(adc_data), + .dout_sync(adc_sync) +); + +always @(posedge clk) begin + reg [13:0] data1,data2,data3,data4, sum; + reg adc_sync_d; + + adc_sync_d<=adc_sync; + if(adc_sync_d ^ adc_sync) begin + data1 <= data2; + data2 <= data3; + data3 <= data4; + data4 <= adc_data; + + sum <= data1+data2+data3+data4; + + if(sum[13:2]HIST_HIGH) dout <= 1; + end +end + +assign active = |act; + +reg [1:0] act; +always @(posedge clk) begin + reg [31:0] onesec; + reg old_dout; + + onesec <= onesec + 1; + if(onesec>CLK_RATE) begin + onesec <= 0; + if(act) act <= act - 1'd1; + end + + old_dout <= dout; + if(old_dout ^ dout) act <= 2; +end + +endmodule diff --git a/sys/osd.v b/sys/osd.v index 81939c6..5c1fb04 100644 --- a/sys/osd.v +++ b/sys/osd.v @@ -24,8 +24,14 @@ parameter OSD_Y_OFFSET = 12'd0; localparam OSD_WIDTH = 12'd256; localparam OSD_HEIGHT = 12'd64; +`ifdef OSD_HEADER +localparam OSD_HDR = 12'd32; +`else +localparam OSD_HDR = 12'd0; +`endif + reg osd_enable; -reg [7:0] osd_buffer[4096]; +reg [7:0] osd_buffer[OSD_HDR ? (4096+1024) : 4096]; reg info = 0; reg [8:0] infoh; @@ -35,13 +41,13 @@ reg [21:0] infoy; reg [21:0] hrheight; always@(posedge clk_sys) begin - reg [11:0] bcnt; + reg [12:0] bcnt; reg [7:0] cmd; reg has_cmd; reg old_strobe; reg highres = 0; - hrheight <= info ? infoh : (OSD_HEIGHT<>1) + OSD_Y_OFFSET; + v_osd_start_640 <= ((v_cnt-(hrheight<<1))>>1) + OSD_Y_OFFSET; + v_osd_start_960 <= ((v_cnt-(hrheight + (hrheight<<1)))>>1) + OSD_Y_OFFSET; + v_osd_start_other <= ((v_cnt-(hrheight<<2))>>1) + OSD_Y_OFFSET; +end always @(posedge clk_video) begin reg deD; @@ -114,7 +136,6 @@ always @(posedge clk_video) begin reg [1:0] multiscan; reg [7:0] osd_byte; reg [23:0] h_cnt; - reg [21:0] v_cnt; reg [21:0] dsp_width; reg [21:0] osd_vcnt; reg [21:0] h_osd_start; @@ -130,7 +151,8 @@ always @(posedge clk_video) begin if(~&osd_hcnt) osd_hcnt <= osd_hcnt + 1'd1; if (h_cnt == h_osd_start) begin - osd_de[0] <= osd_en[1] && hrheight && (osd_vcnt < hrheight); + osd_de[0] <= osd_en[1] && hrheight && (info ? (osd_vcnt < hrheight) : + (!osd_vcnt[11:7] || (osd_vcnt[11] && osd_vcnt[7] && (osd_vcnt[6:0] >= 4) && (osd_vcnt[6:0] < 19)))); osd_hcnt <= 0; end if (osd_hcnt+1 == (info ? infow : OSD_WIDTH)) osd_de[0] <= 0; @@ -145,38 +167,39 @@ always @(posedge clk_video) begin h_osd_start <= info ? infox : (((dsp_width - OSD_WIDTH)>>1) + OSD_X_OFFSET - 2'd2); if(h_cnt > {dsp_width, 2'b00}) begin - v_cnt <= 0; + v_cnt <= 1; osd_en <= (osd_en << 1) | osd_enable; if(~osd_enable) osd_en <= 0; - if(v_cnt<320) begin + if(v_cnt_below320) begin multiscan <= 0; - v_osd_start <= info ? infoy : (((v_cnt-hrheight)>>1) + OSD_Y_OFFSET); + v_osd_start <= info ? infoy : v_osd_start_320; end - else if(v_cnt<640) begin + else if(v_cnt_below640) begin multiscan <= 1; - v_osd_start <= info ? (infoy<<1) : (((v_cnt-(hrheight<<1))>>1) + OSD_Y_OFFSET); + v_osd_start <= info ? (infoy<<1) : v_osd_start_640; end - else if(v_cnt<960) begin + else if(v_cnt_below960) begin multiscan <= 2; - v_osd_start <= info ? (infoy + (infoy << 1)) : (((v_cnt-(hrheight + (hrheight<<1)))>>1) + OSD_Y_OFFSET); + v_osd_start <= info ? (infoy + (infoy << 1)) : v_osd_start_960; end else begin multiscan <= 3; - v_osd_start <= info ? (infoy<<2) : (((v_cnt-(hrheight<<2))>>1) + OSD_Y_OFFSET); + v_osd_start <= info ? (infoy<<2) : v_osd_start_other; end end - + osd_div <= osd_div + 1'd1; if(osd_div == multiscan) begin osd_div <= 0; - if(~&osd_vcnt) osd_vcnt <= osd_vcnt + 1'd1; + if(~osd_vcnt[10]) osd_vcnt <= osd_vcnt + 1'd1; + if(osd_vcnt == 'b100010011111 && ~info) osd_vcnt <= 0; end - if(v_osd_start == (v_cnt+1'b1)) {osd_div, osd_vcnt} <= 0; + if(v_osd_start == v_cnt) {osd_div, osd_vcnt} <= OSD_HDR ? {~info, 3'b000, ~info, 7'b0000000} : 22'd0; end - osd_byte <= osd_buffer[{osd_vcnt[6:3], osd_hcnt[7:0]}]; + osd_byte <= osd_buffer[{osd_vcnt[7:3], osd_hcnt[7:0]}]; osd_pixel <= osd_byte[osd_vcnt[2:0]]; osd_de[2:1] <= osd_de[1:0]; end @@ -185,11 +208,19 @@ end reg [23:0] rdout; assign dout = rdout; +reg [23:0] osd_rdout, normal_rdout; +reg osd_mux; +reg de_dly; + always @(posedge clk_video) begin - rdout <= ~osd_de[2] ? din : {{osd_pixel, osd_pixel, OSD_COLOR[2], din[23:19]}, - {osd_pixel, osd_pixel, OSD_COLOR[1], din[15:11]}, - {osd_pixel, osd_pixel, OSD_COLOR[0], din[7:3]}}; - de_out <= de_in; + normal_rdout <= din; + osd_rdout <= {{osd_pixel, osd_pixel, OSD_COLOR[2], din[23:19]},// 23:16 + {osd_pixel, osd_pixel, OSD_COLOR[1], din[15:11]},// 15:8 + {osd_pixel, osd_pixel, OSD_COLOR[0], din[7:3]}}; // 7:0 + osd_mux <= ~osd_de[2]; + rdout <= osd_mux ? normal_rdout : osd_rdout; + de_dly <= de_in; + de_out <= de_dly; end endmodule diff --git a/sys/pll.13.qip b/sys/pll.13.qip new file mode 100644 index 0000000..a5cd7dc --- /dev/null +++ b/sys/pll.13.qip @@ -0,0 +1,13 @@ +set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_VERSION "13.1" +set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_ENV "mwpim" +set_global_assignment -library "pll" -name MISC_FILE [file join $::quartus(qip_path) "pll.cmp"] +set_global_assignment -name SYNTHESIS_ONLY_QIP ON + +set_global_assignment -library "pll" -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"] +set_global_assignment -library "pll" -name VERILOG_FILE [file join $::quartus(qip_path) "pll/pll_0002.v"] +set_global_assignment -library "pll" -name QIP_FILE [file join $::quartus(qip_path) "pll/pll_0002_q13.qip"] + +set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_VERSION "13.1" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_ENV "mwpim" diff --git a/sys/pll/pll_0002_q13.qip b/sys/pll/pll_0002_q13.qip new file mode 100644 index 0000000..9f8ded1 --- /dev/null +++ b/sys/pll/pll_0002_q13.qip @@ -0,0 +1,4 @@ +set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_0002*|altera_pll:altera_pll_i*|*" diff --git a/sys/pll_cfg.qip b/sys/pll_cfg.qip new file mode 100644 index 0000000..c3394be --- /dev/null +++ b/sys/pll_cfg.qip @@ -0,0 +1,44 @@ +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_TOOL_NAME "altera_pll_reconfig" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_TOOL_VERSION "17.0" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_TOOL_ENV "mwpim" +set_global_assignment -library "pll_cfg" -name MISC_FILE [file join $::quartus(qip_path) "pll_cfg.cmp"] +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_QSYS_MODE "UNKNOWN" +set_global_assignment -name SYNTHESIS_ONLY_QIP ON +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_NAME "cGxsX2hkbWlfY2Zn" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTCBSZWNvbmZpZw==" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_VERSION "MTcuMA==" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIFJlY29uZmlndXJhdGlvbiBCbG9jayhBTFRFUkFfUExMX1JFQ09ORklHKQ==" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0JZVEVFTkFCTEU=::ZmFsc2U=::QWRkIGJ5dGVlbmFibGUgcG9ydA==" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "QllURUVOQUJMRV9XSURUSA==::NA==::QllURUVOQUJMRV9XSURUSA==" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfQUREUl9XSURUSA==::Ng==::UkVDT05GSUdfQUREUl9XSURUSA==" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfREFUQV9XSURUSA==::MzI=::UkVDT05GSUdfREFUQV9XSURUSA==" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "cmVjb25mX3dpZHRo::NjQ=::cmVjb25mX3dpZHRo" +set_global_assignment -entity "pll_cfg" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "V0FJVF9GT1JfTE9DSw==::dHJ1ZQ==::V0FJVF9GT1JfTE9DSw==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_NAME "YWx0ZXJhX3BsbF9yZWNvbmZpZ190b3A=" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTCBSZWNvbmZpZw==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_VERSION "MTcuMA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIFJlY29uZmlndXJhdGlvbiBCbG9jayhBTFRFUkFfUExMX1JFQ09ORklHKQ==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "ZGV2aWNlX2ZhbWlseQ==::Q3ljbG9uZSBW::ZGV2aWNlX2ZhbWlseQ==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX01JRg==::ZmFsc2U=::RW5hYmxlIE1JRiBTdHJlYW1pbmc=" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0JZVEVFTkFCTEU=::ZmFsc2U=::QWRkIGJ5dGVlbmFibGUgcG9ydA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "QllURUVOQUJMRV9XSURUSA==::NA==::QllURUVOQUJMRV9XSURUSA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfQUREUl9XSURUSA==::Ng==::UkVDT05GSUdfQUREUl9XSURUSA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfREFUQV9XSURUSA==::MzI=::UkVDT05GSUdfREFUQV9XSURUSA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "cmVjb25mX3dpZHRo::NjQ=::cmVjb25mX3dpZHRo" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_COMPONENT_PARAMETER "V0FJVF9GT1JfTE9DSw==::dHJ1ZQ==::V0FJVF9GT1JfTE9DSw==" + +set_global_assignment -library "pll_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_cfg.v"] +set_global_assignment -library "pll_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_cfg/altera_pll_reconfig_top.v"] +set_global_assignment -library "pll_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_cfg/altera_pll_reconfig_core.v"] + +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_TOOL_NAME "altera_pll_reconfig" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_TOOL_VERSION "17.0" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_cfg" -name IP_TOOL_ENV "mwpim" diff --git a/sys/pll_hdmi_cfg.v b/sys/pll_cfg.v similarity index 92% rename from sys/pll_hdmi_cfg.v rename to sys/pll_cfg.v index 1ebf6f0..0adc36f 100644 --- a/sys/pll_hdmi_cfg.v +++ b/sys/pll_cfg.v @@ -1,11 +1,11 @@ // megafunction wizard: %Altera PLL Reconfig v17.0% // GENERATION: XML -// pll_hdmi_cfg.v +// pll_cfg.v // Generated using ACDS version 17.0 598 `timescale 1 ps / 1 ps -module pll_hdmi_cfg #( +module pll_cfg #( parameter ENABLE_BYTEENABLE = 0, parameter BYTEENABLE_WIDTH = 4, parameter RECONFIG_ADDR_WIDTH = 6, @@ -28,14 +28,14 @@ module pll_hdmi_cfg #( altera_pll_reconfig_top #( .device_family ("Cyclone V"), .ENABLE_MIF (0), - .MIF_FILE_NAME ("sys/pll_hdmi_cfg.mif"), + .MIF_FILE_NAME ("sys/pll_cfg.mif"), .ENABLE_BYTEENABLE (ENABLE_BYTEENABLE), .BYTEENABLE_WIDTH (BYTEENABLE_WIDTH), .RECONFIG_ADDR_WIDTH (RECONFIG_ADDR_WIDTH), .RECONFIG_DATA_WIDTH (RECONFIG_DATA_WIDTH), .reconf_width (reconf_width), .WAIT_FOR_LOCK (WAIT_FOR_LOCK) - ) pll_hdmi_cfg_inst ( + ) pll_cfg_inst ( .mgmt_clk (mgmt_clk), // mgmt_clk.clk .mgmt_reset (mgmt_reset), // mgmt_reset.reset .mgmt_waitrequest (mgmt_waitrequest), // mgmt_avalon_slave.waitrequest @@ -79,8 +79,8 @@ endmodule // Retrieval info: // Retrieval info: // Retrieval info: -// Retrieval info: +// Retrieval info: // Retrieval info: // Retrieval info: -// IPFS_FILES : pll_hdmi_cfg.vo -// RELATED_FILES: pll_hdmi_cfg.v, altera_pll_reconfig_top.v, altera_pll_reconfig_core.v, altera_std_synchronizer.v +// IPFS_FILES : pll_cfg.vo +// RELATED_FILES: pll_cfg.v, altera_pll_reconfig_top.v, altera_pll_reconfig_core.v, altera_std_synchronizer.v diff --git a/sys/pll_hdmi_cfg/altera_pll_reconfig_core.v b/sys/pll_cfg/altera_pll_reconfig_core.v similarity index 100% rename from sys/pll_hdmi_cfg/altera_pll_reconfig_core.v rename to sys/pll_cfg/altera_pll_reconfig_core.v diff --git a/sys/pll_hdmi_cfg/altera_pll_reconfig_top.v b/sys/pll_cfg/altera_pll_reconfig_top.v similarity index 100% rename from sys/pll_hdmi_cfg/altera_pll_reconfig_top.v rename to sys/pll_cfg/altera_pll_reconfig_top.v diff --git a/sys/pll_hdmi_q13.qip b/sys/pll_hdmi.13.qip similarity index 100% rename from sys/pll_hdmi_q13.qip rename to sys/pll_hdmi.13.qip diff --git a/sys/pll_hdmi_adj.vhd b/sys/pll_hdmi_adj.vhd index 8c242af..67287cb 100644 --- a/sys/pll_hdmi_adj.vhd +++ b/sys/pll_hdmi_adj.vhd @@ -5,11 +5,11 @@ -- Changes the HDMI PLL frequency according to the scaler suggestions. -------------------------------------------- -- LLTUNE : --- 0 : Input Syncline --- 1 : +-- 0 : Input Display Enable +-- 1 : Input Vsync -- 2 : Input Interlaced mode -- 3 : Input Interlaced field --- 4 : Output Syncline +-- 4 : Output Image frame -- 5 : -- 6 : Input clock -- 7 : Output clock @@ -51,6 +51,11 @@ END ENTITY pll_hdmi_adj; --############################################################################## ARCHITECTURE rtl OF pll_hdmi_adj IS + + SIGNAL i_clk,i_de,i_de2,i_vss,i_vss2,i_vss_delay,i_ce : std_logic; + SIGNAL i_linecpt,i_line : natural RANGE 0 TO 2**12-1; + SIGNAL i_delay : natural RANGE 0 TO 2**14-1; + SIGNAL pwrite : std_logic; SIGNAL paddress : unsigned(5 DOWNTO 0); SIGNAL pdata : unsigned(31 DOWNTO 0); @@ -61,19 +66,57 @@ ARCHITECTURE rtl OF pll_hdmi_adj IS SIGNAL mfrac,mfrac_mem,mfrac_ref,diff : unsigned(40 DOWNTO 0); SIGNAL mul : unsigned(15 DOWNTO 0); SIGNAL sign,sign_pre : std_logic; + SIGNAL expand : boolean; SIGNAL up,modo,phm,dir : std_logic; SIGNAL cpt : natural RANGE 0 TO 3; SIGNAL col : natural RANGE 0 TO 15; - SIGNAL icpt,ocpt,ssh : natural RANGE 0 TO 2**24-1; - SIGNAL isync,isync2,itog,ipulse : std_logic; - SIGNAL osync,osync2,otog,opulse : std_logic; + SIGNAL icpt,ocpt,o2cpt,ssh,ofsize,ifsize : natural RANGE 0 TO 2**24-1; + SIGNAL ivss,ivss2,itog : std_logic; + SIGNAL ovss,ovss2,otog : std_logic; SIGNAL sync,pulse,los,lop : std_logic; - SIGNAL osize,isize,offset,osizep : signed(23 DOWNTO 0); + SIGNAL osize,offset,osizep,offsetp : signed(23 DOWNTO 0); SIGNAL logcpt : natural RANGE 0 TO 31; SIGNAL udiff : integer RANGE -2**23 TO 2**23-1 :=0; BEGIN + + ---------------------------------------------------------------------------- + -- 4 lines delay to input + i_vss<=lltune(0); + i_de <=lltune(1); + i_ce <=lltune(5); + i_clk<=lltune(6); + + Delay:PROCESS(i_clk) IS + BEGIN + IF rising_edge(i_clk) THEN + IF i_ce='1' THEN + -- Measure input line time. + i_de2<=i_de; + + IF i_de='1' AND i_de2='0' THEN + i_linecpt<=0; + IF i_vss='1' THEN + i_line<=i_linecpt; + END IF; + ELSE + i_linecpt<=i_linecpt+1; + END IF; + + -- Delay 4 lines + i_vss2<=i_vss; + IF i_vss/=i_vss2 THEN + i_delay<=0; + ELSIF i_delay=i_line * 4 THEN + i_vss_delay<=i_vss; + ELSE + i_delay<=i_delay+1; + END IF; + END IF; + END IF; + END PROCESS Delay; + ---------------------------------------------------------------------------- -- Sample image sizes Sampler:PROCESS(clk,reset_na) IS @@ -82,39 +125,47 @@ BEGIN --pragma synthesis_off otog<='0'; itog<='0'; - isync<='0'; - isync2<='0'; - osync<='0'; - osync2<='0'; + ivss<='0'; + ivss2<='0'; + ovss<='0'; + ovss2<='0'; --pragma synthesis_on ELSIF rising_edge(clk) THEN -- Clock domain crossing - isync<=lltune(0); -- - isync2<=isync; - osync<=lltune(4); -- - osync2<=osync; - itog<=itog XOR (isync AND NOT isync2); - otog<=otog XOR (osync AND NOT osync2); + ivss<=i_vss_delay; -- + ivss2<=ivss; - --ipulse<=isync AND NOT isync2 AND itog; - --opulse<=osync AND NOT osync2 AND otog; + ovss<=lltune(4); -- + ovss2<=ovss; - -- Measure output image size - IF osync='1' AND osync2='0' AND otog='1' THEN + otog<=otog XOR (ovss AND NOT ovss2); + + -- Measure output frame time + IF ovss='1' AND ovss2='0' AND otog='1' THEN ocpt<=0; osizep<=to_signed(ocpt,24); ELSE ocpt<=ocpt+1; END IF; + IF ovss='0' AND ovss2='1' AND otog='0' THEN + o2cpt<=0; + ELSE + o2cpt<=o2cpt+1; + END IF; - -- Measure input image size - IF isync='1' AND isync2='0' AND itog='1' THEN + -- Measure output image time + IF ovss='0' AND ovss2='1' AND otog='0' THEN + ofsize<=ocpt; + END IF; + + itog<=itog XOR (ivss AND NOT ivss2); + + -- Measure input frame time + IF ivss='1' AND ivss2='0' AND itog='1' THEN icpt<=0; - --isize<=to_signed(icpt,24); osize<=osizep; - offset<=to_signed(ocpt,24); udiff<=integer(to_integer(osizep)) - integer(icpt); sync<='1'; ELSE @@ -122,6 +173,28 @@ BEGIN sync<='0'; END IF; + -- Measure input image time + IF ivss='0' AND ivss2='1' AND itog='0' THEN + ifsize<=icpt; + END IF; + + expand<=(ofsize>=ifsize); + -- IN | ######### | EXPAND = 1 + -- OUT | ############# | + + -- IN | ######### | EXPAND = 0 + -- OUT | ###### | + + IF expand THEN + IF ivss='1' AND ivss2='0' AND itog='1' THEN + offset<=to_signed(ocpt,24); + END IF; + ELSE + IF ivss='0' AND ivss2='1' AND itog='0' THEN + offset<=to_signed(o2cpt,24); + END IF; + END IF; + -------------------------------------------- pulse<='0'; IF sync='1' THEN diff --git a/sys/pll_hdmi_cfg.qip b/sys/pll_hdmi_cfg.qip deleted file mode 100644 index f6447f5..0000000 --- a/sys/pll_hdmi_cfg.qip +++ /dev/null @@ -1,44 +0,0 @@ -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TOOL_NAME "altera_pll_reconfig" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TOOL_VERSION "17.0" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TOOL_ENV "mwpim" -set_global_assignment -library "pll_hdmi_cfg" -name MISC_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg.cmp"] -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_QSYS_MODE "UNKNOWN" -set_global_assignment -name SYNTHESIS_ONLY_QIP ON -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_NAME "cGxsX2hkbWlfY2Zn" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTCBSZWNvbmZpZw==" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_REPORT_HIERARCHY "Off" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_INTERNAL "Off" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_VERSION "MTcuMA==" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIFJlY29uZmlndXJhdGlvbiBCbG9jayhBTFRFUkFfUExMX1JFQ09ORklHKQ==" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0JZVEVFTkFCTEU=::ZmFsc2U=::QWRkIGJ5dGVlbmFibGUgcG9ydA==" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "QllURUVOQUJMRV9XSURUSA==::NA==::QllURUVOQUJMRV9XSURUSA==" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfQUREUl9XSURUSA==::Ng==::UkVDT05GSUdfQUREUl9XSURUSA==" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfREFUQV9XSURUSA==::MzI=::UkVDT05GSUdfREFUQV9XSURUSA==" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "cmVjb25mX3dpZHRo::NjQ=::cmVjb25mX3dpZHRo" -set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "V0FJVF9GT1JfTE9DSw==::dHJ1ZQ==::V0FJVF9GT1JfTE9DSw==" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_NAME "YWx0ZXJhX3BsbF9yZWNvbmZpZ190b3A=" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTCBSZWNvbmZpZw==" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_REPORT_HIERARCHY "Off" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_INTERNAL "Off" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_VERSION "MTcuMA==" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIFJlY29uZmlndXJhdGlvbiBCbG9jayhBTFRFUkFfUExMX1JFQ09ORklHKQ==" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "ZGV2aWNlX2ZhbWlseQ==::Q3ljbG9uZSBW::ZGV2aWNlX2ZhbWlseQ==" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX01JRg==::ZmFsc2U=::RW5hYmxlIE1JRiBTdHJlYW1pbmc=" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0JZVEVFTkFCTEU=::ZmFsc2U=::QWRkIGJ5dGVlbmFibGUgcG9ydA==" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "QllURUVOQUJMRV9XSURUSA==::NA==::QllURUVOQUJMRV9XSURUSA==" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfQUREUl9XSURUSA==::Ng==::UkVDT05GSUdfQUREUl9XSURUSA==" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfREFUQV9XSURUSA==::MzI=::UkVDT05GSUdfREFUQV9XSURUSA==" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "cmVjb25mX3dpZHRo::NjQ=::cmVjb25mX3dpZHRo" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "V0FJVF9GT1JfTE9DSw==::dHJ1ZQ==::V0FJVF9GT1JfTE9DSw==" - -set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg.v"] -set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg/altera_pll_reconfig_top.v"] -set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg/altera_pll_reconfig_core.v"] - -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_TOOL_NAME "altera_pll_reconfig" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_TOOL_VERSION "17.0" -set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_TOOL_ENV "mwpim" diff --git a/sys/pll_q13.qip b/sys/pll_q13.qip new file mode 100644 index 0000000..7018c53 --- /dev/null +++ b/sys/pll_q13.qip @@ -0,0 +1,5 @@ +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll.13.qip ] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.13.qip ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_cfg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_cfg/altera_pll_reconfig_core.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_cfg/altera_pll_reconfig_top.v ] diff --git a/sys/pll_q17.qip b/sys/pll_q17.qip new file mode 100644 index 0000000..9c69934 --- /dev/null +++ b/sys/pll_q17.qip @@ -0,0 +1,3 @@ +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll.qip ] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.qip ] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_cfg.qip ] diff --git a/sys/scandoubler.v b/sys/scandoubler.v index 9997cf6..1a39247 100644 --- a/sys/scandoubler.v +++ b/sys/scandoubler.v @@ -49,38 +49,27 @@ module scandoubler #(parameter LENGTH, parameter HALF_DEPTH) output [DWIDTH:0] b_out ); - localparam DWIDTH = HALF_DEPTH ? 3 : 7; -assign vs_out = vso[3]; -assign ce_pix_out = hq2x ? ce_x4 : ce_x2; - -//Compensate picture shift after HQ2x -assign vb_out = vbo[3]; -assign hb_out = hbo[6]; - reg [7:0] pix_len = 0; -reg [7:0] pix_cnt = 0; wire [7:0] pl = pix_len + 1'b1; -wire [7:0] pc = pix_cnt + 1'b1; -reg ce_x4, ce_x2, ce_x1; +reg [7:0] pix_in_cnt = 0; +wire [7:0] pc_in = pix_in_cnt + 1'b1; +reg [7:0] pixsz, pixsz2, pixsz4 = 0; + +reg ce_x4i, ce_x1i; always @(negedge clk_sys) begin reg old_ce, valid, hs; - reg [2:0] ce_cnt; - - reg [7:0] pixsz, pixsz2, pixsz4 = 0; if(~&pix_len) pix_len <= pl; - if(~&pix_cnt) pix_cnt <= pc; + if(~&pix_in_cnt) pix_in_cnt <= pc_in; - ce_x4 <= 0; - ce_x2 <= 0; - ce_x1 <= 0; + ce_x4i <= 0; + ce_x1i <= 0; // use such odd comparison to place ce_x4 evenly if master clock isn't multiple of 4. - if((pc == pixsz4) || (pc == pixsz2) || (pc == (pixsz2+pixsz4))) ce_x4 <= 1; - if( pc == pixsz2) ce_x2 <= 1; + if((pc_in == pixsz4) || (pc_in == pixsz2) || (pc_in == (pixsz2+pixsz4))) ce_x4i <= 1; old_ce <= ce_pix; if(~old_ce & ce_pix) begin @@ -93,41 +82,72 @@ always @(negedge clk_sys) begin valid <= 1; end - if(hb_in | vb_in) valid <= 0; + hs <= hs_in; + if((~hs & hs_in) || (pc_in >= pixsz)) begin + ce_x4i <= 1; + ce_x1i <= 1; + pix_in_cnt <= 0; + end - hs <= hs_out; - if((~hs & hs_out) || (pc >= pixsz)) begin - ce_x2 <= 1; - ce_x4 <= 1; - ce_x1 <= 1; - pix_cnt <= 0; + if(hb_in | vb_in) valid <= 0; +end + +reg req_line_reset; +reg [DWIDTH:0] r_d, g_d, b_d; +always @(posedge clk_sys) begin + if(ce_x1i) begin + req_line_reset <= hb_in; + r_d <= r_in; + g_d <= g_in; + b_d <= b_in; end end Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x ( .clk(clk_sys), - .ce_x4(ce_x4), + + .ce_in(ce_x4i), .inputpixel({b_d,g_d,r_d}), .mono(mono), .disable_hq2x(~hq2x), .reset_frame(vb_in), .reset_line(req_line_reset), + + .ce_out(ce_x4o), .read_y(sd_line), .hblank(hbo[0]&hbo[8]), .outpixel({b_out,g_out,r_out}) ); -reg [DWIDTH:0] r_d; -reg [DWIDTH:0] g_d; -reg [DWIDTH:0] b_d; +reg [7:0] pix_out_cnt = 0; +wire [7:0] pc_out = pix_out_cnt + 1'b1; + +reg ce_x4o, ce_x2o; +always @(negedge clk_sys) begin + reg hs; + + if(~&pix_out_cnt) pix_out_cnt <= pc_out; + + ce_x4o <= 0; + ce_x2o <= 0; + + // use such odd comparison to place ce_x4 evenly if master clock isn't multiple of 4. + if((pc_out == pixsz4) || (pc_out == pixsz2) || (pc_out == (pixsz2+pixsz4))) ce_x4o <= 1; + if( pc_out == pixsz2) ce_x2o <= 1; + + hs <= hs_out; + if((~hs & hs_out) || (pc_out >= pixsz)) begin + ce_x2o <= 1; + ce_x4o <= 1; + pix_out_cnt <= 0; + end +end reg [1:0] sd_line; reg [3:0] vbo; reg [3:0] vso; reg [8:0] hbo; - -reg req_line_reset; always @(posedge clk_sys) begin reg [31:0] hcnt; @@ -137,7 +157,7 @@ always @(posedge clk_sys) begin reg hs, hb; - if(ce_x4) begin + if(ce_x4o) begin hbo[8:1] <= hbo[7:0]; end @@ -164,13 +184,6 @@ always @(posedge clk_sys) begin hs <= hs_in; hb <= hb_in; - if(ce_x1) begin - req_line_reset <= hb_in; - r_d <= r_in; - g_d <= g_in; - b_d <= b_in; - end - hcnt <= hcnt + 1'd1; if(hb && !hb_in) begin hde_start <= hcnt[31:1]; @@ -192,4 +205,11 @@ always @(posedge clk_sys) begin if(!hs && hs_in) hs_start <= hcnt[31:1]; end +assign vs_out = vso[3]; +assign ce_pix_out = hq2x ? ce_x4o : ce_x2o; + +//Compensate picture shift after HQ2x +assign vb_out = vbo[3]; +assign hb_out = hbo[6]; + endmodule diff --git a/sys/sys.qip b/sys/sys.qip index 986b6d2..a67123e 100644 --- a/sys/sys.qip +++ b/sys/sys.qip @@ -1,10 +1,9 @@ +set_global_assignment -name QIP_FILE [join [list $::quartus(qip_path) pll_q [regexp -inline {[0-9]+} $quartus(version)] .qip] {}] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sys_top.v ] set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sys_top.sdc ] -set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll.qip ] -set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi.qip ] -set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi_cfg.qip ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) pll_hdmi_adj.vhd ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) fbpal.sv ] set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ] @@ -17,10 +16,9 @@ set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) a set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) spdif.v ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) audio_out.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ltc2308.sv ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ] set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.sv ] set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sysmem.sv ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sd_card.v ] set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) hps_io.v ] -set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALSPIMASTER_X52_Y72_N111 -entity sys_top -to spi -set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALUART_X52_Y67_N111 -entity sys_top -to uart diff --git a/sys/sys.tcl b/sys/sys.tcl new file mode 100644 index 0000000..d976d0e --- /dev/null +++ b/sys/sys.tcl @@ -0,0 +1,254 @@ +set_global_assignment -name FAMILY "Cyclone V" +set_global_assignment -name DEVICE 5CSEBA6U23I7 +set_global_assignment -name DEVICE_FILTER_PACKAGE UFBGA +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 672 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 7 + +#============================================================ +# ADC +#============================================================ +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ADC_CONVST +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ADC_SCK +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ADC_SDI +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ADC_SDO +set_location_assignment PIN_U9 -to ADC_CONVST +set_location_assignment PIN_V10 -to ADC_SCK +set_location_assignment PIN_AC4 -to ADC_SDI +set_location_assignment PIN_AD4 -to ADC_SDO + +#============================================================ +# ARDUINO +#============================================================ +set_location_assignment PIN_AG9 -to ARDUINO_IO[3] +set_location_assignment PIN_U14 -to ARDUINO_IO[4] +set_location_assignment PIN_U13 -to ARDUINO_IO[5] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[*] +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to ARDUINO_IO[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to ARDUINO_IO[*] + +#============================================================ +# USER PORT +#============================================================ +set_location_assignment PIN_AF15 -to USER_IO[5] +set_location_assignment PIN_AG16 -to USER_IO[4] +set_location_assignment PIN_AH11 -to USER_IO[3] +set_location_assignment PIN_AH12 -to USER_IO[2] +set_location_assignment PIN_AH9 -to USER_IO[1] +set_location_assignment PIN_AG11 -to USER_IO[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to USER_IO[*] +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to USER_IO[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to USER_IO[*] + +#============================================================ +# SDIO_CD or SPDIF_OUT +#============================================================ +set_location_assignment PIN_AH7 -to SDCD_SPDIF + +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDCD_SPDIF + +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDCD_SPDIF +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDCD_SPDIF + +#============================================================ +# SDRAM +#============================================================ +set_location_assignment PIN_Y11 -to SDRAM_A[0] +set_location_assignment PIN_AA26 -to SDRAM_A[1] +set_location_assignment PIN_AA13 -to SDRAM_A[2] +set_location_assignment PIN_AA11 -to SDRAM_A[3] +set_location_assignment PIN_W11 -to SDRAM_A[4] +set_location_assignment PIN_Y19 -to SDRAM_A[5] +set_location_assignment PIN_AB23 -to SDRAM_A[6] +set_location_assignment PIN_AC23 -to SDRAM_A[7] +set_location_assignment PIN_AC22 -to SDRAM_A[8] +set_location_assignment PIN_C12 -to SDRAM_A[9] +set_location_assignment PIN_AB26 -to SDRAM_A[10] +set_location_assignment PIN_AD17 -to SDRAM_A[11] +set_location_assignment PIN_D12 -to SDRAM_A[12] +set_location_assignment PIN_Y17 -to SDRAM_BA[0] +set_location_assignment PIN_AB25 -to SDRAM_BA[1] + +set_location_assignment PIN_E8 -to SDRAM_DQ[0] +set_location_assignment PIN_V12 -to SDRAM_DQ[1] +set_location_assignment PIN_D11 -to SDRAM_DQ[2] +set_location_assignment PIN_W12 -to SDRAM_DQ[3] +set_location_assignment PIN_AH13 -to SDRAM_DQ[4] +set_location_assignment PIN_D8 -to SDRAM_DQ[5] +set_location_assignment PIN_AH14 -to SDRAM_DQ[6] +set_location_assignment PIN_AF7 -to SDRAM_DQ[7] +set_location_assignment PIN_AE24 -to SDRAM_DQ[8] +set_location_assignment PIN_AD23 -to SDRAM_DQ[9] +set_location_assignment PIN_AE6 -to SDRAM_DQ[10] +set_location_assignment PIN_AE23 -to SDRAM_DQ[11] +set_location_assignment PIN_AG14 -to SDRAM_DQ[12] +set_location_assignment PIN_AD5 -to SDRAM_DQ[13] +set_location_assignment PIN_AF4 -to SDRAM_DQ[14] +set_location_assignment PIN_AH3 -to SDRAM_DQ[15] +set_location_assignment PIN_AG13 -to SDRAM_DQML +set_location_assignment PIN_AF13 -to SDRAM_DQMH + +set_location_assignment PIN_AD20 -to SDRAM_CLK +set_location_assignment PIN_AG10 -to SDRAM_CKE + +set_location_assignment PIN_AA19 -to SDRAM_nWE +set_location_assignment PIN_AA18 -to SDRAM_nCAS +set_location_assignment PIN_Y18 -to SDRAM_nCS +set_location_assignment PIN_W14 -to SDRAM_nRAS + +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM_* +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQM* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_n* +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF -to *|SDRAM_* + +#============================================================ +# I/O #2 +#============================================================ +set_location_assignment PIN_AG8 -to BTNLED[0] +set_location_assignment PIN_AH8 -to BTNLED[1] +set_location_assignment PIN_AF17 -to BTNLED[2] +set_location_assignment PIN_AE15 -to BTNLED[3] + +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to BTNLED[*] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to BTNLED[*] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to BTNLED[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to BTNLED[*] +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to BTNLED[*] + + +#============================================================ +# CLOCK +#============================================================ +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to FPGA_CLK1_50 +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to FPGA_CLK2_50 +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to FPGA_CLK3_50 +set_location_assignment PIN_V11 -to FPGA_CLK1_50 +set_location_assignment PIN_Y13 -to FPGA_CLK2_50 +set_location_assignment PIN_E11 -to FPGA_CLK3_50 + +#============================================================ +# HDMI +#============================================================ +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2C_SCL +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2C_SDA +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_I2S +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_LRCLK +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_MCLK +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_SCLK +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_CLK +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_DE +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[1] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[2] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[3] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[4] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[5] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[6] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[7] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[8] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[9] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[10] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[11] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[12] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[13] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[14] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[15] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[16] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[17] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[18] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[19] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[20] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[21] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[22] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_D[23] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_HS +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_INT +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HDMI_TX_VS +set_location_assignment PIN_U10 -to HDMI_I2C_SCL +set_location_assignment PIN_AA4 -to HDMI_I2C_SDA +set_location_assignment PIN_T13 -to HDMI_I2S +set_location_assignment PIN_T11 -to HDMI_LRCLK +set_location_assignment PIN_U11 -to HDMI_MCLK +set_location_assignment PIN_T12 -to HDMI_SCLK +set_location_assignment PIN_AG5 -to HDMI_TX_CLK +set_location_assignment PIN_AD19 -to HDMI_TX_DE +set_location_assignment PIN_AD12 -to HDMI_TX_D[0] +set_location_assignment PIN_AE12 -to HDMI_TX_D[1] +set_location_assignment PIN_W8 -to HDMI_TX_D[2] +set_location_assignment PIN_Y8 -to HDMI_TX_D[3] +set_location_assignment PIN_AD11 -to HDMI_TX_D[4] +set_location_assignment PIN_AD10 -to HDMI_TX_D[5] +set_location_assignment PIN_AE11 -to HDMI_TX_D[6] +set_location_assignment PIN_Y5 -to HDMI_TX_D[7] +set_location_assignment PIN_AF10 -to HDMI_TX_D[8] +set_location_assignment PIN_Y4 -to HDMI_TX_D[9] +set_location_assignment PIN_AE9 -to HDMI_TX_D[10] +set_location_assignment PIN_AB4 -to HDMI_TX_D[11] +set_location_assignment PIN_AE7 -to HDMI_TX_D[12] +set_location_assignment PIN_AF6 -to HDMI_TX_D[13] +set_location_assignment PIN_AF8 -to HDMI_TX_D[14] +set_location_assignment PIN_AF5 -to HDMI_TX_D[15] +set_location_assignment PIN_AE4 -to HDMI_TX_D[16] +set_location_assignment PIN_AH2 -to HDMI_TX_D[17] +set_location_assignment PIN_AH4 -to HDMI_TX_D[18] +set_location_assignment PIN_AH5 -to HDMI_TX_D[19] +set_location_assignment PIN_AH6 -to HDMI_TX_D[20] +set_location_assignment PIN_AG6 -to HDMI_TX_D[21] +set_location_assignment PIN_AF9 -to HDMI_TX_D[22] +set_location_assignment PIN_AE8 -to HDMI_TX_D[23] +set_location_assignment PIN_T8 -to HDMI_TX_HS +set_location_assignment PIN_AF11 -to HDMI_TX_INT +set_location_assignment PIN_V13 -to HDMI_TX_VS + +#============================================================ +# KEY +#============================================================ +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[1] +set_location_assignment PIN_AH17 -to KEY[0] +set_location_assignment PIN_AH16 -to KEY[1] + +#============================================================ +# LED +#============================================================ +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[1] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[2] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[3] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[4] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[5] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[6] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[7] +set_location_assignment PIN_W15 -to LED[0] +set_location_assignment PIN_AA24 -to LED[1] +set_location_assignment PIN_V16 -to LED[2] +set_location_assignment PIN_V15 -to LED[3] +set_location_assignment PIN_AF26 -to LED[4] +set_location_assignment PIN_AE26 -to LED[5] +set_location_assignment PIN_Y16 -to LED[6] +set_location_assignment PIN_AA23 -to LED[7] + +#============================================================ +# SW +#============================================================ +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[1] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[2] +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[3] +set_location_assignment PIN_Y24 -to SW[0] +set_location_assignment PIN_W24 -to SW[1] +set_location_assignment PIN_W21 -to SW[2] +set_location_assignment PIN_W20 -to SW[3] + +set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALSPIMASTER_X52_Y72_N111 -entity sys_top -to spi +set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALUART_X52_Y67_N111 -entity sys_top -to uart + +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:sys/build_id.tcl" + +set_global_assignment -name CDF_FILE jtag.cdf +set_global_assignment -name QIP_FILE sys/sys.qip + diff --git a/sys/sys_analog.tcl b/sys/sys_analog.tcl new file mode 100644 index 0000000..692043f --- /dev/null +++ b/sys/sys_analog.tcl @@ -0,0 +1,71 @@ +#============================================================ +# SDIO +#============================================================ +set_location_assignment PIN_AF25 -to SDIO_DAT[0] +set_location_assignment PIN_AF23 -to SDIO_DAT[1] +set_location_assignment PIN_AD26 -to SDIO_DAT[2] +set_location_assignment PIN_AF28 -to SDIO_DAT[3] +set_location_assignment PIN_AF27 -to SDIO_CMD +set_location_assignment PIN_AH26 -to SDIO_CLK +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDIO_* + +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDIO_* +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDIO_DAT[*] +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SDIO_CMD + +#============================================================ +# VGA +#============================================================ +set_location_assignment PIN_AE17 -to VGA_R[0] +set_location_assignment PIN_AE20 -to VGA_R[1] +set_location_assignment PIN_AF20 -to VGA_R[2] +set_location_assignment PIN_AH18 -to VGA_R[3] +set_location_assignment PIN_AH19 -to VGA_R[4] +set_location_assignment PIN_AF21 -to VGA_R[5] + +set_location_assignment PIN_AE19 -to VGA_G[0] +set_location_assignment PIN_AG15 -to VGA_G[1] +set_location_assignment PIN_AF18 -to VGA_G[2] +set_location_assignment PIN_AG18 -to VGA_G[3] +set_location_assignment PIN_AG19 -to VGA_G[4] +set_location_assignment PIN_AG20 -to VGA_G[5] + +set_location_assignment PIN_AG21 -to VGA_B[0] +set_location_assignment PIN_AA20 -to VGA_B[1] +set_location_assignment PIN_AE22 -to VGA_B[2] +set_location_assignment PIN_AF22 -to VGA_B[3] +set_location_assignment PIN_AH23 -to VGA_B[4] +set_location_assignment PIN_AH21 -to VGA_B[5] + +set_location_assignment PIN_AH22 -to VGA_HS +set_location_assignment PIN_AG24 -to VGA_VS + +set_location_assignment PIN_AH27 -to VGA_EN +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to VGA_EN + +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to VGA_* +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_* + +#============================================================ +# AUDIO +#============================================================ +set_location_assignment PIN_AC24 -to AUDIO_L +set_location_assignment PIN_AE25 -to AUDIO_R +set_location_assignment PIN_AG26 -to AUDIO_SPDIF +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to AUDIO_* +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to AUDIO_* + +#============================================================ +# I/O #1 +#============================================================ +set_location_assignment PIN_Y15 -to LED_USER +set_location_assignment PIN_AA15 -to LED_HDD +set_location_assignment PIN_AG28 -to LED_POWER + +set_location_assignment PIN_AH24 -to BTN_USER +set_location_assignment PIN_AG25 -to BTN_OSD +set_location_assignment PIN_AG23 -to BTN_RESET + +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED_* +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to BTN_* +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to BTN_* diff --git a/sys/sys_dual_sdram.tcl b/sys/sys_dual_sdram.tcl new file mode 100644 index 0000000..de9fd29 --- /dev/null +++ b/sys/sys_dual_sdram.tcl @@ -0,0 +1,53 @@ +#============================================================ +# Secondary SDRAM +#============================================================ +set_location_assignment PIN_Y15 -to SDRAM2_DQ[0] +set_location_assignment PIN_AC24 -to SDRAM2_DQ[1] +set_location_assignment PIN_AA15 -to SDRAM2_DQ[2] +set_location_assignment PIN_AD26 -to SDRAM2_DQ[3] +set_location_assignment PIN_AG28 -to SDRAM2_DQ[4] +set_location_assignment PIN_AF28 -to SDRAM2_DQ[5] +set_location_assignment PIN_AE25 -to SDRAM2_DQ[6] +set_location_assignment PIN_AF27 -to SDRAM2_DQ[7] +set_location_assignment PIN_AG26 -to SDRAM2_DQ[14] +set_location_assignment PIN_AH27 -to SDRAM2_DQ[15] + +set_location_assignment PIN_AG25 -to SDRAM2_DQ[13] +set_location_assignment PIN_AH26 -to SDRAM2_DQ[12] +set_location_assignment PIN_AH24 -to SDRAM2_DQ[11] +set_location_assignment PIN_AF25 -to SDRAM2_DQ[10] +set_location_assignment PIN_AG23 -to SDRAM2_DQ[9] +set_location_assignment PIN_AF23 -to SDRAM2_DQ[8] +set_location_assignment PIN_AG24 -to SDRAM2_A[12] +set_location_assignment PIN_AH22 -to SDRAM2_CLK +set_location_assignment PIN_AH21 -to SDRAM2_A[9] +set_location_assignment PIN_AG21 -to SDRAM2_A[11] +set_location_assignment PIN_AH23 -to SDRAM2_A[7] +set_location_assignment PIN_AA20 -to SDRAM2_A[8] +set_location_assignment PIN_AF22 -to SDRAM2_A[5] +set_location_assignment PIN_AE22 -to SDRAM2_A[6] +set_location_assignment PIN_AG20 -to SDRAM2_nWE +set_location_assignment PIN_AF21 -to SDRAM2_A[4] + +set_location_assignment PIN_AG19 -to SDRAM2_nCAS +set_location_assignment PIN_AH19 -to SDRAM2_nRAS +set_location_assignment PIN_AG18 -to SDRAM2_nCS +set_location_assignment PIN_AH18 -to SDRAM2_BA[0] +set_location_assignment PIN_AF18 -to SDRAM2_BA[1] +set_location_assignment PIN_AF20 -to SDRAM2_A[10] +set_location_assignment PIN_AG15 -to SDRAM2_A[0] +set_location_assignment PIN_AE20 -to SDRAM2_A[1] +set_location_assignment PIN_AE19 -to SDRAM2_A[2] +set_location_assignment PIN_AE17 -to SDRAM2_A[3] + +set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SDRAM2_* +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM2_* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_A* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_BA* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_DQ[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_DQM* +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM2_n* +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM2_DQ[*] +set_instance_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF -to *|SDRAM2_* + +set_global_assignment -name VERILOG_MACRO "DUAL_SDRAM=1" diff --git a/sys/sys_q13.qip b/sys/sys_q13.qip deleted file mode 100644 index 760991a..0000000 --- a/sys/sys_q13.qip +++ /dev/null @@ -1,30 +0,0 @@ -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sys_top.v ] -set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sys_top.sdc ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll/pll_0002.v ] -set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll/pll_0002.qip ] -set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) pll_hdmi_q13.qip ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg/altera_pll_reconfig_core.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pll_hdmi_cfg/altera_pll_reconfig_top.v ] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) ascal.vhd ] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) pll_hdmi_adj.vhd ] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines.v ] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_cleaner.sv ] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) video_mixer.sv ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v ] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) vga_out.sv ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2c.v ] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) alsa.sv ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) i2s.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) spdif.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) audio_out.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sigma_delta_dac.v ] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hdmi_config.sv ] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sysmem.sv ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) sd_card.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) hps_io.v ] -set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALSPIMASTER_X52_Y72_N111 -entity sys_top -to spi -set_instance_assignment -name HPS_LOCATION HPSINTERFACEPERIPHERALUART_X52_Y67_N111 -entity sys_top -to uart diff --git a/sys/sys_top.sdc b/sys/sys_top.sdc index 37720b2..c253d88 100644 --- a/sys/sys_top.sdc +++ b/sys/sys_top.sdc @@ -7,7 +7,7 @@ create_clock -period 10.0 [get_pins -compatibility_mode spi|sclk_out] -name spi_ derive_pll_clocks -create_generated_clock -source [get_pins -compatibility_mode {pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk}] \ +create_generated_clock -source [get_pins -compatibility_mode {pll_hdmi|pll_hdmi_inst|altera_pll_i|*[0].*|divclk}] \ -name HDMI_CLK [get_ports HDMI_TX_CLK] @@ -15,8 +15,8 @@ derive_clock_uncertainty # Decouple different clock groups (to simplify routing) set_clock_groups -asynchronous \ - -group [get_clocks { *|pll|pll_inst|altera_pll_i|general[*].gpll~PLL_OUTPUT_COUNTER|divclk}] \ - -group [get_clocks { pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk}] \ + -group [get_clocks { *|pll|pll_inst|altera_pll_i|*[*].*|divclk}] \ + -group [get_clocks { pll_hdmi|pll_hdmi_inst|altera_pll_i|*[0].*|divclk}] \ -group [get_clocks { *|h2f_user0_clk}] \ -group [get_clocks { FPGA_CLK1_50 FPGA_CLK2_50 FPGA_CLK3_50}] diff --git a/sys/sys_top.v b/sys/sys_top.v index 517189f..5d0a8bb 100644 --- a/sys/sys_top.v +++ b/sys/sys_top.v @@ -26,19 +26,6 @@ module sys_top input FPGA_CLK2_50, input FPGA_CLK3_50, - //////////// VGA /////////// - output [5:0] VGA_R, - output [5:0] VGA_G, - output [5:0] VGA_B, - inout VGA_HS, // VGA_HS is secondary SD card detect when VGA_EN = 1 (inactive) - output VGA_VS, - input VGA_EN, // active low - - /////////// AUDIO ////////// - output AUDIO_L, - output AUDIO_R, - output AUDIO_SPDIF, - //////////// HDMI ////////// output HDMI_I2C_SCL, inout HDMI_I2C_SDA, @@ -69,6 +56,36 @@ module sys_top output SDRAM_CLK, output SDRAM_CKE, +`ifdef DUAL_SDRAM + ////////// SDR #2 ////////// + output [12:0] SDRAM2_A, + inout [15:0] SDRAM2_DQ, + output SDRAM2_nWE, + output SDRAM2_nCAS, + output SDRAM2_nRAS, + output SDRAM2_nCS, + output [1:0] SDRAM2_BA, + output SDRAM2_CLK, + +`else + //////////// VGA /////////// + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + inout VGA_HS, // VGA_HS is secondary SD card detect when VGA_EN = 1 (inactive) + output VGA_VS, + input VGA_EN, // active low + + /////////// AUDIO ////////// + output AUDIO_L, + output AUDIO_R, + output AUDIO_SPDIF, + + //////////// SDIO /////////// + inout [3:0] SDIO_DAT, + inout SDIO_CMD, + output SDIO_CLK, + //////////// I/O /////////// output LED_USER, output LED_HDD, @@ -76,12 +93,17 @@ module sys_top input BTN_USER, input BTN_OSD, input BTN_RESET, +`endif - //////////// SDIO /////////// - inout [3:0] SDIO_DAT, - inout SDIO_CMD, - output SDIO_CLK, - input SDIO_CD, + ////////// I/O ALT ///////// + inout [3:0] BTNLED, + inout SDCD_SPDIF, + + ////////// ADC ////////////// + output ADC_SCK, + input ADC_SDO, + output ADC_SDI, + output ADC_CONVST, ////////// MB KEY /////////// input [1:0] KEY, @@ -96,11 +118,19 @@ module sys_top inout [5:0] USER_IO ); +////////////////////// Secondary SD /////////////////////////////////// -assign SDIO_DAT[2:1] = 2'bZZ; +`ifndef DUAL_SDRAM + wire SD_CS, SD_CLK, SD_MOSI, SD_MISO; + assign SDIO_DAT[2:1]= 2'bZZ; + assign SDIO_DAT[3] = SW[3] ? 1'bZ : SD_CS; + assign SDIO_CLK = SW[3] ? 1'bZ : SD_CLK; + assign SDIO_CMD = SW[3] ? 1'bZ : SD_MOSI; + assign SD_MISO = SW[3] ? 1'b1 : SDIO_DAT[0]; +`endif -////////////////////////// LEDs /////////////////////////////////////// +////////////////////// LEDs/Buttons /////////////////////////////////// reg [7:0] led_overtake = 0; reg [7:0] led_state = 0; @@ -110,15 +140,43 @@ wire led_d = led_disk[1] ? ~led_disk[0] : ~(led_disk[0] | gp_out[29]); wire led_u = ~led_user; wire led_locked; -assign LED_POWER = led_p ? 1'bZ : 1'b0; -assign LED_HDD = led_d ? 1'bZ : 1'b0; -assign LED_USER = led_u ? 1'bZ : 1'b0; +`ifndef DUAL_SDRAM + assign LED_POWER = (SW[3] | led_p) ? 1'bZ : 1'b0; + assign LED_HDD = (SW[3] | led_d) ? 1'bZ : 1'b0; + assign LED_USER = (SW[3] | led_u) ? 1'bZ : 1'b0; +`endif //LEDs on main board assign LED = (led_overtake & led_state) | (~led_overtake & {1'b0,led_locked,1'b0, ~led_p, 1'b0, ~led_d, 1'b0, ~led_u}); +reg [3:0] btnled = 3'bZZZ; +reg btn_r = 0, btn_o = 0, btn_u = 0; +always @(posedge FPGA_CLK2_50) begin + reg [12:0] cnt; + + if(SW[3]) begin + cnt <= cnt + 1'd1; + if(~&cnt[12:8]) btnled <= ~{1'b0,led_p,led_d,led_u}; + else begin + if(~cnt[7]) btnled <= 0; + else btnled <= 4'b0ZZZ; + if(&cnt) {btn_r,btn_o,btn_u} <= ~BTNLED[2:0]; + end + end + else begin + cnt <= 0; + `ifdef DUAL_SDRAM + {btn_r,btn_o,btn_u} <= 0; + btnled <= 4'bZZZZ; + `else + {btn_r,btn_o,btn_u} <= ~{BTN_RESET,BTN_OSD,BTN_USER}; + btnled <= {(~VGA_EN & sog & ~(vs1 ^ hs1)) ? 1'b1 : 1'bZ, 3'bZZZ}; + `endif + end +end + +assign BTNLED = btnled; -////////////////////////// Buttons /////////////////////////////////// reg btn_user, btn_osd; always @(posedge FPGA_CLK2_50) begin integer div; @@ -127,21 +185,18 @@ always @(posedge FPGA_CLK2_50) begin div <= div + 1'b1; if(div > 100000) div <= 0; - + if(!div) begin - deb_user <= {deb_user[6:0], ~(BTN_USER & KEY[1])}; + deb_user <= {deb_user[6:0], btn_u | ~KEY[1]}; if(&deb_user) btn_user <= 1; if(!deb_user) btn_user <= 0; - deb_osd <= {deb_osd[6:0], ~(BTN_OSD & KEY[0])}; + deb_osd <= {deb_osd[6:0], btn_o | ~KEY[0]}; if(&deb_osd) btn_osd <= 1; if(!deb_osd) btn_osd <= 0; end end -reg btn_reset = 1; -always @(posedge FPGA_CLK2_50) btn_reset <= BTN_RESET; - ///////////////////////// HPS I/O ///////////////////////////////////// @@ -150,23 +205,27 @@ always @(posedge FPGA_CLK2_50) btn_reset <= BTN_RESET; wire [31:0] gp_in = {1'b0, btn_user, btn_osd, 9'd0, io_ver, io_ack, io_wide, io_dout}; wire [31:0] gp_out; -wire [1:0] io_ver = 1; // 0 - standard MiST I/O (for quick porting of complex MiST cores). 1 - optimized HPS I/O. 2,3 - reserved for future. +wire [1:0] io_ver = 1; // 0 - standard MiST I/O (for quick porting of complex MiST cores). 1 - optimized HPS I/O. 2,3 - reserved for future. wire io_wait; wire io_wide; wire [15:0] io_dout; -wire [15:0] io_din = gp_outr[15:0]; -wire io_clk = gp_outr[17]; -wire io_fpga = gp_outr[18]; -wire io_osd = gp_outr[19]; -wire io_uio = gp_outr[20]; +wire [15:0] io_din = gp_outr[15:0]; +wire io_clk = gp_outr[17]; +wire io_ss0 = gp_outr[18]; +wire io_ss1 = gp_outr[19]; +wire io_ss2 = gp_outr[20]; //wire io_sdd = gp_outr[21]; // used only in ST core +wire io_osd_hdmi = io_ss1 & ~io_ss0; +wire io_fpga = ~io_ss1 & io_ss0; +wire io_uio = ~io_ss1 & io_ss2; + reg io_ack; reg rack; wire io_strobe = ~rack & io_clk; always @(posedge clk_sys) begin - if(~io_wait | io_strobe) begin + if(~(io_wait | vs_wait) | io_strobe) begin rack <= io_clk; io_ack <= rack; end @@ -195,12 +254,16 @@ reg [15:0] cfg; reg cfg_got = 0; reg cfg_set = 0; -//wire [2:0] hdmi_res = cfg[10:8]; +wire hdmi_limited = cfg[8]; wire dvi_mode = cfg[7]; wire audio_96k = cfg[6]; -wire ypbpr_en = cfg[5]; -wire csync = cfg[3]; -wire vga_scaler= cfg[2]; +`ifndef DUAL_SDRAM + wire sog = cfg[9]; + wire ypbpr_en = cfg[5]; + wire csync = cfg[3]; + wire vga_scaler= cfg[2]; + wire io_osd_vga= io_ss1 & ~io_ss2; +`endif reg cfg_custom_t = 0; reg [5:0] cfg_custom_p1; @@ -212,22 +275,27 @@ reg [6:0] coef_addr; reg [8:0] coef_data; reg coef_wr = 0; -wire [7:0] ARX, ARY; -reg [11:0] VSET = 0; -reg [2:0] scaler_flt; -reg lowlat = 0; +wire [7:0] ARX, ARY; +reg [11:0] VSET = 0; +reg [2:0] scaler_flt; +reg lowlat = 0; +reg cfg_dis = 0; + +reg vs_wait = 0; always@(posedge clk_sys) begin reg [7:0] cmd; reg has_cmd; reg old_strobe; reg [7:0] cnt = 0; + reg vs_d0,vs_d1,vs_d2; old_strobe <= io_strobe; coef_wr <= 0; if(~io_uio) begin has_cmd <= 0; + cmd <= 0; end else if(~old_strobe & io_strobe) begin @@ -235,6 +303,7 @@ always@(posedge clk_sys) begin has_cmd <= 1; cmd <= io_din[7:0]; cnt <= 0; + if(io_din[7:0] == 'h30) vs_wait <= 1; end else begin if(cmd == 1) begin @@ -245,15 +314,15 @@ always@(posedge clk_sys) begin cfg_set <= 0; cnt <= cnt + 1'd1; if(cnt<8) begin - case(cnt) - 0: if(WIDTH != io_din[11:0]) begin WIDTH <= io_din[11:0]; end - 1: if(HFP != io_din[11:0]) begin HFP <= io_din[11:0]; end - 2: if(HS != io_din[11:0]) begin HS <= io_din[11:0]; end - 3: if(HBP != io_din[11:0]) begin HBP <= io_din[11:0]; end - 4: if(HEIGHT != io_din[11:0]) begin HEIGHT <= io_din[11:0]; end - 5: if(VFP != io_din[11:0]) begin VFP <= io_din[11:0]; end - 6: if(VS != io_din[11:0]) begin VS <= io_din[11:0]; end - 7: if(VBP != io_din[11:0]) begin VBP <= io_din[11:0]; end + case(cnt[2:0]) + 0: if(WIDTH != io_din[11:0]) WIDTH <= io_din[11:0]; + 1: if(HFP != io_din[11:0]) HFP <= io_din[11:0]; + 2: if(HS != io_din[11:0]) HS <= io_din[11:0]; + 3: if(HBP != io_din[11:0]) HBP <= io_din[11:0]; + 4: if(HEIGHT != io_din[11:0]) HEIGHT <= io_din[11:0]; + 5: if(VFP != io_din[11:0]) VFP <= io_din[11:0]; + 6: if(VS != io_din[11:0]) VS <= io_din[11:0]; + 7: if(VBP != io_din[11:0]) VBP <= io_din[11:0]; endcase if(cnt == 1) begin cfg_custom_p1 <= 0; @@ -269,9 +338,23 @@ always@(posedge clk_sys) begin cfg_custom_t <= ~cfg_custom_t; cnt[2:0] <= 3'b100; end - if(cnt == 8) lowlat <= io_din[15]; + if(cnt == 8) {lowlat,cfg_dis} <= io_din[15:14]; end end + if(cmd == 'h2F) begin + cnt <= cnt + 1'd1; + case(cnt[3:0]) + 0: {FB_EN,FB_FLT,FB_FMT} <= {io_din[15], io_din[14], io_din[5:0]}; + 1: FB_BASE[15:0] <= io_din[15:0]; + 2: FB_BASE[31:16] <= io_din[15:0]; + 3: FB_WIDTH <= io_din[11:0]; + 4: FB_HEIGHT <= io_din[11:0]; + 5: FB_HMIN <= io_din[11:0]; + 6: FB_HMAX <= io_din[11:0]; + 7: FB_VMIN <= io_din[11:0]; + 8: FB_VMAX <= io_din[11:0]; + endcase + end if(cmd == 'h25) {led_overtake, led_state} <= io_din; if(cmd == 'h26) vol_att <= io_din[4:0]; if(cmd == 'h27) VSET <= io_din[11:0]; @@ -279,6 +362,12 @@ always@(posedge clk_sys) begin if(cmd == 'h2B) scaler_flt <= io_din[2:0]; end end + + vs_d0 <= HDMI_TX_VS; + if(vs_d0 == HDMI_TX_VS) vs_d1 <= vs_d0; + + vs_d2 <= vs_d1; + if(~vs_d2 & vs_d1) vs_wait <= 0; end always @(posedge clk_sys) begin @@ -315,6 +404,11 @@ cyclonev_hps_interface_peripheral_spi_master spi .ss_in_n(1) ); +wire [63:0] f2h_irq = {HDMI_TX_VS}; +cyclonev_hps_interface_interrupts interrupts +( + .irq(f2h_irq) +); /////////////////////////// RESET /////////////////////////////////// @@ -339,6 +433,7 @@ end wire clk_100m; wire clk_hdmi = ~HDMI_TX_CLK; // Internal HDMI clock, inverted in relation to external clock wire clk_audio = FPGA_CLK3_50; +wire clk_pal = FPGA_CLK3_50; //////////////////// SYSTEM MEMORY & SCALER ///////////////////////// @@ -351,7 +446,7 @@ sysmem_lite sysmem .clock(clk_100m), //DE10-nano has no reset signal on GPIO, so core has to emulate cold reset button. - .reset_hps_cold_req(~btn_reset), + .reset_hps_cold_req(btn_r), //64-bit DDR3 RAM access .ram1_clk(ram_clk), @@ -367,12 +462,12 @@ sysmem_lite sysmem //64-bit DDR3 RAM access .ram2_clk(clk_audio), - .ram2_address(aram_address), - .ram2_burstcount(aram_burstcount), + .ram2_address((ap_en1 == ap_en2) ? aram_address : pram_address), + .ram2_burstcount((ap_en1 == ap_en2) ? aram_burstcount : pram_burstcount), .ram2_waitrequest(aram_waitrequest), .ram2_readdata(aram_readdata), .ram2_readdatavalid(aram_readdatavalid), - .ram2_read(aram_read), + .ram2_read((ap_en1 == ap_en2) ? aram_read : pram_read), .ram2_writedata(0), .ram2_byteenable(8'hFF), .ram2_write(0), @@ -413,49 +508,60 @@ ascal .run (1), .freeze (0), - .i_clk (clk_vid), - .i_ce (ce_pix), - .i_r (r_out), - .i_g (g_out), - .i_b (b_out), - .i_hs (hs), - .i_vs (vs), - .i_fl (f1), - .i_de (de), - .iauto (1), - .himin (0), - .himax (0), - .vimin (0), - .vimax (0), + .i_clk (clk_vid), + .i_ce (ce_pix), + .i_r (r_out), + .i_g (g_out), + .i_b (b_out), + .i_hs (hs), + .i_vs (vs), + .i_fl (f1), + .i_de (de), + .iauto (1), + .himin (0), + .himax (0), + .vimin (0), + .vimax (0), - .o_clk (clk_hdmi), - .o_ce (1), - .o_r (hdmi_data[23:16]), - .o_g (hdmi_data[15:8]), - .o_b (hdmi_data[7:0]), - .o_hs (HDMI_TX_HS), - .o_vs (HDMI_TX_VS), - .o_de (hdmi_de), + .o_clk (clk_hdmi), + .o_ce (1), + .o_r (hdmi_data[23:16]), + .o_g (hdmi_data[15:8]), + .o_b (hdmi_data[7:0]), + .o_hs (HDMI_TX_HS), + .o_vs (HDMI_TX_VS), + .o_de (hdmi_de), .o_lltune (lltune), - .htotal (WIDTH+HFP+HBP+HS), - .hsstart(WIDTH + HFP), - .hsend (WIDTH + HFP + HS), - .hdisp (WIDTH), - .hmin (hmin), - .hmax (hmax), - .vtotal (HEIGHT+VFP+VBP+VS), - .vsstart(HEIGHT + VFP), - .vsend (HEIGHT + VFP + VS), - .vdisp (HEIGHT), - .vmin (vmin), - .vmax (vmax), + .htotal (WIDTH + HFP + HBP + HS), + .hsstart (WIDTH + HFP), + .hsend (WIDTH + HFP + HS), + .hdisp (WIDTH), + .hmin (hmin), + .hmax (hmax), + .vtotal (HEIGHT + VFP + VBP + VS), + .vsstart (HEIGHT + VFP), + .vsend (HEIGHT + VFP + VS), + .vdisp (HEIGHT), + .vmin (vmin), + .vmax (vmax), - .mode ({~lowlat,|scaler_flt,2'b00}), + .mode ({~lowlat,FB_EN ? FB_FLT : |scaler_flt,2'b00}), .poly_clk (clk_sys), .poly_a (coef_addr), .poly_dw (coef_data), .poly_wr (coef_wr), + .pal_clk (clk_pal), + .pal_dw (pal_d), + .pal_a (pal_a), + .pal_wr (pal_wr), + + .o_fb_ena (FB_EN), + .o_fb_hsize (FB_WIDTH), + .o_fb_vsize (FB_HEIGHT), + .o_fb_format (FB_FMT), + .o_fb_base (FB_BASE), + .avl_clk (clk_100m), .avl_waitrequest (vbuf_waitrequest), .avl_readdata (vbuf_readdata), @@ -468,6 +574,17 @@ ascal .avl_byteenable (vbuf_byteenable) ); +reg FB_EN = 0; +reg FB_FLT = 0; +reg [5:0] FB_FMT = 0; +reg [11:0] FB_WIDTH = 0; +reg [11:0] FB_HEIGHT = 0; +reg [11:0] FB_HMIN = 0; +reg [11:0] FB_HMAX = 0; +reg [11:0] FB_VMIN = 0; +reg [11:0] FB_VMAX = 0; +reg [31:0] FB_BASE = 0; + reg [11:0] hmin; reg [11:0] hmax; reg [11:0] vmin; @@ -479,13 +596,29 @@ always @(posedge clk_vid) begin reg [2:0] state; reg [11:0] videow; reg [11:0] videoh; - + state <= state + 1'd1; case(state) - 0: begin + 0: if(FB_EN) begin + hmin <= FB_HMIN; + vmin <= FB_VMIN; + hmax <= FB_HMAX; + vmax <= FB_VMAX; + state<= 0; + end + else if(ARX && ARY) begin wcalc <= VSET ? (VSET*ARX)/ARY : (HEIGHT*ARX)/ARY; hcalc <= (WIDTH*ARY)/ARX; end + else begin + hmin <= 0; + hmax <= WIDTH - 1'd1; + vmin <= 0; + vmax <= HEIGHT - 1'd1; + wcalc<= WIDTH; + hcalc<= HEIGHT; + state<= 0; + end 6: begin videow <= (!VSET && (wcalc > WIDTH)) ? WIDTH : wcalc[11:0]; videoh <= VSET ? VSET : (hcalc > HEIGHT) ? HEIGHT : hcalc[11:0]; @@ -507,7 +640,7 @@ pll_hdmi_adj pll_hdmi_adj .reset_na(~reset_req), .llena(lowlat), - .lltune(lltune), + .lltune({16{hdmi_config_done | cfg_dis}} & lltune), .locked(led_locked), .i_waitrequest(adj_waitrequest), .i_write(adj_write), @@ -519,6 +652,38 @@ pll_hdmi_adj pll_hdmi_adj .o_writedata(cfg_data) ); +wire [23:0] pal_d; +wire [7:0] pal_a; +wire pal_wr; + +wire ap_en1, ap_en2; + +wire [28:0] pram_address; +wire [7:0] pram_burstcount; +wire pram_read; + +fbpal fbpal +( + .reset(reset), + .en_in(ap_en2), + .en_out(ap_en1), + + .ram_clk(clk_pal), + .ram_address(pram_address), + .ram_burstcount(pram_burstcount), + .ram_waitrequest(aram_waitrequest), + .ram_readdata(aram_readdata), + .ram_readdatavalid(aram_readdatavalid), + .ram_read(pram_read), + + .fb_address(FB_BASE), + + .pal_en(~FB_FMT[2] & FB_FMT[1] & FB_FMT[0] & FB_EN), + .pal_a(pal_a), + .pal_d(pal_d), + .pal_wr(pal_wr) +); + ///////////////////////// HDMI output ///////////////////////////////// @@ -551,7 +716,7 @@ reg adj_write; reg [5:0] adj_address; reg [31:0] adj_data; -pll_hdmi_cfg pll_hdmi_cfg +pll_cfg pll_cfg ( .mgmt_clk(FPGA_CLK1_50), .mgmt_reset(reset_req), @@ -595,16 +760,19 @@ always @(posedge FPGA_CLK1_50) begin if(old_wait & ~adj_waitrequest & gotd) cfg_ready <= 1; end +wire hdmi_config_done; hdmi_config hdmi_config ( .iCLK(FPGA_CLK1_50), - .iRST_N(cfg_ready & ~HDMI_TX_INT), + .iRST_N(cfg_ready & ~HDMI_TX_INT & ~cfg_dis), + .done(hdmi_config_done), .I2C_SCL(HDMI_I2C_SCL), .I2C_SDA(HDMI_I2C_SDA), .dvi_mode(dvi_mode), - .audio_96k(audio_96k) + .audio_96k(audio_96k), + .hdmi_limited(hdmi_limited) ); wire [23:0] hdmi_data; @@ -626,7 +794,7 @@ osd hdmi_osd ( .clk_sys(clk_sys), - .io_osd(io_osd), + .io_osd(io_osd_hdmi), .io_strobe(io_strobe), .io_din(io_din), @@ -641,59 +809,66 @@ osd hdmi_osd ///////////////////////// VGA output ////////////////////////////////// -wire [23:0] vga_data_sl; +`ifndef DUAL_SDRAM + wire [23:0] vga_data_sl; -scanlines #(0) VGA_scanlines -( - .clk(clk_vid), + scanlines #(0) VGA_scanlines + ( + .clk(clk_vid), - .scanlines(scanlines), - .din(de ? {r_out, g_out, b_out} : 24'd0), - .dout(vga_data_sl), - .hs(hs1), - .vs(vs1) -); + .scanlines(scanlines), + .din(de ? {r_out, g_out, b_out} : 24'd0), + .dout(vga_data_sl), + .hs(hs1), + .vs(vs1) + ); -osd vga_osd -( - .clk_sys(clk_sys), + osd vga_osd + ( + .clk_sys(clk_sys), - .io_osd(io_osd), - .io_strobe(io_strobe), - .io_din(io_din), + .io_osd(io_osd_vga), + .io_strobe(io_strobe), + .io_din(io_din), - .clk_video(clk_vid), - .din(vga_data_sl), - .dout(vga_q), - .de_in(de) -); + .clk_video(clk_vid), + .din(vga_data_sl), + .dout(vga_q), + .de_in(de) + ); -wire [23:0] vga_q; -wire [23:0] vga_o; + wire [23:0] vga_q; + wire [23:0] vga_o; -vga_out vga_out -( - .ypbpr_full(1), - .ypbpr_en(ypbpr_en), - .dout(vga_o), - .din(vga_scaler ? {24{HDMI_TX_DE}} & HDMI_TX_D : vga_q) -); + vga_out vga_out + ( + .ypbpr_full(1), + .ypbpr_en(ypbpr_en), + .dout(vga_o), + .din(vga_scaler ? {24{HDMI_TX_DE}} & HDMI_TX_D : vga_q) + ); -wire vs1 = vga_scaler ? HDMI_TX_VS : vs; -wire hs1 = vga_scaler ? HDMI_TX_HS : hs; - -assign VGA_VS = VGA_EN ? 1'bZ : csync ? 1'b1 : ~vs1; -assign VGA_HS = VGA_EN ? 1'bZ : csync ? ~(vs1 ^ hs1) : ~hs1; -assign VGA_R = VGA_EN ? 6'bZZZZZZ : vga_o[23:18]; -assign VGA_G = VGA_EN ? 6'bZZZZZZ : vga_o[15:10]; -assign VGA_B = VGA_EN ? 6'bZZZZZZ : vga_o[7:2]; + wire vs1 = vga_scaler ? HDMI_TX_VS : vs; + wire hs1 = vga_scaler ? HDMI_TX_HS : hs; + assign VGA_VS = (VGA_EN | SW[3]) ? 1'bZ : csync ? 1'b1 : ~vs1; + assign VGA_HS = (VGA_EN | SW[3]) ? 1'bZ : csync ? ~(vs1 ^ hs1) : ~hs1; + assign VGA_R = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[23:18]; + assign VGA_G = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[15:10]; + assign VGA_B = (VGA_EN | SW[3]) ? 6'bZZZZZZ : vga_o[7:2]; +`endif ///////////////////////// Audio output //////////////////////////////// -assign AUDIO_SPDIF = SW[0] ? HDMI_LRCLK : spdif; -assign AUDIO_R = SW[0] ? HDMI_I2S : anr; -assign AUDIO_L = SW[0] ? HDMI_SCLK : anl; +assign SDCD_SPDIF =(SW[3] & spdif) ? 1'b0 : 1'bZ; + +`ifndef DUAL_SDRAM + wire anl,anr; + + assign AUDIO_SPDIF = SW[3] ? 1'bZ : SW[0] ? HDMI_LRCLK : spdif; + assign AUDIO_R = SW[3] ? 1'bZ : SW[0] ? HDMI_I2S : anr; + assign AUDIO_L = SW[3] ? 1'bZ : SW[0] ? HDMI_SCLK : anl; +`endif assign HDMI_MCLK = 0; @@ -729,7 +904,7 @@ aud_mix_top audmix_r .out(audio_r) ); -wire anl,anr,spdif; +wire spdif; audio_out audio_out ( .reset(reset), @@ -740,9 +915,11 @@ audio_out audio_out .i2s_bclk(HDMI_SCLK), .i2s_lrclk(HDMI_LRCLK), .i2s_data(HDMI_I2S), - .spdif(spdif), +`ifndef DUAL_SDRAM .dac_l(anl), - .dac_r(anr) + .dac_r(anr), +`endif + .spdif(spdif) ); wire [28:0] aram_address; @@ -757,6 +934,8 @@ wire [15:0] alsa_l, alsa_r; alsa alsa ( .reset(reset), + .en_in(ap_en1), + .en_out(ap_en2), .ram_clk(clk_audio), .ram_address(aram_address), @@ -835,7 +1014,7 @@ emu emu ( .CLK_50M(FPGA_CLK3_50), .RESET(reset), - .HPS_BUS({HDMI_TX_VS, clk_100m, clk_vid, ce_pix, de, hs, vs, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}), + .HPS_BUS({f1, HDMI_TX_VS, clk_100m, clk_vid, ce_pix, de, hs, vs, io_wait, clk_sys, io_fpga, io_uio, io_strobe, io_wide, io_din, io_dout}), .CLK_VIDEO(clk_vid), .CE_PIXEL(ce_pix), @@ -860,13 +1039,8 @@ emu emu .AUDIO_R(audio_rs), .AUDIO_S(audio_s), .AUDIO_MIX(audio_mix), - .TAPE_IN(0), - .SD_SCK(SDIO_CLK), - .SD_MOSI(SDIO_CMD), - .SD_MISO(SDIO_DAT[0]), - .SD_CS(SDIO_DAT[3]), - .SD_CD(VGA_EN ? VGA_HS : SDIO_CD), + .ADC_BUS({ADC_SCK,ADC_SDO,ADC_SDI,ADC_CONVST}), .DDRAM_CLK(ram_clk), .DDRAM_ADDR(ram_address), @@ -891,6 +1065,24 @@ emu emu .SDRAM_CLK(SDRAM_CLK), .SDRAM_CKE(SDRAM_CKE), +`ifdef DUAL_SDRAM + .SDRAM2_DQ(SDRAM2_DQ), + .SDRAM2_A(SDRAM2_A), + .SDRAM2_BA(SDRAM2_BA), + .SDRAM2_nCS(SDRAM2_nCS), + .SDRAM2_nWE(SDRAM2_nWE), + .SDRAM2_nRAS(SDRAM2_nRAS), + .SDRAM2_nCAS(SDRAM2_nCAS), + .SDRAM2_CLK(SDRAM2_CLK), + .SDRAM2_EN(SW[3]), +`else + .SD_SCK(SD_CLK), + .SD_MOSI(SD_MOSI), + .SD_MISO(SD_MISO), + .SD_CS(SD_CS), + .SD_CD(SW[0] ? VGA_HS : SW[3] ? 1'b1 : SDCD_SPDIF ), +`endif + .UART_CTS(uart_rts), .UART_RTS(uart_cts), .UART_RXD(uart_txd),