From 6ae0f8d4f14fdfa98ae3ed17ea9470b26fe72b86 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Sat, 9 Mar 2019 05:31:23 +0800 Subject: [PATCH] Update sys. --- MacPlus-lite.qsf | 376 --- MacPlus-lite.srf | 16 - MacPlus.qpf | 1 - MacPlus.qsf | 42 +- MacPlus.sv | 27 +- sdram.qip | 2 + sdram.sdc | 17 + sys/alsa.sv | 128 + sys/ascal.vhd | 2312 +++++++++++++++++ sys/audio_out.v | 157 ++ sys/hdmi_config.sv | 4 +- sys/hdmi_lite.sv | 395 --- sys/hps_io.v | 158 +- sys/hq2x.sv | 183 +- sys/i2s.v | 190 +- sys/ip/avalon_combiner.v | 60 - sys/ip/avalon_combiner_hw.tcl | 204 -- sys/ip/de10_hps_hw.tcl | 3706 ---------------------------- sys/ip/in_split.v | 52 - sys/ip/in_split_hw.tcl | 104 - sys/ip/out_mix.v | 44 - sys/ip/out_mix_hw.tcl | 97 - sys/ip/reset_source.v | 50 - sys/ip/reset_source_hw.tcl | 152 -- sys/lpf48k.sv | 100 - sys/osd.v | 130 +- sys/pattern_vg.v | 120 - sys/pll_hdmi/pll_hdmi_0002_q13.qip | 4 + sys/pll_hdmi_adj.vhd | 360 +++ sys/pll_hdmi_q13.qip | 13 + sys/scandoubler.v | 181 +- sys/scanlines.v | 52 + sys/sd_card.v | 538 ++++ sys/spdif.v | 126 - sys/sync_vg.v | 78 - sys/sys.qip | 49 +- sys/sys_q13.qip | 30 + sys/sys_top.sdc | 25 +- sys/sys_top.v | 1934 ++++++++------- sys/sysmem.sv | 948 ++++--- sys/video_cleaner.sv | 91 + sys/video_mixer.sv | 2 +- sys/vip.qsys | 1177 --------- sys/vip_config.sv | 159 -- 44 files changed, 5585 insertions(+), 9009 deletions(-) delete mode 100644 MacPlus-lite.qsf delete mode 100644 MacPlus-lite.srf create mode 100644 sdram.qip create mode 100644 sdram.sdc create mode 100644 sys/alsa.sv create mode 100644 sys/ascal.vhd create mode 100644 sys/audio_out.v delete mode 100644 sys/hdmi_lite.sv delete mode 100644 sys/ip/avalon_combiner.v delete mode 100644 sys/ip/avalon_combiner_hw.tcl delete mode 100644 sys/ip/de10_hps_hw.tcl delete mode 100644 sys/ip/in_split.v delete mode 100644 sys/ip/in_split_hw.tcl delete mode 100644 sys/ip/out_mix.v delete mode 100644 sys/ip/out_mix_hw.tcl delete mode 100644 sys/ip/reset_source.v delete mode 100644 sys/ip/reset_source_hw.tcl delete mode 100644 sys/lpf48k.sv delete mode 100644 sys/pattern_vg.v create mode 100644 sys/pll_hdmi/pll_hdmi_0002_q13.qip create mode 100644 sys/pll_hdmi_adj.vhd create mode 100644 sys/pll_hdmi_q13.qip create mode 100644 sys/scanlines.v create mode 100644 sys/sd_card.v delete mode 100644 sys/sync_vg.v create mode 100644 sys/sys_q13.qip create mode 100644 sys/video_cleaner.sv delete mode 100644 sys/vip.qsys delete mode 100644 sys/vip_config.sv diff --git a/MacPlus-lite.qsf b/MacPlus-lite.qsf deleted file mode 100644 index d65ff77..0000000 --- a/MacPlus-lite.qsf +++ /dev/null @@ -1,376 +0,0 @@ -# -------------------------------------------------------------------------- # -# -# 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 16.1.2 Build 203 01/18/2017 SJ Standard Edition -# Date created = 01:53:32 April 20, 2017 -# -# -------------------------------------------------------------------------- # - -set_global_assignment -name VERILOG_MACRO "LITE=1" - -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 LAST_QUARTUS_VERSION "17.0.1 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" -set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" -set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF -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 BALANCED -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_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[3] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[7] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[8] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[9] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[10] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[11] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[12] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[13] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[14] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[15] -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_location_assignment PIN_AF15 -to ARDUINO_IO[10] -set_location_assignment PIN_AG16 -to ARDUINO_IO[11] -set_location_assignment PIN_AH11 -to ARDUINO_IO[12] -set_location_assignment PIN_AH12 -to ARDUINO_IO[13] -set_location_assignment PIN_AH9 -to ARDUINO_IO[14] -set_location_assignment PIN_AG11 -to ARDUINO_IO[15] - -#============================================================ -# 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 SYSTEMVERILOG_FILE sdram.sv -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 -set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/MacPlus-lite.srf b/MacPlus-lite.srf deleted file mode 100644 index 8aa3b1b..0000000 --- a/MacPlus-lite.srf +++ /dev/null @@ -1,16 +0,0 @@ -{ "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_kbd_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "Inferred RAM node \"emu:emu\|mister_io:mister_io\|ps2_mouse_fifo_rtl_0\" from synchronous design logic. Pass-through logic has been added to match the read-during-write behavior of the original design." { } { } 0 276020 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "Synthesized away node \"emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|outclk_wire\[2\]\"" { } { } 0 14320 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[1\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[0\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "Ignored locations or region assignments to the following nodes" { } { } 0 15705 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "RST port on the PLL is not properly connected on instance emu:emu\|pll:pll\|pll_0002:pll_inst\|altera_pll:altera_pll_i\|general\[2\].gpll. The reset port on the PLL should be connected. If the PLL loses lock for any reason, you might need to manually reset the PLL in order to re-establish lock to the reference clock." { } { } 0 0 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "Verilog HDL or VHDL warning at de10_top.v(129): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "Verilog HDL or VHDL warning at de10_top.v(134): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "Verilog HDL or VHDL warning at de10_top.v(97): object \"io_win\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "Verilog HDL or VHDL warning at de10_top.v(102): object \"io_sdd\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details" { } { } 0 15714 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "LOCKED port on the PLL is not properly connected on instance \"pll_hdmi:pll_hdmi\|pll_hdmi_0002:pll_hdmi_inst\|altera_pll:altera_pll_i\|general\[0\].gpll\". The LOCKED port on the PLL should be connected when the FBOUTCLK port is connected. Although it is unnecessary to connect the LOCKED signal, any logic driven off of an output clock of the PLL will not know when the PLL is locked and ready." { } { } 0 21300 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "*" { } { } 0 21074 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "RST" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} -{ "" "" "" "sysmem_HPS_fpga_interfaces.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} diff --git a/MacPlus.qpf b/MacPlus.qpf index 9acc2d2..300eb86 100644 --- a/MacPlus.qpf +++ b/MacPlus.qpf @@ -29,4 +29,3 @@ DATE = "04:04:47 October 16, 2017" # Revisions PROJECT_REVISION = "MacPlus" -PROJECT_REVISION = "MacPlus-lite" diff --git a/MacPlus.qsf b/MacPlus.qsf index 8fdae3e..8a6fcc8 100644 --- a/MacPlus.qsf +++ b/MacPlus.qsf @@ -27,7 +27,7 @@ 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 LAST_QUARTUS_VERSION "17.0.1 Standard Edition" +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 @@ -50,6 +50,8 @@ 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 OPTIMIZATION_TECHNIQUE SPEED +set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON set_global_assignment -name SEED 1 #============================================================ @@ -67,19 +69,6 @@ set_location_assignment PIN_AD4 -to ADC_SDO #============================================================ # ARDUINO #============================================================ -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[3] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[7] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[8] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[9] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[10] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[11] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[12] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[13] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[14] -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to ARDUINO_IO[15] 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] @@ -87,12 +76,22 @@ 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_location_assignment PIN_AF15 -to ARDUINO_IO[10] -set_location_assignment PIN_AG16 -to ARDUINO_IO[11] -set_location_assignment PIN_AH11 -to ARDUINO_IO[12] -set_location_assignment PIN_AH12 -to ARDUINO_IO[13] -set_location_assignment PIN_AH9 -to ARDUINO_IO[14] -set_location_assignment PIN_AG11 -to ARDUINO_IO[15] +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 @@ -353,8 +352,7 @@ 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 QSYS_FILE sys/vip.qsys -set_global_assignment -name SYSTEMVERILOG_FILE sdram.sv +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 diff --git a/MacPlus.sv b/MacPlus.sv index 07c8375..8281b58 100644 --- a/MacPlus.sv +++ b/MacPlus.sv @@ -48,6 +48,8 @@ module emu output VGA_HS, output VGA_VS, output VGA_DE, // = ~(VBlank | HBlank) + output VGA_F1, + output [1:0] VGA_SL, output LED_USER, // 1 - ON, 0 - OFF. @@ -94,9 +96,28 @@ module emu output SDRAM_nCS, output SDRAM_nCAS, output SDRAM_nRAS, - output SDRAM_nWE + output SDRAM_nWE, + + input UART_CTS, + output UART_RTS, + input UART_RXD, + output UART_TXD, + output UART_DTR, + input UART_DSR, + + // Open-drain User port. + // 0 - D+/RX + // 1 - D-/TX + // 2..5 - USR1..USR4 + // Set USER_OUT to 1 to read from USER_IN. + input [5:0] USER_IN, + output [5:0] USER_OUT, + + input OSD_STATUS ); +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; assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; @@ -121,7 +142,7 @@ localparam CONF_STR = { "O5,Speed,Normal,Turbo;", "-;", "R6,Reset;", - "V,v1.00.",`BUILD_DATE + "V,v",`BUILD_DATE }; //////////////////// CLOCKS /////////////////// @@ -284,6 +305,8 @@ assign VGA_G = {8{pixelOut}}; assign VGA_B = {8{pixelOut}}; assign CLK_VIDEO = clk_sys; assign CE_PIXEL = cepix; +assign VGA_F1 = 0; +assign VGA_SL = 0; wire screenWrite; always @(*) begin diff --git a/sdram.qip b/sdram.qip new file mode 100644 index 0000000..5677c08 --- /dev/null +++ b/sdram.qip @@ -0,0 +1,2 @@ +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) sdram.sv ] +set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) sdram.sdc ] diff --git a/sdram.sdc b/sdram.sdc new file mode 100644 index 0000000..d50310e --- /dev/null +++ b/sdram.sdc @@ -0,0 +1,17 @@ +derive_pll_clocks + +create_generated_clock -source [get_pins -compatibility_mode {*|pll|pll_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk}] \ + -name SDRAM_CLK [get_ports {SDRAM_CLK}] + +derive_clock_uncertainty + +# Set acceptable delays for SDRAM chip (See correspondent chip datasheet) +set_input_delay -max -clock SDRAM_CLK 6.4ns [get_ports SDRAM_DQ[*]] +set_input_delay -min -clock SDRAM_CLK 3.7ns [get_ports SDRAM_DQ[*]] + +set_multicycle_path -from [get_clocks {SDRAM_CLK}] \ + -to [get_clocks {*|pll|pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] \ + -setup 2 + +set_output_delay -max -clock SDRAM_CLK 1.6ns [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] +set_output_delay -min -clock SDRAM_CLK -0.9ns [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] diff --git a/sys/alsa.sv b/sys/alsa.sv new file mode 100644 index 0000000..9ed448e --- /dev/null +++ b/sys/alsa.sv @@ -0,0 +1,128 @@ +//============================================================================ +// +// ALSA sound 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 alsa +( + input reset, + + 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 spi_ss, + input spi_sck, + input spi_mosi, + + output reg [15:0] pcm_l, + output reg [15:0] pcm_r +); + +reg spi_new = 0; +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}; + + spicnt <= spicnt + 1'd1; + if(&spicnt[2:0]) begin + spi_data[{spicnt[6:3],3'b000} +:8] <= {mosi[6:0],spi_mosi}; + spi_new <= &spicnt; + end + end +end + +reg [31:0] buf_addr; +reg [31:0] buf_len; +reg [31:0] buf_wptr = 0; + +always @(posedge ram_clk) begin + reg n1,n2,n3; + reg [127:0] data1,data2; + + 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 + +reg [31:0] buf_rptr = 0; +always @(posedge ram_clk) begin + reg got_first = 0; + reg ready = 0; + reg ud; + reg [31:0] readdata; + + if(~ram_waitrequest) ram_read <= 0; + if(ram_readdatavalid && ram_burstcount) begin + ram_burstcount <= 0; + ready <= 1; + readdata <= ud ? ram_readdata[63:32] : ram_readdata[31:0]; + if(buf_rptr[31:2] >= buf_len[31:2]) buf_rptr <= 0; + end + + if(reset) {ready, got_first} <= 0; + else + if(buf_rptr[31:2] != buf_wptr[31:2]) begin + if(~got_first) begin + buf_rptr <= buf_wptr; + got_first <= 1; + end + else + if(!ram_burstcount && ~ram_waitrequest && ~ready) begin + ram_address <= buf_addr[31:3] + buf_rptr[31:3]; + ud <= buf_rptr[2]; + ram_burstcount <= 1; + ram_read <= 1; + buf_rptr <= buf_rptr + 4; + end + end + + if(ready & ce_48k) begin + {pcm_r,pcm_l} <= readdata; + ready <= 0; + end +end + +reg ce_48k; +always @(posedge ram_clk) begin + reg [15:0] acc = 0; + + ce_48k <= 0; + acc <= acc + 16'd48; + if(acc >= 50000) begin + acc <= acc - 16'd50000; + ce_48k <= 1; + end +end + +endmodule diff --git a/sys/ascal.vhd b/sys/ascal.vhd new file mode 100644 index 0000000..651ee6d --- /dev/null +++ b/sys/ascal.vhd @@ -0,0 +1,2312 @@ +-------------------------------------------------------------------------------- +-- AVALON SCALER +-------------------------------------------------------------------------------- +-- TEMLIB 10/2018 +-------------------------------------------------------------------------------- +-- This code can be freely distributed and used for any purpose, but, if you +-- find any bug, or want to suggest an enhancement, you ought to send a mail +-- to info@temlib.org. +-------------------------------------------------------------------------------- + +-- Features : +-- - Arbitrary output video format +-- - Autodetect input image size or fixed window +-- - Progressive and interlaced input +-- - Interpolation +-- Upscaling : Nearest, Bilinear, Sharp Bilinear, Bicubic, Polyphase +-- Downscaling : Nearest, Bilinear +-- - Avalon bus interface with 128 or 64 bits DATA +-- - Optional triple buffering +-- - Support for external low lag syntonization + +-------------------------------------------- +-- Downscaling +-- - Horizontal and vertical up-/down-scaling are independant. +-- - Downscaling, H and/or V, supports only nearest-neighbour and bilinear +-- filtering. +-- - For interlaced video, when the vertical size is lower than a deinterlaced +-- frame size (2x half-frame), the scaler processes only half-frames +-- and upscales (when the output size is between 1x an 2x) or downscales (size +-- below 1x) them. + +-------------------------------------------- +-- 4 asynchronous clock domains : +-- i_xxx : Input video +-- o_xxx : Output video +-- avl_xxx : Avalon memory bus +-- poly_xxx : Polyphase filters memory + +-------------------------------------------- +-- Mode 24bits + +-------------------------------------------- +-- Image header. When HEADER = TRUE +-- Header Address = RAMBASE +-- Image Address = RAMBASE + HEADER_SIZE + +-- Header (Bytes. Big Endian.) +-- 0 : Type = 1 +-- 1 : Pixel format +-- 1 : 24 bits/pixel, packed RGB. Big Endian + +-- 3:2 : Header size : Offset to start of picture (= N_BURST). 12 bits +-- 5:4 : Attributes. TBD +-- b0 ; Interlaced +-- b1 : Field number +-- b2 : Horizontal downscaled +-- b3 : Vertical downscaled +-- b4 : Triple buffered +-- b7-5 : Frame counter +-- 7:6 : Image width. Pixels. 12 bits +-- 9:8 : Image height. Pixels. 12 bits +-- 11:10 : Line length. Bytes. +-- 13:12 : Output width. Pixels. 12 bits +-- 15:14 : Output height. Pixels. 12 bits +-------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +-- MODE[2:0] +-- 000 : Nearest +-- 001 : Bilinear +-- 010 : Sharp Bilinear +-- 011 : Bicubic +-- 100 : Polyphase +-- 101 : TBD +-- 110 : TBD +-- 111 : TEST + +-- MODE[3] +-- 0 : Direct. Single framebuffer. +-- 1 : Triple buffering + +-- MODE[4] : TBD + +-- MASK : Enable / Disable selected interpoler +-- 0:Nearest 1:Bilinear 2:SharpBilinear 3:Bicubic 4:Polyphase +-- RAMBASE : RAM base address for framebuffer +-- RAMSIZE : RAM allocated for one framebuffer (needs x3 if triple-buffering) +-- Must be a power of two +-- INTER : True=Autodetect interlaced video False=Force progressive scan +-- HEADER : True=Add image properties header +-- 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. +-- (Used for sizing line buffers) +-- N_DW : Avalon data bus width. 64 or 128 bits +-- N_AW : Avalon address bus width +-- N_BURST : Burst size in bytes. Power of two. + +ENTITY ascal IS + GENERIC ( + MASK : unsigned(7 DOWNTO 0) :=x"FF"; + RAMBASE : unsigned(31 DOWNTO 0); + RAMSIZE : unsigned(31 DOWNTO 0) := x"0080_0000"; -- =8MB + INTER : boolean := true; + HEADER : boolean := true; + DOWNSCALE : boolean := true; + BYTESWAP : 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; + N_AW : natural RANGE 8 TO 32 := 32; + N_BURST : natural := 256 -- 256 bytes per burst + ); + PORT ( + ------------------------------------ + -- Input video + i_r : IN unsigned(7 DOWNTO 0); + i_g : IN unsigned(7 DOWNTO 0); + i_b : IN unsigned(7 DOWNTO 0); + i_hs : IN std_logic; -- H sync + i_vs : IN std_logic; -- V sync + i_fl : IN std_logic; -- Interlaced field + i_de : IN std_logic; -- Display Enable + i_ce : IN std_logic; -- Clock Enable + i_clk : IN std_logic; -- Input clock + + ------------------------------------ + -- Output video + o_r : OUT unsigned(7 DOWNTO 0); + o_g : OUT unsigned(7 DOWNTO 0); + o_b : OUT unsigned(7 DOWNTO 0); + o_hs : OUT std_logic; -- H sync + o_vs : OUT std_logic; -- V sync + o_de : OUT std_logic; -- Display Enable + o_ce : IN std_logic; -- Clock Enable + o_clk : IN std_logic; -- Output clock + + ------------------------------------ + -- Low lag PLL tuning + o_lltune : OUT unsigned(15 DOWNTO 0); + + ------------------------------------ + -- Input video parameters + iauto : IN std_logic; -- 1=Autodetect image size 0=Choose window + himin : IN natural RANGE 0 TO 4095; -- MIN < MAX, MIN >=0, MAX < DISP + himax : IN natural RANGE 0 TO 4095; + vimin : IN natural RANGE 0 TO 4095; + 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 + mode : IN unsigned(4 DOWNTO 0); + -- 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; + hdisp : IN natural RANGE 0 TO 4095; + hmin : IN natural RANGE 0 TO 4095; + hmax : IN natural RANGE 0 TO 4095; -- 0 <= hmin < hmax < hdisp + vtotal : IN natural RANGE 0 TO 4095; + vsstart : IN natural RANGE 0 TO 4095; + vsend : IN natural RANGE 0 TO 4095; + vdisp : IN natural RANGE 0 TO 4095; + vmin : IN natural RANGE 0 TO 4095; + vmax : IN natural RANGE 0 TO 4095; -- 0 <= vmin < vmax < vdisp + + ------------------------------------ + -- Polyphase filter coefficients + -- Order : + -- [Horizontal] [Vertical] + -- [0]...[2**FRAC-1] + -- [-1][0][1][2] + poly_clk : IN std_logic; + poly_dw : IN unsigned(8 DOWNTO 0); + poly_a : IN unsigned(FRAC+2 DOWNTO 0); + poly_wr : IN std_logic; + + ------------------------------------ + -- Avalon + avl_clk : IN std_logic; -- Avalon clock + avl_waitrequest : IN std_logic; + avl_readdata : IN std_logic_vector(N_DW-1 DOWNTO 0); + avl_readdatavalid : IN std_logic; + avl_burstcount : OUT std_logic_vector(7 DOWNTO 0); + avl_writedata : OUT std_logic_vector(N_DW-1 DOWNTO 0); + avl_address : OUT std_logic_vector(N_AW-1 DOWNTO 0); + 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 + ); + +BEGIN + ASSERT N_DW=64 OR N_DW=128 REPORT "DW" SEVERITY failure; + +END ENTITY ascal; + +--############################################################################## + +ARCHITECTURE rtl OF ascal IS + + CONSTANT MASK_NEAREST : natural :=0; + CONSTANT MASK_BILINEAR : natural :=1; + CONSTANT MASK_SHARP_BILINEAR : natural :=2; + CONSTANT MASK_BICUBIC : natural :=3; + CONSTANT MASK_POLY : natural :=4; + + ---------------------------------------------------------- + FUNCTION ilog2 (CONSTANT v : natural) RETURN natural IS + VARIABLE r : natural := 1; + VARIABLE n : natural := 0; + BEGIN + WHILE v>r LOOP + n:=n+1; + r:=r*2; + END LOOP; + RETURN n; + END FUNCTION ilog2; + FUNCTION to_std_logic (a : boolean) RETURN std_logic IS + BEGIN + IF a THEN RETURN '1'; + ELSE RETURN '0'; + END IF; + END FUNCTION to_std_logic; + + ---------------------------------------------------------- + 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); + + TYPE type_pix IS RECORD + r,g,b : unsigned(7 DOWNTO 0); -- 0.8 + END RECORD; + TYPE arr_pix IS ARRAY (natural RANGE <>) OF type_pix; + ATTRIBUTE ramstyle : string; + + SUBTYPE uint12 IS natural RANGE 0 TO 4095; + SUBTYPE uint13 IS natural RANGE 0 TO 8191; + + ---------------------------------------------------------- + -- Input image + SIGNAL i_pvs,i_pfl,i_pde,i_pce : std_logic; + SIGNAL i_ppix : type_pix; + SIGNAL i_freeze : std_logic; + SIGNAL i_count : unsigned(2 DOWNTO 0); + SIGNAL i_hsize,i_hmin,i_hmax,i_hcpt : uint12; + SIGNAL i_hrsize,i_vrsize : uint12; + SIGNAL i_himax,i_vimax : uint12; + 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_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_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_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_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_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_ohsize,i_ovsize : uint12; + SIGNAL i_vdivi : unsigned(12 DOWNTO 0); + SIGNAL i_vdivr : unsigned(24 DOWNTO 0); + SIGNAL i_div : unsigned(16 DOWNTO 0); + SIGNAL i_dir : unsigned(11 DOWNTO 0); + SIGNAL i_h_frac,i_v_frac : unsigned(11 DOWNTO 0); + SIGNAL i_hacc,i_vacc : uint13; + SIGNAL i_hdown,i_vdown : std_logic; + SIGNAL i_divcpt : natural RANGE 0 TO 36; + SIGNAL i_lwad,i_lrad : natural RANGE 0 TO OHRES-1; + SIGNAL i_lwr,i_bil : std_logic; + SIGNAL i_ldw,i_ldrm : type_pix; + 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; + + ---------------------------------------------------------- + -- Avalon + TYPE type_avl_state IS (sIDLE,sWRITE,sREAD); + SIGNAL avl_state : type_avl_state; + 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_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; + + FUNCTION buf_next(a,b : natural RANGE 0 TO 2) RETURN natural IS + BEGIN + IF (a=0 AND b=1) OR (a=1 AND b=0) THEN RETURN 2; END IF; + 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 + BEGIN + IF b=1 THEN RETURN RAMSIZE; END IF; + IF b=2 THEN RETURN RAMSIZE(30 DOWNTO 0) & '0'; END IF; + RETURN x"00000000"; + END FUNCTION; + + ---------------------------------------------------------- + -- Output + SIGNAL o_run : std_logic; + SIGNAL o_mode,o_hmode,o_vmode : unsigned(4 DOWNTO 0); + SIGNAL o_htotal,o_hsstart,o_hsend : uint12; + SIGNAL o_hmin,o_hmax,o_hdisp : uint12; + SIGNAL o_hsize,o_vsize : uint12; + SIGNAL o_vtotal,o_vsstart,o_vsend : uint12; + SIGNAL o_vmin,o_vmax,o_vdisp : uint12; + SIGNAL o_divcpt : natural RANGE 0 TO 36; + SIGNAL o_iendframe0,o_iendframe02,o_iendframe1,o_iendframe12 : std_logic; + SIGNAL o_bufup0,o_bufup1,o_inter : std_logic; + SIGNAL o_ibuf0,o_ibuf1,o_obuf0,o_obuf1 : natural RANGE 0 TO 2; + 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_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; + SIGNAL o_ad,o_ad1,o_ad2,o_ad3 : natural RANGE 0 TO 2*BLEN-1; + 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_reset_na : std_logic; + SIGNAL o_dpram : arr_dw(0 TO BLEN*2-1); + ATTRIBUTE ramstyle OF o_dpram : SIGNAL IS "no_rw_check"; + SIGNAL o_line0,o_line1,o_line2,o_line3 : arr_pix(0 TO OHRES-1); + ATTRIBUTE ramstyle OF o_line0 : SIGNAL IS "no_rw_check"; + ATTRIBUTE ramstyle OF o_line1 : SIGNAL IS "no_rw_check"; + ATTRIBUTE ramstyle OF o_line2 : SIGNAL IS "no_rw_check"; + ATTRIBUTE ramstyle OF o_line3 : SIGNAL IS "no_rw_check"; + SIGNAL o_wadl,o_radl : natural RANGE 0 TO OHRES-1; + SIGNAL o_ldw,o_ldr0,o_ldr1,o_ldr2,o_ldr3 : type_pix; + SIGNAL o_wr : unsigned(3 DOWNTO 0); + 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_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; + SIGNAL o_read,o_read_pre : std_logic; + SIGNAL o_readlev,o_copylev : natural RANGE 0 TO 2; + SIGNAL o_hburst,o_hbcpt : natural RANGE 0 TO 31; + SIGNAL o_fload : natural RANGE 0 TO 3; + SIGNAL o_acpt,o_acpt1,o_acpt2,o_acpt3,o_acpt4 : natural RANGE 0 TO 15; -- Alternance pixels FIFO + 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_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_hpixq,o_vpixq,o_vpixq1 : arr_pix(0 TO 3); + + SIGNAL o_vpe : std_logic; + SIGNAL o_div,o_div2 : unsigned(18 DOWNTO 0); --uint12; + SIGNAL o_dir,o_dir2 : unsigned(11 DOWNTO 0); + SIGNAL o_vdivi : unsigned(12 DOWNTO 0); + SIGNAL o_vdivr : unsigned(24 DOWNTO 0); + SIGNAL o_divstart : std_logic; + SIGNAL o_divrun : std_logic; + 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 + + -- 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 + 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; + RETURN dw; + END FUNCTION; + + FUNCTION shift24_inext (acpt : natural RANGE 0 TO 15) 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; + 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 + 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; + RETURN shift_v; + END FUNCTION; + + FUNCTION shift24_onext (acpt : natural RANGE 0 TO 15) 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; + END FUNCTION; + + FUNCTION swap(d : unsigned(N_DW-1 DOWNTO 0)) RETURN unsigned IS + VARIABLE e : unsigned(N_DW-1 DOWNTO 0); + BEGIN + IF BYTESWAP THEN + FOR i IN 0 TO N_DW/8-1 LOOP + e(i*8+7 DOWNTO i*8):=d(N_DW-i*8-1 DOWNTO N_DW-i*8-8); + END LOOP; + RETURN e; + ELSE + RETURN d; + END IF; + END FUNCTION swap; + + ----------------------------------------------------------------------------- + FUNCTION altx (a : unsigned(1 DOWNTO 0)) RETURN unsigned IS + BEGIN + CASE a IS + WHEN "00" => RETURN "0001"; + WHEN "01" => RETURN "0010"; + WHEN "10" => RETURN "0100"; + WHEN OTHERS => RETURN "1000"; + END CASE; + END FUNCTION; + + ----------------------------------------------------------------------------- + FUNCTION bound(a : unsigned; + s : natural) RETURN unsigned IS + BEGIN + IF a(a'left)='1' THEN + RETURN x"00"; + ELSIF a(a'left DOWNTO s)/=0 THEN + RETURN x"FF"; + ELSE + RETURN a(s-1 DOWNTO s-8); + END IF; + END FUNCTION bound; + + ----------------------------------------------------------------------------- + -- Nearest + FUNCTION near_frac(f : unsigned) RETURN unsigned IS + VARIABLE x : unsigned(FRAC-1 DOWNTO 0); + BEGIN + x:=(OTHERS =>f(f'left)); + RETURN x; + END FUNCTION; + + SIGNAL o_h_frac2,o_v_frac : unsigned(FRAC-1 DOWNTO 0); + SIGNAL o_h_bil_pix,o_v_bil_pix : type_pix; + + ----------------------------------------------------------------------------- + -- Nearest + Bilinear + Sharp Bilinear + FUNCTION bil_frac(f : unsigned) RETURN unsigned IS + BEGIN + RETURN f(f'left DOWNTO f'left+1-FRAC); + END FUNCTION; + + TYPE type_bil_t IS RECORD + r,g,b : unsigned(8+FRAC DOWNTO 0); + END RECORD; + FUNCTION bil_calc(f : unsigned(FRAC-1 DOWNTO 0); + p : arr_pix(0 TO 3)) RETURN type_bil_t IS + VARIABLE fp,fn : unsigned(FRAC DOWNTO 0); + VARIABLE u : unsigned(8+FRAC DOWNTO 0); + VARIABLE x : type_bil_t; + CONSTANT Z : unsigned(FRAC-1 DOWNTO 0):=(OTHERS =>'0'); + BEGIN + fp:='0' & f; + fn:=('1' & Z) - fp; + u:=p(2).r * fp + p(1).r * fn; + x.r:=u; + u:=p(2).g * fp + p(1).g * fn; + x.g:=u; + u:=p(2).b * fp + p(1).b * fn; + x.b:=u; + RETURN x; + END FUNCTION; + SIGNAL o_h_bil_t,o_v_bil_t : type_bil_t; + SIGNAL i_h_bil_t : type_bil_t; + + ----------------------------------------------------------------------------- + -- Sharp Bilinear + -- <0.5 : x*x*x*4 + -- >0.5 : 1 - (1-x)*(1-x)*(1-x)*4 + + TYPE type_sbil_tt IS RECORD + f : unsigned(FRAC-1 DOWNTO 0); + s : unsigned(FRAC-1 DOWNTO 0); + END RECORD; + + SIGNAL o_h_sbil_t,o_v_sbil_t : type_sbil_tt; + + FUNCTION sbil_frac1(f : unsigned(11 DOWNTO 0)) RETURN type_sbil_tt IS + VARIABLE u : unsigned(FRAC-1 DOWNTO 0); + VARIABLE v : unsigned(2*FRAC-1 DOWNTO 0); + VARIABLE x : type_sbil_tt; + BEGIN + IF f(11)='0' THEN + u:=f(11 DOWNTO 12-FRAC); + ELSE + u:=NOT f(11 DOWNTO 12-FRAC); + END IF; + v:=u*u; + x.f:=u; + x.s:=v(2*FRAC-2 DOWNTO FRAC-1); + RETURN x; + END FUNCTION; + + FUNCTION sbil_frac2(f : unsigned(11 DOWNTO 0); + t : type_sbil_tt) RETURN unsigned IS + VARIABLE v : unsigned(2*FRAC-1 DOWNTO 0); + BEGIN + v:=t.f*t.s; + IF f(11)='0' THEN + RETURN v(2*FRAC-2 DOWNTO FRAC-1); + ELSE + RETURN NOT v(2*FRAC-2 DOWNTO FRAC-1); + END IF; + END FUNCTION; + + ----------------------------------------------------------------------------- + -- Bicubic + TYPE type_bic_abcd IS RECORD + a : unsigned(7 DOWNTO 0); -- 0.8 + b : signed(8 DOWNTO 0); -- 0.9 + c : signed(11 DOWNTO 0); -- 3.9 + d : signed(10 DOWNTO 0); -- 2.9 + xx : signed(8 DOWNTO 0); -- X.X 1.8 + END RECORD; + TYPE type_bic_pix_abcd IS RECORD + r,g,b : type_bic_abcd; + END RECORD; + TYPE type_bic_tt1 IS RECORD -- Intermediate result + r_bx,g_bx,b_bx : signed(8 DOWNTO 0); -- B.X 1.8 + r_cxx,g_cxx,b_cxx : signed(11 DOWNTO 0); -- C.XX 3.9 + r_dxx,g_dxx,b_dxx : signed(10 DOWNTO 0); -- D.XX 2.9 + END RECORD; + TYPE type_bic_tt2 IS RECORD -- Intermediate result + r_abxcxx,g_abxcxx,b_abxcxx : signed(9 DOWNTO 0); -- A + B.X + C.XX 2.8 + r_dxxx,g_dxxx,b_dxxx : signed(9 DOWNTO 0); -- D.X.X.X 2.8 + END RECORD; + + ---------------------------------------------------------- + -- Y = A + B.X + C.X.X + D.X.X.X = A + X.(B + X.(C + X.D)) + -- A = Y(0) 0 .. 1 unsigned + -- B = Y(1)/2 - Y(-1)/2 -1/2 .. +1/2 signed + -- C = Y(-1) - 5*Y(0)/2 + 2*Y(1) - Y(2)/2 -3 .. +3 signed + -- D = -Y(-1)/2 + 3*Y(0)/2 - 3*Y(1)/2 + Y(2)/2 -2 .. +2 signed + + FUNCTION bic_calc0(f : unsigned(11 DOWNTO 0); + pm,p0,p1,p2 : unsigned(7 DOWNTO 0)) RETURN type_bic_abcd IS + VARIABLE xx : signed(2*FRAC+1 DOWNTO 0); -- 2.(2*FRAC) + BEGIN + xx := signed('0' & f(11 DOWNTO 12-FRAC)) * + signed('0' & f(11 DOWNTO 12-FRAC)); -- 2.(2*FRAC) + RETURN type_bic_abcd'( + a=>p0,-- 0.8 + b=>signed(('0' & p1) - ('0' & pm)), -- 0.9 + c=>signed(("000" & pm & '0') - ("00" & p0 & "00") - ("0000" & p0) + + ("00" & p1 & "00") - ("0000" & p2)), -- 3.9 + d=>signed(("00" & p0 & '0') - ("00" & p1 & '0') - ("000" & p1) + + ("000" & p0) + ("000" & p2) - ("000" & pm)), -- 2.9 + xx=>xx(2*FRAC DOWNTO 2*FRAC-8)); -- 1.8 + END FUNCTION; + FUNCTION bic_calc0(f : unsigned(11 DOWNTO 0); + p : arr_pix(0 TO 3)) RETURN type_bic_pix_abcd IS + BEGIN + RETURN type_bic_pix_abcd'(r=>bic_calc0(f,p(0).r,p(1).r,p(2).r,p(3).r), + g=>bic_calc0(f,p(0).g,p(1).g,p(2).g,p(3).g), + b=>bic_calc0(f,p(0).b,p(1).b,p(2).b,p(3).b)); + END FUNCTION; + + ---------------------------------------------------------- + -- Calc : B.X, C.XX, D.XX + FUNCTION bic_calc1(f : unsigned(11 DOWNTO 0); + abcd : type_bic_pix_abcd) RETURN type_bic_tt1 IS + VARIABLE t : type_bic_tt1; + VARIABLE bx : signed(9+FRAC DOWNTO 0); -- 1.(FRAC+9) + VARIABLE cxx : signed(20 DOWNTO 0); -- 4.17 + VARIABLE dxx : signed(19 DOWNTO 0); -- 3.17 + BEGIN + bx := abcd.r.b * signed('0' & f(11 DOWNTO 12-FRAC)); -- 1.(FRAC+9) + t.r_bx:=bx(9+FRAC DOWNTO 9+FRAC-8); -- 1.8 + cxx:= abcd.r.c * abcd.r.xx; -- 3.9 * 1.8 = 4.17 + t.r_cxx:=cxx(19 DOWNTO 8); -- 3.9 + dxx:= abcd.r.d * abcd.r.xx; -- 2.9 * 1.8 = 3.17 + t.r_dxx:=dxx(18 DOWNTO 8); -- 2.9 + bx := abcd.g.b * signed('0' & f(11 DOWNTO 12-FRAC)); -- 1.(FRAC+9) + t.g_bx:=bx(9+FRAC DOWNTO 9+FRAC-8); -- 1.8 + cxx:= abcd.g.c * abcd.g.xx; -- 3.9 * 1.8 = 4.17 + t.g_cxx:=cxx(19 DOWNTO 8); -- 3.9 + dxx:= abcd.g.d * abcd.g.xx; -- 2.9 * 1.8 = 3.17 + t.g_dxx:=dxx(18 DOWNTO 8); -- 2.9 + bx := abcd.b.b * signed('0' & f(11 DOWNTO 12-FRAC)); -- 1.(FRAC+9) + t.b_bx:=bx(9+FRAC DOWNTO 9+FRAC-8); -- 1.8 + cxx:= abcd.b.c * abcd.b.xx; -- 3.9 * 1.8 = 4.17 + t.b_cxx:=cxx(19 DOWNTO 8); -- 3.9 + dxx:= abcd.b.d * abcd.b.xx; -- 2.9 * 1.8 = 3.17 + t.b_dxx:=dxx(18 DOWNTO 8); -- 2.9 + RETURN t; + END FUNCTION; + + ---------------------------------------------------------- + -- Calc A + BX + CXX , X.DXX + FUNCTION bic_calc2(f : unsigned(11 DOWNTO 0); + t : type_bic_tt1; + abcd : type_bic_pix_abcd) RETURN type_bic_tt2 IS + VARIABLE u : type_bic_tt2; + VARIABLE x : signed(11+FRAC DOWNTO 0); -- 3.(9+FRAC) + BEGIN + u.r_abxcxx:=(t.r_bx(8) & t.r_bx) + ("00" & signed(abcd.r.a)) + t.r_cxx(10 DOWNTO 1); -- 2.8 + u.g_abxcxx:=(t.g_bx(8) & t.g_bx) + ("00" & signed(abcd.g.a)) + t.g_cxx(10 DOWNTO 1); -- 2.8 + u.b_abxcxx:=(t.b_bx(8) & t.b_bx) + ("00" & signed(abcd.b.a)) + t.b_cxx(10 DOWNTO 1); -- 2.8 + + x:=t.r_dxx * signed('0' & f(11 DOWNTO 12-FRAC)); --2.9 * 1.FRAC =3.(9+FRAC) + u.r_dxxx:=x(10+FRAC DOWNTO 9+FRAC-8); -- 2.8 + x:=t.g_dxx * signed('0' & f(11 DOWNTO 12-FRAC)); --2.9 * 1.FRAC =3.(9+FRAC) + u.g_dxxx:=x(10+FRAC DOWNTO 9+FRAC-8); -- 2.8 + x:=t.b_dxx * signed('0' & f(11 DOWNTO 12-FRAC)); --2.9 * 1.FRAC =3.(9+FRAC) + u.b_dxxx:=x(10+FRAC DOWNTO 9+FRAC-8); -- 2.8 + RETURN u; + END FUNCTION; + + ---------------------------------------------------------- + -- Calc (A + BX + CXX) + (DXXX) + FUNCTION bic_calc3(f : unsigned(11 DOWNTO 0); + t : type_bic_tt2; + abcd : type_bic_pix_abcd) RETURN type_pix IS + VARIABLE x : type_pix; + VARIABLE v : signed(9 DOWNTO 0); -- 2.8 + BEGIN + v:=t.r_abxcxx + t.r_dxxx; + x.r:=bound(unsigned(v),8); + v:=t.g_abxcxx + t.g_dxxx; + x.g:=bound(unsigned(v),8); + v:=t.b_abxcxx + t.b_dxxx; + x.b:=bound(unsigned(v),8); + RETURN x; + END FUNCTION; + + ----------------------------------------------------------------------------- + SIGNAL o_h_bic_pix,o_v_bic_pix : type_pix; + SIGNAL o_h_bic_abcd1,o_h_bic_abcd2 : type_bic_pix_abcd; + SIGNAL o_v_bic_abcd1,o_v_bic_abcd2 : type_bic_pix_abcd; + SIGNAL o_h_bic_tt1,o_v_bic_tt1 : type_bic_tt1; + SIGNAL o_h_bic_tt2,o_v_bic_tt2 : type_bic_tt2; + + ----------------------------------------------------------------------------- + -- 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, + -24,-25,-26,-24,-20,-6,4,27,58,85,115,131,150,160,169,174, + 0,0,0,1,3,4,5,8,6,8,4,-1,-5,-9,-15,-21); + + CONSTANT POLY32 : arr_int9 := ( + -24,-22,-20,-18,-16,-13,-11,-8,-6,-3,-1,0,2,3,5,5,6,6,6,5,5,4,4,3,2,1,1,0,0,0,0,0, + 176,175,174,172,169,164,160,153,147,138,129,119,109,96,84,71,58,40,22,12,3,-4,-12,-16,-20,-22,-25,-25,-26,-25,-25,-25, + -24,-25,-26,-26,-26,-24,-23,-19,-16,-10,-4,4,11,22,32,45,58,77,96,108,119,129,140,147,154,159,165,168,172,173,175,175, + 0,0,0,0,1,1,2,2,3,3,4,5,6,7,7,7,6,5,4,3,1,-1,-4,-6,-8,-10,-13,-15,-18,-20,-22,-22); + + FUNCTION init_poly RETURN arr_uv36 IS + VARIABLE m : arr_uv36(0 TO 2**FRAC-1) :=(OTHERS =>x"000000000"); + BEGIN + IF FRAC=4 THEN + FOR i IN 0 TO 15 LOOP + m(i):=unsigned(to_signed(POLY16(i),9) & to_signed(POLY16(i+16),9) & + to_signed(POLY16(i+32),9) & to_signed(POLY16(i+48),9)); + END LOOP; + ELSIF FRAC=5 THEN + FOR i IN 0 TO 31 LOOP + m(i):=unsigned(to_signed(POLY32(i),9) & to_signed(POLY32(i+32),9) & + to_signed(POLY32(i+64),9) & to_signed(POLY32(i+96),9)); + END LOOP; + END IF; + RETURN m; + END FUNCTION; + + SIGNAL o_h_poly : arr_uv36(0 TO 2**FRAC-1):=init_poly; + SIGNAL o_v_poly : arr_uv36(0 TO 2**FRAC-1):=init_poly; + ATTRIBUTE ramstyle OF o_h_poly : SIGNAL IS "no_rw_check"; + ATTRIBUTE ramstyle OF o_v_poly : SIGNAL IS "no_rw_check"; + SIGNAL o_h_poly_a,o_v_poly_a : integer RANGE 0 TO 2**FRAC-1; + SIGNAL o_h_poly_dr,o_h_poly_dr2,o_v_poly_dr,o_v_poly_dr2 : unsigned(35 DOWNTO 0); + SIGNAL o_h_poly_pix,o_v_poly_pix : type_pix; + SIGNAL poly_h_wr,poly_v_wr : std_logic; + SIGNAL poly_tdw : unsigned(35 DOWNTO 0); + SIGNAL poly_a2 : unsigned(FRAC-1 DOWNTO 0); + + TYPE type_poly_t IS RECORD + r0,r1,b0,b1,g0,g1 : signed(17 DOWNTO 0); + END RECORD; + + SIGNAL o_h_poly_t,o_v_poly_t : type_poly_t; + + FUNCTION poly_calc1(fi : unsigned(35 DOWNTO 0); + p : arr_pix(0 TO 3)) RETURN type_poly_t IS + VARIABLE t : type_poly_t; + BEGIN + -- 2.7 * 1.8 = 3.15 + t.r0:=(signed(fi(35 DOWNTO 27)) * signed('0' & p(0).r) + + signed(fi(26 DOWNTO 18)) * signed('0' & p(1).r)); + t.r1:=(signed(fi(17 DOWNTO 9)) * signed('0' & p(2).r) + + signed(fi( 8 DOWNTO 0)) * signed('0' & p(3).r)); + t.g0:=(signed(fi(35 DOWNTO 27)) * signed('0' & p(0).g) + + signed(fi(26 DOWNTO 18)) * signed('0' & p(1).g)); + t.g1:=(signed(fi(17 DOWNTO 9)) * signed('0' & p(2).g) + + signed(fi( 8 DOWNTO 0)) * signed('0' & p(3).g)); + t.b0:=(signed(fi(35 DOWNTO 27)) * signed('0' & p(0).b) + + signed(fi(26 DOWNTO 18)) * signed('0' & p(1).b)); + t.b1:=(signed(fi(17 DOWNTO 9)) * signed('0' & p(2).b) + + signed(fi( 8 DOWNTO 0)) * signed('0' & p(3).b)); + RETURN t; + END FUNCTION; + + FUNCTION poly_calc2(t : type_poly_t) RETURN type_pix IS + VARIABLE p : type_pix; + BEGIN + p.r:=bound(unsigned(t.r0+t.r1),15); + p.g:=bound(unsigned(t.g0+t.g1),15); + p.b:=bound(unsigned(t.b0+t.b1),15); + RETURN p; + END FUNCTION; + +BEGIN + + ----------------------------------------------------------------------------- + i_reset_na<='0' WHEN reset_na='0' ELSE '1' WHEN rising_edge(i_clk); + o_reset_na<='0' WHEN reset_na='0' ELSE '1' WHEN rising_edge(o_clk); + avl_reset_na<='0' WHEN reset_na='0' ELSE '1' WHEN rising_edge(avl_clk); + + ----------------------------------------------------------------------------- + -- Input pixels FIFO and shreg + InAT:PROCESS(i_clk,i_reset_na) IS + CONSTANT Z : unsigned(FRAC-1 DOWNTO 0):=(OTHERS =>'0'); + VARIABLE frac_v : unsigned(FRAC-1 DOWNTO 0); + VARIABLE div_v : unsigned(16 DOWNTO 0); + VARIABLE dir_v : unsigned(11 DOWNTO 0); + VARIABLE bil_t_v : type_bil_t; + BEGIN + IF i_reset_na='0' THEN + i_write<='0'; + + ELSIF rising_edge(i_clk) THEN + i_push<='0'; + i_eol<='0'; -- End Of Line + i_freeze <=freeze; -- + i_iauto<=iauto; -- + + ------------------------------------------------------ + i_head(127 DOWNTO 120)<=x"01"; -- Header type + i_head(119 DOWNTO 112)<=x"01"; -- 24bits/pixels, packed RGB, big endian + 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; + i_head(81)<=i_flm; + i_head(82)<=i_hdown; + i_head(83)<=i_vdown; + i_head(84)<=i_mode(3); + i_head(87 DOWNTO 85)<=i_count; + i_head(79 DOWNTO 64)<="0000" & to_unsigned(i_hrsize,12); -- Image width + i_head(63 DOWNTO 48)<="0000" & to_unsigned(i_vrsize,12); -- Image height + i_head(47 DOWNTO 32)<= + to_unsigned(N_BURST * i_hburst,16); -- Line Length. Bytes + i_head(31 DOWNTO 16)<="0000" & to_unsigned(i_ohsize,12); + i_head(15 DOWNTO 0) <="0000" & to_unsigned(i_ovsize,12); + + ------------------------------------------------------ + i_ppix<=(i_r,i_g,i_b); + i_pvs<=i_vs; + i_pfl<=i_fl; + i_pde<=i_de; + i_pce<=i_ce; + + ------------------------------------------------------ + IF i_pce='1' THEN + ---------------------------------------------------- + i_vs_pre<=i_pvs; + i_de_pre<=i_pde; + i_fl_pre<=i_pfl; + + ---------------------------------------------------- + -- Detect interlaced video + IF NOT INTER THEN + i_intercnt<=0; + ELSIF i_pfl/=i_fl_pre THEN + i_intercnt<=3; + ELSIF i_pvs='1' AND i_vs_pre='0' AND i_intercnt>0 THEN + i_intercnt<=i_intercnt-1; + END IF; + i_inter<=to_std_logic(i_intercnt>0); + + ---------------------------------------------------- + IF i_pvs='1' AND i_vs_pre='0' THEN + i_sof<='1'; + 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'; + 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_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')); + + -- Detects third line for low lag mode + i_syncline<=to_std_logic(i_vcpt=i_vmin + 4); + + ---------------------------------------------------- + IF i_pde='1' AND i_de_pre='0' THEN + i_vimax<=i_vcpt; + i_hcpt<=0; + ELSE + i_hcpt<=(i_hcpt+1) MOD 4096; + END IF; + + IF i_pde='0' AND i_de_pre='1' THEN + i_himax<=i_hcpt; + END IF; + + IF i_iauto='1' THEN + -- Auto-size + i_hmin<=0; + i_hmax<=i_himax; + i_vmin<=0; + IF i_pvs='1' AND i_vs_pre='0' AND (i_inter='0' OR i_pfl='0') THEN + i_vmax<=i_vimax; + END IF; + ELSE + -- Forced image + i_hmin<=himin; -- + i_hmax<=himax; -- + i_vmin<=vimin; -- + i_vmax<=vimax; -- + END IF; + + ---------------------------------------------------- + i_mode<=mode; -- + + -- Downscaling : Nearest or bilinear + i_bil<=to_std_logic(i_mode(2 DOWNTO 0)/="000" AND DOWNSCALE); + + i_hdown<=to_std_logic(i_hsize>i_ohsize AND DOWNSCALE); --H downscale + i_vdown<=to_std_logic(i_vsize>i_ovsize AND DOWNSCALE); --V downscale + + ---------------------------------------------------- + i_hsize <=(4096+i_hmax-i_hmin+1) MOD 4096; + i_vmaxmin<=(4096+i_vmax-i_vmin+1) MOD 4096; + + IF i_inter='0' THEN + -- Non interlaced + i_vsize<=i_vmaxmin; + i_half<='0'; + ELSIF i_ovsize<2*i_vmaxmin THEN + -- Interlaced, but downscaling, use only half frames + i_vsize<=i_vmaxmin; + i_half<='1'; + ELSE + -- Interlaced : Double image height + i_vsize<=2*i_vmaxmin; + i_half<='0'; + END IF; + + i_ohsize<=o_hsize; -- + i_ovsize<=o_vsize; -- + + ---------------------------------------------------- + -- Downscaling vertical + i_divstart<='0'; + IF i_hs_delay=7 THEN + IF (i_vacc + 2*i_ovsize) < 2*i_vsize THEN + i_vacc<=(i_vacc + 2*i_ovsize) MOD 8192; + i_vnp<='0'; + ELSE + i_vacc<=(i_vacc + 2*i_ovsize - 2*i_vsize + 8192) MOD 8192; + i_vnp<='1'; + END IF; + i_divstart<='1'; + + IF i_vcpt=i_vmin THEN + i_vacc<=(i_vsize - i_ovsize + 8192) MOD 8192; + i_vnp<='1'; -- + END IF; + END IF; + + --IF i_vdown='0' THEN + -- i_vnp<='1'; + --END IF; + + -- Downscaling horizontal + IF i_ven='1' THEN + IF i_hacc + 2*i_ohsize < 2*i_hsize THEN + i_hacc<=(i_hacc + 2*i_ohsize) MOD 8192; + i_hnp<='0'; -- Skip. pix. + ELSE + i_hacc<=(i_hacc + 2*i_ohsize - 2*i_hsize + 8192) MOD 8192; + i_hnp<='1'; + END IF; + END IF; + IF i_hdown='0' THEN + i_hnp<='1'; + END IF; + + ---------------------------------------------------- + -- Downscaling interpolation + i_hpixp<=i_ppix; + i_hpix0<=i_hpixp; + i_hpix1<=i_hpix0; + i_hpix2<=i_hpix1; + 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; + + -- C1 : DIV 1. Pipelined 4 bits non-restoring divider + dir_v:=x"000"; + div_v:=to_unsigned(i_hacc * 16,17); + + div_v:=div_v-to_unsigned(i_hsize*16,17); + dir_v(11):=NOT div_v(16); + IF div_v(16)='0' THEN + div_v:=div_v-to_unsigned(i_hsize*8,17); + ELSE + div_v:=div_v+to_unsigned(i_hsize*8,17); + END IF; + dir_v(10):=NOT div_v(16); + i_div<=div_v; + i_dir<=dir_v; + + -- C2 : DIV 2. + div_v:=i_div; + dir_v:=i_dir; + IF div_v(16)='0' THEN + div_v:=div_v-to_unsigned(i_hsize*4,17); + ELSE + div_v:=div_v+to_unsigned(i_hsize*4,17); + END IF; + dir_v(9):=NOT div_v(16); + + IF div_v(16)='0' THEN + div_v:=div_v-to_unsigned(i_hsize*2,17); + ELSE + div_v:=div_v+to_unsigned(i_hsize*2,17); + END IF; + dir_v(8):=NOT div_v(16); + i_h_frac<=dir_v; + + -- C4 : Horizontal Bilinear + IF i_bil='0' THEN + frac_v:=near_frac(i_h_frac); + ELSE + frac_v:=bil_frac(i_h_frac); + END IF; + + i_h_bil_t<=bil_calc(frac_v,(i_hpix2,i_hpix2,i_hpix3,i_hpix3)); + i_hpix.r<=bound(i_h_bil_t.r,8+FRAC); + i_hpix.g<=bound(i_h_bil_t.g,8+FRAC); + i_hpix.b<=bound(i_h_bil_t.b,8+FRAC); + + IF i_hdown='0' THEN + i_hpix<=i_hpix4; + END IF; + + -- C5 : Vertical Bilinear + IF i_bil='0' THEN + frac_v:=near_frac(i_v_frac(11 DOWNTO 0)); + ELSE + frac_v:=bil_frac(i_v_frac(11 DOWNTO 0)); + END IF; + + bil_t_v:=bil_calc(frac_v,(i_hpix,i_hpix,i_ldrm,i_ldrm)); + i_pix.r<=bound(bil_t_v.r,8+FRAC); + i_pix.g<=bound(bil_t_v.g,8+FRAC); + i_pix.b<=bound(bil_t_v.b,8+FRAC); + + IF i_vdown='0' THEN + i_pix<=i_hpix; + END IF; + + ---------------------------------------------------- + -- VNP : Vert. downscaling line enable + -- HNP : Horiz. downscaling pix. enable + -- 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); + + IF shift24_inext(i_acpt) 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 + 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 + i_lwad<=0; + i_lrad<=0; + i_vcpt<=i_vcpt+1; + i_hacc<=(i_hsize - i_ohsize + 8192) MOD 8192; + END IF; + IF i_hs_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' + + ------------------------------------------------------ + -- Push pixels to downscaling line buffer + i_lwr<=i_hnp4 AND i_ven5 AND i_pce; + IF i_lwr='1' THEN + i_lwad<=(i_lwad+1) MOD OHRES; + END IF; + i_ldw<=i_hpix; + + IF i_hnp3='1' AND i_ven4='1' AND i_pce='1' THEN + i_lrad<=(i_lrad+1) MOD OHRES; + END IF; + + ------------------------------------------------------ + -- Push pixels to DPRAM + i_wr<='0'; + + 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 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; + END IF; + END IF; + + i_pushhead3<=i_pushhead2; + + IF i_pushhead2='1' AND i_freeze='0' THEN + i_wr<='1'; + i_wad<=0; + i_write<=i_write XOR NOT i_freeze; + i_walt<='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; + + -- End of line + IF i_eol3='1' AND i_freeze='0' THEN + IF (i_wad MOD BLEN)/=BLEN-1 THEN + -- Some pixels are in the partially filled buffer + i_hbcpt<=(i_hbcpt+1) MOD 32; + i_write<=i_write XOR NOT i_freeze; + i_walt <=to_std_logic(i_wad/BLEN /= 0); + i_adrs <=i_adrsi; + IF i_inter='1' AND i_half='0' THEN + -- Skip every other line for interlaced video + i_adrsi<=i_adrsi + N_BURST * (i_hburst + 1); + ELSE + i_adrsi<=i_adrsi + N_BURST; + END IF; + ELSE + IF i_inter='1' AND i_half='0' THEN + -- Skip every other line for interlaced video + i_adrsi<=i_adrsi + N_BURST * i_hburst; + END IF; + END IF; + END IF; + END IF; + END PROCESS; + + -- If downscaling, export to the output part the downscaled size + i_hrsize<=i_hsize WHEN i_hdown='0' ELSE i_ohsize; + i_vrsize<=i_vsize WHEN i_vdown='0' ELSE i_ovsize; + + ----------------------------------------------------------------------------- + -- Input Divider. For downscaling. + -- Vfrac = IVacc / IVsize 12 / 12 --> 12 + IDividers:PROCESS (i_clk,i_reset_na) IS + BEGIN + IF i_reset_na='0' THEN +--pragma synthesis_off + i_v_frac<=x"000"; +--pragma synthesis_on + NULL; + ELSIF rising_edge(i_clk) THEN + i_vdivi<=to_unsigned(2*i_vsize,13); + i_vdivr<=to_unsigned(i_vacc*4096,25); + + ------------------------------------------------------ + IF i_divstart='1' THEN + i_divcpt<=0; + i_divrun<='1'; + + ELSIF i_divrun='1' THEN + ---------------------------------------------------- + IF i_divcpt=6 THEN + i_divrun<='0'; + i_v_frac<=i_vdivr(4 DOWNTO 0) & NOT i_vdivr(24) & "000000"; + ELSE + i_divcpt<=i_divcpt+1; + END IF; + + IF i_vdivr(24)='0' THEN + i_vdivr(24 DOWNTO 12)<=i_vdivr(23 DOWNTO 11) - i_vdivi; + ELSE + i_vdivr(24 DOWNTO 12)<=i_vdivr(23 DOWNTO 11) + i_vdivi; + END IF; + i_vdivr(11 DOWNTO 0)<=i_vdivr(10 DOWNTO 0) & NOT i_vdivr(24); + + ---------------------------------------------------- + END IF; + END IF; + END PROCESS IDividers; + + ----------------------------------------------------------------------------- + -- DPRAM Input. Double buffer for RAM bursts. + PROCESS (i_clk) IS + BEGIN + IF rising_edge(i_clk) THEN + IF i_wr='1' THEN + i_dpram(i_wad)<=i_dw; + END IF; + END IF; + END PROCESS; + + avl_dr<=i_dpram(avl_rad_c) WHEN rising_edge(avl_clk); + + -- Line buffer for downscaling with interpolation + DownLine:IF DOWNSCALE GENERATE + ILBUF:PROCESS(i_clk) IS + BEGIN + IF rising_edge(i_clk) THEN + IF i_lwr='1' THEN + i_line(i_lwad MOD IHRES)<=i_ldw; + END IF; + IF i_pce='1' THEN + i_ldrm<=i_line(i_lrad MOD IHRES); + END IF; + END IF; + END PROCESS ILBUF; + END GENERATE DownLine; + + ----------------------------------------------------------------------------- + -- AVALON interface + Avaloir:PROCESS(avl_clk,avl_reset_na) IS + BEGIN + IF avl_reset_na='0' THEN + avl_reading<='0'; + avl_state<=sIDLE; + avl_write_sr<='0'; + avl_read_sr<='0'; + avl_readack<='0'; + + ELSIF rising_edge(avl_clk) THEN + ---------------------------------- + avl_write_sync<=i_write; -- + 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; -- + + ---------------------------------- + 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<=avl_o_vs_sync; + + -------------------------------------------- + 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_write_clr<='0'; + avl_read_clr <='0'; + + avl_rad<=avl_rad_c; + + -------------------------------------------- + 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'; + IF avl_walt='0' THEN + avl_rad<=0; + 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; + ELSE + avl_wad<=BLEN-1; + END IF; + 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 + avl_write_i<='0'; + avl_state<=sIDLE; + END IF; + END IF; + + WHEN sREAD => + IF avl_rline='0' THEN + avl_address<=std_logic_vector(RAMBASE(N_AW+NB_LA-1 DOWNTO NB_LA) + + 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_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'; + END IF; + END CASE; + + -------------------------------------------- + -- Pipelined data read + avl_wr<='0'; + IF avl_readdatavalid='1' THEN + 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; + END IF; + END IF; + + -------------------------------------------- + END IF; + END PROCESS Avaloir; + + avl_read<=avl_read_i; + avl_write<=avl_write_i; + avl_writedata<=std_logic_vector(swap(avl_dr)); + avl_burstcount<=std_logic_vector(to_unsigned(BLEN,8)); + avl_byteenable<=(OTHERS =>'1'); + + avl_rad_c<=(avl_rad+1) MOD (2*BLEN) + WHEN avl_write_i='1' AND avl_waitrequest='0' ELSE avl_rad; + + ----------------------------------------------------------------------------- + -- DPRAM Output. Double buffer for RAM bursts. + PROCESS (avl_clk) IS + BEGIN + IF rising_edge(avl_clk) THEN + IF avl_wr='1' THEN + o_dpram(avl_wad)<=avl_dw; + END IF; + END IF; + END PROCESS; + + o_dr<=o_dpram(o_ad3) WHEN rising_edge(o_clk); + + ----------------------------------------------------------------------------- + -- Output Vertical Divider + -- Vfrac = Vacc / Vsize + ODivider:PROCESS (o_clk,o_reset_na) IS + BEGIN + IF o_reset_na='0' THEN +--pragma synthesis_off + o_vfrac<=x"000"; +--pragma synthesis_on + ELSIF rising_edge(o_clk) THEN + o_vdivi<=to_unsigned(2*o_vsize,13); + o_vdivr<=to_unsigned(o_vacc*4096,25); + ------------------------------------------------------ + IF o_divstart='1' THEN + o_divcpt<=0; + o_divrun<='1'; + + ELSIF o_divrun='1' THEN + ---------------------------------------------------- + IF o_divcpt=12 THEN + o_divrun<='0'; + o_vfrac<=o_vdivr(10 DOWNTO 0) & NOT o_vdivr(24); + ELSE + o_divcpt<=o_divcpt+1; + END IF; + + IF o_vdivr(24)='0' THEN + o_vdivr(24 DOWNTO 12)<=o_vdivr(23 DOWNTO 11) - o_vdivi; + ELSE + o_vdivr(24 DOWNTO 12)<=o_vdivr(23 DOWNTO 11) + o_vdivi; + END IF; + o_vdivr(11 DOWNTO 0)<=o_vdivr(10 DOWNTO 0) & NOT o_vdivr(24); + ---------------------------------------------------- + END IF; + END IF; + END PROCESS ODivider; + + ----------------------------------------------------------------------------- + Scalaire:PROCESS (o_clk,o_reset_na) IS + 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 hcarry_v,vcarry_v : boolean; + VARIABLE dif_v : natural RANGE 0 TO 8*OHRES-1; + BEGIN + IF o_reset_na='0' THEN + o_copy<='0'; + o_state<=sDISP; + o_read_pre<='0'; + o_readlev<=0; + o_copylev<=0; + o_hsp<='0'; + + ELSIF rising_edge(o_clk) THEN + ------------------------------------------------------ + o_mode <=mode; -- ? + o_run <=run; -- ? + + o_htotal <=htotal; -- ? + o_hsstart<=hsstart; -- ? + o_hsend <=hsend; -- ? + o_hdisp <=hdisp; -- ? + o_hmin <=hmin; -- ? + o_hmax <=hmax; -- ? + + o_vtotal <=vtotal; -- ? + o_vsstart<=vsstart; -- ? + o_vsend <=vsend; -- ? + o_vdisp <=vdisp; -- ? + o_vmin <=vmin; -- ? + o_vmax <=vmax; -- ? + + o_hsize <=o_hmax - o_hmin + 1; + o_vsize <=o_vmax - o_vmin + 1; + + -------------------------------------------- + -- Triple buffering. + -- For intelaced video, half frames are updated independently + -- Input : Toggle buffer at end of input frame + o_inter <=i_inter; -- + o_iendframe0<=i_endframe0; -- + o_iendframe02<=o_iendframe0; + IF o_iendframe0='1' AND o_iendframe02='0' THEN + o_ibuf0<=buf_next(o_ibuf0,o_obuf0); + o_bufup0<='1'; + END IF; + o_iendframe1<=i_endframe1; -- + o_iendframe12<=o_iendframe1; + IF o_iendframe1='1' AND o_iendframe12='0' THEN + o_ibuf1<=buf_next(o_ibuf1,o_obuf1); + o_bufup1<='1'; + END IF; + -- Output : Change framebuffer, and image properties, at VS falling edge + 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; + 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'; + END IF; + + IF o_inter='0' THEN + o_ibuf1<=o_ibuf0; + o_obuf1<=o_obuf0; + END IF; + + -- Triple buffer disabled + IF o_mode(3)='0' THEN + o_obuf0<=0; + o_obuf1<=0; + o_ibuf0<=0; + o_ibuf1<=0; + END IF; + + ------------------------------------------------------ + o_hmode<=o_mode; + IF o_hdown='1' AND DOWNSCALE THEN + -- Force nearest if downscaling : Downscaled framebuffer + o_hmode(2 DOWNTO 0)<="000"; + END IF; + + o_vmode<=o_mode; + IF o_vdown='1' AND DOWNSCALE THEN + -- Force nearest if downscaling : Downscaled framebuffer + o_vmode(2 DOWNTO 0)<="000"; + END IF; + + ------------------------------------------------------ + -- End DRAM READ + o_readack_sync<=avl_readack; -- + o_readack_sync2<=o_readack_sync; + o_readack<=o_readack_sync XOR o_readack_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; + END IF; + o_hsp<='1'; + END IF; + + o_vpe<=to_std_logic(o_vcpt_pre=o_vmin); + o_divstart<='0'; + o_adrsa<='0'; + + o_vacc_ini<=(o_vsize - o_ivsize + 8192) MOD 8192; + o_hacc_ini<=(o_hsize + o_ihsize + 8192) MOD 8192; + + CASE o_state IS + -------------------------------------------------- + WHEN sDISP => + IF o_hsp='1' THEN + o_state<=sHSYNC; + o_hsp<='0'; + END IF; + + -------------------------------------------------- + WHEN sHSYNC => + dif_v:=(o_vacc_next - 2*o_vsize + 16384) MOD 16384; + IF dif_v>=8192 THEN + o_vacc <=o_vacc_next; + o_vacc_next<=(o_vacc_next + 2*o_ivsize) MOD 8192; + vcarry_v:=false; + ELSE + o_vacc <=dif_v; + o_vacc_next<=(dif_v + 2*o_ivsize + 8192) MOD 8192; + vcarry_v:=true; + END IF; + o_divstart<='1'; + IF o_vcpt_pre2=o_vmin THEN --pe='0' THEN + o_vacc <=o_vacc_ini; + o_vacc_next<=o_vacc_ini + 2*o_ivsize; + o_vacpt<=x"001"; + vcarry_v:=false; + END IF; + + IF vcarry_v THEN + o_vacpt<=o_vacpt+1; + END IF; + o_hbcpt<=0; -- Clear burst counter on line + IF (o_vpe='1' AND vcarry_v) OR o_fload>0 THEN + o_state<=sREAD; + ELSE + o_state<=sDISP; + END IF; + + WHEN sREAD => + -- Read a block + IF o_readlev<2 THEN + lev_inc_v:='1'; + o_read_pre<=NOT o_read_pre; + o_state <=sWAITREAD; + o_bibu<=NOT o_bibu; + END IF; + 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 => + IF o_readack='1' THEN + o_hbcpt<=o_hbcpt+1; + IF o_hbcpt=1 THEN + o_fload<=o_fload-1; + END IF; + END IF; + END IF; + + -------------------------------------------------- + END CASE; + + o_read<=o_read_pre AND o_run; + + 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; + 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; + END IF; + END IF; + + ------------------------------------------------------ + -- Copy from buffered memory to pixel lines + o_sh<='0'; + IF o_copy='0' THEN + o_copyv(0)<='0'; + IF o_copylev>0 AND o_copyv(0)='0' THEN + o_copy<='1'; + 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"; + o_dcpt<=0; + o_dshi<=2; + o_acpt<=0; + o_first<='1'; + o_last<='0'; + END IF; + + IF o_bibv(0)='0' THEN + o_ad<=0; + ELSE + o_ad<=BLEN; + END IF; + ELSE + -- dshi : Force shift first two or three pixels of each line + IF o_dshi=0 THEN + dif_v:=(o_hacc_next - 2*o_hsize + (8*OHRES)) MOD (8*OHRES); + IF dif_v>=4*OHRES THEN + o_hacc<=o_hacc_next; + o_hacc_next<=o_hacc_next + 2*o_ihsize; + hcarry_v:=false; + ELSE + o_hacc<=dif_v; + o_hacc_next<=(dif_v + 2*o_ihsize + (4*OHRES)) MOD (4*OHRES); + hcarry_v:=true; + END IF; + o_dcpt<=(o_dcpt+1) MOD 4096; + ELSE + o_dshi<=o_dshi-1; + hcarry_v:=false; + END IF; + IF o_dshi<=1 THEN + o_copyv(0)<='1'; + END IF; + IF hcarry_v THEN + o_hacpt<=o_hacpt+1; + o_last<=to_std_logic(o_hacpt>=o_ihsize-2); + END IF; + + IF hcarry_v OR o_dshi>0 THEN + o_sh<='1'; + o_acpt<=(o_acpt+1) MOD 16; + + -- Shift two more pixels to the right before ending line. + o_last1<=o_last; + o_last2<=o_last1; + + IF shift24_onext(o_acpt) THEN + o_ad<=(o_ad+1) MOD (2*BLEN); + END IF; + + IF o_adturn='1' AND (shift24_onext((o_acpt+1) MOD 16)) AND + (((o_ad MOD BLEN=0) AND o_lastv(0)='0') OR o_last2='1') THEN + o_copy<='0'; + lev_dec_v:='1'; + END IF; + + IF o_ad MOD BLEN=4 THEN + o_adturn<='1'; + END IF; + END IF; + END IF; + + 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_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); + 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_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_first<='0'; + END IF; + IF o_lastt3='1' THEN + -- Right edge. Keep last pixel. + o_hpix0<=o_hpix0; + END IF; + END IF; + + ------------------------------------------------------ + -- 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 + 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 + o_copylev<=o_copylev-1; + ELSIF lev_dec_v='0' AND o_readack='1' THEN + o_copylev<=o_copylev+1; + END IF; + + -- FIFOs + IF lev_dec_v='1' THEN + o_primv(0 TO 1)<=o_primv(1 TO 2); -- First buffer of line + o_lastv(0 TO 1)<=o_lastv(1 TO 2); -- Last buffer of line + o_bibv (0 TO 1)<=o_bibv (1 TO 2); -- Double buffer select + END IF; + + IF lev_inc_v='1' THEN + IF o_readlev=0 OR (o_readlev=1 AND lev_dec_v='1') THEN + o_primv(0)<=prim_v; + o_lastv(0)<=last_v; + o_bibv (0)<=bib_v; + ELSIF (o_readlev=1 AND lev_dec_v='0') OR + (o_readlev=2 AND lev_dec_v='1') THEN + o_primv(1)<=prim_v; + o_lastv(1)<=last_v; + o_bibv (1)<=bib_v; + END IF; + o_primv(2)<=prim_v; + o_lastv(2)<=last_v; + o_bibv (2)<=bib_v; + END IF; + + ------------------------------------------------------ + END IF; + END PROCESS Scalaire; + + o_h_poly_a<=to_integer(o_hfrac(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); + + ----------------------------------------------------------------------------- + -- Polyphase ROMs + Polikarpov:PROCESS(poly_clk) IS + BEGIN + IF rising_edge(poly_clk) THEN + IF poly_wr='1' THEN + poly_tdw(8+9*(3-to_integer(poly_a(1 DOWNTO 0))) DOWNTO + 9*(3-to_integer(poly_a(1 DOWNTO 0))))<=poly_dw; + END IF; + + poly_h_wr<=poly_wr AND NOT poly_a(FRAC+2); + poly_v_wr<=poly_wr AND poly_a(FRAC+2); + poly_a2<=poly_a(FRAC+1 DOWNTO 2); + + IF poly_h_wr='1' THEN + o_h_poly(to_integer(poly_a2))<=poly_tdw; + END IF; + IF poly_v_wr='1' THEN + o_v_poly(to_integer(poly_a2))<=poly_tdw; + END IF; + END IF; + END PROCESS Polikarpov; + + ----------------------------------------------------------------------------- + -- Horizontal Scaler + HSCAL:PROCESS(o_clk) IS + VARIABLE div_v : unsigned(18 DOWNTO 0); + VARIABLE dir_v : unsigned(11 DOWNTO 0); + BEGIN + IF rising_edge(o_clk) THEN + -- Pipeline signals + ----------------------------------- + -- Pipelined 6 bits non-restoring divider. Cycle 1 + dir_v:=x"000"; + div_v:=to_unsigned(o_hacc * 64,19); + + div_v:=div_v-to_unsigned(o_hsize*64,19); + dir_v(11):=NOT div_v(18); + IF div_v(18)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*32,19); + ELSE + div_v:=div_v+to_unsigned(o_hsize*32,19); + END IF; + dir_v(10):=NOT div_v(18); + o_div<=div_v; + o_dir<=dir_v; + + -- Cycle 2 + div_v:=o_div; + dir_v:=o_dir; + IF div_v(18)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*16,19); + ELSE + div_v:=div_v+to_unsigned(o_hsize*16,19); + END IF; + dir_v( 9):=NOT div_v(18); + + IF div_v(18)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*8,19); + ELSE + div_v:=div_v+to_unsigned(o_hsize*8,19); + END IF; + dir_v(8):=NOT div_v(18); + o_div2<=div_v; + o_dir2<=dir_v; + + -- Cycle 3 + div_v:=o_div2; + dir_v:=o_dir2; + IF FRAC>4 THEN + IF div_v(18)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*4,19); + ELSE + div_v:=div_v+to_unsigned(o_hsize*4,19); + END IF; + dir_v(7):=NOT div_v(18); + IF div_v(18)='0' THEN + div_v:=div_v-to_unsigned(o_hsize*2,19); + ELSE + div_v:=div_v+to_unsigned(o_hsize*2,19); + END IF; + dir_v(6):=NOT div_v(18); + END IF; + + ----------------------------------- + o_hfrac<=dir_v; + o_hfrac1<=o_hfrac; o_hfrac2<=o_hfrac1; o_hfrac3<=o_hfrac2; + + o_copyv(1 TO 7)<=o_copyv(0 TO 6); + + o_dcpt1<=o_dcpt; + IF o_dcpt1>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_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); + + -- 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); + END IF; + WHEN "01" => -- Bilinear + IF MASK(MASK_BILINEAR)='1' THEN + o_h_frac2<=bil_frac(o_hfrac1); + END IF; + WHEN "10" => -- Sharp Bilinear + IF MASK(MASK_SHARP_BILINEAR)='1' THEN + o_h_frac2<=sbil_frac2(o_hfrac1,o_h_sbil_t); + END IF; + WHEN OTHERS => + NULL; + END CASE; + + -- C3 : Opposite frac + o_h_bil_t<=bil_calc(o_h_frac2,o_hpixq); + + -- C4 : Nearest / Bilinear / Sharp Bilinear + o_h_bil_pix.r<=bound(o_h_bil_t.r,8+FRAC); + o_h_bil_pix.g<=bound(o_h_bil_t.g,8+FRAC); + o_h_bil_pix.b<=bound(o_h_bil_t.b,8+FRAC); + + -- BICUBIC ------------------------------------------- + -- 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))); + + -- 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); + + -- C4 : Bicubic final Y = X.T2 + A + o_h_bic_pix<=bic_calc3(o_hfrac3,o_h_bic_tt2,o_h_bic_abcd2); + + -- POLYPHASE ----------------------------------------- + -- C1 : Read memory + + -- C2 : Filter calc + o_h_poly_dr2<=o_h_poly_dr; + + -- C3 : Add + o_h_poly_t<=poly_calc1(o_h_poly_dr2,o_hpixq); + + -- C4 : Bounding + 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_ldw<=(x"00",x"00",x"00"); + + CASE o_hmode(2 DOWNTO 0) IS + WHEN "000" | "001" | "010" => -- Nearest | Bilinear | Sharp Bilinear + IF MASK(MASK_NEAREST)='1' OR + MASK(MASK_BILINEAR)='1' OR + MASK(MASK_SHARP_BILINEAR)='1' THEN + o_ldw<=o_h_bil_pix; + END IF; + WHEN "011" => -- BiCubic + IF MASK(MASK_BICUBIC)='1' THEN + o_ldw<=o_h_bic_pix; + END IF; + WHEN OTHERS => -- PolyPhase + IF MASK(MASK_POLY)='1' THEN + o_ldw<=o_h_poly_pix; + END IF; + END CASE; + ------------------------------------------------------ + END IF; + END PROCESS HSCAL; + + ----------------------------------------------------------------------------- + -- Line buffers 4 x OHRES x (R+G+B) + OLBUF:PROCESS(o_clk) IS + BEGIN + IF rising_edge(o_clk) THEN + -- WRITES + IF o_wr(0)='1' THEN o_line0(o_wadl)<=o_ldw; END IF; + IF o_wr(1)='1' THEN o_line1(o_wadl)<=o_ldw; END IF; + IF o_wr(2)='1' THEN o_line2(o_wadl)<=o_ldw; END IF; + IF o_wr(3)='1' THEN o_line3(o_wadl)<=o_ldw; END IF; + + -- READS + o_ldr0<=o_line0(o_radl); + o_ldr1<=o_line1(o_radl); + o_ldr2<=o_line2(o_radl); + o_ldr3<=o_line3(o_radl); + END IF; + END PROCESS OLBUF; + + ----------------------------------------------------------------------------- + -- Output video sweep + OSWEEP:PROCESS(o_clk) IS + BEGIN + IF rising_edge(o_clk) THEN + IF o_ce='1' THEN + -- Output pixels count + IF o_hcpt+1=o_vtotal THEN + o_vcpt_pre3<=0; + ELSE + o_vcpt_pre3<=(o_vcpt_pre3+1) MOD 4096; + END IF; + o_vcpt_pre2<=o_vcpt_pre3; + o_vcpt_pre<=o_vcpt_pre2; + o_vcpt<=o_vcpt_pre; + END IF; + + o_dev(0)<=to_std_logic(o_hcpt=o_hmin AND o_hcpt<=o_hmax AND + o_vcpt>=o_vmin AND o_vcpt<=o_vmax); + o_hsv(0)<=to_std_logic(o_hcpt>=o_hsstart AND o_hcpt=o_hsstart) OR + (o_vcpt>o_vsstart AND o_vcpt pixq_v:=(o_ldr0,o_ldr1,o_ldr2,o_ldr3); + WHEN "11" => pixq_v:=(o_ldr1,o_ldr2,o_ldr3,o_ldr0); + WHEN "00" => pixq_v:=(o_ldr2,o_ldr3,o_ldr0,o_ldr1); + WHEN OTHERS => pixq_v:=(o_ldr3,o_ldr0,o_ldr1,o_ldr2); + END CASE; + + o_vpixq<=pixq_v; + + -- Bottom edge : replicate last line + IF to_integer(o_vacpt)=o_ivsize THEN + o_vpixq(2)<=pixq_v(2); + END IF; + IF to_integer(o_vacpt)>=o_ivsize+1 THEN + o_vpixq(2)<=pixq_v(1); + o_vpixq(1)<=pixq_v(1); + END IF; + + o_vpixq1<=o_vpixq; + + -- NEAREST / BILINEAR / SHARP BILINEAR ------------- + -- C3 : Pre-calc Sharp Bilinear + o_v_sbil_t<=sbil_frac1(o_vfrac); + + -- C4 : Select + o_v_frac<=(OTHERS =>'0'); + CASE o_vmode(1 DOWNTO 0) IS + WHEN "00" => -- Nearest + IF MASK(MASK_NEAREST)='1' THEN + o_v_frac<=near_frac(o_vfrac); + END IF; + WHEN "01" => -- Bilinear + IF MASK(MASK_BILINEAR)='1' THEN + o_v_frac<=bil_frac(o_vfrac); + END IF; + WHEN "10" => -- Sharp Bilinear + IF MASK(MASK_SHARP_BILINEAR)='1' THEN + o_v_frac<=sbil_frac2(o_vfrac,o_v_sbil_t); + END IF; + WHEN OTHERS => NULL; + END CASE; + + o_v_bil_t<=bil_calc(o_v_frac,o_vpixq1); + + -- C6 : Nearest / Bilinear / Sharp Bilinear + o_v_bil_pix.r<=bound(o_v_bil_t.r,8+FRAC); + o_v_bil_pix.g<=bound(o_v_bil_t.g,8+FRAC); + o_v_bil_pix.b<=bound(o_v_bil_t.b,8+FRAC); + + -- BICUBIC ----------------------------------------- + -- C3 : Bicubic coefficients A,B,C,D + + -- C4 : Bicubic calc T1 = X.D + C + o_v_bic_abcd1<=bic_calc0(o_vfrac,o_vpixq); + o_v_bic_tt1<=bic_calc1(o_vfrac,bic_calc0(o_vfrac,o_vpixq)); + + -- C5 : Bicubic calc T2 = X.T1 + B + o_v_bic_abcd2<=o_v_bic_abcd1; + o_v_bic_tt2<=bic_calc2(o_vfrac,o_v_bic_tt1,o_v_bic_abcd1); + + -- C6 : Bicubic final Y = X.T2 + A + o_v_bic_pix<=bic_calc3(o_vfrac,o_v_bic_tt2,o_v_bic_abcd2); + + -- POLYPHASE --------------------------------------- + -- C3 : Read memory + + -- C4 : Filter calc + o_v_poly_dr2<=o_v_poly_dr; + + -- C5 : Add + o_v_poly_t<=poly_calc1(o_v_poly_dr2,o_vpixq1); + + -- C6 : Bounding + o_v_poly_pix<=poly_calc2(o_v_poly_t); + + -- CYCLE 6 ----------------------------------------- + o_hs<=o_hsv(5); + o_vs<=o_vsv(5); + o_de<=o_dev(5); + o_r<=x"00"; + o_g<=x"00"; + o_b<=x"00"; + + CASE o_vmode(2 DOWNTO 0) IS + WHEN "000" | "001" | "010" => -- Nearest | Bilinear | Sharp Bilinear + IF MASK(MASK_NEAREST)='1' OR + MASK(MASK_BILINEAR)='1' OR + MASK(MASK_SHARP_BILINEAR)='1' THEN + o_r<=o_v_bil_pix.r; + o_g<=o_v_bil_pix.g; + o_b<=o_v_bil_pix.b; + END IF; + WHEN "011" => -- BiCubic + IF MASK(MASK_BICUBIC)='1' THEN + o_r<=o_v_bic_pix.r; + o_g<=o_v_bic_pix.g; + o_b<=o_v_bic_pix.b; + END IF; + + WHEN OTHERS => -- Polyphase + IF MASK(MASK_POLY)='1' THEN + o_r<=o_v_poly_pix.r; + o_g<=o_v_poly_pix.g; + o_b<=o_v_poly_pix.b; + END IF; + END CASE; + + IF o_pev(5)='0' THEN + o_r<=x"00"; -- Border colour + o_g<=x"00"; + o_b<=x"00"; + END IF; + + ---------------------------------------------------- + END IF; + END IF; + + END PROCESS VSCAL; + + ----------------------------------------------------------------------------- + -- Low Lag syntoniser interface + -- i_syncline falling edge shall be aligned with o_vss raising edge. + + o_lltune<=(0 => NOT i_syncline, + 1 => '0', + 2 => i_inter, + 3 => i_flm, + 4 => o_vss, + 5 => '0', + 6 => i_clk, + 7 => o_clk, + OTHERS =>'0'); + + ---------------------------------------------------------------------------- +END ARCHITECTURE rtl; + diff --git a/sys/audio_out.v b/sys/audio_out.v new file mode 100644 index 0000000..545f3b9 --- /dev/null +++ b/sys/audio_out.v @@ -0,0 +1,157 @@ + +module audio_out +#( + parameter CLK_RATE = 50000000 +) +( + input reset, + input clk, + + //0 - 48KHz, 1 - 96KHz + input sample_rate, + + input [15:0] left_in, + input [15:0] right_in, + + // I2S + output i2s_bclk, + output i2s_lrclk, + output i2s_data, + + // SPDIF + output spdif, + + // Sigma-Delta DAC + output dac_l, + output dac_r +); + +localparam AUDIO_RATE = 48000; +localparam AUDIO_DW = 16; + +localparam CE_RATE = AUDIO_RATE*AUDIO_DW*8; +localparam FILTER_DIV = (CE_RATE/(AUDIO_RATE*32))-1; + +wire [31:0] real_ce = sample_rate ? {CE_RATE[30:0],1'b0} : CE_RATE[31:0]; + +reg mclk_ce; +always @(posedge clk) begin + reg [31:0] cnt; + + mclk_ce <= 0; + cnt = cnt + real_ce; + if(cnt >= CLK_RATE) begin + cnt = cnt - CLK_RATE; + mclk_ce <= 1; + end +end + +reg i2s_ce; +always @(posedge clk) begin + reg div; + i2s_ce <= 0; + if(mclk_ce) begin + div <= ~div; + i2s_ce <= div; + end +end + +reg lpf_ce; +always @(posedge clk) begin + integer div; + lpf_ce <= 0; + if(mclk_ce) begin + div <= div + 1; + if(div == FILTER_DIV) begin + div <= 0; + lpf_ce <= 1; + end + end +end + +i2s i2s +( + .reset(reset), + + .clk(clk), + .ce(i2s_ce), + + .sclk(i2s_bclk), + .lrclk(i2s_lrclk), + .sdata(i2s_data), + + .left_chan(al), + .right_chan(ar) +); + +spdif toslink +( + .rst_i(reset), + + .clk_i(clk), + .bit_out_en_i(mclk_ce), + + .sample_i({ar,al}), + .spdif_o(spdif) +); + +sigma_delta_dac #(15) sd_l +( + .CLK(clk), + .RESET(reset), + .DACin({~al[15], al[14:0]}), + .DACout(dac_l) +); + +sigma_delta_dac #(15) sd_r +( + .CLK(clk), + .RESET(reset), + .DACin({~ar[15], ar[14:0]}), + .DACout(dac_r) +); + +wire [15:0] al, ar; +lpf_aud lpf_l +( + .CLK(clk), + .CE(lpf_ce), + .IDATA(left_in), + .ODATA(al) +); + +lpf_aud lpf_r +( + .CLK(clk), + .CE(lpf_ce), + .IDATA(right_in), + .ODATA(ar) +); + +endmodule + +module lpf_aud +( + input CLK, + input CE, + input [15:0] IDATA, + output reg [15:0] ODATA +); + +reg [511:0] acc; +reg [20:0] sum; + +always @(*) begin + integer i; + sum = 0; + for (i = 0; i < 32; i = i+1) sum = sum + {{5{acc[(i*16)+15]}}, acc[i*16 +:16]}; +end + +always @(posedge CLK) begin + if(CE) begin + acc <= {acc[495:0], IDATA}; + ODATA <= sum[20:5]; + end +end + +endmodule diff --git a/sys/hdmi_config.sv b/sys/hdmi_config.sv index 0321792..476d72d 100644 --- a/sys/hdmi_config.sv +++ b/sys/hdmi_config.sv @@ -142,9 +142,9 @@ wire [15:0] init_data[58] = 16'hAA00, // ADI required Write. 16'hAB40, // ADI required Write. - {8'hAF, 6'b0001_01,~dvi_mode,1'b0}, // [7]=0 HDCP Disabled. + {8'hAF, 6'b0000_01,~dvi_mode,1'b0}, // [7]=0 HDCP Disabled. // [6:5] must be b00! - // [4]=1 Current frame IS HDCP encrypted!??? (HDCP disabled anyway?) + // [4]=0 Current frame is unencrypted // [3:2] must be b01! // [1]=1 HDMI Mode. // [0] must be b0! diff --git a/sys/hdmi_lite.sv b/sys/hdmi_lite.sv deleted file mode 100644 index 96eb441..0000000 --- a/sys/hdmi_lite.sv +++ /dev/null @@ -1,395 +0,0 @@ -//============================================================================ -// -// HDMI Lite output module -// Copyright (C) 2017 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. -// -//============================================================================ - - -module hdmi_lite -( - input reset, - - input clk_video, - input ce_pixel, - input video_vs, - input video_de, - input [23:0] video_d, - - input clk_hdmi, - input hdmi_hde, - input hdmi_vde, - output reg hdmi_de, - output [23:0] hdmi_d, - - input [11:0] screen_w, - input [11:0] screen_h, - input quadbuf, - - // 0-3 => scale 1-4 - input [1:0] scale_x, - input [1:0] scale_y, - input scale_auto, - - input clk_vbuf, - output [27:0] vbuf_address, - input [127:0] vbuf_readdata, - output [127:0] vbuf_writedata, - output [7:0] vbuf_burstcount, - output [15:0] vbuf_byteenable, - input vbuf_waitrequest, - input vbuf_readdatavalid, - output reg vbuf_read, - output reg vbuf_write -); - -localparam [7:0] burstsz = 64; - -reg [1:0] nbuf = 0; -wire [27:0] read_buf = {4'd2, 3'b000, (quadbuf ? nbuf-2'd1 : 2'b00), 19'd0}; -wire [27:0] write_buf = {4'd2, 3'b000, (quadbuf ? nbuf+2'd1 : 2'b00), 19'd0}; - -assign vbuf_address = vbuf_write ? vbuf_waddress : vbuf_raddress; -assign vbuf_burstcount = vbuf_write ? vbuf_wburstcount : vbuf_rburstcount; - -wire [95:0] hf_out; -wire [7:0] hf_usedw; -reg hf_reset = 0; - -vbuf_fifo out_fifo -( - .aclr(hf_reset), - - .wrclk(clk_vbuf), - .wrreq(vbuf_readdatavalid), - .data({vbuf_readdata[96+:24],vbuf_readdata[64+:24],vbuf_readdata[32+:24],vbuf_readdata[0+:24]}), - .wrusedw(hf_usedw), - - .rdclk(~clk_hdmi), - .rdreq(hf_rdreq), - .q(hf_out) -); - -reg [11:0] rd_stride; -wire [7:0] rd_burst = (burstsz < rd_stride) ? burstsz : rd_stride[7:0]; - -reg [27:0] vbuf_raddress; -reg [7:0] vbuf_rburstcount; -always @(posedge clk_vbuf) begin - reg [18:0] rdcnt; - reg [7:0] bcnt; - reg vde1, vde2; - reg [1:0] mcnt; - reg [1:0] my; - reg [18:0] fsz; - reg [11:0] strd; - - vde1 <= hdmi_vde; - vde2 <= vde1; - - if(vbuf_readdatavalid) begin - rdcnt <= rdcnt + 1'd1; - if(bcnt) bcnt <= bcnt - 1'd1; - vbuf_raddress <= vbuf_raddress + 1'd1; - end - - if(!bcnt && reading) reading <= 0; - - vbuf_read <= 0; - if(~vbuf_waitrequest) begin - if(!hf_reset && rdcnt=off_x) && (x<(vh_width+off_x)) && (y>=off_y) && (y<(vh_height+off_y)) && !hload && !pcnt; -wire de_in = hdmi_hde & hdmi_vde; - -always @(posedge clk_hdmi) begin - reg [71:0] px_out; - reg [1:0] mx; - reg vde; - - vde <= hdmi_vde; - - if(vde & ~hdmi_vde) begin - off_x <= (screen_w>v_width) ? (screen_w - v_width)>>1 : 12'd0; - off_y <= (screen_h>v_height) ? (screen_h - v_height)>>1 : 12'd0; - vh_height <= v_height; - vh_width <= v_width; - mx <= mult_x; - end - - pcnt <= pcnt + 1'd1; - if(pcnt == mx) begin - pcnt <= 0; - hload <= hload + 1'd1; - end - - if(~de_in || x (screen_h/2)) ? 2'b00 : (video_y > (screen_h/3)) ? 2'b01 : (video_y > (screen_h/4)) ? 2'b10 : 2'b11; -wire [1:0] tm_x = (l1_width > (screen_w/2)) ? 2'b00 : (l1_width > (screen_w/3)) ? 2'b01 : (l1_width > (screen_w/4)) ? 2'b10 : 2'b11; -wire [1:0] tm_xy = (tm_x < tm_y) ? tm_x : tm_y; -wire [1:0] tmf_y = scale_auto ? tm_xy : scale_y; -wire [1:0] tmf_x = scale_auto ? tm_xy : scale_x; -wire [11:0] t_height = video_y + (tmf_y[0] ? video_y : 12'd0) + (tmf_y[1] ? video_y<<1 : 12'd0); -wire [11:0] t_width = l1_width + (tmf_x[0] ? l1_width : 12'd0) + (tmf_x[1] ? l1_width<<1 : 12'd0); -wire [23:0] t_fsz = l1_stride * t_height; - -reg [11:0] l1_width; -reg [11:0] l1_stride; -always @(posedge clk_video) begin - reg [7:0] loaded = 0; - reg [11:0] strd = 0; - reg old_de = 0; - reg old_vs = 0; - - old_vs <= video_vs; - if(~old_vs & video_vs) begin - cur_addr<= write_buf; - video_x <= 0; - video_y <= 0; - loaded <= 0; - strd <= 0; - nbuf <= nbuf + 1'd1; - - stride <= l1_stride; - framesz <= t_fsz[18:0]; - v_height<= t_height; - v_width <= t_width; - mult_x <= tmf_x; - mult_y <= tmf_y; - end - - if(pix_wr) begin - case(video_x[1:0]) - 0: pix_acc <= video_d; // zeroes upper bits too - 1: pix_acc[47:24] <= video_d; - 2: pix_acc[71:48] <= video_d; - 3: loaded <= loaded + 1'd1; - endcase - if(video_x= burstsz) || (old_de & ~video_de)) begin - if(loaded + infifo_tail) begin - flush_size <= loaded + infifo_tail; - flush_addr <= cur_addr; - flush_req <= ~flush_req; - loaded <= 0; - strd <= strd + loaded; - end - - cur_addr <= cur_addr + loaded + infifo_tail; - if(~video_de) begin - if(video_y -// Copyright (c) 2017 Sorgelig (port to DE10-nano) +// Copyright (c) 2017,2018 Sorgelig // // This source file is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published @@ -40,13 +40,26 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0) 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 [15:0] joystick_analog_0, output reg [15:0] joystick_analog_1, + output reg [15:0] joystick_analog_2, + output reg [15:0] joystick_analog_3, + output reg [15:0] joystick_analog_4, + output reg [15:0] joystick_analog_5, output [1:0] buttons, output forced_scandoubler, output reg [31:0] status, + input [31:0] status_in, + input status_set, + + //toggle to force notify of video mode change + input new_vmode, // SD config output reg [VD:0] img_mounted, // signaling that new image has been mounted @@ -58,7 +71,7 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0) input [VD:0] sd_rd, // only single sd_rd can be active at any given time input [VD:0] sd_wr, // only single sd_wr can be active at any given time output reg sd_ack, - + // do not use in new projects. // CID and CSD are fake except CSD image size field. input sd_conf, @@ -76,6 +89,7 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0) output reg ioctl_wr, output reg [24:0] ioctl_addr, // in WIDE mode address will be incremented by 2 output reg [DW:0] ioctl_dout, + output reg [31:0] ioctl_file_ext, input ioctl_wait, // RTC MSM6242B layout @@ -84,6 +98,9 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0) // Seconds since 1970-01-01 00:00:00 output reg [32:0] TIMESTAMP, + // UART flags + input [15:0] uart_mode, + // ps2 keyboard emulation output ps2_kbd_clk_out, output ps2_kbd_data_out, @@ -102,7 +119,7 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0) // [8] - extended, [9] - pressed, [10] - toggles with every press/release output reg [10:0] ps2_key = 0, - + // [24] - toggles with every event output reg [24:0] ps2_mouse = 0 ); @@ -131,7 +148,7 @@ assign forced_scandoubler = cfg[4]; //cfg[5] - ypbpr handled in sys_top // command byte read by the io controller -wire [15:0] sd_cmd = +wire [15:0] sd_cmd = { 2'b00, (VDNUM>=4) ? sd_wr[3] : 1'b0, @@ -141,7 +158,7 @@ wire [15:0] sd_cmd = (VDNUM>=4) ? sd_rd[3] : 1'b0, (VDNUM>=3) ? sd_rd[2] : 1'b0, (VDNUM>=2) ? sd_rd[1] : 1'b0, - + 4'h5, sd_conf, 1'b1, sd_wr[0], sd_rd[0] @@ -164,7 +181,7 @@ integer hcnt; always @(posedge clk_vid) begin integer vcnt; - reg old_vs= 0, old_de = 0; + reg old_vs= 0, old_de = 0, old_vmode = 0; reg calch = 0; if(ce_pix) begin @@ -177,7 +194,8 @@ always @(posedge clk_vid) begin if(old_vs & ~vs) begin if(hcnt && vcnt) begin - if(vid_hcnt != hcnt || vid_vcnt != vcnt) vid_nres <= vid_nres + 1'd1; + 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; end @@ -256,13 +274,22 @@ always@(posedge clk_sys) begin reg [2:0] b_wr; reg [2:0] stick_idx; reg ps2skip = 0; + reg [3:0] stflg = 0; + reg [31:0] status_req; + reg old_status_set = 0; + + old_status_set <= status_set; + if(~old_status_set & status_set) begin + stflg <= stflg + 1'd1; + status_req <= status_in; + end sd_buff_wr <= b_wr[0]; 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(~io_enable) begin if(cmd == 4 && !ps2skip) ps2_mouse[24] <= ~ps2_mouse[24]; if(cmd == 5 && !ps2skip) begin @@ -292,6 +319,8 @@ always@(posedge clk_sys) begin 'h19: sd_ack_conf <= 1; 'h17, 'h18: sd_ack <= 1; + 'h29: io_dout <= {4'hA, stflg}; + 'h2B: io_dout <= 1; endcase sd_buff_addr <= 0; @@ -301,11 +330,15 @@ always@(posedge clk_sys) begin case(cmd) // buttons and switches - 'h01: cfg <= io_din[7:0]; + '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; - // store incoming ps2 mouse bytes + // store incoming ps2 mouse bytes 'h04: begin mouse_data <= io_din[7:0]; mouse_we <= 1; @@ -319,7 +352,7 @@ always@(posedge clk_sys) begin end end - // store incoming ps2 keyboard bytes + // store incoming ps2 keyboard bytes '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]}; @@ -327,20 +360,15 @@ always@(posedge clk_sys) begin kbd_we <= 1; end - // reading config string - 'h14: begin - // returning a byte from string - if(byte_cnt < STRLEN + 1) io_dout[7:0] <= conf_str[(STRLEN - byte_cnt)<<3 +:8]; - end + // reading config string, returning a byte from string + 'h14: if(byte_cnt < STRLEN + 1) io_dout[7:0] <= conf_str[(STRLEN - byte_cnt)<<3 +:8]; // reading sd card status - 'h16: begin - case(byte_cnt) + 'h16: case(byte_cnt) 1: io_dout <= sd_cmd; 2: io_dout <= sd_lba[15:0]; 3: io_dout <= sd_lba[31:16]; endcase - end // send SD config IO -> FPGA // flag that download begins @@ -361,14 +389,17 @@ always@(posedge clk_sys) begin end // joystick analog - 'h1a: begin - // first byte is joystick index - if(byte_cnt == 1) stick_idx <= io_din[2:0]; - if(byte_cnt == 2) begin - if(stick_idx == 0) joystick_analog_0 <= io_din; - if(stick_idx == 1) joystick_analog_1 <= io_din; - end - end + 'h1a: case(byte_cnt) + 1: stick_idx <= io_din[2:0]; // first byte is joystick index + 2: case(stick_idx) + 0: joystick_analog_0 <= io_din; + 1: joystick_analog_1 <= io_din; + 2: joystick_analog_2 <= io_din; + 3: joystick_analog_3 <= io_din; + 4: joystick_analog_4 <= io_din; + 5: joystick_analog_5 <= io_din; + endcase + endcase // notify image selection 'h1c: begin @@ -387,41 +418,46 @@ 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: begin - if(byte_cnt == 1) begin + '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; end - end //RTC 'h22: RTC[(byte_cnt-6'd1)<<4 +:16] <= io_din; //Video res. - 'h23: begin - case(byte_cnt) - 1: io_dout <= vid_nres; - 2: io_dout <= vid_hcnt[15:0]; - 3: io_dout <= vid_hcnt[31:16]; - 4: io_dout <= vid_vcnt[15:0]; - 5: io_dout <= vid_vcnt[31:16]; - 6: io_dout <= vid_htime[15:0]; - 7: io_dout <= vid_htime[31:16]; - 8: io_dout <= vid_vtime[15:0]; - 9: io_dout <= vid_vtime[31:16]; - 10: io_dout <= vid_pix[15:0]; - 11: io_dout <= vid_pix[31:16]; - 12: io_dout <= vid_vtime_hdmi[15:0]; - 13: io_dout <= vid_vtime_hdmi[31:16]; - endcase - end + 'h23: case(byte_cnt) + 1: io_dout <= vid_nres; + 2: io_dout <= vid_hcnt[15:0]; + 3: io_dout <= vid_hcnt[31:16]; + 4: io_dout <= vid_vcnt[15:0]; + 5: io_dout <= vid_vcnt[31:16]; + 6: io_dout <= vid_htime[15:0]; + 7: io_dout <= vid_htime[31:16]; + 8: io_dout <= vid_vtime[15:0]; + 9: io_dout <= vid_vtime[31:16]; + 10: io_dout <= vid_pix[15:0]; + 11: io_dout <= vid_pix[31:16]; + 12: io_dout <= vid_vtime_hdmi[15:0]; + 13: io_dout <= vid_vtime_hdmi[31:16]; + endcase //RTC 'h24: TIMESTAMP[(byte_cnt-6'd1)<<4 +:16] <= io_din; + + //UART flags + 'h28: io_dout <= uart_mode; + + //status set + 'h29: case(byte_cnt) + 1: io_dout <= status_req[15:0]; + 2: io_dout <= status_req[31:16]; + endcase endcase end end @@ -455,7 +491,7 @@ ps2_device keyboard .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), @@ -492,9 +528,11 @@ ps2_device mouse localparam UIO_FILE_TX = 8'h53; localparam UIO_FILE_TX_DAT = 8'h54; localparam UIO_FILE_INDEX = 8'h55; +localparam UIO_FILE_INFO = 8'h56; always@(posedge clk_sys) begin reg [15:0] cmd; + reg [2:0] cnt; reg has_cmd; reg [24:0] addr; reg wr; @@ -509,9 +547,19 @@ always@(posedge clk_sys) begin if(!has_cmd) begin cmd <= io_din; has_cmd <= 1; + cnt <= 0; end else begin case(cmd) + UIO_FILE_INFO: + if(~cnt[1]) begin + case(cnt) + 0: ioctl_file_ext[31:16] <= io_din; + 1: ioctl_file_ext[15:00] <= io_din; + endcase + cnt <= cnt + 1'd1; + end + UIO_FILE_INDEX: begin ioctl_index <= io_din[7:0]; @@ -521,7 +569,7 @@ always@(posedge clk_sys) begin begin if(io_din[7:0]) begin addr <= 0; - ioctl_download <= 1; + ioctl_download <= 1; end else begin ioctl_addr <= addr; ioctl_download <= 0; @@ -560,7 +608,7 @@ module ps2_device #(parameter PS2_FIFO_BITS=5) input ps2_clk_in, input ps2_dat_in, - + output [8:0] rdata, input rd ); @@ -615,7 +663,7 @@ always@(posedge clk_sys) begin rx_state <= rx_state + 1'b1; rx_cnt <= 0; end - + 2: begin if(rx_cnt <= 7) data <= {d1, data[7:1]}; else rx_state <= rx_state + 1'b1; @@ -626,7 +674,7 @@ always@(posedge clk_sys) begin rx_state <= rx_state + 1'b1; ps2_dat_out <= 0; end - + 4: begin ps2_dat_out <= 1; has_data <= 1; @@ -661,7 +709,7 @@ always@(posedge clk_sys) begin if((tx_state >= 1)&&(tx_state < 9)) begin ps2_dat_out <= tx_byte[0]; // data bits tx_byte[6:0] <= tx_byte[7:1]; // shift down - if(tx_byte[0]) + if(tx_byte[0]) parity <= !parity; end diff --git a/sys/hq2x.sv b/sys/hq2x.sv index 02b8543..ece54f9 100644 --- a/sys/hq2x.sv +++ b/sys/hq2x.sv @@ -1,7 +1,7 @@ // // // Copyright (c) 2012-2013 Ludvig Strigeus -// Copyright (c) 2017 Sorgelig +// Copyright (c) 2017,2018 Sorgelig // // This program is GPL Licensed. See COPYING for the full license. // @@ -12,36 +12,24 @@ `timescale 1 ps / 1 ps // synopsys translate_on -`define BITS_TO_FIT(N) ( \ - N <= 2 ? 0 : \ - N <= 4 ? 1 : \ - N <= 8 ? 2 : \ - N <= 16 ? 3 : \ - N <= 32 ? 4 : \ - N <= 64 ? 5 : \ - N <= 128 ? 6 : \ - N <= 256 ? 7 : \ - N <= 512 ? 8 : \ - N <= 1024 ? 9 : \ - N <= 2048 ?10 : 11 ) - module Hq2x #(parameter LENGTH, parameter HALF_DEPTH) ( - input clk, - input ce_x4, - input [DWIDTH:0] inputpixel, - input mono, - input disable_hq2x, - input reset_frame, - input reset_line, - input [1:0] read_y, - input [AWIDTH+1:0] read_x, - output [DWIDTH:0] outpixel + input clk, + input ce_x4, + input [DWIDTH:0] inputpixel, + input mono, + input disable_hq2x, + input reset_frame, + input reset_line, + input [1:0] read_y, + input hblank, + output [DWIDTH:0] outpixel ); -localparam AWIDTH = `BITS_TO_FIT(LENGTH); +localparam AWIDTH = $clog2(LENGTH)-1; localparam DWIDTH = HALF_DEPTH ? 11 : 23; +localparam DWIDTH1 = DWIDTH+1; wire [5:0] hqTable[256] = '{ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, @@ -62,30 +50,29 @@ wire [5:0] hqTable[256] = '{ 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43 }; -reg [23:0] Prev0, Prev1, Prev2, Curr0, Curr1, Next0, Next1, Next2; +reg [23:0] Prev0, Prev1, Prev2, Curr0, Curr1, Curr2, Next0, Next1, Next2; reg [23:0] A, B, D, F, G, H; reg [7:0] pattern, nextpatt; -reg [1:0] i; -reg [7:0] y; +reg [1:0] cyc; -wire curbuf = y[0]; +reg curbuf; reg prevbuf = 0; wire iobuf = !curbuf; wire diff0, diff1; -DiffCheck diffcheck0(Curr1, (i == 0) ? Prev0 : (i == 1) ? Curr0 : (i == 2) ? Prev2 : Next1, diff0); -DiffCheck diffcheck1(Curr1, (i == 0) ? Prev1 : (i == 1) ? Next0 : (i == 2) ? Curr2 : Next2, diff1); +DiffCheck diffcheck0(Curr1, (cyc == 0) ? Prev0 : (cyc == 1) ? Curr0 : (cyc == 2) ? Prev2 : Next1, diff0); +DiffCheck diffcheck1(Curr1, (cyc == 0) ? Prev1 : (cyc == 1) ? Next0 : (cyc == 2) ? Curr2 : Next2, diff1); wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]}; -wire [23:0] X = (i == 0) ? A : (i == 1) ? Prev1 : (i == 2) ? Next1 : G; -wire [23:0] blend_result; -Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result); +wire [23:0] X = (cyc == 0) ? A : (cyc == 1) ? Prev1 : (cyc == 2) ? Next1 : G; +wire [23:0] blend_result_pre; +Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result_pre); -reg Curr2_addr1; -reg [AWIDTH:0] Curr2_addr2; -wire [23:0] Curr2 = HALF_DEPTH ? h2rgb(Curr2tmp) : Curr2tmp; -wire [DWIDTH:0] Curr2tmp; +wire [DWIDTH:0] Curr20tmp; +wire [23:0] Curr20 = HALF_DEPTH ? h2rgb(Curr20tmp) : Curr20tmp; +wire [DWIDTH:0] Curr21tmp; +wire [23:0] Curr21 = HALF_DEPTH ? h2rgb(Curr21tmp) : Curr21tmp; reg [AWIDTH:0] wrin_addr2; reg [DWIDTH:0] wrpix; @@ -109,9 +96,11 @@ hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in ( .clk(clk), - .rdaddr(Curr2_addr2), - .rdbuf(Curr2_addr1), - .q(Curr2tmp), + .rdaddr(offs), + .rdbuf0(prevbuf), + .rdbuf1(curbuf), + .q0(Curr20tmp), + .q1(Curr21tmp), .wraddr(wrin_addr2), .wrbuf(iobuf), @@ -119,27 +108,31 @@ hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in .wren(wrin_en) ); -reg [1:0] wrout_addr1; -reg [AWIDTH+1:0] wrout_addr2; -reg wrout_en; -reg [DWIDTH:0] wrdata; +reg [AWIDTH+1:0] read_x; +reg [AWIDTH+1:0] wrout_addr; +reg wrout_en; +reg [DWIDTH1*4-1:0] wrdata, wrdata_pre; +wire [DWIDTH1*4-1:0] outpixel_x4; +reg [DWIDTH1*2-1:0] outpixel_x2; -hq2x_out #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_out +assign outpixel = read_x[0] ? outpixel_x2[DWIDTH1*2-1:DWIDTH1] : outpixel_x2[DWIDTH:0]; + +hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH+1), .DWIDTH(DWIDTH1*4-1)) hq2x_out ( - .clk(clk), + .clock(clk), - .rdaddr(read_x), - .rdbuf(read_y), - .q(outpixel), + .rdaddress({read_x[AWIDTH+1:1],read_y[1]}), + .q(outpixel_x4), - .wraddr(wrout_addr2), - .wrbuf(wrout_addr1), .data(wrdata), + .wraddress(wrout_addr), .wren(wrout_en) ); +wire [DWIDTH:0] blend_result = HALF_DEPTH ? rgb2h(blend_result_pre) : blend_result_pre[DWIDTH:0]; + +reg [AWIDTH:0] offs; always @(posedge clk) begin - reg [AWIDTH:0] offs; reg old_reset_line; reg old_reset_frame; @@ -149,36 +142,33 @@ always @(posedge clk) begin 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(~&offs) begin - if (i == 0) begin - Curr2_addr1 <= prevbuf; - Curr2_addr2 <= offs; - end - if (i == 1) begin - Prev2 <= Curr2; - Curr2_addr1 <= curbuf; - Curr2_addr2 <= offs; - end - if (i == 2) begin + if (cyc == 1) begin + Prev2 <= Curr20; + Curr2 <= Curr21; Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel; wrpix <= inputpixel; wrin_addr2 <= offs; wrin_en <= 1; end - if (i == 3) begin + + case({cyc[1],^cyc}) + 0: wrdata[DWIDTH:0] <= blend_result; + 1: wrdata[DWIDTH1+DWIDTH:DWIDTH1] <= blend_result; + 2: wrdata[DWIDTH1*2+DWIDTH:DWIDTH1*2] <= blend_result; + 3: wrdata[DWIDTH1*3+DWIDTH:DWIDTH1*3] <= blend_result; + endcase + + if(cyc==3) begin offs <= offs + 1'd1; + wrout_addr <= {offs, curbuf}; + wrout_en <= 1; end - - if(HALF_DEPTH) wrdata <= rgb2h(blend_result); - else wrdata <= blend_result; - - wrout_addr1 <= {curbuf, i[1]}; - wrout_addr2 <= {offs, i[1]^i[0]}; - wrout_en <= 1; end - if(i==3) begin + 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}; {B, F, H, D} <= {Prev1, Curr2, Next1, Curr0}; @@ -190,18 +180,22 @@ always @(posedge clk) begin {B, F, H, D} <= {F, H, D, B}; end - i <= i + 1'b1; + cyc <= cyc + 1'b1; if(old_reset_line && ~reset_line) begin old_reset_frame <= reset_frame; offs <= 0; - i <= 0; - y <= y + 1'd1; + cyc <= 0; + curbuf <= ~curbuf; prevbuf <= curbuf; + {Prev0, Prev1, Prev2, Curr0, Curr1, Curr2, Next0, Next1, Next2} <= '0; if(old_reset_frame & ~reset_frame) begin - y <= 0; + curbuf <= 0; prevbuf <= 0; end end + + if(~hblank & ~&read_x) read_x <= read_x + 1'd1; + if(hblank) read_x <= 0; old_reset_line <= reset_line; end @@ -216,8 +210,8 @@ module hq2x_in #(parameter LENGTH, parameter DWIDTH) input clk, input [AWIDTH:0] rdaddr, - input rdbuf, - output[DWIDTH:0] q, + input rdbuf0, rdbuf1, + output[DWIDTH:0] q0,q1, input [AWIDTH:0] wraddr, input wrbuf, @@ -225,40 +219,15 @@ module hq2x_in #(parameter LENGTH, parameter DWIDTH) input wren ); - localparam AWIDTH = `BITS_TO_FIT(LENGTH); - wire [DWIDTH:0] out[2]; - assign q = out[rdbuf]; + localparam AWIDTH = $clog2(LENGTH)-1; + wire [DWIDTH:0] out[2]; + assign q0 = out[rdbuf0]; + assign q1 = out[rdbuf1]; hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]); hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]); endmodule - -module hq2x_out #(parameter LENGTH, parameter DWIDTH) -( - input clk, - - input [AWIDTH:0] rdaddr, - input [1:0] rdbuf, - output[DWIDTH:0] q, - - input [AWIDTH:0] wraddr, - input [1:0] wrbuf, - input [DWIDTH:0] data, - input wren -); - - localparam AWIDTH = `BITS_TO_FIT(LENGTH*2); - wire [DWIDTH:0] out[4]; - assign q = out[rdbuf]; - - hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]); - hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]); - hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf2(clk,data,rdaddr,wraddr,wren && (wrbuf == 2),out[2]); - hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf3(clk,data,rdaddr,wraddr,wren && (wrbuf == 3),out[3]); -endmodule - - module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH) ( input clock, diff --git a/sys/i2s.v b/sys/i2s.v index b4c2d95..7d4517b 100644 --- a/sys/i2s.v +++ b/sys/i2s.v @@ -1,136 +1,54 @@ - -module i2s -#( - parameter CLK_RATE = 50000000, - parameter AUDIO_DW = 16, - parameter AUDIO_RATE = 96000 -) -( - input reset, - input clk_sys, - input half_rate, - - output reg sclk, - output reg lrclk, - output reg sdata, - - input [AUDIO_DW-1:0] left_chan, - input [AUDIO_DW-1:0] right_chan -); - -localparam WHOLE_CYCLES = (CLK_RATE) / (AUDIO_RATE*AUDIO_DW*4); -localparam ERROR_BASE = 10000; -localparam [63:0] ERRORS_PER_BIT = ((CLK_RATE * ERROR_BASE) / (AUDIO_RATE*AUDIO_DW*4)) - (WHOLE_CYCLES * ERROR_BASE); - -reg lpf_ce; -wire [AUDIO_DW-1:0] al, ar; - -lpf_i2s lpf_l -( - .CLK(clk_sys), - .CE(lpf_ce), - .IDATA(left_chan), - .ODATA(al) -); - -lpf_i2s lpf_r -( - .CLK(clk_sys), - .CE(lpf_ce), - - .IDATA(right_chan), - .ODATA(ar) -); - -always @(posedge clk_sys) begin - reg [31:0] count_q; - reg [31:0] error_q; - reg [7:0] bit_cnt; - reg skip = 0; - - reg [AUDIO_DW-1:0] left; - reg [AUDIO_DW-1:0] right; - - reg msclk; - reg ce; - - lpf_ce <= 0; - - if (reset) begin - count_q <= 0; - error_q <= 0; - ce <= 0; - bit_cnt <= 1; - lrclk <= 1; - sclk <= 1; - msclk <= 1; - end - else - begin - if(count_q == WHOLE_CYCLES-1) begin - if (error_q < (ERROR_BASE - ERRORS_PER_BIT)) begin - error_q <= error_q + ERRORS_PER_BIT[31:0]; - count_q <= 0; - end else begin - error_q <= error_q + ERRORS_PER_BIT[31:0] - ERROR_BASE; - count_q <= count_q + 1; - end - end else if(count_q == WHOLE_CYCLES) begin - count_q <= 0; - end else begin - count_q <= count_q + 1; - end - - sclk <= msclk; - if(!count_q) begin - ce <= ~ce; - if(~half_rate || ce) begin - msclk <= ~msclk; - if(msclk) begin - skip <= ~skip; - if(skip) lpf_ce <= 1; - if(bit_cnt >= AUDIO_DW) begin - bit_cnt <= 1; - lrclk <= ~lrclk; - if(lrclk) begin - left <= al; - right <= ar; - end - end - else begin - bit_cnt <= bit_cnt + 1'd1; - end - sdata <= lrclk ? right[AUDIO_DW - bit_cnt] : left[AUDIO_DW - bit_cnt]; - end - end - end - end -end - -endmodule - -module lpf_i2s -( - input CLK, - input CE, - input [15:0] IDATA, - output reg [15:0] ODATA -); - -reg [511:0] acc; -reg [20:0] sum; - -always @(*) begin - integer i; - sum = 0; - for (i = 0; i < 32; i = i+1) sum = sum + {{5{acc[(i*16)+15]}}, acc[i*16 +:16]}; -end - -always @(posedge CLK) begin - if(CE) begin - acc <= {acc[495:0], IDATA}; - ODATA <= sum[20:5]; - end -end - -endmodule + +module i2s +#( + parameter AUDIO_DW = 16 +) +( + input reset, + input clk, + input ce, + + output reg sclk, + output reg lrclk, + output reg sdata, + + input [AUDIO_DW-1:0] left_chan, + input [AUDIO_DW-1:0] right_chan +); + +always @(posedge clk) begin + reg [7:0] bit_cnt; + reg msclk; + + reg [AUDIO_DW-1:0] left; + reg [AUDIO_DW-1:0] right; + + if (reset) begin + bit_cnt <= 1; + lrclk <= 1; + sclk <= 1; + msclk <= 1; + end + else begin + sclk <= msclk; + if(ce) begin + msclk <= ~msclk; + if(msclk) begin + if(bit_cnt >= AUDIO_DW) begin + bit_cnt <= 1; + lrclk <= ~lrclk; + if(lrclk) begin + left <= left_chan; + right <= right_chan; + end + end + else begin + bit_cnt <= bit_cnt + 1'd1; + end + sdata <= lrclk ? right[AUDIO_DW - bit_cnt] : left[AUDIO_DW - bit_cnt]; + end + end + end +end + +endmodule diff --git a/sys/ip/avalon_combiner.v b/sys/ip/avalon_combiner.v deleted file mode 100644 index 164906c..0000000 --- a/sys/ip/avalon_combiner.v +++ /dev/null @@ -1,60 +0,0 @@ -// avalon_combiner.v - -`timescale 1 ps / 1 ps -module avalon_combiner -( - input wire clk, // clock.clk - input wire rst, // reset.reset - - output wire [6:0] mixer_address, // ctl_mixer.address - output wire [3:0] mixer_byteenable, // .byteenable - output wire mixer_write, // .write - output wire [31:0] mixer_writedata, // .writedata - input wire mixer_waitrequest, // .waitrequest - - output wire [6:0] scaler_address, // ctl_scaler.address - output wire [3:0] scaler_byteenable, // .byteenable - input wire scaler_waitrequest, // .waitrequest - output wire scaler_write, // .write - output wire [31:0] scaler_writedata, // .writedata - - output wire [7:0] video_address, // ctl_video.address - output wire [3:0] video_byteenable, // .byteenable - input wire video_waitrequest, // .waitrequest - output wire video_write, // .write - output wire [31:0] video_writedata, // .writedata - - output wire clock, // control.clock - output wire reset, // .reset - input wire [8:0] address, // .address - input wire write, // .write - input wire [31:0] writedata, // .writedata - output wire waitrequest // .waitrequest -); - -assign clock = clk; -assign reset = rst; - -assign mixer_address = address[6:0]; -assign scaler_address = address[6:0]; -assign video_address = address[7:0]; - -assign mixer_byteenable = 4'b1111; -assign scaler_byteenable = 4'b1111; -assign video_byteenable = 4'b1111; - -wire en_scaler = (address[8:7] == 0); -wire en_mixer = (address[8:7] == 1); -wire en_video = address[8]; - -assign mixer_write = en_mixer & write; -assign scaler_write = en_scaler & write; -assign video_write = en_video & write; - -assign mixer_writedata = writedata; -assign scaler_writedata = writedata; -assign video_writedata = writedata; - -assign waitrequest = (en_mixer & mixer_waitrequest) | (en_scaler & scaler_waitrequest) | (en_video & video_waitrequest); - -endmodule diff --git a/sys/ip/avalon_combiner_hw.tcl b/sys/ip/avalon_combiner_hw.tcl deleted file mode 100644 index 5eede9c..0000000 --- a/sys/ip/avalon_combiner_hw.tcl +++ /dev/null @@ -1,204 +0,0 @@ -# TCL File Generated by Component Editor 17.0 -# Wed Dec 13 01:40:49 CST 2017 -# DO NOT MODIFY - - -# -# avalon_combiner "avalon_combiner" v17.0 -# sorgelig 2017.12.13.01:40:49 -# -# - -# -# request TCL package from ACDS 16.1 -# -package require -exact qsys 16.1 - - -# -# module avalon_combiner -# -set_module_property DESCRIPTION "" -set_module_property NAME avalon_combiner -set_module_property VERSION 17.0 -set_module_property INTERNAL false -set_module_property OPAQUE_ADDRESS_MAP true -set_module_property AUTHOR sorgelig -set_module_property DISPLAY_NAME avalon_combiner -set_module_property INSTANTIATE_IN_SYSTEM_MODULE true -set_module_property EDITABLE true -set_module_property REPORT_TO_TALKBACK false -set_module_property ALLOW_GREYBOX_GENERATION false -set_module_property REPORT_HIERARCHY false - - -# -# file sets -# -add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" "" -set_fileset_property QUARTUS_SYNTH TOP_LEVEL avalon_combiner -set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false -set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE true -add_fileset_file avalon_combiner.v VERILOG PATH avalon_combiner.v TOP_LEVEL_FILE - - -# -# parameters -# - - -# -# display items -# - - -# -# connection point clock -# -add_interface clock clock end -set_interface_property clock clockRate 0 -set_interface_property clock ENABLED true -set_interface_property clock EXPORT_OF "" -set_interface_property clock PORT_NAME_MAP "" -set_interface_property clock CMSIS_SVD_VARIABLES "" -set_interface_property clock SVD_ADDRESS_GROUP "" - -add_interface_port clock clk clk Input 1 - - -# -# connection point reset -# -add_interface reset reset end -set_interface_property reset associatedClock clock -set_interface_property reset synchronousEdges DEASSERT -set_interface_property reset ENABLED true -set_interface_property reset EXPORT_OF "" -set_interface_property reset PORT_NAME_MAP "" -set_interface_property reset CMSIS_SVD_VARIABLES "" -set_interface_property reset SVD_ADDRESS_GROUP "" - -add_interface_port reset rst reset Input 1 - - -# -# connection point ctl_mixer -# -add_interface ctl_mixer avalon start -set_interface_property ctl_mixer addressUnits WORDS -set_interface_property ctl_mixer associatedClock clock -set_interface_property ctl_mixer associatedReset reset -set_interface_property ctl_mixer bitsPerSymbol 8 -set_interface_property ctl_mixer burstOnBurstBoundariesOnly false -set_interface_property ctl_mixer burstcountUnits WORDS -set_interface_property ctl_mixer doStreamReads false -set_interface_property ctl_mixer doStreamWrites false -set_interface_property ctl_mixer holdTime 0 -set_interface_property ctl_mixer linewrapBursts false -set_interface_property ctl_mixer maximumPendingReadTransactions 0 -set_interface_property ctl_mixer maximumPendingWriteTransactions 0 -set_interface_property ctl_mixer readLatency 0 -set_interface_property ctl_mixer readWaitTime 1 -set_interface_property ctl_mixer setupTime 0 -set_interface_property ctl_mixer timingUnits Cycles -set_interface_property ctl_mixer writeWaitTime 0 -set_interface_property ctl_mixer ENABLED true -set_interface_property ctl_mixer EXPORT_OF "" -set_interface_property ctl_mixer PORT_NAME_MAP "" -set_interface_property ctl_mixer CMSIS_SVD_VARIABLES "" -set_interface_property ctl_mixer SVD_ADDRESS_GROUP "" - -add_interface_port ctl_mixer mixer_address address Output 7 -add_interface_port ctl_mixer mixer_byteenable byteenable Output 4 -add_interface_port ctl_mixer mixer_write write Output 1 -add_interface_port ctl_mixer mixer_writedata writedata Output 32 -add_interface_port ctl_mixer mixer_waitrequest waitrequest Input 1 - - -# -# connection point ctl_scaler -# -add_interface ctl_scaler avalon start -set_interface_property ctl_scaler addressUnits WORDS -set_interface_property ctl_scaler associatedClock clock -set_interface_property ctl_scaler associatedReset reset -set_interface_property ctl_scaler bitsPerSymbol 8 -set_interface_property ctl_scaler burstOnBurstBoundariesOnly false -set_interface_property ctl_scaler burstcountUnits WORDS -set_interface_property ctl_scaler doStreamReads false -set_interface_property ctl_scaler doStreamWrites false -set_interface_property ctl_scaler holdTime 0 -set_interface_property ctl_scaler linewrapBursts false -set_interface_property ctl_scaler maximumPendingReadTransactions 0 -set_interface_property ctl_scaler maximumPendingWriteTransactions 0 -set_interface_property ctl_scaler readLatency 0 -set_interface_property ctl_scaler readWaitTime 1 -set_interface_property ctl_scaler setupTime 0 -set_interface_property ctl_scaler timingUnits Cycles -set_interface_property ctl_scaler writeWaitTime 0 -set_interface_property ctl_scaler ENABLED true -set_interface_property ctl_scaler EXPORT_OF "" -set_interface_property ctl_scaler PORT_NAME_MAP "" -set_interface_property ctl_scaler CMSIS_SVD_VARIABLES "" -set_interface_property ctl_scaler SVD_ADDRESS_GROUP "" - -add_interface_port ctl_scaler scaler_address address Output 7 -add_interface_port ctl_scaler scaler_byteenable byteenable Output 4 -add_interface_port ctl_scaler scaler_waitrequest waitrequest Input 1 -add_interface_port ctl_scaler scaler_write write Output 1 -add_interface_port ctl_scaler scaler_writedata writedata Output 32 - - -# -# connection point ctl_video -# -add_interface ctl_video avalon start -set_interface_property ctl_video addressUnits WORDS -set_interface_property ctl_video associatedClock clock -set_interface_property ctl_video associatedReset reset -set_interface_property ctl_video bitsPerSymbol 8 -set_interface_property ctl_video burstOnBurstBoundariesOnly false -set_interface_property ctl_video burstcountUnits WORDS -set_interface_property ctl_video doStreamReads false -set_interface_property ctl_video doStreamWrites false -set_interface_property ctl_video holdTime 0 -set_interface_property ctl_video linewrapBursts false -set_interface_property ctl_video maximumPendingReadTransactions 0 -set_interface_property ctl_video maximumPendingWriteTransactions 0 -set_interface_property ctl_video readLatency 0 -set_interface_property ctl_video readWaitTime 1 -set_interface_property ctl_video setupTime 0 -set_interface_property ctl_video timingUnits Cycles -set_interface_property ctl_video writeWaitTime 0 -set_interface_property ctl_video ENABLED true -set_interface_property ctl_video EXPORT_OF "" -set_interface_property ctl_video PORT_NAME_MAP "" -set_interface_property ctl_video CMSIS_SVD_VARIABLES "" -set_interface_property ctl_video SVD_ADDRESS_GROUP "" - -add_interface_port ctl_video video_address address Output 8 -add_interface_port ctl_video video_byteenable byteenable Output 4 -add_interface_port ctl_video video_waitrequest waitrequest Input 1 -add_interface_port ctl_video video_write write Output 1 -add_interface_port ctl_video video_writedata writedata Output 32 - - -# -# connection point control -# -add_interface control conduit end -set_interface_property control associatedClock clock -set_interface_property control associatedReset reset -set_interface_property control ENABLED true -set_interface_property control EXPORT_OF "" -set_interface_property control PORT_NAME_MAP "" -set_interface_property control CMSIS_SVD_VARIABLES "" -set_interface_property control SVD_ADDRESS_GROUP "" - -add_interface_port control address address Input 9 -add_interface_port control write write Input 1 -add_interface_port control writedata writedata Input 32 -add_interface_port control waitrequest waitrequest Output 1 -add_interface_port control clock clock Output 1 -add_interface_port control reset reset Output 1 - diff --git a/sys/ip/de10_hps_hw.tcl b/sys/ip/de10_hps_hw.tcl deleted file mode 100644 index a166ca0..0000000 --- a/sys/ip/de10_hps_hw.tcl +++ /dev/null @@ -1,3706 +0,0 @@ -# (C) 2001-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 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, 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. - - -# This IP is modified standard Altera HPS IP. -# Direct DDR3 SDRAM access has been removed since it won't work together with HPS DDR3 SDRAM access. -# FPGA access the memory through MPFE (FPGA2SDRAM bridge). -# By removing direct DDR3 SDRAM access synthesis time has been reduced by 3 times! - - -package require -exact qsys 12.0 -package require -exact altera_terp 1.0 -package require quartus::advanced_wysiwyg - -set_module_property NAME altera_hps_lite -set_module_property VERSION 17.0 -set_module_property AUTHOR "Altera Corporation/Sorgelig" -set_module_property SUPPORTED_DEVICE_FAMILIES {CYCLONEV ARRIAV} - -set_module_property DISPLAY_NAME "DE10-nano Hard Processor System" -set_module_property INSTANTIATE_IN_SYSTEM_MODULE true -set_module_property EDITABLE false -set_module_property HIDE_FROM_SOPC true -set_module_property HIDE_FROM_QUARTUS true - -add_documentation_link "HPS User Guide for Cyclone V" "http://www.altera.com/literature/hb/cyclone-v/cv_5v4.pdf" -add_documentation_link "HPS User Guide for Arria V" "http://www.altera.com/literature/hb/arria-v/av_5v4.pdf" - -set alt_mem_if_tcl_libs_dir "$env(QUARTUS_ROOTDIR)/../ip/altera/alt_mem_if/alt_mem_if_tcl_packages" -if {[lsearch -exact $auto_path $alt_mem_if_tcl_libs_dir] == -1} { - lappend auto_path $alt_mem_if_tcl_libs_dir -} - -package require alt_mem_if::gui::system_info - -source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/util/constants.tcl -source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/util/procedures.tcl -source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/util/pin_mux.tcl -source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/util/pin_mux_db.tcl -source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/util/locations.tcl -source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/util/ui.tcl -source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_hps/clocks.tcl -source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_hps/clock_manager.tcl - -proc add_storage_parameter {name { default_value {} } } { - add_parameter $name string $default_value "" - set_parameter_property $name derived true - set_parameter_property $name visible false -} - -proc add_reset_parameters {} { - set group_name "Resets" - add_display_item "FPGA Interfaces" $group_name "group" "" - - add_parameter S2FCLK_COLDRST_Enable boolean false "" - set_parameter_property S2FCLK_COLDRST_Enable display_name "Enable HPS-to-FPGA cold reset output" - set_parameter_property S2FCLK_COLDRST_Enable group $group_name - - add_parameter S2FCLK_PENDINGRST_Enable boolean false "" - set_parameter_property S2FCLK_PENDINGRST_Enable display_name "Enable HPS warm reset handshake signals" - set_parameter_property S2FCLK_PENDINGRST_Enable group $group_name - - add_parameter F2SCLK_DBGRST_Enable boolean false "" - set_parameter_property F2SCLK_DBGRST_Enable display_name "Enable FPGA-to-HPS debug reset request" - set_parameter_property F2SCLK_DBGRST_Enable group $group_name - - add_parameter F2SCLK_WARMRST_Enable boolean false "" - set_parameter_property F2SCLK_WARMRST_Enable display_name "Enable FPGA-to-HPS warm reset request" - set_parameter_property F2SCLK_WARMRST_Enable group $group_name - - add_parameter F2SCLK_COLDRST_Enable boolean false "" - set_parameter_property F2SCLK_COLDRST_Enable display_name "Enable FPGA-to-HPS cold reset request" - set_parameter_property F2SCLK_COLDRST_Enable group $group_name - -} - -proc list_h2f_interrupt_groups {} { - return { - "CAN" "CLOCKPERIPHERAL" "CTI" - "DMA" "EMAC" "FPGAMANAGER" - "GPIO" "I2CEMAC" "I2CPERIPHERAL" - "L4TIMER" "NAND" "OSCTIMER" - "QSPI" "SDMMC" "SPIMASTER" - "SPISLAVE" "UART" "USB" - "WATCHDOG" - } -} - -proc get_h2f_interrupt_descriptions {data_ref} { - upvar 1 $data_ref data - array set data { - "DMA" "Enable DMA interrupts" - "EMAC" "Enable EMAC interrupts (for EMAC0 and EMAC1)" - "USB" "Enable USB interrupts" - "CAN" "Enable CAN interrupts" - "SDMMC" "Enable SD/MMC interrupt" - "NAND" "Enable NAND interrupt" - "QSPI" "Enable Quad SPI interrupt" - "SPIMASTER" "Enable SPI master interrupts" - "SPISLAVE" "Enable SPI slave interrupts" - "I2CPERIPHERAL" "Enable I2C peripheral interrupts (for I2C0 and I2C1)" - "I2CEMAC" "Enable I2C-EMAC interrupts (for I2C2 and I2C3)" - "UART" "Enable UART interrupts" - "GPIO" "Enable GPIO interrupts" - "L4TIMER" "Enable L4 timer interrupts" - "OSCTIMER" "Enable OSC timer interrupts" - "WATCHDOG" "Enable watchdog interrupts" - "CLOCKPERIPHERAL" "Enable clock peripheral interrupts" - "FPGAMANAGER" "Enable FPGA manager interrupt" - "CTI" "Enable CTI interrupts" - } -} - -proc load_h2f_interrupt_table {functions_by_group_ref - width_by_function_ref - inverted_by_function_ref} { - upvar 1 $functions_by_group_ref functions_by_group - upvar 1 $width_by_function_ref width_by_function - upvar 1 $inverted_by_function_ref inverted_by_function - array set functions_by_group { - "DMA" {"dma" "dma_abort" } - "EMAC" {"emac0" "emac1" } - "USB" {"usb0" "usb1" } - "CAN" {"can0" "can1" } - "SDMMC" {"sdmmc" } - "NAND" {"nand" } - "QSPI" {"qspi" } - "SPIMASTER" {"spi0" "spi1" } - "SPISLAVE" {"spi2" "spi3" } - "I2CPERIPHERAL" {"i2c0" "i2c1" } - "I2CEMAC" {"i2c_emac0" "i2c_emac1" } - "UART" {"uart0" "uart1" } - "GPIO" {"gpio0" "gpio1" "gpio2"} - "L4TIMER" {"l4sp0" "l4sp1" } - "OSCTIMER" {"osc0" "osc1" } - "WATCHDOG" {"wdog0" "wdog1" } - "CLOCKPERIPHERAL" {"clkmgr" "mpuwakeup" } - "FPGAMANAGER" {"fpga_man" } - "CTI" {"cti" } - } - array set width_by_function { - "dma" 8 - "cti" 2 - } - array set inverted_by_function { - "cti" 1 - } -} - -proc add_interrupt_parameters {} { - set top_group_name "Interrupts" - add_display_item "FPGA Interfaces" $top_group_name "group" "" - - # add_display_item $group_name "f2h_interrupts_label" "text" "FPGA-to-HPS" - add_parameter F2SINTERRUPT_Enable boolean false - set_parameter_property F2SINTERRUPT_Enable enabled true - set_parameter_property F2SINTERRUPT_Enable display_name "Enable FPGA-to-HPS Interrupts" - set_parameter_property F2SINTERRUPT_Enable group $top_group_name - - set inner_group_name "HPS-to-FPGA" - add_display_item $top_group_name $inner_group_name "group" "" - get_h2f_interrupt_descriptions descriptions_by_group - set interrupt_groups [list_h2f_interrupt_groups] - foreach interrupt_group $interrupt_groups { - set parameter "S2FINTERRUPT_${interrupt_group}_Enable" - add_parameter $parameter boolean false - set_parameter_property $parameter enabled true - set_parameter_property $parameter display_name $descriptions_by_group($interrupt_group) - set_parameter_property $parameter group $inner_group_name - } -} - -proc add_dma_parameters {} { - set group_name "DMA Peripheral Request" - add_display_item "FPGA Interfaces" $group_name "group" "" - add_display_item $group_name "DMA Table" "group" "table" - - add_parameter DMA_PeriphId_DERIVED string_list {0 1 2 3 4 5 6 7} - set_parameter_property DMA_PeriphId_DERIVED display_name "Peripheral Request ID" - set_parameter_property DMA_PeriphId_DERIVED derived true - set_parameter_property DMA_PeriphId_DERIVED display_hint "FIXED_SIZE" - set_parameter_property DMA_PeriphId_DERIVED group "DMA Table" - - add_parameter DMA_Enable string_list {"No" "No" "No" "No" "No" "No" "No" "No"} - set_parameter_property DMA_Enable allowed_ranges {"Yes" "No"} - set_parameter_property DMA_Enable display_name "Enabled" - set_parameter_property DMA_Enable display_hint "FIXED_SIZE" - set_parameter_property DMA_Enable group "DMA Table" -} - -proc range_from_zero {end} { - set result [list] - for {set i 0} {$i <= $end} {incr i} { - lappend result $i - } - return $result -} - -proc create_generic_parameters {} { - - ::alt_mem_if::util::hwtcl_utils::_add_parameter SYS_INFO_DEVICE_FAMILY STRING "" - set_parameter_property SYS_INFO_DEVICE_FAMILY SYSTEM_INFO DEVICE_FAMILY - set_parameter_property SYS_INFO_DEVICE_FAMILY VISIBLE FALSE - - ::alt_mem_if::util::hwtcl_utils::_add_parameter DEVICE_FAMILY STRING "" - set_parameter_property DEVICE_FAMILY DERIVED true - set_parameter_property DEVICE_FAMILY VISIBLE FALSE - - return 1 -} - -create_generic_parameters - -add_display_item "" "FPGA Interfaces" "group" "tab" -add_display_item "" "Peripheral Pins" "group" "tab" -add_display_item "" "HPS Clocks" "group" "tab" -add_clock_tab "HPS Clocks" - -add_display_item "FPGA Interfaces" "General" "group" "" - -add_parameter MPU_EVENTS_Enable boolean true -set_parameter_property MPU_EVENTS_Enable display_name "Enable MPU standby and event signals" -set_parameter_property MPU_EVENTS_Enable description "Enables elaboration of the mpu_events interface." -set_parameter_property MPU_EVENTS_Enable group "General" - -add_parameter GP_Enable boolean false -set_parameter_property GP_Enable display_name "Enable general purpose signals" -set_parameter_property GP_Enable description "Enables elaboration of interface h2f_gp." -set_parameter_property GP_Enable group "General" - -add_parameter DEBUGAPB_Enable boolean false -set_parameter_property DEBUGAPB_Enable display_name "Enable Debug APB interface" -set_parameter_property DEBUGAPB_Enable description "Enables elaboration of Debug APB interfaces." -set_parameter_property DEBUGAPB_Enable group "General" - -add_parameter STM_Enable boolean false -set_parameter_property STM_Enable display_name "Enable System Trace Macrocell hardware events" -set_parameter_property STM_Enable description "Enables elaboration of interface stm_hwevents." -set_parameter_property STM_Enable group "General" - -add_parameter CTI_Enable boolean false -set_parameter_property CTI_Enable display_name "Enable FPGA Cross Trigger Interface" -set_parameter_property CTI_Enable description "Enables elaboration of interface cti_trigger, cti_clk_in." -set_parameter_property CTI_Enable group "General" - -add_parameter TPIUFPGA_Enable boolean false -set_parameter_property TPIUFPGA_Enable display_name "Enable FPGA Trace Port Interface Unit" -set_parameter_property TPIUFPGA_Enable description "Enables elaboration of TPIU FPGA interfaces." -set_parameter_property TPIUFPGA_Enable group "General" - -add_parameter TPIUFPGA_alt boolean false -set_parameter_property TPIUFPGA_alt display_name "Enable FPGA Trace Port Alternate FPGA Interface" -set_parameter_property TPIUFPGA_alt description "When the trace port is enabled, it creates an interface compatible with the Arria 10 Trace Interface. (This just moves the clock_in port into the same conduit)" -set_parameter_property TPIUFPGA_alt group "General" -set_parameter_property TPIUFPGA_alt enabled false - - -add_parameter BOOTFROMFPGA_Enable boolean false -set_parameter_property BOOTFROMFPGA_Enable enabled true -set_parameter_property BOOTFROMFPGA_Enable display_name "Enable boot from fpga signals" -set_parameter_property BOOTFROMFPGA_Enable description "Enables elaboration of interface boot_from_fpga." -set_parameter_property BOOTFROMFPGA_Enable group "General" - -add_parameter TEST_Enable boolean false -set_parameter_property TEST_Enable enabled true -set_parameter_property TEST_Enable display_name "Enable Test Interface" -set_parameter_property TEST_Enable group "General" - -add_parameter HLGPI_Enable boolean false -set_parameter_property HLGPI_Enable enabled true -set_parameter_property HLGPI_Enable display_name "Enable HLGPI Interface" -set_parameter_property HLGPI_Enable group "General" - -add_display_item "FPGA Interfaces" "Boot and Clock Selection" "group" "" -add_parameter BSEL_EN boolean false -set_parameter_property BSEL_EN enabled true -set_parameter_property BSEL_EN display_name "Enable boot selection from FPGA" -set_parameter_property BSEL_EN group "Boot and Clock Selection" -set_parameter_property BSEL_EN visible false -set_parameter_property BSEL_EN enabled false - -add_parameter BSEL integer 1 -set_parameter_property BSEL allowed_ranges {"1:FPGA" "2:NAND Flash (1.8v)" "3:NAND Flash (3.0v)" "4:SD/MMC External Transceiver (1.8v)" "5:SD/MMC Internal Transceiver (3.0v)" "6:Quad SPI Flash (1.8v)" "7:Quad SPI Flash (3.0v)"} -set_parameter_property BSEL display_name "Boot selection from FPGA" -set_parameter_property BSEL group "Boot and Clock Selection" -set_parameter_property BSEL visible false -set_parameter_property BSEL enabled false - -add_parameter CSEL_EN boolean false -set_parameter_property CSEL_EN enabled true -set_parameter_property CSEL_EN display_name "Enable clock selection from FPGA" -set_parameter_property CSEL_EN group "Boot and Clock Selection" -set_parameter_property CSEL_EN visible false -set_parameter_property CSEL_EN enabled false - -add_parameter CSEL integer 0 -set_parameter_property CSEL allowed_ranges {"0:CSEL_0" "1:CSEL_1" "2:CSEL_2" "3:CSEL_3"} -set_parameter_property CSEL display_name "Clock selection from FPGA" -set_parameter_property CSEL group "Boot and Clock Selection" -set_parameter_property CSEL visible false -set_parameter_property CSEL enabled false - -add_display_item "FPGA Interfaces" "AXI Bridges" "group" "" -add_parameter F2S_Width integer 2 -set_parameter_property F2S_Width allowed_ranges {"0:Unused" "1:32-bit" "2:64-bit" "3:128-bit"} -set_parameter_property F2S_Width display_name "FPGA-to-HPS interface width" -set_parameter_property F2S_Width hdl_parameter true -set_parameter_property F2S_Width group "AXI Bridges" - -add_parameter S2F_Width integer 2 -set_parameter_property S2F_Width allowed_ranges {"0:Unused" "1:32-bit" "2:64-bit" "3:128-bit"} -set_parameter_property S2F_Width display_name "HPS-to-FPGA interface width" -set_parameter_property S2F_Width hdl_parameter true -set_parameter_property S2F_Width group "AXI Bridges" - -add_parameter LWH2F_Enable string true -set_parameter_property LWH2F_Enable display_name "Lightweight HPS-to-FPGA interface width" -set_parameter_property LWH2F_Enable description "The lightweight HPS-to-FPGA bridge provides a secondary, fixed-width, smaller address space, lower-performance master interface to the FPGA fabric. Use the lightweight HPS-to-FPGA bridge for high-latency, low-bandwidth traffic, such as memory-mapped register accesses of FPGA peripherals. This approach diverts traffic from the high-performance HPS-to-FPGA bridge, which can improve overall performance." -set_parameter_property LWH2F_Enable allowed_ranges {"true:32-bit" "false:Unused"} -set_parameter_property LWH2F_Enable group "AXI Bridges" - - -set group_name "FPGA-to-HPS SDRAM Interface" -add_display_item "FPGA Interfaces" $group_name "group" "" -add_display_item $group_name "f2sdram_label" "text" "Click the '+' and '-' buttons to add and remove FPGA-to-HPS SDRAM ports." -set table_name "F2SDRAM Settings" -add_display_item $group_name $table_name "group" "table" - -add_parameter F2SDRAM_Name_DERIVED string_list {"f2h_sdram0"} -set_parameter_property F2SDRAM_Name_DERIVED derived true -set_parameter_property F2SDRAM_Name_DERIVED display_name "Name" -set_parameter_property F2SDRAM_Name_DERIVED group $table_name - -add_parameter F2SDRAM_Type string_list [list [F2HSDRAM_AXI3]] -set_parameter_property F2SDRAM_Type allowed_ranges [list [F2HSDRAM_AXI3] [F2HSDRAM_AVM] [F2HSDRAM_AVM_WRITEONLY] [F2HSDRAM_AVM_READONLY]] -set_parameter_property F2SDRAM_Type display_name "Type" -set_parameter_property F2SDRAM_Type group $table_name - -add_parameter F2SDRAM_Width integer_list {"64"} -set_parameter_property F2SDRAM_Width allowed_ranges "32,64,128,256" -set_parameter_property F2SDRAM_Width display_name "Width" -set_parameter_property F2SDRAM_Width group $table_name -set_parameter_update_callback F2SDRAM_Width on_altered_f2sdram_width -# TODO: f2sdram derived parameters for resource counts in the table -# TODO: f2sdram derived parameters for remaining resources, not a part of the table - -add_storage_parameter F2SDRAM_Width_Last_Size 1 -add_storage_parameter F2SDRAM_CMD_PORT_USED 0 -add_storage_parameter F2SDRAM_WR_PORT_USED 0 -add_storage_parameter F2SDRAM_RD_PORT_USED 0 -add_storage_parameter F2SDRAM_RST_PORT_USED 0 -set_parameter_property F2SDRAM_Width_Last_Size group $group_name -set_parameter_property F2SDRAM_CMD_PORT_USED group $group_name -set_parameter_property F2SDRAM_WR_PORT_USED group $group_name -set_parameter_property F2SDRAM_RD_PORT_USED group $group_name -set_parameter_property F2SDRAM_RST_PORT_USED group $group_name - -#Parameter to export Bonding_out signal from fpga2sdram Atom -add_parameter BONDING_OUT_ENABLED boolean false -set_parameter_property BONDING_OUT_ENABLED display_name "Enable BONDING-OUT signals" -set_parameter_property BONDING_OUT_ENABLED group $group_name -set_parameter_property BONDING_OUT_ENABLED enabled false -set_parameter_property BONDING_OUT_ENABLED visible false - - -proc on_altered_f2sdram_width { param } { - set old_size [get_parameter_value F2SDRAM_Width_Last_Size] - set current_value [get_parameter_value F2SDRAM_Width] - set current_size [llength $current_value] - - if {$current_size == $old_size + 1} { ;# look for case of newly added row - set last_element_index [expr {$current_size - 1}] - set new_value [lreplace $current_value $last_element_index $last_element_index "64"] - set_parameter_value F2SDRAM_Width $new_value - } -} - -add_reset_parameters - -add_dma_parameters - -add_interrupt_parameters - - set group_name "EMAC ptp interface" - add_display_item "FPGA Interfaces" $group_name "group" "" - - add_parameter EMAC0_PTP boolean false - set_parameter_property EMAC0_PTP display_name "Enable EMAC0 Precision Time Protocol (PTP) FPGA Interface" - set_parameter_property EMAC0_PTP hdl_parameter false - set_parameter_property EMAC0_PTP enabled false - set_parameter_property EMAC0_PTP group $group_name - set_parameter_property EMAC0_PTP description "When the EMAC is connected to the HPS IO via the Pinmux, the IEEE 1588 Precision Time Protocol (PTP) interface can be accessed through the FPGA. When the EMAC connects to the FPGA, the PTP signals are always available." - - add_parameter EMAC1_PTP boolean false - set_parameter_property EMAC1_PTP display_name "Enable EMAC1 Precision Time Protocol (PTP) FPGA Interface" - set_parameter_property EMAC1_PTP hdl_parameter false - set_parameter_property EMAC1_PTP enabled false - set_parameter_property EMAC1_PTP group $group_name - set_parameter_property EMAC1_PTP description "When the EMAC is connected to the HPS IO via the Pinmux, the IEEE 1588 Precision Time Protocol (PTP) interface can be accessed through the FPGA. When the EMAC connects to the FPGA, the PTP signals are always available." - - -proc make_mode_display_name {peripheral} { - set default_suffix "mode" - array set custom_suffix_by_peripheral { - USB0 "PHY interface mode" - USB1 "PHY interface mode" - } - if {[info exists custom_suffix_by_peripheral($peripheral)]} { - set suffix $custom_suffix_by_peripheral($peripheral) - } else { - set suffix $default_suffix - } - - set display_name "${peripheral} ${suffix}" - return $display_name -} - -proc add_peripheral_pin_muxing_parameters {} { - set TOP_LEVEL_GROUP_NAME "Peripheral Pins" - - - foreach group_name [list_group_names] { - add_display_item $TOP_LEVEL_GROUP_NAME $group_name "group" "" - - foreach peripheral_name [peripherals_in_group $group_name] { - set pin_muxing_param_name "${peripheral_name}_PinMuxing" - set mode_param_name "${peripheral_name}_Mode" - add_parameter $pin_muxing_param_name string [UNUSED_MUX_VALUE] - set_parameter_property $pin_muxing_param_name enabled false - set_parameter_property $pin_muxing_param_name display_name "${peripheral_name} pin" - set_parameter_property $pin_muxing_param_name allowed_ranges [UNUSED_MUX_VALUE] - set_parameter_property $pin_muxing_param_name group $group_name - set_parameter_update_callback $pin_muxing_param_name on_altered_peripheral_pin_muxing $peripheral_name - - set mode_display_name [make_mode_display_name $peripheral_name] - add_parameter $mode_param_name string [NA_MODE_VALUE] - set_parameter_property $mode_param_name enabled false - set_parameter_property $mode_param_name display_name $mode_display_name - set_parameter_property $mode_param_name allowed_ranges [NA_MODE_VALUE] - set_parameter_property $mode_param_name group $group_name - - if {[string match "*EMAC*" $peripheral_name]} { - set_parameter_update_callback $mode_param_name on_emac_mode_switch_internal $peripheral_name - } - } - } -} -add_peripheral_pin_muxing_parameters - -proc add_gpio_parameters {} { - set TOP_LEVEL_GROUP_NAME "Peripheral Pins" - set group_name "Peripherals Mux Table" - set table_name "Conflict Table" - - add_display_item $TOP_LEVEL_GROUP_NAME $group_name "group" "" - #add_display_item $group_name $table_name "group" "table" - - add_parameter Customer_Pin_Name_DERIVED string_list {} - set_parameter_property Customer_Pin_Name_DERIVED display_name "Pin Name" - set_parameter_property Customer_Pin_Name_DERIVED derived true - set_parameter_property Customer_Pin_Name_DERIVED display_hint "FIXED_SIZE" - set_parameter_property Customer_Pin_Name_DERIVED visible false - # set_parameter_property Customer_Pin_Name_DERIVED group $table_name - - add_parameter GPIO_Conflict_DERIVED string_list {} - set_parameter_property GPIO_Conflict_DERIVED display_name "Used by" - set_parameter_property GPIO_Conflict_DERIVED derived true - set_parameter_property GPIO_Conflict_DERIVED display_hint "FIXED_SIZE" - set_parameter_property GPIO_Conflict_DERIVED visible false - #set_parameter_property GPIO_Conflict_DERIVED group $table_name - - add_parameter GPIO_Name_DERIVED string_list {} - set_parameter_property GPIO_Name_DERIVED display_name "GPIO" - set_parameter_property GPIO_Name_DERIVED derived true - set_parameter_property GPIO_Name_DERIVED display_hint "FIXED_SIZE" - set_parameter_property GPIO_Name_DERIVED visible false - #set_parameter_property GPIO_Name_DERIVED group $table_name - - # TODO: change? - set max_possible_gpio_options 100 - set enable_list [list] - for {set i 0} {$i < $max_possible_gpio_options} {incr i} { - lappend enable_list "No" - } - - add_parameter GPIO_Enable string_list $enable_list - set_parameter_property GPIO_Enable allowed_ranges {"Yes" "No"} - set_parameter_property GPIO_Enable display_name "GPIO Enabled" - set_parameter_property GPIO_Enable visible false - # set_parameter_property GPIO_Enable group $table_name - - add_parameter LOANIO_Name_DERIVED string_list {} - set_parameter_property LOANIO_Name_DERIVED display_name "Loan I/O" - set_parameter_property LOANIO_Name_DERIVED derived true - set_parameter_property LOANIO_Name_DERIVED display_hint "FIXED_SIZE" - set_parameter_property LOANIO_Name_DERIVED visible false - - add_parameter GPIO_Pin_Used_DERIVED boolean false - set_parameter_property GPIO_Pin_Used_DERIVED display_name "GPIO Pin Used" - set_parameter_property GPIO_Pin_Used_DERIVED derived true - set_parameter_property GPIO_Pin_Used_DERIVED display_hint "GPIO Pin Used" - set_parameter_property GPIO_Pin_Used_DERIVED visible false - - add_parameter LOANIO_Enable string_list $enable_list - set_parameter_property LOANIO_Enable allowed_ranges {"Yes" "No"} - set_parameter_property LOANIO_Enable display_name "Loan I/O Enabled" - set_parameter_property LOANIO_Enable visible false - #set_parameter_property LOANIO_Enable group $table_name - - - -} -add_gpio_parameters - -proc add_reset_parameters {} { - set group_name "Resets" - add_display_item "FPGA Interfaces" $group_name "group" "" - - add_parameter S2FCLK_COLDRST_Enable boolean false "" - set_parameter_property S2FCLK_COLDRST_Enable display_name "Enable HPS-to-FPGA cold reset output" - set_parameter_property S2FCLK_COLDRST_Enable group $group_name - - add_parameter S2FCLK_PENDINGRST_Enable boolean false "" - set_parameter_property S2FCLK_PENDINGRST_Enable display_name "Enable HPS warm reset handshake signals" - set_parameter_property S2FCLK_PENDINGRST_Enable group $group_name - - add_parameter F2SCLK_DBGRST_Enable boolean false "" - set_parameter_property F2SCLK_DBGRST_Enable display_name "Enable FPGA-to-HPS debug reset request" - set_parameter_property F2SCLK_DBGRST_Enable group $group_name - - add_parameter F2SCLK_WARMRST_Enable boolean false "" - set_parameter_property F2SCLK_WARMRST_Enable display_name "Enable FPGA-to-HPS warm reset request" - set_parameter_property F2SCLK_WARMRST_Enable group $group_name - - add_parameter F2SCLK_COLDRST_Enable boolean false "" - set_parameter_property F2SCLK_COLDRST_Enable display_name "Enable FPGA-to-HPS cold reset request" - set_parameter_property F2SCLK_COLDRST_Enable group $group_name - -} - -proc add_java_gui_parameters {} { - set TOP_LEVEL_GROUP_NAME "Peripheral Pins" - set group_name "Peripherals Mux Table" - - add_display_item $TOP_LEVEL_GROUP_NAME $group_name "group" "" - # add_display_item $group_name the_widget "group" "" - - add_parameter JAVA_CONFLICT_PIN string_list {} - set_parameter_property JAVA_CONFLICT_PIN derived true - set_parameter_property JAVA_CONFLICT_PIN visible false - - - add_parameter JAVA_GUI_PIN_LIST string_list {} - set_parameter_property JAVA_GUI_PIN_LIST derived true - set_parameter_property JAVA_GUI_PIN_LIST visible false - - set peripherals [list_peripheral_names] - set widget_parameter [list \ - Customer_Pin_Name_DERIVED Customer_Pin_Name_DERIVED \ - GPIO_Name_DERIVED GPIO_Name_DERIVED \ - LOANIO_Name_DERIVED LOANIO_Name_DERIVED \ - LOANIO_Enable LOANIO_Enable \ - GPIO_Enable GPIO_Enable \ - JAVA_CONFLICT_PIN GUI_Conflict_Pins_List \ - JAVA_GUI_PIN_LIST GUI_GPIO_Pins_List] - - foreach peripheral_name $peripherals { - add_parameter "JAVA_${peripheral_name}_DATA" string "" - set_parameter_property "JAVA_${peripheral_name}_DATA" derived true - set_parameter_property "JAVA_${peripheral_name}_DATA" visible false - - lappend widget_parameter "JAVA_${peripheral_name}_DATA" - lappend widget_parameter "${peripheral_name}_pin_muxing" - lappend widget_parameter "${peripheral_name}_PinMuxing" - lappend widget_parameter "${peripheral_name}_PinMuxing" - lappend widget_parameter "${peripheral_name}_Mode" - lappend widget_parameter "${peripheral_name}_Mode" - } - - add_display_item $group_name the_widget "group" - set_display_item_property the_widget widget [list ../widget/pin_mux_widget.jar Altera_hps_widget] - set_display_item_property the_widget widget_parameter_map $widget_parameter -} - -add_java_gui_parameters - -############################################## -# Clocks! -# -# All clock enable parameters go here. -# Clock frequency parameters also go here. All -# the parameters need to be declared regardless -# of whether the clock will be exercised. -# -# Validation logic will enable/show frequency -# parameters based on whether the actual clock -# is being elaborated. -# -# There are four categories of clocks in this -# component: inputs on SoC I/O -# outputs on SoC I/O -# inputs on FPGA pins -# outputs on FPGA pins -# -# Inputs on SoC I/O have user-input parameters -# so the data can be consumed by downstream -# embedded software tools. -# Outputs on SoC I/O need not have frequency -# information recorded. -# Inputs on FPGA pins have system info parameters -# so the data can be consumed by downstream -# embedded software tools. -# Outputs on FPGA pins have user input parameters -# to be consumed by Quartus via SDC. -# -############################################## -proc add_clock_parameters {} { - set TOP_LEVEL_GROUP_NAME "Input Clocks" - - set group_name "User Clocks" - add_display_item $TOP_LEVEL_GROUP_NAME $group_name "group" "" - - # fake group - set group_name "FPGA Interface Clocks" - add_display_item $TOP_LEVEL_GROUP_NAME $group_name "group" "" - - foreach interface { - f2h_axi_clock h2f_axi_clock h2f_lw_axi_clock - f2h_sdram0_clock f2h_sdram1_clock f2h_sdram2_clock - f2h_sdram3_clock f2h_sdram4_clock f2h_sdram5_clock - h2f_cti_clock h2f_tpiu_clock_in h2f_debug_apb_clock - } { - set parameter "[string toupper ${interface}]_FREQ" - add_parameter $parameter integer 100 "" - set_parameter_property $parameter display_name "${interface} clock frequency" - set_parameter_property $parameter system_info_type "CLOCK_RATE" - set_parameter_property $parameter system_info_arg $interface - set_parameter_property $parameter visible false - set_parameter_property $parameter group $group_name - } - - set peripherals [list_peripheral_names] - - # TODO: Remove the following for 12.0 - set group_name "Peripheral FPGA Clocks" - add_display_item $TOP_LEVEL_GROUP_NAME $group_name "group" "" - - # Add parameter explicitly for cross-emac ptp since it doesn't belong to a single peripheral - set parameter [form_peripheral_fpga_input_clock_frequency_parameter emac_ptp_ref_clock] - add_parameter $parameter integer 100 "" - set_parameter_property $parameter display_name "EMAC emac_ptp_ref_clock clock frequency" - set_parameter_property $parameter group $group_name - set_parameter_property $parameter system_info_type "CLOCK_RATE" - set_parameter_property $parameter system_info_arg emac_ptp_ref_clock - set_parameter_property $parameter visible false - - foreach peripheral $peripherals { - set clocks [get_peripheral_fpga_input_clocks $peripheral] - foreach clock $clocks { - set parameter [form_peripheral_fpga_input_clock_frequency_parameter $clock] - add_parameter $parameter integer 100 "" - set_parameter_property $parameter display_name "${peripheral} ${clock} clock frequency" - set_parameter_property $parameter group $group_name - set_parameter_property $parameter system_info_type "CLOCK_RATE" - set_parameter_property $parameter system_info_arg $clock - set_parameter_property $parameter visible false - } - - set clocks [get_peripheral_fpga_output_clocks $peripheral] - foreach clock $clocks { - set parameter [form_peripheral_fpga_output_clock_frequency_parameter $clock] - if { [string match "*emac?_md*" $clock]} { - add_parameter $parameter float 2.5 "" - } elseif { [string match "*emac?_gtx_clk*" $clock] } { - add_parameter $parameter integer 125 "" - } else { - add_parameter $parameter integer 100 "" - if { [string compare $peripheral "SDIO" ] == 0 } { - set_parameter_property $parameter visible false - } - } - set_parameter_property $parameter display_name "${peripheral} ${clock} clock frequency" - set_parameter_property $parameter group $group_name - set_parameter_property $parameter units Megahertz - set_parameter_property $parameter allowedRanges {1:1000} - } - - } -} -add_clock_parameters - -add_parameter hps_device_family string "" "" -set_parameter_property hps_device_family derived true -set_parameter_property hps_device_family visible false - -add_parameter device_name string "" "" -set_parameter_property device_name system_info {DEVICE} -set_parameter_property device_name visible false - -add_parameter quartus_ini_hps_ip_enable_all_peripheral_fpga_interfaces boolean "" "" -set_parameter_property quartus_ini_hps_ip_enable_all_peripheral_fpga_interfaces system_info_type quartus_ini -set_parameter_property quartus_ini_hps_ip_enable_all_peripheral_fpga_interfaces system_info_arg hps_ip_enable_all_peripheral_fpga_interfaces -set_parameter_property quartus_ini_hps_ip_enable_all_peripheral_fpga_interfaces visible false - -add_parameter quartus_ini_hps_ip_enable_emac0_peripheral_fpga_interface boolean "" "" -set_parameter_property quartus_ini_hps_ip_enable_emac0_peripheral_fpga_interface system_info_type quartus_ini -set_parameter_property quartus_ini_hps_ip_enable_emac0_peripheral_fpga_interface system_info_arg hps_ip_enable_emac0_peripheral_fpga_interface -set_parameter_property quartus_ini_hps_ip_enable_emac0_peripheral_fpga_interface visible false - -add_parameter quartus_ini_hps_ip_enable_test_interface boolean "" "" -set_parameter_property quartus_ini_hps_ip_enable_test_interface system_info_type quartus_ini -set_parameter_property quartus_ini_hps_ip_enable_test_interface system_info_arg hps_ip_enable_test_interface -set_parameter_property quartus_ini_hps_ip_enable_test_interface visible false - -add_parameter quartus_ini_hps_ip_fast_f2sdram_sim_model boolean "" "" -set_parameter_property quartus_ini_hps_ip_fast_f2sdram_sim_model system_info_type quartus_ini -set_parameter_property quartus_ini_hps_ip_fast_f2sdram_sim_model system_info_arg hps_ip_fast_f2sdram_sim_model -set_parameter_property quartus_ini_hps_ip_fast_f2sdram_sim_model visible false - -add_parameter quartus_ini_hps_ip_suppress_sdram_synth boolean "" "" -set_parameter_property quartus_ini_hps_ip_suppress_sdram_synth system_info_type quartus_ini -set_parameter_property quartus_ini_hps_ip_suppress_sdram_synth system_info_arg hps_ip_suppress_sdram_synth -set_parameter_property quartus_ini_hps_ip_suppress_sdram_synth visible false - -add_parameter quartus_ini_hps_ip_enable_low_speed_serial_fpga_interfaces boolean "" "" -set_parameter_property quartus_ini_hps_ip_enable_low_speed_serial_fpga_interfaces system_info_type quartus_ini -set_parameter_property quartus_ini_hps_ip_enable_low_speed_serial_fpga_interfaces system_info_arg hps_ip_enable_low_speed_serial_fpga_interfaces -set_parameter_property quartus_ini_hps_ip_enable_low_speed_serial_fpga_interfaces visible false - -add_parameter quartus_ini_hps_ip_enable_bsel_csel boolean "" "" -set_parameter_property quartus_ini_hps_ip_enable_bsel_csel system_info_type quartus_ini -set_parameter_property quartus_ini_hps_ip_enable_bsel_csel system_info_arg hps_ip_enable_bsel_csel -set_parameter_property quartus_ini_hps_ip_enable_bsel_csel visible false - -add_parameter quartus_ini_hps_ip_f2sdram_bonding_out boolean "" "" -set_parameter_property quartus_ini_hps_ip_f2sdram_bonding_out system_info_type quartus_ini -set_parameter_property quartus_ini_hps_ip_f2sdram_bonding_out system_info_arg hps_ip_enable_f2sdram_bonding_out -set_parameter_property quartus_ini_hps_ip_f2sdram_bonding_out visible false - - -add_parameter quartus_ini_hps_emif_pll boolean "" "" -set_parameter_property quartus_ini_hps_emif_pll system_info_type quartus_ini -set_parameter_property quartus_ini_hps_emif_pll system_info_arg hps_emif_pll -set_parameter_property quartus_ini_hps_emif_pll visible false - - -proc load_test_iface_definition {} { - set csv_file $::env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_hps/test_iface.csv - - set data [list] - set count 0 - csv_foreach_row $csv_file cols { - incr count - if {$count == 1} { - continue - } - - lassign_trimmed $cols port width dir - lappend data $port $width $dir - } - return $data -} -add_storage_parameter test_iface_definition [load_test_iface_definition] - -# order of interfaces per peripheral should be kept -# order of ports per interface should be kept -proc load_periph_ifaces_db {} { - set interfaces_file $::env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_hps/fpga_peripheral_interfaces.csv - set peripherals_file $::env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_hps/fpga_peripheral_atoms.csv - set ports_file $::env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_hps/fpga_interface_ports.csv - set pins_file $::env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_hps/fpga_port_pins.csv - set bfm_types_file $::env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_hps/fpga_bfm_types.csv - - # peripherals and interfaces - set peripherals([ORDERED_NAMES]) [list] - funset interface_ports - set count 0 - set PERIPHERAL_INTERFACES_PROPERTIES_COLUMNS_START 4 - csv_foreach_row $interfaces_file cols { - incr count - # skip header - if {$count == 1} { - set ordered_names [list] - set length [llength $cols] - for {set col $PERIPHERAL_INTERFACES_PROPERTIES_COLUMNS_START} {$col < $length} {incr col} { - set col_value [lindex $cols $col] - if {$col_value != ""} { - set property_to_col($col_value) $col - lappend ordered_names $col_value - } - } - set property_to_col([ORDERED_NAMES]) $ordered_names - continue - } - - set peripheral_name [string trim [lindex $cols 0]] - set interface_name [string trim [lindex $cols 1]] - set type [string trim [lindex $cols 2]] - set dir [string trim [lindex $cols 3]] - - funset peripheral - if {[info exists peripherals($peripheral_name)]} { - array set peripheral $peripherals($peripheral_name) - } else { - funset interfaces - set interfaces([ORDERED_NAMES]) [list] - set peripheral(interfaces) [array get interfaces] - set ordered_names $peripherals([ORDERED_NAMES]) - lappend ordered_names $peripheral_name - set peripherals([ORDERED_NAMES]) $ordered_names - } - funset interfaces - array set interfaces $peripheral(interfaces) - set ordered_names $interfaces([ORDERED_NAMES]) - lappend ordered_names $interface_name - set interfaces([ORDERED_NAMES]) $ordered_names - funset interface - set interface(type) $type - set interface(direction) $dir - funset properties - foreach property $property_to_col([ORDERED_NAMES]) { - set col $property_to_col($property) - set property_value [lindex $cols $col] - - if {$property_value != ""} { - # Add Meta Property - if { [string compare [string index ${property} 0] "@" ] == 0 } { - set interface(${property}) ${property_value} - } else { - set properties($property) $property_value - } - } - } - - set interface(properties) [array get properties] - - set interfaces($interface_name) [array get interface] - set peripheral(interfaces) [array get interfaces] - set peripherals($peripheral_name) [array get peripheral] - - funset ports - set ports([ORDERED_NAMES]) [list] - set interface_ports($interface_name) [array get ports] - } - set count 0 - csv_foreach_row $peripherals_file cols { ;# peripheral atom and location table - incr count - - # skip header - if {$count == 1} { - continue - } - - set peripheral_name [string trim [lindex $cols 0]] - set atom_name [string trim [lindex $cols 1]] - - funset peripheral - if {[info exists peripherals($peripheral_name)]} { - array set peripheral $peripherals($peripheral_name) - } else { - # Assume that if a peripheral hasn't be recognized until now, we won't be using it - continue - } - set peripheral(atom_name) $atom_name - set peripherals($peripheral_name) [array get peripheral] - } - add_parameter DB_periph_ifaces string [array get peripherals] "" - set_parameter_property DB_periph_ifaces derived true - set_parameter_property DB_periph_ifaces visible false - - set p [array get peripherals] - send_message debug "DB_periph_ifaces: ${p}" - - # ports - array set ports_to_pins {} - # # prepopulate interface_ports with names of interfaces that are known - # foreach {peripheral_name peripheral_string} [array get peripherals] { - # array set peripheral_array $peripheral_string - # foreach interface_name [array names peripheral_array] { - # set interface_ports($interface_name) {} - # } - # } - set count 0 - csv_foreach_row $ports_file cols { - incr count - - # skip header - if {$count == 1} continue - - set interface_name [string trim [lindex $cols 0]] - set port_name [string trim [lindex $cols 1]] - set role [string trim [lindex $cols 2]] - set dir [string trim [lindex $cols 3]] - set atom_signal_name [string trim [lindex $cols 4]] - - funset interface - array set interface $interface_ports($interface_name) - set ordered_names $interface([ORDERED_NAMES]) - lappend ordered_names $port_name - set interface([ORDERED_NAMES]) $ordered_names - - funset port - set port(role) $role - set port(direction) $dir - set port(atom_signal_name) $atom_signal_name - set interface($port_name) [array get port] - set interface_ports($interface_name) [array get interface] - - set ports_to_pins($port_name) {} - } - add_parameter DB_iface_ports string [array get interface_ports] "" - set_parameter_property DB_iface_ports derived true - set_parameter_property DB_iface_ports visible false - - set p [array get interface_ports] - send_message debug "DB_iface_ports: ${p}" - - # peripheral signals to ports - set count 0 - csv_foreach_row $pins_file cols { - incr count - - # skip header - if {$count == 1} continue - - set peripheral_name [string trim [lindex $cols 0]] - set pin_name [string trim [lindex $cols 1]] - set port_name [string trim [lindex $cols 2]] - - set is_multibit_signal [regexp {^([a-zA-Z0-9_]+)\[([0-9]+)\]} $port_name match real_name bit] - if {$is_multibit_signal == 0} { - set bit 0 - } else { - set port_name $real_name - } - - if {[info exists ports_to_pins($port_name)] == 0} { - send_message error "Peripheral ${peripheral_name} signal ${pin_name} is defined but corresponding FPGA signal ${port_name}\[${bit}\] is not" - } else { - funset port - array set port $ports_to_pins($port_name) - - if {[info exists port($bit)]} { - # collision! - send_message error "Signal ${port_name}\[${bit}\] is having original assignment ${peripheral_name}.${port($bit)} replaced with ${peripheral_name}.${pin_name}" - } - set port($bit) $pin_name - set ports_to_pins($port_name) [array get port] - } - } - add_parameter DB_port_pins string [array get ports_to_pins] "" - set_parameter_property DB_port_pins derived true - set_parameter_property DB_port_pins visible false - - set p [array get ports_to_pins] - send_message debug "DB_port_pins: ${p}" - - # bfm types - set count 0 - funset bfm_types - csv_foreach_row $bfm_types_file cols { - incr count - - # skip header - if {$count == 1} continue - - set bfm_type_name [string trim [lindex $cols 0]] - set property_name [string trim [lindex $cols 1]] - set value [string trim [lindex $cols 2]] - - if {[info exists bfm_types($bfm_type_name)] == 0} { - set bfm_types($bfm_type_name) {} - } - funset bfm_type - array set bfm_type $bfm_types($bfm_type_name) - set bfm_type($property_name) $value - set bfm_types($bfm_type_name) [array get bfm_type] - } - add_parameter DB_bfm_types string [array get bfm_types] "" - set_parameter_property DB_bfm_types derived true - set_parameter_property DB_bfm_types visible false - # TODO: what to do so that mode information on a peripheral.pin basis can be used for elaboration??? -} - -# only run during class creation -load_periph_ifaces_db - -####################### -##### Composition ##### -####################### - -namespace eval ::fpga_interfaces { - source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_interface_generator/api.tcl -} - -namespace eval ::hps_io { - namespace eval internal { - source $env(QUARTUS_ROOTDIR)/../ip/altera/hps/altera_interface_generator/api.tcl - } - variable pins - - proc add_peripheral {peripheral_name atom_name location} { - internal::add_module_instance $peripheral_name $atom_name $location - } - - # oe used in tristate output and inout - # out used in output and inout - # in used in input and inout - proc add_pin {peripheral_name pin_name dir location in_port out_port oe_port} { - variable pins - lappend pins [list $peripheral_name $pin_name $dir $location $in_port $out_port $oe_port] - } - - proc process_pins {} { - variable pins - - set interface_name "hps_io" - set hps_io_interface_created 0 - funset ports_used ;# set of inst/ports used - funset port_wire ;# map of ports to aliased wires - foreach pin $pins { ;# Check for multiple uses of the same port and create wires for those cases - lassign $pin peripheral_name pin_name dir location in_port out_port oe_port - - # check to see if port is used multiple times - foreach port_part [list $in_port $out_port $oe_port] { - if {$port_part != "" && [info exists ports_used($port_part)]} { - # Assume only outputs will be used multiple times. Inputs would be an error - if {[info exists port_wire($port_part)] == 0} { - set port_wire($port_part) [internal::allocate_wire] - # Drive new wire with port - internal::set_wire_port_fragments $port_wire($port_part) driven_by $port_part - } - } - set ports_used($port_part) 1 - } - } - - set qip [list] - foreach pin $pins { - lassign $pin peripheral_name pin_name dir location in_port out_port oe_port - foreach port_part_ref {in_port out_port oe_port} { ;# Replace ports with wires if needed - set port_part [set $port_part_ref] - if {[info exists port_wire($port_part)]} { - set $port_part_ref [internal::wire_tofragment $port_wire($port_part)] - } - } - - # Hook things up - set instance_name [string tolower $peripheral_name] ;# is this necessary??? - if {$hps_io_interface_created == 0} { - set hps_io_interface_created 1 - internal::add_interface $interface_name conduit input - } - set export_signal_name "hps_io_${instance_name}_${pin_name}" - internal::add_interface_port $interface_name $export_signal_name $export_signal_name $dir 1 - if {[string compare $dir "input"] == 0} { - internal::set_port_fragments $interface_name $export_signal_name $in_port - internal::add_raw_sdc_constraint "set_false_path -from \[get_ports ${interface_name}_${export_signal_name}\] -to *" - } elseif {[string compare $dir "output"] == 0} { - if {[string compare $oe_port "" ] == 0} { - internal::set_port_fragments $interface_name $export_signal_name $out_port - internal::add_raw_sdc_constraint "set_false_path -from * -to \[get_ports ${interface_name}_${export_signal_name}\]" - } else { - internal::set_port_tristate_output $interface_name $export_signal_name $out_port $oe_port - internal::add_raw_sdc_constraint "set_false_path -from * -to \[get_ports ${interface_name}_${export_signal_name}\]" - } - } else { - internal::set_port_fragments $interface_name $export_signal_name $in_port - internal::set_port_tristate_output $interface_name $export_signal_name $out_port $oe_port - internal::add_raw_sdc_constraint "set_false_path -from \[get_ports ${interface_name}_${export_signal_name}\] -to *" - internal::add_raw_sdc_constraint "set_false_path -from * -to \[get_ports ${interface_name}_${export_signal_name}\]" - } - set path_to_pin "hps_io|border|${export_signal_name}\[0\]" - set location_assignment "set_instance_assignment -name HPS_LOCATION ${location} -entity %entityName% -to ${path_to_pin}" - lappend qip $location_assignment - } - set_qip_strings $qip - } - - proc init {} { - internal::init - variable pins [list] - } - - proc serialize {var_name} { - upvar 1 $var_name data - process_pins - internal::serialize data - } -} - -set_module_property composition_callback compose - -proc compose {} { - # synchronize device families between the EMIF and HPS parameter sets - set_parameter_value hps_device_family [get_parameter_value SYS_INFO_DEVICE_FAMILY] - fpga_interfaces::init - fpga_interfaces::set_bfm_types [array get DB_bfm_types] - - hps_io::init - validate - elab 0 - - update_hps_to_fpga_clock_frequency_parameters - - - fpga_interfaces::serialize fpga_interfaces_data - - add_instance fpga_interfaces altera_interface_generator - set_instance_parameter_value fpga_interfaces interfaceDefinition [array get fpga_interfaces_data] - - expose_border fpga_interfaces $fpga_interfaces_data(interfaces) - - declare_cmsis_svd $fpga_interfaces_data(interfaces) - - clear_array temp_array -} - -proc logicalview_dtg {} { - - set hard_peripheral_logical_view_dir $::env(QUARTUS_ROOTDIR)/../ip/altera/hps/hard_peripheral_logical_view - - source "$hard_peripheral_logical_view_dir/common/hps_utils.tcl" - - source "$hard_peripheral_logical_view_dir/hps_periphs/hps_periphs.tcl" - - set f2h_present [ expr [ get_parameter_value F2S_Width ] != 0] - set h2f_present [ expr [ get_parameter_value S2F_Width ] != 0] - set F2S_Width [ get_parameter_value F2S_Width ] - set S2F_Width [ get_parameter_value S2F_Width ] - set h2f_lw_present [ expr [ string compare [ get_parameter_value LWH2F_Enable ] "true" ] == 0 ] - set LWH2F_Enable [ get_parameter_value LWH2F_Enable ] - set device_family [get_parameter_value SYS_INFO_DEVICE_FAMILY] - - # Need to add whole bunch of device tree generation parameters here (dtg) - # Getting whether is it single or dual core by checking the device family. List of single core: - # Cyclone V SE - regsub "^.* V" $device_family "" se_family - regsub " " $se_family "" se_family - - set number_of_a9 0 - if { [string toupper $se_family] == "SE"} { - set number_of_a9 1 - } else { - set number_of_a9 2 - } - - set F2SDRAM_Width [get_parameter_value F2SDRAM_Width] - set F2SDRAM_Type [get_parameter_value F2SDRAM_Type] - set quartus_ini_hps_ip_f2sdram_bonding_out [get_parameter_value quartus_ini_hps_ip_f2sdram_bonding_out] - set BONDING_OUT_ENABLED [get_parameter_value BONDING_OUT_ENABLED] - add_instance clk_0 hps_clk_src - hps_utils_add_instance_clk_reset clk_0 bridges hps_bridge_avalon - set_instance_parameter_value bridges F2S_Width $F2S_Width - set_instance_parameter_value bridges S2F_Width $S2F_Width - set_instance_parameter_value bridges BONDING_OUT_ENABLED $BONDING_OUT_ENABLED - set_instance_parameter_value bridges LWH2F_Enable $LWH2F_Enable - set_instance_parameter_value bridges quartus_ini_hps_ip_f2sdram_bonding_out $quartus_ini_hps_ip_f2sdram_bonding_out - add_interface h2f_reset reset output - set_interface_property h2f_reset EXPORT_OF bridges.h2f_reset - set_interface_property h2f_reset PORT_NAME_MAP "h2f_rst_n h2f_rst_n" - - set rows [llength $F2SDRAM_Width] - set type_list $F2SDRAM_Type - set append_type_list "" - set append_type_width "" - set total_command_port 0 - set total_write_port 0 - set total_read_port 0 - if {$rows > 0} { - for {set i 0} {${i} < $rows} {incr i} { - set type_choice [lindex $type_list $i] - set type_width [lindex $F2SDRAM_Width $i] - if { [string compare $type_choice [F2HSDRAM_AVM]] == 0 } { - set type_id 1 - set total_command_port [expr $total_command_port + 1] - if {$type_width == 128} { - set total_write_port [expr $total_write_port + 2] - set total_read_port [expr $total_read_port + 2] - } elseif {$type_width == 256 } { - set total_write_port [expr $total_write_port + 4] - set total_read_port [expr $total_read_port + 4] - } else { - set total_write_port [expr $total_write_port + 1] - set total_read_port [expr $total_read_port + 1] - } - } elseif { [string compare $type_choice [F2HSDRAM_AVM_WRITEONLY]] == 0 } { - set type_id 2 - set total_command_port [expr $total_command_port + 1] - if {$type_width == 128} { - set total_write_port [expr $total_write_port + 2] - } elseif {$type_width == 256 } { - set total_write_port [expr $total_write_port + 4] - } else { - set total_write_port [expr $total_write_port + 1] - } - } elseif { [string compare $type_choice [F2HSDRAM_AVM_READONLY]] == 0 } { - set type_id 3 - set total_command_port [expr $total_command_port + 1] - if {$type_width == 128} { - set total_read_port [expr $total_read_port + 2] - } elseif {$type_width == 256 } { - set total_read_port [expr $total_read_port + 4] - } else { - set total_read_port [expr $total_read_port + 1] - } - } else { - set type_id 0 - if { [ expr $total_command_port % 2 ] } { - incr total_command_port 1 - } - set total_command_port [expr $total_command_port + 2] - if {$type_width == 128} { - set total_write_port [expr $total_write_port + 2] - set total_read_port [expr $total_read_port + 2] - } elseif {$type_width == 256 } { - set total_write_port [expr $total_write_port + 4] - set total_read_port [expr $total_read_port + 4] - } else { - set total_write_port [expr $total_write_port + 1] - set total_read_port [expr $total_read_port + 1] - } - } - - if {$total_command_port > 6} { - if {$type_id == 0} { - send_message error "No command ports available to allocate AXI Interface f2h_sdram${i}" - } else { - send_message error "No command ports available to allocate Avalon-MM Interface f2h_sdram${i}" - } - } - if {$total_read_port > 4} { - if {$type_id == 0} { - send_message error "No read ports available to allocate AXI Interface f2h_sdram${i}" - } else { - send_message error "No read ports available to allocate Avalon-MM Interface f2h_sdram${i}" - } - } - if {$total_write_port > 4} { - if {$type_id == 0} { - send_message error "No write ports available to allocate AXI Interface f2h_sdram${i}" - } else { - send_message error "No write ports available to allocate Avalon-MM Interface f2h_sdram${i}" - } - } - if {$total_command_port < 7 && $total_write_port < 5 && $total_read_port < 5} { - lappend append_type_list $type_id - lappend append_type_width $type_width - } - } - } - set_instance_parameter_value bridges F2SDRAM_Type $append_type_list - set_instance_parameter_value bridges F2SDRAM_Width $append_type_width - set total_command_port 0 - set total_write_port 0 - set total_read_port 0 - set bonding_out_signal [expr { [string compare [get_parameter_value BONDING_OUT_ENABLED] "true"] == 0} && {[string compare [get_parameter_value quartus_ini_hps_ip_f2sdram_bonding_out] "true"] == 0}] - - if {$rows > 0} { - for {set i 0} {${i} < $rows} {incr i} { - - set type_choice [lindex $type_list $i] - set type_width [lindex $F2SDRAM_Width $i] - - if { [string compare $type_choice [F2HSDRAM_AVM]] == 0 } { - set type "avalon" - set total_command_port [expr $total_command_port + 1] - if {$type_width == 128} { - set total_write_port [expr $total_write_port + 2] - set total_read_port [expr $total_read_port + 2] - } elseif {$type_width == 256 } { - set total_write_port [expr $total_write_port + 4] - set total_read_port [expr $total_read_port + 4] - } else { - set total_write_port [expr $total_write_port + 1] - set total_read_port [expr $total_read_port + 1] - } - set sdram_data "f2h_sdram${i}_ADDRESS f2h_sdram${i}_ADDRESS f2h_sdram${i}_BURSTCOUNT f2h_sdram${i}_BURSTCOUNT f2h_sdram${i}_WAITREQUEST f2h_sdram${i}_WAITREQUEST f2h_sdram${i}_READDATA f2h_sdram${i}_READDATA f2h_sdram${i}_READDATAVALID f2h_sdram${i}_READDATAVALID f2h_sdram${i}_READ f2h_sdram${i}_READ f2h_sdram${i}_WRITEDATA f2h_sdram${i}_WRITEDATA f2h_sdram${i}_BYTEENABLE f2h_sdram${i}_BYTEENABLE f2h_sdram${i}_WRITE f2h_sdram${i}_WRITE" - } elseif { [string compare $type_choice [F2HSDRAM_AVM_WRITEONLY]] == 0 } { - set type "avalon" - set total_command_port [expr $total_command_port + 1] - if {$type_width == 128} { - set total_write_port [expr $total_write_port + 2] - } elseif {$type_width == 256 } { - set total_write_port [expr $total_write_port + 4] - } else { - set total_write_port [expr $total_write_port + 1] - } - set sdram_data "f2h_sdram${i}_ADDRESS f2h_sdram${i}_ADDRESS f2h_sdram${i}_BURSTCOUNT f2h_sdram${i}_BURSTCOUNT f2h_sdram${i}_WAITREQUEST f2h_sdram${i}_WAITREQUEST f2h_sdram${i}_WRITEDATA f2h_sdram${i}_WRITEDATA f2h_sdram${i}_BYTEENABLE f2h_sdram${i}_BYTEENABLE f2h_sdram${i}_WRITE f2h_sdram${i}_WRITE" - } elseif { [string compare $type_choice [F2HSDRAM_AVM_READONLY]] == 0 } { - set type "avalon" - set total_command_port [expr $total_command_port + 1] - if {$type_width == 128} { - set total_read_port [expr $total_read_port + 2] - } elseif {$type_width == 256 } { - set total_read_port [expr $total_read_port + 4] - } else { - set total_read_port [expr $total_read_port + 1] - } - set sdram_data "f2h_sdram${i}_ADDRESS f2h_sdram${i}_ADDRESS f2h_sdram${i}_BURSTCOUNT f2h_sdram${i}_BURSTCOUNT f2h_sdram${i}_WAITREQUEST f2h_sdram${i}_WAITREQUEST f2h_sdram${i}_READDATA f2h_sdram${i}_READDATA f2h_sdram${i}_READDATAVALID f2h_sdram${i}_READDATAVALID f2h_sdram${i}_READ f2h_sdram${i}_READ" - } else { - set type "axi" - if { [ expr $total_command_port % 2 ] } { - incr total_command_port 1 - } - set total_command_port [expr $total_command_port + 2] - if {$type_width == 128} { - set total_write_port [expr $total_write_port + 2] - set total_read_port [expr $total_read_port + 2] - } elseif {$type_width == 256 } { - set total_write_port [expr $total_write_port + 4] - set total_read_port [expr $total_read_port + 4] - } else { - set total_write_port [expr $total_write_port + 1] - set total_read_port [expr $total_read_port + 1] - } - set sdram_data "f2h_sdram${i}_ARADDR f2h_sdram${i}_ARADDR f2h_sdram${i}_ARLEN f2h_sdram${i}_ARLEN f2h_sdram${i}_ARID f2h_sdram${i}_ARID f2h_sdram${i}_ARSIZE f2h_sdram${i}_ARSIZE f2h_sdram${i}_ARBURST f2h_sdram${i}_ARBURST f2h_sdram${i}_ARLOCK f2h_sdram${i}_ARLOCK f2h_sdram${i}_ARPROT f2h_sdram${i}_ARPROT f2h_sdram${i}_ARVALID f2h_sdram${i}_ARVALID f2h_sdram${i}_ARCACHE f2h_sdram${i}_ARCACHE f2h_sdram${i}_AWADDR f2h_sdram${i}_AWADDR f2h_sdram${i}_AWLEN f2h_sdram${i}_AWLEN f2h_sdram${i}_AWID f2h_sdram${i}_AWID f2h_sdram${i}_AWSIZE f2h_sdram${i}_AWSIZE f2h_sdram${i}_AWBURST f2h_sdram${i}_AWBURST f2h_sdram${i}_AWLOCK f2h_sdram${i}_AWLOCK f2h_sdram${i}_AWPROT f2h_sdram${i}_AWPROT f2h_sdram${i}_AWVALID f2h_sdram${i}_AWVALID f2h_sdram${i}_AWCACHE f2h_sdram${i}_AWCACHE f2h_sdram${i}_BRESP f2h_sdram${i}_BRESP f2h_sdram${i}_BID f2h_sdram${i}_BID f2h_sdram${i}_BVALID f2h_sdram${i}_BVALID f2h_sdram${i}_BREADY f2h_sdram${i}_BREADY f2h_sdram${i}_ARREADY f2h_sdram${i}_ARREADY f2h_sdram${i}_AWREADY f2h_sdram${i}_AWREADY f2h_sdram${i}_RREADY f2h_sdram${i}_RREADY f2h_sdram${i}_RDATA f2h_sdram${i}_RDATA f2h_sdram${i}_RRESP f2h_sdram${i}_RRESP f2h_sdram${i}_RLAST f2h_sdram${i}_RLAST f2h_sdram${i}_RID f2h_sdram${i}_RID f2h_sdram${i}_RVALID f2h_sdram${i}_RVALID f2h_sdram${i}_WLAST f2h_sdram${i}_WLAST f2h_sdram${i}_WVALID f2h_sdram${i}_WVALID f2h_sdram${i}_WDATA f2h_sdram${i}_WDATA f2h_sdram${i}_WSTRB f2h_sdram${i}_WSTRB f2h_sdram${i}_WREADY f2h_sdram${i}_WREADY f2h_sdram${i}_WID f2h_sdram${i}_WID" - } - - if {$total_command_port > 6 || $total_write_port > 4 || $total_read_port > 4} { - break - } - add_interface f2h_sdram${i}_clock clock Input - set_interface_property f2h_sdram${i}_clock EXPORT_OF bridges.f2h_sdram${i}_clock - set_interface_property f2h_sdram${i}_clock PORT_NAME_MAP "f2h_sdram${i}_clk f2h_sdram${i}_clk" - add_interface f2h_sdram${i}_data $type slave - set_interface_property f2h_sdram${i}_data EXPORT_OF bridges.f2h_sdram${i}_data - set_interface_property f2h_sdram${i}_data PORT_NAME_MAP "$sdram_data" - } - - if $bonding_out_signal { - set bon_out_signal "f2h_sdram_BONOUT_1 f2h_sdram_BONOUT_1 f2h_sdram_BONOUT_2 f2h_sdram_BONOUT_2" - add_interface f2h_sdram_bon_out conduit Output - set_interface_property f2h_sdram_bon_out EXPORT_OF bridges.f2h_sdram_bon_out - set_interface_property f2h_sdram_bon_out PORT_NAME_MAP "$bon_out_signal" - } - - } - - set declared_svd_file 0 - set svd_path [file join $::env(QUARTUS_ROOTDIR) .. ip altera hps altera_hps altera_hps.svd] - if { $h2f_present } { - hps_utils_add_slave_interface arm_a9_0.altera_axi_master bridges.axi_h2f {0xc0000000} - if { $number_of_a9 > 1 } { - hps_utils_add_slave_interface arm_a9_1.altera_axi_master bridges.axi_h2f {0xc0000000} - } - - add_interface h2f_axi_clock clock Input - set_interface_property h2f_axi_clock EXPORT_OF bridges.h2f_axi_clock - set_interface_property h2f_axi_clock PORT_NAME_MAP "h2f_axi_clk h2f_axi_clk" - - add_interface h2f_axi_master axi master - set_interface_property h2f_axi_master EXPORT_OF bridges.h2f - set_interface_property h2f_axi_master PORT_NAME_MAP "h2f_AWID h2f_AWID h2f_AWADDR h2f_AWADDR h2f_AWLEN h2f_AWLEN h2f_AWSIZE h2f_AWSIZE h2f_AWBURST h2f_AWBURST h2f_AWLOCK h2f_AWLOCK h2f_AWCACHE h2f_AWCACHE h2f_AWPROT h2f_AWPROT h2f_AWVALID h2f_AWVALID h2f_AWREADY h2f_AWREADY h2f_WID h2f_WID h2f_WDATA h2f_WDATA h2f_WSTRB h2f_WSTRB h2f_WLAST h2f_WLAST h2f_WVALID h2f_WVALID h2f_WREADY h2f_WREADY h2f_BID h2f_BID h2f_BRESP h2f_BRESP h2f_BVALID h2f_BVALID h2f_BREADY h2f_BREADY h2f_ARID h2f_ARID h2f_ARADDR h2f_ARADDR h2f_ARLEN h2f_ARLEN h2f_ARSIZE h2f_ARSIZE h2f_ARBURST h2f_ARBURST h2f_ARLOCK h2f_ARLOCK h2f_ARCACHE h2f_ARCACHE h2f_ARPROT h2f_ARPROT h2f_ARVALID h2f_ARVALID h2f_ARREADY h2f_ARREADY h2f_RID h2f_RID h2f_RDATA h2f_RDATA h2f_RRESP h2f_RRESP h2f_RLAST h2f_RLAST h2f_RVALID h2f_RVALID h2f_RREADY h2f_RREADY" - set_interface_property h2f_axi_master SVD_ADDRESS_GROUP "hps" - set_interface_property h2f_axi_master SVD_ADDRESS_OFFSET 0xC0000000 - if {!$declared_svd_file} { - set_interface_property h2f_axi_master CMSIS_SVD_FILE $svd_path - set declared_svd_file 1 - } - } - - if { $f2h_present } { - add_interface f2h_axi_clock clock Input - set_interface_property f2h_axi_clock EXPORT_OF bridges.f2h_axi_clock - set_interface_property f2h_axi_clock PORT_NAME_MAP "f2h_axi_clk f2h_axi_clk" - - add_interface f2h_axi_slave axi slave - set_interface_property f2h_axi_slave EXPORT_OF bridges.f2h - set_interface_property f2h_axi_slave PORT_NAME_MAP "f2h_AWID f2h_AWID f2h_AWADDR f2h_AWADDR f2h_AWLEN f2h_AWLEN f2h_AWSIZE f2h_AWSIZE f2h_AWBURST f2h_AWBURST f2h_AWLOCK f2h_AWLOCK f2h_AWCACHE f2h_AWCACHE f2h_AWPROT f2h_AWPROT f2h_AWVALID f2h_AWVALID f2h_AWREADY f2h_AWREADY f2h_AWUSER f2h_AWUSER f2h_WID f2h_WID f2h_WDATA f2h_WDATA f2h_WSTRB f2h_WSTRB f2h_WLAST f2h_WLAST f2h_WVALID f2h_WVALID f2h_WREADY f2h_WREADY f2h_BID f2h_BID f2h_BRESP f2h_BRESP f2h_BVALID f2h_BVALID f2h_BREADY f2h_BREADY f2h_ARID f2h_ARID f2h_ARADDR f2h_ARADDR f2h_ARLEN f2h_ARLEN f2h_ARSIZE f2h_ARSIZE f2h_ARBURST f2h_ARBURST f2h_ARLOCK f2h_ARLOCK f2h_ARCACHE f2h_ARCACHE f2h_ARPROT f2h_ARPROT f2h_ARVALID f2h_ARVALID f2h_ARREADY f2h_ARREADY f2h_ARUSER f2h_ARUSER f2h_RID f2h_RID f2h_RDATA f2h_RDATA f2h_RRESP f2h_RRESP f2h_RLAST f2h_RLAST f2h_RVALID f2h_RVALID f2h_RREADY f2h_RREADY" - } - - if { $h2f_lw_present } { - hps_utils_add_slave_interface arm_a9_0.altera_axi_master bridges.axi_h2f_lw {0xff200000} - if { $number_of_a9 > 1 } { - hps_utils_add_slave_interface arm_a9_1.altera_axi_master bridges.axi_h2f_lw {0xff200000} - } - - add_interface h2f_lw_axi_clock clock Input - set_interface_property h2f_lw_axi_clock EXPORT_OF bridges.h2f_lw_axi_clock - set_interface_property h2f_lw_axi_clock PORT_NAME_MAP "h2f_lw_axi_clk h2f_lw_axi_clk" - - add_interface h2f_lw_axi_master axi start - set_interface_property h2f_lw_axi_master EXPORT_OF bridges.h2f_lw - set_interface_property h2f_lw_axi_master PORT_NAME_MAP "h2f_lw_AWID h2f_lw_AWID h2f_lw_AWADDR h2f_lw_AWADDR h2f_lw_AWLEN h2f_lw_AWLEN h2f_lw_AWSIZE h2f_lw_AWSIZE h2f_lw_AWBURST h2f_lw_AWBURST h2f_lw_AWLOCK h2f_lw_AWLOCK h2f_lw_AWCACHE h2f_lw_AWCACHE h2f_lw_AWPROT h2f_lw_AWPROT h2f_lw_AWVALID h2f_lw_AWVALID h2f_lw_AWREADY h2f_lw_AWREADY h2f_lw_WID h2f_lw_WID h2f_lw_WDATA h2f_lw_WDATA h2f_lw_WSTRB h2f_lw_WSTRB h2f_lw_WLAST h2f_lw_WLAST h2f_lw_WVALID h2f_lw_WVALID h2f_lw_WREADY h2f_lw_WREADY h2f_lw_BID h2f_lw_BID h2f_lw_BRESP h2f_lw_BRESP h2f_lw_BVALID h2f_lw_BVALID h2f_lw_BREADY h2f_lw_BREADY h2f_lw_ARID h2f_lw_ARID h2f_lw_ARADDR h2f_lw_ARADDR h2f_lw_ARLEN h2f_lw_ARLEN h2f_lw_ARSIZE h2f_lw_ARSIZE h2f_lw_ARBURST h2f_lw_ARBURST h2f_lw_ARLOCK h2f_lw_ARLOCK h2f_lw_ARCACHE h2f_lw_ARCACHE h2f_lw_ARPROT h2f_lw_ARPROT h2f_lw_ARVALID h2f_lw_ARVALID h2f_lw_ARREADY h2f_lw_ARREADY h2f_lw_RID h2f_lw_RID h2f_lw_RDATA h2f_lw_RDATA h2f_lw_RRESP h2f_lw_RRESP h2f_lw_RLAST h2f_lw_RLAST h2f_lw_RVALID h2f_lw_RVALID h2f_lw_RREADY h2f_lw_RREADY" - set_interface_property h2f_lw_axi_master SVD_ADDRESS_GROUP "hps" - set_interface_property h2f_lw_axi_master SVD_ADDRESS_OFFSET 0xFF200000 - if {!$declared_svd_file} { - set_interface_property h2f_lw_axi_master CMSIS_SVD_FILE $svd_path - set declared_svd_file 1 - } - } - - if {!$declared_svd_file} { - set_module_assignment "cmsis.svd.file" $svd_path - set_module_assignment "cmsis.svd.suffix" "hps" - } - - clocks_logicalview_dtg - - if { $number_of_a9 > 0 } { - hps_utils_add_instance_clk_reset clk_0 arm_a9_0 arm_a9 - } - - if { $number_of_a9 > 1 } { - hps_utils_add_instance_clk_reset clk_0 arm_a9_1 arm_a9 - } - - - hps_instantiate_arm_gic_0 $number_of_a9 - - hps_instantiate_L2 $number_of_a9 - - hps_instantiate_dma $number_of_a9 - - hps_instantiate_sysmgr $number_of_a9 - - hps_instantiate_clkmgr $number_of_a9 - - hps_instantiate_rstmgr $number_of_a9 - - hps_instantiate_fpgamgr $number_of_a9 - - hps_instantiate_uart0 $number_of_a9 "UART0_PinMuxing" [get_parameter_value l4_sp_clk_mhz] - - hps_instantiate_uart1 $number_of_a9 "UART1_PinMuxing" [get_parameter_value l4_sp_clk_mhz] - - hps_instantiate_timer0 $number_of_a9 - - hps_instantiate_timer1 $number_of_a9 - - hps_instantiate_timer2 $number_of_a9 - - hps_instantiate_timer3 $number_of_a9 - - hps_instantiate_wd_timer0 $number_of_a9 - - hps_instantiate_wd_timer1 $number_of_a9 - - hps_instantiate_gpio0 $number_of_a9 - - hps_instantiate_gpio1 $number_of_a9 - - hps_instantiate_gpio2 $number_of_a9 - - hps_instantiate_i2c0 $number_of_a9 "I2C0_PinMuxing" - - hps_instantiate_i2c1 $number_of_a9 "I2C1_PinMuxing" - - hps_instantiate_i2c2 $number_of_a9 "I2C2_PinMuxing" - - hps_instantiate_i2c3 $number_of_a9 "I2C3_PinMuxing" - - hps_instantiate_nand0 $number_of_a9 "NAND_PinMuxing" - - hps_instantiate_spim0 $number_of_a9 "SPIM0_PinMuxing" - - hps_instantiate_spim1 $number_of_a9 "SPIM1_PinMuxing" - - hps_instantiate_qspi $number_of_a9 "QSPI_PinMuxing" - - hps_instantiate_sdmmc $number_of_a9 "SDIO_PinMuxing" - - hps_instantiate_usb0 $number_of_a9 "USB0_PinMuxing" - - hps_instantiate_usb1 $number_of_a9 "USB1_PinMuxing" - - hps_instantiate_gmac0 $number_of_a9 "EMAC0_PinMuxing" - - hps_instantiate_gmac1 $number_of_a9 "EMAC1_PinMuxing" - - hps_instantiate_dcan0 $number_of_a9 "CAN0_PinMuxing" - - hps_instantiate_dcan1 $number_of_a9 "CAN1_PinMuxing" - - hps_instantiate_l3regs $number_of_a9 - - hps_instantiate_sdrctl $number_of_a9 - - hps_instantiate_axi_ocram $number_of_a9 - - hps_instantiate_axi_sdram $number_of_a9 - - hps_instantiate_timer $number_of_a9 - - hps_instantiate_scu $number_of_a9 - - add_connection arm_gic_0.arm_gic_ppi timer.interrupt_sender - set_connection_parameter_value arm_gic_0.arm_gic_ppi/timer.interrupt_sender irqNumber 13 - - if { $f2h_present } { - hps_utils_add_slave_interface bridges.axi_f2h arm_gic_0.axi_slave0 {0xfffed000} - hps_utils_add_slave_interface bridges.axi_f2h arm_gic_0.axi_slave1 {0xfffec100} - hps_utils_add_slave_interface bridges.axi_f2h L2.axi_slave0 {0xfffef000} - hps_utils_add_slave_interface bridges.axi_f2h dma.axi_slave0 {0xffe01000} - hps_utils_add_slave_interface bridges.axi_f2h sysmgr.axi_slave0 {0xffd08000} - hps_utils_add_slave_interface bridges.axi_f2h clkmgr.axi_slave0 {0xffd04000} - hps_utils_add_slave_interface bridges.axi_f2h rstmgr.axi_slave0 {0xffd05000} - hps_utils_add_slave_interface bridges.axi_f2h fpgamgr.axi_slave0 {0xff706000} - hps_utils_add_slave_interface bridges.axi_f2h fpgamgr.axi_slave1 {0xffb90000} - hps_utils_add_slave_interface bridges.axi_f2h uart0.axi_slave0 {0xffc02000} - hps_utils_add_slave_interface bridges.axi_f2h uart1.axi_slave0 {0xffc03000} - hps_utils_add_slave_interface bridges.axi_f2h timer0.axi_slave0 {0xffc08000} - hps_utils_add_slave_interface bridges.axi_f2h timer1.axi_slave0 {0xffc09000} - hps_utils_add_slave_interface bridges.axi_f2h timer2.axi_slave0 [hps_timer2_base] - hps_utils_add_slave_interface bridges.axi_f2h timer3.axi_slave0 [hps_timer3_base] - hps_utils_add_slave_interface bridges.axi_f2h gpio0.axi_slave0 {0xff708000} - hps_utils_add_slave_interface bridges.axi_f2h gpio1.axi_slave0 {0xff709000} - hps_utils_add_slave_interface bridges.axi_f2h gpio2.axi_slave0 {0xff70a000} - hps_utils_add_slave_interface bridges.axi_f2h i2c0.axi_slave0 {0xffc04000} - hps_utils_add_slave_interface bridges.axi_f2h i2c1.axi_slave0 {0xffc05000} - hps_utils_add_slave_interface bridges.axi_f2h i2c2.axi_slave0 {0xffc06000} - hps_utils_add_slave_interface bridges.axi_f2h i2c3.axi_slave0 {0xffc07000} - hps_utils_add_slave_interface bridges.axi_f2h nand0.axi_slave0 {0xff900000} - hps_utils_add_slave_interface bridges.axi_f2h nand0.axi_slave1 {0xffb80000} - hps_utils_add_slave_interface bridges.axi_f2h spim0.axi_slave0 [hps_spim0_base] - hps_utils_add_slave_interface bridges.axi_f2h spim1.axi_slave0 [hps_spim1_base] - hps_utils_add_slave_interface bridges.axi_f2h qspi.axi_slave0 {0xff705000} - hps_utils_add_slave_interface bridges.axi_f2h qspi.axi_slave1 {0xffa00000} - hps_utils_add_slave_interface bridges.axi_f2h sdmmc.axi_slave0 {0xff704000} - hps_utils_add_slave_interface bridges.axi_f2h usb0.axi_slave0 {0xffb00000} - hps_utils_add_slave_interface bridges.axi_f2h usb1.axi_slave0 {0xffb40000} - hps_utils_add_slave_interface bridges.axi_f2h gmac0.axi_slave0 {0xff700000} - hps_utils_add_slave_interface bridges.axi_f2h gmac1.axi_slave0 {0xff702000} - hps_utils_add_slave_interface bridges.axi_f2h axi_ocram.axi_slave0 {0xffff0000} - hps_utils_add_slave_interface bridges.axi_f2h axi_sdram.axi_slave0 [hps_sdram_base] - hps_utils_add_slave_interface bridges.axi_f2h timer.axi_slave0 {0xfffec600} - hps_utils_add_slave_interface bridges.axi_f2h dcan0.axi_slave0 [hps_dcan0_base] - hps_utils_add_slave_interface bridges.axi_f2h dcan1.axi_slave0 [hps_dcan1_base] - hps_utils_add_slave_interface bridges.axi_f2h l3regs.axi_slave0 [hps_l3regs_base] - hps_utils_add_slave_interface bridges.axi_f2h sdrctl.axi_slave0 [hps_sdrctl_base] - } - - ##### F2H ##### - if [is_enabled F2SINTERRUPT_Enable] { - set any_interrupt_enabled 1 - set iname "f2h_irq" - set pname "f2h_irq" - add_interface "${iname}0" interrupt receiver - set_interface_property f2h_irq0 EXPORT_OF arm_gic_0.f2h_irq_0_irq_rx_offset_40 - set_interface_property f2h_irq0 PORT_NAME_MAP "f2h_irq_p0 irq_siq_40" - - add_interface "${iname}1" interrupt receiver - set_interface_property f2h_irq1 EXPORT_OF arm_gic_0.f2h_irq_32_irq_rx_offset_72 - set_interface_property f2h_irq1 PORT_NAME_MAP "f2h_irq_p1 irq_siq_72" - } -} - -set_module_property OPAQUE_ADDRESS_MAP false -set_module_property STRUCTURAL_COMPOSITION_CALLBACK compose_logicalview -proc compose_logicalview {} { - # synchronize device families between the EMIF and HPS parameter sets - set_parameter_value hps_device_family [get_parameter_value SYS_INFO_DEVICE_FAMILY] - fpga_interfaces::init - fpga_interfaces::set_bfm_types [array get DB_bfm_types] - - hps_io::init - validate - elab 1 - - update_hps_to_fpga_clock_frequency_parameters - - - fpga_interfaces::serialize fpga_interfaces_data - - add_instance fpga_interfaces altera_interface_generator - set_instance_parameter_value fpga_interfaces interfaceDefinition [array get fpga_interfaces_data] - - expose_border fpga_interfaces $fpga_interfaces_data(interfaces) - - #declare_cmsis_svd $fpga_interfaces_data(interfaces) - - logicalview_dtg -} - -proc declare_cmsis_svd {interfaces_str} { - array set interfaces $interfaces_str - set interface_names $interfaces([ORDERED_NAMES]) - - set h2f_exists 0 - set lwh2f_exists 0 - foreach interface_name $interface_names { - if {[string compare $interface_name "h2f_axi_master"] == 0} { - set h2f_exists 1 - } elseif {[string compare $interface_name "h2f_lw_axi_master"] == 0} { - set lwh2f_exists 1 - } - } - - set svd_path [file join $::env(QUARTUS_ROOTDIR) .. ip altera hps altera_hps altera_hps.svd] - set address_group hps - set declared_svd_file 0 - - if {$h2f_exists} { - if {!$declared_svd_file} { - set_interface_property h2f_axi_master CMSIS_SVD_FILE $svd_path - set declared_svd_file 1 - } - set_interface_property h2f_axi_master SVD_ADDRESS_GROUP $address_group - set_interface_property h2f_axi_master SVD_ADDRESS_OFFSET 0xC0000000 - } - if {$lwh2f_exists} { - if {!$declared_svd_file} { - set_interface_property h2f_lw_axi_master CMSIS_SVD_FILE $svd_path - set declared_svd_file 1 - } - set_interface_property h2f_lw_axi_master SVD_ADDRESS_GROUP $address_group - set_interface_property h2f_lw_axi_master SVD_ADDRESS_OFFSET 0xFF200000 - } - if {!$declared_svd_file} { - set_module_assignment "cmsis.svd.file" $svd_path - set_module_assignment "cmsis.svd.suffix" $address_group - } -} - - -###################### -##### Validation ##### -###################### - -proc validate {} { - set device_family [get_parameter_value hps_device_family] - set device [get_device] - ensure_pin_muxing_data $device_family - update_table_derived_parameters - - validate_F2SDRAM - update_S2F_CLK_mux_options - update_pin_muxing_ui $device_family - - # funset placement_by_pin - validate_pin_muxing $device_family placement_by_pin - update_gpio_ui placement_by_pin - - validate_TEST - - validate_interrupt $device_family - - validate_clocks - -} - -proc validate_TEST {} { - set ini [get_parameter_value quartus_ini_hps_ip_enable_test_interface] - set_parameter_property TEST_Enable visible $ini -} - -proc hide_param { paramName hide} { - -} -proc update_hps_to_fpga_clock_frequency_parameters {} { - set u0 [get_parameter_value S2FCLK_USER0CLK_Enable] - set u1 [get_parameter_value S2FCLK_USER1CLK_Enable] - #set u2 [get_parameter_value S2FCLK_USER2CLK_Enable] - - for { set i 0 } { $i < 2 } { incr i } { - set_parameter_property "S2FCLK_USER${i}CLK_FREQ" enabled [expr "\$u${i}"] - - if { [string compare true [expr "\$u${i}"] ] == 0 } { - fpga_interfaces::set_interface_property "h2f_user${i}_clock" clockRateKnown true - fpga_interfaces::set_interface_property "h2f_user${i}_clock" clockRate [expr [get_parameter_value "S2FCLK_USER${i}CLK_FREQ"] * 1000000 ] - } - } -} - -proc update_table_derived_parameters {} { - update_f2sdram_names - update_dma_peripheral_ids -} - -proc update_f2sdram_names {} { - set num_rows [llength [get_parameter_value F2SDRAM_Width]] - set names [list] - - for {set index 0} {$index < $num_rows} {incr index} { - set name "f2h_sdram${index}" - lappend names $name - } - set_parameter_value F2SDRAM_Name_DERIVED ${names} -} - -proc update_dma_peripheral_ids {} { - set periph_id_list {0 1 2 3 4 5 6 7} - set_parameter_value DMA_PeriphId_DERIVED $periph_id_list -} - -proc is_enabled {parameter} { - if { [string compare [get_parameter_value $parameter] "true" ] == 0 } { - return 1 - } else { - return 0 - } -} - -proc validate_F2SDRAM {} { - set type_list [get_parameter_value F2SDRAM_Type] - set width_list [get_parameter_value F2SDRAM_Width] - set rows [llength $width_list] - - set command_ports_bit 0 - set read_ports_bit 0 - set write_ports_bit 0 - - set command_ports_mask 0 - set read_ports_mask 0 - set write_ports_mask 0 - set reset_ports_mask 0 - - for {set index 0} {${index} < ${rows}} {incr index} { - # check for invalid combinations of type/width - set mytype [lindex $type_list $index] - set mywidth [lindex $width_list $index] - - if {$mywidth < 64} { - send_message warning "Setting the slave port width of interface f2h_sdram${index} to ${mywidth} results in bandwidth under-utilization. Altera recommends you set the interface data width to 64-bit or greater." - } - - # count used ports - # command - if { [string compare $mytype [F2HSDRAM_AXI3]] == 0 } { - if { [ expr $command_ports_bit % 2 ] } { - incr command_ports_bit 1 - } - set command_ports_mask [ expr $command_ports_mask | ( 3 << $command_ports_bit) ] - incr command_ports_bit 2 - } else { - set command_ports_mask [ expr $command_ports_mask | ( 1 << $command_ports_bit) ] - incr command_ports_bit 1 - } - - # read - if {$mytype != [F2HSDRAM_AVM_WRITEONLY]} { - if {$mywidth <= 64} { - set read_ports_mask [ expr $read_ports_mask | ( 1 << $read_ports_bit) ] - incr read_ports_bit 1 - } elseif {$mywidth == 128} { - set read_ports_mask [ expr $read_ports_mask | ( 3 << $read_ports_bit) ] - incr read_ports_bit 2 - } else { - set read_ports_mask [ expr $read_ports_mask | ( 15 << $read_ports_bit) ] - incr read_ports_bit 4 - } - } - - # write - if {$mytype != [F2HSDRAM_AVM_READONLY]} { - if {$mywidth <= 64} { - set write_ports_mask [ expr $write_ports_mask | ( 1 << $write_ports_bit) ] - incr write_ports_bit 1 - } elseif {$mywidth == 128} { - set write_ports_mask [ expr $write_ports_mask | ( 3 << $write_ports_bit) ] - incr write_ports_bit 2 - } else { - set write_ports_mask [ expr $write_ports_mask | ( 15 << $write_ports_bit) ] - incr write_ports_bit 4 - } - } - - # reset - set reset_ports_mask [ expr ($command_ports_mask << 8) | ($write_ports_mask << 4) | ($read_ports_mask) ] - - } - # check for port over-use - if {$command_ports_bit > 6} { - send_message error "The current FPGA to SDRAM configuration is using more command ports than are available." - } - if {$read_ports_bit > 4} { - send_message error "The current FPGA to SDRAM configuration is using more read ports than are available." - } - if {$write_ports_bit > 4} { - send_message error "The current FPGA to SDRAM configuration is using more write ports than are available." - } - - # Store ports used & number of elements to determine when new rows are added - set_parameter_value F2SDRAM_Width_Last_Size $rows - set_parameter_value F2SDRAM_CMD_PORT_USED [ format "0x%X" $command_ports_mask ] - set_parameter_value F2SDRAM_RD_PORT_USED [ format "0x%X" $read_ports_mask ] - set_parameter_value F2SDRAM_WR_PORT_USED [ format "0x%X" $write_ports_mask ] - set_parameter_value F2SDRAM_RST_PORT_USED [ format "0x%X" $reset_ports_mask ] - - # Bonding_out signals will be exported if f2sdram selected - if { ${rows} > 0 } { - set param [get_parameter_value quartus_ini_hps_ip_f2sdram_bonding_out] - set_parameter_property BONDING_OUT_ENABLED visible $param - set_parameter_property BONDING_OUT_ENABLED enabled $param - } else { - set_parameter_property BONDING_OUT_ENABLED enabled false - } - -} - -proc update_S2F_CLK_mux_options {} { - # TODO: retrieve mux options - # TODO: set allowed_ranges on muxes -} - -proc dec2bin {i} { - set res {} - while {$i>0} { - set res [ expr {$i%2} ]$res - set i [expr {$i/2}] - } - if {$res == {}} { - set res 0 - } - return $res -} - -##################################################################### -# -# Gets valid modes for a peripheral with a given pin muxing option. -# Parameters: * peripheral_ref: name of an array pointing to the -# Peripheral HPS I/O Data -# -# Update parameter value with label -proc get_valid_modes {peripheral_name pin_muxing_option peripheral_ref fpga_available} { -##################################################################### - upvar 1 $peripheral_ref peripheral - - if {[info exists peripheral(pin_sets)]} { - array set pin_sets $peripheral(pin_sets) - } - - if {[info exists pin_sets($pin_muxing_option)]} { - array set pin_set $pin_sets($pin_muxing_option) - set pin_set_modes $pin_set(valid_modes) - if {[string match -nocase "trace" $peripheral_name]} { - set valid_modes [list "HPS:8-bit Data" "HPSx4:4-bit Data"] - } elseif {[string match -nocase "usb*" $peripheral_name]} { - set valid_modes [list "SDR:SDR with PHY clock output mode" "SDR without external clock:SDR with PHY clock input mode"] - } else { - set valid_modes [lsort -ascii -increasing $pin_set_modes] - } - } elseif {$fpga_available && [string compare $pin_muxing_option [FPGA_MUX_VALUE]] == 0} { - set valid_modes [list "Full"] - } else { - set valid_modes [list [NA_MODE_VALUE]] - } - return $valid_modes -} - -proc is_peripheral_low_speed_serial_interface {peripheral_name} { - if {[string match -nocase "i2c*" $peripheral_name] || - [string match -nocase "can*" $peripheral_name] || - [string match -nocase "spi*" $peripheral_name] || - [string match -nocase "uart*" $peripheral_name] - } { - return 1 - } - return 0 -} - -# updates the _PinMuxing and _Mode parameter allowed ranges -# -uses a data structure to keep track of choices -# -allowed ranges can come from FPGA Peripheral Interfaces or IOs -# -when a pin muxing option is selected, the mode allowed ranges are -# set according to what's specified from the source (FPGA or pin i/o) -proc update_pin_muxing_ui {device_family} { - - set peripheral_names [list_peripheral_names] - foreach peripheral $peripheral_names { - - get_peripheral_parameter_valid_ranges hps_ip_pin_muxing_model $peripheral\ - selected_pin_muxing_option pin_muxing_options mode_options - - set pin_muxing_param_name [format [PIN_MUX_PARAM_FORMAT] $peripheral] - set mode_param_name [format [MODE_PARAM_FORMAT] $peripheral] - - set pin_muxing_options [lsort -ascii $pin_muxing_options] - set pin_muxing_options [linsert $pin_muxing_options 0 [UNUSED_MUX_VALUE]] - set_parameter_property $pin_muxing_param_name enabled true - set_parameter_property $pin_muxing_param_name visible true - set_parameter_property $pin_muxing_param_name allowed_ranges $pin_muxing_options - set_parameter_property $mode_param_name visible true - - - set selected_mode_option [get_parameter_value $mode_param_name] - - # Disable I2C parameters so they can only be changed by altering EMAC parameters - # in the HPS IP GUI - if {([string compare $peripheral "I2C2" ] == 0 || [string compare $peripheral "I2C3" ] == 0) - && [string match "*EMAC*" $selected_mode_option]} { - set_parameter_property $pin_muxing_param_name enabled false - set_parameter_property $mode_param_name enabled false - } else { - set_parameter_property $mode_param_name enabled true - } - set_parameter_property $mode_param_name allowed_ranges $mode_options - - # Disabled peripherals that not supported by certain device family - if {[check_device_family_equivalence $device_family ARRIAV]} { - foreach excluded_peripheral [ARRIAV_EXCLUDED_PERIPHRERALS] { - if {[string compare $excluded_peripheral $peripheral] == 0} { - set_parameter_property $pin_muxing_param_name enabled false - set_parameter_property $pin_muxing_param_name visible false - set_parameter_property $mode_param_name enabled false - set_parameter_property $mode_param_name visible false - } - } - } - } - - # Only show I2C's "Used by EMACx" modes when EMAC is using I2C - if {[is_pin_mux_data_available hps_ip_pin_muxing_model]} { - foreach emac {EMAC0 EMAC1} { - set emac_pin_set [get_parameter_value [format [PIN_MUX_PARAM_FORMAT] $emac]] - set emac_mode [get_parameter_value [format [MODE_PARAM_FORMAT] $emac]] - - funset i2c_name - get_linked_peripheral hps_ip_pin_muxing_model $emac $emac_pin_set\ - i2c_name i2c_pin_set i2c_mode - - if {[info exists i2c_name] && ![string match "*${i2c_name}*" $emac_mode]} { - # remove EMAC mode - set i2c_mode_param [format [MODE_PARAM_FORMAT] $i2c_name] - set i2c_valid_modes [get_parameter_property $i2c_mode_param ALLOWED_RANGES] - - set new_i2c_valid_modes [list] - foreach mode $i2c_valid_modes { - if {![string match "*${emac}*" $mode]} { - lappend new_i2c_valid_modes $mode - } - } - set_parameter_property $i2c_mode_param ALLOWED_RANGES $new_i2c_valid_modes - } - } - } -} - -proc validate_interrupt {device_family} { - set interrupt_groups [list_h2f_interrupt_groups] - set excluded "CAN" - foreach interrupt_group $interrupt_groups { - set parameter "S2FINTERRUPT_${interrupt_group}_Enable" - set_parameter_property $parameter enabled true - set_parameter_property $parameter visible true - if {[check_device_family_equivalence $device_family ARRIAV] && [string compare $excluded $interrupt_group] == 0} { - set_parameter_property $parameter enabled false - set_parameter_property $parameter visible false - } - } -} - -proc update_gpio_ui {placement_by_pin_ref} { - upvar 1 $placement_by_pin_ref placement_by_pin - # TODO: caching of what needs to be updated? - set customer_pin_names [list] - set gpio_names [list] - set loanio_names [list] - set conflicts [list] - - set customer_pin_names [hps_ip_pin_muxing_model::get_customer_pin_names] - - foreach_gpio_entry hps_ip_pin_muxing_model\ - entry gpio_index gpio_name pin gplin_used gplin_select\ - { - lappend gpio_names $gpio_name - - set conflict "" - if {[info exists placement_by_pin($pin)]} { - set conflict [join $placement_by_pin($pin) ", "] - } - lappend conflicts $conflict - } - foreach_loan_io_entry hps_ip_pin_muxing_model\ - entry loanio_index loanio_name pin gplin_used gplin_select\ - { - lappend loanio_names $loanio_name - } - set_parameter_value Customer_Pin_Name_DERIVED $customer_pin_names - set_parameter_value GPIO_Name_DERIVED $gpio_names - set_parameter_value LOANIO_Name_DERIVED $loanio_names - set_parameter_value GPIO_Conflict_DERIVED $conflicts -} - -proc peripheral_to_wys_atom_name {device_family peripheral} { - set generic_atom_name [hps_io_peripheral_to_generic_atom_name $peripheral] - set wys_atom_name [generic_atom_to_wys_atom $device_family $generic_atom_name] - return $wys_atom_name -} - -# TODO: deal with going out of bounds (gpio_index > 70) -proc gpio_index_to_gpio_port_index {gpio_index} { - set group [expr {$gpio_index / 29}] - set port_index [expr {$gpio_index % 29}] - - set result [list $group $port_index] - return $result -} - - - -proc validate_pin_muxing {device_family placement_by_pin_ref} { - upvar 1 $placement_by_pin_ref placement_by_pin - - # see which pins are being used more than once - # peripherals - funset pin_to_peripheral ;# pin names to peripheral that is occupying - funset conflict_pin_list ; - - foreach peripheral_name [list_peripheral_names] { - set pins_used 0 - set mapping_msg "Peripheral $peripheral_name pin mapping:" - set comma " " - set periph_inst [string tolower "${peripheral_name}_inst"] - foreach_used_peripheral_pin hps_ip_pin_muxing_model $peripheral_name\ - signal_name\ - map\ - pin\ - location\ - mux_select\ - { - # Validate - set entry_exists [info exists pin_to_peripheral($pin)] - if {$entry_exists == 1} { - set conflicting_peripheral $pin_to_peripheral($pin) - # only emit an error once per unique pair of conflicting peripherals - if {[info exists known_conflicts($conflicting_peripheral)] == 0} { - set known_conflicts($conflicting_peripheral) 1 - # TODO: more detailed error message e.g. which pins? explicitly say the bank and modes? - send_message error "Refer to the Peripherals Mux Table for more details. The selected peripherals '$conflicting_peripheral' and '$peripheral_name' are conflicting. " - } - set conflict_pin_list($pin) 1 - } else { - set pin_to_peripheral($pin) $peripheral_name - } - - # Render pins - lassign $map in_port out_port oe_port - set goes_out 0 - set goes_in 0 - - # by default, all signals are assumed to be from the same instance - if {$in_port != ""} { - set in_port "${periph_inst}:${in_port}" - set goes_in 1 - } - if {$out_port != ""} { - set out_port "${periph_inst}:${out_port}" - set goes_out 1 - } - if {$oe_port != ""} { - set oe_port "${periph_inst}:${oe_port}" - set goes_out 1 - } - - if {$goes_in && $goes_out} { - set dir bidir - } elseif {$goes_out} { - set dir output - } else { - set dir input - } - - hps_io::add_pin $periph_inst $signal_name $dir $location $in_port $out_port $oe_port - - if {[info exists placement_by_pin($pin)] == 0} { - set placement_by_pin($pin) [list] - } - lappend placement_by_pin($pin) "${peripheral_name}.${signal_name}" - - set mapping_msg "${mapping_msg}${comma}${signal_name}:${pin}" - set comma ", " - set pins_used 1 - } - if {$pins_used} { - # send_message info $mapping_msg - set wys_atom_name [peripheral_to_wys_atom_name $device_family $peripheral_name] - set location [locations::get_hps_io_peripheral_location $peripheral_name] - hps_io::add_peripheral ${periph_inst} $wys_atom_name $location - } - } - - # HLGPI input only pins - set hlgpi_pins [hps_ip_pin_muxing_model::get_hlgpi_pins] - set hlgpi_count [llength $hlgpi_pins] - set wys_atom_name [peripheral_to_wys_atom_name $device_family "GPIO"] - set periph_inst "gpio_inst" - set gpio_unused 1 - set device [get_device] - - if { [ string range $device 0 3 ] == "5CSE" && [ string range $device 8 9 ] == "19" } { - send_message info "HLGPI is not available for Device $device (484 pins)" - set_parameter_property HLGPI_Enable enabled false - } else { - set_parameter_property HLGPI_Enable enabled true - } - - if { [is_enabled HLGPI_Enable] && [get_parameter_property HLGPI_Enable enabled] } { - for {set hlgpi_pin_index 0} {$hlgpi_pin_index < $hlgpi_count} {incr hlgpi_pin_index} { - # HLGPI connected to gpio[26:13] - set gpio_port_index [ expr {$hlgpi_pin_index + 13} ] - set hlgpi_pin [ lindex $hlgpi_pins $hlgpi_pin_index] - - if {$gpio_unused} { - set atom_location [locations::get_hps_io_peripheral_location "GPIO"] - hps_io::add_peripheral ${periph_inst} $wys_atom_name $atom_location - set gpio_unused 0 - } - - set signal_name "HLGPI${hlgpi_pin_index}" - set pin_location [::pin_mux_db::get_location_of_pin $hlgpi_pin] - set in_port "${periph_inst}:GPIO2_PORTA_I($gpio_port_index:$gpio_port_index)" - set out_port "" - set oe_port "" - - hps_io::add_pin ${periph_inst} $signal_name input $pin_location $in_port $out_port $oe_port - } - } - - # gpio - funset gpio_port_placement_set ;# set of gpio ports that are being used - set enable_list [get_parameter_value GPIO_Enable] - set wys_atom_name [peripheral_to_wys_atom_name $device_family "GPIO"] - set periph_inst "gpio_inst" - - # check and set GPIO_Pin_Used_DERIVED parameter - set_parameter_value GPIO_Pin_Used_DERIVED false - - foreach_gpio_entry hps_ip_pin_muxing_model\ - entry gpio_index gpio_name pin gplin_used gplin_select\ - { - set enabled 0 - set enable_value [lindex $enable_list $entry] - if { [string compare $enable_value "Yes" ] == 0 } { - set enabled 1 - } - if {$enabled} { - set entry_exists [info exists pin_to_peripheral($pin)] - if {$entry_exists} { - set conflicting_peripheral $pin_to_peripheral($pin) - send_message error "Refer to the Peripherals Mux Table for more details. The selected peripheral '$conflicting_peripheral' and '${gpio_name}' are conflicting." - set conflict_pin_list($pin) 1 - } else { - set pin_to_peripheral($pin) $gpio_name - } - - if {[info exists gpio_port_placement_set($gpio_index)]} { - send_message error "Refer to the Peripherals Mux Table for more details. GPIO${gpio_index} cannot be used twice." - set conflict_pin_list($pin) 1 - } else { - set gpio_port_placement_set($gpio_index) 1 - } - - if {$gpio_unused} { - set atom_location [locations::get_hps_io_peripheral_location "GPIO"] - hps_io::add_peripheral ${periph_inst} $wys_atom_name $atom_location - set gpio_unused 0 - } - - lassign [gpio_index_to_gpio_port_index $gpio_index] gpio_group gpio_port_index - set in_port "${periph_inst}:GPIO${gpio_group}_PORTA_I($gpio_port_index:$gpio_port_index)" - set out_port "${periph_inst}:GPIO${gpio_group}_PORTA_O($gpio_port_index:$gpio_port_index)" - set oe_port "${periph_inst}:GPIO${gpio_group}_PORTA_OE($gpio_port_index:$gpio_port_index)" - - set pin_location [::pin_mux_db::get_location_of_pin $pin] - hps_io::add_pin $periph_inst $gpio_name bidir $pin_location $in_port $out_port $oe_port - - # set GPIO_Pin_Used_DERIVED to true if GPIO pins used - set_parameter_value GPIO_Pin_Used_DERIVED true - } - } - - # loan i/o - set enable_list [get_parameter_value LOANIO_Enable] - set loanio_used 0 - set loanio_count 0 - foreach_loan_io_entry hps_ip_pin_muxing_model\ - entry loanio_index loanio_name pin gplin_used gplin_select\ - { - if {$loanio_count < $loanio_index} { - set loanio_count $loanio_index - } - set enabled 0 - set enable_value [lindex $enable_list $entry] - if { [string compare $enable_value "Yes" ] == 0 } { - set enabled 1 - } - - if {$enabled} { - set entry_exists [info exists pin_to_peripheral($pin)] - if {$entry_exists} { - set conflicting_peripheral $pin_to_peripheral($pin) - send_message error "Refer to the Peripherals Mux Table for more details. The selected peripheral for '$conflicting_peripheral' and '${loanio_name}' are conflicting." - set conflict_pin_list($pin) 1 - } else { - set pin_to_peripheral($pin) $loanio_name - } - - if {[info exists gpio_port_placement_set($loanio_index)]} { - send_message error "Refer to the Peripherals Mux Table for more details. GPIO${loanio_index} cannot be used twice." - set conflict_pin_list($pin) 1 - } else { - set gpio_port_placement_set($loanio_index) 1 - } - - set loanio_used 1 - if {$gpio_unused} { - set atom_location [locations::get_hps_io_peripheral_location "GPIO"] - hps_io::add_peripheral ${periph_inst} $wys_atom_name $atom_location - set gpio_unused 0 - } - - lassign [gpio_index_to_gpio_port_index $loanio_index] gpio_group gpio_port_index - set in_port "${periph_inst}:GPIO${gpio_group}_PORTA_I($gpio_port_index:$gpio_port_index)" - set out_port "${periph_inst}:GPIO${gpio_group}_PORTA_O($gpio_port_index:$gpio_port_index)" - set oe_port "${periph_inst}:GPIO${gpio_group}_PORTA_OE($gpio_port_index:$gpio_port_index)" - - set pin_location [::pin_mux_db::get_location_of_pin $pin] - hps_io::add_pin $periph_inst $loanio_name bidir $pin_location $in_port $out_port $oe_port - - } - } - incr loanio_count ;# count is one greater than the highest index - if $loanio_used { - set wys_atom_name [peripheral_to_wys_atom_name $device_family "LOANIO"] - set location {} - set periph_inst "loan_io_inst" - set iface_name "h2f_loan_io" - set z "h2f_loan_" - fpga_interfaces::add_module_instance ${periph_inst} $wys_atom_name $location - fpga_interfaces::add_interface $iface_name conduit Input - set pin_muxing [get_parameter_value pin_muxing] - fpga_interfaces::add_interface_port $iface_name "${z}in" in Output ${loanio_count} $periph_inst loanio_in - fpga_interfaces::add_interface_port $iface_name "${z}out" out Input ${loanio_count} $periph_inst loanio_out - fpga_interfaces::add_interface_port $iface_name "${z}oe" oe Input ${loanio_count} $periph_inst loanio_oe - - # add loanIO to GPIO atom connection - set loanio_periph_inst "loan_io_inst" - set loanio_iface_name "loanio_gpio" - set loanio_z "loanio_gpio_" - set gpio_periph_inst "gpio_inst" - set gpio_iface_name "gpio_loanio" - set gpio_z "gpio_loanio_" - set gpio_port_size 29 - set start_index 0 - - if {$gpio_unused} { - set gpio_wys_atom_name [peripheral_to_wys_atom_name $device_family "GPIO"] - set gpio_atom_location [locations::get_hps_io_peripheral_location "GPIO"] - hps_io::add_peripheral ${gpio_periph_inst} ${gpio_wys_atom_name} ${gpio_atom_location} - set gpio_unused 0 - } - - fpga_interfaces::add_interface $loanio_iface_name conduit Input "NO_EXPORT" - ::hps_io::internal::add_interface $gpio_iface_name conduit Output "NO_EXPORT" - - for {set i 0} {$i <= 2} {incr i} { - if {[expr ($loanio_count - $start_index)] < $gpio_port_size} { - set gpio_port_size [expr ($loanio_count - $start_index)] - } - set end_index [expr ($start_index + $gpio_port_size - 1)] - - fpga_interfaces::add_interface_port $loanio_iface_name "${loanio_z}loanio${i}_i" "loanio${i}_i" Input ${gpio_port_size} - fpga_interfaces::add_interface_port $loanio_iface_name "${loanio_z}loanio${i}_oe" "loanio${i}_oe" Output ${gpio_port_size} - fpga_interfaces::add_interface_port $loanio_iface_name "${loanio_z}loanio${i}_o" "loanio${i}_o" Output ${gpio_port_size} - - fpga_interfaces::set_port_fragments $loanio_iface_name "${loanio_z}loanio${i}_i" "${loanio_periph_inst}:GPIO_IN($end_index:$start_index)" - fpga_interfaces::set_port_fragments $loanio_iface_name "${loanio_z}loanio${i}_oe" "${loanio_periph_inst}:GPIO_OE($end_index:$start_index)" - fpga_interfaces::set_port_fragments $loanio_iface_name "${loanio_z}loanio${i}_o" "${loanio_periph_inst}:GPIO_OUT($end_index:$start_index)" - - ::hps_io::internal::add_interface_port $gpio_iface_name "${gpio_z}loanio${i}_i" "loanio${i}_i" Output ${gpio_port_size} $gpio_periph_inst "LOANIO${i}_I" - ::hps_io::internal::add_interface_port $gpio_iface_name "${gpio_z}loanio${i}_oe" "loanio${i}_oe" Input ${gpio_port_size} $gpio_periph_inst "LOANIO${i}_OE" - ::hps_io::internal::add_interface_port $gpio_iface_name "${gpio_z}loanio${i}_o" "loanio${i}_o" Input ${gpio_port_size} $gpio_periph_inst "LOANIO${i}_O" - - set start_index [expr ($end_index + 1)] - } - } - set conflicts [list] - set pins [list] - foreach_gpio_entry hps_ip_pin_muxing_model\ - entry gpio_index gpio_name pin gplin_used gplin_select\ - { - set entry_exists [info exists conflict_pin_list($pin)] - if {$entry_exists} { - set conflict "Yes" - } else { - set conflict "No" - } - lappend conflicts $conflict - lappend pins $pin - } - set_parameter_value JAVA_CONFLICT_PIN $conflicts - set_parameter_value JAVA_GUI_PIN_LIST $pins -} - -##################################################### -# -# Sets a valid mode for the peripheral when its pin -# muxing option changes. Will try to retain the -# original mode if available. -# -proc on_altered_peripheral_pin_muxing {peripheral_name} { -##################################################### - set mode_param_name "${peripheral_name}_Mode" - set mode_option [get_parameter_value $mode_param_name] - - get_peripheral_parameter_valid_ranges hps_ip_pin_muxing_model $peripheral_name\ - selected_pin_muxing_option pin_muxing_options new_valid_modes - - # filter the label name of the parameter value if exist - if {[lsearch $new_valid_modes $mode_option] == -1} { - regsub ":.*" [lindex $new_valid_modes 0] "" new_mode_option - } else { - set new_mode_option $mode_option - } - set_parameter_value $mode_param_name $new_mode_option - - if {[string match "*EMAC*" $peripheral_name]} { - on_emac_mode_switch_internal $peripheral_name - } -} - -# Adds the pin muxing model argument -proc on_emac_mode_switch_internal {peripheral_name} { - on_emac_mode_switch hps_ip_pin_muxing_model $peripheral_name -} - -proc validate_and_update_ddr {} { - set desired_operational_freq [get_parameter_value DDR_DesiredFreq] - if {$desired_operational_freq < 0.0} { - send_message error "The operational frequency of the DDR Controller cannot be negative." - } else { - send_message warning "The recommended DDR Controller clock frequency and phase shift information is not correct." - - set_parameter_value DDR_PLLC0RecommendedFreq_DERIVED $desired_operational_freq - set_parameter_value DDR_PLLC1RecommendedFreq_DERIVED [expr $desired_operational_freq * 2.0] - set_parameter_value DDR_PLLC2RecommendedFreq_DERIVED $desired_operational_freq - set_parameter_value DDR_PLLC3RecommendedFreq_DERIVED $desired_operational_freq - - set_parameter_value DDR_PLLC0RecommendedPhase_DERIVED 0.0 - set_parameter_value DDR_PLLC1RecommendedPhase_DERIVED 1.0 - set_parameter_value DDR_PLLC2RecommendedPhase_DERIVED 2.0 - set_parameter_value DDR_PLLC3RecommendedPhase_DERIVED 3.0 - } - - for {set index 0} {${index} < 4} {incr index} { - set p_name "DDR_PLLC${index}ActualFreq" - set value [get_parameter_value $p_name] - if {$value < 0.0} { - send_message error "DDR PLL Output C${index} cannot have a negative clock frequency." - } - - set p_name "DDR_PLLC${index}ActualPhase" - set value [get_parameter_value $p_name] - if {$value < 0.0} { - send_message error "DDR PLL Output C${index} cannot have a negative clock phase shift." - } - } -} - - -###################### -##### Elaboration ##### -###################### - -proc elab {logical_view} { - # TODO: add RTL information for each - set device_family [get_parameter_value hps_device_family] - - elab_clocks_resets $device_family - - elab_MPU_EVENTS $device_family - elab_DEBUGAPB $device_family - elab_STM $device_family - elab_CTI $device_family - elab_TPIUFPGA $device_family - elab_GP $device_family - elab_BOOTFROMFPGA $device_family - - if {$logical_view == 0} { - elab_F2S $device_family - elab_LWH2F $device_family - elab_S2F $device_family - elab_F2SDRAM $device_family - - } - - elab_DMA $device_family - elab_INTERRUPTS $device_family $logical_view - - elab_emac_ptp $device_family - - elab_TEST $device_family - - # Handle Special Case EMAC signal... ptp_ref_clk - set emac0_pin_mux_param_name [format [PIN_MUX_PARAM_FORMAT] EMAC0] - set emac1_pin_mux_param_name [format [PIN_MUX_PARAM_FORMAT] EMAC1] - set emac0_pin_mux_value [get_parameter_value $emac0_pin_mux_param_name] - set emac1_pin_mux_value [get_parameter_value $emac1_pin_mux_param_name] - set emac0_pin_mux_allowed_ranges [get_parameter_property $emac0_pin_mux_param_name allowed_ranges] - set emac1_pin_mux_allowed_ranges [get_parameter_property $emac1_pin_mux_param_name allowed_ranges] - - set emac0_ptp_enabled [expr {[string compare $emac0_pin_mux_value [FPGA_MUX_VALUE]] == 0 && [lsearch $emac0_pin_mux_allowed_ranges [FPGA_MUX_VALUE]] != -1}] - set emac1_ptp_enabled [expr {[string compare $emac1_pin_mux_value [FPGA_MUX_VALUE]] == 0 && [lsearch $emac1_pin_mux_allowed_ranges [FPGA_MUX_VALUE]] != -1}] - - set emac0_io_enabled [expr {[string compare $emac0_pin_mux_value "HPS I/O Set 0"] == 0 && [lsearch $emac0_pin_mux_allowed_ranges "HPS I/O Set 0"] != -1}] - set emac1_io_enabled [expr {[string compare $emac1_pin_mux_value "HPS I/O Set 0"] == 0 && [lsearch $emac1_pin_mux_allowed_ranges "HPS I/O Set 0"] != -1}] - - set emac0_ptp [get_parameter_value EMAC0_PTP] - set emac1_ptp [get_parameter_value EMAC1_PTP] - - if {$emac0_ptp && $emac0_io_enabled} { - set emac0_ptp_enabled 1 - } - if {$emac1_ptp && $emac1_io_enabled} { - set emac1_ptp_enabled 1 - } - - if {$emac0_ptp_enabled || $emac1_ptp_enabled } { - set instance_name clocks_resets - fpga_interfaces::add_interface emac_ptp_ref_clock clock Input - fpga_interfaces::add_interface_port emac_ptp_ref_clock emac_ptp_ref_clk clk Input 1 $instance_name ptp_ref_clk - } - - # TODO: elab peripherals that mux signals to the fpga - elab_FPGA_Peripheral_Signals $device_family - - set_parameter_value DEVICE_FAMILY [get_parameter_value SYS_INFO_DEVICE_FAMILY] -} - -proc elab_MPU_EVENTS {device_family} { - if [is_enabled MPU_EVENTS_Enable] { - set instance_name mpu_events - set atom_name hps_interface_mpu_event_standby - set location [locations::get_fpga_location $instance_name $atom_name] - - set iface_name "h2f_mpu_events" - set z "h2f_mpu_" - fpga_interfaces::add_interface $iface_name conduit Input - fpga_interfaces::add_interface_port $iface_name ${z}eventi eventi Input 1 $instance_name eventi - fpga_interfaces::add_interface_port $iface_name ${z}evento evento Output 1 $instance_name evento - fpga_interfaces::add_interface_port $iface_name ${z}standbywfe standbywfe Output 2 $instance_name standbywfe - fpga_interfaces::add_interface_port $iface_name ${z}standbywfi standbywfi Output 2 $instance_name standbywfi - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } -} - -proc elab_DEBUGAPB {device_family} { - set instance_name debug_apb - set atom_name hps_interface_dbg_apb - set location [locations::get_fpga_location $instance_name $atom_name] - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - - if [is_enabled DEBUGAPB_Enable] { - set clock_name "h2f_debug_apb_clock" - fpga_interfaces::add_interface $clock_name clock Input - fpga_interfaces::add_interface_port $clock_name "h2f_dbg_apb_clk" clk Input 1 $instance_name P_CLK - - set reset_name "h2f_debug_apb_reset" - fpga_interfaces::add_interface $reset_name reset Output - fpga_interfaces::add_interface_port $reset_name "h2f_dbg_apb_rst_n" reset_n Output 1 $instance_name P_RESET_N - fpga_interfaces::set_interface_property $reset_name associatedClock $clock_name - - set iface_name "h2f_debug_apb" - set z "h2f_dbg_apb_" - fpga_interfaces::add_interface $iface_name apb master - fpga_interfaces::add_interface_port $iface_name "${z}PADDR" paddr Output 18 $instance_name P_ADDR - fpga_interfaces::add_interface_port $iface_name "${z}PADDR31" paddr31 Output 1 $instance_name P_ADDR_31 - fpga_interfaces::add_interface_port $iface_name "${z}PENABLE" penable Output 1 $instance_name P_ENABLE - fpga_interfaces::add_interface_port $iface_name "${z}PRDATA" prdata Input 32 $instance_name P_RDATA - fpga_interfaces::add_interface_port $iface_name "${z}PREADY" pready Input 1 $instance_name P_READY - fpga_interfaces::add_interface_port $iface_name "${z}PSEL" psel Output 1 $instance_name P_SEL - fpga_interfaces::add_interface_port $iface_name "${z}PSLVERR" pslverr Input 1 $instance_name P_SLV_ERR - fpga_interfaces::add_interface_port $iface_name "${z}PWDATA" pwdata Output 32 $instance_name P_WDATA - fpga_interfaces::add_interface_port $iface_name "${z}PWRITE" pwrite Output 1 $instance_name P_WRITE - fpga_interfaces::set_interface_property $iface_name associatedClock $clock_name - fpga_interfaces::set_interface_property $iface_name associatedReset $reset_name - - set iface_name "h2f_debug_apb_sideband" - set z "h2f_dbg_apb_" - fpga_interfaces::add_interface $iface_name conduit Input - fpga_interfaces::add_interface_port $iface_name "${z}PCLKEN" pclken Input 1 $instance_name P_CLK_EN - fpga_interfaces::add_interface_port $iface_name "${z}DBG_APB_DISABLE" dbg_apb_disable Input 1 $instance_name DBG_APB_DISABLE - fpga_interfaces::set_interface_property $iface_name associatedClock $clock_name - fpga_interfaces::set_interface_property $iface_name associatedReset $reset_name - - } else { - # Tie low when FPGA debug apb not being used - fpga_interfaces::set_instance_port_termination ${instance_name} "P_CLK_EN" 1 0 0:0 0 - fpga_interfaces::set_instance_port_termination ${instance_name} "DBG_APB_DISABLE" 1 0 0:0 0 - } -} - -proc elab_STM {device_family} { - if [is_enabled STM_Enable] { - set instance_name stm_event - set atom_name hps_interface_stm_event - set location [locations::get_fpga_location $instance_name $atom_name] - - fpga_interfaces::add_interface f2h_stm_hw_events conduit Input - fpga_interfaces::add_interface_port f2h_stm_hw_events f2h_stm_hwevents stm_hwevents Input 28 $instance_name stm_event - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } -} - -proc elab_CTI {device_family} { - set instance_name cross_trigger_interface - set atom_name hps_interface_cross_trigger - set location [locations::get_fpga_location $instance_name $atom_name] - - if [is_enabled CTI_Enable] { - set iface_name "h2f_cti" - set z "h2f_cti_" - fpga_interfaces::add_interface $iface_name conduit Input - fpga_interfaces::add_interface_port $iface_name ${z}trig_in trig_in Input 8 $instance_name trig_in - fpga_interfaces::add_interface_port $iface_name ${z}trig_in_ack trig_in_ack Output 8 $instance_name trig_inack - fpga_interfaces::add_interface_port $iface_name ${z}trig_out trig_out Output 8 $instance_name trig_out - fpga_interfaces::add_interface_port $iface_name ${z}trig_out_ack trig_out_ack Input 8 $instance_name trig_outack - # case:105603 hide asicctl output signal - # fpga_interfaces::add_interface_port $iface_name ${z}asicctl asicctl Output 8 $instance_name asicctl - fpga_interfaces::add_interface_port $iface_name ${z}fpga_clk_en fpga_clk_en Input 1 $instance_name clk_en - fpga_interfaces::set_interface_property $iface_name associatedClock h2f_cti_clock - fpga_interfaces::set_interface_property $iface_name associatedReset h2f_reset - - fpga_interfaces::add_interface h2f_cti_clock clock Input - fpga_interfaces::add_interface_port h2f_cti_clock h2f_cti_clk clk Input 1 $instance_name clk - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } -} - -proc elab_TPIUFPGA {device_family} { - set instance_name tpiu - set atom_name hps_interface_tpiu_trace - set location [locations::get_fpga_location $instance_name $atom_name] - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - - if { [string compare [get_parameter_value TPIUFPGA_Enable] "true" ] == 0 } { - set_parameter_property TPIUFPGA_alt enabled true - set iface_name "h2f_tpiu" - set z "h2f_tpiu_" - fpga_interfaces::add_interface $iface_name conduit input - fpga_interfaces::add_interface_port $iface_name ${z}clk_ctl clk_ctl Input 1 $instance_name traceclk_ctl - fpga_interfaces::add_interface_port $iface_name ${z}data data Output 32 $instance_name trace_data - - # case 245159 - if {[string compare [get_parameter_value TPIUFPGA_alt] "true" ] == 0} { - fpga_interfaces::add_interface_port $iface_name ${z}clkin clkin Input 1 $instance_name traceclkin - } else { - set iface_name "h2f_tpiu_clock_in" - fpga_interfaces::add_interface $iface_name clock input - fpga_interfaces::add_interface_port $iface_name ${z}clk_in clk Input 1 $instance_name traceclkin - } - - set clock_in_rate [get_parameter_value H2F_TPIU_CLOCK_IN_FREQ] - set clock_rate [expr {$clock_in_rate / 2}] - set iface_name "h2f_tpiu_clock" - fpga_interfaces::add_interface $iface_name clock output - fpga_interfaces::add_interface_port $iface_name ${z}clk clk Output 1 $instance_name traceclk - fpga_interfaces::set_interface_property $iface_name clockRateKnown true - fpga_interfaces::set_interface_property $iface_name clockRate $clock_rate - - add_clock_constraint_if_valid $clock_rate "*|fpga_interfaces|${instance_name}|traceclk" - - } else { - set_parameter_property TPIUFPGA_alt enabled false - fpga_interfaces::set_instance_port_termination ${instance_name} "traceclk_ctl" 1 1 0:0 1 - } -} - -proc elab_GP {device_family} { - if [is_enabled GP_Enable] { - set instance_name h2f_gp - set atom_name hps_interface_mpu_general_purpose - set location [locations::get_fpga_location $instance_name $atom_name] - - set iface_name "h2f_gp" - set z "h2f_gp_" - fpga_interfaces::add_interface $iface_name conduit Input - fpga_interfaces::add_interface_port $iface_name ${z}in gp_in Input 32 $instance_name gp_in - fpga_interfaces::add_interface_port $iface_name ${z}out gp_out Output 32 $instance_name gp_out - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } -} - -proc elab_BOOTFROMFPGA {device_family} { - set instance_name boot_from_fpga - set atom_name hps_interface_boot_from_fpga - set location [locations::get_fpga_location $instance_name $atom_name] - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - - set bsel_en [expr { [string compare [get_parameter_value BSEL_EN] "true" ] == 0 } ] - set bsel [get_parameter_value BSEL] - set csel_en [expr { [string compare [get_parameter_value CSEL_EN] "true" ] == 0 } ] - set csel [get_parameter_value CSEL] - set boot_from_fpga_enable [expr { [string compare [get_parameter_value BOOTFROMFPGA_Enable] "true" ] == 0 } ] - set ini_string [get_parameter_value quartus_ini_hps_ip_enable_bsel_csel] - set ini_enabled [expr { [string compare $ini_string "true" ] == 0 } ] - - # force disable bsel/csel by default - if {!$ini_enabled} { - set bsel_en 0 - set bsel 1 - set csel_en 0 - set csel 1 - } - - # when INI enabled, the controls should appear in the GUI - foreach parameter {BSEL BSEL_EN CSEL CSEL_EN} { - set_parameter_property $parameter visible $ini_string - set_parameter_property $parameter enabled $ini_string - } - - fpga_interfaces::set_instance_port_termination ${instance_name} "bsel" 3 0 2:0 $bsel - fpga_interfaces::set_instance_port_termination ${instance_name} "csel" 2 0 1:0 $csel - - if {$bsel_en} { - fpga_interfaces::set_instance_port_termination ${instance_name} "bsel_en" 1 0 0:0 1 - } else { - fpga_interfaces::set_instance_port_termination ${instance_name} "bsel_en" 1 0 0:0 0 - } - - if {$csel_en} { - fpga_interfaces::set_instance_port_termination ${instance_name} "csel_en" 1 0 0:0 1 - } else { - fpga_interfaces::set_instance_port_termination ${instance_name} "csel_en" 1 0 0:0 0 - } - - if {$boot_from_fpga_enable} { - set iface_name "f2h_boot_from_fpga" - set z "f2h_boot_from_fpga_" - fpga_interfaces::add_interface $iface_name conduit Input - fpga_interfaces::add_interface_port $iface_name "${z}ready" boot_from_fpga_ready Input 1 $instance_name boot_from_fpga_ready - fpga_interfaces::add_interface_port $iface_name "${z}on_failure" boot_from_fpga_on_failure Input 1 $instance_name boot_from_fpga_on_failure - } else { - fpga_interfaces::set_instance_port_termination ${instance_name} "boot_from_fpga_ready" 1 0 0:0 0 - fpga_interfaces::set_instance_port_termination ${instance_name} "boot_from_fpga_on_failure" 1 0 0:0 0 - } - - if {$boot_from_fpga_enable} { - send_message info "Ensure that valid Cortex A9 boot code is available to the HPS system when enabling boot from FPGA and h2f_axi_master interface is connecting to slave component start at address 0x0." - } - - if {$bsel_en && $bsel == 1 && !$boot_from_fpga_enable} { - send_message warning "Boot from FPGA ready must be enabled to correctly boot from the FPGA." - } -} - - -proc elab_F2S {device_family} { - set instance_name fpga2hps - set atom_name hps_interface_fpga2hps - set location [locations::get_fpga_location $instance_name $atom_name] - set termination_value 3 - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - - set addr_width 32 - set width [get_parameter_value F2S_Width] - if {$width > 0} { - set data_width 32 - set strb_width 4 - set termination_value 0 - if {$width == 2} { - set data_width 64 - set strb_width 8 - set termination_value 1 - } elseif {$width == 3} { - set data_width 128 - set strb_width 16 - set termination_value 2 - } - - set clock_name "f2h_axi_clock" - fpga_interfaces::add_interface $clock_name clock Input - fpga_interfaces::add_interface_port $clock_name f2h_axi_clk clk Input 1 $instance_name clk - - set iface_name "f2h_axi_slave" - set z "f2h_" - - fpga_interfaces::add_interface $iface_name axi slave - fpga_interfaces::set_interface_property $iface_name associatedClock $clock_name - fpga_interfaces::set_interface_property $iface_name associatedReset h2f_reset - fpga_interfaces::set_interface_property $iface_name readAcceptanceCapability 8 - fpga_interfaces::set_interface_property $iface_name writeAcceptanceCapability 8 - fpga_interfaces::set_interface_property $iface_name combinedAcceptanceCapability 16 - fpga_interfaces::set_interface_property $iface_name readDataReorderingDepth 16 - fpga_interfaces::set_interface_meta_property $iface_name data_width $data_width - fpga_interfaces::set_interface_meta_property $iface_name address_width $addr_width - - fpga_interfaces::add_interface_port $iface_name ${z}AWID awid Input 8 $instance_name awid - fpga_interfaces::add_interface_port $iface_name ${z}AWADDR awaddr Input $addr_width $instance_name awaddr - fpga_interfaces::add_interface_port $iface_name ${z}AWLEN awlen Input 4 $instance_name awlen - fpga_interfaces::add_interface_port $iface_name ${z}AWSIZE awsize Input 3 $instance_name awsize - fpga_interfaces::add_interface_port $iface_name ${z}AWBURST awburst Input 2 $instance_name awburst - fpga_interfaces::add_interface_port $iface_name ${z}AWLOCK awlock Input 2 $instance_name awlock - fpga_interfaces::add_interface_port $iface_name ${z}AWCACHE awcache Input 4 $instance_name awcache - fpga_interfaces::add_interface_port $iface_name ${z}AWPROT awprot Input 3 $instance_name awprot - fpga_interfaces::add_interface_port $iface_name ${z}AWVALID awvalid Input 1 $instance_name awvalid - fpga_interfaces::add_interface_port $iface_name ${z}AWREADY awready Output 1 $instance_name awready - fpga_interfaces::add_interface_port $iface_name ${z}AWUSER awuser Input 5 $instance_name awuser - - fpga_interfaces::add_interface_port $iface_name ${z}WID wid Input 8 $instance_name wid - fpga_interfaces::add_interface_port $iface_name ${z}WDATA wdata Input $data_width $instance_name wdata - fpga_interfaces::add_interface_port $iface_name ${z}WSTRB wstrb Input $strb_width $instance_name wstrb - fpga_interfaces::add_interface_port $iface_name ${z}WLAST wlast Input 1 $instance_name wlast - fpga_interfaces::add_interface_port $iface_name ${z}WVALID wvalid Input 1 $instance_name wvalid - fpga_interfaces::add_interface_port $iface_name ${z}WREADY wready Output 1 $instance_name wready - - fpga_interfaces::add_interface_port $iface_name ${z}BID bid Output 8 $instance_name bid - fpga_interfaces::add_interface_port $iface_name ${z}BRESP bresp Output 2 $instance_name bresp - fpga_interfaces::add_interface_port $iface_name ${z}BVALID bvalid Output 1 $instance_name bvalid - fpga_interfaces::add_interface_port $iface_name ${z}BREADY bready Input 1 $instance_name bready - - - fpga_interfaces::add_interface_port $iface_name ${z}ARID arid Input 8 $instance_name arid - fpga_interfaces::add_interface_port $iface_name ${z}ARADDR araddr Input $addr_width $instance_name araddr - fpga_interfaces::add_interface_port $iface_name ${z}ARLEN arlen Input 4 $instance_name arlen - fpga_interfaces::add_interface_port $iface_name ${z}ARSIZE arsize Input 3 $instance_name arsize - fpga_interfaces::add_interface_port $iface_name ${z}ARBURST arburst Input 2 $instance_name arburst - fpga_interfaces::add_interface_port $iface_name ${z}ARLOCK arlock Input 2 $instance_name arlock - fpga_interfaces::add_interface_port $iface_name ${z}ARCACHE arcache Input 4 $instance_name arcache - fpga_interfaces::add_interface_port $iface_name ${z}ARPROT arprot Input 3 $instance_name arprot - fpga_interfaces::add_interface_port $iface_name ${z}ARVALID arvalid Input 1 $instance_name arvalid - fpga_interfaces::add_interface_port $iface_name ${z}ARREADY arready Output 1 $instance_name arready - fpga_interfaces::add_interface_port $iface_name ${z}ARUSER aruser Input 5 $instance_name aruser - - fpga_interfaces::add_interface_port $iface_name ${z}RID rid Output 8 $instance_name rid - fpga_interfaces::add_interface_port $iface_name ${z}RDATA rdata Output $data_width $instance_name rdata - fpga_interfaces::add_interface_port $iface_name ${z}RRESP rresp Output 2 $instance_name rresp - fpga_interfaces::add_interface_port $iface_name ${z}RLAST rlast Output 1 $instance_name rlast - fpga_interfaces::add_interface_port $iface_name ${z}RVALID rvalid Output 1 $instance_name rvalid - fpga_interfaces::add_interface_port $iface_name ${z}RREADY rready Input 1 $instance_name rready - } - fpga_interfaces::set_instance_port_termination ${instance_name} "port_size_config" 2 0 1:0 $termination_value -} - -proc elab_S2F {device_family} { - set instance_name hps2fpga - set atom_name hps_interface_hps2fpga - set location [locations::get_fpga_location $instance_name $atom_name] - set termination_value 3 - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - - set addr_width 30 - set id_width 12 - set width [get_parameter_value S2F_Width] - if {$width > 0} { - set data_width 32 - set strb_width 4 - set termination_value 0 - - if {$width == 2} { - set data_width 64 - set strb_width 8 - set termination_value 1 - - } elseif {$width == 3} { - set data_width 128 - set strb_width 16 - set termination_value 2 - } - - set clock_name "h2f_axi_clock" - fpga_interfaces::add_interface $clock_name clock Input - fpga_interfaces::add_interface_port $clock_name h2f_axi_clk clk Input 1 $instance_name clk - - set iface_name "h2f_axi_master" - set z "h2f_" - - fpga_interfaces::add_interface $iface_name axi master - fpga_interfaces::set_interface_property $iface_name associatedClock $clock_name - fpga_interfaces::set_interface_property $iface_name associatedReset h2f_reset - fpga_interfaces::set_interface_property $iface_name readIssuingCapability 8 - fpga_interfaces::set_interface_property $iface_name writeIssuingCapability 8 - fpga_interfaces::set_interface_property $iface_name combinedIssuingCapability 16 - -# set svd_path [file join $::env(QUARTUS_ROOTDIR) .. ip altera hps altera_hps golden_ref_design_CMSIS_1_1_to_arm_v2.svd] -# send_message info "REMOVE! SVD_PATH = $svd_path" -# fpga_interfaces::set_interface_property $iface_name CMSIS_SVD_FILE $svd_path -# fpga_interfaces::set_interface_property $iface_name SVD_ADDRESS_GROUP hps -# fpga_interfaces::set_interface_property $iface_name SVD_ADDRESS_OFFSET [expr {0xC0000000}] - fpga_interfaces::set_interface_meta_property $iface_name data_width $data_width - fpga_interfaces::set_interface_meta_property $iface_name address_width $addr_width - fpga_interfaces::set_interface_meta_property $iface_name id_width $id_width - - fpga_interfaces::add_interface_port $iface_name ${z}AWID awid Output $id_width $instance_name awid - fpga_interfaces::add_interface_port $iface_name ${z}AWADDR awaddr Output $addr_width $instance_name awaddr - fpga_interfaces::add_interface_port $iface_name ${z}AWLEN awlen Output 4 $instance_name awlen - fpga_interfaces::add_interface_port $iface_name ${z}AWSIZE awsize Output 3 $instance_name awsize - fpga_interfaces::add_interface_port $iface_name ${z}AWBURST awburst Output 2 $instance_name awburst - fpga_interfaces::add_interface_port $iface_name ${z}AWLOCK awlock Output 2 $instance_name awlock - fpga_interfaces::add_interface_port $iface_name ${z}AWCACHE awcache Output 4 $instance_name awcache - fpga_interfaces::add_interface_port $iface_name ${z}AWPROT awprot Output 3 $instance_name awprot - fpga_interfaces::add_interface_port $iface_name ${z}AWVALID awvalid Output 1 $instance_name awvalid - fpga_interfaces::add_interface_port $iface_name ${z}AWREADY awready Input 1 $instance_name awready - - fpga_interfaces::add_interface_port $iface_name ${z}WID wid Output $id_width $instance_name wid - fpga_interfaces::add_interface_port $iface_name ${z}WDATA wdata Output $data_width $instance_name wdata - fpga_interfaces::add_interface_port $iface_name ${z}WSTRB wstrb Output $strb_width $instance_name wstrb - fpga_interfaces::add_interface_port $iface_name ${z}WLAST wlast Output 1 $instance_name wlast - fpga_interfaces::add_interface_port $iface_name ${z}WVALID wvalid Output 1 $instance_name wvalid - fpga_interfaces::add_interface_port $iface_name ${z}WREADY wready Input 1 $instance_name wready - - fpga_interfaces::add_interface_port $iface_name ${z}BID bid Input $id_width $instance_name bid - fpga_interfaces::add_interface_port $iface_name ${z}BRESP bresp Input 2 $instance_name bresp - fpga_interfaces::add_interface_port $iface_name ${z}BVALID bvalid Input 1 $instance_name bvalid - fpga_interfaces::add_interface_port $iface_name ${z}BREADY bready Output 1 $instance_name bready - - fpga_interfaces::add_interface_port $iface_name ${z}ARID arid Output $id_width $instance_name arid - fpga_interfaces::add_interface_port $iface_name ${z}ARADDR araddr Output $addr_width $instance_name araddr - fpga_interfaces::add_interface_port $iface_name ${z}ARLEN arlen Output 4 $instance_name arlen - fpga_interfaces::add_interface_port $iface_name ${z}ARSIZE arsize Output 3 $instance_name arsize - fpga_interfaces::add_interface_port $iface_name ${z}ARBURST arburst Output 2 $instance_name arburst - fpga_interfaces::add_interface_port $iface_name ${z}ARLOCK arlock Output 2 $instance_name arlock - fpga_interfaces::add_interface_port $iface_name ${z}ARCACHE arcache Output 4 $instance_name arcache - fpga_interfaces::add_interface_port $iface_name ${z}ARPROT arprot Output 3 $instance_name arprot - fpga_interfaces::add_interface_port $iface_name ${z}ARVALID arvalid Output 1 $instance_name arvalid - fpga_interfaces::add_interface_port $iface_name ${z}ARREADY arready Input 1 $instance_name arready - - fpga_interfaces::add_interface_port $iface_name ${z}RID rid Input $id_width $instance_name rid - fpga_interfaces::add_interface_port $iface_name ${z}RDATA rdata Input $data_width $instance_name rdata - fpga_interfaces::add_interface_port $iface_name ${z}RRESP rresp Input 2 $instance_name rresp - fpga_interfaces::add_interface_port $iface_name ${z}RLAST rlast Input 1 $instance_name rlast - fpga_interfaces::add_interface_port $iface_name ${z}RVALID rvalid Input 1 $instance_name rvalid - fpga_interfaces::add_interface_port $iface_name ${z}RREADY rready Output 1 $instance_name rready - - } - fpga_interfaces::set_instance_port_termination ${instance_name} "port_size_config" 2 0 1:0 $termination_value -} - -proc elab_LWH2F {device_family} { - set instance_name hps2fpga_light_weight - set atom_name hps_interface_hps2fpga_light_weight - set location [locations::get_fpga_location $instance_name $atom_name] - - if [is_enabled LWH2F_Enable] { - set addr_width 21 - set data_width 32 - set strb_width 4 - set id_width 12 - set clock_name "h2f_lw_axi_clock" - fpga_interfaces::add_interface $clock_name clock Input - fpga_interfaces::add_interface_port $clock_name h2f_lw_axi_clk clk Input 1 $instance_name clk - - set iface_name "h2f_lw_axi_master" - set z "h2f_lw_" - fpga_interfaces::add_interface $iface_name axi master -# fpga_interfaces::set_interface_property $iface_name SVD_ADDRESS_GROUP hps -# fpga_interfaces::set_interface_property $iface_name SVD_ADDRESS_OFFSET [expr {0xFC000000}] - fpga_interfaces::set_interface_property $iface_name associatedClock $clock_name - fpga_interfaces::set_interface_property $iface_name associatedReset h2f_reset - fpga_interfaces::set_interface_property $iface_name readIssuingCapability 8 - fpga_interfaces::set_interface_property $iface_name writeIssuingCapability 8 - fpga_interfaces::set_interface_property $iface_name combinedIssuingCapability 16 - fpga_interfaces::set_interface_meta_property $iface_name data_width $data_width - fpga_interfaces::set_interface_meta_property $iface_name address_width $addr_width - fpga_interfaces::set_interface_meta_property $iface_name id_width $id_width - - fpga_interfaces::add_interface_port $iface_name ${z}AWID awid Output $id_width $instance_name awid - fpga_interfaces::add_interface_port $iface_name ${z}AWADDR awaddr Output $addr_width $instance_name awaddr - fpga_interfaces::add_interface_port $iface_name ${z}AWLEN awlen Output 4 $instance_name awlen - fpga_interfaces::add_interface_port $iface_name ${z}AWSIZE awsize Output 3 $instance_name awsize - fpga_interfaces::add_interface_port $iface_name ${z}AWBURST awburst Output 2 $instance_name awburst - fpga_interfaces::add_interface_port $iface_name ${z}AWLOCK awlock Output 2 $instance_name awlock - fpga_interfaces::add_interface_port $iface_name ${z}AWCACHE awcache Output 4 $instance_name awcache - fpga_interfaces::add_interface_port $iface_name ${z}AWPROT awprot Output 3 $instance_name awprot - fpga_interfaces::add_interface_port $iface_name ${z}AWVALID awvalid Output 1 $instance_name awvalid - fpga_interfaces::add_interface_port $iface_name ${z}AWREADY awready Input 1 $instance_name awready - - fpga_interfaces::add_interface_port $iface_name ${z}WID wid Output $id_width $instance_name wid - fpga_interfaces::add_interface_port $iface_name ${z}WDATA wdata Output $data_width $instance_name wdata - fpga_interfaces::add_interface_port $iface_name ${z}WSTRB wstrb Output $strb_width $instance_name wstrb - fpga_interfaces::add_interface_port $iface_name ${z}WLAST wlast Output 1 $instance_name wlast - fpga_interfaces::add_interface_port $iface_name ${z}WVALID wvalid Output 1 $instance_name wvalid - fpga_interfaces::add_interface_port $iface_name ${z}WREADY wready Input 1 $instance_name wready - - fpga_interfaces::add_interface_port $iface_name ${z}BID bid Input $id_width $instance_name bid - fpga_interfaces::add_interface_port $iface_name ${z}BRESP bresp Input 2 $instance_name bresp - fpga_interfaces::add_interface_port $iface_name ${z}BVALID bvalid Input 1 $instance_name bvalid - fpga_interfaces::add_interface_port $iface_name ${z}BREADY bready Output 1 $instance_name bready - - fpga_interfaces::add_interface_port $iface_name ${z}ARID arid Output $id_width $instance_name arid - fpga_interfaces::add_interface_port $iface_name ${z}ARADDR araddr Output $addr_width $instance_name araddr - fpga_interfaces::add_interface_port $iface_name ${z}ARLEN arlen Output 4 $instance_name arlen - fpga_interfaces::add_interface_port $iface_name ${z}ARSIZE arsize Output 3 $instance_name arsize - fpga_interfaces::add_interface_port $iface_name ${z}ARBURST arburst Output 2 $instance_name arburst - fpga_interfaces::add_interface_port $iface_name ${z}ARLOCK arlock Output 2 $instance_name arlock - fpga_interfaces::add_interface_port $iface_name ${z}ARCACHE arcache Output 4 $instance_name arcache - fpga_interfaces::add_interface_port $iface_name ${z}ARPROT arprot Output 3 $instance_name arprot - fpga_interfaces::add_interface_port $iface_name ${z}ARVALID arvalid Output 1 $instance_name arvalid - fpga_interfaces::add_interface_port $iface_name ${z}ARREADY arready Input 1 $instance_name arready - - fpga_interfaces::add_interface_port $iface_name ${z}RID rid Input $id_width $instance_name rid - fpga_interfaces::add_interface_port $iface_name ${z}RDATA rdata Input $data_width $instance_name rdata - fpga_interfaces::add_interface_port $iface_name ${z}RRESP rresp Input 2 $instance_name rresp - fpga_interfaces::add_interface_port $iface_name ${z}RLAST rlast Input 1 $instance_name rlast - fpga_interfaces::add_interface_port $iface_name ${z}RVALID rvalid Input 1 $instance_name rvalid - fpga_interfaces::add_interface_port $iface_name ${z}RREADY rready Output 1 $instance_name rready - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } -} - -proc elab_F2SDRAM {device_family} { - f2sdram::init_registers - - set instance_name f2sdram - set atom_name hps_interface_fpga2sdram - set location [locations::get_fpga_location $instance_name $atom_name] - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - - set use_fast_sim_model [expr { [string compare [get_parameter_value quartus_ini_hps_ip_fast_f2sdram_sim_model] "true" ] == 0 }] - set bonding_out_signal [expr { [string compare [get_parameter_value BONDING_OUT_ENABLED] "true"] == 0} && {[string compare [get_parameter_value quartus_ini_hps_ip_f2sdram_bonding_out] "true"] == 0}] - #newly added - set width_list [get_parameter_value F2SDRAM_Width] - set rows [llength $width_list] - if {$rows > 0} { - # TODO: move outside of 'if' once registers are rendered - - - set type_list [get_parameter_value F2SDRAM_Type] - for {set i 0} {${i} < $rows} {incr i} { - set width [lindex $width_list $i] - set type_choice [lindex $type_list $i] - - set type "axi" - set type_id 0 - if { [string compare $type_choice [F2HSDRAM_AVM]] == 0 } { - set type "avalon" - set type_id 1 - } elseif { [string compare $type_choice [F2HSDRAM_AVM_WRITEONLY]] == 0 } { - set type "avalon" - set type_id 2 - } elseif { [string compare $type_choice [F2HSDRAM_AVM_READONLY]] == 0 } { - set type "avalon" - set type_id 3 - } - - set sim_is_synth [expr !$use_fast_sim_model] - - # To make sure bonding_out_signal only being added once even thought there are more than one f2sdram - if {$i == 0 } { - set bonding_out_signal [expr { [string compare [get_parameter_value BONDING_OUT_ENABLED] "true"] == 0} && {[string compare [get_parameter_value quartus_ini_hps_ip_f2sdram_bonding_out] "true"] == 0}] - } else { - set bonding_out_signal 0 - } - - f2sdram::add_port registers $i $type_id $width $instance_name $sim_is_synth $bonding_out_signal - } - f2sdram::add_sdc $use_fast_sim_model - fpga_interfaces::set_property IMPLEMENT_F2SDRAM_MEMORY_BACKED_SIM $use_fast_sim_model - - } - # write the registers out - f2sdram::render_registers registers $instance_name -} - -proc elab_clocks_resets {device_family} { - set instance_name clocks_resets - set atom_name hps_interface_clocks_resets - set location [locations::get_fpga_location $instance_name $atom_name] - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - - fpga_interfaces::add_interface h2f_reset reset Output - fpga_interfaces::add_interface_port h2f_reset h2f_rst_n reset_n Output 1 $instance_name - fpga_interfaces::set_interface_property h2f_reset synchronousEdges none - fpga_interfaces::set_interface_property h2f_reset associatedResetSinks none - - if [is_enabled S2FCLK_COLDRST_Enable] { - fpga_interfaces::add_interface h2f_cold_reset reset Output - fpga_interfaces::add_interface_port h2f_cold_reset h2f_cold_rst_n reset_n Output 1 $instance_name - fpga_interfaces::set_interface_property h2f_cold_reset synchronousEdges none - fpga_interfaces::set_interface_property h2f_cold_reset associatedResetSinks none - } - - if [is_enabled F2SCLK_COLDRST_Enable] { - fpga_interfaces::add_interface f2h_cold_reset_req reset Input - fpga_interfaces::add_interface_port f2h_cold_reset_req f2h_cold_rst_req_n reset_n Input 1 $instance_name - fpga_interfaces::set_interface_property f2h_cold_reset_req synchronousEdges none - fpga_interfaces::set_interface_property h2f_reset associatedResetSinks f2h_cold_reset_req - if [is_enabled S2FCLK_COLDRST_Enable] { - fpga_interfaces::set_interface_property h2f_cold_reset associatedResetSinks f2h_cold_reset_req - } - } else { - fpga_interfaces::set_instance_port_termination ${instance_name} "f2h_cold_rst_req_n" 1 1 0:0 1 - } - - if [is_enabled S2FCLK_PENDINGRST_Enable] { - fpga_interfaces::add_interface h2f_warm_reset_handshake conduit Output - fpga_interfaces::add_interface_port h2f_warm_reset_handshake h2f_pending_rst_req_n h2f_pending_rst_req_n Output 1 $instance_name - fpga_interfaces::add_interface_port h2f_warm_reset_handshake f2h_pending_rst_ack_n f2h_pending_rst_ack_n Input 1 $instance_name f2h_pending_rst_ack - } else { - fpga_interfaces::set_instance_port_termination ${instance_name} "f2h_pending_rst_ack" 1 1 0:0 1 - } - - if [is_enabled F2SCLK_DBGRST_Enable] { - fpga_interfaces::add_interface f2h_debug_reset_req reset Input - fpga_interfaces::add_interface_port f2h_debug_reset_req f2h_dbg_rst_req_n reset_n Input 1 $instance_name - fpga_interfaces::set_interface_property f2h_debug_reset_req synchronousEdges none - } else { - fpga_interfaces::set_instance_port_termination ${instance_name} "f2h_dbg_rst_req_n" 1 1 0:0 1 - } - - if [is_enabled F2SCLK_WARMRST_Enable] { - fpga_interfaces::add_interface f2h_warm_reset_req reset Input - fpga_interfaces::add_interface_port f2h_warm_reset_req f2h_warm_rst_req_n reset_n Input 1 $instance_name - fpga_interfaces::set_interface_property f2h_warm_reset_req synchronousEdges none - - if [is_enabled F2SCLK_COLDRST_Enable] { - fpga_interfaces::set_interface_property h2f_reset associatedResetSinks {f2h_warm_reset_req f2h_cold_reset_req} - } else { - fpga_interfaces::set_interface_property h2f_reset associatedResetSinks {f2h_warm_reset_req} - } - } else { - fpga_interfaces::set_instance_port_termination ${instance_name} "f2h_warm_rst_req_n" 1 1 0:0 1 - } - - if [is_enabled S2FCLK_USER0CLK_Enable] { - fpga_interfaces::add_interface h2f_user0_clock clock Output - fpga_interfaces::add_interface_port h2f_user0_clock h2f_user0_clk clk Output 1 $instance_name - set frequency [get_parameter_value S2FCLK_USER0CLK_FREQ] - set frequency [expr {$frequency * [MHZ_TO_HZ]}] - fpga_interfaces::set_interface_property h2f_user0_clock clockRateKnown true - fpga_interfaces::set_interface_property h2f_user0_clock clockRate $frequency - add_clock_constraint_if_valid $frequency "*|fpga_interfaces|${instance_name}|h2f_user0_clk" - } - - if [is_enabled S2FCLK_USER1CLK_Enable] { - fpga_interfaces::add_interface h2f_user1_clock clock Output - fpga_interfaces::add_interface_port h2f_user1_clock h2f_user1_clk clk Output 1 $instance_name - set frequency [get_parameter_value S2FCLK_USER1CLK_FREQ] - set frequency [expr {$frequency * [MHZ_TO_HZ]}] - fpga_interfaces::set_interface_property h2f_user1_clock clockRateKnown true - fpga_interfaces::set_interface_property h2f_user1_clock clockRate $frequency - add_clock_constraint_if_valid $frequency "*|fpga_interfaces|${instance_name}|h2f_user1_clk" - } - - set_parameter_property S2FCLK_USER2CLK enabled false - - if [is_enabled F2SCLK_PERIPHCLK_Enable] { - fpga_interfaces::add_interface f2h_periph_ref_clock clock Input - fpga_interfaces::add_interface_port f2h_periph_ref_clock f2h_periph_ref_clk clk Input 1 $instance_name - } else { - fpga_interfaces::set_instance_port_termination ${instance_name} "f2h_periph_ref_clk" 1 0 - } - - - if [is_enabled F2SCLK_SDRAMCLK_Enable] { - fpga_interfaces::add_interface f2h_sdram_ref_clock clock Input - fpga_interfaces::add_interface_port f2h_sdram_ref_clock f2h_sdram_ref_clk clk Input 1 $instance_name - } else { - fpga_interfaces::set_instance_port_termination ${instance_name} "f2h_sdram_ref_clk" 1 0 - } -} - -# Elaborate peripheral request interfaces for the fpga and -# the clk/reset per pair -# TODO: Make sure the DMA RTL contains the wrapper -proc elab_DMA {device_family} { - set instance_name dma - set atom_name hps_interface_dma - set location [locations::get_fpga_location $instance_name $atom_name] - - set can_message 0 - set available_list [get_parameter_value DMA_Enable] - if {[llength $available_list] > 0} { - set dma_used 0 - set periph_id 0 - foreach entry $available_list { - if {[string compare $entry "Yes" ] == 0} { - elab_DMA_entry $periph_id $instance_name - set dma_used 1 - if {$periph_id >= 4} { - set can_message 1 - } - } - incr periph_id - } - if $dma_used { - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } - if $can_message { - send_message info "DMA Peripheral Request Interfaces 4-7 may be consumed by an HPS CAN Controller" - } - } -} - -proc elab_DMA_make_conduit_name {periph_id} { - return "f2h_dma_req${periph_id}" -} - -proc elab_DMA_entry {periph_id instance_name} { - set iname [elab_DMA_make_conduit_name $periph_id] - set atom_signal_prefix "channel${periph_id}" - fpga_interfaces::add_interface $iname conduit Output - fpga_interfaces::add_interface_port $iname "${iname}_req" "dma_req" Input 1 $instance_name ${atom_signal_prefix}_req - fpga_interfaces::add_interface_port $iname "${iname}_single" "dma_single" Input 1 $instance_name ${atom_signal_prefix}_single - fpga_interfaces::add_interface_port $iname "${iname}_ack" "dma_ack" Output 1 $instance_name ${atom_signal_prefix}_xx_ack -} - - -proc elab_emac_ptp {device_family} { - # added for case http://fogbugz.altera.com/default.asp?307450 - for {set i 0} {$i < 2} {incr i} { - set emac_fpga_enabled false - set emac_io_enabled false - - set emac_pin_mux_value [get_parameter_value EMAC${i}_PinMuxing] - set emac_ptp [get_parameter_value EMAC${i}_PTP] - - if {[string compare $emac_pin_mux_value [FPGA_MUX_VALUE]] == 0} { - set emac_fpga_enabled true - } - if {[string compare $emac_pin_mux_value "HPS I/O Set 0"] == 0} { - set emac_io_enabled true - } - - set_parameter_property EMAC${i}_PTP enabled $emac_io_enabled - - if {$emac_io_enabled && $emac_ptp } { - set instance_name peripheral_emac${i} - set atom_name hps_interface_peripheral_emac - set wys_atom_name arriav_hps_interface_peripheral_emac - set location [locations::get_fpga_location $instance_name $atom_name] - - set iface_name "emac${i}" - - fpga_interfaces::add_interface $iface_name conduit input - fpga_interfaces::add_interface_port $iface_name emac${i}_ptp_aux_ts_trig_i ptp_aux_ts_trig_i Input 1 $instance_name ptp_aux_ts_trig_i - fpga_interfaces::add_interface_port $iface_name emac${i}_ptp_pps_o ptp_pps_o Output 1 $instance_name ptp_pps_o - - - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } - - } -} - -proc elab_INTERRUPTS {device_family logical_view} { - set instance_name interrupts - set atom_name hps_interface_interrupts - set location [locations::get_fpga_location $instance_name $atom_name] - set any_interrupt_enabled 0 - - ##### F2H ##### - if [is_enabled F2SINTERRUPT_Enable] { - set any_interrupt_enabled 1 - set iname "f2h_irq" - set pname "f2h_irq" - if { $logical_view == 0 } { - fpga_interfaces::add_interface "${iname}0" interrupt receiver - fpga_interfaces::add_interface_port "${iname}0" "${pname}_p0" irq Input 32 - fpga_interfaces::set_port_fragments "${iname}0" "${pname}_p0" "${instance_name}:irq(31:0)" - - fpga_interfaces::add_interface "${iname}1" interrupt receiver - fpga_interfaces::add_interface_port "${iname}1" "${pname}_p1" irq Input 32 - fpga_interfaces::set_port_fragments "${iname}1" "${pname}_p1" "${instance_name}:irq(63:32)" - } - } - - ##### H2F ##### - load_h2f_interrupt_table\ - functions_by_group width_by_function inverted_by_function - - set interrupt_groups [list_h2f_interrupt_groups] - foreach group $interrupt_groups { - set parameter "S2FINTERRUPT_${group}_Enable" - set enabled [is_enabled $parameter] - - if {!$enabled} { - continue - } - set any_interrupt_enabled 1 - - foreach function $functions_by_group($group) { - set width 1 - if {[info exists width_by_function($function)]} { - set width $width_by_function($function) - } - - set suffix "" - set inverted [info exists inverted_by_function($function)] - if {$inverted} { - set suffix "_n" - } - - #skip fpga_interfaces interrupt declaration for uart - if { ($logical_view == 1) && ( - $function == "uart0" || - $function == "uart1" )} { - continue - } - - set prefix "h2f_${function}_" - set interface "${prefix}interrupt" - set port "${prefix}irq" - - if {$width > 1} { ;# for buses, use index in interface/port names - for {set i 0} {$i < $width} {incr i} { - set indexed_interface "${interface}${i}" - set indexed_port "${port}${i}${suffix}" - fpga_interfaces::add_interface\ - $indexed_interface interrupt sender - fpga_interfaces::add_interface_port\ - $indexed_interface $indexed_port irq Output 1\ - $instance_name $indexed_port - } - } else { - set port "$port${suffix}" - fpga_interfaces::add_interface\ - $interface interrupt sender - fpga_interfaces::add_interface_port\ - $interface $port irq Output 1 $instance_name $port - } - } - } - - if {$any_interrupt_enabled} { - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } -} - -proc elab_TEST {device_family} { - set parameter_enabled [expr {[string compare [get_parameter_value TEST_Enable] "true" ] == 0}] - set ini_enabled [expr {[string compare [get_parameter_value quartus_ini_hps_ip_enable_test_interface] "true" ] == 0}] - - if {$parameter_enabled && $ini_enabled} { - set instance_name test_interface - set atom_name hps_interface_test - set location [locations::get_fpga_location $instance_name $atom_name] - - set iname "test" - set z "test_" - - set data [get_parameter_value test_iface_definition] - - fpga_interfaces::add_interface $iname conduit input - foreach {port width dir} $data { - fpga_interfaces::add_interface_port $iname "${z}${port}" $port $dir $width $instance_name $port - } - - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } -} - -# TODO: Mode usage data -proc elab_FPGA_Peripheral_Signals {device_family} { - # disable and hide all parameters related to fpga outputs - set emac0_fpga [get_parameter_value quartus_ini_hps_ip_enable_emac0_peripheral_fpga_interface] - set lssis_fpga [get_parameter_value quartus_ini_hps_ip_enable_low_speed_serial_fpga_interfaces] - set all_fpga "true" - - set peripherals [list_peripheral_names] - foreach peripheral $peripherals { - if { [string compare $peripheral "SDIO" ] == 0 } { - continue - } - set visible false - if {[string compare $all_fpga "true" ] == 0} { - set visible true - } elseif {[string compare $emac0_fpga "true" ] == 0 && [string compare -nocase $peripheral "emac0"] == 0} { - set visible true - } elseif {[string compare $lssis_fpga "true" ] == 0 && [is_peripheral_low_speed_serial_interface $peripheral_name]} { - set visible true - } - if {[string compare -nocase $peripheral "emac0" ] == 0 || [string compare -nocase $peripheral "emac1" ] == 0} { - set visible true - } - set clocks [get_peripheral_fpga_output_clocks $peripheral] - foreach clock $clocks { - set parameter [form_peripheral_fpga_output_clock_frequency_parameter $clock] - set_parameter_property $parameter enabled false - set_parameter_property $parameter visible $visible - set clock_output_set($clock) 1 - } - - set clocks [get_peripheral_fpga_input_clocks $peripheral] - foreach clock $clocks { - set clock_input_set($clock) 1 - } - } - - array set fpga_ifaces [get_parameter_value DB_periph_ifaces] - array set iface_ports [get_parameter_value DB_iface_ports] - array set port_pins [get_parameter_value DB_port_pins] - foreach peripheral_name $fpga_ifaces([ORDERED_NAMES]) { ;# Peripherals - set pin_mux_param_name [format [PIN_MUX_PARAM_FORMAT] $peripheral_name] - set pin_mux_value [get_parameter_value $pin_mux_param_name] - set allowed_ranges [get_parameter_property $pin_mux_param_name allowed_ranges] - - if {[string compare $pin_mux_value [FPGA_MUX_VALUE]] == 0 && [lsearch $allowed_ranges [FPGA_MUX_VALUE]] != -1} { - funset peripheral - array set peripheral $fpga_ifaces($peripheral_name) - funset interfaces - array set interfaces $peripheral(interfaces) - - set instance_name [invent_peripheral_instance_name $peripheral_name] - - foreach interface_name $interfaces([ORDERED_NAMES]) { ;# Interfaces - funset interface - array set interface $interfaces($interface_name) - fpga_interfaces::add_interface $interface_name $interface(type) $interface(direction) - foreach {property_key property_value} $interface(properties) { - fpga_interfaces::set_interface_property $interface_name $property_key $property_value - } - #send_message info "NEA: peripheral_name $peripheral_name interface_name $interface_name " - - if { [string match "EMAC?" $peripheral_name] && [string match "*x_reset" $interface_name ] } { - fpga_interfaces::set_interface_property $interface_name associatedResetSinks none - } - - foreach {meta_property} [array names interface] { - # Meta Property if leading with an @ - if {[string compare [string index ${meta_property} 0] "@"] == 0} { - fpga_interfaces::set_interface_meta_property $interface_name [string replace ${meta_property} 0 0] $interface($meta_property) - } - } - - set once_per_clock 1 - funset ports - array set ports $iface_ports($interface_name) - foreach port_name $ports([ORDERED_NAMES]) { ;# Ports - funset port - array set port $ports($port_name) - - # TODO: determine width based on pins available via mode - set width [calculate_port_width $port_pins($port_name)] - - fpga_interfaces::add_interface_port $interface_name $port_name $port(role) $port(direction) $width $instance_name $port(atom_signal_name) - - set frequency 0 - # enable and show clock frequency parameters for outputs - if {[info exists clock_output_set($interface_name)]} { - set parameter [form_peripheral_fpga_output_clock_frequency_parameter $interface_name] - set_parameter_property $parameter enabled true - set frequency [get_parameter_value $parameter] - set frequency [expr {$frequency * [MHZ_TO_HZ]}] - fpga_interfaces::set_interface_property $interface_name clockRateKnown true - fpga_interfaces::set_interface_property $interface_name clockRate $frequency - } - - if {[string compare -nocase $interface(type) "clock"] == 0 && $once_per_clock} { - set once_per_clock 0 - add_clock_constraint_if_valid $frequency "*|fpga_interfaces|${instance_name}|[string tolower $port(atom_signal_name)]" - } - } - } - - # device-specific atom - set atom_name $peripheral(atom_name) - set wys_atom_name [generic_atom_to_wys_atom $device_family $atom_name] - set location [locations::get_fpga_location $peripheral_name $atom_name] - - fpga_interfaces::add_module_instance $instance_name $wys_atom_name $location - } - } -} - -# derives the WYS (device family-specific) atom name from the generic one -proc generic_atom_to_wys_atom {device_family atom_name} { - # TODO: base this on a table of data instead of on code - set result "" - if {[check_device_family_equivalence $device_family CYCLONEV]} { - set result "cyclonev_${atom_name}" - } elseif {[check_device_family_equivalence $device_family ARRIAV]} { - set result "arriav_${atom_name}" - } - return $result -} - -# invents an instance name from the peripheral's name -# assumes that the instance name is the same across a peripheral -proc invent_peripheral_instance_name {peripheral_name} { - return "peripheral_[string tolower $peripheral_name]" -} - -# TODO: do width calculation at db load time so we don't do it every elaboration! -# then make it accessible by a mode to width array for every peripheral with fpga periph interface -# TODO: also validate the static data, checking if the mode signals make sense aka only contiguous, 0-indexed mappings -proc calculate_port_width {pin_array_string} { - array set pins $pin_array_string - # TODO: -do we need to be able to support ports that don't start with pins at 0? - # -e.g. pins D0-D7 are indexed 0-7. if want D4-D7, can we do indexes 4-7? - # -for now, no! - set bit_index 0 - while {[info exists pins($bit_index)]} { - incr bit_index - } - return $bit_index -} - -proc pin_to_bank {pin} { - set io_index [string first "IO" $pin] - return [string range $pin 0 [expr {$io_index - 1}]] -} - -proc sort_pins {pins} { - set pin_suffixes [list] - foreach pin $pins { - set io_index [string first "IO" $pin] - set suffix_start [expr {$io_index + 2}] - set length [string length $pin] - set suffix [string range $pin $suffix_start [expr {$length - 1}]] - lappend pin_suffixes $suffix - } - set result [list] - set indices [lsort-indices -increasing -integer $pin_suffixes] - foreach index $indices { - lappend result [lindex $pins $index] - } - return $result -} - -proc set_peripheral_pin_muxing_description {peripheral_name pin_muxing_description mode_description} { - set parameter "[string toupper $peripheral_name]_PinMuxing" - set_display_item_property $parameter DESCRIPTION $pin_muxing_description - - set parameter "[string toupper $peripheral_name]_Mode" - set_display_item_property $parameter DESCRIPTION $mode_description -} - -# Expects same set of keys between both parameters -proc create_pin_muxing_description_table_html {signals_by_option_str pins_by_option_str} { - array set pins_by_option $pins_by_option_str - - set options [list] - foreach {option signals} $signals_by_option_str { - lappend options $option - - set pins $pins_by_option($option) - - foreach signal $signals pin $pins { - set key "${option}.${signal}" - set pins_by_option_and_signal($key) $pin - set signal_set($signal) 1 - } - } - - set sorted_signals [lsort -increasing -ascii [array names signal_set]] - set sorted_options [lsort -increasing -ascii $options] - - set ALIGN_CENTER {align="center"} - - set html "" ;# start of table, first row cell empty for signal column - foreach option $sorted_options { - set html "${html}" - } - set html "${html}" - foreach signal $sorted_signals { - set html "${html}" ;# new row w/ first cell (header) being the signal name - foreach option $sorted_options { - set key "${option}.${signal}" - if {[info exists pins_by_option_and_signal($key)]} { - set pin $pins_by_option_and_signal($key) - } else { - set pin "" - } - set html "${html}" - } - set html "${html}" - } - set html "${html}
${option}
${signal}${pin}
" - return $html -} - -proc create_mode_description_table_html {signals_by_mode_str} { - set modes [list] - - foreach {mode signals} $signals_by_mode_str { - lappend modes $mode - foreach signal $signals { - set key "${mode}.${signal}" - set membership_by_mode_and_signal($key) 1 - set signal_set($signal) 1 - } - } - - set sorted_signals [lsort -increasing -ascii [array names signal_set]] - set sorted_modes [lsort -increasing -ascii $modes] - - set ALIGN_CENTER {align="center"} - - set html "" ;# start of table, first row cell empty for signal column - foreach mode $sorted_modes { - set html "${html}" - } - set html "${html}" - foreach signal $sorted_signals { - set html "${html}" ;# new row w/ first cell (header) being the signal name - - foreach mode $sorted_modes { - set key "${mode}.${signal}" - if {[info exists membership_by_mode_and_signal($key)]} { - set member_marker "X" - } else { - set member_marker "" - } - set html "${html}" - } - set html "${html}" - } - set html "${html}
${mode}
${signal}${member_marker}
" - return $html -} - -proc get_quartus_edition {} { - set code { - set version "" - regexp {([a-zA-Z]+) (Edition|Version)$} $quartus(version) total version - return $version - } - set safe_code [string map {\n ; \t ""} $code] - set package_name "advanced_device" - set result [lindex [run_quartus_tcl_command "${package_name}:${safe_code}"] 0] - return $result -} - -proc is_soc_device {device} { - return [::pin_mux_db::verify_soc_device $device] -} - -proc set_peripheral_pin_muxing_descriptions {peripherals_ref} { - upvar 1 $peripherals_ref peripherals - - foreach peripheral_name [array names peripherals] { - set signals_by_option [list] - set pins_by_option [list] - - funset peripheral - array set peripheral $peripherals($peripheral_name) - funset pin_sets - array set pin_sets $peripheral(pin_sets) - - foreach pin_set_name [array names pin_sets] { - funset pin_set - array set pin_set $pin_sets($pin_set_name) - set signals $pin_set(signals) - lappend signals_by_option $pin_set_name $signals - set pins $pin_set(pins) - lappend pins_by_option $pin_set_name $pins - } - set signals_by_mode $peripheral(signals_by_mode) - - set table_html [create_pin_muxing_description_table_html $signals_by_option $pins_by_option] - set pin_muxing_description "" - - set table_html [create_mode_description_table_html $signals_by_mode] - set mode_description "Signal Membership Per Mode Usage Option:
${table_html}" - set_peripheral_pin_muxing_description $peripheral_name $pin_muxing_description $mode_description - } -} - -# Add pin muxing details to soc_io peripheral/signal data -add_storage_parameter pin_muxing {} -add_storage_parameter pin_muxing_check "" -proc ensure_pin_muxing_data {device_family} { - if {[check_device_family_equivalence $device_family [get_module_property SUPPORTED_DEVICE_FAMILIES]] == 0} { - return - } - - set device [get_device] - - if {![is_soc_device $device]} { - send_message error "Selected device '${device}' is not an SoC device. Please choose a valid SoC device to use the Hard Processor System." - return - } - - set device_configuration "${device_family}+${device}" - - set old_device_configuration [get_parameter_value pin_muxing_check] - if {$old_device_configuration == $device_configuration} { - return - } - - set load_rc [::pin_mux_db::load $device] - if {!$load_rc} { - send_message error "The pin information for the Hard Processor System could not be determined. Please check whether your edition of Quartus Prime supports the selected device." - return - } - locations::load $device - - load_peripherals_pin_muxing_model pin_muxing_peripherals - set_peripheral_pin_muxing_descriptions pin_muxing_peripherals - - set gpio_pins [::pin_mux_db::get_gpio_pins] - set loanio_pins [::pin_mux_db::get_loan_io_pins] - set customer_pin_names [::pin_mux_db::get_customer_pin_names] - set hlgpi_pins [::pin_mux_db::get_hlgpi_pins] - - set pin_muxing [list [array get pin_muxing_peripherals] $gpio_pins $loanio_pins $customer_pin_names $hlgpi_pins] - set_parameter_value pin_muxing $pin_muxing - set_parameter_value pin_muxing_check $device_configuration - - #### update pin_muxing data to use in java GUI #### - set pinmux_peripherals [array get pin_muxing_peripherals] - array set periph_key_value $pinmux_peripherals - - foreach {key value} [array get periph_key_value] { - set_parameter_value JAVA_${key}_DATA "$key \{$value\}" - } -} - -proc get_device {} { - - set device_name [get_parameter_value device_name] - return $device_name -} - -proc construct_hps_parameter_map {} { - set parameters [get_parameters] - foreach parameter $parameters { - set value [get_parameter_value $parameter] - set result($parameter) $value - } - return [array get result] -} - -################################################################################ -# Implements interface of util/pin_mux.tcl -# -namespace eval hps_ip_pin_muxing_model { -################################################################################ - proc get_peripherals_model {} { - set pin_muxing [get_parameter_value pin_muxing] - set peripherals [lindex $pin_muxing 0] - return $peripherals - } - proc get_emac0_fpga_ini {} { - return [is_enabled quartus_ini_hps_ip_enable_emac0_peripheral_fpga_interface] - } - proc get_lssis_fpga_ini {} { - return [is_enabled quartus_ini_hps_ip_enable_low_speed_serial_fpga_interfaces] - } - proc get_all_fpga_ini {} { - return [is_enabled quartus_ini_hps_ip_enable_all_peripheral_fpga_interfaces] - } - proc get_peripheral_pin_muxing_selection {peripheral_name} { - set pin_muxing_param_name [format [PIN_MUX_PARAM_FORMAT] $peripheral_name] - set selection [get_parameter_value $pin_muxing_param_name] - return $selection - } - proc get_peripheral_mode_selection {peripheral_name} { - set mode_param_name [format [MODE_PARAM_FORMAT] $peripheral_name] - set selection [get_parameter_value $mode_param_name] - return $selection - } - proc get_gpio_pins {} { - set pin_muxing [get_parameter_value pin_muxing] - set pins [lindex $pin_muxing 1] - return $pins - } - proc get_loanio_pins {} { - set pin_muxing [get_parameter_value pin_muxing] - set pins [lindex $pin_muxing 2] - return $pins - } - proc get_customer_pin_names {} { - set pin_muxing [get_parameter_value pin_muxing] - set pins [lindex $pin_muxing 3] - return $pins - } - proc get_hlgpi_pins {} { - set pin_muxing [get_parameter_value pin_muxing] - set pins [lindex $pin_muxing 4] - return $pins - } - proc get_unsupported_peripheral {peripheral_name} { - set device_family [get_parameter_value hps_device_family] - set skip 0 - if {[check_device_family_equivalence $device_family ARRIAV]} { - foreach excluded_peripheral [ARRIAV_EXCLUDED_PERIPHRERALS] { - if {[string compare $excluded_peripheral $peripheral_name] == 0} { - set skip 1 - } - } - } - return $skip - } -} - - -## Add documentation links for user guide and/or release notes -add_documentation_link "User Guide" https://www.altera.com/products/soc/overview.html diff --git a/sys/ip/in_split.v b/sys/ip/in_split.v deleted file mode 100644 index 9e141e4..0000000 --- a/sys/ip/in_split.v +++ /dev/null @@ -1,52 +0,0 @@ -// in_split.v - - -`timescale 1 ps / 1 ps -module in_split ( - input wire clk, // input.clk - input wire ce, // .ce - input wire de, // .de - input wire h_sync, // .h_sync - input wire v_sync, // .v_sync - input wire f, // .f - input wire [23:0] data, // .data - output wire vid_clk, // Output.vid_clk - output reg vid_datavalid, // .vid_datavalid - output reg [1:0] vid_de, // .vid_de - output reg [1:0] vid_f, // .vid_f - output reg [1:0] vid_h_sync, // .vid_h_sync - output reg [1:0] vid_v_sync, // .vid_v_sync - output reg [47:0] vid_data, // .vid_data - output wire vid_locked, // .vid_locked - output wire [7:0] vid_color_encoding, // .vid_color_encoding - output wire [7:0] vid_bit_width, // .vid_bit_width - input wire clipping, // .clipping - input wire overflow, // .overflow - input wire sof, // .sof - input wire sof_locked, // .sof_locked - input wire refclk_div, // .refclk_div - input wire padding // .padding - ); - - assign vid_bit_width = 0; - assign vid_color_encoding = 0; - assign vid_locked = 1; - assign vid_clk = clk; - - always @(posedge clk) begin - reg odd = 0; - - vid_datavalid <= 0; - if(ce) begin - vid_de[odd] <= de; - vid_f[odd] <= f; - vid_h_sync[odd] <= h_sync; - vid_v_sync[odd] <= v_sync; - if(odd) vid_data[47:24] <= data; - else vid_data[23:0] <= data; - - odd <= ~odd; - vid_datavalid <= odd; - end - end -endmodule diff --git a/sys/ip/in_split_hw.tcl b/sys/ip/in_split_hw.tcl deleted file mode 100644 index 403555a..0000000 --- a/sys/ip/in_split_hw.tcl +++ /dev/null @@ -1,104 +0,0 @@ -# TCL File Generated by Component Editor 17.0 -# Thu Jan 25 18:50:29 CST 2018 -# DO NOT MODIFY - - -# -# in_split "Input Splitter" v17.0 -# Sorgelig 2018.01.25.18:50:29 -# -# - -# -# request TCL package from ACDS 16.1 -# -package require -exact qsys 16.1 - - -# -# module in_split -# -set_module_property DESCRIPTION "" -set_module_property NAME in_split -set_module_property VERSION 17.0 -set_module_property INTERNAL false -set_module_property OPAQUE_ADDRESS_MAP true -set_module_property AUTHOR Sorgelig -set_module_property DISPLAY_NAME "Input Splitter" -set_module_property INSTANTIATE_IN_SYSTEM_MODULE true -set_module_property EDITABLE true -set_module_property REPORT_TO_TALKBACK false -set_module_property ALLOW_GREYBOX_GENERATION false -set_module_property REPORT_HIERARCHY false - - -# -# file sets -# -add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" "" -set_fileset_property QUARTUS_SYNTH TOP_LEVEL in_split -set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false -set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE true -add_fileset_file in_split.v VERILOG PATH in_split.v TOP_LEVEL_FILE - - -# -# parameters -# - - -# -# display items -# - - -# -# connection point input -# -add_interface input conduit end -set_interface_property input associatedClock "" -set_interface_property input associatedReset "" -set_interface_property input ENABLED true -set_interface_property input EXPORT_OF "" -set_interface_property input PORT_NAME_MAP "" -set_interface_property input CMSIS_SVD_VARIABLES "" -set_interface_property input SVD_ADDRESS_GROUP "" - -add_interface_port input clk clk Input 1 -add_interface_port input ce ce Input 1 -add_interface_port input de de Input 1 -add_interface_port input h_sync h_sync Input 1 -add_interface_port input v_sync v_sync Input 1 -add_interface_port input f f Input 1 -add_interface_port input data data Input 24 - - -# -# connection point Output -# -add_interface Output conduit end -set_interface_property Output associatedClock "" -set_interface_property Output associatedReset "" -set_interface_property Output ENABLED true -set_interface_property Output EXPORT_OF "" -set_interface_property Output PORT_NAME_MAP "" -set_interface_property Output CMSIS_SVD_VARIABLES "" -set_interface_property Output SVD_ADDRESS_GROUP "" - -add_interface_port Output vid_clk vid_clk Output 1 -add_interface_port Output vid_datavalid vid_datavalid Output 1 -add_interface_port Output vid_de vid_de Output 2 -add_interface_port Output vid_f vid_f Output 2 -add_interface_port Output vid_h_sync vid_h_sync Output 2 -add_interface_port Output vid_v_sync vid_v_sync Output 2 -add_interface_port Output vid_data vid_data Output 48 -add_interface_port Output vid_locked vid_locked Output 1 -add_interface_port Output vid_color_encoding vid_color_encoding Output 8 -add_interface_port Output vid_bit_width vid_bit_width Output 8 -add_interface_port Output clipping clipping Input 1 -add_interface_port Output overflow overflow Input 1 -add_interface_port Output sof sof Input 1 -add_interface_port Output sof_locked sof_locked Input 1 -add_interface_port Output refclk_div refclk_div Input 1 -add_interface_port Output padding padding Input 1 - diff --git a/sys/ip/out_mix.v b/sys/ip/out_mix.v deleted file mode 100644 index 280a3d5..0000000 --- a/sys/ip/out_mix.v +++ /dev/null @@ -1,44 +0,0 @@ -// out_mix.v - -`timescale 1 ps / 1 ps -module out_mix ( - input wire clk, // Output.clk - output reg de, // .de - output reg h_sync, // .h_sync - output reg v_sync, // .v_sync - output reg [23:0] data, // .data - output reg vid_clk, // input.vid_clk - input wire [1:0] vid_datavalid, // .vid_datavalid - input wire [1:0] vid_h_sync, // .vid_h_sync - input wire [1:0] vid_v_sync, // .vid_v_sync - input wire [47:0] vid_data, // .vid_data - input wire underflow, // .underflow - input wire vid_mode_change, // .vid_mode_change - input wire [1:0] vid_std, // .vid_std - input wire [1:0] vid_f, // .vid_f - input wire [1:0] vid_h, // .vid_h - input wire [1:0] vid_v // .vid_v - ); - - reg r_de; - reg r_h_sync; - reg r_v_sync; - reg [23:0] r_data; - - always @(posedge clk) begin - vid_clk <= ~vid_clk; - - if(~vid_clk) begin - {r_de,de} <= vid_datavalid; - {r_h_sync, h_sync} <= vid_h_sync; - {r_v_sync, v_sync} <= vid_v_sync; - {r_data, data} <= vid_data; - end else begin - de <= r_de; - h_sync <= r_h_sync; - v_sync <= r_v_sync; - data <= r_data; - end - end - -endmodule diff --git a/sys/ip/out_mix_hw.tcl b/sys/ip/out_mix_hw.tcl deleted file mode 100644 index b388891..0000000 --- a/sys/ip/out_mix_hw.tcl +++ /dev/null @@ -1,97 +0,0 @@ -# TCL File Generated by Component Editor 17.0 -# Thu Jan 25 06:51:26 CST 2018 -# DO NOT MODIFY - - -# -# out_mix "Output Mixer" v1.0 -# Sorgelig 2018.01.25.06:51:26 -# -# - -# -# request TCL package from ACDS 16.1 -# -package require -exact qsys 16.1 - - -# -# module out_mix -# -set_module_property DESCRIPTION "" -set_module_property NAME out_mix -set_module_property VERSION 17.0 -set_module_property INTERNAL false -set_module_property OPAQUE_ADDRESS_MAP true -set_module_property AUTHOR Sorgelig -set_module_property DISPLAY_NAME "Output Mixer" -set_module_property INSTANTIATE_IN_SYSTEM_MODULE true -set_module_property EDITABLE true -set_module_property REPORT_TO_TALKBACK false -set_module_property ALLOW_GREYBOX_GENERATION false -set_module_property REPORT_HIERARCHY false - - -# -# file sets -# -add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" "" -set_fileset_property QUARTUS_SYNTH TOP_LEVEL out_mix -set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false -set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE true -add_fileset_file out_mix.v VERILOG PATH out_mix.v TOP_LEVEL_FILE - - -# -# parameters -# - - -# -# display items -# - - -# -# connection point Output -# -add_interface Output conduit end -set_interface_property Output associatedClock "" -set_interface_property Output associatedReset "" -set_interface_property Output ENABLED true -set_interface_property Output EXPORT_OF "" -set_interface_property Output PORT_NAME_MAP "" -set_interface_property Output CMSIS_SVD_VARIABLES "" -set_interface_property Output SVD_ADDRESS_GROUP "" - -add_interface_port Output clk clk Input 1 -add_interface_port Output de de Output 1 -add_interface_port Output h_sync h_sync Output 1 -add_interface_port Output v_sync v_sync Output 1 -add_interface_port Output data data Output 24 - - -# -# connection point input -# -add_interface input conduit end -set_interface_property input associatedClock "" -set_interface_property input associatedReset "" -set_interface_property input ENABLED true -set_interface_property input EXPORT_OF "" -set_interface_property input PORT_NAME_MAP "" -set_interface_property input CMSIS_SVD_VARIABLES "" -set_interface_property input SVD_ADDRESS_GROUP "" - -add_interface_port input vid_clk vid_clk Output 1 -add_interface_port input vid_datavalid vid_datavalid Input 2 -add_interface_port input vid_h_sync vid_h_sync Input 2 -add_interface_port input vid_v_sync vid_v_sync Input 2 -add_interface_port input vid_data vid_data Input 48 -add_interface_port input underflow underflow Input 1 -add_interface_port input vid_mode_change vid_mode_change Input 1 -add_interface_port input vid_std vid_std Input 2 -add_interface_port input vid_f vid_f Input 2 -add_interface_port input vid_h vid_h Input 2 -add_interface_port input vid_v vid_v Input 2 - diff --git a/sys/ip/reset_source.v b/sys/ip/reset_source.v deleted file mode 100644 index 569eb9c..0000000 --- a/sys/ip/reset_source.v +++ /dev/null @@ -1,50 +0,0 @@ -// reset_source.v - -// This file was auto-generated as a prototype implementation of a module -// created in component editor. It ties off all outputs to ground and -// ignores all inputs. It needs to be edited to make it do something -// useful. -// -// This file will not be automatically regenerated. You should check it in -// to your version control system if you want to keep it. - -`timescale 1 ps / 1 ps -module reset_source -( - input wire clk, // clock.clk - input wire reset_hps, // reset_hps.reset - output wire reset_sys, // reset_sys.reset - output wire reset_cold, // reset_cold.reset - input wire cold_req, // reset_ctl.cold_req - output wire reset, // .reset - input wire reset_req, // .reset_req - input wire reset_vip, // .reset_vip - input wire warm_req, // .warm_req - output wire reset_warm // reset_warm.reset -); - -assign reset_cold = cold_req; -assign reset_warm = warm_req; - -wire reset_m = sys_reset | reset_hps | reset_req; -assign reset = reset_m; -assign reset_sys = reset_m | reset_vip; - -reg sys_reset = 1; -always @(posedge clk) begin - integer timeout = 0; - reg reset_lock = 0; - - reset_lock <= reset_lock | cold_req; - - if(timeout < 2000000) begin - sys_reset <= 1; - timeout <= timeout + 1; - reset_lock <= 0; - end - else begin - sys_reset <= reset_lock; - end -end - -endmodule diff --git a/sys/ip/reset_source_hw.tcl b/sys/ip/reset_source_hw.tcl deleted file mode 100644 index cba39f7..0000000 --- a/sys/ip/reset_source_hw.tcl +++ /dev/null @@ -1,152 +0,0 @@ -# TCL File Generated by Component Editor 17.0 -# Tue Feb 20 07:55:55 CST 2018 -# DO NOT MODIFY - - -# -# reset_source "reset_source" v17.0 -# Sorgelig 2018.02.20.07:55:55 -# -# - -# -# request TCL package from ACDS 16.1 -# -package require -exact qsys 16.1 - - -# -# module reset_source -# -set_module_property DESCRIPTION "" -set_module_property NAME reset_source -set_module_property VERSION 17.0 -set_module_property INTERNAL false -set_module_property OPAQUE_ADDRESS_MAP true -set_module_property AUTHOR Sorgelig -set_module_property DISPLAY_NAME reset_source -set_module_property INSTANTIATE_IN_SYSTEM_MODULE true -set_module_property EDITABLE true -set_module_property REPORT_TO_TALKBACK false -set_module_property ALLOW_GREYBOX_GENERATION false -set_module_property REPORT_HIERARCHY false - - -# -# file sets -# -add_fileset QUARTUS_SYNTH QUARTUS_SYNTH "" "" -set_fileset_property QUARTUS_SYNTH TOP_LEVEL reset_source -set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false -set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE true -add_fileset_file reset_source.v VERILOG PATH reset_source.v TOP_LEVEL_FILE - - -# -# parameters -# - - -# -# display items -# - - -# -# connection point clock -# -add_interface clock clock end -set_interface_property clock clockRate 0 -set_interface_property clock ENABLED true -set_interface_property clock EXPORT_OF "" -set_interface_property clock PORT_NAME_MAP "" -set_interface_property clock CMSIS_SVD_VARIABLES "" -set_interface_property clock SVD_ADDRESS_GROUP "" - -add_interface_port clock clk clk Input 1 - - -# -# connection point reset_hps -# -add_interface reset_hps reset end -set_interface_property reset_hps associatedClock "" -set_interface_property reset_hps synchronousEdges NONE -set_interface_property reset_hps ENABLED true -set_interface_property reset_hps EXPORT_OF "" -set_interface_property reset_hps PORT_NAME_MAP "" -set_interface_property reset_hps CMSIS_SVD_VARIABLES "" -set_interface_property reset_hps SVD_ADDRESS_GROUP "" - -add_interface_port reset_hps reset_hps reset Input 1 - - -# -# connection point reset_sys -# -add_interface reset_sys reset start -set_interface_property reset_sys associatedClock "" -set_interface_property reset_sys associatedDirectReset "" -set_interface_property reset_sys associatedResetSinks "" -set_interface_property reset_sys synchronousEdges NONE -set_interface_property reset_sys ENABLED true -set_interface_property reset_sys EXPORT_OF "" -set_interface_property reset_sys PORT_NAME_MAP "" -set_interface_property reset_sys CMSIS_SVD_VARIABLES "" -set_interface_property reset_sys SVD_ADDRESS_GROUP "" - -add_interface_port reset_sys reset_sys reset Output 1 - - -# -# connection point reset_ctl -# -add_interface reset_ctl conduit end -set_interface_property reset_ctl associatedClock "" -set_interface_property reset_ctl associatedReset "" -set_interface_property reset_ctl ENABLED true -set_interface_property reset_ctl EXPORT_OF "" -set_interface_property reset_ctl PORT_NAME_MAP "" -set_interface_property reset_ctl CMSIS_SVD_VARIABLES "" -set_interface_property reset_ctl SVD_ADDRESS_GROUP "" - -add_interface_port reset_ctl cold_req cold_req Input 1 -add_interface_port reset_ctl reset reset Output 1 -add_interface_port reset_ctl reset_req reset_req Input 1 -add_interface_port reset_ctl warm_req warm_req Input 1 -add_interface_port reset_ctl reset_vip reset_vip Input 1 - - -# -# connection point reset_warm -# -add_interface reset_warm reset start -set_interface_property reset_warm associatedClock "" -set_interface_property reset_warm associatedDirectReset "" -set_interface_property reset_warm associatedResetSinks "" -set_interface_property reset_warm synchronousEdges NONE -set_interface_property reset_warm ENABLED true -set_interface_property reset_warm EXPORT_OF "" -set_interface_property reset_warm PORT_NAME_MAP "" -set_interface_property reset_warm CMSIS_SVD_VARIABLES "" -set_interface_property reset_warm SVD_ADDRESS_GROUP "" - -add_interface_port reset_warm reset_warm reset Output 1 - - -# -# connection point reset_cold -# -add_interface reset_cold reset start -set_interface_property reset_cold associatedClock "" -set_interface_property reset_cold associatedDirectReset "" -set_interface_property reset_cold associatedResetSinks "" -set_interface_property reset_cold synchronousEdges NONE -set_interface_property reset_cold ENABLED true -set_interface_property reset_cold EXPORT_OF "" -set_interface_property reset_cold PORT_NAME_MAP "" -set_interface_property reset_cold CMSIS_SVD_VARIABLES "" -set_interface_property reset_cold SVD_ADDRESS_GROUP "" - -add_interface_port reset_cold reset_cold reset Output 1 - diff --git a/sys/lpf48k.sv b/sys/lpf48k.sv deleted file mode 100644 index 2a32981..0000000 --- a/sys/lpf48k.sv +++ /dev/null @@ -1,100 +0,0 @@ -// low pass filter -// Revision 1.00 -// -// Copyright (c) 2008 Takayuki Hara. -// All rights reserved. -// -// Redistribution and use of this source code or any derivative works, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// 3. Redistributions may not be sold, nor may they be used in a commercial -// product or activity without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// -// LPF (cut off 48kHz at 3.58MHz) - -module lpf48k #(parameter MSB = 15) -( - input RESET, - input CLK, - input CE, - input ENABLE, - - input [MSB:0] IDATA, - output [MSB:0] ODATA -); - -wire [7:0] LPF_TAP_DATA[0:71] = -'{ - 8'h51, 8'h07, 8'h07, 8'h08, 8'h08, 8'h08, 8'h09, 8'h09, - 8'h09, 8'h0A, 8'h0A, 8'h0A, 8'h0A, 8'h0B, 8'h0B, 8'h0B, - 8'h0B, 8'h0C, 8'h0C, 8'h0C, 8'h0C, 8'h0D, 8'h0D, 8'h0D, - 8'h0D, 8'h0D, 8'h0D, 8'h0E, 8'h0E, 8'h0E, 8'h0E, 8'h0E, - 8'h0E, 8'h0E, 8'h0E, 8'h0E, 8'h0E, 8'h0E, 8'h0E, 8'h0E, - 8'h0E, 8'h0E, 8'h0E, 8'h0E, 8'h0E, 8'h0D, 8'h0D, 8'h0D, - 8'h0D, 8'h0D, 8'h0D, 8'h0C, 8'h0C, 8'h0C, 8'h0C, 8'h0B, - 8'h0B, 8'h0B, 8'h0B, 8'h0A, 8'h0A, 8'h0A, 8'h0A, 8'h09, - 8'h09, 8'h09, 8'h08, 8'h08, 8'h08, 8'h07, 8'h07, 8'h51 -}; - -reg [7:0] FF_ADDR = 0; -reg [MSB+10:0] FF_INTEG = 0; -wire [MSB+8:0] W_DATA; -wire W_ADDR_END; - -assign W_ADDR_END = ((FF_ADDR == 71)); - -reg [MSB:0] OUT; - -assign ODATA = ENABLE ? OUT : IDATA; - -always @(posedge RESET or posedge CLK) begin - if (RESET) FF_ADDR <= 0; - else - begin - if (CE) begin - if (W_ADDR_END) FF_ADDR <= 0; - else FF_ADDR <= FF_ADDR + 1'd1; - end - end -end - -assign W_DATA = LPF_TAP_DATA[FF_ADDR] * IDATA; - -always @(posedge RESET or posedge CLK) begin - if (RESET) FF_INTEG <= 0; - else - begin - if (CE) begin - if (W_ADDR_END) FF_INTEG <= 0; - else FF_INTEG <= FF_INTEG + W_DATA; - end - end -end - -always @(posedge RESET or posedge CLK) begin - if (RESET) OUT <= 0; - else - begin - if (CE && W_ADDR_END) OUT <= FF_INTEG[MSB + 10:10]; - end -end - -endmodule diff --git a/sys/osd.v b/sys/osd.v index f6e8915..81939c6 100644 --- a/sys/osd.v +++ b/sys/osd.v @@ -13,7 +13,8 @@ module osd input [23:0] din, output [23:0] dout, input de_in, - output reg de_out + output reg de_out, + output reg osd_status ); parameter OSD_COLOR = 3'd4; @@ -23,21 +24,24 @@ parameter OSD_Y_OFFSET = 12'd0; localparam OSD_WIDTH = 12'd256; localparam OSD_HEIGHT = 12'd64; -reg osd_enable; -(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[4096]; +reg osd_enable; +reg [7:0] osd_buffer[4096]; -reg highres = 0; reg info = 0; reg [8:0] infoh; reg [8:0] infow; reg [11:0] infox; reg [21:0] infoy; +reg [21:0] hrheight; always@(posedge clk_sys) begin reg [11:0] bcnt; reg [7:0] cmd; reg has_cmd; reg old_strobe; + reg highres = 0; + + hrheight <= info ? infoh : (OSD_HEIGHT<>1) + OSD_X_OFFSET - 2'd2); + if(h_cnt > {dsp_width, 2'b00}) begin v_cnt <= 0; - dsp_height <= v_cnt; - if(osd_enable) begin - if(v_cnt<320) begin - multiscan <= 0; - fheight <= hrheight; - finfoy <= infoy; - end - else if(v_cnt<640) begin - multiscan <= 1; - fheight <= hrheight << 1; - finfoy <= infoy << 1; - end - else if(v_cnt<960) begin - multiscan <= 2; - fheight <= hrheight + (hrheight<<1); - finfoy <= infoy + (infoy << 1); - end - else begin - multiscan <= 3; - fheight <= hrheight << 2; - finfoy <= infoy << 2; - end + osd_en <= (osd_en << 1) | osd_enable; + if(~osd_enable) osd_en <= 0; + + if(v_cnt<320) begin + multiscan <= 0; + v_osd_start <= info ? infoy : (((v_cnt-hrheight)>>1) + OSD_Y_OFFSET); + end + else if(v_cnt<640) begin + multiscan <= 1; + v_osd_start <= info ? (infoy<<1) : (((v_cnt-(hrheight<<1))>>1) + OSD_Y_OFFSET); + end + else if(v_cnt<960) begin + multiscan <= 2; + v_osd_start <= info ? (infoy + (infoy << 1)) : (((v_cnt-(hrheight + (hrheight<<1)))>>1) + OSD_Y_OFFSET); end else begin - fheight <= 0; + multiscan <= 3; + v_osd_start <= info ? (infoy<<2) : (((v_cnt-(hrheight<<2))>>1) + OSD_Y_OFFSET); end end - h_cnt <= 0; - + osd_div <= osd_div + 1'd1; if(osd_div == multiscan) begin osd_div <= 0; - osd_vcnt <= osd_vcnt + 1'd1; + if(~&osd_vcnt) osd_vcnt <= osd_vcnt + 1'd1; end if(v_osd_start == (v_cnt+1'b1)) {osd_div, osd_vcnt} <= 0; end - - osd_byte <= osd_buffer[{osd_vcnt[6:3], osd_hcnt[7:0]}]; + + osd_byte <= osd_buffer[{osd_vcnt[6:3], osd_hcnt[7:0]}]; + osd_pixel <= osd_byte[osd_vcnt[2:0]]; + osd_de[2:1] <= osd_de[1:0]; end end -// area in which OSD is being displayed -wire [21:0] h_osd_start = info ? infox : ((dsp_width - OSD_WIDTH)>>1) + OSD_X_OFFSET; -wire [21:0] h_osd_end = info ? (h_osd_start + infow) : (h_osd_start + OSD_WIDTH); -wire [21:0] v_osd_start = info ? finfoy : ((dsp_height- fheight)>>1) + OSD_Y_OFFSET; -wire [21:0] v_osd_end = v_osd_start + fheight; - -wire [21:0] osd_hcnt = h_cnt[21:0] - h_osd_start + 1'd1; - -wire osd_de = osd_enable && fheight && - (h_cnt >= h_osd_start) && (h_cnt < h_osd_end) && - (v_cnt >= v_osd_start) && (v_cnt < v_osd_end); - -wire osd_pixel = osd_byte[osd_vcnt[2:0]]; - reg [23:0] rdout; assign dout = rdout; - + always @(posedge clk_video) begin - rdout <= !osd_de ? 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]}}; + 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; end diff --git a/sys/pattern_vg.v b/sys/pattern_vg.v deleted file mode 100644 index 6379278..0000000 --- a/sys/pattern_vg.v +++ /dev/null @@ -1,120 +0,0 @@ -module pattern_vg -#( - parameter B=8, // number of bits per channel - X_BITS=13, - Y_BITS=13, - FRACTIONAL_BITS = 12 -) - -( - input reset, clk_in, - input wire [X_BITS-1:0] x, - input wire [Y_BITS-1:0] y, - input wire vn_in, hn_in, dn_in, - input wire [B-1:0] r_in, g_in, b_in, - output reg vn_out, hn_out, den_out, - output reg [B-1:0] r_out, g_out, b_out, - input wire [X_BITS-1:0] total_active_pix, - input wire [Y_BITS-1:0] total_active_lines, - input wire [7:0] pattern, - input wire [B+FRACTIONAL_BITS-1:0] ramp_step -); - -reg [B+FRACTIONAL_BITS-1:0] ramp_values; // 12-bit fractional end for ramp values - - -//wire bar_0 = y<90; -wire bar_1 = y>=90 & y<180; -wire bar_2 = y>=180 & y<270; -wire bar_3 = y>=270 & y<360; -wire bar_4 = y>=360 & y<450; -wire bar_5 = y>=450 & y<540; -wire bar_6 = y>=540 & y<630; -wire bar_7 = y>=630 & y<720; - - -wire red_enable = bar_1 | bar_3 | bar_5 | bar_7; -wire green_enable = bar_2 | bar_3 | bar_6 | bar_7; -wire blue_enable = bar_4 | bar_5 | bar_6 | bar_7; - -always @(posedge clk_in) - begin - vn_out <= vn_in; - hn_out <= hn_in; - den_out <= dn_in; - if (reset) - ramp_values <= 0; - else if (pattern == 8'b0) // no pattern - begin - r_out <= r_in; - g_out <= g_in; - b_out <= b_in; - end - else if (pattern == 8'b1) // border - begin - if (dn_in && ((y == 12'b0) || (x == 12'b0) || (x == total_active_pix - 1) || (y == total_active_lines - 1))) - begin - r_out <= 8'hFF; - g_out <= 8'hFF; - b_out <= 8'hFF; - end - else // Double-border (OzOnE)... - if (dn_in && ((y == 12'b0+20) || (x == 12'b0+20) || (x == total_active_pix - 1 - 20) || (y == total_active_lines - 1 - 20))) - begin - r_out <= 8'hD0; - g_out <= 8'hB0; - b_out <= 8'hB0; - end - else - begin - r_out <= r_in; - g_out <= g_in; - b_out <= b_in; - end - end - else if (pattern == 8'd2) // moireX - begin - if ((dn_in) && x[0] == 1'b1) - begin - r_out <= 8'hFF; - g_out <= 8'hFF; - b_out <= 8'hFF; - end - else - begin - r_out <= 8'b0; - g_out <= 8'b0; - b_out <= 8'b0; - end - end - else if (pattern == 8'd3) // moireY - begin - if ((dn_in) && y[0] == 1'b1) - begin - r_out <= 8'hFF; - g_out <= 8'hFF; - b_out <= 8'hFF; - end - else - begin - r_out <= 8'b0; - g_out <= 8'b0; - b_out <= 8'b0; - end - end - else if (pattern == 8'd4) // Simple RAMP - begin - r_out <= (red_enable) ? ramp_values[B+FRACTIONAL_BITS-1:FRACTIONAL_BITS] : 8'h00; - g_out <= (green_enable) ? ramp_values[B+FRACTIONAL_BITS-1:FRACTIONAL_BITS] : 8'h00; - b_out <= (blue_enable) ? ramp_values[B+FRACTIONAL_BITS-1:FRACTIONAL_BITS] : 8'h00; - - if ((x == total_active_pix - 1) && (dn_in)) - ramp_values <= 0; - else if ((x == 0) && (dn_in)) - ramp_values <= ramp_step; - else if (dn_in) - ramp_values <= ramp_values + ramp_step; - end -end - -endmodule diff --git a/sys/pll_hdmi/pll_hdmi_0002_q13.qip b/sys/pll_hdmi/pll_hdmi_0002_q13.qip new file mode 100644 index 0000000..fb8053d --- /dev/null +++ b/sys/pll_hdmi/pll_hdmi_0002_q13.qip @@ -0,0 +1,4 @@ +set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" diff --git a/sys/pll_hdmi_adj.vhd b/sys/pll_hdmi_adj.vhd new file mode 100644 index 0000000..8c242af --- /dev/null +++ b/sys/pll_hdmi_adj.vhd @@ -0,0 +1,360 @@ +-------------------------------------------------------------------------------- +-- HDMI PLL Adjust +-------------------------------------------------------------------------------- + +-- Changes the HDMI PLL frequency according to the scaler suggestions. +-------------------------------------------- +-- LLTUNE : +-- 0 : Input Syncline +-- 1 : +-- 2 : Input Interlaced mode +-- 3 : Input Interlaced field +-- 4 : Output Syncline +-- 5 : +-- 6 : Input clock +-- 7 : Output clock + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY pll_hdmi_adj IS + PORT ( + -- Scaler + llena : IN std_logic; -- 0=Disabled 1=Enabled + lltune : IN unsigned(15 DOWNTO 0); -- Outputs from scaler + + locked : OUT std_logic; + + -- Signals from reconfig commands + i_waitrequest : OUT std_logic; + i_write : IN std_logic; + i_address : IN unsigned(5 DOWNTO 0); + i_writedata : IN unsigned(31 DOWNTO 0); + + -- Outputs to PLL_HDMI_CFG + o_waitrequest : IN std_logic; + o_write : OUT std_logic; + o_address : OUT unsigned(5 DOWNTO 0); + o_writedata : OUT unsigned(31 DOWNTO 0); + + ------------------------------------ + clk : IN std_logic; + reset_na : IN std_logic + ); + +BEGIN + + +END ENTITY pll_hdmi_adj; + +--############################################################################## + +ARCHITECTURE rtl OF pll_hdmi_adj IS + SIGNAL pwrite : std_logic; + SIGNAL paddress : unsigned(5 DOWNTO 0); + SIGNAL pdata : unsigned(31 DOWNTO 0); + TYPE enum_state IS (sIDLE,sW1,sW2,sW3,sW4,sW5,sW6); + SIGNAL state : enum_state; + SIGNAL tune_freq,tune_phase : unsigned(5 DOWNTO 0); + SIGNAL lltune_sync,lltune_sync2,lltune_sync3 : unsigned(15 DOWNTO 0); + SIGNAL mfrac,mfrac_mem,mfrac_ref,diff : unsigned(40 DOWNTO 0); + SIGNAL mul : unsigned(15 DOWNTO 0); + SIGNAL sign,sign_pre : std_logic; + 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 sync,pulse,los,lop : std_logic; + SIGNAL osize,isize,offset,osizep : signed(23 DOWNTO 0); + SIGNAL logcpt : natural RANGE 0 TO 31; + SIGNAL udiff : integer RANGE -2**23 TO 2**23-1 :=0; + +BEGIN + ---------------------------------------------------------------------------- + -- Sample image sizes + Sampler:PROCESS(clk,reset_na) IS + BEGIN + IF reset_na='0' THEN +--pragma synthesis_off + otog<='0'; + itog<='0'; + isync<='0'; + isync2<='0'; + osync<='0'; + osync2<='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); + + --ipulse<=isync AND NOT isync2 AND itog; + --opulse<=osync AND NOT osync2 AND otog; + + -- Measure output image size + IF osync='1' AND osync2='0' AND otog='1' THEN + ocpt<=0; + osizep<=to_signed(ocpt,24); + ELSE + ocpt<=ocpt+1; + END IF; + + -- Measure input image size + IF isync='1' AND isync2='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 + icpt<=icpt+1; + sync<='0'; + END IF; + + -------------------------------------------- + pulse<='0'; + IF sync='1' THEN + logcpt<=0; + ssh<=to_integer(osize); + los<='0'; + lop<='0'; + + ELSIF logcpt<24 THEN + -- Frequency difference + IF udiff>0 AND ssh=osize/2 AND ssh<(osize-offset) AND lop='0' THEN + tune_phase<='1' & to_unsigned(logcpt,5); + lop<='1'; + END IF; + ssh<=ssh/2; + logcpt<=logcpt+1; + + ELSIF logcpt=24 THEN + pulse<='1'; + ssh<=ssh/2; + logcpt<=logcpt+1; + END IF; + + END IF; + END PROCESS Sampler; + + ---------------------------------------------------------------------------- + -- 000010 : Start reg "Write either 0 or 1 to start fractional PLL reconf. + -- 000100 : M counter + -- 000111 : M counter Fractional Value K + + Comb:PROCESS(i_write,i_address, + i_writedata,pwrite,paddress,pdata) IS + BEGIN + IF i_write='1' THEN + o_write <=i_write; + o_address <=i_address; + o_writedata <=i_writedata; + ELSE + o_write <=pwrite; + o_address <=paddress; + o_writedata<=pdata; + END IF; + END PROCESS Comb; + + i_waitrequest<=o_waitrequest WHEN state=sIDLE ELSE '0'; + + ---------------------------------------------------------------------------- + Schmurtz:PROCESS(clk,reset_na) IS + VARIABLE off_v,ofp_v : natural RANGE 0 TO 63; + VARIABLE diff_v : unsigned(40 DOWNTO 0); + VARIABLE mulco : unsigned(15 DOWNTO 0); + VARIABLE up_v,sign_v : std_logic; + BEGIN + IF reset_na='0' THEN + modo<='0'; + state<=sIDLE; + ELSIF rising_edge(clk) THEN + ------------------------------------------------------ + -- Snoop accesses to PLL reconfiguration + IF i_address="000100" AND i_write='1' THEN + mfrac (40 DOWNTO 32)<=('0' & i_writedata(15 DOWNTO 8)) + + ('0' & i_writedata(7 DOWNTO 0)); + mfrac_ref(40 DOWNTO 32)<=('0' & i_writedata(15 DOWNTO 8)) + + ('0' & i_writedata(7 DOWNTO 0)); + mfrac_mem(40 DOWNTO 32)<=('0' & i_writedata(15 DOWNTO 8)) + + ('0' & i_writedata(7 DOWNTO 0)); + mul<=i_writedata(15 DOWNTO 0); + modo<='1'; + END IF; + + IF i_address="000111" AND i_write='1' THEN + mfrac (31 DOWNTO 0)<=i_writedata; + mfrac_ref(31 DOWNTO 0)<=i_writedata; + mfrac_mem(31 DOWNTO 0)<=i_writedata; + modo<='1'; + END IF; + + ------------------------------------------------------ + -- Tuning + off_v:=to_integer('0' & tune_freq(4 DOWNTO 0)); + ofp_v:=to_integer('0' & tune_phase(4 DOWNTO 0)); + --IF off_v<8 THEN off_v:=8; END IF; + --IF ofp_v<7 THEN ofp_v:=7; END IF; + IF off_v<4 THEN off_v:=4; END IF; + IF ofp_v<4 THEN ofp_v:=4; END IF; + + IF off_v>=18 AND ofp_v>=18 THEN + locked<=llena; + ELSE + locked<='0'; + END IF; + + up_v:='0'; + IF pulse='1' THEN + cpt<=(cpt+1) MOD 4; + IF llena='0' THEN + -- Recover original freq when disabling low lag mode + cpt<=0; + col<=0; + IF modo='1' THEN + mfrac<=mfrac_mem; + mfrac_ref<=mfrac_mem; + up<='1'; + modo<='0'; + END IF; + + ELSIF phm='0' AND cpt=0 THEN + -- Frequency adjust + sign_v:=tune_freq(5); + IF col<10 THEN col<=col+1; END IF; + IF off_v>=16 AND col>=10 THEN + phm<='1'; + col<=0; + ELSE + off_v:=off_v+1; + IF off_v>17 THEN + off_v:=off_v + 3; + END IF; + up_v:='1'; + up<='1'; + END IF; + + ELSIF cpt=0 THEN + -- Phase adjust + sign_v:=NOT tune_phase(5); + col<=col+1; + IF col>=10 THEN + phm<='0'; + up_v:='1'; + off_v:=31; + col<=0; + ELSE + off_v:=ofp_v + 1; + IF ofp_v>7 THEN + off_v:=off_v + 1; + END IF; + IF ofp_v>14 THEN + off_v:=off_v + 2; + END IF; + IF ofp_v>17 THEN + off_v:=off_v + 3; + END IF; + up_v:='1'; + END IF; + up<='1'; + END IF; + END IF; + + diff_v:=shift_right(mfrac_ref,off_v); + IF sign_v='0' THEN + diff_v:=mfrac_ref + diff_v; + ELSE + diff_v:=mfrac_ref - diff_v; + END IF; + + IF up_v='1' THEN + mfrac<=diff_v; + END IF; + + IF up_v='1' AND phm='0' THEN + mfrac_ref<=diff_v; + END IF; + + ------------------------------------------------------ + -- Update PLL registers + mulco:=mfrac(40 DOWNTO 33) & (mfrac(40 DOWNTO 33) + ('0' & mfrac(32))); + + CASE state IS + WHEN sIDLE => + pwrite<='0'; + IF up='1' THEN + up<='0'; + IF mulco/=mul THEN + state<=sW1; + ELSE + state<=sW3; + END IF; + END IF; + + WHEN sW1 => -- Change M multiplier + mul<=mulco; + pdata<=x"0000" & mulco; + paddress<="000100"; + pwrite<='1'; + state<=sW2; + + WHEN sW2 => + IF pwrite='1' AND o_waitrequest='0' THEN + state<=sW3; + pwrite<='0'; + END IF; + + WHEN sW3 => -- Change M fractional value + pdata<=mfrac(31 DOWNTO 0); + paddress<="000111"; + pwrite<='1'; + state<=sW4; + + WHEN sW4 => + IF pwrite='1' AND o_waitrequest='0' THEN + state<=sW5; + pwrite<='0'; + END IF; + + WHEN sW5 => + pdata<=x"0000_0001"; + paddress<="000010"; + pwrite<='1'; + state<=sW6; + + WHEN sW6 => + IF pwrite='1' AND o_waitrequest='0' THEN + pwrite<='0'; + state<=sIDLE; + END IF; + END CASE; + + END IF; + END PROCESS Schmurtz; + + ---------------------------------------------------------------------------- + +END ARCHITECTURE rtl; + diff --git a/sys/pll_hdmi_q13.qip b/sys/pll_hdmi_q13.qip new file mode 100644 index 0000000..705d514 --- /dev/null +++ b/sys/pll_hdmi_q13.qip @@ -0,0 +1,13 @@ +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_TOOL_VERSION "13.1" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_TOOL_ENV "mwpim" +set_global_assignment -library "pll_hdmi" -name MISC_FILE [file join $::quartus(qip_path) "pll_hdmi.cmp"] +set_global_assignment -name SYNTHESIS_ONLY_QIP ON + +set_global_assignment -library "pll_hdmi" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi.v"] +set_global_assignment -library "pll_hdmi" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi/pll_hdmi_0002.v"] +set_global_assignment -library "pll_hdmi" -name QIP_FILE [file join $::quartus(qip_path) "pll_hdmi/pll_hdmi_0002_q13.qip"] + +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_VERSION "13.1" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_ENV "mwpim" diff --git a/sys/scandoubler.v b/sys/scandoubler.v index f0728fc..9997cf6 100644 --- a/sys/scandoubler.v +++ b/sys/scandoubler.v @@ -2,7 +2,7 @@ // scandoubler.v // // Copyright (c) 2015 Till Harbaum -// Copyright (c) 2017 Sorgelig +// Copyright (c) 2017-2019 Sorgelig // // This source file is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published @@ -31,8 +31,8 @@ module scandoubler #(parameter LENGTH, parameter HALF_DEPTH) // shifter video interface input hs_in, input vs_in, - input hb_in, - input vb_in, + input hb_in, + input vb_in, input [DWIDTH:0] r_in, input [DWIDTH:0] g_in, @@ -42,8 +42,8 @@ module scandoubler #(parameter LENGTH, parameter HALF_DEPTH) // output interface output reg hs_out, output vs_out, - output hb_out, - output vb_out, + output hb_out, + output vb_out, output [DWIDTH:0] r_out, output [DWIDTH:0] g_out, output [DWIDTH:0] b_out @@ -52,48 +52,58 @@ module scandoubler #(parameter LENGTH, parameter HALF_DEPTH) localparam DWIDTH = HALF_DEPTH ? 3 : 7; -assign vs_out = vs_in; -assign ce_pix_out = ce_x4; +assign vs_out = vso[3]; +assign ce_pix_out = hq2x ? ce_x4 : ce_x2; //Compensate picture shift after HQ2x -assign vb_out = vbo[2]; -assign hb_out = &hbo[5:4]; +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_x1, ce_x4; -reg req_line_reset; +reg ce_x4, ce_x2, ce_x1; always @(negedge clk_sys) begin - reg old_ce; + reg old_ce, valid, hs; reg [2:0] ce_cnt; - reg [7:0] pixsz2, pixsz4 = 0; + reg [7:0] pixsz, pixsz2, pixsz4 = 0; - old_ce <= ce_pix; - if(~&pix_len) pix_len <= pix_len + 1'd1; + if(~&pix_len) pix_len <= pl; + if(~&pix_cnt) pix_cnt <= pc; ce_x4 <= 0; + ce_x2 <= 0; ce_x1 <= 0; - // use such odd comparison to place ce_x4 evenly if master clock isn't multiple 4. - if((pl == pixsz4) || (pl == pixsz2) || (pl == (pixsz2+pixsz4))) begin - ce_x4 <= 1; + // 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; + + old_ce <= ce_pix; + if(~old_ce & ce_pix) begin + if(valid & ~hb_in & ~vb_in) begin + pixsz <= pl; + pixsz2 <= {1'b0, pl[7:1]}; + pixsz4 <= {2'b00, pl[7:2]}; + end + pix_len <= 0; + valid <= 1; end - if(~old_ce & ce_pix) begin - pixsz2 <= {1'b0, pl[7:1]}; - pixsz4 <= {2'b00, pl[7:2]}; - ce_x1 <= 1; - ce_x4 <= 1; - pix_len <= 0; - req_line_reset <= 0; + if(hb_in | vb_in) valid <= 0; - if(hb_in) req_line_reset <= 1; + hs <= hs_out; + if((~hs & hs_out) || (pc >= pixsz)) begin + ce_x2 <= 1; + ce_x4 <= 1; + ce_x1 <= 1; + pix_cnt <= 0; end end -localparam AWIDTH = `BITS_TO_FIT(LENGTH); Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x ( .clk(clk_sys), @@ -101,86 +111,85 @@ Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x .inputpixel({b_d,g_d,r_d}), .mono(mono), .disable_hq2x(~hq2x), - .reset_frame(vs_in), + .reset_frame(vb_in), .reset_line(req_line_reset), .read_y(sd_line), - .read_x(sd_h), + .hblank(hbo[0]&hbo[8]), .outpixel({b_out,g_out,r_out}) ); -reg [10:0] sd_h; -reg [1:0] sd_line; -reg [2:0] vbo; -reg [5:0] hbo; - reg [DWIDTH:0] r_d; reg [DWIDTH:0] g_d; reg [DWIDTH:0] b_d; +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 [11:0] hs_max,hs_rise; - reg [10:0] hcnt; - reg [11:0] sd_hcnt; - reg [11:0] hde_start, hde_end; + reg [31:0] hcnt; + reg [30:0] sd_hcnt; + reg [30:0] hs_start, hs_end; + reg [30:0] hde_start, hde_end; - reg hs, hs2, vs, hb; + reg hs, hb; + + if(ce_x4) begin + hbo[8:1] <= hbo[7:0]; + end + + // output counter synchronous to input and at twice the rate + sd_hcnt <= sd_hcnt + 1'd1; + if(sd_hcnt == hde_start) begin + sd_hcnt <= 0; + vbo[3:1] <= vbo[2:0]; + end + + if(sd_hcnt == hs_end) begin + sd_line <= sd_line + 1'd1; + if(&vbo[3:2]) sd_line <= 1; + vso[3:1] <= vso[2:0]; + end + + if(sd_hcnt == hde_start)hbo[0] <= 0; + if(sd_hcnt == hde_end) hbo[0] <= 1; + + // replicate horizontal sync at twice the speed + if(sd_hcnt == hs_end) hs_out <= 0; + if(sd_hcnt == hs_start) hs_out <= 1; + + hs <= hs_in; + hb <= hb_in; if(ce_x1) begin - hs <= hs_in; - hb <= hb_in; - + req_line_reset <= hb_in; r_d <= r_in; g_d <= g_in; b_d <= b_in; - - if(hb && !hb_in) begin - hde_start <= {hcnt,1'b0}; - vbo <= {vbo[1:0], vb_in}; - end - if(!hb && hb_in) hde_end <= {hcnt,1'b0}; - - // falling edge of hsync indicates start of line - if(hs && !hs_in) begin - hs_max <= {hcnt,1'b1}; - hcnt <= 0; - end else begin - hcnt <= hcnt + 1'd1; - end - - // save position of rising edge - if(!hs && hs_in) hs_rise <= {hcnt,1'b1}; - - vs <= vs_in; - if(vs && ~vs_in) sd_line <= 0; end - if(ce_x4) begin - hs2 <= hs_in; - hbo[5:1] <= hbo[4:0]; - - // output counter synchronous to input and at twice the rate - sd_hcnt <= sd_hcnt + 1'd1; - if(~&hbo) sd_h <= sd_h + 1'd1; - - if(hs2 && !hs_in) sd_hcnt <= hs_max; - if(sd_hcnt == hs_max) sd_hcnt <= 0; - - - //prepare to read in advance - if(sd_hcnt == (hde_start-2)) begin - sd_h <= 0; - sd_line <= sd_line + 1'd1; - end - - if(sd_hcnt == hde_start) hbo[0] <= 0; - if(sd_hcnt == hde_end) hbo[0] <= 1; - - // replicate horizontal sync at twice the speed - if(sd_hcnt == hs_max) hs_out <= 0; - if(sd_hcnt == hs_rise) hs_out <= 1; + hcnt <= hcnt + 1'd1; + if(hb && !hb_in) begin + hde_start <= hcnt[31:1]; + hbo[0] <= 0; + hcnt <= 0; + sd_hcnt <= 0; + vbo <= {vbo[2:0],vb_in}; end + + if(!hb && hb_in) hde_end <= hcnt[31:1]; + + // falling edge of hsync indicates start of line + if(hs && !hs_in) begin + hs_end <= hcnt[31:1]; + vso[0] <= vs_in; + end + + // save position of rising edge + if(!hs && hs_in) hs_start <= hcnt[31:1]; end endmodule diff --git a/sys/scanlines.v b/sys/scanlines.v new file mode 100644 index 0000000..96aa6e3 --- /dev/null +++ b/sys/scanlines.v @@ -0,0 +1,52 @@ +module scanlines #(parameter v2=0) +( + input clk, + + input [1:0] scanlines, + input [23:0] din, + output reg [23:0] dout, + input hs,vs +); + +reg [1:0] scanline; +always @(posedge clk) begin + reg old_hs, old_vs; + + old_hs <= hs; + old_vs <= vs; + + if(old_hs && ~hs) begin + if(v2) begin + scanline <= scanline + 1'd1; + if (scanline == scanlines) scanline <= 0; + end + else scanline <= scanline ^ scanlines; + end + if(old_vs && ~vs) scanline <= 0; +end + +wire [7:0] r,g,b; +assign {r,g,b} = din; + +always @(*) begin + case(scanline) + 1: // reduce 25% = 1/2 + 1/4 + dout = {{1'b0, r[7:1]} + {2'b00, r[7:2]}, + {1'b0, g[7:1]} + {2'b00, g[7:2]}, + {1'b0, b[7:1]} + {2'b00, b[7:2]}}; + + 2: // reduce 50% = 1/2 + dout = {{1'b0, r[7:1]}, + {1'b0, g[7:1]}, + {1'b0, b[7:1]}}; + + 3: // reduce 75% = 1/4 + dout = {{2'b00, r[7:2]}, + {2'b00, g[7:2]}, + {2'b00, b[7:2]}}; + + default: dout = {r,g,b}; + endcase +end + +endmodule diff --git a/sys/sd_card.v b/sys/sd_card.v new file mode 100644 index 0000000..3761a7e --- /dev/null +++ b/sys/sd_card.v @@ -0,0 +1,538 @@ +// +// sd_card.v +// +// Copyright (c) 2014 Till Harbaum +// Copyright (c) 2015-2018 Sorgelig +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the Lesser GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file 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, see . +// +// http://elm-chan.org/docs/mmc/mmc_e.html +// +///////////////////////////////////////////////////////////////////////// + +// +// Made module syncrhronous. Total code refactoring. (Sorgelig) +// clk_spi must be at least 4 x sck for proper work. + +module sd_card +( + input clk_sys, + input reset, + + input sdhc, + + output [31:0] sd_lba, + output reg sd_rd, + output reg sd_wr, + input sd_ack, + input sd_ack_conf, + + input [8:0] sd_buff_addr, + input [7:0] sd_buff_dout, + output [7:0] sd_buff_din, + input sd_buff_wr, + + // SPI interface + input clk_spi, + + input ss, + input sck, + input mosi, + output reg miso +); + +assign sd_lba = sdhc ? lba : {9'd0, lba[31:9]}; + +wire[31:0] OCR = { 1'b1, sdhc, 30'd0 }; // bit30 = 1 -> high capaciry card (sdhc) // bit31 = 0 -> card power up finished +wire [7:0] READ_DATA_TOKEN = 8'hfe; +wire [7:0] WRITE_DATA_RESPONSE = 8'h05; + +// number of bytes to wait after a command before sending the reply +localparam NCR=3; + +localparam RD_STATE_IDLE = 0; +localparam RD_STATE_WAIT_IO = 1; +localparam RD_STATE_SEND_TOKEN = 2; +localparam RD_STATE_SEND_DATA = 3; +localparam RD_STATE_WAIT_M = 4; + +localparam WR_STATE_IDLE = 0; +localparam WR_STATE_EXP_DTOKEN = 1; +localparam WR_STATE_RECV_DATA = 2; +localparam WR_STATE_RECV_CRC0 = 3; +localparam WR_STATE_RECV_CRC1 = 4; +localparam WR_STATE_SEND_DRESP = 5; +localparam WR_STATE_BUSY = 6; + +sdbuf buffer +( + .clock_a(clk_sys), + .address_a(sd_buff_addr), + .data_a(sd_buff_dout), + .wren_a(sd_ack & sd_buff_wr), + .q_a(sd_buff_din), + + .clock_b(clk_spi), + .address_b(buffer_ptr), + .data_b(buffer_din), + .wren_b(buffer_wr), + .q_b(buffer_dout) +); + +sdbuf conf +( + .clock_a(clk_sys), + .address_a(sd_buff_addr), + .data_a(sd_buff_dout), + .wren_a(sd_ack_conf & sd_buff_wr), + + .clock_b(clk_spi), + .address_b(buffer_ptr), + .q_b(config_dout) +); + +reg [31:0] lba, new_lba; +reg [8:0] buffer_ptr; +reg [7:0] buffer_din; +wire [7:0] buffer_dout; +wire [7:0] config_dout; +reg buffer_wr; + +always @(posedge clk_spi) begin + reg [2:0] read_state; + reg [2:0] write_state; + reg [6:0] sbuf; + reg cmd55; + reg [7:0] cmd; + reg [2:0] bit_cnt; + reg [3:0] byte_cnt; + reg [7:0] reply; + reg [7:0] reply0, reply1, reply2, reply3; + reg [3:0] reply_len; + reg tx_finish; + reg rx_finish; + reg old_sck; + reg synced; + reg [5:0] ack; + reg io_ack; + reg [4:0] idle_cnt = 0; + reg [2:0] wait_m_cnt; + + if(buffer_wr & ~&buffer_ptr) buffer_ptr <= buffer_ptr + 1'd1; + buffer_wr <= 0; + + ack <= {ack[4:0], sd_ack}; + if(ack[5:4] == 2'b10) io_ack <= 1; + if(ack[5:4] == 2'b01) {sd_rd,sd_wr} <= 0; + + old_sck <= sck; + + if(~ss) idle_cnt <= 31; + else if(~old_sck && sck && idle_cnt) idle_cnt <= idle_cnt - 1'd1; + + if(reset || !idle_cnt) begin + bit_cnt <= 0; + byte_cnt <= 15; + synced <= 0; + miso <= 1; + sbuf <= 7'b1111111; + tx_finish <= 0; + rx_finish <= 0; + read_state <= RD_STATE_IDLE; + write_state <= WR_STATE_IDLE; + end + + if(old_sck & ~sck & ~ss) begin + tx_finish <= 0; + miso <= 1; // default: send 1's (busy/wait) + + if(byte_cnt == 5+NCR) begin + miso <= reply[~bit_cnt]; + + if(bit_cnt == 7) begin + // these three commands all have a reply_len of 0 and will thus + // not send more than a single reply byte + + // CMD9: SEND_CSD + // CMD10: SEND_CID + if((cmd == 'h49) | (cmd == 'h4a)) + read_state <= RD_STATE_SEND_TOKEN; // jump directly to data transmission + + // CMD17/CMD18 + if((cmd == 'h51) | (cmd == 'h52)) begin + io_ack <= 0; + read_state <= RD_STATE_WAIT_IO; // start waiting for data from io controller + lba <= new_lba; + sd_rd <= 1; // trigger request to io controller + end + end + end + else if((reply_len > 0) && (byte_cnt == 5+NCR+1)) miso <= reply0[~bit_cnt]; + else if((reply_len > 1) && (byte_cnt == 5+NCR+2)) miso <= reply1[~bit_cnt]; + else if((reply_len > 2) && (byte_cnt == 5+NCR+3)) miso <= reply2[~bit_cnt]; + else if((reply_len > 3) && (byte_cnt == 5+NCR+4)) miso <= reply3[~bit_cnt]; + else begin + if(byte_cnt > 5+NCR && read_state==RD_STATE_IDLE && write_state==WR_STATE_IDLE) tx_finish <= 1; + end + + // ---------- read state machine processing ------------- + + case(read_state) + RD_STATE_IDLE: ; // do nothing + + + // waiting for io controller to return data + RD_STATE_WAIT_IO: begin + if(io_ack & (bit_cnt == 7)) read_state <= RD_STATE_SEND_TOKEN; + end + + // send data token + RD_STATE_SEND_TOKEN: begin + miso <= READ_DATA_TOKEN[~bit_cnt]; + + if(bit_cnt == 7) begin + read_state <= RD_STATE_SEND_DATA; // next: send data + buffer_ptr <= 0; + if(cmd == 'h49) buffer_ptr <= 16; + end + end + + // send data + RD_STATE_SEND_DATA: begin + + miso <= ((cmd == 'h49) | (cmd == 'h4A)) ? config_dout[~bit_cnt] : buffer_dout[~bit_cnt]; + + if(bit_cnt == 7) begin + + // sent 512 sector data bytes? + if((cmd == 'h51) & &buffer_ptr) read_state <= RD_STATE_IDLE; + else if((cmd == 'h52) & &buffer_ptr) begin + read_state <= RD_STATE_WAIT_M; + wait_m_cnt <= 0; + end + + // sent 16 cid/csd data bytes? + else if(((cmd == 'h49) | (cmd == 'h4a)) & (&buffer_ptr[3:0])) read_state <= RD_STATE_IDLE; + + // not done yet -> trigger read of next data byte + else buffer_ptr <= buffer_ptr + 1'd1; + end + end + + RD_STATE_WAIT_M: begin + if(bit_cnt == 7) begin + wait_m_cnt <= wait_m_cnt + 1'd1; + if(&wait_m_cnt) begin + lba <= lba + 1; + io_ack <= 0; + sd_rd <= 1; + read_state <= RD_STATE_WAIT_IO; + end + end + end + endcase + + // ------------------ write support ---------------------- + // send write data response + if(write_state == WR_STATE_SEND_DRESP) miso <= WRITE_DATA_RESPONSE[~bit_cnt]; + + // busy after write until the io controller sends ack + if(write_state == WR_STATE_BUSY) miso <= 0; + end + + if(~old_sck & sck & ~ss) begin + + if(synced) bit_cnt <= bit_cnt + 1'd1; + + // assemble byte + if(bit_cnt != 7) begin + sbuf[6:0] <= { sbuf[5:0], mosi }; + + // resync while waiting for token + if(write_state==WR_STATE_EXP_DTOKEN) begin + if(cmd == 'h58) begin + if({sbuf,mosi} == 8'hfe) begin + write_state <= WR_STATE_RECV_DATA; + buffer_ptr <= 0; + bit_cnt <= 0; + end + end + else begin + if({sbuf,mosi} == 8'hfc) begin + write_state <= WR_STATE_RECV_DATA; + buffer_ptr <= 0; + bit_cnt <= 0; + end + if({sbuf,mosi} == 8'hfd) begin + write_state <= WR_STATE_IDLE; + rx_finish <= 1; + bit_cnt <= 0; + end + end + end + end + else begin + // finished reading one byte + // byte counter runs against 15 byte boundary + if(byte_cnt != 15) byte_cnt <= byte_cnt + 1'd1; + + // byte_cnt > 6 -> complete command received + // first byte of valid command is 01xxxxxx + // don't accept new commands once a write or read command has been accepted + if((byte_cnt > 5) & (write_state == WR_STATE_IDLE) & (read_state == RD_STATE_IDLE) && !rx_finish) begin + byte_cnt <= 0; + cmd <= { sbuf, mosi}; + + // set cmd55 flag if previous command was 55 + cmd55 <= (cmd == 'h77); + end + + if((byte_cnt > 5) & (read_state == RD_STATE_WAIT_M) && ({sbuf, mosi} == 8'h4c)) begin + byte_cnt <= 0; + rx_finish <= 0; + cmd <= {sbuf, mosi}; + read_state <= RD_STATE_IDLE; + end + + // parse additional command bytes + if(byte_cnt == 0) new_lba[31:24] <= { sbuf, mosi}; + if(byte_cnt == 1) new_lba[23:16] <= { sbuf, mosi}; + if(byte_cnt == 2) new_lba[15:8] <= { sbuf, mosi}; + if(byte_cnt == 3) new_lba[7:0] <= { sbuf, mosi}; + + // last byte (crc) received, evaluate + if(byte_cnt == 4) begin + + // default: + reply <= 4; // illegal command + reply_len <= 0; // no extra reply bytes + rx_finish <= 1; + + case(cmd) + // CMD0: GO_IDLE_STATE + 'h40: reply <= 1; // ok, busy + + // CMD1: SEND_OP_COND + 'h41: reply <= 0; // ok, not busy + + // CMD8: SEND_IF_COND (V2 only) + 'h48: begin + reply <= 1; // ok, busy + + reply0 <= 'h00; + reply1 <= 'h00; + reply2 <= 'h01; + reply3 <= 'hAA; + reply_len <= 4; + end + + // CMD9: SEND_CSD + 'h49: reply <= 0; // ok + + // CMD10: SEND_CID + 'h4a: reply <= 0; // ok + + // CMD12: STOP_TRANSMISSION + 'h4c: reply <= 0; // ok + + // CMD16: SET_BLOCKLEN + 'h50: begin + // we only support a block size of 512 + if(new_lba == 512) reply <= 0; // ok + else reply <= 'h40; // parmeter error + end + + // CMD17: READ_SINGLE_BLOCK + 'h51: reply <= 0; // ok + + // CMD18: READ_MULTIPLE + 'h52: reply <= 0; // ok + + // CMD24: WRITE_BLOCK + 'h58, + // CMD25: WRITE_MULTIPLE + 'h59: begin + reply <= 0; // ok + write_state <= WR_STATE_EXP_DTOKEN; // expect data token + rx_finish <=0; + lba <= new_lba; + end + + // ACMD41: APP_SEND_OP_COND + 'h69: if(cmd55) reply <= 0; // ok, not busy + + // CMD55: APP_COND + 'h77: reply <= 1; // ok, busy + + // CMD58: READ_OCR + 'h7a: begin + reply <= 0; // ok + + reply0 <= OCR[31:24]; // bit 30 = 1 -> high capacity card + reply1 <= OCR[23:16]; + reply2 <= OCR[15:8]; + reply3 <= OCR[7:0]; + reply_len <= 4; + end + + // CMD59: CRC_ON_OFF + 'h7b: reply <= 0; // ok + endcase + end + + // ---------- handle write ----------- + case(write_state) + // do nothing in idle state + WR_STATE_IDLE: ; + + // waiting for data token + WR_STATE_EXP_DTOKEN: begin + buffer_ptr <= 0; + if(cmd == 'h58) begin + if({sbuf,mosi} == 8'hfe) write_state <= WR_STATE_RECV_DATA; + end + else begin + if({sbuf,mosi} == 8'hfc) write_state <= WR_STATE_RECV_DATA; + if({sbuf,mosi} == 8'hfd) begin + write_state <= WR_STATE_IDLE; + rx_finish <= 1; + end + end + end + + // transfer 512 bytes + WR_STATE_RECV_DATA: begin + // push one byte into local buffer + buffer_wr <= 1; + buffer_din <= {sbuf, mosi}; + + // all bytes written? + if(&buffer_ptr) write_state <= WR_STATE_RECV_CRC0; + end + + // transfer 1st crc byte + WR_STATE_RECV_CRC0: + write_state <= WR_STATE_RECV_CRC1; + + // transfer 2nd crc byte + WR_STATE_RECV_CRC1: + write_state <= WR_STATE_SEND_DRESP; + + // send data response + WR_STATE_SEND_DRESP: begin + write_state <= WR_STATE_BUSY; + io_ack <= 0; + sd_wr <= 1; + end + + // wait for io controller to accept data + WR_STATE_BUSY: + if(io_ack) begin + if(cmd == 'h59) begin + write_state <= WR_STATE_EXP_DTOKEN; + lba <= lba + 1; + end + else begin + write_state <= WR_STATE_IDLE; + rx_finish <= 1; + end + end + endcase + end + + // wait for first 0 bit until start counting bits + if(!synced && !mosi) begin + synced <= 1; + bit_cnt <= 1; // byte assembly prepare for next time loop + sbuf <= 7'b1111110; // byte assembly prepare for next time loop + rx_finish<= 0; + end else if (synced && tx_finish && rx_finish ) begin + synced <= 0; + bit_cnt <= 0; + rx_finish<= 0; + end + end +end + +endmodule + +module sdbuf +( + input clock_a, + input clock_b, + input [8:0] address_a, + input [8:0] address_b, + input [7:0] data_a, + input [7:0] data_b, + input wren_a, + input wren_b, + output [7:0] q_a, + output [7:0] q_b +); + +altsyncram altsyncram_component +( + .address_a (address_a), + .address_b (address_b), + .clock0 (clock_a), + .clock1 (clock_b), + .data_a (data_a), + .data_b (data_b), + .wren_a (wren_a), + .wren_b (wren_b), + .q_a (q_a), + .q_b (q_b), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .eccstatus (), + .rden_a (1'b1), + .rden_b (1'b1) +); +defparam + altsyncram_component.address_reg_b = "CLOCK1", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_a = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.indata_reg_b = "CLOCK1", + altsyncram_component.intended_device_family = "Cyclone V", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 512, + altsyncram_component.numwords_b = 512, + altsyncram_component.operation_mode = "BIDIR_DUAL_PORT", + altsyncram_component.outdata_aclr_a = "NONE", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_a = "UNREGISTERED", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ", + altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ", + altsyncram_component.widthad_a = 9, + altsyncram_component.widthad_b = 9, + altsyncram_component.width_a = 8, + altsyncram_component.width_b = 8, + altsyncram_component.width_byteena_a = 1, + altsyncram_component.width_byteena_b = 1, + altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK1"; + +endmodule + diff --git a/sys/spdif.v b/sys/spdif.v index 671dcb2..d50c2da 100644 --- a/sys/spdif.v +++ b/sys/spdif.v @@ -31,132 +31,6 @@ // altera message_off 10240 module spdif - -//----------------------------------------------------------------- -// Params -//----------------------------------------------------------------- -#( - parameter CLK_RATE = 50000000, - parameter AUDIO_RATE = 48000, - - // Generated params - parameter WHOLE_CYCLES = (CLK_RATE) / (AUDIO_RATE*128), - parameter ERROR_BASE = 10000, - parameter [63:0] ERRORS_PER_BIT = ((CLK_RATE * ERROR_BASE) / (AUDIO_RATE*128)) - (WHOLE_CYCLES * ERROR_BASE) -) - -//----------------------------------------------------------------- -// Ports -//----------------------------------------------------------------- -( - input clk_i, - input rst_i, - input half_rate, - - // Output - output spdif_o, - - // Audio interface (16-bit x 2 = RL) - input [15:0] audio_r, - input [15:0] audio_l, - output sample_req_o -); - -reg lpf_ce; -always @(negedge clk_i) begin - reg [3:0] div; - - div <= div + 1'd1; - if(div == 13) div <= 0; - - lpf_ce <= !div; -end - -wire [15:0] al, ar; - -lpf48k #(15) lpf_l -( - .RESET(rst_i), - .CLK(clk_i), - .CE(lpf_ce), - .ENABLE(1), - - .IDATA(audio_l), - .ODATA(al) -); - -lpf48k #(15) lpf_r -( - .RESET(rst_i), - .CLK(clk_i), - .CE(lpf_ce), - .ENABLE(1), - - .IDATA(audio_r), - .ODATA(ar) -); - -reg bit_clk_q; - -// Clock pulse generator -always @ (posedge rst_i or posedge clk_i) begin - reg [31:0] count_q; - reg [31:0] error_q; - reg ce; - - if (rst_i) begin - count_q <= 0; - error_q <= 0; - bit_clk_q <= 1; - ce <= 0; - end - else - begin - if(count_q == WHOLE_CYCLES-1) begin - if (error_q < (ERROR_BASE - ERRORS_PER_BIT)) begin - error_q <= error_q + ERRORS_PER_BIT[31:0]; - count_q <= 0; - end else begin - error_q <= error_q + ERRORS_PER_BIT[31:0] - ERROR_BASE; - count_q <= count_q + 1; - end - end else if(count_q == WHOLE_CYCLES) begin - count_q <= 0; - end else begin - count_q <= count_q + 1; - end - - bit_clk_q <= 0; - if(!count_q) begin - ce <= ~ce; - if(~half_rate || ce) bit_clk_q <= 1; - end - end -end - -//----------------------------------------------------------------- -// Core SPDIF -//----------------------------------------------------------------- - -wire [31:0] sample_i = {ar, al}; - -spdif_core -u_core -( - .clk_i(clk_i), - .rst_i(rst_i), - - .bit_out_en_i(bit_clk_q), - - .spdif_o(spdif_o), - - .sample_i(sample_i), - .sample_req_o(sample_req_o) -); - -endmodule - -module spdif_core ( input clk_i, input rst_i, diff --git a/sys/sync_vg.v b/sys/sync_vg.v deleted file mode 100644 index 54fc614..0000000 --- a/sys/sync_vg.v +++ /dev/null @@ -1,78 +0,0 @@ -module sync_vg -#( - parameter X_BITS=12, Y_BITS=12 -) -( - input wire clk, - input wire reset, - - input wire [Y_BITS-1:0] v_total, - input wire [Y_BITS-1:0] v_fp, - input wire [Y_BITS-1:0] v_bp, - input wire [Y_BITS-1:0] v_sync, - input wire [X_BITS-1:0] h_total, - input wire [X_BITS-1:0] h_fp, - input wire [X_BITS-1:0] h_bp, - input wire [X_BITS-1:0] h_sync, - input wire [X_BITS-1:0] hv_offset, - - output reg vs_out, - output reg hs_out, - output reg hde_out, - output reg vde_out, - output reg [Y_BITS-1:0] v_count_out, - output reg [X_BITS-1:0] h_count_out, - output reg [X_BITS-1:0] x_out, - output reg [Y_BITS-1:0] y_out -); - -reg [X_BITS-1:0] h_count; -reg [Y_BITS-1:0] v_count; - -/* horizontal counter */ -always @(posedge clk) - if (reset) - h_count <= 0; - else - if (h_count < h_total - 1) - h_count <= h_count + 1'd1; - else - h_count <= 0; - -/* vertical counter */ -always @(posedge clk) - if (reset) - v_count <= 0; - else - if (h_count == h_total - 1) - begin - if (v_count == v_total - 1) - v_count <= 0; - else - v_count <= v_count + 1'd1; - end - -always @(posedge clk) - if (reset) - { vs_out, hs_out, hde_out, vde_out } <= 0; - else begin - hs_out <= ((h_count < h_sync)); - - hde_out <= (h_count >= h_sync + h_bp) && (h_count <= h_total - h_fp - 1); - vde_out <= (v_count >= v_sync + v_bp) && (v_count <= v_total - v_fp - 1); - - if ((v_count == 0) && (h_count == hv_offset)) - vs_out <= 1'b1; - else if ((v_count == v_sync) && (h_count == hv_offset)) - vs_out <= 1'b0; - - /* H_COUNT_OUT and V_COUNT_OUT */ - h_count_out <= h_count; - v_count_out <= v_count; - - /* X and Y coords for a backend pattern generator */ - x_out <= h_count - (h_sync + h_bp); - y_out <= v_count - (v_sync + v_bp); - end - -endmodule diff --git a/sys/sys.qip b/sys/sys.qip index 5b397f4..986b6d2 100644 --- a/sys/sys.qip +++ b/sys/sys.qip @@ -1,23 +1,26 @@ -set_global_assignment -name VERILOG_FILE sys/sys_top.v -set_global_assignment -name SDC_FILE sys/sys_top.sdc -set_global_assignment -name QIP_FILE sys/pll.qip -set_global_assignment -name QIP_FILE sys/pll_hdmi.qip -set_global_assignment -name QIP_FILE sys/pll_hdmi_cfg.qip -set_global_assignment -name SYSTEMVERILOG_FILE sys/hdmi_lite.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/hq2x.sv -set_global_assignment -name VERILOG_FILE sys/scandoubler.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/video_mixer.sv -set_global_assignment -name VERILOG_FILE sys/osd.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/vga_out.sv -set_global_assignment -name VERILOG_FILE sys/sync_vg.v -set_global_assignment -name VERILOG_FILE sys/pattern_vg.v -set_global_assignment -name VERILOG_FILE sys/i2c.v -set_global_assignment -name VERILOG_FILE sys/i2s.v -set_global_assignment -name VERILOG_FILE sys/spdif.v -set_global_assignment -name VERILOG_FILE sys/sigma_delta_dac.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/lpf48k.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/hdmi_config.sv -set_global_assignment -name SYSTEMVERILOG_FILE sys/sysmem.sv -set_global_assignment -name VERILOG_FILE sys/ip/reset_source.v -set_global_assignment -name SYSTEMVERILOG_FILE sys/vip_config.sv -set_global_assignment -name VERILOG_FILE sys/hps_io.v +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) 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_q13.qip b/sys/sys_q13.qip new file mode 100644 index 0000000..760991a --- /dev/null +++ b/sys/sys_q13.qip @@ -0,0 +1,30 @@ +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 3ff1e17..37720b2 100644 --- a/sys/sys_top.sdc +++ b/sys/sys_top.sdc @@ -3,44 +3,29 @@ create_clock -period "50.0 MHz" [get_ports FPGA_CLK1_50] create_clock -period "50.0 MHz" [get_ports FPGA_CLK2_50] create_clock -period "50.0 MHz" [get_ports FPGA_CLK3_50] create_clock -period "100.0 MHz" [get_pins -compatibility_mode *|h2f_user0_clk] +create_clock -period 10.0 [get_pins -compatibility_mode spi|sclk_out] -name spi_sck derive_pll_clocks -# Specify PLL-generated clock(s) -create_generated_clock -source [get_pins -compatibility_mode {*|pll|pll_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk}] \ - -name SDRAM_CLK [get_ports {SDRAM_CLK}] - create_generated_clock -source [get_pins -compatibility_mode {pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk}] \ -name HDMI_CLK [get_ports HDMI_TX_CLK] -create_generated_clock -source [get_pins { pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk}] \ - -name VID_CLK -divide_by 2 -duty_cycle 50 [get_nets {vip|output_inst|vid_clk}] - derive_clock_uncertainty - -# Set acceptable delays for SDRAM chip (See correspondent chip datasheet) -set_input_delay -max -clock SDRAM_CLK 6.4ns [get_ports SDRAM_DQ[*]] -set_input_delay -min -clock SDRAM_CLK 3.7ns [get_ports SDRAM_DQ[*]] - -set_multicycle_path -from [get_clocks {SDRAM_CLK}] \ - -to [get_clocks {*|pll|pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk}] \ - -setup 2 - -set_output_delay -max -clock SDRAM_CLK 1.6ns [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] -set_output_delay -min -clock SDRAM_CLK -0.9ns [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] - # 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 VID_CLK}] \ + -group [get_clocks { pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk}] \ -group [get_clocks { *|h2f_user0_clk}] \ -group [get_clocks { FPGA_CLK1_50 FPGA_CLK2_50 FPGA_CLK3_50}] set_output_delay -max -clock HDMI_CLK 2.0ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}] set_output_delay -min -clock HDMI_CLK -1.5ns [get_ports {HDMI_TX_D[*] HDMI_TX_DE HDMI_TX_HS HDMI_TX_VS}] +set_false_path -from {*} -to [get_registers {wcalc[*] hcalc[*]}] + + # Put constraints on input ports set_false_path -from [get_ports {KEY*}] -to * set_false_path -from [get_ports {BTN_*}] -to * diff --git a/sys/sys_top.v b/sys/sys_top.v index 76558c3..517189f 100644 --- a/sys/sys_top.v +++ b/sys/sys_top.v @@ -1,946 +1,988 @@ -//============================================================================ -// -// MiSTer hardware abstraction module -// (c)2017,2018 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 sys_top -( - /////////// CLOCK ////////// - input FPGA_CLK1_50, - 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, - - output HDMI_MCLK, - output HDMI_SCLK, - output HDMI_LRCLK, - output HDMI_I2S, - - output HDMI_TX_CLK, - output HDMI_TX_DE, - output [23:0] HDMI_TX_D, - output HDMI_TX_HS, - output HDMI_TX_VS, - - input HDMI_TX_INT, - - //////////// SDR /////////// - output [12:0] SDRAM_A, - inout [15:0] SDRAM_DQ, - output SDRAM_DQML, - output SDRAM_DQMH, - output SDRAM_nWE, - output SDRAM_nCAS, - output SDRAM_nRAS, - output SDRAM_nCS, - output [1:0] SDRAM_BA, - output SDRAM_CLK, - output SDRAM_CKE, - - //////////// I/O /////////// - output LED_USER, - output LED_HDD, - output LED_POWER, - input BTN_USER, - input BTN_OSD, - input BTN_RESET, - - //////////// SDIO /////////// - inout [3:0] SDIO_DAT, - inout SDIO_CMD, - output SDIO_CLK, - input SDIO_CD, - - ////////// MB KEY /////////// - input [1:0] KEY, - - ////////// MB SWITCH //////// - input [3:0] SW, - - ////////// MB LED /////////// - output [7:0] LED -); - - -assign SDIO_DAT[2:1] = 2'bZZ; - - -////////////////////////// LEDs /////////////////////////////////////// - -reg [7:0] led_overtake = 0; -reg [7:0] led_state = 0; - -wire led_p = led_power[1] ? ~led_power[0] : 1'b0; -wire led_d = led_disk[1] ? ~led_disk[0] : ~(led_disk[0] | gp_out[29]); -wire led_u = ~led_user; - -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; - -//LEDs on main board -assign LED = (led_overtake & led_state) | (~led_overtake & {3'b000, ~led_p, 1'b0, ~led_d, 1'b0, ~led_u}); - - -////////////////////////// Buttons /////////////////////////////////// -reg btn_user, btn_osd; -always @(posedge FPGA_CLK2_50) begin - integer div; - reg [7:0] deb_user; - reg [7:0] deb_osd; - - div <= div + 1'b1; - if(div > 100000) div <= 0; - - if(!div) begin - deb_user <= {deb_user[6:0], ~(BTN_USER & KEY[1])}; - if(&deb_user) btn_user <= 1; - if(!deb_user) btn_user <= 0; - - deb_osd <= {deb_osd[6:0], ~(BTN_OSD & 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 ///////////////////////////////////// - -// gp_in[31] = 0 - quick flag that FPGA is initialized (HPS reads 1 when FPGA is not in user mode) -// used to avoid lockups while JTAG loading -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 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 io_sdd = gp_outr[21]; // used only in ST core - -reg io_ack; -reg rack; -wire io_strobe = ~rack & io_clk; - -always @(posedge clk_sys) begin - if(~io_wait | io_strobe) begin - rack <= io_clk; - io_ack <= rack; - end -end - -reg [31:0] gp_outr; -always @(posedge clk_sys) begin - reg [31:0] gp_outd; - gp_outr <= gp_outd; - gp_outd <= gp_out; -end - -wire [7:0] core_type = 'hA4; // A4 - generic core. - -// HPS will not communicate to core if magic is different -wire [31:0] core_magic = {24'h5CA623, core_type}; - -cyclonev_hps_interface_mpu_general_purpose h2f_gp -( - .gp_in({~gp_out[31] ? core_magic : gp_in}), - .gp_out(gp_out) -); - - -reg [15:0] cfg; - -reg cfg_got = 0; -reg cfg_set = 0; -//wire [2:0] hdmi_res = cfg[10:8]; -wire dvi_mode = cfg[7]; -wire audio_96k = cfg[6]; -wire ypbpr_en = cfg[5]; -wire csync = cfg[3]; -`ifndef LITE -wire vga_scaler= cfg[2]; -`endif - -reg cfg_custom_t = 0; -reg [5:0] cfg_custom_p1; -reg [31:0] cfg_custom_p2; - -reg [4:0] vol_att = 0; - -reg vip_newcfg = 0; -always@(posedge clk_sys) begin - reg [7:0] cmd; - reg has_cmd; - reg old_strobe; - reg [7:0] cnt = 0; - - old_strobe <= io_strobe; - - if(~io_uio) has_cmd <= 0; - else - if(~old_strobe & io_strobe) begin - if(!has_cmd) begin - has_cmd <= 1; - cmd <= io_din[7:0]; - cnt <= 0; - end - else begin - if(cmd == 1) begin - cfg <= io_din; - cfg_set <= 1; - end - if(cmd == 'h20) begin - cfg_set <= 0; - cnt <= cnt + 1'd1; - if(cnt<8) begin - if(!cnt) vip_newcfg <= ~cfg_ready; - case(cnt) - 0: if(WIDTH != io_din[11:0]) begin WIDTH <= io_din[11:0]; vip_newcfg <= 1; end - 1: if(HFP != io_din[11:0]) begin HFP <= io_din[11:0]; vip_newcfg <= 1; end - 2: if(HS != io_din[11:0]) begin HS <= io_din[11:0]; vip_newcfg <= 1; end - 3: if(HBP != io_din[11:0]) begin HBP <= io_din[11:0]; vip_newcfg <= 1; end - 4: if(HEIGHT != io_din[11:0]) begin HEIGHT <= io_din[11:0]; vip_newcfg <= 1; end - 5: if(VFP != io_din[11:0]) begin VFP <= io_din[11:0]; vip_newcfg <= 1; end - 6: if(VS != io_din[11:0]) begin VS <= io_din[11:0]; vip_newcfg <= 1; end - 7: if(VBP != io_din[11:0]) begin VBP <= io_din[11:0]; vip_newcfg <= 1; end - endcase - if(cnt == 1) begin - cfg_custom_p1 <= 0; - cfg_custom_p2 <= 0; - cfg_custom_t <= ~cfg_custom_t; - end - end - else begin - if(cnt[1:0]==0) cfg_custom_p1 <= io_din[5:0]; - if(cnt[1:0]==1) cfg_custom_p2[15:0] <= io_din; - if(cnt[1:0]==2) begin - cfg_custom_p2[31:16] <= io_din; - cfg_custom_t <= ~cfg_custom_t; - cnt[1:0] <= 0; - end - end - 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]; - end - end -end - -always @(posedge clk_sys) begin - reg vsd, vsd2; - if(~cfg_ready || ~cfg_set) cfg_got <= cfg_set; - else begin - vsd <= HDMI_TX_VS; - vsd2 <= vsd; - if(~vsd2 & vsd) cfg_got <= cfg_set; - end -end - -/////////////////////////// RESET /////////////////////////////////// - -reg reset_req = 0; -always @(posedge FPGA_CLK2_50) begin - reg [1:0] resetd, resetd2; - reg old_reset; - - //latch the reset - old_reset <= reset; - if(~old_reset & reset) reset_req <= 1; - - //special combination to set/clear the reset - //preventing of accidental reset control - if(resetd==1) reset_req <= 1; - if(resetd==2 && resetd2==0) reset_req <= 0; - - resetd <= gp_out[31:30]; - resetd2 <= resetd; -end - -wire clk_ctl; - -///////////////////////// VIP version /////////////////////////////// - -wire iHdmiClk = ~HDMI_TX_CLK; // Internal HDMI clock, inverted in relation to external clock - -`ifndef LITE - -wire reset; -vip vip -( - //Reset/Clock - .reset_reset_req(reset_req | ~cfg_ready), - .reset_reset(reset), - .reset_reset_vip(0), - - //DE10-nano has no reset signal on GPIO, so core has to emulate cold reset button. - .reset_cold_req(~btn_reset), - .reset_warm_req(0), - - //control - .ctl_address(ctl_address), - .ctl_write(ctl_write), - .ctl_writedata(ctl_writedata), - .ctl_waitrequest(ctl_waitrequest), - .ctl_clock(clk_ctl), - .ctl_reset(ctl_reset), - - //64-bit DDR3 RAM access - .ramclk1_clk(ram_clk), - .ram1_address(ram_address), - .ram1_burstcount(ram_burstcount), - .ram1_waitrequest(ram_waitrequest), - .ram1_readdata(ram_readdata), - .ram1_readdatavalid(ram_readdatavalid), - .ram1_read(ram_read), - .ram1_writedata(ram_writedata), - .ram1_byteenable(ram_byteenable), - .ram1_write(ram_write), - - //Spare 64-bit DDR3 RAM access - //currently unused - //can combine with ram1 to make a wider RAM bus (although will increase the latency) - .ramclk2_clk(0), - .ram2_address(0), - .ram2_burstcount(0), - .ram2_waitrequest(), - .ram2_readdata(), - .ram2_readdatavalid(), - .ram2_read(0), - .ram2_writedata(0), - .ram2_byteenable(0), - .ram2_write(0), - - //Video input - .in_clk(clk_vid), - .in_data({r_out, g_out, b_out}), - .in_de(de), - .in_v_sync(vs), - .in_h_sync(hs), - .in_ce(ce_pix), - .in_f(0), - - //HDMI output - .hdmi_clk(iHdmiClk), - .hdmi_data(hdmi_data), - .hdmi_de(hdmi_de), - .hdmi_v_sync(HDMI_TX_VS), - .hdmi_h_sync(HDMI_TX_HS) -); - -wire [8:0] ctl_address; -wire ctl_write; -wire [31:0] ctl_writedata; -wire ctl_waitrequest; -wire ctl_reset; -wire [7:0] ARX, ARY; - -vip_config vip_config -( - .clk(clk_ctl), - .reset(ctl_reset), - - .ARX(ARX), - .ARY(ARY), - .CFG_SET(vip_newcfg & cfg_got), - - .WIDTH(WIDTH), - .HFP(HFP), - .HBP(HBP), - .HS(HS), - .HEIGHT(HEIGHT), - .VFP(VFP), - .VBP(VBP), - .VS(VS), - .VSET(VSET), - - .address(ctl_address), - .write(ctl_write), - .writedata(ctl_writedata), - .waitrequest(ctl_waitrequest) -); -`endif - - -///////////////////////// Lite version //////////////////////////////// - -`ifdef LITE - -wire [11:0] x; -wire [11:0] y; - -sync_vg #(.X_BITS(12), .Y_BITS(12)) sync_vg -( - .clk(iHdmiClk), - .reset(reset), - .v_total(HEIGHT+VFP+VBP+VS), - .v_fp(VFP), - .v_bp(VBP), - .v_sync(VS), - .h_total(WIDTH+HFP+HBP+HS), - .h_fp(HFP), - .h_bp(HBP), - .h_sync(HS), - .hv_offset(0), - .vde_out(vde), - .hde_out(hde), - .vs_out(vs_hdmi), - .v_count_out(), - .h_count_out(), - .x_out(x), - .y_out(y), - .hs_out(hs_hdmi) -); - -wire vde, hde; -wire vs_hdmi; -wire hs_hdmi; - -/* - -pattern_vg -#( - .B(8), // Bits per channel - .X_BITS(12), - .Y_BITS(12), - .FRACTIONAL_BITS(12) // Number of fractional bits for ramp pattern -) -pattern_vg -( - .reset(reset), - .clk_in(iHdmiClk), - .x(x), - .y(y), - .vn_in(vs_hdmi), - .hn_in(hs_hdmi), - .dn_in(vde & hde), - .r_in(0), - .g_in(0), - .b_in(0), - .vn_out(HDMI_TX_VS), - .hn_out(HDMI_TX_HS), - .den_out(HDMI_TX_DE), - .r_out(hdmi_data[23:16]), - .g_out(hdmi_data[15:8]), - .b_out(hdmi_data[7:0]), - .total_active_pix(WIDTH), - .total_active_lines(HEIGHT), - .pattern(4), - .ramp_step(20'h0333) -); -*/ - -wire reset; -sysmem_lite sysmem -( - //Reset/Clock - .reset_reset_req(reset_req), - .reset_reset(reset), - .ctl_clock(clk_ctl), - - //DE10-nano has no reset signal on GPIO, so core has to emulate cold reset button. - .reset_cold_req(~btn_reset), - .reset_warm_req(0), - - //64-bit DDR3 RAM access - .ramclk1_clk(ram_clk), - .ram1_address(ram_address), - .ram1_burstcount(ram_burstcount), - .ram1_waitrequest(ram_waitrequest), - .ram1_readdata(ram_readdata), - .ram1_readdatavalid(ram_readdatavalid), - .ram1_read(ram_read), - .ram1_writedata(ram_writedata), - .ram1_byteenable(ram_byteenable), - .ram1_write(ram_write), - - //Spare 64-bit DDR3 RAM access - //currently unused - //can combine with ram1 to make a wider RAM bus (although will increase the latency) - .ramclk2_clk(0), - .ram2_address(0), - .ram2_burstcount(0), - .ram2_waitrequest(), - .ram2_readdata(), - .ram2_readdatavalid(), - .ram2_read(0), - .ram2_writedata(0), - .ram2_byteenable(0), - .ram2_write(0), - - // HDMI frame buffer - .vbuf_clk(clk_ctl), - .vbuf_address(vbuf_address), - .vbuf_burstcount(vbuf_burstcount), - .vbuf_waitrequest(vbuf_waitrequest), - .vbuf_writedata(vbuf_writedata), - .vbuf_byteenable(vbuf_byteenable), - .vbuf_write(vbuf_write), - .vbuf_readdata(vbuf_readdata), - .vbuf_readdatavalid(vbuf_readdatavalid), - .vbuf_read(vbuf_read) -); - -wire [27:0] vbuf_address; -wire [7:0] vbuf_burstcount; -wire vbuf_waitrequest; -wire [127:0] vbuf_readdata; -wire vbuf_readdatavalid; -wire vbuf_read; -wire [127:0] vbuf_writedata; -wire [15:0] vbuf_byteenable; -wire vbuf_write; - -assign HDMI_TX_VS = vs_hdmi; -assign HDMI_TX_HS = hs_hdmi; - -hdmi_lite hdmi_lite -( - .reset(reset), - - .clk_video(clk_vid), - .ce_pixel(ce_pix), - .video_vs(vs), - .video_de(de), - .video_d({r_out,g_out,b_out}), - - .clk_hdmi(HDMI_TX_CLK), - .hdmi_hde(hde), - .hdmi_vde(vde), - .hdmi_d(hdmi_data), - .hdmi_de(hdmi_de), - - .screen_w(WIDTH), - .screen_h(HEIGHT), - .quadbuf(1), - .scale_x(0), - .scale_y(0), - .scale_auto(1), - - .clk_vbuf(clk_ctl), - .vbuf_address(vbuf_address), - .vbuf_burstcount(vbuf_burstcount), - .vbuf_waitrequest(vbuf_waitrequest), - .vbuf_writedata(vbuf_writedata), - .vbuf_byteenable(vbuf_byteenable), - .vbuf_write(vbuf_write), - .vbuf_readdata(vbuf_readdata), - .vbuf_readdatavalid(vbuf_readdatavalid), - .vbuf_read(vbuf_read) -); - -`endif - - -///////////////////////// HDMI output ///////////////////////////////// - -pll_hdmi pll_hdmi -( - .refclk(FPGA_CLK1_50), - .rst(reset_req), - .reconfig_to_pll(reconfig_to_pll), - .reconfig_from_pll(reconfig_from_pll), - .outclk_0(HDMI_TX_CLK) -); - -//1920x1080@60 PCLK=148.5MHz CEA -reg [11:0] WIDTH = 1920; -reg [11:0] HFP = 88; -reg [11:0] HS = 48; -reg [11:0] HBP = 148; -reg [11:0] HEIGHT = 1080; -reg [11:0] VFP = 4; -reg [11:0] VS = 5; -reg [11:0] VBP = 36; -reg [11:0] VSET = 0; - -wire [63:0] reconfig_to_pll; -wire [63:0] reconfig_from_pll; -wire cfg_waitrequest; -reg cfg_write; -reg [5:0] cfg_address; -reg [31:0] cfg_data; - -pll_hdmi_cfg pll_hdmi_cfg -( - .mgmt_clk(FPGA_CLK1_50), - .mgmt_reset(reset_req), - .mgmt_waitrequest(cfg_waitrequest), - .mgmt_read(0), - .mgmt_readdata(), - .mgmt_write(cfg_write), - .mgmt_address(cfg_address), - .mgmt_writedata(cfg_data), - .reconfig_to_pll(reconfig_to_pll), - .reconfig_from_pll(reconfig_from_pll) -); - -reg cfg_ready = 0; - -always @(posedge FPGA_CLK1_50) begin - reg gotd = 0, gotd2 = 0; - reg custd = 0, custd2 = 0; - reg old_wait = 0; - - gotd <= cfg_got; - gotd2 <= gotd; - - cfg_write <= 0; - - custd <= cfg_custom_t; - custd2 <= custd; - if(custd2 != custd & ~gotd) begin - cfg_address <= cfg_custom_p1; - cfg_data <= cfg_custom_p2; - cfg_write <= 1; - end - - if(~gotd2 & gotd) begin - cfg_address <= 2; - cfg_data <= 0; - cfg_write <= 1; - end - - old_wait <= cfg_waitrequest; - if(old_wait & ~cfg_waitrequest & gotd) cfg_ready <= 1; -end - -hdmi_config hdmi_config -( - .iCLK(FPGA_CLK1_50), - .iRST_N(cfg_ready & ~HDMI_TX_INT), - - .I2C_SCL(HDMI_I2C_SCL), - .I2C_SDA(HDMI_I2C_SDA), - - .dvi_mode(dvi_mode), - .audio_96k(audio_96k) -); - -wire [23:0] hdmi_data; -wire hdmi_de; - -osd hdmi_osd -( - .clk_sys(clk_sys), - - .io_osd(io_osd), - .io_strobe(io_strobe), - .io_din(io_din), - - .clk_video(iHdmiClk), - .din(hdmi_data), - .dout(HDMI_TX_D), - .de_in(hdmi_de), - .de_out(HDMI_TX_DE) -); - -assign HDMI_MCLK = 0; -i2s i2s -( - .reset(~cfg_ready), - .clk_sys(FPGA_CLK3_50), - .half_rate(~audio_96k), - - .sclk(HDMI_SCLK), - .lrclk(HDMI_LRCLK), - .sdata(HDMI_I2S), - - //Could inverse the MSB but it will shift 0 level to -MAX level - .left_chan (audio_l >> !audio_s), - .right_chan(audio_r >> !audio_s) -); - - -///////////////////////// VGA output ////////////////////////////////// - -wire [23:0] vga_q; -osd vga_osd -( - .clk_sys(clk_sys), - - .io_osd(io_osd), - .io_strobe(io_strobe), - .io_din(io_din), - - .clk_video(clk_vid), - .din(de ? {r_out, g_out, b_out} : 24'd0), - .dout(vga_q), - .de_in(de) -); - -wire [23:0] vga_o; - -vga_out vga_out -( - .ypbpr_full(1), - .ypbpr_en(ypbpr_en), - .dout(vga_o), -`ifdef LITE - .din(vga_q) -`else - .din(vga_scaler ? HDMI_TX_D : vga_q) -`endif -); - -`ifdef LITE - wire vs1 = vs; - wire hs1 = hs; -`else - wire vs1 = vga_scaler ? HDMI_TX_VS : vs; - wire hs1 = vga_scaler ? HDMI_TX_HS : hs; -`endif - -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]; - - -///////////////////////// Audio output //////////////////////////////// - -wire al, ar, aspdif; - -sigma_delta_dac #(15) dac_l -( - .CLK(FPGA_CLK3_50), - .RESET(reset), - .DACin({audio_l[15] ^ audio_s, audio_l[14:0]}), - .DACout(al) -); - -sigma_delta_dac #(15) dac_r -( - .CLK(FPGA_CLK3_50), - .RESET(reset), - .DACin({audio_r[15] ^ audio_s, audio_r[14:0]}), - .DACout(ar) -); - -spdif toslink -( - .clk_i(FPGA_CLK3_50), - - .rst_i(reset), - .half_rate(0), - - .audio_l(audio_l >> !audio_s), - .audio_r(audio_r >> !audio_s), - - .spdif_o(aspdif) -); - -assign AUDIO_SPDIF = SW[0] ? HDMI_LRCLK : aspdif; -assign AUDIO_R = SW[0] ? HDMI_I2S : ar; -assign AUDIO_L = SW[0] ? HDMI_SCLK : al; - -reg [15:0] audio_l; -reg [15:0] audio_r; - -always @(posedge FPGA_CLK3_50) begin - reg signed [15:0] al; - reg signed [15:0] ar; - - case({audio_s,audio_mix}) - 'b000: al <= audio_ls; - 'b001: al <= audio_ls - (audio_ls >> 3) + (audio_rs >> 3); - 'b010: al <= audio_ls - (audio_ls >> 2) + (audio_rs >> 2); - 'b011: al <= (audio_ls >> 1) + (audio_rs >> 1); - 'b100: al <= audio_ls; - 'b101: al <= audio_ls - (audio_ls >>> 3) + (audio_rs >>> 3); - 'b110: al <= audio_ls - (audio_ls >>> 2) + (audio_rs >>> 2); - 'b111: al <= (audio_ls >>> 1) + (audio_rs >>> 1); - endcase - - case({audio_s,audio_mix}) - 'b000: ar <= audio_rs; - 'b001: ar <= audio_rs - (audio_rs >> 3) + (audio_ls >> 3); - 'b010: ar <= audio_rs - (audio_rs >> 2) + (audio_ls >> 2); - 'b011: ar <= (audio_rs >> 1) + (audio_ls >> 1); - 'b100: ar <= audio_rs; - 'b101: ar <= audio_rs - (audio_rs >>> 3) + (audio_ls >>> 3); - 'b110: ar <= audio_rs - (audio_rs >>> 2) + (audio_ls >>> 2); - 'b111: ar <= (audio_rs >>> 1) + (audio_ls >>> 1); - endcase - - if(vol_att[4]) begin - audio_l <= 0; - audio_r <= 0; - end - else - if(audio_s) begin - audio_l <= al >>> vol_att[3:0]; - audio_r <= ar >>> vol_att[3:0]; - end - else - begin - audio_l <= al >> vol_att[3:0]; - audio_r <= ar >> vol_att[3:0]; - end -end - -/////////////////// User module connection //////////////////////////// - -wire signed [15:0] audio_ls, audio_rs; -wire audio_s; -wire [1:0] audio_mix; -wire [7:0] r_out, g_out, b_out; -wire vs, hs, de; -wire clk_sys, clk_vid, ce_pix; - -wire ram_clk; -wire [28:0] ram_address; -wire [7:0] ram_burstcount; -wire ram_waitrequest; -wire [63:0] ram_readdata; -wire ram_readdatavalid; -wire ram_read; -wire [63:0] ram_writedata; -wire [7:0] ram_byteenable; -wire ram_write; - -wire led_user; -wire [1:0] led_power; -wire [1:0] led_disk; - -wire vs_emu, hs_emu; -sync_fix sync_v(FPGA_CLK3_50, vs_emu, vs); -sync_fix sync_h(FPGA_CLK3_50, hs_emu, hs); - -emu emu -( - .CLK_50M(FPGA_CLK3_50), - .RESET(reset), - .HPS_BUS({HDMI_TX_VS, clk_ctl, 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), - - .VGA_R(r_out), - .VGA_G(g_out), - .VGA_B(b_out), - .VGA_HS(hs_emu), - .VGA_VS(vs_emu), - .VGA_DE(de), - - .LED_USER(led_user), - .LED_POWER(led_power), - .LED_DISK(led_disk), - -`ifndef LITE - .VIDEO_ARX(ARX), - .VIDEO_ARY(ARY), -`endif - - .AUDIO_L(audio_ls), - .AUDIO_R(audio_rs), - .AUDIO_S(audio_s), - .AUDIO_MIX(audio_mix), - .TAPE_IN(0), - - // SCK -> CLK - // MOSI -> CMD - // MISO <- DAT0 - // Z -> DAT1 - // Z -> DAT2 - // CS -> DAT3 - .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), - - .DDRAM_CLK(ram_clk), - .DDRAM_ADDR(ram_address), - .DDRAM_BURSTCNT(ram_burstcount), - .DDRAM_BUSY(ram_waitrequest), - .DDRAM_DOUT(ram_readdata), - .DDRAM_DOUT_READY(ram_readdatavalid), - .DDRAM_RD(ram_read), - .DDRAM_DIN(ram_writedata), - .DDRAM_BE(ram_byteenable), - .DDRAM_WE(ram_write), - - .SDRAM_DQ(SDRAM_DQ), - .SDRAM_A(SDRAM_A), - .SDRAM_DQML(SDRAM_DQML), - .SDRAM_DQMH(SDRAM_DQMH), - .SDRAM_BA(SDRAM_BA), - .SDRAM_nCS(SDRAM_nCS), - .SDRAM_nWE(SDRAM_nWE), - .SDRAM_nRAS(SDRAM_nRAS), - .SDRAM_nCAS(SDRAM_nCAS), - .SDRAM_CLK(SDRAM_CLK), - .SDRAM_CKE(SDRAM_CKE) -); - -endmodule - -module sync_fix -( - input clk, - - input sync_in, - output sync_out -); - -assign sync_out = sync_in ^ pol; - -reg pol; -always @(posedge clk) begin - integer pos = 0, neg = 0, cnt = 0; - reg s1,s2; - - s1 <= sync_in; - s2 <= s1; - - if(~s2 & s1) neg <= cnt; - if(s2 & ~s1) pos <= cnt; - - cnt <= cnt + 1; - if(s2 != s1) cnt <= 0; - - pol <= pos > neg; -end - -endmodule +//============================================================================ +// +// MiSTer hardware abstraction module +// (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 +// 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 sys_top +( + /////////// CLOCK ////////// + input FPGA_CLK1_50, + 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, + + output HDMI_MCLK, + output HDMI_SCLK, + output HDMI_LRCLK, + output HDMI_I2S, + + output HDMI_TX_CLK, + output HDMI_TX_DE, + output [23:0] HDMI_TX_D, + output HDMI_TX_HS, + output HDMI_TX_VS, + + input HDMI_TX_INT, + + //////////// SDR /////////// + output [12:0] SDRAM_A, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nWE, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nCS, + output [1:0] SDRAM_BA, + output SDRAM_CLK, + output SDRAM_CKE, + + //////////// I/O /////////// + output LED_USER, + output LED_HDD, + output LED_POWER, + input BTN_USER, + input BTN_OSD, + input BTN_RESET, + + //////////// SDIO /////////// + inout [3:0] SDIO_DAT, + inout SDIO_CMD, + output SDIO_CLK, + input SDIO_CD, + + ////////// MB KEY /////////// + input [1:0] KEY, + + ////////// MB SWITCH //////// + input [3:0] SW, + + ////////// MB LED /////////// + output [7:0] LED, + + ///////// USER IO /////////// + inout [5:0] USER_IO +); + + +assign SDIO_DAT[2:1] = 2'bZZ; + + +////////////////////////// LEDs /////////////////////////////////////// + +reg [7:0] led_overtake = 0; +reg [7:0] led_state = 0; + +wire led_p = led_power[1] ? ~led_power[0] : 1'b0; +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; + +//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}); + + +////////////////////////// Buttons /////////////////////////////////// +reg btn_user, btn_osd; +always @(posedge FPGA_CLK2_50) begin + integer div; + reg [7:0] deb_user; + reg [7:0] deb_osd; + + div <= div + 1'b1; + if(div > 100000) div <= 0; + + if(!div) begin + deb_user <= {deb_user[6:0], ~(BTN_USER & KEY[1])}; + if(&deb_user) btn_user <= 1; + if(!deb_user) btn_user <= 0; + + deb_osd <= {deb_osd[6:0], ~(BTN_OSD & 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 ///////////////////////////////////// + +// gp_in[31] = 0 - quick flag that FPGA is initialized (HPS reads 1 when FPGA is not in user mode) +// used to avoid lockups while JTAG loading +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 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 io_sdd = gp_outr[21]; // used only in ST core + +reg io_ack; +reg rack; +wire io_strobe = ~rack & io_clk; + +always @(posedge clk_sys) begin + if(~io_wait | io_strobe) begin + rack <= io_clk; + io_ack <= rack; + end +end + +reg [31:0] gp_outr; +always @(posedge clk_sys) begin + reg [31:0] gp_outd; + gp_outr <= gp_outd; + gp_outd <= gp_out; +end + +wire [7:0] core_type = 'hA4; // A4 - generic core. + +// HPS will not communicate to core if magic is different +wire [31:0] core_magic = {24'h5CA623, core_type}; + +cyclonev_hps_interface_mpu_general_purpose h2f_gp +( + .gp_in({~gp_out[31] ? core_magic : gp_in}), + .gp_out(gp_out) +); + + +reg [15:0] cfg; + +reg cfg_got = 0; +reg cfg_set = 0; +//wire [2:0] hdmi_res = cfg[10: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]; + +reg cfg_custom_t = 0; +reg [5:0] cfg_custom_p1; +reg [31:0] cfg_custom_p2; + +reg [4:0] vol_att = 0; + +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; + +always@(posedge clk_sys) begin + reg [7:0] cmd; + reg has_cmd; + reg old_strobe; + reg [7:0] cnt = 0; + + old_strobe <= io_strobe; + coef_wr <= 0; + + if(~io_uio) begin + has_cmd <= 0; + end + else + if(~old_strobe & io_strobe) begin + if(!has_cmd) begin + has_cmd <= 1; + cmd <= io_din[7:0]; + cnt <= 0; + end + else begin + if(cmd == 1) begin + cfg <= io_din; + cfg_set <= 1; + end + if(cmd == 'h20) 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 + endcase + if(cnt == 1) begin + cfg_custom_p1 <= 0; + cfg_custom_p2 <= 0; + cfg_custom_t <= ~cfg_custom_t; + end + end + else begin + if(cnt[1:0]==0) cfg_custom_p1 <= io_din[5:0]; + if(cnt[1:0]==1) cfg_custom_p2[15:0] <= io_din; + if(cnt[1:0]==2) begin + cfg_custom_p2[31:16] <= io_din; + cfg_custom_t <= ~cfg_custom_t; + cnt[2:0] <= 3'b100; + end + if(cnt == 8) lowlat <= io_din[15]; + end + 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]; + if(cmd == 'h2A) {coef_wr,coef_addr,coef_data} <= {1'b1,io_din}; + if(cmd == 'h2B) scaler_flt <= io_din[2:0]; + end + end +end + +always @(posedge clk_sys) begin + reg vsd, vsd2; + if(~cfg_ready || ~cfg_set) cfg_got <= cfg_set; + else begin + vsd <= HDMI_TX_VS; + vsd2 <= vsd; + if(~vsd2 & vsd) cfg_got <= cfg_set; + end +end + +cyclonev_hps_interface_peripheral_uart uart +( + .ri(0), + .dsr(uart_dsr), + .dcd(uart_dsr), + .dtr(uart_dtr), + + .cts(uart_cts), + .rts(uart_rts), + .rxd(uart_rxd), + .txd(uart_txd) +); + +wire aspi_sck,aspi_mosi,aspi_ss; +cyclonev_hps_interface_peripheral_spi_master spi +( + .sclk_out(aspi_sck), + .txd(aspi_mosi), // mosi + .rxd(1), // miso + + .ss_0_n(aspi_ss), + .ss_in_n(1) +); + + +/////////////////////////// RESET /////////////////////////////////// + +reg reset_req = 0; +always @(posedge FPGA_CLK2_50) begin + reg [1:0] resetd, resetd2; + reg old_reset; + + //latch the reset + old_reset <= reset; + if(~old_reset & reset) reset_req <= 1; + + //special combination to set/clear the reset + //preventing of accidental reset control + if(resetd==1) reset_req <= 1; + if(resetd==2 && resetd2==0) reset_req <= 0; + + resetd <= gp_out[31:30]; + resetd2 <= resetd; +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; + +//////////////////// SYSTEM MEMORY & SCALER ///////////////////////// + +wire reset; +sysmem_lite sysmem +( + //Reset/Clock + .reset_core_req(reset_req), + .reset_out(reset), + .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), + + //64-bit DDR3 RAM access + .ram1_clk(ram_clk), + .ram1_address(ram_address), + .ram1_burstcount(ram_burstcount), + .ram1_waitrequest(ram_waitrequest), + .ram1_readdata(ram_readdata), + .ram1_readdatavalid(ram_readdatavalid), + .ram1_read(ram_read), + .ram1_writedata(ram_writedata), + .ram1_byteenable(ram_byteenable), + .ram1_write(ram_write), + + //64-bit DDR3 RAM access + .ram2_clk(clk_audio), + .ram2_address(aram_address), + .ram2_burstcount(aram_burstcount), + .ram2_waitrequest(aram_waitrequest), + .ram2_readdata(aram_readdata), + .ram2_readdatavalid(aram_readdatavalid), + .ram2_read(aram_read), + .ram2_writedata(0), + .ram2_byteenable(8'hFF), + .ram2_write(0), + + //128-bit DDR3 RAM access + // HDMI frame buffer + .vbuf_clk(clk_100m), + .vbuf_address(vbuf_address), + .vbuf_burstcount(vbuf_burstcount), + .vbuf_waitrequest(vbuf_waitrequest), + .vbuf_writedata(vbuf_writedata), + .vbuf_byteenable(vbuf_byteenable), + .vbuf_write(vbuf_write), + .vbuf_readdata(vbuf_readdata), + .vbuf_readdatavalid(vbuf_readdatavalid), + .vbuf_read(vbuf_read) +); + +wire [27:0] vbuf_address; +wire [7:0] vbuf_burstcount; +wire vbuf_waitrequest; +wire [127:0] vbuf_readdata; +wire vbuf_readdatavalid; +wire vbuf_read; +wire [127:0] vbuf_writedata; +wire [15:0] vbuf_byteenable; +wire vbuf_write; + +ascal +#( + .RAMBASE(32'h20000000), + .N_DW(128), + .N_AW(28) +) +ascal +( + .reset_na (~reset_req), + .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), + + .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), + + .mode ({~lowlat,|scaler_flt,2'b00}), + .poly_clk (clk_sys), + .poly_a (coef_addr), + .poly_dw (coef_data), + .poly_wr (coef_wr), + + .avl_clk (clk_100m), + .avl_waitrequest (vbuf_waitrequest), + .avl_readdata (vbuf_readdata), + .avl_readdatavalid(vbuf_readdatavalid), + .avl_burstcount (vbuf_burstcount), + .avl_writedata (vbuf_writedata), + .avl_address (vbuf_address), + .avl_write (vbuf_write), + .avl_read (vbuf_read), + .avl_byteenable (vbuf_byteenable) +); + +reg [11:0] hmin; +reg [11:0] hmax; +reg [11:0] vmin; +reg [11:0] vmax; + +always @(posedge clk_vid) begin + reg [31:0] wcalc; + reg [31:0] hcalc; + reg [2:0] state; + reg [11:0] videow; + reg [11:0] videoh; + + state <= state + 1'd1; + case(state) + 0: begin + wcalc <= VSET ? (VSET*ARX)/ARY : (HEIGHT*ARX)/ARY; + hcalc <= (WIDTH*ARY)/ARX; + end + 6: begin + videow <= (!VSET && (wcalc > WIDTH)) ? WIDTH : wcalc[11:0]; + videoh <= VSET ? VSET : (hcalc > HEIGHT) ? HEIGHT : hcalc[11:0]; + end + 7: begin + hmin <= ((WIDTH - videow)>>1); + hmax <= ((WIDTH - videow)>>1) + videow - 1'd1; + vmin <= ((HEIGHT - videoh)>>1); + vmax <= ((HEIGHT - videoh)>>1) + videoh - 1'd1; + end + endcase +end + +wire [15:0] lltune; + +pll_hdmi_adj pll_hdmi_adj +( + .clk(FPGA_CLK1_50), + .reset_na(~reset_req), + + .llena(lowlat), + .lltune(lltune), + .locked(led_locked), + .i_waitrequest(adj_waitrequest), + .i_write(adj_write), + .i_address(adj_address), + .i_writedata(adj_data), + .o_waitrequest(cfg_waitrequest), + .o_write(cfg_write), + .o_address(cfg_address), + .o_writedata(cfg_data) +); + + +///////////////////////// HDMI output ///////////////////////////////// + +pll_hdmi pll_hdmi +( + .refclk(FPGA_CLK1_50), + .rst(reset_req), + .reconfig_to_pll(reconfig_to_pll), + .reconfig_from_pll(reconfig_from_pll), + .outclk_0(HDMI_TX_CLK) +); + +//1920x1080@60 PCLK=148.5MHz CEA +reg [11:0] WIDTH = 1920; +reg [11:0] HFP = 88; +reg [11:0] HS = 48; +reg [11:0] HBP = 148; +reg [11:0] HEIGHT = 1080; +reg [11:0] VFP = 4; +reg [11:0] VS = 5; +reg [11:0] VBP = 36; + +wire [63:0] reconfig_to_pll; +wire [63:0] reconfig_from_pll; +wire cfg_waitrequest,adj_waitrequest; +wire cfg_write; +wire [5:0] cfg_address; +wire [31:0] cfg_data; +reg adj_write; +reg [5:0] adj_address; +reg [31:0] adj_data; + +pll_hdmi_cfg pll_hdmi_cfg +( + .mgmt_clk(FPGA_CLK1_50), + .mgmt_reset(reset_req), + .mgmt_waitrequest(cfg_waitrequest), + .mgmt_read(0), + .mgmt_readdata(), + .mgmt_write(cfg_write), + .mgmt_address(cfg_address), + .mgmt_writedata(cfg_data), + .reconfig_to_pll(reconfig_to_pll), + .reconfig_from_pll(reconfig_from_pll) +); + +reg cfg_ready = 0; + +always @(posedge FPGA_CLK1_50) begin + reg gotd = 0, gotd2 = 0; + reg custd = 0, custd2 = 0; + reg old_wait = 0; + + gotd <= cfg_got; + gotd2 <= gotd; + + adj_write <= 0; + + custd <= cfg_custom_t; + custd2 <= custd; + if(custd2 != custd & ~gotd) begin + adj_address <= cfg_custom_p1; + adj_data <= cfg_custom_p2; + adj_write <= 1; + end + + if(~gotd2 & gotd) begin + adj_address <= 2; + adj_data <= 0; + adj_write <= 1; + end + + old_wait <= adj_waitrequest; + if(old_wait & ~adj_waitrequest & gotd) cfg_ready <= 1; +end + +hdmi_config hdmi_config +( + .iCLK(FPGA_CLK1_50), + .iRST_N(cfg_ready & ~HDMI_TX_INT), + + .I2C_SCL(HDMI_I2C_SCL), + .I2C_SDA(HDMI_I2C_SDA), + + .dvi_mode(dvi_mode), + .audio_96k(audio_96k) +); + +wire [23:0] hdmi_data; +wire [23:0] hdmi_data_sl; +wire hdmi_de; + +scanlines #(1) HDMI_scanlines +( + .clk(clk_hdmi), + + .scanlines(scanlines), + .din(hdmi_data), + .dout(hdmi_data_sl), + .hs(HDMI_TX_HS), + .vs(HDMI_TX_VS) +); + +osd hdmi_osd +( + .clk_sys(clk_sys), + + .io_osd(io_osd), + .io_strobe(io_strobe), + .io_din(io_din), + + .clk_video(clk_hdmi), + .din(hdmi_data_sl), + .dout(HDMI_TX_D), + .de_in(hdmi_de), + .de_out(HDMI_TX_DE), + + .osd_status(osd_status) +); + +///////////////////////// VGA output ////////////////////////////////// + +wire [23:0] vga_data_sl; + +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) +); + +osd vga_osd +( + .clk_sys(clk_sys), + + .io_osd(io_osd), + .io_strobe(io_strobe), + .io_din(io_din), + + .clk_video(clk_vid), + .din(vga_data_sl), + .dout(vga_q), + .de_in(de) +); + +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) +); + +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]; + + +///////////////////////// 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 HDMI_MCLK = 0; + +wire [15:0] audio_l, audio_l_pre; +aud_mix_top audmix_l +( + .clk(clk_audio), + .att(vol_att), + .mix(audio_mix), + .is_signed(audio_s), + + .core_audio(audio_ls), + .pre_in(audio_r_pre), + .linux_audio(alsa_l), + + .pre_out(audio_l_pre), + .out(audio_l) +); + +wire [15:0] audio_r, audio_r_pre; +aud_mix_top audmix_r +( + .clk(clk_audio), + .att(vol_att), + .mix(audio_mix), + .is_signed(audio_s), + + .core_audio(audio_rs), + .pre_in(audio_l_pre), + .linux_audio(alsa_r), + + .pre_out(audio_r_pre), + .out(audio_r) +); + +wire anl,anr,spdif; +audio_out audio_out +( + .reset(reset), + .clk(clk_audio), + .sample_rate(audio_96k), + .left_in(audio_l), + .right_in(audio_r), + .i2s_bclk(HDMI_SCLK), + .i2s_lrclk(HDMI_LRCLK), + .i2s_data(HDMI_I2S), + .spdif(spdif), + .dac_l(anl), + .dac_r(anr) +); + +wire [28:0] aram_address; +wire [7:0] aram_burstcount; +wire aram_waitrequest; +wire [63:0] aram_readdata; +wire aram_readdatavalid; +wire aram_read; + +wire [15:0] alsa_l, alsa_r; + +alsa alsa +( + .reset(reset), + + .ram_clk(clk_audio), + .ram_address(aram_address), + .ram_burstcount(aram_burstcount), + .ram_waitrequest(aram_waitrequest), + .ram_readdata(aram_readdata), + .ram_readdatavalid(aram_readdatavalid), + .ram_read(aram_read), + + .spi_ss(aspi_ss), + .spi_sck(aspi_sck), + .spi_mosi(aspi_mosi), + + .pcm_l(alsa_l), + .pcm_r(alsa_r) +); + + +//////////////// User I/O (USB 3.0 connector) ///////////////////////// + +assign USER_IO[0] = !user_out[0] ? 1'b0 : 1'bZ; +assign USER_IO[1] = !user_out[1] ? 1'b0 : 1'bZ; +assign USER_IO[2] = !(SW[1] ? HDMI_I2S : user_out[2]) ? 1'b0 : 1'bZ; +assign USER_IO[3] = !user_out[3] ? 1'b0 : 1'bZ; +assign USER_IO[4] = !(SW[1] ? HDMI_SCLK : user_out[4]) ? 1'b0 : 1'bZ; +assign USER_IO[5] = !(SW[1] ? HDMI_LRCLK : user_out[5]) ? 1'b0 : 1'bZ; + +assign user_in[0] = USER_IO[0]; +assign user_in[1] = USER_IO[1]; +assign user_in[2] = SW[1] | USER_IO[2]; +assign user_in[3] = USER_IO[3]; +assign user_in[4] = SW[1] | USER_IO[4]; +assign user_in[5] = SW[1] | USER_IO[5]; + + +/////////////////// User module connection //////////////////////////// + +wire [15:0] audio_ls, audio_rs; +wire audio_s; +wire [1:0] audio_mix; +wire [7:0] r_out, g_out, b_out; +wire vs, hs, de, f1; +wire [1:0] scanlines; +wire clk_sys, clk_vid, ce_pix; + +wire ram_clk; +wire [28:0] ram_address; +wire [7:0] ram_burstcount; +wire ram_waitrequest; +wire [63:0] ram_readdata; +wire ram_readdatavalid; +wire ram_read; +wire [63:0] ram_writedata; +wire [7:0] ram_byteenable; +wire ram_write; + +wire led_user; +wire [1:0] led_power; +wire [1:0] led_disk; + +wire vs_emu, hs_emu; +sync_fix sync_v(clk_vid, vs_emu, vs); +sync_fix sync_h(clk_vid, hs_emu, hs); + +wire uart_dtr; +wire uart_dsr; +wire uart_cts; +wire uart_rts; +wire uart_rxd; +wire uart_txd; +wire osd_status; + +wire [5:0] user_out, user_in; + +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}), + + .CLK_VIDEO(clk_vid), + .CE_PIXEL(ce_pix), + + .VGA_R(r_out), + .VGA_G(g_out), + .VGA_B(b_out), + .VGA_HS(hs_emu), + .VGA_VS(vs_emu), + .VGA_DE(de), + .VGA_F1(f1), + .VGA_SL(scanlines), + + .LED_USER(led_user), + .LED_POWER(led_power), + .LED_DISK(led_disk), + + .VIDEO_ARX(ARX), + .VIDEO_ARY(ARY), + + .AUDIO_L(audio_ls), + .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), + + .DDRAM_CLK(ram_clk), + .DDRAM_ADDR(ram_address), + .DDRAM_BURSTCNT(ram_burstcount), + .DDRAM_BUSY(ram_waitrequest), + .DDRAM_DOUT(ram_readdata), + .DDRAM_DOUT_READY(ram_readdatavalid), + .DDRAM_RD(ram_read), + .DDRAM_DIN(ram_writedata), + .DDRAM_BE(ram_byteenable), + .DDRAM_WE(ram_write), + + .SDRAM_DQ(SDRAM_DQ), + .SDRAM_A(SDRAM_A), + .SDRAM_DQML(SDRAM_DQML), + .SDRAM_DQMH(SDRAM_DQMH), + .SDRAM_BA(SDRAM_BA), + .SDRAM_nCS(SDRAM_nCS), + .SDRAM_nWE(SDRAM_nWE), + .SDRAM_nRAS(SDRAM_nRAS), + .SDRAM_nCAS(SDRAM_nCAS), + .SDRAM_CLK(SDRAM_CLK), + .SDRAM_CKE(SDRAM_CKE), + + .UART_CTS(uart_rts), + .UART_RTS(uart_cts), + .UART_RXD(uart_txd), + .UART_TXD(uart_rxd), + .UART_DTR(uart_dsr), + .UART_DSR(uart_dtr), + + .USER_OUT(user_out), + .USER_IN(user_in), + + .OSD_STATUS(osd_status) +); + +endmodule + +///////////////////////////////////////////////////////////////////// + +module sync_fix +( + input clk, + + input sync_in, + output sync_out +); + +assign sync_out = sync_in ^ pol; + +reg pol; +always @(posedge clk) begin + integer pos = 0, neg = 0, cnt = 0; + reg s1,s2; + + s1 <= sync_in; + s2 <= s1; + + if(~s2 & s1) neg <= cnt; + if(s2 & ~s1) pos <= cnt; + + cnt <= cnt + 1; + if(s2 != s1) cnt <= 0; + + pol <= pos > neg; +end + +endmodule + +///////////////////////////////////////////////////////////////////// + +module aud_mix_top +( + input clk, + + input [4:0] att, + input [1:0] mix, + input is_signed, + + input [15:0] core_audio, + input [15:0] linux_audio, + input [15:0] pre_in, + + output reg [15:0] pre_out, + output reg [15:0] out +); + +reg [15:0] ca; +always @(posedge clk) begin + reg [15:0] d1,d2,d3; + + d1 <= core_audio; d2<=d1; d3<=d2; + if(d2 == d3) ca <= d2; +end + +always @(posedge clk) begin + reg signed [16:0] a1, a2, a3, a4; + + a1 <= is_signed ? {ca[15],ca} : {2'b00,ca[15:1]}; + a2 <= a1 + {linux_audio[15],linux_audio}; + + pre_out <= a2[16:1]; + + case(mix) + 0: a3 <= a2; + 1: a3 <= $signed(a2) - $signed(a2[16:3]) + $signed(pre_in[15:2]); + 2: a3 <= $signed(a2) - $signed(a2[16:2]) + $signed(pre_in[15:1]); + 3: a3 <= {a2[16],a2[16:1]} + {pre_in[15],pre_in}; + endcase + + if(att[4]) a4 <= 0; + else a4 <= a3 >>> att[3:0]; + + //clamping + out <= ^a4[16:15] ? {a4[16],{15{a4[15]}}} : a4[15:0]; +end + +endmodule diff --git a/sys/sysmem.sv b/sys/sysmem.sv index 0f60f65..c90395e 100644 --- a/sys/sysmem.sv +++ b/sys/sysmem.sv @@ -1,531 +1,429 @@ -`timescale 1 ps / 1 ps -module sysmem_lite -( - input ramclk1_clk, // ramclk1.clk - input [28:0] ram1_address, // ram1.address - input [7:0] ram1_burstcount, // .burstcount - output ram1_waitrequest, // .waitrequest - output [63:0] ram1_readdata, // .readdata - output ram1_readdatavalid, // .readdatavalid - input ram1_read, // .read - input [63:0] ram1_writedata, // .writedata - input [7:0] ram1_byteenable, // .byteenable - input ram1_write, // .write - - input ramclk2_clk, // ramclk2.clk - input [28:0] ram2_address, // ram2.address - input [7:0] ram2_burstcount, // .burstcount - output ram2_waitrequest, // .waitrequest - output [63:0] ram2_readdata, // .readdata - output ram2_readdatavalid, // .readdatavalid - input ram2_read, // .read - input [63:0] ram2_writedata, // .writedata - input [7:0] ram2_byteenable, // .byteenable - input ram2_write, // .write - - output ctl_clock, - input reset_cold_req, // reset.cold_req - output reset_reset, // .reset - input reset_reset_req, // .reset_req - input reset_warm_req, // .warm_req - - input vbuf_clk, // vbuf.clk - input [27:0] vbuf_address, // vbuf.address - input [7:0] vbuf_burstcount, // .burstcount - output vbuf_waitrequest, // .waitrequest - output [127:0] vbuf_readdata, // .readdata - output vbuf_readdatavalid, // .readdatavalid - input vbuf_read, // .read - input [127:0] vbuf_writedata, // .writedata - input [15:0] vbuf_byteenable, // .byteenable - input vbuf_write // .write -); - -assign ctl_clock = clk_vip_clk; - -wire hps_h2f_reset_reset; // HPS:h2f_rst_n -> Reset_Source:reset_hps -wire reset_source_reset_cold_reset; // Reset_Source:reset_cold -> HPS:f2h_cold_rst_req_n -wire reset_source_reset_warm_reset; // Reset_Source:reset_warm -> HPS:f2h_warm_rst_req_n -wire clk_vip_clk; - -sysmem_HPS_fpga_interfaces fpga_interfaces ( - .f2h_cold_rst_req_n (~reset_source_reset_cold_reset), // f2h_cold_reset_req.reset_n - .f2h_warm_rst_req_n (~reset_source_reset_warm_reset), // f2h_warm_reset_req.reset_n - .h2f_user0_clk (clk_vip_clk), // h2f_user0_clock.clk - .h2f_rst_n (hps_h2f_reset_reset), // h2f_reset.reset_n - .f2h_sdram0_clk (vbuf_clk), // f2h_sdram0_clock.clk - .f2h_sdram0_ADDRESS (vbuf_address), // f2h_sdram0_data.address - .f2h_sdram0_BURSTCOUNT (vbuf_burstcount), // .burstcount - .f2h_sdram0_WAITREQUEST (vbuf_waitrequest), // .waitrequest - .f2h_sdram0_READDATA (vbuf_readdata), // .readdata - .f2h_sdram0_READDATAVALID (vbuf_readdatavalid), // .readdatavalid - .f2h_sdram0_READ (vbuf_read), // .read - .f2h_sdram0_WRITEDATA (vbuf_writedata), // .writedata - .f2h_sdram0_BYTEENABLE (vbuf_byteenable), // .byteenable - .f2h_sdram0_WRITE (vbuf_write), // .write - .f2h_sdram1_clk (ramclk1_clk), // f2h_sdram1_clock.clk - .f2h_sdram1_ADDRESS (ram1_address), // f2h_sdram1_data.address - .f2h_sdram1_BURSTCOUNT (ram1_burstcount), // .burstcount - .f2h_sdram1_WAITREQUEST (ram1_waitrequest), // .waitrequest - .f2h_sdram1_READDATA (ram1_readdata), // .readdata - .f2h_sdram1_READDATAVALID (ram1_readdatavalid), // .readdatavalid - .f2h_sdram1_READ (ram1_read), // .read - .f2h_sdram1_WRITEDATA (ram1_writedata), // .writedata - .f2h_sdram1_BYTEENABLE (ram1_byteenable), // .byteenable - .f2h_sdram1_WRITE (ram1_write), // .write - .f2h_sdram2_clk (ramclk2_clk), // f2h_sdram2_clock.clk - .f2h_sdram2_ADDRESS (ram2_address), // f2h_sdram2_data.address - .f2h_sdram2_BURSTCOUNT (ram2_burstcount), // .burstcount - .f2h_sdram2_WAITREQUEST (ram2_waitrequest), // .waitrequest - .f2h_sdram2_READDATA (ram2_readdata), // .readdata - .f2h_sdram2_READDATAVALID (ram2_readdatavalid), // .readdatavalid - .f2h_sdram2_READ (ram2_read), // .read - .f2h_sdram2_WRITEDATA (ram2_writedata), // .writedata - .f2h_sdram2_BYTEENABLE (ram2_byteenable), // .byteenable - .f2h_sdram2_WRITE (ram2_write) // .write -); - -reset_source reset_source ( - .clk (clk_vip_clk), // clock.clk - .reset_hps (~hps_h2f_reset_reset), // reset_hps.reset - .reset_sys (), // reset_sys.reset - .cold_req (reset_cold_req), // reset_ctl.cold_req - .reset (reset_reset), // .reset - .reset_req (reset_reset_req), // .reset_req - .reset_vip (0), // .reset_vip - .warm_req (reset_warm_req), // .warm_req - .reset_warm (reset_source_reset_warm_reset), // reset_warm.reset - .reset_cold (reset_source_reset_cold_reset) // reset_cold.reset -); - -endmodule - `timescale 1 ps / 1 ps -module sysmem -( - input ramclk1_clk, // ramclk1.clk - input [28:0] ram1_address, // ram1.address - input [7:0] ram1_burstcount, // .burstcount - output ram1_waitrequest, // .waitrequest - output [63:0] ram1_readdata, // .readdata - output ram1_readdatavalid, // .readdatavalid - input ram1_read, // .read - input [63:0] ram1_writedata, // .writedata - input [7:0] ram1_byteenable, // .byteenable - input ram1_write, // .write +module sysmem_lite +( + output clock, + output reset_out, - input ramclk2_clk, // ramclk2.clk - input [28:0] ram2_address, // ram2.address - input [7:0] ram2_burstcount, // .burstcount - output ram2_waitrequest, // .waitrequest - output [63:0] ram2_readdata, // .readdata - output ram2_readdatavalid, // .readdatavalid - input ram2_read, // .read - input [63:0] ram2_writedata, // .writedata - input [7:0] ram2_byteenable, // .byteenable - input ram2_write, // .write + input reset_hps_cold_req, + input reset_hps_warm_req, + input reset_core_req, - input reset_cold_req, // reset.cold_req - output reset_reset, // .reset - input reset_reset_req, // .reset_req - input reset_warm_req, // .warm_req + input ram1_clk, + input [28:0] ram1_address, + input [7:0] ram1_burstcount, + output ram1_waitrequest, + output [63:0] ram1_readdata, + output ram1_readdatavalid, + input ram1_read, + input [63:0] ram1_writedata, + input [7:0] ram1_byteenable, + input ram1_write, - input [27:0] ram_vip_address, // ram_vip.address - input [7:0] ram_vip_burstcount, // .burstcount - output ram_vip_waitrequest, // .waitrequest - output [127:0] ram_vip_readdata, // .readdata - output ram_vip_readdatavalid, // .readdatavalid - input ram_vip_read, // .read - input [127:0] ram_vip_writedata, // .writedata - input [15:0] ram_vip_byteenable, // .byteenable - input ram_vip_write, // .write + input ram2_clk, + input [28:0] ram2_address, + input [7:0] ram2_burstcount, + output ram2_waitrequest, + output [63:0] ram2_readdata, + output ram2_readdatavalid, + input ram2_read, + input [63:0] ram2_writedata, + input [7:0] ram2_byteenable, + input ram2_write, + + input vbuf_clk, + input [27:0] vbuf_address, + input [7:0] vbuf_burstcount, + output vbuf_waitrequest, + output [127:0] vbuf_readdata, + output vbuf_readdatavalid, + input vbuf_read, + input [127:0] vbuf_writedata, + input [15:0] vbuf_byteenable, + input vbuf_write +); + +assign reset_out = ~init_reset_n | ~hps_h2f_reset_n | reset_core_req; - output clk_vip_clk, // clk_vip.clk - output reset_vip_reset // reset_vip.reset -); - -wire hps_h2f_reset_reset; // HPS:h2f_rst_n -> Reset_Source:reset_hps -wire reset_source_reset_cold_reset; // Reset_Source:reset_cold -> HPS:f2h_cold_rst_req_n -wire reset_source_reset_warm_reset; // Reset_Source:reset_warm -> HPS:f2h_warm_rst_req_n - sysmem_HPS_fpga_interfaces fpga_interfaces ( - .f2h_cold_rst_req_n (~reset_source_reset_cold_reset), // f2h_cold_reset_req.reset_n - .f2h_warm_rst_req_n (~reset_source_reset_warm_reset), // f2h_warm_reset_req.reset_n - .h2f_user0_clk (clk_vip_clk), // h2f_user0_clock.clk - .h2f_rst_n (hps_h2f_reset_reset), // h2f_reset.reset_n - .f2h_sdram0_clk (clk_vip_clk), // f2h_sdram0_clock.clk - .f2h_sdram0_ADDRESS (ram_vip_address), // f2h_sdram0_data.address - .f2h_sdram0_BURSTCOUNT (ram_vip_burstcount), // .burstcount - .f2h_sdram0_WAITREQUEST (ram_vip_waitrequest), // .waitrequest - .f2h_sdram0_READDATA (ram_vip_readdata), // .readdata - .f2h_sdram0_READDATAVALID (ram_vip_readdatavalid), // .readdatavalid - .f2h_sdram0_READ (ram_vip_read), // .read - .f2h_sdram0_WRITEDATA (ram_vip_writedata), // .writedata - .f2h_sdram0_BYTEENABLE (ram_vip_byteenable), // .byteenable - .f2h_sdram0_WRITE (ram_vip_write), // .write - .f2h_sdram1_clk (ramclk1_clk), // f2h_sdram1_clock.clk - .f2h_sdram1_ADDRESS (ram1_address), // f2h_sdram1_data.address - .f2h_sdram1_BURSTCOUNT (ram1_burstcount), // .burstcount - .f2h_sdram1_WAITREQUEST (ram1_waitrequest), // .waitrequest - .f2h_sdram1_READDATA (ram1_readdata), // .readdata - .f2h_sdram1_READDATAVALID (ram1_readdatavalid), // .readdatavalid - .f2h_sdram1_READ (ram1_read), // .read - .f2h_sdram1_WRITEDATA (ram1_writedata), // .writedata - .f2h_sdram1_BYTEENABLE (ram1_byteenable), // .byteenable - .f2h_sdram1_WRITE (ram1_write), // .write - .f2h_sdram2_clk (ramclk2_clk), // f2h_sdram2_clock.clk - .f2h_sdram2_ADDRESS (ram2_address), // f2h_sdram2_data.address - .f2h_sdram2_BURSTCOUNT (ram2_burstcount), // .burstcount - .f2h_sdram2_WAITREQUEST (ram2_waitrequest), // .waitrequest - .f2h_sdram2_READDATA (ram2_readdata), // .readdata - .f2h_sdram2_READDATAVALID (ram2_readdatavalid), // .readdatavalid - .f2h_sdram2_READ (ram2_read), // .read - .f2h_sdram2_WRITEDATA (ram2_writedata), // .writedata - .f2h_sdram2_BYTEENABLE (ram2_byteenable), // .byteenable - .f2h_sdram2_WRITE (ram2_write) // .write -); - -reset_source reset_source ( - .clk (clk_vip_clk), // clock.clk - .reset_hps (~hps_h2f_reset_reset), // reset_hps.reset - .reset_sys (reset_vip_reset), // reset_sys.reset - .cold_req (reset_cold_req), // reset_ctl.cold_req - .reset (reset_reset), // .reset - .reset_req (reset_reset_req), // .reset_req - .warm_req (reset_warm_req), // .warm_req - .reset_warm (reset_source_reset_warm_reset), // reset_warm.reset - .reset_cold (reset_source_reset_cold_reset) // reset_cold.reset -); - -endmodule - -module sysmem_HPS_fpga_interfaces -( - // h2f_reset - output wire [1 - 1 : 0 ] h2f_rst_n - - // f2h_cold_reset_req - ,input wire [1 - 1 : 0 ] f2h_cold_rst_req_n - - // f2h_warm_reset_req - ,input wire [1 - 1 : 0 ] f2h_warm_rst_req_n - - // h2f_user0_clock - ,output wire [1 - 1 : 0 ] h2f_user0_clk - - // f2h_sdram0_data - ,input wire [28 - 1 : 0 ] f2h_sdram0_ADDRESS - ,input wire [8 - 1 : 0 ] f2h_sdram0_BURSTCOUNT - ,output wire [1 - 1 : 0 ] f2h_sdram0_WAITREQUEST - ,output wire [128 - 1 : 0 ] f2h_sdram0_READDATA - ,output wire [1 - 1 : 0 ] f2h_sdram0_READDATAVALID - ,input wire [1 - 1 : 0 ] f2h_sdram0_READ - ,input wire [128 - 1 : 0 ] f2h_sdram0_WRITEDATA - ,input wire [16 - 1 : 0 ] f2h_sdram0_BYTEENABLE - ,input wire [1 - 1 : 0 ] f2h_sdram0_WRITE - - // f2h_sdram0_clock - ,input wire [1 - 1 : 0 ] f2h_sdram0_clk - - // f2h_sdram1_data - ,input wire [29 - 1 : 0 ] f2h_sdram1_ADDRESS - ,input wire [8 - 1 : 0 ] f2h_sdram1_BURSTCOUNT - ,output wire [1 - 1 : 0 ] f2h_sdram1_WAITREQUEST - ,output wire [64 - 1 : 0 ] f2h_sdram1_READDATA - ,output wire [1 - 1 : 0 ] f2h_sdram1_READDATAVALID - ,input wire [1 - 1 : 0 ] f2h_sdram1_READ - ,input wire [64 - 1 : 0 ] f2h_sdram1_WRITEDATA - ,input wire [8 - 1 : 0 ] f2h_sdram1_BYTEENABLE - ,input wire [1 - 1 : 0 ] f2h_sdram1_WRITE - - // f2h_sdram1_clock - ,input wire [1 - 1 : 0 ] f2h_sdram1_clk - - // f2h_sdram2_data - ,input wire [29 - 1 : 0 ] f2h_sdram2_ADDRESS - ,input wire [8 - 1 : 0 ] f2h_sdram2_BURSTCOUNT - ,output wire [1 - 1 : 0 ] f2h_sdram2_WAITREQUEST - ,output wire [64 - 1 : 0 ] f2h_sdram2_READDATA - ,output wire [1 - 1 : 0 ] f2h_sdram2_READDATAVALID - ,input wire [1 - 1 : 0 ] f2h_sdram2_READ - ,input wire [64 - 1 : 0 ] f2h_sdram2_WRITEDATA - ,input wire [8 - 1 : 0 ] f2h_sdram2_BYTEENABLE - ,input wire [1 - 1 : 0 ] f2h_sdram2_WRITE - - // f2h_sdram2_clock - ,input wire [1 - 1 : 0 ] f2h_sdram2_clk -); - - -wire [29 - 1 : 0] intermediate; -assign intermediate[0:0] = ~intermediate[1:1]; -assign intermediate[8:8] = intermediate[4:4]|intermediate[7:7]; -assign intermediate[2:2] = intermediate[9:9]; -assign intermediate[3:3] = intermediate[9:9]; -assign intermediate[5:5] = intermediate[9:9]; -assign intermediate[6:6] = intermediate[9:9]; -assign intermediate[10:10] = intermediate[9:9]; -assign intermediate[11:11] = ~intermediate[12:12]; -assign intermediate[17:17] = intermediate[14:14]|intermediate[16:16]; -assign intermediate[13:13] = intermediate[18:18]; -assign intermediate[15:15] = intermediate[18:18]; -assign intermediate[19:19] = intermediate[18:18]; -assign intermediate[20:20] = ~intermediate[21:21]; -assign intermediate[26:26] = intermediate[23:23]|intermediate[25:25]; -assign intermediate[22:22] = intermediate[27:27]; -assign intermediate[24:24] = intermediate[27:27]; -assign intermediate[28:28] = intermediate[27:27]; -assign f2h_sdram0_WAITREQUEST[0:0] = intermediate[0:0]; -assign f2h_sdram1_WAITREQUEST[0:0] = intermediate[11:11]; -assign f2h_sdram2_WAITREQUEST[0:0] = intermediate[20:20]; -assign intermediate[4:4] = f2h_sdram0_READ[0:0]; -assign intermediate[7:7] = f2h_sdram0_WRITE[0:0]; -assign intermediate[9:9] = f2h_sdram0_clk[0:0]; -assign intermediate[14:14] = f2h_sdram1_READ[0:0]; -assign intermediate[16:16] = f2h_sdram1_WRITE[0:0]; -assign intermediate[18:18] = f2h_sdram1_clk[0:0]; -assign intermediate[23:23] = f2h_sdram2_READ[0:0]; -assign intermediate[25:25] = f2h_sdram2_WRITE[0:0]; -assign intermediate[27:27] = f2h_sdram2_clk[0:0]; - -cyclonev_hps_interface_clocks_resets clocks_resets( - .f2h_warm_rst_req_n({ - f2h_warm_rst_req_n[0:0] // 0:0 - }) -,.f2h_pending_rst_ack({ - 1'b1 // 0:0 - }) -,.f2h_dbg_rst_req_n({ - 1'b1 // 0:0 - }) -,.h2f_rst_n({ - h2f_rst_n[0:0] // 0:0 - }) -,.f2h_cold_rst_req_n({ - f2h_cold_rst_req_n[0:0] // 0:0 - }) -,.h2f_user0_clk({ - h2f_user0_clk[0:0] // 0:0 - }) -); - - -cyclonev_hps_interface_dbg_apb debug_apb( - .DBG_APB_DISABLE({ - 1'b0 // 0:0 - }) -,.P_CLK_EN({ - 1'b0 // 0:0 - }) -); - - -cyclonev_hps_interface_tpiu_trace tpiu( - .traceclk_ctl({ - 1'b1 // 0:0 - }) -); - - -cyclonev_hps_interface_boot_from_fpga boot_from_fpga( - .boot_from_fpga_ready({ - 1'b0 // 0:0 - }) -,.boot_from_fpga_on_failure({ - 1'b0 // 0:0 - }) -,.bsel_en({ - 1'b0 // 0:0 - }) -,.csel_en({ - 1'b0 // 0:0 - }) -,.csel({ - 2'b01 // 1:0 - }) -,.bsel({ - 3'b001 // 2:0 - }) -); - - -cyclonev_hps_interface_fpga2hps fpga2hps( - .port_size_config({ - 2'b11 // 1:0 - }) -); - - -cyclonev_hps_interface_hps2fpga hps2fpga( - .port_size_config({ - 2'b11 // 1:0 - }) -); - - -cyclonev_hps_interface_fpga2sdram f2sdram( - .cfg_rfifo_cport_map({ - 16'b0010000100000000 // 15:0 - }) -,.cfg_wfifo_cport_map({ - 16'b0010000100000000 // 15:0 - }) -,.rd_ready_3({ - 1'b1 // 0:0 - }) -,.cmd_port_clk_2({ - intermediate[28:28] // 0:0 - }) -,.rd_ready_2({ - 1'b1 // 0:0 - }) -,.cmd_port_clk_1({ - intermediate[19:19] // 0:0 - }) -,.rd_ready_1({ - 1'b1 // 0:0 - }) -,.cmd_port_clk_0({ - intermediate[10:10] // 0:0 - }) -,.rd_ready_0({ - 1'b1 // 0:0 - }) -,.wrack_ready_2({ - 1'b1 // 0:0 - }) -,.wrack_ready_1({ - 1'b1 // 0:0 - }) -,.wrack_ready_0({ - 1'b1 // 0:0 - }) -,.cmd_ready_2({ - intermediate[21:21] // 0:0 - }) -,.cmd_ready_1({ - intermediate[12:12] // 0:0 - }) -,.cmd_ready_0({ - intermediate[1:1] // 0:0 - }) -,.cfg_port_width({ - 12'b000000010110 // 11:0 - }) -,.rd_valid_3({ - f2h_sdram2_READDATAVALID[0:0] // 0:0 - }) -,.rd_valid_2({ - f2h_sdram1_READDATAVALID[0:0] // 0:0 - }) -,.rd_valid_1({ - f2h_sdram0_READDATAVALID[0:0] // 0:0 - }) -,.rd_clk_3({ - intermediate[22:22] // 0:0 - }) -,.rd_data_3({ - f2h_sdram2_READDATA[63:0] // 63:0 - }) -,.rd_clk_2({ - intermediate[13:13] // 0:0 - }) -,.rd_data_2({ - f2h_sdram1_READDATA[63:0] // 63:0 - }) -,.rd_clk_1({ - intermediate[3:3] // 0:0 - }) -,.rd_data_1({ - f2h_sdram0_READDATA[127:64] // 63:0 - }) -,.rd_clk_0({ - intermediate[2:2] // 0:0 - }) -,.rd_data_0({ - f2h_sdram0_READDATA[63:0] // 63:0 - }) -,.cfg_axi_mm_select({ - 6'b000000 // 5:0 - }) -,.cmd_valid_2({ - intermediate[26:26] // 0:0 - }) -,.cmd_valid_1({ - intermediate[17:17] // 0:0 - }) -,.cmd_valid_0({ - intermediate[8:8] // 0:0 - }) -,.cfg_cport_rfifo_map({ - 18'b000000000011010000 // 17:0 - }) -,.wr_data_3({ - 2'b00 // 89:88 - ,f2h_sdram2_BYTEENABLE[7:0] // 87:80 - ,16'b0000000000000000 // 79:64 - ,f2h_sdram2_WRITEDATA[63:0] // 63:0 - }) -,.wr_data_2({ - 2'b00 // 89:88 - ,f2h_sdram1_BYTEENABLE[7:0] // 87:80 - ,16'b0000000000000000 // 79:64 - ,f2h_sdram1_WRITEDATA[63:0] // 63:0 - }) -,.wr_data_1({ - 2'b00 // 89:88 - ,f2h_sdram0_BYTEENABLE[15:8] // 87:80 - ,16'b0000000000000000 // 79:64 - ,f2h_sdram0_WRITEDATA[127:64] // 63:0 - }) -,.cfg_cport_type({ - 12'b000000111111 // 11:0 - }) -,.wr_data_0({ - 2'b00 // 89:88 - ,f2h_sdram0_BYTEENABLE[7:0] // 87:80 - ,16'b0000000000000000 // 79:64 - ,f2h_sdram0_WRITEDATA[63:0] // 63:0 - }) -,.cfg_cport_wfifo_map({ - 18'b000000000011010000 // 17:0 - }) -,.wr_clk_3({ - intermediate[24:24] // 0:0 - }) -,.wr_clk_2({ - intermediate[15:15] // 0:0 - }) -,.wr_clk_1({ - intermediate[6:6] // 0:0 - }) -,.wr_clk_0({ - intermediate[5:5] // 0:0 - }) -,.cmd_data_2({ - 18'b000000000000000000 // 59:42 - ,f2h_sdram2_BURSTCOUNT[7:0] // 41:34 - ,3'b000 // 33:31 - ,f2h_sdram2_ADDRESS[28:0] // 30:2 - ,intermediate[25:25] // 1:1 - ,intermediate[23:23] // 0:0 - }) -,.cmd_data_1({ - 18'b000000000000000000 // 59:42 - ,f2h_sdram1_BURSTCOUNT[7:0] // 41:34 - ,3'b000 // 33:31 - ,f2h_sdram1_ADDRESS[28:0] // 30:2 - ,intermediate[16:16] // 1:1 - ,intermediate[14:14] // 0:0 - }) -,.cmd_data_0({ - 18'b000000000000000000 // 59:42 - ,f2h_sdram0_BURSTCOUNT[7:0] // 41:34 - ,4'b0000 // 33:30 - ,f2h_sdram0_ADDRESS[27:0] // 29:2 - ,intermediate[7:7] // 1:1 - ,intermediate[4:4] // 0:0 - }) -); - -endmodule + .f2h_cold_rst_req_n (~reset_hps_cold_req), + .f2h_warm_rst_req_n (~reset_hps_warm_req), + .h2f_user0_clk (clock), + .h2f_rst_n (hps_h2f_reset_n), + .f2h_sdram0_clk (vbuf_clk), + .f2h_sdram0_ADDRESS (vbuf_address), + .f2h_sdram0_BURSTCOUNT (vbuf_burstcount), + .f2h_sdram0_WAITREQUEST (vbuf_waitrequest), + .f2h_sdram0_READDATA (vbuf_readdata), + .f2h_sdram0_READDATAVALID (vbuf_readdatavalid), + .f2h_sdram0_READ (vbuf_read), + .f2h_sdram0_WRITEDATA (vbuf_writedata), + .f2h_sdram0_BYTEENABLE (vbuf_byteenable), + .f2h_sdram0_WRITE (vbuf_write), + .f2h_sdram1_clk (ram1_clk), + .f2h_sdram1_ADDRESS (ram1_address), + .f2h_sdram1_BURSTCOUNT (ram1_burstcount), + .f2h_sdram1_WAITREQUEST (ram1_waitrequest), + .f2h_sdram1_READDATA (ram1_readdata), + .f2h_sdram1_READDATAVALID (ram1_readdatavalid), + .f2h_sdram1_READ (ram1_read), + .f2h_sdram1_WRITEDATA (ram1_writedata), + .f2h_sdram1_BYTEENABLE (ram1_byteenable), + .f2h_sdram1_WRITE (ram1_write), + .f2h_sdram2_clk (ram2_clk), + .f2h_sdram2_ADDRESS (ram2_address), + .f2h_sdram2_BURSTCOUNT (ram2_burstcount), + .f2h_sdram2_WAITREQUEST (ram2_waitrequest), + .f2h_sdram2_READDATA (ram2_readdata), + .f2h_sdram2_READDATAVALID (ram2_readdatavalid), + .f2h_sdram2_READ (ram2_read), + .f2h_sdram2_WRITEDATA (ram2_writedata), + .f2h_sdram2_BYTEENABLE (ram2_byteenable), + .f2h_sdram2_WRITE (ram2_write) +); + +wire hps_h2f_reset_n; + +reg init_reset_n = 0; +always @(posedge clock) begin + integer timeout = 0; + + if(timeout < 2000000) begin + init_reset_n <= 0; + timeout <= timeout + 1; + end + else init_reset_n <= 1; +end + +endmodule + + +module sysmem_HPS_fpga_interfaces +( + // h2f_reset + output wire [1 - 1 : 0 ] h2f_rst_n + + // f2h_cold_reset_req + ,input wire [1 - 1 : 0 ] f2h_cold_rst_req_n + + // f2h_warm_reset_req + ,input wire [1 - 1 : 0 ] f2h_warm_rst_req_n + + // h2f_user0_clock + ,output wire [1 - 1 : 0 ] h2f_user0_clk + + // f2h_sdram0_data + ,input wire [28 - 1 : 0 ] f2h_sdram0_ADDRESS + ,input wire [8 - 1 : 0 ] f2h_sdram0_BURSTCOUNT + ,output wire [1 - 1 : 0 ] f2h_sdram0_WAITREQUEST + ,output wire [128 - 1 : 0 ] f2h_sdram0_READDATA + ,output wire [1 - 1 : 0 ] f2h_sdram0_READDATAVALID + ,input wire [1 - 1 : 0 ] f2h_sdram0_READ + ,input wire [128 - 1 : 0 ] f2h_sdram0_WRITEDATA + ,input wire [16 - 1 : 0 ] f2h_sdram0_BYTEENABLE + ,input wire [1 - 1 : 0 ] f2h_sdram0_WRITE + + // f2h_sdram0_clock + ,input wire [1 - 1 : 0 ] f2h_sdram0_clk + + // f2h_sdram1_data + ,input wire [29 - 1 : 0 ] f2h_sdram1_ADDRESS + ,input wire [8 - 1 : 0 ] f2h_sdram1_BURSTCOUNT + ,output wire [1 - 1 : 0 ] f2h_sdram1_WAITREQUEST + ,output wire [64 - 1 : 0 ] f2h_sdram1_READDATA + ,output wire [1 - 1 : 0 ] f2h_sdram1_READDATAVALID + ,input wire [1 - 1 : 0 ] f2h_sdram1_READ + ,input wire [64 - 1 : 0 ] f2h_sdram1_WRITEDATA + ,input wire [8 - 1 : 0 ] f2h_sdram1_BYTEENABLE + ,input wire [1 - 1 : 0 ] f2h_sdram1_WRITE + + // f2h_sdram1_clock + ,input wire [1 - 1 : 0 ] f2h_sdram1_clk + + // f2h_sdram2_data + ,input wire [29 - 1 : 0 ] f2h_sdram2_ADDRESS + ,input wire [8 - 1 : 0 ] f2h_sdram2_BURSTCOUNT + ,output wire [1 - 1 : 0 ] f2h_sdram2_WAITREQUEST + ,output wire [64 - 1 : 0 ] f2h_sdram2_READDATA + ,output wire [1 - 1 : 0 ] f2h_sdram2_READDATAVALID + ,input wire [1 - 1 : 0 ] f2h_sdram2_READ + ,input wire [64 - 1 : 0 ] f2h_sdram2_WRITEDATA + ,input wire [8 - 1 : 0 ] f2h_sdram2_BYTEENABLE + ,input wire [1 - 1 : 0 ] f2h_sdram2_WRITE + + // f2h_sdram2_clock + ,input wire [1 - 1 : 0 ] f2h_sdram2_clk +); + + +wire [29 - 1 : 0] intermediate; +assign intermediate[0:0] = ~intermediate[1:1]; +assign intermediate[8:8] = intermediate[4:4]|intermediate[7:7]; +assign intermediate[2:2] = intermediate[9:9]; +assign intermediate[3:3] = intermediate[9:9]; +assign intermediate[5:5] = intermediate[9:9]; +assign intermediate[6:6] = intermediate[9:9]; +assign intermediate[10:10] = intermediate[9:9]; +assign intermediate[11:11] = ~intermediate[12:12]; +assign intermediate[17:17] = intermediate[14:14]|intermediate[16:16]; +assign intermediate[13:13] = intermediate[18:18]; +assign intermediate[15:15] = intermediate[18:18]; +assign intermediate[19:19] = intermediate[18:18]; +assign intermediate[20:20] = ~intermediate[21:21]; +assign intermediate[26:26] = intermediate[23:23]|intermediate[25:25]; +assign intermediate[22:22] = intermediate[27:27]; +assign intermediate[24:24] = intermediate[27:27]; +assign intermediate[28:28] = intermediate[27:27]; +assign f2h_sdram0_WAITREQUEST[0:0] = intermediate[0:0]; +assign f2h_sdram1_WAITREQUEST[0:0] = intermediate[11:11]; +assign f2h_sdram2_WAITREQUEST[0:0] = intermediate[20:20]; +assign intermediate[4:4] = f2h_sdram0_READ[0:0]; +assign intermediate[7:7] = f2h_sdram0_WRITE[0:0]; +assign intermediate[9:9] = f2h_sdram0_clk[0:0]; +assign intermediate[14:14] = f2h_sdram1_READ[0:0]; +assign intermediate[16:16] = f2h_sdram1_WRITE[0:0]; +assign intermediate[18:18] = f2h_sdram1_clk[0:0]; +assign intermediate[23:23] = f2h_sdram2_READ[0:0]; +assign intermediate[25:25] = f2h_sdram2_WRITE[0:0]; +assign intermediate[27:27] = f2h_sdram2_clk[0:0]; + +cyclonev_hps_interface_clocks_resets clocks_resets( + .f2h_warm_rst_req_n({ + f2h_warm_rst_req_n[0:0] // 0:0 + }) +,.f2h_pending_rst_ack({ + 1'b1 // 0:0 + }) +,.f2h_dbg_rst_req_n({ + 1'b1 // 0:0 + }) +,.h2f_rst_n({ + h2f_rst_n[0:0] // 0:0 + }) +,.f2h_cold_rst_req_n({ + f2h_cold_rst_req_n[0:0] // 0:0 + }) +,.h2f_user0_clk({ + h2f_user0_clk[0:0] // 0:0 + }) +); + + +cyclonev_hps_interface_dbg_apb debug_apb( + .DBG_APB_DISABLE({ + 1'b0 // 0:0 + }) +,.P_CLK_EN({ + 1'b0 // 0:0 + }) +); + + +cyclonev_hps_interface_tpiu_trace tpiu( + .traceclk_ctl({ + 1'b1 // 0:0 + }) +); + + +cyclonev_hps_interface_boot_from_fpga boot_from_fpga( + .boot_from_fpga_ready({ + 1'b0 // 0:0 + }) +,.boot_from_fpga_on_failure({ + 1'b0 // 0:0 + }) +,.bsel_en({ + 1'b0 // 0:0 + }) +,.csel_en({ + 1'b0 // 0:0 + }) +,.csel({ + 2'b01 // 1:0 + }) +,.bsel({ + 3'b001 // 2:0 + }) +); + + +cyclonev_hps_interface_fpga2hps fpga2hps( + .port_size_config({ + 2'b11 // 1:0 + }) +); + + +cyclonev_hps_interface_hps2fpga hps2fpga( + .port_size_config({ + 2'b11 // 1:0 + }) +); + + +cyclonev_hps_interface_fpga2sdram f2sdram( + .cfg_rfifo_cport_map({ + 16'b0010000100000000 // 15:0 + }) +,.cfg_wfifo_cport_map({ + 16'b0010000100000000 // 15:0 + }) +,.rd_ready_3({ + 1'b1 // 0:0 + }) +,.cmd_port_clk_2({ + intermediate[28:28] // 0:0 + }) +,.rd_ready_2({ + 1'b1 // 0:0 + }) +,.cmd_port_clk_1({ + intermediate[19:19] // 0:0 + }) +,.rd_ready_1({ + 1'b1 // 0:0 + }) +,.cmd_port_clk_0({ + intermediate[10:10] // 0:0 + }) +,.rd_ready_0({ + 1'b1 // 0:0 + }) +,.wrack_ready_2({ + 1'b1 // 0:0 + }) +,.wrack_ready_1({ + 1'b1 // 0:0 + }) +,.wrack_ready_0({ + 1'b1 // 0:0 + }) +,.cmd_ready_2({ + intermediate[21:21] // 0:0 + }) +,.cmd_ready_1({ + intermediate[12:12] // 0:0 + }) +,.cmd_ready_0({ + intermediate[1:1] // 0:0 + }) +,.cfg_port_width({ + 12'b000000010110 // 11:0 + }) +,.rd_valid_3({ + f2h_sdram2_READDATAVALID[0:0] // 0:0 + }) +,.rd_valid_2({ + f2h_sdram1_READDATAVALID[0:0] // 0:0 + }) +,.rd_valid_1({ + f2h_sdram0_READDATAVALID[0:0] // 0:0 + }) +,.rd_clk_3({ + intermediate[22:22] // 0:0 + }) +,.rd_data_3({ + f2h_sdram2_READDATA[63:0] // 63:0 + }) +,.rd_clk_2({ + intermediate[13:13] // 0:0 + }) +,.rd_data_2({ + f2h_sdram1_READDATA[63:0] // 63:0 + }) +,.rd_clk_1({ + intermediate[3:3] // 0:0 + }) +,.rd_data_1({ + f2h_sdram0_READDATA[127:64] // 63:0 + }) +,.rd_clk_0({ + intermediate[2:2] // 0:0 + }) +,.rd_data_0({ + f2h_sdram0_READDATA[63:0] // 63:0 + }) +,.cfg_axi_mm_select({ + 6'b000000 // 5:0 + }) +,.cmd_valid_2({ + intermediate[26:26] // 0:0 + }) +,.cmd_valid_1({ + intermediate[17:17] // 0:0 + }) +,.cmd_valid_0({ + intermediate[8:8] // 0:0 + }) +,.cfg_cport_rfifo_map({ + 18'b000000000011010000 // 17:0 + }) +,.wr_data_3({ + 2'b00 // 89:88 + ,f2h_sdram2_BYTEENABLE[7:0] // 87:80 + ,16'b0000000000000000 // 79:64 + ,f2h_sdram2_WRITEDATA[63:0] // 63:0 + }) +,.wr_data_2({ + 2'b00 // 89:88 + ,f2h_sdram1_BYTEENABLE[7:0] // 87:80 + ,16'b0000000000000000 // 79:64 + ,f2h_sdram1_WRITEDATA[63:0] // 63:0 + }) +,.wr_data_1({ + 2'b00 // 89:88 + ,f2h_sdram0_BYTEENABLE[15:8] // 87:80 + ,16'b0000000000000000 // 79:64 + ,f2h_sdram0_WRITEDATA[127:64] // 63:0 + }) +,.cfg_cport_type({ + 12'b000000111111 // 11:0 + }) +,.wr_data_0({ + 2'b00 // 89:88 + ,f2h_sdram0_BYTEENABLE[7:0] // 87:80 + ,16'b0000000000000000 // 79:64 + ,f2h_sdram0_WRITEDATA[63:0] // 63:0 + }) +,.cfg_cport_wfifo_map({ + 18'b000000000011010000 // 17:0 + }) +,.wr_clk_3({ + intermediate[24:24] // 0:0 + }) +,.wr_clk_2({ + intermediate[15:15] // 0:0 + }) +,.wr_clk_1({ + intermediate[6:6] // 0:0 + }) +,.wr_clk_0({ + intermediate[5:5] // 0:0 + }) +,.cmd_data_2({ + 18'b000000000000000000 // 59:42 + ,f2h_sdram2_BURSTCOUNT[7:0] // 41:34 + ,3'b000 // 33:31 + ,f2h_sdram2_ADDRESS[28:0] // 30:2 + ,intermediate[25:25] // 1:1 + ,intermediate[23:23] // 0:0 + }) +,.cmd_data_1({ + 18'b000000000000000000 // 59:42 + ,f2h_sdram1_BURSTCOUNT[7:0] // 41:34 + ,3'b000 // 33:31 + ,f2h_sdram1_ADDRESS[28:0] // 30:2 + ,intermediate[16:16] // 1:1 + ,intermediate[14:14] // 0:0 + }) +,.cmd_data_0({ + 18'b000000000000000000 // 59:42 + ,f2h_sdram0_BURSTCOUNT[7:0] // 41:34 + ,4'b0000 // 33:30 + ,f2h_sdram0_ADDRESS[27:0] // 29:2 + ,intermediate[7:7] // 1:1 + ,intermediate[4:4] // 0:0 + }) +); + +endmodule diff --git a/sys/video_cleaner.sv b/sys/video_cleaner.sv new file mode 100644 index 0000000..f9f23d2 --- /dev/null +++ b/sys/video_cleaner.sv @@ -0,0 +1,91 @@ +// +// +// Copyright (c) 2018 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +`timescale 1ns / 1ps + +module video_cleaner +( + input clk_vid, + input ce_pix, + + input [7:0] R, + input [7:0] G, + input [7:0] B, + + input HSync, + input VSync, + input HBlank, + input VBlank, + + // video output signals + output reg [7:0] VGA_R, + output reg [7:0] VGA_G, + output reg [7:0] VGA_B, + output reg VGA_VS, + output reg VGA_HS, + output VGA_DE, + + // optional aligned blank + output reg HBlank_out, + output reg VBlank_out +); + +wire hs, vs; +s_fix sync_v(clk_vid, HSync, hs); +s_fix sync_h(clk_vid, VSync, vs); + +wire hbl = hs | HBlank; +wire vbl = vs | VBlank; + +assign VGA_DE = ~(HBlank_out | VBlank_out); + +always @(posedge clk_vid) begin + if(ce_pix) begin + HBlank_out <= hbl; + + VGA_VS <= vs; + VGA_HS <= hs; + VGA_R <= R; + VGA_G <= G; + VGA_B <= B; + + if(HBlank_out & ~hbl) VBlank_out <= vbl; + end +end + +endmodule + +module s_fix +( + input clk, + + input sync_in, + output sync_out +); + +assign sync_out = sync_in ^ pol; + +reg pol; +always @(posedge clk) begin + integer pos = 0, neg = 0, cnt = 0; + reg s1,s2; + + s1 <= sync_in; + s2 <= s1; + + if(~s2 & s1) neg <= cnt; + if(s2 & ~s1) pos <= cnt; + + cnt <= cnt + 1; + if(s2 != s1) cnt <= 0; + + pol <= pos > neg; +end + +endmodule diff --git a/sys/video_mixer.sv b/sys/video_mixer.sv index 6babc3e..8f48f11 100644 --- a/sys/video_mixer.sv +++ b/sys/video_mixer.sv @@ -160,7 +160,7 @@ always @(posedge clk_sys) begin VGA_HS <= hs; old_hde <= hde; - if(~old_hde && hde && vde) VGA_DE <= 1; + if(~old_hde && hde) VGA_DE <= vde; if(old_hde && ~hde) VGA_DE <= 0; end diff --git a/sys/vip.qsys b/sys/vip.qsys deleted file mode 100644 index 47306be..0000000 --- a/sys/vip.qsys +++ /dev/null @@ -1,1177 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No,No,No,No,No,No,No,No - - - - - - - - - - - - - - - - - - - - - Avalon-MM Bidirectional,Avalon-MM Bidirectional,Avalon-MM Bidirectional - - - - - - - - - - - - - - - - - - - - - - - - - - - - - No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No - - - - - - - - - - - - - - - - No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No,No - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {320000000 1600000000} {320000000 1000000000} {800000000 400000000 400000000} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sys/vip_config.sv b/sys/vip_config.sv deleted file mode 100644 index 89bf241..0000000 --- a/sys/vip_config.sv +++ /dev/null @@ -1,159 +0,0 @@ - -module vip_config -( - input clk, - input reset, - - input [7:0] ARX, - input [7:0] ARY, - input CFG_SET, - - input [11:0] WIDTH, - input [11:0] HFP, - input [11:0] HBP, - input [11:0] HS, - input [11:0] HEIGHT, - input [11:0] VFP, - input [11:0] VBP, - input [11:0] VS, - - input [11:0] VSET, - - output reg [8:0] address, - output reg write, - output reg [31:0] writedata, - input waitrequest -); - - -reg newres = 1; - -wire [21:0] init[23] = -'{ - //video mode - {newres, 2'd2, 7'd04, 12'd0 }, //Bank - {newres, 2'd2, 7'd30, 12'd0 }, //Valid - {newres, 2'd2, 7'd05, 12'd0 }, //Progressive/Interlaced - {newres, 2'd2, 7'd06, w }, //Active pixel count - {newres, 2'd2, 7'd07, h }, //Active line count - {newres, 2'd2, 7'd09, hfp }, //Horizontal Front Porch - {newres, 2'd2, 7'd10, hs }, //Horizontal Sync Length - {newres, 2'd2, 7'd11, hb }, //Horizontal Blanking (HFP+HBP+HSync) - {newres, 2'd2, 7'd12, vfp }, //Vertical Front Porch - {newres, 2'd2, 7'd13, vs }, //Vertical Sync Length - {newres, 2'd2, 7'd14, vb }, //Vertical blanking (VFP+VBP+VSync) - {newres, 2'd2, 7'd30, 12'd1 }, //Valid - {newres, 2'd2, 7'd00, 12'd1 }, //Go - - //mixer - { 1'd1, 2'd1, 7'd03, w }, //Bkg Width - { 1'd1, 2'd1, 7'd04, h }, //Bkg Height - { 1'd1, 2'd1, 7'd08, posx }, //Pos X - { 1'd1, 2'd1, 7'd09, posy }, //Pos Y - { 1'd1, 2'd1, 7'd10, 12'd1 }, //Enable Video 0 - { 1'd1, 2'd1, 7'd00, 12'd1 }, //Go - - //scaler - { 1'd1, 2'd0, 7'd03, videow }, //Output Width - { 1'd1, 2'd0, 7'd04, videoh }, //Output Height - { 1'd1, 2'd0, 7'd00, 12'd1 }, //Go - - 22'h3FFFFF -}; - -reg [11:0] w; -reg [11:0] hfp; -reg [11:0] hbp; -reg [11:0] hs; -reg [11:0] hb; -reg [11:0] h; -reg [11:0] vfp; -reg [11:0] vbp; -reg [11:0] vs; -reg [11:0] vb; - -reg [11:0] videow; -reg [11:0] videoh; - -reg [11:0] posx; -reg [11:0] posy; - -always @(posedge clk) begin - reg [7:0] state = 0; - reg [7:0] arx, ary; - reg [7:0] arxd, aryd; - reg [11:0] vset, vsetd; - reg cfg, cfgd; - reg [31:0] wcalc; - reg [31:0] hcalc; - reg [12:0] timeout = 0; - - arxd <= ARX; - aryd <= ARY; - vsetd <= VSET; - - cfg <= CFG_SET; - cfgd <= cfg; - - write <= 0; - if(reset || (arx != arxd) || (ary != aryd) || (vset != vsetd) || (~cfgd && cfg)) begin - arx <= arxd; - ary <= aryd; - vset <= vsetd; - timeout <= '1; - state <= 0; - if(reset || (~cfgd && cfg)) newres <= 1; - end - else - if(timeout > 0) - begin - timeout <= timeout - 1'd1; - state <= 1; - if(!(timeout & 'h1f)) case(timeout>>5) - 5: begin - w <= WIDTH; - hfp <= HFP; - hbp <= HBP; - hs <= HS; - h <= HEIGHT; - vfp <= VFP; - vbp <= VBP; - vs <= VS; - end - 4: begin - hb <= hfp+hbp+hs; - vb <= vfp+vbp+vs; - end - 3: begin - wcalc <= vset ? (vset*arx)/ary : (h*arx)/ary; - hcalc <= (w*ary)/arx; - end - 2: begin - videow <= (!vset && (wcalc > w)) ? w : wcalc[11:0]; - videoh <= vset ? vset : (hcalc > h) ? h : hcalc[11:0]; - end - 1: begin - posx <= (w - videow)>>1; - posy <= (h - videoh)>>1; - end - endcase - end - else - if(~waitrequest && state) - begin - state <= state + 1'd1; - write <= 0; - if((state&3)==3) begin - if(init[state>>2] == 22'h3FFFFF) begin - state <= 0; - newres <= 0; - end - else begin - writedata <= 0; - {write, address, writedata[11:0]} <= init[state>>2]; - end - end - end -end - -endmodule