commit a1d17ed38add8056339b0910eb6193ecad0970c1 Author: sorgelig Date: Thu Aug 16 05:21:32 2018 +0800 Initial commit. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a80016f --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +db +greybox_tmp +incremental_db +output_files +simulation +hc_output +scaler +hps_isw_handoff +vip +*_sim +.qsys_edit +PLLJ_PLLSPE_INFO.txt +*.bak +*.orig +*.rej +*.qdf +*.rpt +*.smsg +*.summary +*.done +*.jdi +*.pin +*.sof +*.qws +*.ppf +*.ddb +build_id.v +c5_pin_model_dump.txt +*.sopcinfo +*.csv +*.f +*.cmp +*.sip +*.spd +*.bsf +*~ +*.xml +*_netlist +*.cdf diff --git a/TSConf-lite.qsf b/TSConf-lite.qsf new file mode 100644 index 0000000..55da076 --- /dev/null +++ b/TSConf-lite.qsf @@ -0,0 +1,402 @@ +# -------------------------------------------------------------------------- # +# +# 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 "HIGH PERFORMANCE EFFORT" +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 VHDL_FILE src/t80/T80_Reg.vhd +set_global_assignment -name VHDL_FILE src/t80/T80_Pack.vhd +set_global_assignment -name VHDL_FILE src/t80/T80_MCode.vhd +set_global_assignment -name VHDL_FILE src/t80/T80_ALU.vhd +set_global_assignment -name VHDL_FILE src/t80/T80.vhd +set_global_assignment -name VHDL_FILE src/t80/T80s.vhd +set_global_assignment -name VERILOG_FILE src/cpu/zsignals.v +set_global_assignment -name VERILOG_FILE src/cpu/zports.v +set_global_assignment -name VERILOG_FILE src/cpu/zmem.v +set_global_assignment -name VERILOG_FILE src/cpu/zmaps.v +set_global_assignment -name VERILOG_FILE src/cpu/zint.v +set_global_assignment -name VERILOG_FILE src/cpu/zclock.v +set_global_assignment -name VERILOG_FILE src/cpu/cache_data.v +set_global_assignment -name VERILOG_FILE src/cpu/cache_addr.v +set_global_assignment -name VHDL_FILE src/rtc/CMOS.vhd +set_global_assignment -name VHDL_FILE src/rtc/mc146818a.vhd +set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd +set_global_assignment -name VHDL_FILE src/sound/turbosound.vhd +set_global_assignment -name VHDL_FILE src/sound/ay8910.vhd +set_global_assignment -name VERILOG_FILE src/memory/dma.v +set_global_assignment -name VERILOG_FILE src/memory/arbiter.v +set_global_assignment -name VERILOG_FILE src/video/video_ts_render.v +set_global_assignment -name VERILOG_FILE src/video/video_ts.v +set_global_assignment -name VERILOG_FILE src/video/video_sync.v +set_global_assignment -name VERILOG_FILE src/video/video_render.v +set_global_assignment -name VERILOG_FILE src/video/video_ports.v +set_global_assignment -name VERILOG_FILE src/video/video_out.v +set_global_assignment -name VERILOG_FILE src/video/video_mode.v +set_global_assignment -name VERILOG_FILE src/video/video_fetch.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_vmem.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_tsline1.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_tsline0.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_tmbuf.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_sfile.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_cram.v +set_global_assignment -name VERILOG_FILE src/video/video_top.v +set_global_assignment -name VHDL_FILE src/rom.vhd +set_global_assignment -name VHDL_FILE src/keyboard.vhd +set_global_assignment -name VERILOG_FILE src/kempston_mouse.v +set_global_assignment -name VERILOG_FILE src/spi.v +set_global_assignment -name VHDL_FILE src/sdram.vhd +set_global_assignment -name VERILOG_FILE src/clock.v +set_global_assignment -name VHDL_FILE src/tsconf.vhd +set_global_assignment -name SYSTEMVERILOG_FILE TSConf.sv +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/TSConf-lite.srf b/TSConf-lite.srf new file mode 100644 index 0000000..c8aa08b --- /dev/null +++ b/TSConf-lite.srf @@ -0,0 +1,23 @@ +{ "" "" "" "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 ""} +{ "" "" "" "Verilog HDL or VHDL warning at sys_top.v(209): object \"vip_newcfg\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Verilog HDL or VHDL warning at sys_top.v(601): object \"VSET\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Verilog HDL or VHDL warning at altera_pll_reconfig_core.v(208): object \"dps_start_assert\" assigned a value but never read" { } { } 0 10036 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Port \"extclk\" on the entity instantiation of \"cyclonev_pll\" is connected to a signal of width 1. The formal width of the signal in the module is 2. The extra bits will be left dangling without any fan-out logic." { } { } 0 12030 "" 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 ""} +{ "" "" "" "altera_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "altera_cyclonev_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "altera_pll_reconfig_core.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} diff --git a/TSConf.qpf b/TSConf.qpf new file mode 100644 index 0000000..f1e58fa --- /dev/null +++ b/TSConf.qpf @@ -0,0 +1,13 @@ +# +# please keep this file read-only! +# Quartus changes this file everytime revision is switched, +# and it will be marked as changed with every commit. +# + +QUARTUS_VERSION = "16.1" +DATE = "23:13:02 April 27, 2017" + +# Revisions + +PROJECT_REVISION = "TSConf" +PROJECT_REVISION = "TSConf-lite" diff --git a/TSConf.qsf b/TSConf.qsf new file mode 100644 index 0000000..ed721a8 --- /dev/null +++ b/TSConf.qsf @@ -0,0 +1,408 @@ +# -------------------------------------------------------------------------- # +# +# 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 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 ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON +set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name ALM_REGISTER_PACKING_EFFORT LOW +set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF +set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON +set_global_assignment -name FITTER_EFFORT "STANDARD FIT" +set_global_assignment -name OPTIMIZATION_MODE "AGGRESSIVE PERFORMANCE" +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 QSYS_FILE sys/vip.qsys +set_global_assignment -name VHDL_FILE src/t80/T80_Reg.vhd +set_global_assignment -name VHDL_FILE src/t80/T80_Pack.vhd +set_global_assignment -name VHDL_FILE src/t80/T80_MCode.vhd +set_global_assignment -name VHDL_FILE src/t80/T80_ALU.vhd +set_global_assignment -name VHDL_FILE src/t80/T80.vhd +set_global_assignment -name VHDL_FILE src/t80/T80s.vhd +set_global_assignment -name VERILOG_FILE src/cpu/zsignals.v +set_global_assignment -name VERILOG_FILE src/cpu/zports.v +set_global_assignment -name VERILOG_FILE src/cpu/zmem.v +set_global_assignment -name VERILOG_FILE src/cpu/zmaps.v +set_global_assignment -name VERILOG_FILE src/cpu/zint.v +set_global_assignment -name VERILOG_FILE src/cpu/zclock.v +set_global_assignment -name VERILOG_FILE src/cpu/cache_data.v +set_global_assignment -name VERILOG_FILE src/cpu/cache_addr.v +set_global_assignment -name VHDL_FILE src/rtc/CMOS.vhd +set_global_assignment -name VHDL_FILE src/rtc/mc146818a.vhd +set_global_assignment -name VHDL_FILE src/sound/soundrive.vhd +set_global_assignment -name VHDL_FILE src/sound/turbosound.vhd +set_global_assignment -name VHDL_FILE src/sound/ay8910.vhd +set_global_assignment -name VERILOG_FILE src/memory/dma.v +set_global_assignment -name VERILOG_FILE src/memory/arbiter.v +set_global_assignment -name VERILOG_FILE src/video/video_ts_render.v +set_global_assignment -name VERILOG_FILE src/video/video_ts.v +set_global_assignment -name VERILOG_FILE src/video/video_sync.v +set_global_assignment -name VERILOG_FILE src/video/video_render.v +set_global_assignment -name VERILOG_FILE src/video/video_ports.v +set_global_assignment -name VERILOG_FILE src/video/video_out.v +set_global_assignment -name VERILOG_FILE src/video/video_mode.v +set_global_assignment -name VERILOG_FILE src/video/video_fetch.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_vmem.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_tsline1.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_tsline0.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_tmbuf.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_sfile.v +set_global_assignment -name VERILOG_FILE src/video/mem/video_cram.v +set_global_assignment -name VERILOG_FILE src/video/video_top.v +set_global_assignment -name VHDL_FILE src/rom.vhd +set_global_assignment -name VHDL_FILE src/keyboard.vhd +set_global_assignment -name VERILOG_FILE src/kempston_mouse.v +set_global_assignment -name VERILOG_FILE src/spi.v +set_global_assignment -name VHDL_FILE src/sdram.vhd +set_global_assignment -name VERILOG_FILE src/clock.v +set_global_assignment -name VHDL_FILE src/tsconf.vhd +set_global_assignment -name SYSTEMVERILOG_FILE TSConf.sv +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/TSConf.srf b/TSConf.srf new file mode 100644 index 0000000..35a7eff --- /dev/null +++ b/TSConf.srf @@ -0,0 +1,29 @@ +{ "" "" "" "Vip.Mixer: The MixerII register map changed in ACDS v16.0. Please refer to the VIP User Guide for details." { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Vip.Reset_Source.reset_sys: Associated reset sinks not declared" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Vip.Reset_Source.reset_warm: Associated reset sinks not declared" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Vip.Reset_Source.reset_cold: Associated reset sinks not declared" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Vip.Video_Output.control: Interrupt sender control.av_mm_control_interrupt is not connected to an interrupt receiver" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Vip.Video_Output: Interrupt sender Video_Output.status_update_irq is not connected to an interrupt receiver" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Vip.: You have exported the interface HPS.f2h_sdram1_data but not its associated reset interface. Export the driver(s) of HPS.h2f_reset" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Vip.: You have exported the interface HPS.f2h_sdram2_data but not its associated reset interface. Export the driver(s) of HPS.h2f_reset" { } { } 0 12251 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Variable or input pin \"data_b\" is defined but never used." { } { } 0 287013 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Variable or input pin \"data_a\" is defined but never used." { } { } 0 287013 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Port \"extclk\" on the entity instantiation of \"cyclonev_pll\" is connected to a signal of width 1. The formal width of the signal in the module is 2. The extra bits will be left dangling without any fan-out logic." { } { } 0 12030 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Port \"trs\" on the entity instantiation of \"statemachine\" is connected to a signal of width 2. The formal width of the signal in the module is 1. The extra bits will be ignored." { } { } 0 12020 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Port \"reset_value\" on the entity instantiation of \"h_counter\" is connected to a signal of width 32. The formal width of the signal in the module is 16. The extra bits will be ignored." { } { } 0 12020 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "Overwriting existing clock: vip\|hps\|fpga_interfaces\|clocks_resets\|h2f_user0_clk" { } { } 0 332043 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "LOCKED 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 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 ""} +{ "" "" "" "Vip.vip: Module dependency loop involving: \"HPS\"" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "alt_vip_common_frame_counter.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "alt_vip_cvo_mode_banks.sv" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "altera_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "altera_cyclonev_pll.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "altera_pll_reconfig_core.v" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "genlock_enable_sync" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "u_calculate_mode" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "mode_banks" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "RST port on the PLL is not properly connected" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "alt_vip_cvo_core.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "alt_vip_packet_transfer.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "alt_vip_common_dc_mixed_widths_fifo.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} +{ "" "" "" "vip_HPS_fpga_interfaces.sdc" { } { } 0 9999 "" 0 0 "Design Software" 0 -1 0 ""} diff --git a/TSConf.sv b/TSConf.sv new file mode 100644 index 0000000..a0381d0 --- /dev/null +++ b/TSConf.sv @@ -0,0 +1,366 @@ +//============================================================================ +// Atari 800 replica +// +// Port to MiSTer +// Copyright (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 emu +( + //Master input clock + input CLK_50M, + + //Async reset from top-level module. + //Can be used as initial reset. + input RESET, + + //Must be passed to hps_io module + inout [44:0] HPS_BUS, + + //Base video clock. Usually equals to CLK_SYS. + output CLK_VIDEO, + + //Multiple resolutions are supported using different CE_PIXEL rates. + //Must be based on CLK_VIDEO + output CE_PIXEL, + + //Video aspect ratio for HDMI. Most retro systems have ratio 4:3. + output [7:0] VIDEO_ARX, + output [7:0] VIDEO_ARY, + + output [7:0] VGA_R, + output [7:0] VGA_G, + output [7:0] VGA_B, + output VGA_HS, + output VGA_VS, + output VGA_DE, // = ~(VBlank | HBlank) + + output LED_USER, // 1 - ON, 0 - OFF. + + // b[1]: 0 - LED status is system status OR'd with b[0] + // 1 - LED status is controled solely by b[0] + // hint: supply 2'b00 to let the system control the LED. + output [1:0] LED_POWER, + output [1:0] LED_DISK, + + output [15:0] AUDIO_L, + output [15:0] AUDIO_R, + output AUDIO_S, // 1 - signed audio samples, 0 - unsigned + output [1:0] AUDIO_MIX, // 0 - no mix, 1 - 25%, 2 - 50%, 3 - 100% (mono) + input TAPE_IN, + + // SD-SPI + output SD_SCK, + output SD_MOSI, + input SD_MISO, + output SD_CS, + input SD_CD, + + //High latency DDR3 RAM interface + //Use for non-critical time purposes + output DDRAM_CLK, + input DDRAM_BUSY, + output [7:0] DDRAM_BURSTCNT, + output [28:0] DDRAM_ADDR, + input [63:0] DDRAM_DOUT, + input DDRAM_DOUT_READY, + output DDRAM_RD, + output [63:0] DDRAM_DIN, + output [7:0] DDRAM_BE, + output DDRAM_WE, + + //SDRAM interface with lower latency + output SDRAM_CLK, + output SDRAM_CKE, + output [12:0] SDRAM_A, + output [1:0] SDRAM_BA, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE +); + +assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = '0; + +assign LED_USER = vsd_sel & sd_act; +assign LED_DISK = {1'b1, ~vsd_sel & sd_act}; +assign LED_POWER = 0; + +assign VIDEO_ARX = status[5] ? 8'd16 : 8'd4; +assign VIDEO_ARY = status[5] ? 8'd9 : 8'd3; + +`include "build_id.v" +localparam CONF_STR = { + "TSConf;;", + "O5,Aspect ratio,4:3,16:9;", + "O12,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;", + "O34,Stereo mix,None,25%,50%,100%;", + "-;", + "O67,CPU Speed,3.5MHz,7MHz,14MHz;", + "O8,CPU Cache,On,Off;", + "O9A,#7FFD span,128K,128K Auto,1024K,512K;", + "OLN,ZX Palette,Default,B.black,Light,Pale,Dark,Grayscale,Custom;", + "OO,NGS Reset,Off,On;", + "OPR,INT Offset,2,3,4,5,6,7,0,1;", + "-;", + "OBD,F11 Reset,boot.$C,sys.rom,ROM #00,ROM #04,RAM #F8;", + "OEF, bank,TR-DOS,Basic 48,Basic 128,SYS;", + "OGI,Shift+F11 Reset,ROM #00,ROM #04,RAM #F8,boot.$C,sys.rom;", + "OJK, bank,Basic 128,SYS,TR-DOS,Basic 48;", + "-;", + "R0,Reset and apply settings;", + "J,Fire 1,Fire 2;", + "V,v1.00.",`BUILD_DATE +}; + +wire [27:0] CMOSCfg; + +// fix default values +assign CMOSCfg[5:0] = 0; +assign CMOSCfg[7:6] = status[7:6]; +assign CMOSCfg[8] = ~status[8]; +assign CMOSCfg[10:9] = status[10:9] + 1'd1; +assign CMOSCfg[13:11]= (status[13:11] < 2) ? status[13:11] + 3'd3 : status[13:11] - 3'd2; +assign CMOSCfg[15:14]= status[15:14]; +assign CMOSCfg[18:16]= status[18:16]; +assign CMOSCfg[20:19]= status[20:19] + 2'd2; +assign CMOSCfg[23:21]= status[23:21]; +assign CMOSCfg[24] = status[24]; +assign CMOSCfg[27:25]= status[27:25] + 3'd2; + + +//////////////////// CLOCKS /////////////////// + +wire locked; +wire clk_mem; +wire clk_sys; +wire clk_28m; + +pll pll +( + .refclk(CLK_50M), + .rst(0), + .outclk_0(clk_mem), + .outclk_1(SDRAM_CLK), + .outclk_2(clk_sys), + .outclk_3(clk_28m), + .locked(locked) +); + +wire reset = RESET | status[0] | ~initReset_n | buttons[1]; + +reg initReset_n = 0; +always @(posedge clk_sys) begin + integer timeout = 0; + + if(timeout < 5000000) timeout <= timeout + 1; + else initReset_n <= 1; +end + +////////////////// HPS I/O /////////////////// +wire [5:0] joy_0; +wire [5:0] joy_1; +wire [15:0] joya_0; +wire [15:0] joya_1; +wire [1:0] buttons; +wire [31:0] status; +wire [24:0] ps2_mouse; +wire [10:0] ps2_key; + +wire forced_scandoubler; + +wire [31:0] sd_lba; +wire sd_rd; +wire sd_wr; +wire sd_ack; +wire [8:0] sd_buff_addr; +wire [7:0] sd_buff_dout; +wire [7:0] sd_buff_din; +wire sd_buff_wr; +wire img_mounted; +wire img_readonly; +wire [63:0] img_size; +wire sd_ack_conf; +wire [64:0] RTC; + +hps_io #(.STRLEN($size(CONF_STR)>>3)) hps_io +( + .clk_sys(clk_sys), + .HPS_BUS(HPS_BUS), + + .conf_str(CONF_STR), + + .joystick_0(joy_0), + .joystick_1(joy_1), + .joystick_analog_0(joya_0), + .joystick_analog_1(joya_1), + + .buttons(buttons), + .status(status), + .forced_scandoubler(forced_scandoubler), + + .RTC(RTC), + + .ps2_mouse(ps2_mouse), + .ps2_key(ps2_key), + + .sd_lba(sd_lba), + .sd_rd(sd_rd), + .sd_wr(sd_wr), + .sd_ack(sd_ack), + .sd_ack_conf(sd_ack_conf), + .sd_buff_addr(sd_buff_addr), + .sd_buff_dout(sd_buff_dout), + .sd_buff_din(sd_buff_din), + .sd_buff_wr(sd_buff_wr), + .img_mounted(img_mounted), + .img_readonly(img_readonly), + .img_size(img_size), + + .ioctl_wait(0) +); + + +wire [7:0] R,G,B; +wire HBlank,VBlank; +wire VSync, HSync; +wire ce_vid; + +wire [10:0] laudio, raudio; + +tsconf tsconf +( + .clk_84mhz(clk_mem), + .clk_28mhz(clk_28m), + + .SDRAM_DQ(SDRAM_DQ), + .SDRAM_A(SDRAM_A), + .SDRAM_BA(SDRAM_BA), + .SDRAM_DQML(SDRAM_DQML), + .SDRAM_DQMH(SDRAM_DQMH), + .SDRAM_WE_N(SDRAM_nWE), + .SDRAM_CAS_N(SDRAM_nCAS), + .SDRAM_RAS_N(SDRAM_nRAS), + .SDRAM_CKE(SDRAM_CKE), + .SDRAM_CS_N(SDRAM_nCS), + + .VGA_R(R), + .VGA_G(G), + .VGA_B(B), + .VGA_HS(HSync), + .VGA_VS(VSync), + .VGA_HBLANK(HBlank), + .VGA_VBLANK(VBlank), + .VGA_CEPIX(ce_vid), + + .SD_SO(sdmiso), + .SD_SI(sdmosi), + .SD_CLK(sdclk), + .SD_CS_N(sdss), + + .SOUND_L(laudio), + .SOUND_R(raudio), + + .ARESET(reset), + .RESET_OUT(), + .RTC(RTC), + + .CMOSCfg(CMOSCfg), + + .PS2_KEY(ps2_key), + .PS2_MOUSE(ps2_mouse), + .joystick(joy_0[5:0] | joy_1[5:0]) +); + +assign AUDIO_R = {raudio, 5'd0}; +assign AUDIO_L = {laudio, 5'd0}; +assign AUDIO_S = 0; +assign AUDIO_MIX = status[4:3]; + +reg ce_pix; +always @(posedge clk_sys) begin + reg old_ce; + + old_ce <= ce_vid; + ce_pix <= ~old_ce & ce_vid; +end + +assign CLK_VIDEO = clk_sys; + +wire [1:0] scale = status[2:1]; +video_mixer video_mixer +( + .*, + .ce_pix_out(CE_PIXEL), + + .scanlines({scale == 3, scale == 2}), + .scandoubler(scale || forced_scandoubler), + .hq2x(scale==1), + .mono(0) +); + + +////////////////// SD /////////////////// + +wire sdclk; +wire sdmosi; +wire sdmiso = vsd_sel ? vsdmiso : SD_MISO; +wire sdss; + +reg vsd_sel = 0; +always @(posedge clk_sys) if(img_mounted) vsd_sel <= |img_size; + +wire vsdmiso; +sd_card sd_card +( + .*, + .clk_spi(clk_sys), + + .sdhc(1), + + .sck(sdclk), + .ss(~vsd_sel | sdss), + .mosi(sdmosi), + .miso(vsdmiso) +); + +assign SD_CS = vsd_sel | sdss; +assign SD_SCK = sdclk & ~SD_CS; +assign SD_MOSI = sdmosi & ~SD_CS; + +reg sd_act; + +always @(posedge clk_sys) begin + reg old_mosi, old_miso; + integer timeout = 0; + + old_mosi <= sdmosi; + old_miso <= sdmiso; + + sd_act <= 0; + if(timeout < 1000000) begin + timeout <= timeout + 1; + sd_act <= 1; + end + + if((old_mosi ^ sdmosi) || (old_miso ^ sdmiso)) timeout <= 0; +end + +endmodule diff --git a/clean.bat b/clean.bat new file mode 100644 index 0000000..1de319e --- /dev/null +++ b/clean.bat @@ -0,0 +1,36 @@ +@echo off +del /s *.bak +del /s *.orig +del /s *.rej +del /s *~ +rmdir /s /q db +rmdir /s /q incremental_db +rmdir /s /q output_files +rmdir /s /q simulation +rmdir /s /q greybox_tmp +rmdir /s /q hc_output +rmdir /s /q .qsys_edit +rmdir /s /q hps_isw_handoff +rmdir /s /q sys\.qsys_edit +rmdir /s /q sys\vip +for /d %%i in (sys\*_sim) do rmdir /s /q "sys\%%~nxi" +for /d %%i in (*_sim) do rmdir /s /q "%%~nxi" +del build_id.v +del c5_pin_model_dump.txt +del PLLJ_PLLSPE_INFO.txt +del /s *.qws +del /s *.ppf +del /s *.ddb +del /s *.csv +del /s *.cmp +del /s *.sip +del /s *.spd +del /s *.bsf +del /s *.f +del /s *.sopcinfo +del /s *.xml +del *.cdf +del *.rpt +del /s new_rtl_netlist +del /s old_rtl_netlist +pause diff --git a/releases/SDCard.zip b/releases/SDCard.zip new file mode 100644 index 0000000..82e73d9 Binary files /dev/null and b/releases/SDCard.zip differ diff --git a/src/clock.v b/src/clock.v new file mode 100644 index 0000000..56f38e0 --- /dev/null +++ b/src/clock.v @@ -0,0 +1,51 @@ +// This module receives 28 MHz as input clock +// and strobes strobes for all clocked parts + +// clk|�__��__��__��__�| period = 28 duty = 50% phase = 0 +// cnt|< 0>< 1>< 2>< 3>| +// f0 |����____����____| period = 14 duty = 50% phase = 0 +// f1 |____����____����| period = 14 duty = 50% phase = 180 +// h0 |��������________| period = 7 duty = 50% phase = 0 +// h1 |________��������| period = 7 duty = 50% phase = 180 +// c0 |����____________| period = 7 duty = 25% phase = 0 +// c1 |____����________| period = 7 duty = 25% phase = 90 +// c2 |________����____| period = 7 duty = 25% phase = 180 +// c3 |____________����| period = 7 duty = 25% phase = 270 + +module clock ( + + input wire clk, + input wire [1:0] ay_mod, + + output reg f0, f1, + output reg h0, h1, + output reg c0, c1, c2, c3, + output wire ay_clk +); + + + reg [1:0] cnt; + + always @(posedge clk) + begin + cnt <= cnt + 2'b1; + + {f1, f0} <= 2'b1 << cnt[2'b0]; + {h1, h0} <= 2'b1 << cnt[2'b1]; + {c3, c2, c1, c0} <= 4'b1 << cnt; + end + +// AY clock generator + // ay_mod - clock selection for AY, MHz: 00 - 1.75 / 01 - 1.7733 / 10 - 3.5 / 11 - 3.546 + reg [7:0] skip_cnt; + reg [3:0] ay_cnt; + assign ay_clk = ay_mod[1] ? ay_cnt[2] : ay_cnt[3]; + + always @(posedge clk) + begin + skip_cnt <= skip_cnt[7] ? 8'd73 : skip_cnt - 8'd1; + ay_cnt <= ay_cnt + (skip_cnt[7] & ay_mod[0] ? 4'd2 : 4'd1); + end + + +endmodule diff --git a/src/cpu/cache_addr.v b/src/cpu/cache_addr.v new file mode 100644 index 0000000..088b8a6 --- /dev/null +++ b/src/cpu/cache_addr.v @@ -0,0 +1,222 @@ +// megafunction wizard: %RAM: 2-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: cache_addr.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 10.1 Build 153 11/29/2010 SJ Full Version +// ************************************************************ + + +//Copyright (C) 1991-2010 Altera Corporation +//Your use of Altera 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 Altera Program License +//Subscription Agreement, Altera 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 Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module cache_addr ( + clock, + data, + rdaddress, + wraddress, + wren, + q); + + input clock; + input [15:0] data; + input [8:0] rdaddress; + input [8:0] wraddress; + input wren; + output [15:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri0 wren; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [15:0] sub_wire0; + wire [15:0] q = sub_wire0[15:0]; + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({16{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone IV E", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 512, + altsyncram_component.numwords_b = 512, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "OLD_DATA", + altsyncram_component.widthad_a = 9, + altsyncram_component.widthad_b = 9, + altsyncram_component.width_a = 16, + altsyncram_component.width_b = 16, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLRdata NUMERIC "0" +// Retrieval info: PRIVATE: CLRq NUMERIC "0" +// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRrren NUMERIC "0" +// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRwren NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "0" +// Retrieval info: PRIVATE: Clock_A NUMERIC "0" +// Retrieval info: PRIVATE: Clock_B NUMERIC "0" +// Retrieval info: PRIVATE: ECC NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MEMSIZE NUMERIC "8192" +// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "./core_TSLab/video/mem/video_cram.mif" +// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "1" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +// Retrieval info: PRIVATE: REGdata NUMERIC "1" +// Retrieval info: PRIVATE: REGq NUMERIC "0" +// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +// Retrieval info: PRIVATE: REGrren NUMERIC "1" +// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +// Retrieval info: PRIVATE: REGwren NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +// Retrieval info: PRIVATE: VarWidth NUMERIC "0" +// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "16" +// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: enable NUMERIC "0" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "512" +// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "512" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "OLD_DATA" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "9" +// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "9" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_B NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]" +// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]" +// Retrieval info: USED_PORT: rdaddress 0 0 9 0 INPUT NODEFVAL "rdaddress[8..0]" +// Retrieval info: USED_PORT: wraddress 0 0 9 0 INPUT NODEFVAL "wraddress[8..0]" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +// Retrieval info: CONNECT: @address_a 0 0 9 0 wraddress 0 0 9 0 +// Retrieval info: CONNECT: @address_b 0 0 9 0 rdaddress 0 0 9 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 16 0 @q_b 0 0 16 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_bb.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_waveforms.html FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_wave*.jpg FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_addr.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_addr.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_addr.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_addr.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_addr_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_addr_bb.v TRUE +// Retrieval info: LIB_FILE: altera_mf diff --git a/src/cpu/cache_data.v b/src/cpu/cache_data.v new file mode 100644 index 0000000..c44a579 --- /dev/null +++ b/src/cpu/cache_data.v @@ -0,0 +1,222 @@ +// megafunction wizard: %RAM: 2-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: cache_data.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 10.1 Build 153 11/29/2010 SJ Full Version +// ************************************************************ + + +//Copyright (C) 1991-2010 Altera Corporation +//Your use of Altera 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 Altera Program License +//Subscription Agreement, Altera 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 Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module cache_data ( + clock, + data, + rdaddress, + wraddress, + wren, + q); + + input clock; + input [15:0] data; + input [8:0] rdaddress; + input [8:0] wraddress; + input wren; + output [15:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri0 wren; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [15:0] sub_wire0; + wire [15:0] q = sub_wire0[15:0]; + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({16{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone IV E", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 512, + altsyncram_component.numwords_b = 512, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + altsyncram_component.widthad_a = 9, + altsyncram_component.widthad_b = 9, + altsyncram_component.width_a = 16, + altsyncram_component.width_b = 16, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLRdata NUMERIC "0" +// Retrieval info: PRIVATE: CLRq NUMERIC "0" +// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRrren NUMERIC "0" +// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRwren NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "0" +// Retrieval info: PRIVATE: Clock_A NUMERIC "0" +// Retrieval info: PRIVATE: Clock_B NUMERIC "0" +// Retrieval info: PRIVATE: ECC NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MEMSIZE NUMERIC "8192" +// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "./core_TSLab/video/mem/video_cram.mif" +// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +// Retrieval info: PRIVATE: REGdata NUMERIC "1" +// Retrieval info: PRIVATE: REGq NUMERIC "0" +// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +// Retrieval info: PRIVATE: REGrren NUMERIC "1" +// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +// Retrieval info: PRIVATE: REGwren NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +// Retrieval info: PRIVATE: VarWidth NUMERIC "0" +// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "16" +// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: enable NUMERIC "0" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "512" +// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "512" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "9" +// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "9" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_B NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]" +// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]" +// Retrieval info: USED_PORT: rdaddress 0 0 9 0 INPUT NODEFVAL "rdaddress[8..0]" +// Retrieval info: USED_PORT: wraddress 0 0 9 0 INPUT NODEFVAL "wraddress[8..0]" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +// Retrieval info: CONNECT: @address_a 0 0 9 0 wraddress 0 0 9 0 +// Retrieval info: CONNECT: @address_b 0 0 9 0 rdaddress 0 0 9 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 16 0 @q_b 0 0 16 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_bb.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_waveforms.html FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_wave*.jpg FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_data.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_data.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_data.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_data.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_data_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL cache_data_bb.v TRUE +// Retrieval info: LIB_FILE: altera_mf diff --git a/src/cpu/zclock.v b/src/cpu/zclock.v new file mode 100644 index 0000000..36b7d44 --- /dev/null +++ b/src/cpu/zclock.v @@ -0,0 +1,138 @@ +// PentEvo project (c) NedoPC 2008-2011 +// +// Z80 clocking module, also contains some wait-stating when 14MHz +// +// IDEAL: +// clk _/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\_/`\ +// | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +// zclk /```\___/```\___/```\___/```````\_______/```````\_______/```````````````\_______________/```````````````\_______________/` +// | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +// zpos `\___/```\___/```\___/```\___________/```\___________/```\___________________________/```\___________________________/```\ +// | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +// zneg _/```\___/```\___/```\_______/```\___________/```\___________________/```\___________________________/```\________________ + +// clock phasing: +// c3 must be zpos for 7mhz, therefore c1 - zneg +// for 3.5 mhz, c3 is both zpos and zneg (alternating) + + +// 14MHz rulez: +// 1. do variable stalls for memory access. +// 2. do fallback on 7mhz for external IO accesses +// 3. clock switch 14-7-3.5 only at RFSH + +module zclock( + + input clk, + //output reg zclk_out, // generated Z80 clock - passed through inverter externally! + output wire zclk_out, + input c1, c3, c14Mhz, + + input wire iorq_s, + input wire external_port, + + output reg zpos, + output reg zneg, + output wire dos_stall_o, + +// stall enables and triggers + input wire cpu_stall, + input wire ide_stall, + input wire dos_on, + input wire vdos_off, + + input [1:0] turbo // 2'b00 - 3.5 MHz + // 2'b01 - 7.0 MHz + // 2'b1x - 14.0 MHz +); + reg zclk_o; + assign zclk_out = ~zclk_o; + assign dos_stall_o = !stall_count_end || dos_on; + //`ifdef SIMULATE +// initial // simulation... +// begin +// c2_cnt = 1'b0; +// turbo = 2'b00; +// old_rfsh_n = 1'b1; +// clk14_src = 1'b0; +// +// zclk_out = 1'b0; +// end +//`endif + + + + +// wait generator + wire dos_io_stall = stall_start || !stall_count_end; + wire stall_start = dos_stall || io_stall; + wire dos_stall = dos_on || vdos_off; + wire io_stall = iorq_s && external_port && turbo[1]; //- NOT WORK + wire stall_count_end = stall_count[3]; + + reg [3:0] stall_count; + always @(posedge clk) + if (stall_start) + begin + if (dos_stall) + stall_count <= 4'd4; // 4 tacts 28MHz (1 tact 7MHz) + else if (io_stall) + stall_count <= 4'd0; // 8 tacts 28MHz (1 tact 3.5MHz) + end + else if (!stall_count_end) + stall_count <= stall_count + 3'd1; + + +// Z80 clocking pre-strobes + wire pre_zpos = turbo[1] ? pre_zpos_140 : ( turbo[0] ? pre_zpos_70 : pre_zpos_35 ); + wire pre_zneg = turbo[1] ? pre_zneg_140 : ( turbo[0] ? pre_zneg_70 : pre_zneg_35 ); + + reg clk14_src; // source for 14MHz clock + always @(posedge clk) + if (!stall && !(c14Mhz == 1'b1 && !clk14_src)) // c14Mhz =c1 + //if (!stall) + clk14_src <= ~clk14_src; + + wire pre_zpos_140 = clk14_src; + wire pre_zneg_140 = ~clk14_src; + + wire pre_zpos_70 = c1; + wire pre_zneg_70 = c3; + + wire pre_zpos_35 = c1_cnt && c1; + wire pre_zneg_35 = !c1_cnt && c1; + + reg c1_cnt; + always @(posedge clk) if (c1) + c1_cnt <= ~c1_cnt; + + +// Z80 clocking strobes +//---------------INPUT----count generator- NO + wire stall = cpu_stall || dos_io_stall || ide_stall; + + always @(posedge clk) + begin + zpos <= !stall && pre_zpos && zclk_o; + zneg <= !stall && pre_zneg && !zclk_o; + end + + + // make Z80 clock: account for external inversion and make some leading of clock + // 9.5 ns propagation delay: from clk posedge to zclk returned back any edge + // (1/28)/2=17.9ns half a clock lead + // 2.6ns lag because of non-output register emitting of zclk_out + // total: 5.8 ns lead of any edge of zclk relative to posedge of clk => ACCOUNT FOR THIS WHEN DOING INTER-CLOCK DATA TRANSFERS + + // Z80 clocking + always @(negedge clk) + begin + if (zpos) + zclk_o <= 1'b0; + + if (zneg) + zclk_o <= 1'b1; + end + + +endmodule diff --git a/src/cpu/zint.v b/src/cpu/zint.v new file mode 100644 index 0000000..c3e8ac4 --- /dev/null +++ b/src/cpu/zint.v @@ -0,0 +1,123 @@ + +module zint +( + input wire clk, + input wire zclk, + input wire res, + input wire int_start_frm, + input wire int_start_lin, + input wire int_start_dma, + input wire vdos, + input wire intack, + + //input wire [2:0] im2v_frm, + //input wire [2:0] im2v_lin, + //input wire [2:0] im2v_dma, + input wire [7:0] intmask, + output wire [7:0] im2vect, + + output wire int_n +); + + // In VDOS INTs are focibly disabled. + // For Frame, Line INT its generation is blocked, it will be lost. + // For DMA INT only its output is blocked, so DMA ISR will will be processed as soon as returned from VDOS. + + // IM2 Vector priority ============ OLD + //assign im2vect = {vect[int_sel], 1'b1}; + //wire [6:0] vect [0:3]; + //assign vect[INTFRM] = {4'b1111, im2v_frm}; + //assign vect[INTLIN] = {4'b1110, im2v_lin}; + //assign vect[INTDMA] = {4'b1101, im2v_dma}; + //assign vect[INTDUM] = {4'b1101, im2v_dma}; + + //================================== NEW + assign im2vect = {vect[int_sel]}; + + wire [7:0] vect [0:3]; + assign vect[INTFRM] = 8'hFF; + assign vect[INTLIN] = 8'hFD; + assign vect[INTDMA] = 8'hFB; + assign vect[INTDUM] = 8'hFF; + + assign int_n = int_all ? 1'b0 : 1'b1; + wire int_all = int_frm || int_lin || (int_dma && !vdos); + + //=========================================================== + wire dis_int_frm = !intmask[0]; + wire dis_int_lin = !intmask[1]; + wire dis_int_dma = !intmask[2]; + + // ~INT source latch + wire intack_s = intack && !intack_r; + + reg intack_r; + always @(posedge clk) + intack_r <= intack; + + localparam INTFRM = 2'b00; + localparam INTLIN = 2'b01; + localparam INTDMA = 2'b10; + localparam INTDUM = 2'b11; + + reg [1:0] int_sel; + always @(posedge clk) + if (intack_s) + begin + if (int_frm) + int_sel <= INTFRM; // priority 0 + else if (int_lin) + int_sel <= INTLIN; // priority 1 + else if (int_dma) + int_sel <= INTDMA; // priority 2 + end + +// ~INT generating + reg int_frm; + always @(posedge clk) + if (res || dis_int_frm || vdos) + int_frm <= 1'b0; + else if (int_start_frm) + int_frm <= 1'b1; +// else if (intctr_fin || intack_s) // priority 0 + else if (intctr_fin) // MVV 01.11.2014 + int_frm <= 1'b0; + + reg int_lin; + always @(posedge clk) + if (res || dis_int_lin || vdos) + int_lin <= 1'b0; + else if (int_start_lin) + int_lin <= 1'b1; + else if (intack_s && !int_frm) // priority 1 + int_lin <= 1'b0; + + reg int_dma; + always @(posedge clk) + if (res || dis_int_dma) + int_dma <= 1'b0; + else if (int_start_dma) + int_dma <= 1'b1; + else if (intack_s && !int_frm && !int_lin) // priority 2 + int_dma <= 1'b0; + + +// INT counter +// reg [4:0] intctr; +// wire intctr_fin = &intctr; // 32 clks +// ~INT counter + reg [5:0] intctr; + wire intctr_fin = intctr[5]; // 32 clks + + +// always @(posedge zclk, posedge int_start_lin) + always @(posedge zclk, posedge int_start_frm) // MVV 31.10.2014 + begin +// if (int_start_lin) + if (int_start_frm) // MVV 31.10.2014 + intctr <= 6'b000000; + else if (!intctr_fin) + intctr <= intctr + 6'b000001; + end + +endmodule diff --git a/src/cpu/zmaps.v b/src/cpu/zmaps.v new file mode 100644 index 0000000..b4604dc --- /dev/null +++ b/src/cpu/zmaps.v @@ -0,0 +1,59 @@ + +// This module makes mapping z80 memory accesses into FPGA EABs + +module zmaps( + +// Z80 controls + input wire clk, + input wire memwr_s, + input wire [15:0] a, + input wire [7:0] d, + +// config data + input wire [4:0] fmaddr, + +// FPRAM data + output wire [15:0] zmd, + output wire [7:0] zma, + +// DMA + input wire [15:0] dma_data, + input wire [7:0] dma_wraddr, + input wire dma_cram_we, + input wire dma_sfile_we, + +// FPRAM controls + output wire cram_we, + output wire sfile_we + +); + + +// addresses of files withing zmaps + localparam CRAM = 3'b000; + localparam SFYS = 3'b001; + + +// control signals + wire hit = (a[15:12] == fmaddr[3:0]) && fmaddr[4] && memwr_s; + + +// write enables + assign cram_we = dma_req ? dma_cram_we : (a[11:9] == CRAM) && a[0] && hit; + assign sfile_we = dma_req ? dma_sfile_we : (a[11:9] == SFYS) && a[0] && hit; + + +// LSB fetching + assign zma = dma_req ? dma_wraddr : a[8:1]; + assign zmd = dma_req ? dma_data : {d, zmd0}; // for a[0] = 1 + + reg [7:0] zmd0; + always @(posedge clk) + if (!a[0] && hit) + zmd0 <= d; // a[0] = 0 + +// DMA + wire dma_req = dma_cram_we || dma_sfile_we; + + +endmodule diff --git a/src/cpu/zmem.v b/src/cpu/zmem.v new file mode 100644 index 0000000..7042a17 --- /dev/null +++ b/src/cpu/zmem.v @@ -0,0 +1,312 @@ + +// PentEvo project (c) NedoPC 2008-2009 +// + + +module zmem( + + input wire clk, + input wire c0, c1, c2, c3, + input wire zneg, // strobes which show positive and negative edges of zclk + input wire zpos, + +// Z80 + input wire rst, + input wire [15:0] za, + output wire [ 7:0] zd_out, // output to Z80 bus + output wire zd_ena, // output to Z80 bus enable + + input wire opfetch, + input wire opfetch_s, + input wire mreq, + input wire memrd, + input wire memwr, + input wire memwr_s, + + input wire [ 1:0] turbo, // 2'b00 - 3.5, + // 2'b01 - 7.0, + // 2'b1x - 14.0 + input wire [3:0] cache_en, + input wire [3:0] memconf, + input wire [31:0] xt_page, + output wire [7:0] xtpage_0, + + output wire [4:0] rompg, + output wire csrom, + output wire romoe_n, + output wire romwe_n, + + output wire csvrom, + output wire dos, + output wire dos_on, + output wire dos_off, + output wire dos_change, + + output wire vdos, + output reg pre_vdos, + input wire vdos_on, + input wire vdos_off, + +// DRAM + output wire cpu_req, + output wire [20:0] cpu_addr, + output wire cpu_wrbsel, + input wire [15:0] cpu_rddata, + input wire cpu_next, + input wire cpu_strobe, + input wire cpu_latch, + output wire cpu_stall, // for zclock + + input wire loader, + + input wire testkey, // DEBUG!!! + input wire intt, // DEBUG!!! + output wire [3:0] tst + +); + + assign tst[0] = memwr && win0; + assign tst[1] = rw_en; + assign tst[2] = ramwr; + assign tst[3] = 1'b0; + + assign xtpage_0 = xtpage[0]; + //assign xtpage_0 = { 4'b0, vdos, memconf[2], ~dos, memconf[0]}; + + + //---SELECT ROM PAGE0--------- + //localparam DOS_RESET = 1'h1; //DOS-ON + localparam DOS_RESET = 1'h0; //DOS-OFF + +// pager + wire [1:0] win = za[15:14]; + wire win0 = ~|win; // PAGE 1,2,3 (not PAGE0) + // loader = 1 : при выборе Bank3 - ВСЕГДА ПОДКЛЮЧЕНА ВЕРХНЯЯ ПАМЯТЬ - vROM + // загружаю RОМ через Bank3, запись всегда разрешена + wire rw_en = !win0 || memconf[1] || vdos; // =1 : WRITE ENABLE for PAGE0 when memconf[1]=1 or vDOS + //memconf[1] = 1 BANK0 WR_EN, 0 - DIS + //wire rw_en = !win0 || memconf[3] || memconf[1] || vdos; // WRITE EN for ALL Win if -RAM + + wire [7:0] page = xtpage[win]; + + assign rompg = xtpage[0][4:0]; + assign csrom = 1'b0; // csvrom && !loader; // 1'b0; //- сигнал ЗАПРЕЩЕНИЯ ЗАПИСИ в ВИРУАЛЬНОЕ ПЗУ + + assign csvrom = win0 && !memconf[3] && !vdos; //- сигнал ДОСТУПА К ВИРУТАЛЬНОМУ ПЗУ + // memconf[3] = 1-RAM, =0-ROM + //assign csvrom = win0 && !memconf[3] && !vdos && !(memconf [1] && memwr); // - если WR EN - to RAM ??? + + + wire [7:0] xtpage[0:3]; + assign xtpage[0] = vdos ? 8'hFF : {xt_page[7:2], memconf[2] ? xt_page[1:0] : {~dos, memconf[0]}}; + assign xtpage[1] = xt_page[15:8]; + assign xtpage[2] = xt_page[23:16]; + assign xtpage[3] = xt_page[31:24]; //rampage[3] + + +// DOS signal control + assign dos_on = win0 && opfetch_s && (za[13:8]==6'h3D) && memconf[0] && !memconf[2]; + //assign dos_on = win0 && opfetch_s && (za[13:8]==6'h3D) && memconf[0]; + assign dos_off = !win0 && opfetch_s && !vdos; + //assign dos_off = !win0 && opfetch_s; + assign dos_change = (dos_off && dos_r) || (dos_on && !dos_r); + + //assign dos = (dos_on || dos_off) ^^ dos_r; // to make dos appear 1 clock earlier than dos_r + //assign dos = (dos_on || dos_r); + assign dos = (dos_on || dos_r) && !dos_off; + + reg dos_r; + always @(posedge clk) + if (rst) + //dos_r <= 1'b0; + dos_r <= DOS_RESET; //=1 ON + + else if (dos_off) + dos_r <= 1'b0; + else if (dos_on) + dos_r <= 1'b1; + + +// VDOS signal control + // vdos turn on/off is delayed till next opfetch due to INIR that writes right after iord cycle + assign vdos = opfetch ? pre_vdos : vdos_r; // vdos appears as soon as first opfetch + + reg vdos_r; + always @(posedge clk) + if (rst || vdos_off) + begin + pre_vdos <= 1'b0; + vdos_r <= 1'b0; + end + else if (vdos_on) + pre_vdos <= 1'b1; + else if (opfetch_s) + vdos_r <= pre_vdos; + +// =========================================================================== + +// Z80 controls + assign romoe_n = !memrd; + assign romwe_n = !(memwr && rw_en); + + wire ramreq = mreq && !csrom; + wire ramrd = memrd && !csrom; + wire ramwr = memwr && !csrom && rw_en; + + wire ramwr_s = memwr_s && !csrom && rw_en; + assign zd_ena = memrd && !csrom; + + assign cpu_req = turbo14 ? cpureq_14 : cpureq_357; + assign cpu_stall = turbo14 ? stall14 : stall357; + + wire turbo14 = turbo[1]; + +// 7/3.5MHz support ========================================= + wire cpureq_357 = (ramrd_zs && !cache_hit_en) || ramwr_zs; + wire stall357 = cpureq_357 && !cpu_next; + + wire ramwr_zs = ramwr && !ramwr_zr; + wire ramrd_zs = ramrd && !ramrd_zr; + + reg ramrd_zr, ramwr_zr; + always @(posedge clk) + if (c3 && !cpu_stall) + begin + ramrd_zr <= ramrd; + ramwr_zr <= ramwr; + end + +// 14MHz support ============================================ + // wait tables: + // + // M1 opcode fetch, dram_beg concurs with: + // c3: +3 + // c2: +4 + // c1: +5 + // c0: +6 + // + // memory read, dram_beg concurs with: + // c3: +2 + // c2: +3 + // c1: +4 + // c0: +5 + // + // memory write: no wait + // + // special case: if dram_beg pulses 1 when cpu_next is 0, + // unconditional wait has to be performed until cpu_next is 1, and + // then wait as if dram_beg would concur with c0 + + // memrd, opfetch - wait till c3 && cpu_next, + // memwr - wait till cpu_next + + wire cpureq_14 = dram_beg || pending_cpu_req; + //wire stall14 = stall14_ini || stall14_cyc || stall14_fin; //- not work + wire stall14 = stall14_ini || stall14_cyc; //WORK + + //wire dram_beg = (!cache_hit_en || ramwr) && zpos && ramreq_s_n; //modif N1 + wire dram_beg = (!cache_hit_en && ( memconf[3] ? 1'b1 : ramrd ) || ramwr) && zpos && ramreq_s_n; //-- N2 + //if BANK0-RAM, WR enable all time for 14 MHz + wire ramreq_s_n = ramreq_r_n && ramreq; + reg ramreq_r_n; + //always @(posedge clk) if (zneg) + always @(posedge clk) if (zpos) + ramreq_r_n <= !mreq; + + reg pending_cpu_req; + always @(posedge clk) + if (rst) + pending_cpu_req <= 1'b0; + else if (cpu_next && c3) + pending_cpu_req <= 1'b0; + else if (dram_beg) + pending_cpu_req <= 1'b1; + + wire stall14_ini = dram_beg && (!cpu_next || opfetch || memrd); // no wait at all in write cycles, if next dram cycle is available + wire stall14_cyc = memrd ? stall14_cycrd : !cpu_next; + + + reg stall14_cycrd; + always @(posedge clk) + if (rst) + stall14_cycrd <= 1'b0; + else if (cpu_next && c3) + stall14_cycrd <= 1'b0; + else if (dram_beg && (!c3 || !cpu_next) && (opfetch || memrd)) + stall14_cycrd <= 1'b1; + + reg stall14_fin; + always @(posedge clk) + if (rst) + stall14_fin <= 1'b0; + else if (stall14_fin && ((opfetch && cc[0]) || (memrd && cc[1]))) + stall14_fin <= 1'b0; + else if (cpu_next && c3 && cpu_req && (opfetch || memrd)) + stall14_fin <= 1'b1; + + wire [1:0] cc = turbo[0] ? {c1, c0} : {c2, c1}; // normal or overclock + +// address, data in and data out ============================================= + assign cpu_wrbsel = za[0]; + assign cpu_addr[20:0] = {page, za[13:1]}; + wire [15:0] mem_d = cpu_latch ? cpu_rddata : cache_d; + //assign zd_out = ~cpu_wrbsel ? cpu_rddata[7:0] : cpu_rddata[15:8]; + assign zd_out = ~cpu_wrbsel ? mem_d[7:0] : mem_d[15:8]; + +//================================================================= +// CACHE ==INPUT:ramwr,csvrom,cpu_addr,cpu_rddata ================= + + wire [7:0] ch_addr1 = cpu_addr[7:0]; + wire [12:0] cpu_hi_addr1 = cpu_addr[20:8]; + wire csvrom1 = csvrom; + + reg [7:0] ch_addr2; + reg [12:0] cpu_hi_addr2; + reg csvrom2; + always @(posedge clk) //- !clk + if (c0) // ready for cx ------------c1 -not stable + begin //------------c0 -0k + ch_addr2 <= cpu_addr[7:0]; //--c3 -not stable + cpu_hi_addr2 <= cpu_addr[20:8]; + csvrom2 <= csvrom; + end + //---------------------------------- + //=========================================================== + wire [12:0] cache_a; //address from CACHE + wire [15:0] cache_d; //data from CACHE + wire cache_v; //data valid + wire [1:0] cache_tmp; //empty 16bit: 2 cache_tmp + csvrom + 13cpu_hi_addr1 + + cache_data cache_data ( + .clock (clk), // -- CLK + .rdaddress ({csvrom1, ch_addr1}), // ADDR for RD + .wraddress (loader ? za[8:0] : cpu_strobe ? {csvrom2, ch_addr2} : {csvrom1, ch_addr1}),//WR + //-----------------CACHE DATA ------------------------- + .wren (loader ? 1'b1 : cpu_strobe), //c2 -strobe + .data (loader ? 16'b0 : cpu_rddata), //<===== + .q (cache_d) // ==> data from CACHE + ); + + cache_addr cache_addr ( + .clock (clk), //---- CLK + .rdaddress ({csvrom1, ch_addr1}), // + .wraddress (loader ? za[8:0] : cpu_strobe ? {csvrom2, ch_addr2} : {csvrom1, ch_addr1}), //WR + //--------------arbiter.cpu_strobe <= curr_cpu && cpu_rnw_r; + .q ({cache_tmp, cache_v, cache_a}), // valid, addr from CACHE + .data (loader ? 16'b0 : cpu_strobe ? {cache_tmp, 1'b1, cpu_hi_addr2} : {2'b0, 1'b0, 8'b0}), //wrdata + .wren (loader ? 1'b1 : (cpu_strobe || cache_inv)) //c2 -strobe + ); + //----------- + wire cache_hit = (cpu_hi_addr1 == cache_a) && cache_v; + //---ONLY RAM + //wire cache_hit = !csvrom1 && (cpu_hi_addr1 == cache_a) && cache_v; // asynchronous signal meaning that address requested by CPU is cached and valid + //---ONLY ROM + //wire cache_hit = csvrom1 && (cpu_hi_addr1 == cache_a) && cache_v; + + //wire cache_hit_en = (cache_hit && cache_en) ; + wire cache_hit_en = (cache_hit && (cache_en[win] || csvrom)) ; + wire cache_inv = ramwr_s && cache_hit; // cache invalidation should be only performed if write happens to cached address + + + +endmodule diff --git a/src/cpu/zports.v b/src/cpu/zports.v new file mode 100644 index 0000000..c48718f --- /dev/null +++ b/src/cpu/zports.v @@ -0,0 +1,716 @@ + +// PentEvo project (c) NedoPC 2008-2010 + +module zports( + + input wire zclk, // z80 clock + input wire clk, + + input wire [ 7:0] din, + output reg [ 7:0] dout, + output wire dataout, + input wire [15:0] a, + + input wire rst, // system reset + input wire loader, // + input wire opfetch, + + input wire rd, + input wire wr, + input wire rdwr, + + input wire iorq, + input wire iorq_s, + input wire iord, + input wire iord_s, + input wire iowr, + input wire iowr_s, + input wire iorw, + input wire iorw_s, + + output wire porthit, // when internal port hit occurs, this is 1, else 0; used for iorq1_n iorq2_n on zxbus + output wire external_port, // asserts for AY and VG93 accesses + + output wire zborder_wr , + output wire border_wr , + output wire zvpage_wr , + output wire vpage_wr , + output wire vconf_wr , + output wire gx_offsl_wr , + output wire gx_offsh_wr , + output wire gy_offsl_wr , + output wire gy_offsh_wr , + output wire t0x_offsl_wr, + output wire t0x_offsh_wr, + output wire t0y_offsl_wr, + output wire t0y_offsh_wr, + output wire t1x_offsl_wr, + output wire t1x_offsh_wr, + output wire t1y_offsl_wr, + output wire t1y_offsh_wr, + output wire tsconf_wr , + output wire palsel_wr , + output wire tmpage_wr , + output wire t0gpage_wr , + output wire t1gpage_wr , + output wire sgpage_wr , + output wire hint_beg_wr , + output wire vint_begl_wr, + output wire vint_begh_wr, + + output wire [31:0] xt_page, + + output reg [4:0] fmaddr, + //----Conf----------------- + output reg [7:0] sysconf, + output reg [7:0] memconf, + output reg [3:0] cacheconf, + //------------------------- + output reg [3:0] fddvirt, + + //output reg [2:0] im2v_frm, + //output reg [2:0] im2v_lin, + //output reg [2:0] im2v_dma, + output reg [7:0] intmask, + + output wire [8:0] dmaport_wr, + input wire dma_act, + + input wire dos, + input wire vdos, + output wire vdos_on, + output wire vdos_off, + + output wire ay_bdir, + output wire ay_bc1, + output wire covox_wr, + output wire beeper_wr, + + input wire [ 1:0] rstrom, + input wire tape_read, + +// IDE interface +// input wire [15:0] ide_in, +// output wire [15:0] ide_out, +// output wire ide_cs0_n, +// output wire ide_cs1_n, +// output wire ide_req, +// input wire ide_stb, +// input wire ide_ready, +// output reg ide_stall, + + input wire [ 4:0] keys_in, // keys (port FE) + input wire [ 7:0] mus_in, // mouse (xxDF) + input wire [ 5:0] kj_in, + + input wire vg_intrq, + input wire vg_drq, // from vg93 module - drq + irq read + output wire vg_cs_n, + output wire vg_wrFF, + output reg [1:0] drive_sel, // disk drive selection + +// SPI + output reg sdcs_n, + output wire sd_start, + output wire [ 7:0] sd_datain, + input wire [ 7:0] sd_dataout, + +// WAIT-ports related + output reg [ 7:0] gluclock_addr, + output reg [ 2:0] comport_addr, + output wire wait_start_gluclock, // begin wait from some ports + output wire wait_start_comport, // + output reg [ 7:0] wait_write, + input wire [ 7:0] wait_read, + //---COM PORT------------------------ + input wire [ 7:0] com_data_rx, + input wire [ 7:0] com_status, +//------------------------------ + output wire [ 7:0] TST, + input wire lock_conf + +); + + assign TST = 7'h00|sd_start; + + +///////////////////=========RESET ============================ + //---SELECT ROM PAGE0--------- + localparam DOS_RESET = 1'h1; //DOS-ON + //-----------rampage value after RESET -------------------- + localparam CPU_BANK_0_RESET = 8'h00; //not used for mode3 + localparam CPU_BANK_1_RESET = 8'h05; //VIDEO PAGE =5 + localparam CPU_BANK_2_RESET = 8'h02; //RAM PAGE =2 + localparam CPU_BANK_3_RESET = 8'h00; //WR 7FFD + + localparam MEMCONF_RESET = 8'h04; // xtpage[0] = xt_page[7:0], + localparam CACHECONF_RESET = 4'h0; // disable + //---SELECT PENTAGON Config-------------- + //localparam MEMCONF_RESET = 8'hC0; // MODE3, normal map + //rampage[3] <= (MODE3) {2'b0,7ffd[5],7ffd[7:6], 7ffd[2:0]}; -PENTAGON + //MEMCONF[0] : <=(WR 7FFD)7ffd[4]-ROM128 + //MEMCONF[1] :(W0_WE // WR_BANK0) 0-DIS, 1-ENA + //MEMCONF[2] :!W0_MAP - 0 for use MODE3 + //MEMCONF[3] : W0_RAM(BANK0) 0-ROM, 1-RAM + //MEMCONF[6:4]: + //MEMCONF[7:6]: LOCK128 + // 11 - MODE3 lock128_3 = 8'hC0; + ///============================== + localparam PORTFE = 8'hFE; + localparam PORTFD = 8'hFD; + localparam PORTXT = 8'hAF; + localparam PORTF7 = 8'hF7; + localparam COVOX = 8'hFB; + + localparam NIDE10 = 8'h10; + localparam NIDE11 = 8'h11; + localparam NIDE30 = 8'h30; + localparam NIDE50 = 8'h50; + localparam NIDE70 = 8'h70; + localparam NIDE90 = 8'h90; + localparam NIDEB0 = 8'hB0; + localparam NIDED0 = 8'hD0; + localparam NIDEF0 = 8'hF0; + localparam NIDE08 = 8'h08; + localparam NIDE28 = 8'h28; + localparam NIDE48 = 8'h48; + localparam NIDE68 = 8'h68; + localparam NIDE88 = 8'h88; + localparam NIDEA8 = 8'hA8; + localparam NIDEC8 = 8'hC8; + localparam NIDEE8 = 8'hE8; + + localparam VGCOM = 8'h1F; + localparam VGTRK = 8'h3F; + localparam VGSEC = 8'h5F; + localparam VGDAT = 8'h7F; + localparam VGSYS = 8'hFF; + + localparam KJOY = 8'h1F; + localparam KMOUSE = 8'hDF; + + localparam SDCFG = 8'h77; + localparam SDDAT = 8'h57; + + localparam COMPORT = 8'hEF; // F8EF..FFEF - rs232 ports + + + wire [7:0] loa=a[7:0]; + wire [7:0] hoa=a[15:8]; + + assign porthit = + ((loa==PORTFE) || (loa==PORTXT) || (loa==PORTFD) || (loa==COVOX)) + || ((loa==PORTF7) && !dos) +// || ide_all + || ((vg_port || vgsys_port) && dos) + || ((loa==KJOY) && !dos) + || (loa==KMOUSE) + || (((loa==SDCFG) || (loa==SDDAT)) && (!dos || vdos)) + || (loa==COMPORT); + +// wire ide_all = ide_even || ide_port11; +// wire ide_even = (loa[2:0] == 3'b000) && (loa[3] != loa[4]); // even ports +// wire ide_port11 = (loa==NIDE11); // 11 +// wire ide_port10 = (loa==NIDE10); // 10 +// wire ide_portc8 = (loa==NIDEC8); // C8 + + wire vg_port = (loa==VGCOM) | (loa==VGTRK) | (loa==VGSEC) | (loa==VGDAT); + wire vgsys_port = (loa==VGSYS); + + assign external_port = ((loa==PORTFD) & a[15]) // AY + || (((loa==VGCOM) || (loa==VGTRK) || (loa==VGSEC) || (loa==VGDAT)) && dos); + + assign dataout = porthit & iord & (~external_port); + + +// zclk-synchronous strobes + reg iowr_reg; + reg iord_reg; + reg port_wr; + reg port_rd; + + always @(posedge zclk) + begin + iowr_reg <= iowr; + iord_reg <= iord; + + if (!iowr_reg && iowr) + port_wr <= 1'b1; + else + port_wr <= 1'b0; + + if (!iord_reg && iord) + port_rd <= 1'b1; + else + port_rd <= 1'b0; + end + + +// wire no_ide = 1'b0; // this should be compiled conditionally + + +// reading ports + always @* + begin + dout = 8'hFF; + case (loa) + PORTFE: +// dout = {1'b1, tape_read, 1'b0, keys_in}; + dout = {1'b1, tape_read, 1'b1, keys_in}; // MVV 31.10.2014 + +// NIDE10,NIDE30,NIDE50,NIDE70,NIDE90,NIDEB0,NIDED0,NIDEF0,NIDE08,NIDE28,NIDE48,NIDE68,NIDE88,NIDEA8,NIDEC8,NIDEE8: +// dout = iderdeven; +// NIDE11: +// dout = iderdodd; + + PORTXT: //--hAF + begin + case (hoa) + + XSTAT: + dout = {1'b0, pwr_up_reg, 6'b000011}; // MVV IDE Video DAC Added (���������� ������� �������� $00AF. 2 ������� ���� ��������� ������: 0 (1� �������) ��� 3 (2�)) + //--ADDR h27AF + DMASTAT: //-8'h27 + dout = {dma_act, 7'b0}; + + RAMPAGE+8'd2, RAMPAGE+8'd3: + dout = rampage[hoa[1:0]]; + + default: + dout = 8'hFF; + + endcase + end + + VGSYS: + dout = {vg_intrq, vg_drq, 6'b111111}; + + KJOY: + dout = {2'b00, kj_in}; + KMOUSE: + dout = mus_in; + + SDCFG: + dout = 8'h00; // always SD inserted, SD is in R/W mode + SDDAT: + dout = sd_dataout; + + + PORTF7: + begin + if (!a[14] && (a[8] ^ dos) && gluclock_on) // $BFF7 - data i/o + dout = wait_read; + // dout = 8'h55; + else // any other $xxF7 port + dout = 8'hFF; + end + + COMPORT: // loa = EF // $F8EF..$FFEF ====== + begin + if (hoa[7:0] == 8'hF8) //COM RX DATA + dout = com_data_rx; + if (hoa[7:0] == 8'hFD) //COM STATUS DATA + dout = com_status; + end + + default: + dout = 8'hFF; + endcase + end + + +// power-up +// This bit is loaded as 1 while FPGA is configured +// and automatically reset to 0 after STATUS port reading + + reg pwr_up_reg; + reg pwr_up = 1'b1; + always @(posedge clk) + if (iord_s & (loa == PORTXT) & (hoa == XSTAT)) + begin + pwr_up_reg <= pwr_up; + pwr_up <= 1'b0; + end + + +// writing ports + +//#nnAF + localparam VCONF = 8'h00; + localparam VPAGE = 8'h01; + localparam GXOFFSL = 8'h02; + localparam GXOFFSH = 8'h03; + localparam GYOFFSL = 8'h04; + localparam GYOFFSH = 8'h05; + localparam TSCONF = 8'h06; + localparam PALSEL = 8'h07; + localparam XBORDER = 8'h0F; + + localparam T0XOFFSL = 8'h40; + localparam T0XOFFSH = 8'h41; + localparam T0YOFFSL = 8'h42; + localparam T0YOFFSH = 8'h43; + localparam T1XOFFSL = 8'h44; + localparam T1XOFFSH = 8'h45; + localparam T1YOFFSL = 8'h46; + localparam T1YOFFSH = 8'h47; + + localparam RAMPAGE = 8'h10; // this covers #10-#13 + localparam FMADDR = 8'h15; + localparam TMPAGE = 8'h16; + localparam T0GPAGE = 8'h17; + localparam T1GPAGE = 8'h18; + localparam SGPAGE = 8'h19; + localparam DMASADDRL = 8'h1A; + localparam DMASADDRH = 8'h1B; + localparam DMASADDRX = 8'h1C; + localparam DMADADDRL = 8'h1D; + localparam DMADADDRH = 8'h1E; + localparam DMADADDRX = 8'h1F; + + localparam SYSCONF = 8'h20; + localparam MEMCONF = 8'h21; + localparam HSINT = 8'h22; + localparam VSINTL = 8'h23; + localparam VSINTH = 8'h24; + localparam IM2VECT = 8'h25; + localparam INTFRM = 3'b000; + localparam INTLIN = 3'b001; + localparam INTDMA = 3'b010; + localparam DMALEN = 8'h26; + localparam DMACTRL = 8'h27; + localparam DMANUM = 8'h28; + localparam FDDVIRT = 8'h29; + localparam INTMASK = 8'h2A; + localparam CACHECONF = 8'h2B; + + localparam XSTAT = 8'h00; + localparam DMASTAT = 8'h27; + + assign dmaport_wr[0] = portxt_wr & (hoa == DMASADDRL); + assign dmaport_wr[1] = portxt_wr & (hoa == DMASADDRH); + assign dmaport_wr[2] = portxt_wr & (hoa == DMASADDRX); + assign dmaport_wr[3] = portxt_wr & (hoa == DMADADDRL); + assign dmaport_wr[4] = portxt_wr & (hoa == DMADADDRH); + assign dmaport_wr[5] = portxt_wr & (hoa == DMADADDRX); + assign dmaport_wr[6] = portxt_wr & (hoa == DMALEN); + assign dmaport_wr[7] = portxt_wr & (hoa == DMACTRL); + assign dmaport_wr[8] = portxt_wr & (hoa == DMANUM); + + assign zborder_wr = portfe_wr; + assign border_wr = (portxt_wr & (hoa == XBORDER)); + assign zvpage_wr = p7ffd_wr; + assign vpage_wr = (portxt_wr & (hoa == VPAGE )); + assign vconf_wr = (portxt_wr & (hoa == VCONF )); + assign gx_offsl_wr = (portxt_wr & (hoa == GXOFFSL)); + assign gx_offsh_wr = (portxt_wr & (hoa == GXOFFSH)); + assign gy_offsl_wr = (portxt_wr & (hoa == GYOFFSL)); + assign gy_offsh_wr = (portxt_wr & (hoa == GYOFFSH)); + assign t0x_offsl_wr = (portxt_wr & (hoa == T0XOFFSL)); + assign t0x_offsh_wr = (portxt_wr & (hoa == T0XOFFSH)); + assign t0y_offsl_wr = (portxt_wr & (hoa == T0YOFFSL)); + assign t0y_offsh_wr = (portxt_wr & (hoa == T0YOFFSH)); + assign t1x_offsl_wr = (portxt_wr & (hoa == T1XOFFSL)); + assign t1x_offsh_wr = (portxt_wr & (hoa == T1XOFFSH)); + assign t1y_offsl_wr = (portxt_wr & (hoa == T1YOFFSL)); + assign t1y_offsh_wr = (portxt_wr & (hoa == T1YOFFSH)); + assign tsconf_wr = (portxt_wr & (hoa == TSCONF)); + assign palsel_wr = (portxt_wr & (hoa == PALSEL)); + assign tmpage_wr = (portxt_wr & (hoa == TMPAGE)); + assign t0gpage_wr = (portxt_wr & (hoa == T0GPAGE)); + assign t1gpage_wr = (portxt_wr & (hoa == T1GPAGE)); + assign sgpage_wr = (portxt_wr & (hoa == SGPAGE)); + assign hint_beg_wr = (portxt_wr & (hoa == HSINT )); + assign vint_begl_wr = (portxt_wr & (hoa == VSINTL)); + assign vint_begh_wr = (portxt_wr & (hoa == VSINTH)); + + assign beeper_wr = portfe_wr; + wire portfe_wr = (loa==PORTFE) && iowr_s; + assign covox_wr = (loa==COVOX) && iowr_s; + wire portxt_wr = (loa==PORTXT) && iowr_s; + + reg [7:0] rampage[0:3]; + assign xt_page = {rampage[3], rampage[2], rampage[1], rampage[0]}; + + wire lock128 = lock128_3 ? 1'b0 : (lock128_2 ? m1_lock128 : memconf[6]); + wire lock128_2 = memconf[7:6] == 2'b10; // mode 2 + wire lock128_3 = memconf[7:6] == 2'b11; // mode 3 + + reg m1_lock128; + always @(posedge clk) + if (opfetch) + m1_lock128 <= !(din[7] ^ din[6]); + + + always @(posedge clk) + if (rst) + begin + fmaddr[4] <= 1'b0; + //im2v_frm <= 3'b111; + intmask <= 8'b1; + //fddvirt <= 4'b0; + fddvirt <= 4'b0001; // VIRTUAL DOS A driver virtual + sysconf <= 8'h01; // turbo 7 MHz + //------- + memconf <= MEMCONF_RESET; // mode=3, normal map + cacheconf <= CACHECONF_RESET; // no cache + //--------------------------------------------- + rampage[0] <= CPU_BANK_0_RESET; //8'h00; + rampage[1] <= CPU_BANK_1_RESET; //8'h05; + rampage[2] <= CPU_BANK_2_RESET; //8'h02; + rampage[3] <= CPU_BANK_3_RESET; //8'h00; + end + + else + if (p7ffd_wr) + begin + memconf[0] <= din[4]; //<= din[4] = ROM128 + rampage[3] <= {2'b0, lock128_3 ? {din[5], din[7:6]} : ({1'b0, lock128 ? 2'b0 : din[7:6]}), din[2:0]}; + end //lock128_3 = memconf[7:6] == 2'b11; // mode 3 + + else + if (portxt_wr) + begin + if (hoa[7:2] == RAMPAGE[7:2]) + rampage[hoa[1:0]] <= din; + if (hoa == FMADDR) + fmaddr <= din[4:0]; + if (hoa == SYSCONF) + begin + sysconf <= din; + cacheconf <= {4{din[2]}}; + end + if (hoa == CACHECONF) + cacheconf <= din[3:0]; + if (hoa == MEMCONF) // & !lock_conf + memconf <= din; + //================================ + //if (hoa == IM2VECT) + //begin + // if (din[6:4] == INTFRM) + // im2v_frm <= din[3:1]; + // if (din[6:4] == INTLIN) + // im2v_lin <= din[3:1]; + // if (din[6:4] == INTDMA) + // im2v_dma <= din[3:1]; + //end + //================================ + if (hoa == FDDVIRT) + fddvirt <= din[3:0]; + if (hoa == INTMASK) + intmask <= din; + end + + +// 7FFD port + wire p7ffd_wr = !a[15] && (loa==PORTFD) && iowr_s && !lock48; + + reg lock48; + always @(posedge clk) + if (rst) + lock48 <= 1'b0; + else if (p7ffd_wr && !lock128_3) + lock48 <= din[5]; + + +// AY control + wire ay_hit = (loa==PORTFD) & a[15]; + assign ay_bc1 = ay_hit & a[14] & iorw; + assign ay_bdir = ay_hit & iowr; +//=========================================== + + +// VG93 + wire virt_vg = fddvirt[drive_sel]; + + assign vg_cs_n = !(iorw && vg_port && dos && !vdos && !virt_vg); + assign vg_wrFF = wr && iorq_s && vgsys_port && dos && !vdos && !virt_vg; + + assign vdos_on = rdwr && iorq_s && (vg_port || vgsys_port) && dos && !vdos && virt_vg; + assign vdos_off = rdwr && iorq_s && vg_port && vdos; + + // write drive number + always @(posedge clk) + if (iowr_s && vgsys_port && dos) + drive_sel <= din[1:0]; + + +// SD card (Z-control?r compatible) + wire sdcfg_wr; + wire sddat_wr; + wire sddat_rd; + // if loader =1 should be ENABLE + assign sdcfg_wr = ((loa==SDCFG) && iowr_s && ((!dos || vdos)) || loader); + assign sddat_wr = ((loa==SDDAT) && iowr_s && ((!dos || vdos)) || loader); + assign sddat_rd = ((loa==SDDAT) && iord_s); + + // SDCFG write - sdcs_n control + always @(posedge clk) + if (rst) + sdcs_n <= 1'b1; + else if (sdcfg_wr) + sdcs_n <= din[1]; + + + // start signal for SPI module with resyncing to fclk + assign sd_start = sddat_wr || sddat_rd; + + + // data for SPI module + assign sd_datain = wr ? din : 8'hFF; + + +// xxF7 + wire portf7_wr = ((loa==PORTF7) && (a[8]==1'b1) && port_wr && (!dos || vdos)); + wire portf7_rd = ((loa==PORTF7) && (a[8]==1'b1) && port_rd && (!dos || vdos)); + + +// EFF7 port + reg [7:0] peff7; + always @(posedge clk) + if (rst) + peff7 <= 8'h00; + else if (!a[12] && portf7_wr && !dos) // #EEF7 in dos is not accessible + peff7 <= din; + + +// gluclock ports + wire gluclock_on = peff7[7] || dos; // in dos mode EEF7 is not accessible, gluclock access is ON in dos mode. + + always @(posedge zclk) + if (gluclock_on && portf7_wr) // gluclocks on + if( !a[13] ) // $DFF7 - addr reg + gluclock_addr <= din; + + + + +// write to wait registers + always @(posedge zclk) + begin + // gluclocks + if (gluclock_on && portf7_wr && !a[14]) // $BFF7 - data reg + wait_write <= din; + // com ports + else if (comport_wr) // $F8EF..$FFEF - comports + wait_write <= din; + end + + +// comports + wire comport_wr = ((loa==COMPORT) && port_wr); + wire comport_rd = ((loa==COMPORT) && port_rd); + + always @(posedge zclk) + if (comport_wr || comport_rd) + comport_addr <= a[10:8]; + + +// wait from wait registers + // ACHTUNG!!!! here portxx_wr are ON Z80 CLOCK! logic must change when moving to clk strobes + assign wait_start_gluclock = (gluclock_on && !a[14] && (portf7_rd || portf7_wr)); // $BFF7 - gluclock r/w + assign wait_start_comport = (comport_rd || comport_wr); + +// IDE ports + // do NOT generate IDE write, if neither of ide_wrhi|lo latches set and writing to NIDE10 +// wire ide_cs0 = ide_even && !ide_portc8; +// wire ide_cs1 = ide_portc8; +// wire ide_rd = rd && !(ide_rd_latch && ide_port10); +// wire ide_wr = wr && !(!ide_wrlo_latch && !ide_wrhi_latch && ide_port10); +// assign ide_req = iorq_s && ide_even && (ide_rd || ide_wr); +// assign ide_cs0_n = !ide_cs0; +// assign ide_cs1_n = !ide_cs1; + + +// always @(posedge clk) +// if (ide_req) +// ide_stall <= 1'b1; +// else if (ide_ready) +// ide_stall <= 1'b0; + + + // control read & write triggers, which allow nemo-divide mod to work. + // read trigger: +// reg ide_rd_trig; // nemo-divide read trigger +// always @(posedge zclk) +// begin +// if (ide_port10 && port_rd && !ide_rd_trig) +// ide_rd_trig <= 1'b1; +// else if (ide_all && (port_rd || port_wr)) +// ide_rd_trig <= 1'b0; +// end + + + // two triggers for write sequence +// reg ide_wrlo_trig, ide_wrhi_trig; // nemo-divide write triggers +// always @(posedge zclk) +// if (ide_all && (port_rd || port_wr)) +// begin +// if (ide_port11 && port_wr) +// ide_wrhi_trig <= 1'b1; +// else +// ide_wrhi_trig <= 1'b0; +// +// if (ide_port10 && port_wr && !ide_wrhi_trig && !ide_wrlo_trig) +// ide_wrlo_trig <= 1'b1; +// else +// ide_wrlo_trig <= 1'b0; +// end + + + // normal read: #10(low), #11(high) + // divide read: #10(low), #10(high) + // + // normal write: #11(high), #10(low) + // divide write: #10(low), #10(high) + +// reg [15:0] idewrreg; // write register, either low or high part is pre-written here, + // while other part is out directly from Z80 bus +// always @(posedge zclk) +// begin +// if (port_wr && ide_port11) +// idewrreg[15:8] <= din; + +// if (port_wr && ide_port10 && !ide_wrlo_trig) +// idewrreg[ 7:0] <= din; +// end + + + // generate read cycles for IDE as usual, except for reading #10 + // instead of #11 for high byte (nemo-divide). I use additional latch + // since 'ide_rd_trig' clears during second Z80 IO read cycle to #10 +// reg ide_rd_latch; // to save state of trigger during read cycle +// always @* +// if (!rd) +// ide_rd_latch <= ide_rd_trig; + +// reg ide_wrlo_latch, ide_wrhi_latch; // save state during write cycles +// always @* +// if (!wr) +// begin +// ide_wrlo_latch <= ide_wrlo_trig; // same for write triggers +// ide_wrhi_latch <= ide_wrhi_trig; +// end + + + // data read by Z80 from IDE +// wire idein_lo_rd = port_rd && ide_port10 && (!ide_rd_trig); // while high part is remembered here +// wire [7:0] iderdodd = iderdreg[15:8]; // read data from "odd" port (#11) +// wire [7:0] iderdeven = (ide_rd_latch && ide_port10) ? iderdreg[15:8] : iderdreg[7:0]; // to control read data from "even" ide ports (all except #11) + // wire [7:0] iderdeven = (ide_rd_latch && ide_port10) ? idehiin[7:0] : ide_in[7:0]; // to control read data from "even" ide ports (all except #11) + +// reg [15:0] iderdreg; + // reg [7:0] idehiin; // IDE high part read register: low part is read directly to Z80 bus, +// always @(posedge clk) +// if (ide_stb) +// iderdreg <= ide_in; + // if (idein_lo_rd) + // idehiin <= ide_in[15:8]; + + + // data written to IDE from Z80 +// wire [7:0] ideout1 = ide_wrhi_latch ? idewrreg[15:8] : din[ 7:0]; +// wire [7:0] ideout0 = ide_wrlo_latch ? idewrreg[ 7:0] : din[ 7:0]; +// assign ide_out = {ideout1, ideout0}; + +endmodule diff --git a/src/cpu/zsignals.v b/src/cpu/zsignals.v new file mode 100644 index 0000000..e435de7 --- /dev/null +++ b/src/cpu/zsignals.v @@ -0,0 +1,94 @@ + +// Decoding and strobing of z80 signals + +module zsignals( + +// clocks + input wire clk, + input wire zpos, + +// z80 interface input + input wire iorq_n, + input wire mreq_n, + input wire m1_n, + input wire rfsh_n, + input wire rd_n, + input wire wr_n, + +// Z80 signals + output wire m1, + output wire rfsh, + output wire rd, + output wire wr, + output wire iorq, + output wire mreq, + output wire rdwr, + output wire iord, + output wire iowr, + output wire iorw, + output wire memrd, + output wire memwr, + output wire memrw, + output wire opfetch, + output wire intack, + +// Z80 signals strobes, at fclk + output wire iorq_s, + output wire mreq_s, + output wire iord_s, + output wire iowr_s, + output wire iorw_s, + output wire memrd_s, + output wire memwr_s, + output wire memrw_s, + output wire opfetch_s +); + +// invertors + assign m1 = !m1_n; + assign rfsh = !rfsh_n; + assign rd = !rd_n; + assign wr = !wr_n; + +// requests + assign iorq = !iorq_n && m1_n; // this is masked by ~M1 to avoid port decoding on INT ack + assign mreq = !mreq_n && rfsh_n; // this is masked by ~RFSH to ignore refresh cycles as memory requests + +// combined + assign rdwr = rd || wr; + assign iord = iorq && rd; + assign iowr = iorq && wr; + assign iorw = iorq && rdwr; + assign memrd = mreq && rd; + assign memwr = mreq && !rd; + assign memrw = mreq && rdwr; + assign opfetch = memrd && m1; + assign intack = !iorq_n && m1; // NOT masked by M1 + +// strobed + assign iorq_s = iorq_r[0] && !iorq_r[1]; + assign mreq_s = mreq_r[0] && !mreq_r[1]; + assign iord_s = iorq_s && rd; + assign iowr_s = iorq_s && wr; + assign iorw_s = iorq_s && rdwr; + assign memrd_s = mreq_s && rd; + assign memwr_s = mreq_s && !rd; + assign memrw_s = mreq_s && rdwr; + assign opfetch_s = memrd_s && m1; + +// latch inputs on FPGA clock + reg [1:0] iorq_r, mreq_r; + always @(posedge clk) if (zpos) + begin + iorq_r[0] <= iorq; + mreq_r[0] <= mreq; + end + + always @(posedge clk) + begin + iorq_r[1] <= iorq_r[0]; + mreq_r[1] <= mreq_r[0]; + end + + +endmodule diff --git a/src/kempston_mouse.v b/src/kempston_mouse.v new file mode 100644 index 0000000..7169794 --- /dev/null +++ b/src/kempston_mouse.v @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// PS2-to-Kempston Mouse v2 +// (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 kempston_mouse +( + input clk_sys, + input reset, + + input [24:0] ps2_mouse, + + input [2:0] addr, + output sel, + output [7:0] dout +); + +assign dout = data; +assign sel = port_sel; + +reg [11:0] dx; +reg [11:0] dy; + +reg [7:0] data; +reg port_sel; +always @* begin + port_sel = 1; + casex(addr) + 3'b011: data = dx[7:0]; + 3'b111: data = dy[7:0]; + 3'bX10: data = ~{5'b00000,ps2_mouse[2], ps2_mouse[0], ps2_mouse[1]} ; + default: {port_sel,data} = 8'hFF; + endcase +end + +always @(posedge clk_sys) begin + reg old_status; + old_status <= ps2_mouse[24]; + + if(reset) begin + dx <= 128; // dx != dy for better mouse detection + dy <= 0; + end + else if(old_status != ps2_mouse[24]) begin + dx <= dx + {{4{ps2_mouse[4]}},ps2_mouse[15:8]}; + dy <= dy + {{4{ps2_mouse[5]}},ps2_mouse[23:16]}; + end +end + +endmodule diff --git a/src/keyboard.vhd b/src/keyboard.vhd new file mode 100644 index 0000000..5f4e514 --- /dev/null +++ b/src/keyboard.vhd @@ -0,0 +1,195 @@ +-------------------------------------------------------------------[28.07.2014] +-- KEYBOARD CONTROLLER USB HID scancode to Spectrum matrix conversion +------------------------------------------------------------------------------- +-- V0.1 05.10.2011 первая версия +-- V0.2 16.03.2014 измененмия в key_f (активная клавиша теперь устанавливается в '1') +-- V1.0 24.07.2014 доработан под USB HID Keyboard +-- V1.1 28.07.2014 добавлены спец клавиши +-- WXEDA 10.03.2015 добавлен контроллер ps/2 + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity keyboard is +port ( + CLK : in std_logic; + RESET : in std_logic; + A : in std_logic_vector(7 downto 0); + KEYB : out std_logic_vector(4 downto 0); + KEYF : out std_logic_vector(4 downto 0); + SCANCODE : out std_logic_vector(7 downto 0); + PS2_KEY : in std_logic_vector(10 downto 0) +); +end keyboard; + +architecture rtl of keyboard is + +-- Internal signals +type key_matrix is array (11 downto 0) of std_logic_vector(4 downto 0); +signal keys : key_matrix; +signal row0, row1, row2, row3, row4, row5, row6, row7 : std_logic_vector(4 downto 0); +signal scan : std_logic_vector(7 downto 0); + +-- ps/2 signals +signal pressrelease_n : std_logic; +signal pressrelease : std_logic; + +signal flg : std_logic; + +begin + + -- Output addressed row to ULA + row0 <= keys(0) when A(0) = '0' else (others => '1'); + row1 <= keys(1) when A(1) = '0' else (others => '1'); + row2 <= keys(2) when A(2) = '0' else (others => '1'); + row3 <= keys(3) when A(3) = '0' else (others => '1'); + row4 <= keys(4) when A(4) = '0' else (others => '1'); + row5 <= keys(5) when A(5) = '0' else (others => '1'); + row6 <= keys(6) when A(6) = '0' else (others => '1'); + row7 <= keys(7) when A(7) = '0' else (others => '1'); + KEYB <= row0 and row1 and row2 and row3 and row4 and row5 and row6 and row7; + + KEYF <= keys(9); + SCANCODE <= scan; + + pressrelease_n <= not ps2_key(9); + pressrelease <= ps2_key(9); + + process (CLK) begin + if rising_edge(CLK) then + flg <= ps2_key(10); + + if RESET = '1' then + keys(0) <= (others => '1'); + keys(1) <= (others => '1'); + keys(2) <= (others => '1'); + keys(3) <= (others => '1'); + keys(4) <= (others => '1'); + keys(5) <= (others => '1'); + keys(6) <= (others => '1'); + keys(7) <= (others => '1'); + keys(8) <= (others => '0'); + keys(9) <= (others => '0'); + scan <= (others => '0'); + else + if flg /= ps2_key(10) then + if (pressrelease = '1') then + scan <= ps2_key(7 downto 0); + else + scan <= (others => '1'); + end if; + + case ps2_key(7 downto 0) is + when X"12" => keys(0)(0) <= pressrelease_n; -- Left shift (CAPS SHIFT) + when X"59" => keys(0)(0) <= pressrelease_n; -- Right shift (CAPS SHIFT) + when X"1a" => keys(0)(1) <= pressrelease_n; -- Z + when X"22" => keys(0)(2) <= pressrelease_n; -- X + when X"21" => keys(0)(3) <= pressrelease_n; -- C + when X"2a" => keys(0)(4) <= pressrelease_n; -- V + + when X"1c" => keys(1)(0) <= pressrelease_n; -- A + when X"1b" => keys(1)(1) <= pressrelease_n; -- S + when X"23" => keys(1)(2) <= pressrelease_n; -- D + when X"2b" => keys(1)(3) <= pressrelease_n; -- F + when X"34" => keys(1)(4) <= pressrelease_n; -- G + + when X"15" => keys(2)(0) <= pressrelease_n; -- Q + when X"1d" => keys(2)(1) <= pressrelease_n; -- W + when X"24" => keys(2)(2) <= pressrelease_n; -- E + when X"2d" => keys(2)(3) <= pressrelease_n; -- R + when X"2c" => keys(2)(4) <= pressrelease_n; -- T + + when X"16" => keys(3)(0) <= pressrelease_n; -- 1 + when X"1e" => keys(3)(1) <= pressrelease_n; -- 2 + when X"26" => keys(3)(2) <= pressrelease_n; -- 3 + when X"25" => keys(3)(3) <= pressrelease_n; -- 4 + when X"2e" => keys(3)(4) <= pressrelease_n; -- 5 + + when X"45" => keys(4)(0) <= pressrelease_n; -- 0 + when X"46" => keys(4)(1) <= pressrelease_n; -- 9 + when X"3e" => keys(4)(2) <= pressrelease_n; -- 8 + when X"3d" => keys(4)(3) <= pressrelease_n; -- 7 + when X"36" => keys(4)(4) <= pressrelease_n; -- 6 + + when X"4d" => keys(5)(0) <= pressrelease_n; -- P + when X"44" => keys(5)(1) <= pressrelease_n; -- O + when X"43" => keys(5)(2) <= pressrelease_n; -- I + when X"3c" => keys(5)(3) <= pressrelease_n; -- U + when X"35" => keys(5)(4) <= pressrelease_n; -- Y + + when X"5a" => keys(6)(0) <= pressrelease_n; -- ENTER + when X"4b" => keys(6)(1) <= pressrelease_n; -- L + when X"42" => keys(6)(2) <= pressrelease_n; -- K + when X"3b" => keys(6)(3) <= pressrelease_n; -- J + when X"33" => keys(6)(4) <= pressrelease_n; -- H + + when X"29" => keys(7)(0) <= pressrelease_n; -- SPACE + --keys(8)(4) <= pressrelease; -- kempston fire + when X"14" => keys(7)(1) <= pressrelease_n; -- CTRL (Symbol Shift) + when X"3a" => keys(7)(2) <= pressrelease_n; -- M + when X"31" => keys(7)(3) <= pressrelease_n; -- N + when X"32" => keys(7)(4) <= pressrelease_n; -- B + + -- Cursor keys + when X"6b" => keys(0)(0) <= pressrelease_n; -- Left (CAPS 5) + keys(3)(4) <= pressrelease_n; + --keys(8)(1) <= pressrelease; -- kempston left + when X"72" => keys(0)(0) <= pressrelease_n; -- Down (CAPS 6) + keys(4)(4) <= pressrelease_n; + --keys(8)(2) <= pressrelease; -- kempston down + when X"75" => keys(0)(0) <= pressrelease_n; -- Up (CAPS 7) + keys(4)(3) <= pressrelease_n; + --keys(8)(3) <= pressrelease; -- kempston up + when X"74" => keys(0)(0) <= pressrelease_n; -- Right (CAPS 8) + keys(4)(2) <= pressrelease_n; + --keys(8)(0) <= pressrelease; -- kempston right + + -- Other special keys sent to the ULA as key combinations + when X"66" => keys(0)(0) <= pressrelease_n; -- Backspace (CAPS 0) + keys(4)(0) <= pressrelease_n; + when X"58" => keys(0)(0) <= pressrelease_n; -- Caps lock (CAPS 2) + keys(3)(1) <= pressrelease_n; + when X"0d" => keys(0)(0) <= pressrelease_n; -- Tab (CAPS SPACE) + keys(7)(0) <= pressrelease_n; + when X"49" => keys(7)(2) <= pressrelease_n; -- . + keys(7)(1) <= pressrelease_n; + when X"4e" => keys(6)(3) <= pressrelease_n; -- - + keys(7)(1) <= pressrelease_n; + when X"0e" => keys(3)(0) <= pressrelease_n; -- ` (EDIT) + keys(0)(0) <= pressrelease_n; + when X"41" => keys(7)(3) <= pressrelease_n; -- , + keys(7)(1) <= pressrelease_n; + when X"4c" => keys(5)(1) <= pressrelease_n; -- ; + keys(7)(1) <= pressrelease_n; + when X"52" => keys(5)(0) <= pressrelease_n; -- " + keys(7)(1) <= pressrelease_n; + when X"5d" => keys(0)(1) <= pressrelease_n; -- : + keys(7)(1) <= pressrelease_n; + when X"55" => keys(6)(1) <= pressrelease_n; -- = + keys(7)(1) <= pressrelease_n; + when X"54" => keys(4)(2) <= pressrelease_n; -- ( + keys(7)(1) <= pressrelease_n; + when X"5b" => keys(4)(1) <= pressrelease_n; -- ) + keys(7)(1) <= pressrelease_n; + when X"4a" => keys(0)(3) <= pressrelease_n; -- ? + keys(7)(1) <= pressrelease_n; + -------------------------------------------- + + -- Soft keys + when X"78" => keys(9)(1) <= pressrelease; -- F11 + when X"07" => keys(9)(0) <= pressrelease; -- F12 + + -- Hardware keys + when X"7c" => keys(9)(2) <= pressrelease; -- PrtScr + when X"7e" => keys(9)(3) <= pressrelease; -- Scroll Lock + when X"48" => keys(9)(4) <= pressrelease; -- Pause + + when others => null; + end case; + end if; + end if; + end if; + end process; + +end architecture; diff --git a/src/loader_fat32/.DS_Store b/src/loader_fat32/.DS_Store new file mode 100644 index 0000000..8df2c50 Binary files /dev/null and b/src/loader_fat32/.DS_Store differ diff --git a/src/loader_fat32/bin2hex.py b/src/loader_fat32/bin2hex.py new file mode 100644 index 0000000..dcb6214 --- /dev/null +++ b/src/loader_fat32/bin2hex.py @@ -0,0 +1,318 @@ +#!/usr/bin/env python +""" +File: bin2hex.py +Converts a binary file into intel hex format. For usage try $bin2hex.py -h +License +The MIT License +Permission is hereby granted, free of charge, to any person obtaining a +copy of this hardware, software, and associated documentation files (the +"Product"), to deal in the Product without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Product, and to permit +persons to whom the Product is furnished to do so, subject to the +following conditions: +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Product. +THE PRODUCT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +PRODUCT OR THE USE OR OTHER DEALINGS IN THE PRODUCT. +""" + +import sys +import os +import errno +import optparse +import struct + +HEX_TYPE_DATA = 0 +HEX_TYPE_EOF = 1 +HEX_TYPE_EXT_SEG_ADDRESS = 2 +HEX_TYPE_START_SEG_ADDRESS = 3 +HEX_TYPE_EXT_LINEAR_ADDRESS = 4 +HEX_TYPE_START_LINEAR_ADDRESS = 5 + +HEX_ALLOWED_ADDRESS_TYPES ={ + 0:(1<<16)-1, + 2:(1<<20)-1, + 4:(1<<32)-1, + } + +class HexRecord: + def __init__(self, type, data, checksum = None, address = 0): + self.__type = type + self.__data = data + self.__length = len(data) + self.__address = address + + self.__checksum = self.__length + (address >> 8) + (address & 0xFF) + type + for b in data: + self.__checksum += b + self.__checksum = (~self.__checksum) + 1 + self.__checksum = self.__checksum & 0xFF + if (checksum is not None) and (self.__checksum != checksum): + raise Exception("Error: Checksum does not match. Calculated %02X. Given %02X." % (self.__checksum, checksum)) + + def getType(self): + return self.__type + + def getData(self): + return self.__data + + def getAddress(self): + return self.__address + + def getRecord(self): + # return string representation of the record. + recordstr = ":%02X%04X%02X%s%02X" % (self.__length, + self.__address, + self.__type, + "".join(["%02X" % b for b in self.__data]), + self.__checksum) + return recordstr + + def write(self, stream=sys.stdout): + # write the record to stream + stream.write(":%02X%04X%02X" % (self.__length, self.__address, self.__type)) + for b in self.__data: + stream.write("%02X" % b) + stream.write("%02X\n" % self.__checksum) + + +def readHexFile(stream): + records = [] + lineNum = 0 + for line in stream: + lineNum += 1 + line = line.strip() + if len(line) == 0: + break + + if line[0] != ":": + raise Exception("Error on line %d. Record does not start with ':' character. Starts with '%s'." % (lineNum, line[0])) + + byteCount = int(line[1:3], 16) + address = int(line[3:7], 16) + type = int(line[7:9], 16) + if len(line) != (11 + 2*byteCount): + raise Exception("Bad byteCount on line %d lineNum. Line length is %d chars, expected %d for byteCount %d." % (lineNum, len(line), 11+2*byteCount, byteCount)) + + data = [] + for i in range(byteCount): + hexPair = line[(9+2*i):(9+2*i+2)] + byte = int(hexPair, 16) + data.append(byte) + + checkSum = int(line[-2:], 16) + records.append(HexRecord(type, data, checkSum, address)) + + return records + +def generatehexfile(inputlist, hexsubsettype=4): + ''' From a sorted (by address) list of (address, binaryfilepath) tuples, + produce a hex file string and return it. Assumes arguments are OK. + Only hex subtype 4 is implemented. + ''' + + hexout = [] + + if (hexsubsettype == 4): + recordlength = 32 + elif (hexsubsettype == 2): + recordlength = 16 + else: + # not implemented + return ''.join(hexout) + + # current address and segment address are carried between subfiles. + curraddr = 0 + segaddr = 0 + for (addr, binfile) in inputlist: + # open the file for processing + with open(binfile, 'rb') as f: + fsize = os.path.getsize(binfile) + + # set starting address. + if addr >= (curraddr + segaddr): + curraddr = addr - segaddr + + else: + # shouldn't be out of order this way. error. + raise UserWarning("Error: binfiles are out of order. Contact tool smith.") + + # work through the file generating & storing records as we go + while f.tell() != fsize: + # check if we need a new segment + if (curraddr & 0xFFFF0000) != 0: + # set new segaddr + segaddr = (curraddr & 0xFFFF0000) + segaddr + + if hexsubsettype == 4: + hexout.append(HexRecord(HEX_TYPE_EXT_LINEAR_ADDRESS, [(segaddr >> 24) & 0xFF, (segaddr >> 16) & 0xFF]).getRecord()) + elif hexsubsettype == 2: + hexout.append(HexRecord(HEX_TYPE_EXT_SEG_ADDRESS, [(segaddr >> 12) & 0xFF, (segaddr >> 4) & 0xFF]).getRecord()) + else: + raise UserWarning("Error: somehow hexsubsettype is broken, contact tool smith.") + # advance address pointer + curraddr = curraddr & 0x0000FFFF + + # read up to recordlength bytes from the file, don't bridge segment. + if (curraddr + recordlength) > 0x10000: + bytestoread = (curraddr + recordlength) - 0x10000; + else: + bytestoread = recordlength + + bindata = f.read(bytestoread) + # bindata = struct.unpack('B'*len(bindata),bindata) # better to use ord actually + bindata = map(ord, bindata) + hexout.append(HexRecord(HEX_TYPE_DATA, bindata, address=curraddr).getRecord()) + curraddr += len(bindata) + + # add end of file record + hexout.append(HexRecord(HEX_TYPE_EOF, []).getRecord()) + + return hexout + +def checkhextypearg(option, opt, value, parser): + # check hex type argument + if value not in HEX_ALLOWED_ADDRESS_TYPES: + raise optparse.OptionValueError ("Error: HEX format subset type %d not acceptable."%value) + + setattr(parser.values, option.dest, value) + +def commandline_split(option, opt, value, parser): + # check the binary input + binlist = value.split(',') + if len(value.split(','))%2 != 0: + raise optparse.OptionValueError("Error: each input binary must have a corresponding address") + + # convert to list of lists of (address, binfile) + binlist = map(list, zip(*[iter(binlist)]*2)) + binlistout = [] + + # make sure each argument in each pair is OK + for [addr, binfile] in (binlist): + # convert address to int. int() will raise any format errors + rawaddr = addr + if addr.find('0x') == 0: + addr = int(addr, 16) + else: + addr = int(addr) + if addr > 0xFFFFFFFF: + raise optparse.OptionValueError("Error: address (%s, %s) exceeds 4gb."%(rawaddr, binfile)) + + # ensure binfile path is ok, and abs it. + if os.path.isfile(binfile): + binfile = os.path.abspath(binfile) + else: + raise optparse.OptionValueError("Error: binfile path (%s, %s) is unacceptable"%(rawaddr, binfile)) + + # save it to the output list as a tuple (unmodifiable after this), and + # save the converted values to a list for examination later + binlistout.append((addr, binfile)) + + # now check if any file(size) + address will overlap another + for i, binentry1 in enumerate(binlistout): + for j, binentry2 in enumerate(binlistout): + if (binentry1[0] < binentry2[0]) and (binentry1[0] + os.path.getsize(binentry1[1]) > binentry2[0]): + raise optparse.OptionValueError("Error: binfile entry %s overlaps %s"%(str(binlist[i]), str(binlist[j]))) + + # also check if addr + filesize is going to overflow 4gb limit + if binentry1[0] + os.path.getsize(binentry1[1]) > (1<<32)-1: + raise optparse.OptionValueError("Error: binfile entry %s exceeds 4gb limit"%(str(binlist[i]))) + + # sort the output list (by address) + binlistout.sort() + + setattr(parser.values, option.dest, binlistout) + +def process_command_line(argv=None): + ''' + Return a 2-tuple: (settings object, args list). + `argv` is a list of arguments, or `None` for ``sys.argv[1:]``. + ''' + if argv is None: + if len(sys.argv[1:]): + argv = sys.argv[1:] + else: + argv = ['-h'] + + # initialize the parser object: + parser = optparse.OptionParser( + formatter=optparse.TitledHelpFormatter(width=70), + add_help_option=None) + + # define options here: + parser.add_option('-r', '--format', dest='format', type="int", + default=4, action='callback', callback=checkhextypearg, + help='HEX format subtype. 0 is I8HEX, 2 is I16HEX, 4 is I32HEX. Default is %default. ONLY 2 AND 4 ACCEPTED RIGHT NOW.') + parser.add_option('-b', '--binaries', dest='binaries', type='string', + default=None, action='callback', callback=commandline_split, + help='List of binary file inputs and start addresses. Addresses are either decimal or hex (must be prepended with 0x).', metavar='ADDRESS,FILE,ADDRESS,FILE,...') + parser.add_option('-o', '--outfile', dest='outfile', + default=None, + help='Output file path, optional, defaults to first input binary file dot hex.', metavar='PATH') + parser.add_option('-q', '--quiet',action="store_true", dest="quiet", + default=False, + help="Suppress non-critical output on stdout.") + parser.add_option('-v', '--version',dest='version', + action="store_true", + default=False, + help='Print version and exit.') + parser.add_option('-h', '--help', action='help', + help='Show this help message and exit.') + + settings, args = parser.parse_args(argv) + + # check number of arguments, verify values, etc.: + if args: + parser.error('error in arguments; ' + '"%s" ignored.' % (args,)) + + # further process settings & args if necessary + + return settings, args + +if __name__ == "__main__": + # set args and evaluate them + # http://docs.python.org/2/library/optparse.html#optparse-extending-optparse + settings,args = process_command_line() + if settings.version: + print "bin2hex.py %s"%("0.1") + sys.exit(0) + + # make sure the selected hex record type can represent the largest address + maxaddress = HEX_ALLOWED_ADDRESS_TYPES[settings.format] + for (addr, binfile) in settings.binaries: + # don't check filesize, if it's good enough for gnu objcopy it's ok for us. + #if (addr + os.path.getsize(binfile)) > maxaddress: + #print "Error, address+binfile size 0x%0X is too large for format!"%(addr + os.path.getsize(binfile)) + if addr > maxaddress: + print "Error, address size 0x%0X is too large for format!"%(addr) + exit(errno.EINVAL) + + # check output file + try: + if settings.outfile is None: + # set output file based on first input file. + settings.outfile = os.path.splitext(settings.binaries[0][1])[0]+".hex" + # raise ValueError("Output file must be set!") + + # now check the output file, make sure we can open it + with open(settings.outfile, 'w') as f: + pass + except Exception as inst: + print "Error with output file: %s"%inst + sys.exit(errno.EINVAL) + + # now, produce the hex file from the input files and addresses + hexfiledata = generatehexfile(settings.binaries, settings.format) + + # save it to the selected output file + with open(settings.outfile, 'w') as f: + f.write('\n'.join(hexfiledata)) + f.write('\n') # trailing newline + diff --git a/src/loader_fat32/loader.asm b/src/loader_fat32/loader.asm new file mode 100644 index 0000000..bd00157 --- /dev/null +++ b/src/loader_fat32/loader.asm @@ -0,0 +1,214 @@ + DEVICE ZXSPECTRUM48 +; ----------------------------------------------------------------------------- +; LOADER(FAT32) +; ----------------------------------------------------------------------------- +TX_Port EQU #F8EF +;-----CONST----- +TOTAL_PAGE EQU 31 ; 31(512kB ROM) //+ 2 (32kB) GS ROM +Start EQU #0000 ; BANK0 (ROM) +;================== LOADER EXEC CODE ========================================== + ORG Start ; Exec code - Bank0: + JP StartProg + ;- LOADER ID ------------------------- + ;DB "LOADER(FAT32) V2.0/2014.09.10 | " + ;DB "LOADED FILES:" + ;- Name of ROMs files----------------- +FES1 DB #10 ;flag (#00 - file, #10 - dir) + DB "ROMS" ;DIR name + DB 0 + ;------ +FES2 DB #00 ;flag (#00 - file, #10 - dir) + DB "ZXEVO.ROM" ;file name //"TEST128.ROM" + DB 0 + ;------------------------------------- + ;------ +;FES3 DB #00 ;flag (#00 - file, #10 - dir) +; DB "GS105A.ROM" ;file name - 32kB +; DB 0 + ;ORG #F0 + ;DB "Start Prog 0x100" +;======================================================================= + ;ORG #100 ; Reserve 512byte +StartProg + DI ; DISABLE INT (PAGE2) + LD SP,PWA ; STACK_ADDR = BUFZZ+#4000; 0xC000-x + LD BC,SYC,A,DEFREQ:OUT(C), A ;SET DEFREQ:%00000010-14MHz + ; STACK - + ;---PAGE3 + LD B,PW3/256 : IN A,(C) ;READ PAGE3 //PW3:#13AF + LD (PGR3),A ;(PGR3) <- SAVE orig PAGE3 + ;---PAGE2 + LD B,PW2/256 : IN A,(C) ;READ PAGE2 //PW2:#12AF + LD E,PG0: OUT (C),E ;SET PAGE2=0xF7 + LD (PGR),A ;(PGR) <- SAVE orig PAGE2 + ;======================================================= + +;=============== SD_LOADER======================================== +SD_LOADER + ;step_1 ======== INIT SD CARD ======== + ;LD A, #00 + ;CALL COM_TX + ;------- + LD A, #00 ;STREAM: SD_INIT, HDD + CALL FAT_DRV + JR NZ,ERR ;INIT - FAILED + ;step_2 ======= find DIR entry ======= + LD HL,FES1 + LD A, #01 ;find DIR entry + CALL FAT_DRV + JR NZ,ERR ;dir not found + ;------------------------------------- + LD A, #02 ;SET CURR DIR - ACTIVE + CALL FAT_DRV + ;step_3 ======= find File entry ==== + LD HL,FES2 + LD A, #01 ;find File entry + CALL FAT_DRV + JR NZ,ERR ;file not found + ;step_4 ======= download data ======= + LD A, #0 ;#0 - start page + CALL FAT32_LOADER ; + ;step_5 ======= find File entry ====== + ;------------------------------------- +; LD HL,FES3 +; LD A, #01 ;find File entry +; CALL FAT_DRV +; JR NZ,ERR ;file not found + ;step_6 ======= download data ======== +; LD A, 32 ;32 - start page DEC +; CALL FAT32_LOADER ; + ;step_7 ======= INIT VS +; CALL VS_INIT + ;---------------------- + ;LD A, #01 + ;CALL COM_TX + ;---------------------- + JP RESET_LOADER +;======================================================================================== +FAT32_LOADER + ;----------- Open 1st Page = ROM ======================================== + ;LD A, #0 ;download in page #0 + LD (block_16kB_cnt), A ; RESTORE block_16kB_cnt + ;CALL COM_TX + ;------------------------------- + LD C, A ;page Number + LD DE,#0000 ;offset in PAGE: + LD B, 32 ;1 block-512Byte/32bloks-16kB + LD A, #3 ;code 3: LOAD512(TSFAT.ASM) c + CALL FAT_DRV ;return CDE - Address +;------------------------------------------------------------------------------------- +LOAD_16kb +;------------------------------------------------------------------------------------- + ;------------------------- II ---------------------------------------- + ;----------- Open 2snd Page = ROM + LD A,(block_16kB_cnt) ; A + INC A ; block_16kB_cnt+1 1 + LD (block_16kB_cnt), A ; + ;CALL COM_TX + ;----------- + LD C, A ;page + LD DE,#0000 ;offset in Win3: + LD B,32 ;1 block-512Byte // 32- 16kB + ;-load data from opened file------- + LD A, #3 ;LOAD512(TSFAT.ASM) + CALL FAT_DRV ; 16kB + JR NZ,EXIT_FAT32_LOADER ;EOF -EXIT + ;-----------CHECK CNT-------------------------------------------- + LD A,(block_16kB_cnt) ; A + SUB TOTAL_PAGE ; + JR NZ,LOAD_16kb ; , + ; LOAD_16kb + ;================================================================= + ;--------------- + ; JP VS_INIT + ; JP RESET_LOADER +EXIT_FAT32_LOADER + RET; +;------------------------------------------------------------------------------ +ERR +;------------------------------------------------------------------------------ + LD A,#02 ; ERROR: BORDER -RED!!!!!!!!!!!!!!!!!!!!!!!!!!! + OUT (#FE),A ; + HALT +;============================================================================== +;------------------------------------------------------------------------------ +; VS1053 Init +;------------------------------------------------------------------------------ +VS_INIT + LD A,%00000000 ; XCS=0 XDCS=0 + OUT (#05),A + LD HL,TABLE + LD B,44 +VS_INIT1 LD D,(HL) + CALL VS_RW ; WR D ==> + INC HL + DJNZ VS_INIT1 + LD A,%00100000 ; XCS=0 XDCS=1 + OUT (#05),A + RET +;============================================================================== + +;----------------RESTART------------------------------------------------------- +RESET_LOADER + ;---ESTORE PAGE3 + LD BC,PW3,A,(PGR3):OUT (C),A + ;---ESTORE PAGE2 + LD BC,PW2,A,(PGR) :OUT (C),A + ;-------------------------------------------------- + LD A,%00000100 ; Bit2 = 0:Loader ON, 1:Loader OFF; + LD BC,#0001 + OUT (C),A ; RESET LOADER + LD SP,#FFFF + JP #0000 ; RESTART SYSTEM + ;// 0x0000, LOADER OFF !!!!!!!!! +;================================ DRIVER ====================================== + ;========TS-Labs================================== + INCLUDE "tsfat/TSFAT.ASM" ; +;---------------BANK2---------------------- +PGR3 EQU STRMED+1 ; +block_16kB_cnt EQU STRMED+2 ; + +;------------------------------------------------------------------------------ +; VS1053 +;------------------------------------------------------------------------------ +VS_RW + IN A,(#05) + RLCA + JR C,VS_RW + RLCA + JR NC,VS_RW + LD A,D + OUT (#04), A ; WR DATA + +VS_RW1 IN A,(#05) + RLCA + JR C,VS_RW1 + RLCA + JR NC,VS_RW1 + IN A,(#04) + RET + +TABLE DB #52,#49,#46,#46,#FF,#FF,#FF,#FF ;REFF.... + DB #57,#41,#56,#45,#66,#6D,#74,#20 ;WAVEfmt + DB #10 + DB #00,#00,#00,#01,#00,#02,#00 + + DB #80,#BB,#00,#00 ;48kHz + DB #00,#EE,#02,#00 + + DB #04,#00 + DB #10,#00 + DB #64,#61,#74,#61 ;data + DB #FF,#FF,#FF,#FF +;===================== COM_TX ================================ +;COM_TX +; PUSH BC +; LD BC, #F8EF +; OUT (C), A +; POP BC +; RET +;============================================================= + savebin "loader.bin",Start, 8192 + ;savebin "loader.bin",Start, 2048 ;-2K + + diff --git a/src/loader_fat32/loader.bin b/src/loader_fat32/loader.bin new file mode 100644 index 0000000..19ce44e Binary files /dev/null and b/src/loader_fat32/loader.bin differ diff --git a/src/loader_fat32/loader.hex b/src/loader_fat32/loader.hex new file mode 100644 index 0000000..41df1b0 --- /dev/null +++ b/src/loader_fat32/loader.hex @@ -0,0 +1,257 @@ +:20000000C3140010524F4D5300005A5845564F2E524F4D00F33100C001AF203E02ED7906A0 +:2000200013ED78328FA00612ED781EF7ED59320D963E00CDBA00204B2103003E01CDBA0020 +:2000400020413E02CDBA002109003E01CDBA0020323E00CD5900C39D003290A04F110000B0 +:2000600006203E03CDBA003A90A03C3290A04F11000006203E03CDBA0020073A90A0D61FB6 +:2000800020E5C93E02D3FE763E00D305210C08062C56CDF6072310F93E20D305C901AF1380 +:2000A0003A8FA0ED7901AF123A0D96ED793E04010100ED7931FFFFC30000D921CE00060002 +:2000C0004F09097E23666F01CD00C5E5D9C9D6000A012D017901C52100A0545D1336000125 +:2000E0008D00EDB0C1CD5807CDBD062015CDC5032014210000220F96221196AF4FC93E188D +:20010000B7C93E08B7C93E0AB7C9CDD7022814220F96ED531196D9CD27012A3DA0ED5B3FE5 +:20012000A0AFC93E01B7C9210F96C37202210F96C370011121A00608CD5F01CD5001CC36C4 +:20014000067EFE2E2001230603CD5001CC3606C97EB7C8FE2E23C8121310F53E01B7C97E38 +:20016000FE2EC0122313057EFE2EC012231305C91181A0010400EDB0C9ED430B96EB7CE60B +:200180003F67CD8B01ED4B0B96EBC9AF3203A0CD9F01200478CDB8012A69A03A02A0C922C6 +:2001A00069A03A02A0B7C03A01A0B72009C52161A0CD7202C1C9AFC93204A02A1DA0ED5BF9 +:2001C0001FA0CD2E062104A03A4DA0ED4B01A091477EB7C89030038047AF77783205A02A9C +:2001E00069A0CD3D062269A0211DA01119A0010400EDB02A1DA0ED5B1FA0ED4B05A009306D +:200200000113221DA0ED531FA02101A0798677ED4B4DA0B9DABB012A61A0ED5B63A0CD28D5 +:2002200002CD7202CABB01C9CD6205CB21CB10CB21CB10C5ED530DA0220BA0ED4B4BA07A4E +:20024000B838107BB9380CED4B49A07CB838047DB9301CED4B5BA0CDC205CDC402CD2706BF +:200260002100903E01CD3D06C121009009AFC9C137C9CD1F065E2356237E23666FB4B3B24F +:2002800028347CE60FFE0F2836EB2261A0ED5363A0010200B7ED4230011B3A4DA0CDA805FF +:2002A000ED4B5DA0CDC205EBED4B5FA009EBCDC402CD2706AFC92A4FA0ED5B51A018CB32F3 +:2002C00002A0B7C9ED4B57A0ED4315A0ED4B59A0ED4317A0C3C6057E23322CA0CD33012181 +:2002E00081A01161A0010400EDB0CD1F063A02A0FE0FC82100920601CD8B01360021E091AB +:20030000CD0603C018E7012000097EB7C8CD160320F43E01B7C9E51121A0060BCD3E03CCC6 +:200320003703E1C0E51121A0012000EDB0C12A3BA0ED5B35A0AFC91A4F7EE610B9C91ABEDB +:20034000C0231310F9C9ED430496ED530896220696CD9003C8CD7103ED5B0496B7ED52D05E +:200360002A06965E2356237E23666FEBCD280218DD444D3A4DA02A089671237023732372C1 +:20038000232208963DC8030878B12001130818E95E2356237E23666FB4B3B2C87CFE0FC862 +:2003A000EB010200B7ED4230011B3A4DA0CDA805ED4B5DA0CDC205EBED4B5FA009EBCDC40C +:2003C000023E01B7C9210000545D2261A02263A0220696220896226CA0226EA0CD2706214B +:2003E00000923E01CD3D063E03326BA0320A9621C29311100006047EFE052872FE0B286E71 +:20040000FE0C286AFE0F28661910EC3A0A96B7CA5E05ED5B08962A0696CD27062100923E3B +:2004200001CD3D06216BA035CA500521CE930610AFB62310FCC250052AD693ED5BD8932280 +:2004400015A0ED5317A02A0696ED5B0896CDC605ED530896220696CD27062100923E01CD57 +:200460003D062AC693ED5BC893CDC605180D232323235E2356237E23666FEB2257A0ED5316 +:2004800059A0CD27062100923E01CD3D062A0B927C3D3DB5C20B043A0D92B7CA0B043A0E73 +:2004A00092B7CA0B043A1092B7CA0B042A11927CB52A1692B4B5C20B042A2492B4B52A260B +:2004C00092B4B5CA0B043A0D92324DA00608CB3F380410FA3E01B7C20B042A0E922242A05D +:2004E0002A3092110000CDC4022244A0ED5346A03A10923248A02A24922249A02A2692225B +:200500004BA02A2C92224FA02A2E922251A02A49A0ED5B4BA0ED4B48A00600CDDD05E5D525 +:200520002A42A0225BA0D1C1CDC205225DA0ED535FA02100002261A02263A02281A02283BD +:20054000A02153A00604AF772310FCCD1F06AFC92A6CA0ED5B6EA0AF320A96C37B043E0190 +:20056000B7C97D087D6C635A160017CB15CB14CB13CB1208E67F06004FC97D6C635A1600E2 +:20058000010100B7C4C2053E02FE02D80E00CB3FCB3ACB1BCB1CCB1DCB19CB3F30F279B7ED +:2005A000C8010100CDC205C9FE02D8CB3FCB25CB14CB13CB12CB3F30F4C9060434C0231080 +:2005C000FBC909D013C9EBED4B17A009EBED4B15A0093001132215A0ED5317A0C978414FFB +:2005E0000CB7200405282C04AFB820010D05E5C5626BB828041910FD470D20F9220FA0C19D +:20060000E1545DB8280619380B10FB470D20F7ED5B0FA0C9D92A0FA023220FA0D918EAAFA0 +:200620003201A03202A0C9221DA0ED531FA02289A0ED538BA0C93E20121310FCC9ED5B89C4 +:20064000A0ED4B8BA0083E52CD9F070808CDE307FEFE20F9CD6906083D20F13E4CCD85073B +:20066000CDE3073C20FAC34007C50EF77CFE803004ED4B0B96E63F5779E501AF13ED793E51 +:20068000C08267015700EDB200EDB200ED7800ED78E1110002197CFE40380EFE80300AE6A6 +:2006A0003F673A0B963C320B96C1C940000000009548000001AA875000000200FFCDC906E4 +:2006C000110200B7C0110000C9CD400701570011FF10ED591520FBAF0821AB06CD6A07CD20 +:2006E000E307083D286C083D20EF21B106CD6A07CDE307ED6000ED6000ED6000ED602100C1 +:2007000000CB57200226403E77CD8507CDE3073E69ED7900ED6100ED6900ED6900ED693ECF +:20072000FFED79CDE307A720DE3E7BCD8507CDE307A720F521B706CD6A07CDE307A720F4E5 +:20074000D5C51E03017700ED591E000E57ED59C1D1C9CD58073E01C9AFD377D357C9D5C542 +:200760000177001E01ED59C1D1C9CD5E07C5015700EDA300EDA300EDA300EDA300EDA30022 +:20078000EDA300C1C9C5CD5E07015700ED79AFED7900ED7900ED7900ED793DED79C1C9E531 +:2007A000D5C5F5C50157003E7ACD8507CDE307ED7800ED6000ED6000ED60CB77E1200AEB41 +:2007C00029EBED6A656A531E00F1015700ED7900ED6100ED6900ED5100ED593EFFED79C133 +:2007E000D1E1C9C5D511FF10015700ED78BB20031520F8D1C1C9DB050738FB0730F87AD30B +:2008000004DB050738FB0730F8DB04C952494646FFFFFFFF57415645666D74201000000016 +:200820000100020080BB000000EE02000400100064617461FFFFFFFF0000000000000000E0 +:20084000000000000000000000000000000000000000000000000000000000000000000098 +:20086000000000000000000000000000000000000000000000000000000000000000000078 +:20088000000000000000000000000000000000000000000000000000000000000000000058 +:2008A000000000000000000000000000000000000000000000000000000000000000000038 +:2008C000000000000000000000000000000000000000000000000000000000000000000018 +:2008E0000000000000000000000000000000000000000000000000000000000000000000F8 +:200900000000000000000000000000000000000000000000000000000000000000000000D7 +:200920000000000000000000000000000000000000000000000000000000000000000000B7 +:20094000000000000000000000000000000000000000000000000000000000000000000097 +:20096000000000000000000000000000000000000000000000000000000000000000000077 +:20098000000000000000000000000000000000000000000000000000000000000000000057 +:2009A000000000000000000000000000000000000000000000000000000000000000000037 +:2009C000000000000000000000000000000000000000000000000000000000000000000017 +:2009E0000000000000000000000000000000000000000000000000000000000000000000F7 +:200A00000000000000000000000000000000000000000000000000000000000000000000D6 +:200A20000000000000000000000000000000000000000000000000000000000000000000B6 +:200A4000000000000000000000000000000000000000000000000000000000000000000096 +:200A6000000000000000000000000000000000000000000000000000000000000000000076 +:200A8000000000000000000000000000000000000000000000000000000000000000000056 +:200AA000000000000000000000000000000000000000000000000000000000000000000036 +:200AC000000000000000000000000000000000000000000000000000000000000000000016 +:200AE0000000000000000000000000000000000000000000000000000000000000000000F6 +:200B00000000000000000000000000000000000000000000000000000000000000000000D5 +:200B20000000000000000000000000000000000000000000000000000000000000000000B5 +:200B4000000000000000000000000000000000000000000000000000000000000000000095 +:200B6000000000000000000000000000000000000000000000000000000000000000000075 +:200B8000000000000000000000000000000000000000000000000000000000000000000055 +:200BA000000000000000000000000000000000000000000000000000000000000000000035 +:200BC000000000000000000000000000000000000000000000000000000000000000000015 +:200BE0000000000000000000000000000000000000000000000000000000000000000000F5 +:200C00000000000000000000000000000000000000000000000000000000000000000000D4 +:200C20000000000000000000000000000000000000000000000000000000000000000000B4 +:200C4000000000000000000000000000000000000000000000000000000000000000000094 +:200C6000000000000000000000000000000000000000000000000000000000000000000074 +:200C8000000000000000000000000000000000000000000000000000000000000000000054 +:200CA000000000000000000000000000000000000000000000000000000000000000000034 +:200CC000000000000000000000000000000000000000000000000000000000000000000014 +:200CE0000000000000000000000000000000000000000000000000000000000000000000F4 +:200D00000000000000000000000000000000000000000000000000000000000000000000D3 +:200D20000000000000000000000000000000000000000000000000000000000000000000B3 +:200D4000000000000000000000000000000000000000000000000000000000000000000093 +:200D6000000000000000000000000000000000000000000000000000000000000000000073 +:200D8000000000000000000000000000000000000000000000000000000000000000000053 +:200DA000000000000000000000000000000000000000000000000000000000000000000033 +:200DC000000000000000000000000000000000000000000000000000000000000000000013 +:200DE0000000000000000000000000000000000000000000000000000000000000000000F3 +:200E00000000000000000000000000000000000000000000000000000000000000000000D2 +:200E20000000000000000000000000000000000000000000000000000000000000000000B2 +:200E4000000000000000000000000000000000000000000000000000000000000000000092 +:200E6000000000000000000000000000000000000000000000000000000000000000000072 +:200E8000000000000000000000000000000000000000000000000000000000000000000052 +:200EA000000000000000000000000000000000000000000000000000000000000000000032 +:200EC000000000000000000000000000000000000000000000000000000000000000000012 +:200EE0000000000000000000000000000000000000000000000000000000000000000000F2 +:200F00000000000000000000000000000000000000000000000000000000000000000000D1 +:200F20000000000000000000000000000000000000000000000000000000000000000000B1 +:200F4000000000000000000000000000000000000000000000000000000000000000000091 +:200F6000000000000000000000000000000000000000000000000000000000000000000071 +:200F8000000000000000000000000000000000000000000000000000000000000000000051 +:200FA000000000000000000000000000000000000000000000000000000000000000000031 +:200FC000000000000000000000000000000000000000000000000000000000000000000011 +:200FE0000000000000000000000000000000000000000000000000000000000000000000F1 +:201000000000000000000000000000000000000000000000000000000000000000000000D0 +:201020000000000000000000000000000000000000000000000000000000000000000000B0 +:20104000000000000000000000000000000000000000000000000000000000000000000090 +:20106000000000000000000000000000000000000000000000000000000000000000000070 +:20108000000000000000000000000000000000000000000000000000000000000000000050 +:2010A000000000000000000000000000000000000000000000000000000000000000000030 +:2010C000000000000000000000000000000000000000000000000000000000000000000010 +:2010E0000000000000000000000000000000000000000000000000000000000000000000F0 +:201100000000000000000000000000000000000000000000000000000000000000000000CF +:201120000000000000000000000000000000000000000000000000000000000000000000AF +:2011400000000000000000000000000000000000000000000000000000000000000000008F +:2011600000000000000000000000000000000000000000000000000000000000000000006F +:2011800000000000000000000000000000000000000000000000000000000000000000004F +:2011A00000000000000000000000000000000000000000000000000000000000000000002F +:2011C00000000000000000000000000000000000000000000000000000000000000000000F +:2011E0000000000000000000000000000000000000000000000000000000000000000000EF +:201200000000000000000000000000000000000000000000000000000000000000000000CE +:201220000000000000000000000000000000000000000000000000000000000000000000AE +:2012400000000000000000000000000000000000000000000000000000000000000000008E +:2012600000000000000000000000000000000000000000000000000000000000000000006E +:2012800000000000000000000000000000000000000000000000000000000000000000004E +:2012A00000000000000000000000000000000000000000000000000000000000000000002E +:2012C00000000000000000000000000000000000000000000000000000000000000000000E +:2012E0000000000000000000000000000000000000000000000000000000000000000000EE +:201300000000000000000000000000000000000000000000000000000000000000000000CD +:201320000000000000000000000000000000000000000000000000000000000000000000AD +:2013400000000000000000000000000000000000000000000000000000000000000000008D +:2013600000000000000000000000000000000000000000000000000000000000000000006D +:2013800000000000000000000000000000000000000000000000000000000000000000004D +:2013A00000000000000000000000000000000000000000000000000000000000000000002D +:2013C00000000000000000000000000000000000000000000000000000000000000000000D +:2013E0000000000000000000000000000000000000000000000000000000000000000000ED +:201400000000000000000000000000000000000000000000000000000000000000000000CC +:201420000000000000000000000000000000000000000000000000000000000000000000AC +:2014400000000000000000000000000000000000000000000000000000000000000000008C +:2014600000000000000000000000000000000000000000000000000000000000000000006C +:2014800000000000000000000000000000000000000000000000000000000000000000004C +:2014A00000000000000000000000000000000000000000000000000000000000000000002C +:2014C00000000000000000000000000000000000000000000000000000000000000000000C +:2014E0000000000000000000000000000000000000000000000000000000000000000000EC +:201500000000000000000000000000000000000000000000000000000000000000000000CB +:201520000000000000000000000000000000000000000000000000000000000000000000AB +:2015400000000000000000000000000000000000000000000000000000000000000000008B +:2015600000000000000000000000000000000000000000000000000000000000000000006B +:2015800000000000000000000000000000000000000000000000000000000000000000004B +:2015A00000000000000000000000000000000000000000000000000000000000000000002B +:2015C00000000000000000000000000000000000000000000000000000000000000000000B +:2015E0000000000000000000000000000000000000000000000000000000000000000000EB +:201600000000000000000000000000000000000000000000000000000000000000000000CA +:201620000000000000000000000000000000000000000000000000000000000000000000AA +:2016400000000000000000000000000000000000000000000000000000000000000000008A +:2016600000000000000000000000000000000000000000000000000000000000000000006A +:2016800000000000000000000000000000000000000000000000000000000000000000004A +:2016A00000000000000000000000000000000000000000000000000000000000000000002A +:2016C00000000000000000000000000000000000000000000000000000000000000000000A +:2016E0000000000000000000000000000000000000000000000000000000000000000000EA +:201700000000000000000000000000000000000000000000000000000000000000000000C9 +:201720000000000000000000000000000000000000000000000000000000000000000000A9 +:20174000000000000000000000000000000000000000000000000000000000000000000089 +:20176000000000000000000000000000000000000000000000000000000000000000000069 +:20178000000000000000000000000000000000000000000000000000000000000000000049 +:2017A000000000000000000000000000000000000000000000000000000000000000000029 +:2017C000000000000000000000000000000000000000000000000000000000000000000009 +:2017E0000000000000000000000000000000000000000000000000000000000000000000E9 +:201800000000000000000000000000000000000000000000000000000000000000000000C8 +:201820000000000000000000000000000000000000000000000000000000000000000000A8 +:20184000000000000000000000000000000000000000000000000000000000000000000088 +:20186000000000000000000000000000000000000000000000000000000000000000000068 +:20188000000000000000000000000000000000000000000000000000000000000000000048 +:2018A000000000000000000000000000000000000000000000000000000000000000000028 +:2018C000000000000000000000000000000000000000000000000000000000000000000008 +:2018E0000000000000000000000000000000000000000000000000000000000000000000E8 +:201900000000000000000000000000000000000000000000000000000000000000000000C7 +:201920000000000000000000000000000000000000000000000000000000000000000000A7 +:20194000000000000000000000000000000000000000000000000000000000000000000087 +:20196000000000000000000000000000000000000000000000000000000000000000000067 +:20198000000000000000000000000000000000000000000000000000000000000000000047 +:2019A000000000000000000000000000000000000000000000000000000000000000000027 +:2019C000000000000000000000000000000000000000000000000000000000000000000007 +:2019E0000000000000000000000000000000000000000000000000000000000000000000E7 +:201A00000000000000000000000000000000000000000000000000000000000000000000C6 +:201A20000000000000000000000000000000000000000000000000000000000000000000A6 +:201A4000000000000000000000000000000000000000000000000000000000000000000086 +:201A6000000000000000000000000000000000000000000000000000000000000000000066 +:201A8000000000000000000000000000000000000000000000000000000000000000000046 +:201AA000000000000000000000000000000000000000000000000000000000000000000026 +:201AC000000000000000000000000000000000000000000000000000000000000000000006 +:201AE0000000000000000000000000000000000000000000000000000000000000000000E6 +:201B00000000000000000000000000000000000000000000000000000000000000000000C5 +:201B20000000000000000000000000000000000000000000000000000000000000000000A5 +:201B4000000000000000000000000000000000000000000000000000000000000000000085 +:201B6000000000000000000000000000000000000000000000000000000000000000000065 +:201B8000000000000000000000000000000000000000000000000000000000000000000045 +:201BA000000000000000000000000000000000000000000000000000000000000000000025 +:201BC000000000000000000000000000000000000000000000000000000000000000000005 +:201BE0000000000000000000000000000000000000000000000000000000000000000000E5 +:201C00000000000000000000000000000000000000000000000000000000000000000000C4 +:201C20000000000000000000000000000000000000000000000000000000000000000000A4 +:201C4000000000000000000000000000000000000000000000000000000000000000000084 +:201C6000000000000000000000000000000000000000000000000000000000000000000064 +:201C8000000000000000000000000000000000000000000000000000000000000000000044 +:201CA000000000000000000000000000000000000000000000000000000000000000000024 +:201CC000000000000000000000000000000000000000000000000000000000000000000004 +:201CE0000000000000000000000000000000000000000000000000000000000000000000E4 +:201D00000000000000000000000000000000000000000000000000000000000000000000C3 +:201D20000000000000000000000000000000000000000000000000000000000000000000A3 +:201D4000000000000000000000000000000000000000000000000000000000000000000083 +:201D6000000000000000000000000000000000000000000000000000000000000000000063 +:201D8000000000000000000000000000000000000000000000000000000000000000000043 +:201DA000000000000000000000000000000000000000000000000000000000000000000023 +:201DC000000000000000000000000000000000000000000000000000000000000000000003 +:201DE0000000000000000000000000000000000000000000000000000000000000000000E3 +:201E00000000000000000000000000000000000000000000000000000000000000000000C2 +:201E20000000000000000000000000000000000000000000000000000000000000000000A2 +:201E4000000000000000000000000000000000000000000000000000000000000000000082 +:201E6000000000000000000000000000000000000000000000000000000000000000000062 +:201E8000000000000000000000000000000000000000000000000000000000000000000042 +:201EA000000000000000000000000000000000000000000000000000000000000000000022 +:201EC000000000000000000000000000000000000000000000000000000000000000000002 +:201EE0000000000000000000000000000000000000000000000000000000000000000000E2 +:201F00000000000000000000000000000000000000000000000000000000000000000000C1 +:201F20000000000000000000000000000000000000000000000000000000000000000000A1 +:201F4000000000000000000000000000000000000000000000000000000000000000000081 +:201F6000000000000000000000000000000000000000000000000000000000000000000061 +:201F8000000000000000000000000000000000000000000000000000000000000000000041 +:201FA000000000000000000000000000000000000000000000000000000000000000000021 +:201FC000000000000000000000000000000000000000000000000000000000000000000001 +:201FE0000000000000000000000000000000000000000000000000000000000000000000E1 +:00000001FF diff --git a/src/loader_fat32/loader_spiflash.zip b/src/loader_fat32/loader_spiflash.zip new file mode 100644 index 0000000..6be003d Binary files /dev/null and b/src/loader_fat32/loader_spiflash.zip differ diff --git a/src/loader_fat32/make.sh b/src/loader_fat32/make.sh new file mode 100644 index 0000000..813a10a --- /dev/null +++ b/src/loader_fat32/make.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +rm loader.bin +rm loader.hex +./sjasmplus loader.asm +./bin2hex.py --binaries=0,loader.bin + diff --git a/src/loader_fat32/tsfat/DMA.ASM b/src/loader_fat32/tsfat/DMA.ASM new file mode 100644 index 0000000..7cab7f7 --- /dev/null +++ b/src/loader_fat32/tsfat/DMA.ASM @@ -0,0 +1 @@ +;-------------------------------------------------------------------------------- ; Win 2,3 PG0()=0xF7, - ; Win 0,1 PGO("O") - ;PGO EQU ZES+1;2;Temp Page ;PGR EQU PGO+2;2;Restore Page PREDMA ; i: ; HL - dest adress ; o: A - PAGE ; DL - dest adress LD C,PG0 ; C<-PG0 // PG0 EQU #F7 LD A,H ; A<-DEST ADDR (A15, A14 = no meaning) CP #80:JR NC,$+6: ;if A>0x80 then go to mask :A15=1 (Win2,3) LD BC,(PGO) ;if A<0x80 then BC<-(Temp Page) (Win0,1) ;mask AND %00111111 ; mask A15, A14 = 0x0 LD D,A,A,C ; D<-A [hi byte of dest addr] ; A<-C [page =0xF7] LD BC,STS INF:JP M,$-2 ; RET ;-------------------------------------------------- ;i: ; HL - dest adress ;o: ; HL(+512) - dest adress POSDMA LD DE,512:ADD HL,DE ; HL+512, LD A,H CP #40:JR C, TSDL ; when A < 0x40, RETURN : A14,A15 =0, same PAGE CP #80:JR NC,TSDL ; when A15 = 1, RETURN : A15=1 (Win2,3) AND %00111111:LD H,A ; ELSE: mask A15, A14 = 0x0 LD A,(PGO):INC A ; (PG0)++ // DMA ? LD (PGO),A TSDL INF:JP M,$-2 RET ;-------------------------------------------------------------------------------- STS EQU #27AF ;DMACtrl ;------------------------------ DMASL EQU #1AAF ; - DMASAddrL DMASH EQU #1BAF ; - DMASAddrH DMASX EQU #1CAF ; - ;------------------------------ DMADL EQU #1DAF ; Lo DMADH EQU #1EAF ; Hi DMADX EQU #1FAF ; ;------------------------------------------------ DMA_T EQU #28AF ;0=1, 255=256 DMA_N EQU #26AF ;255=512 // 2..512 2 . DMA_C EQU #27AF ;RW 1 - - - 0 0 1 ;--------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/loader_fat32/tsfat/DSDTS.ASM b/src/loader_fat32/tsfat/DSDTS.ASM new file mode 100644 index 0000000..a44625d --- /dev/null +++ b/src/loader_fat32/tsfat/DSDTS.ASM @@ -0,0 +1 @@ +P_CONF EQU #77 P_DATA EQU #57 CMD_12 EQU #4C CMD_18 EQU #52 CMD_25 EQU #59 CMD_55 EQU #77 CMD_58 EQU #7A CMD_59 EQU #7B ACMD_41 EQU #69 ;------------------------------------------------ ;------------------------------------------------ ;INIsd JP SD__OFF ;============READ SECTORs ======================= ;i ; HL - destination ADDR ; A - Nof Sector for Read ; (BLKNUM), (BLKNUM+2) - Sector Address RDDXX RDDSE RDDSEsd LD DE,(BLKNUM) LD BC,(BLKNUM+2) EXA ;SPI: CMD_18, BC, DE, 0x00 ============== LD A,CMD_18:CALL SECM200 ;SET SECTOR ADDR EXA RD1 EXA CALL IN_OUT:CP #FE:JR NZ,$-5 CALL READSsd ; READ SECTOR EXA DEC A:JR NZ,RD1 ; READ N-sectors LD A,CMD_12 ; STOP MULTIREAD CALL OUT_COM CALL IN_OUT:INC A:JR NZ,$-4 JP CS_HIGH ;=========================> CS_HIGH => RET ;=======READ Sector ========================================================= ; Win 2,3 PG0()=0xF7, - ; Win 0,1 PGO("O") - ;PGO EQU ZES+1;2;Temp Page ;PGR EQU PGO+2;2;Restore Page READSsd ; i: HL - dest adress ;---------------------------------------------------------------------- PRE ; i: ; HL - dest adress ; o: A - PAGE ; DL - dest adress withing PAGE PUSH BC ; -??? LD C,PG0 ; C<-PG0 // PG0 EQU #F7 LD A,H ; A<-DEST ADDR (A15, A14 = no meaning) CP #80:JR NC,$+6: ;if A>0x80 then go to mask :A15=1 (Win2,3) LD BC,(PGO) ;if A<0x80 then BC<-(Temp Page) (Win0,1) ;mask AND %00111111 ; mask A15, A14 = 0x0 LD D,A,A,C ; D<-A [hi byte of dest addr] ; A<-C [page =0xF7] ;---------------------------------------------------------------------- PRE1 ; i: A - ; DL - ; HL - PUSH HL ; ;-------------- -------------------- ; PAGE3=A LD BC, PW3 OUT (C),A ; SET PAGE IN WIN3 ; H - (WIN3) = D + %11000000 LD A, %11000000 ADD A, D LD H, A ;------------------------------------------------------ RD_SECT ; HL - (WIN3) LD BC,P_DATA ; B=0x0 INIR ; (HL) <- Port(C), B-1 (256times) NOP INIR ; (HL) <- Port(C), B-1 (256times) NOP IN A,(C) NOP IN A,(C) ;=========================================================================== POP HL ;- ;--------------------------------------------------------------------------- POS ;i: ; HL - dest adress ;o: ; HL(+512) - dest adress LD DE,512:ADD HL,DE ; HL+512, LD A,H CP #40:JR C, TSDL ; when A < 0x40, RETURN : A14,A15 =0, same PAGE CP #80:JR NC,TSDL ; when A15 = 1, RETURN : A15=1 (Win2,3) AND %00111111:LD H,A ; ELSE: mask A15, A14 = 0x0 LD A,(PGO):INC A ; (PG0)++ // LD (PGO),A ;--------------------------------------------------------------------------- TSDL POP BC ;--???? RET ;------------------------------------------------------ CMD00 DB #40,#00,#00,#00,#00,#95 ; GO_IDLE_STATE CMD08 DB #48,#00,#00,#01,#AA,#87 ; SEND_IF_COND CMD16 DB #50,#00,#00,#02,#00,#FF ; SET_BLOCKEN ;------------------------------------------------------ SEL_DEV SELsd ;i:A - N of Dev : DON't NEED TO CHECK ;OR A:RET NZ ; just 1 driver (for SD) DRDET CALL SD_INIT LD DE,2:OR A:RET NZ LD DE,0 RET ;======================================================= ;================SD_INIT================================ SD_INIT CALL CS_HIGH LD BC,P_DATA,DE,#10FF OUT (C),E:DEC D:JR NZ,$-3 XOR A:EXA ZAW001 LD HL,CMD00:CALL OUTCOM,IN_OUT EXA:DEC A:JR Z,ZAW003 EXA:DEC A:JR NZ,ZAW001 LD HL,CMD08:CALL OUTCOM,IN_OUT IN H,(C) NOP IN H,(C) NOP IN H,(C) NOP IN H,(C) LD HL,0:BIT 2,A JR NZ,ZAW006:LD H,#40 ZAW006 LD A,CMD_55:CALL OUT_COM,IN_OUT LD A,ACMD_41:OUT (C),A:NOP OUT (C),H:NOP OUT (C),L:NOP OUT (C),L:NOP OUT (C),L LD A,#FF:OUT (C),A CALL IN_OUT:AND A:JR NZ,ZAW006 ZAW004 LD A,CMD_59:CALL OUT_COM,IN_OUT AND A:JR NZ,ZAW004 ZAW005 LD HL,CMD16:CALL OUTCOM,IN_OUT ;===============DEBUG ========== CMD16 ========== !!!!!!!!!!! ;CALL COM_TX ; send A : 0x0 (SD/SDHC) ;======================================= AND A:JR NZ,ZAW005 CS_HIGH PUSH DE,BC LD E,3,BC,P_CONF OUT (C),E:LD E,0,C,P_DATA OUT (C),E POP BC,DE RET ZAW003 CALL SD__OFF LD A,1 RET SD__OFF XOR A OUT (P_CONF),A OUT (P_DATA),A RET CS__LOW PUSH DE,BC LD BC,P_CONF,E,1:OUT (C),E POP BC,DE RET OUTCOM CALL CS__LOW PUSH BC LD BC,P_DATA OUTI:NOP : OUTI:NOP : OUTI:NOP OUTI:NOP : OUTI:NOP : OUTI:NOP POP BC RET OUT_COM PUSH BC CALL CS__LOW LD BC,P_DATA OUT (C),A:XOR A OUT (C),A:NOP OUT (C),A:NOP OUT (C),A:NOP OUT (C),A:DEC A OUT (C),A POP BC RET SECM200 PUSH HL,DE,BC,AF,BC LD BC,P_DATA,A,CMD_58 CALL OUT_COM,IN_OUT IN A,(C):NOP IN H,(C):NOP IN H,(C):NOP IN H,(C):BIT 6,A:POP HL JR NZ,SECN200 EX DE,HL:ADD HL,HL:EX DE,HL ADC HL,HL LD H,L,L,D,D,E,E,0 SECN200 POP AF LD BC,P_DATA:OUT (C),A NOP:OUT (C),H NOP:OUT (C),L NOP:OUT (C),D NOP:OUT (C),E LD A,#FF:OUT (C),A POP BC,DE,HL RET IN_OUT PUSH BC,DE LD DE,#10FF LD BC,P_DATA IN_WAIT IN A,(C) CP E:JR NZ,IN_EXIT IN_NEXT DEC D:JR NZ,IN_WAIT IN_EXIT POP DE,BC RET ;--------------------------------------- \ No newline at end of file diff --git a/src/loader_fat32/tsfat/DSDTS_DMA.ASM b/src/loader_fat32/tsfat/DSDTS_DMA.ASM new file mode 100644 index 0000000..b4e7074 --- /dev/null +++ b/src/loader_fat32/tsfat/DSDTS_DMA.ASM @@ -0,0 +1 @@ +P_CONF EQU #77 P_DATA EQU #57 CMD_12 EQU #4C CMD_18 EQU #52 CMD_25 EQU #59 CMD_55 EQU #77 CMD_58 EQU #7A CMD_59 EQU #7B ACMD_41 EQU #69 ;------------------------------------------------ ;------------------------------------------------ ;INIsd JP SD__OFF ;============READ SECTORs ======================= ;i ; HL - destination ADDR ; A - Nof Sector for Read ; (BLKNUM), (BLKNUM+2) - Sector Address RDDXX RDDSE RDDSEsd LD DE,(BLKNUM) LD BC,(BLKNUM+2) EXA ;SPI: CMD_18, BC, DE, 0x00 ============== LD A,CMD_18:CALL SECM200 ;SET SECTOR ADDR EXA RD1 EXA CALL IN_OUT:CP #FE:JR NZ,$-5 CALL READSsd ; READ SECTOR with DMA EXA DEC A:JR NZ,RD1 ; READ N-sectors LD A,CMD_12 ; STOP MULTIREAD CALL OUT_COM CALL IN_OUT:INC A:JR NZ,$-4 JP CS_HIGH ;=========================> CS_HIGH => RET ;=======READ Sector ========================================================= ;i: A - ; HL - READSsd PUSH BC,DE CALL PREDMA ; (Win2,3->Page=0xF7) ;========== LD B,DMADX/256:OUT (C),A ; ===== ;========UART===================0x9200 Win(2) PAGE2=0xF7 ;CALL COM_TX ; 0xF7 - ;LD A, D : CALL COM_TX ; 0x12 - ;LD A, L : CALL COM_TX ; 0x00 - ;======================================================== DEC B:OUT (C),D ; DEC B:OUT (C),L ; LD B,DMA_T/256:XOR A:OUT (C),A ; LD B,DMA_N/256:DEC A:OUT (C),A ; 512 Byte LD B,DMA_C/256,A,%00000010:OUT (C),A ; SPI data is copied to RAM (Dst) CALL POSDMA ; HL+512 - , LD BC,P_DATA IN A,(C) : IN A,(C) POP DE,BC RET ;------------------------------------------------------ CMD00 DB #40,#00,#00,#00,#00,#95 ; GO_IDLE_STATE CMD08 DB #48,#00,#00,#01,#AA,#87 ; SEND_IF_COND CMD16 DB #50,#00,#00,#02,#00,#FF ; SET_BLOCKEN ;------------------------------------------------------ SEL_DEV SELsd ;i:A - N of Dev : DON't NEED TO CHECK ;OR A:RET NZ ; just 1 driver (for SD) DRDET CALL SD_INIT LD DE,2:OR A:RET NZ LD DE,0 RET ;======================================================= ;================SD_INIT================================ SD_INIT CALL CS_HIGH LD BC,P_DATA,DE,#10FF OUT (C),E:DEC D:JR NZ,$-3 XOR A:EXA ZAW001 LD HL,CMD00:CALL OUTCOM,IN_OUT EXA:DEC A:JR Z,ZAW003 EXA:DEC A:JR NZ,ZAW001 LD HL,CMD08:CALL OUTCOM,IN_OUT IN H,(C) NOP IN H,(C) NOP IN H,(C) NOP IN H,(C) LD HL,0:BIT 2,A JR NZ,ZAW006:LD H,#40 ZAW006 LD A,CMD_55:CALL OUT_COM,IN_OUT LD A,ACMD_41:OUT (C),A:NOP OUT (C),H:NOP OUT (C),L:NOP OUT (C),L:NOP OUT (C),L LD A,#FF:OUT (C),A CALL IN_OUT:AND A:JR NZ,ZAW006 ZAW004 LD A,CMD_59:CALL OUT_COM,IN_OUT AND A:JR NZ,ZAW004 ZAW005 LD HL,CMD16:CALL OUTCOM,IN_OUT ;===============DEBUG ========== CMD16 ========== !!!!!!!!!!! ;CALL COM_TX ; send A : 0x0 (SD/SDHC) ;======================================= AND A:JR NZ,ZAW005 CS_HIGH PUSH DE,BC LD E,3,BC,P_CONF OUT (C),E:LD E,0,C,P_DATA OUT (C),E POP BC,DE RET ZAW003 CALL SD__OFF LD A,1 RET SD__OFF XOR A OUT (P_CONF),A OUT (P_DATA),A RET CS__LOW PUSH DE,BC LD BC,P_CONF,E,1:OUT (C),E POP BC,DE RET OUTCOM CALL CS__LOW PUSH BC LD BC,P_DATA OUTI:NOP : OUTI:NOP : OUTI:NOP OUTI:NOP : OUTI:NOP : OUTI:NOP POP BC RET OUT_COM PUSH BC CALL CS__LOW LD BC,P_DATA OUT (C),A:XOR A OUT (C),A:NOP OUT (C),A:NOP OUT (C),A:NOP OUT (C),A:DEC A OUT (C),A POP BC RET SECM200 PUSH HL,DE,BC,AF,BC LD BC,P_DATA,A,CMD_58 CALL OUT_COM,IN_OUT IN A,(C):NOP IN H,(C):NOP IN H,(C):NOP IN H,(C):BIT 6,A:POP HL JR NZ,SECN200 EX DE,HL:ADD HL,HL:EX DE,HL ADC HL,HL LD H,L,L,D,D,E,E,0 SECN200 POP AF LD BC,P_DATA:OUT (C),A NOP:OUT (C),H NOP:OUT (C),L NOP:OUT (C),D NOP:OUT (C),E LD A,#FF:OUT (C),A POP BC,DE,HL RET IN_OUT PUSH BC,DE LD DE,#10FF LD BC,P_DATA IN_WAIT IN A,(C) CP E:JR NZ,IN_EXIT IN_NEXT DEC D:JR NZ,IN_WAIT IN_EXIT POP DE,BC RET ;=============================DMA================================================= ;-------------------------------------------------------------------------------- ; Win 2,3 PG0()=0xF7, - ; Win 0,1 PGO("O") - ;PGO EQU ZES+1;2;Temp Page ;PGR EQU PGO+2;2;Restore Page PREDMA ; i: ; HL - dest adress ; o: A - PAGE ; DL - dest adress LD C,PG0 ; C<-PG0 // PG0 EQU #F7 LD A,H ; A<-DEST ADDR (A15, A14 = no meaning) CP #80:JR NC,$+6: ;if A>0x80 then go to mask :A15=1 (Win2,3) LD BC,(PGO) ;if A<0x80 then BC<-(Temp Page) (Win0,1) ;mask AND %00111111 ; mask A15, A14 = 0x0 LD D,A,A,C ; D<-A [hi byte of dest addr] ; A<-C [page =0xF7] LD BC,STS INF:JP M,$-2 ; RET ;-------------------------------------------------- ;i: ; HL - dest adress ;o: ; HL(+512) - dest adress POSDMA LD DE,512:ADD HL,DE ; HL+512, LD A,H CP #40:JR C, TSDL ; when A < 0x40, RETURN : A14,A15 =0, same PAGE CP #80:JR NC,TSDL ; when A15 = 1, RETURN : A15=1 (Win2,3) AND %00111111:LD H,A ; ELSE: mask A15, A14 = 0x0 LD A,(PGO):INC A ; (PG0)++ // DMA ? LD (PGO),A TSDL INF:JP M,$-2 RET ;-------------------------------------------------------------------------------- STS EQU #27AF ;DMACtrl ;------------------------------ DMASL EQU #1AAF ; - DMASAddrL DMASH EQU #1BAF ; - DMASAddrH DMASX EQU #1CAF ; - ;------------------------------ DMADL EQU #1DAF ; Lo DMADH EQU #1EAF ; Hi DMADX EQU #1FAF ; ;------------------------------------------------ DMA_T EQU #28AF ;0=1, 255=256 DMA_N EQU #26AF ;255=512 // 2..512 2 . DMA_C EQU #27AF ;RW 1 - - - 0 0 1 ;--------------------------------------------------------------------------------- \ No newline at end of file diff --git a/src/loader_fat32/tsfat/STREAM.ASM b/src/loader_fat32/tsfat/STREAM.ASM new file mode 100644 index 0000000..2e2e81a --- /dev/null +++ b/src/loader_fat32/tsfat/STREAM.ASM @@ -0,0 +1 @@ +;--------------------------------------- E_ENF EQU 1; entry not found E_NES EQU 2; not enough space E_DNF EQU 8; device not found E_DNR EQU 9; device not ready E_PNF EQU 10;partition not found E_WRP EQU 16;write protection E_WGS EQU 24;wrong stream E_SNR EQU 25;stream not ready ;---------------------------------------- ;NEW==============================================================N1 FAT_DRV EXX ;SAVE REG LD HL,FUX,B,0,C,A ;HL<-Function Table; C<-Function Number ADD HL,BC ;HL+BC ADD HL,BC ;HL+BC LD A,(HL):INC HL ;GET Function Address LD H,(HL),L,A ;HL- Function Address LD BC,RORO:PUSH BC PUSH HL ;Function Address in STACK EXX ;RESTORE REG RORO RET ;OLD==Source code is 2Bytes more longer then new ver =============N2 ;FAT_DRV ; exx ;---- HL = FUX + A --- ; LD HL,FUX ; sla a ;A x 2 ; add a,l ; ld l,a ; jr nc,f00 ; inc h ;f00 ;---- GO TO (FUX + A)-- ; LD A,(HL):INC HL ; LD H,(HL),L,A ; LD BC,RORO:PUSH BC ; PUSH HL ; exx ;RORO RET FUX DW STREAM; 0; CRTSTREAM DW FENTRY; 1; FENTRY DW GDIR; 2; SETDIR DW LOAD512; 3; READ512 ;================================================================================ ;===================STEARM====================================== STREAM ;i: B - Device -NOT USED ; (0 - SD) ; C - Partition ; o: C - Stream Number PUSH BC ;------STRMCLR - VALS STRMED LD HL,VALS,DE,HL:INC DE LD (HL),0,BC,STRMED-VALS-1:LDIR POP BC ;=======SD Card================================================= CALL SD__OFF ; JP SD__OFF ;XOR A ; A=0: select SD ; SD CALL SEL_DEV:JR NZ,EDNF ;IDE_INI+3 => N1: SELsd SD_INIT ; MBR, FAT32 CALL HDD:JR NZ,EPNF ;SEARCH PARTITION (TSFAT.ASM) ;HDD return 0xO-OK LD HL,0,(CRRR),HL,(CRRR+2),HL ; Clear (CRRR), (CRRR+2) ;LD A,1,(STST),A;Stream Ready XOR A:LD C,A RET ;=======Error============================ EWGS LD A,E_WGS:OR A:RET EDNF LD A,E_DNF:OR A:RET EPNF LD A,E_PNF:OR A:RET ;------- VALS STRMED ;STRMCLR LD HL,VALS,DE,HL:INC DE ; LD (HL),0,BC,STRMED-VALS-1:LDIR ; ;XOR A ; RET ;===================================FENTRY======== ;i: LSTCAT(4) - Active DIR ; HL - Buffer with Name FENTRY CALL SRHDRN ; TSFAT.ASM JR Z,EENF ; IF OK, HL/DE- Cluster number LD (CRRR),HL LD (CRRR+2),DE EXX CALL GFILE LD HL,(ENTRY+28) LD DE,(ENTRY+30) XOR A ; OK A=0 RET ;=========> EXIT EENF LD A,E_ENF:OR A ; ERROR RET ;======================================================= ;GIPAG=>;i:HL(4)-Cluster number //CALL XSPOZ//CALL XPOZI GFILE LD HL,CRRR:JP GIPAG GDIR LD HL,CRRR:JP GLSTCAT ;== IDE_INI ======= ;IDE_INI JP INIsd ;SEL_DEV JP SELsd ;RDDSE JP RDDSEsd ;-------------------------------------------------------- \ No newline at end of file diff --git a/src/loader_fat32/tsfat/TSFAT.ASM b/src/loader_fat32/tsfat/TSFAT.ASM new file mode 100644 index 0000000..6066a62 --- /dev/null +++ b/src/loader_fat32/tsfat/TSFAT.ASM @@ -0,0 +1 @@ +;*************************************** ;ORG #2000,$ ;------- DEFREQ EQU %00000010 SYC EQU #20AF PW1 EQU #11AF PW2 EQU #12AF PW3 EQU #13AF ;-------REG----------------------- PG0 EQU #F7 ;-------VAR BUFZZ EQU #8000 PWA EQU BUFZZ+#4000 ;0xC000 - STACK ;-------#8000-#2000--------------------- GENBU EQU BUFZZ+#0000 GENBE EQU BUFZZ+#1000 SECBU EQU GENBE SECBE EQU SECBU+512 LOBU EQU SECBE LOBE EQU LOBU+512 LoCALL EQU LOBE+512 INTC EQU BUFZZ+#1F00-1 VALS EQU BUFZZ+#2000 ;-------- > #A000 ---------------------- STST EQU VALS; Stream Status (0-notR) NSDC EQU STST+1;\ Sec num in Cluster EOC EQU NSDC+1;/ Flag (EndOfChain) ABT EQU EOC+1 BZN EQU ABT+1;Blocks NR0 EQU BZN+1 CAHL EQU NR0+2 CADE EQU CAHL+2 LSTSE EQU CADE+2 REZDE EQU LSTSE+4 PR EQU REZDE+2 CLHL EQU PR+4 CLDE EQU CLHL+2 LLHL EQU CLDE+2 LTHL EQU LLHL+4;LAST LTDE EQU LTHL+2 ;------------Entry Pattern:------------- ENTRY EQU LTDE+2;DS 11 EFLG EQU ENTRY+11 CLSDE EQU ENTRY+20 CLSHL EQU ENTRY+26 SIZIK EQU ENTRY+28 ;--------------------------------------- ;------------FAT PARAMETERS:------------ BREZS EQU ENTRY+33; [+14(2)] FSINF EQU BREZS+2; [+48(2)]+[ADDTOP] BFATS EQU FSINF+4 BFTSZ EQU BFATS+1 BSECPC EQU BFTSZ+4 BROOTC EQU BSECPC+2 FSTFRC EQU BROOTC+4 ADDTOP EQU FSTFRC+4 SFAT EQU ADDTOP+4 SDFAT EQU SFAT+2 CUHL EQU SDFAT+4 CUDE EQU CUHL+2 NXDE EQU CUDE+2 NXHL EQU NXDE+2 LDHL EQU NXHL+2;ADDRESS COPY COUNT EQU LDHL+2 DUHL EQU COUNT+1 DUDE EQU DUHL+2 DUBA EQU DUDE+2 UUHL EQU DUBA+1 BUHL EQU UUHL+2 CLCNT EQU BUHL+2; COUNTER USED in MKSG FCTS EQU CLCNT+4; FirstClusTS BUTS EQU FCTS+4; BUferTS LSTCAT EQU BUTS+4; Active DIR RECCAT EQU LSTCAT+4;RECYCLED BIN DIR ;------- BLKNUM EQU RECCAT+4 DRVRE EQU BLKNUM+4 STRMED EQU DRVRE+1 ;--------------------------------------- INCLUDE "tsfat/STREAM.ASM" ;---------------------------------------------------------------------------- ;============================================================================ GENTRYX ;i:HL - Text String ; o:ENTRY(11) 8NAME + '.' + 3EXT LD DE,ENTRY ;ENTRY = LTDE+2;DS 11 LD B,8:CALL DOTZ, RYX CALL Z, NOPIDE LD A,(HL):CP ".":JR NZ,$+3:INC HL LD B,3:CALL RYX,Z,NOPIDE RET ;=================== (HL), (DE) ====================== ; RYX LD A,(HL):OR A:RET Z ; '0' - CP ".":INC HL:RET Z ; '.' HL+ LD (DE),A:INC DE:DJNZ RYX ; (DE) '0' LD A,1:OR A ; A <-1 RET ;====================================================== DOTZ LD A,(HL):CP ".":RET NZ ; , ".", LD (DE),A:INC HL,DE:DEC B ; LD A,(HL):CP ".":RET NZ LD (DE),A:INC HL,DE:DEC B RET ;--------------------------------------- ;GIVE Active DIR: GLSTCAT ;i:HL(4) - CLUS num LD DE,LSTCAT,BC,4:LDIR RET ;--------------------------------------- ;LOAD DATA to FAT32 (STREAM): ;i DE - ADDR in WIN ; BC - PAGE LOAD512 LD (PGO),BC : EX DE,HL ; PG0-BC SAVE PAGE; HL<-DE LD A,H:AND #3F:LD H,A ; HL - ADDR in Win CALL LOAD ; (LDMD)<-1, LD BC,(PGO):EX DE,HL ; DE -ADDRESS RET ; A -EOC ;------- ;Load512 LD A,1,(LDMD),A:JP LOAD ; (LDMD)<-1 :READ ;----------------------------------------------------- ;READ DATA from FAT32 (STREAM): LOAD ;i:HL - Address + (PGO) ; B - lenght (512b blocks/sectors) ; CUHL(4) - CLUSnum (if EOC+NSDC=0) ; o:HL - New value + (PGO) ; A - EndOfChain XOR A:LD (ABT),A ; (ABT) <- 0x0 CALL LPREX:JR NZ,RH ; if Z - READ Sector LD A,B:CALL NEWCLA ; DEHL - new Claster POS ? RH LD HL,(LDHL) ; -ADDRESS LD A,(EOC) ; -EOC RET ;Positioning to Cluster, if needed: ======================================== ;i: HL - MEM Address LPREX LD (LDHL),HL LD A,(EOC):OR A:RET NZ ;if EOC=1, end of file RETURN no READ LD A,(NSDC):OR A:JR NZ,RX ;if NSDC > 0 - ; , PUSH BC:LD HL,CUHL:CALL GIPAG ;NSDC =0; CALL XSPOZ ; CALL XPOZI READ POP BC RET ;--> RX XOR A RET ;--> ;=======NEW CLASTER ======================================================== ;i: A-Lenght NEWCLA LD (BZN),A ; (BZN) <- A ; PROZ: SET Sector position NXTC ;i: DEHL - new sector position LD HL,(LTHL),DE,(LTDE):CALL PROZ ;LD (BLKNUM),HL,(BLKNUM+2),DE LD HL,BZN ; LD A,(BSECPC),BC,(NSDC); (BSECPC)-fix (NSDC) SUB C : LD B,A ;B = SectorinClaster - CurrSectNuminCluster LD A,(HL):OR A:RET Z ;Lenght=0? => RETURN ;==========================================EXIT =================>>> SUB B:JR NC,KN ;Lenght - (SecinClast - CurrSectNuminCluster) ; () Lenght, Lenght=0, ADD A,B:LD B,A:XOR A ; , KN ;B-Number of sectors for READ LD (HL),A ; (BZN), LD A,B,(NR0),A ; A<-B Number of sectors for READ (NR0) LD HL,(LDHL);HL-Dest MEMORY, A-Nof Sector CALL RDDXX ;READ Sector(s) =========== !!!!!!!!!!! ;----------- After READING SECTORs LD (LDHL),HL;updating MEM Address (LDHL)<-HL+512*NofSector LD HL,LTHL,DE,LLHL,BC,4 ;(LLHL)<-(LTHL) LDIR ; (DE)<-(HL); HL++, DE++, 4 times ;--(LTDE)(LTHL) + (NR0) -- ? LD HL,(LTHL),DE,(LTDE) LD BC,(NR0) ADD HL,BC ; (LTHL)+(NR0)Nof Readed Sector JR NC,$+3 ; INC DE ; if C, then DE++ LD (LTHL),HL,(LTDE),DE ;(LTDE)(LTHL) - ;---------------------------------------------------- ;--(NSDC) + (NR0)Nof Readed Sector LD HL,NSDC,A,C:ADD A,(HL) LD (HL),A ; (NSDC) ;----------------------------------------------------- ; , LD BC,(BSECPC); Sector per Claster CP C:JP C,NXTC; End OF Cluster? NO ;== LOOP==> NXTC ; YES! LD HL,(CUHL),DE,(CUDE) CALL CURIT ; READ SECTOR FROM FAT CALL GIPAG ; SET NEW POSITION JP Z,NXTC ;== LOOP==> NXTC RET ;================================================================== ;RDDXX EQU RDDSE ; ;================================================================== ;------Read Sector from FAT:------------ CURIT ;i:[DE,HL]-Cluster number ; o:SECBU(512) ; HL-poz in SECBU where Cluster CALL DEL128 SLA C:RL B SLA C:RL B PUSH BC LD (LSTSE+2),DE,(LSTSE),HL LD BC,(BFTSZ+2) LD A,D:CP B:JR C,JK LD A,E:CP C:JR C,JK LD BC,(BFTSZ) LD A,H:CP B:JR C,JK LD A,L:CP C:JR NC,FATEND JK LD BC,(SFAT) CALL ADD4B CALL XSPOZ CALL XPOZI LD HL,SECBU,A,1:CALL RDDSE POP BC LD HL,SECBU:ADD HL,BC XOR A RET ;------- FATEND POP BC SCF RET ;=======Pos. to First Sector of Cluster:========================================================== GIPAG ;i:HL(4) - Cluster number CALL TOS ;(NSDC) <-0; (EOC)<-0 LD E,(HL):INC HL ;E<-(HL+0) LD D,(HL):INC HL ;D<-(HL+1) LD A,(HL):INC HL ;L<-(HL+2) LD H,(HL),L,A ;H<-(HL+3) OR H,E,D:JR Z,RDIR LD A,H:AND #0F:CP #0F:JR Z,MDC EX DE,HL POM LD (CUHL),HL,(CUDE),DE LD BC,2:OR A:SBC HL,BC:JR NC,$+3:DEC DE LD A,(BSECPC):CALL UMNOX2 ; [DE,HL] x (BSECPC -Secotr per Cluster ) = NUmber of Sector LD BC,(SDFAT):CALL ADD4B ; [2FAT+ ] + Sector Number -ABSOLUTE ADDR EX DE,HL ; LD BC,(SDFAT+2):ADD HL,BC ; EX DE,HL CALL XSPOZ ; CALL XPOZI XOR A RET ;-------------------------------------- RDIR LD HL,(BROOTC),DE,(BROOTC+2) JR POM MDC LD (EOC),A OR A RET ;---Getting Absolute Position of SEC:--- XSPOZ LD BC,(ADDTOP),(CLHL),BC LD BC,(ADDTOP+2),(CLDE),BC JP ADD4BF ;========================================================================ENTRY======== ;-----Searching ENTRY in Active DIR:---- ;BY NAME: SRHDRN ;i:LSTCAT(4) - Active DIR ; HL - Buffer with Name ; [flag(1)+name(1-12)+#00] ; o: Z: NOT FOUNT ; NZ: ENTRY(32) ; [DE,HL] - Cluster Number ; BC - Address in LOBU ;-------- ENTRY-------------------------------- LD A,(HL):INC HL ; <-A LD (ENTRY+11),A:CALL GENTRYX ; TSFAT.ASM ENTRY=LTDE+2;DS 11 // <-A ;------------------------------------------------------ LD HL,LSTCAT ;LSTCAT Active DIR LD DE,CUHL,BC,4:LDIR ;(CUHL)4Byte <- (LSTCAT)4Byte CALL TOS ;Clear (NSDC) <-0; (EOC)<-0 HDR LD A,(EOC):CP #0F:RET Z LD HL,LOBU,B,1 ;-Load512-------------------- CALL LOAD ; (LDMD)<-1 :READ ;------------------------------------------ LD (HL),0 LD HL,LOBU-32:CALL VEGA:RET NZ JR HDR ;------- VEGA LD BC,32:ADD HL,BC ; LOBU - FAT32 LD A,(HL):OR A:RET Z ; HL = LOBU , 0x0 - => CALL CHEB:JR NZ,VEGA LD A,1:OR A RET ;------- 11 ENTRY c (HL)---- CHEB PUSH HL LD DE,ENTRY,B,11:CALL CHEE,Z,CHF POP HL:RET NZ PUSH HL:LD DE,ENTRY,BC,32:LDIR POP BC LD HL,(CLSHL) LD DE,(CLSDE) XOR A RET ;------- CHF LD A,(DE),C,A LD A,(HL):AND #10:CP C RET ;------- n (DE) c (HL)---- CHEE LD A,(DE):CP (HL):RET NZ INC HL,DE DJNZ CHEE ; IF OK 11 times ---- RET ;--------------------------------------- ;CHAIN->SECTORS: CHTOSE ;i:HL(4) - First Cluster number ; DE - BUFFER Address ; BC - End Of BUFFER LD (DABC),BC LD (DADE),DE ;- Buffer Address CKAGO LD (DAHL),HL CALL GIPP:RET Z CALL CLUSSEC LD DE,(DABC) OR A:SBC HL,DE:RET NC LD HL,(DAHL) LD E,(HL):INC HL LD D,(HL):INC HL LD A,(HL):INC HL LD H,(HL),L,A:EX DE,HL CALL CURIT JR CKAGO ;------- CLUSSEC ;i: (DADE) - Buffer Address ; (BSECPC) - Sectors per CLUS ; [DE,HL] - Sector number ; ; o: (DADE) - New Value LD BC,HL LD A,(BSECPC) ;-Sector per Claster LD HL,(DADE) USS LD (HL),C:INC HL ;(DADE+0)<-L LD (HL),B:INC HL ;(DADE+1)<-H LD (HL),E:INC HL ;(DADE+2)<-E LD (HL),D:INC HL ;(DADE+3)<-D LD (DADE),HL:DEC A:RET Z INC BC EXA:LD A,B:OR C:JR NZ,$+3:INC DE EXA JR USS ;------- GIPP ;i: HL(4) - Cluster number ; o:[DE,HL] - Sector number ; Z - EndOfChain LD E,(HL):INC HL LD D,(HL):INC HL LD A,(HL):INC HL LD H,(HL),L,A:OR H,E,D:RET Z LD A,H:CP #0F:RET Z EX DE,HL LD BC,2:OR A:SBC HL,BC:JR NC,$+3:DEC DE LD A,(BSECPC):CALL UMNOX2 LD BC,(SDFAT):CALL ADD4B EX DE,HL LD BC,(SDFAT+2):ADD HL,BC EX DE,HL CALL XSPOZ LD A,1:OR A RET ;==================================================================HDD ;SEARCH PARTITION: HDD ;i:none ; o:NZ - FAT32 not found ; Z - all FAT32 vars are ; initialized ;========UART=================== ;LD A, 0x11 ;CALL COM_TX ;=============================== LD HL,0,DE,HL LD (CUHL),HL,(CUDE),HL LD (DAHL),HL,(DADE),HL LD (DUHL),HL,(DUDE),HL CALL XPOZI LD HL,LOBU,A,1:CALL RDDSE ;LOBU - Start Dest Adress LD A,3,(COUNT),A,(ZES),A ;LOBU+446 - Patition Table ================================= LD HL,LOBU+446+4,DE,16,B,4 ;446+4 - ;========UART=================== ;LD A, H : CALL COM_TX ;0x93 ;LD A, L : CALL COM_TX ;0xC2 ;=============================================== KKO LD A,(HL) ; A <- (446+4) 0x93C2 ;CALL COM_TX ; DEBUG CP #05:JR Z,OKK ; 0x05 - Extended MS-DOS Partition CP #0B:JR Z,OKK ; 0x0B - 32-bit FAT (Partition Up to2048GB) //2GB SD CP #0C:JR Z,OKK ; 0x0C - Same as 0BH, but uses LBA1 13h Extensions CP #0F:JR Z,OKK ; 0x0F - Same as 05H, but uses LBA1 13h Extensions ADD HL,DE DJNZ KKO ;======== IF NOT FOUND -> FAILED ======================================================== FHDD LD A,(ZES):OR A:JP Z,Nhdd ;A<-3(ZES) //ZES EQU LOBE+512+10; // LOBE EQU LOBU+512 LD DE,(DADE),HL,(DAHL) CALL XPOZI LD HL,LOBU:LD A,1:CALL RDDSE LD HL,COUNT:DEC (HL):JP Z,NHDD LD HL,LOBU+446+16,B,16 XOR A:OR (HL):INC HL:DJNZ $-2 JP NZ,NHDD LD HL,(LOBU+446+16+8) LD DE,(LOBU+446+16+8+2) LD (CLHL),HL,(CLDE),DE LD HL,(DAHL),DE,(DADE) CALL ADD4BF LD (DADE),DE,(DAHL),HL CALL XPOZI LD HL,LOBU,A,1:CALL RDDSE LD HL,(LOBU+446+8) LD DE,(LOBU+446+8+2) CALL ADD4BF JR LDBPB ;======= 05/0B/0C/0F, FAT ====== OKK INC HL,HL,HL,HL ;HL+4 // HL( )+4 = (4byte) LD E,(HL):INC HL ; ED; LD D,(HL):INC HL ; LD A,(HL):INC HL ; LD H,(HL),L,A ; LH; EX DE,HL ; LH;ED - (4byte) ;====== BIOS Parameter Block // FAT ================= ;LOAD BIOS Parameter Block LDBPB LD (ADDTOP),HL,(ADDTOP+2),DE ; CALL XPOZI ; XPOZI: LD (LTHL),HL,(LTDE),DE // LD (BLKNUM),HL,(BLKNUM+2),DE LD HL,LOBU;LOAD BPB SECTOR LD A,1:CALL RDDSE; BIOS Parameter Block ;RDDSE ============READ SECTOR ============= ;i ; HL - destination ADDR ; A - Nof Sector for Read ; (BLKNUM), (BLKNUM+2) - Sector Adress ;=========================================================================== ;LD HL,LOBU+3,B,6,A,#1D ;FIVE CP (HL):INC HL:JP NC,FHDD ;DJNZ FIVE LD HL,(LOBU+11) ; ( 512) LD A,H:DEC A,A:OR L:JP NZ,FHDD ; 512 -> go FHDD == FAILED LD A,(LOBU+13):OR A:JP Z,FHDD ; LD A,(LOBU+14):OR A:JP Z,FHDD ; FAT LD A,(LOBU+16):OR A:JP Z,FHDD ; FAT ( 2) LD HL,(LOBU+17),A,H:OR L ; ( ) ;LD HL,(LOBU+19):OR H,L LD HL,(LOBU+22):OR H,L ; FAT JP NZ,FHDD LD HL,(LOBU+36):OR H,L LD HL,(LOBU+36+2):OR H,L JP Z,FHDD ;LD HL,ADDTOP,DE,DUHL,BC,4:LDIR ;LD HL,DNU,A,(HL):DEC (HL) ;OR A:JP NZ,FHDD ;LD (HL),0 ;======= ==================================================================================== LD A,(LOBU+13),(BSECPC),A ;(BSECPC)1byte <- LD B,8:SRL A:JR C,NER:DJNZ $-4:LD A,1 NER OR A:JP NZ,FHDD LD HL,(LOBU+14),(BREZS),HL ;(BREZS) 2byte <- FAT LD HL,(LOBU+48),DE,0 ; CALL XSPOZ LD (FSINF),HL,(FSINF+2),DE LD A,(LOBU+16),(BFATS),A ;(BFATS) 1Byte <- FAT ( 2) LD HL,(LOBU+36),(BFTSZ),HL ;(BFTSZ) 4Byte <-Number of Sectors Per FAT LD HL,(LOBU+36+2),(BFTSZ+2),HL ; LD HL,(LOBU+44),(BROOTC),HL ;(BROOTC)4Byte <-Cluster Number of the Startof the Root Directory LD HL,(LOBU+44+2),(BROOTC+2),HL ; LD HL,(BFTSZ),DE,(BFTSZ+2) ;Number of Sectors Per FAT * 2 = 2 LD BC,(BFATS),B,0 CALL UMN4B ;[DE,HL]*BC - 4Byte 2Byte PUSH HL,DE ; LD HL,(BREZS) ;(SFAT) <- LD (SFAT),HL ;(SFAT) <- (BREZS) POP DE,BC ; DE,HL + (BREZS) = 2 + CALL ADD4B ; LD (SDFAT),HL,(SDFAT+2),DE ; (SDFAT) <- 2 + LD HL,0 LD (CUHL),HL LD (CUDE),HL LD (LSTCAT),HL LD (LSTCAT+2),HL ;LD HL,(FSINF),DE,(FSINF+2) ;CALL XPOZI ;LD HL,LOBU ;LD A,1:CALL RDDSE ;LD HL,LOBU+492,DE,FSTFRC ;LD BC,4:LDIR LD HL,FSTFRC,B,4 ;NOPING ----------------------- XOR A:LD (HL),A:INC HL:DJNZ $-2 ;------------------------------ CALL TOS XOR A RET ;============NHDD======================== NHDD LD HL,(DUHL),DE,(DUDE) XOR A:LD (ZES),A JP LDBPB Nhdd LD A,1:OR A RET ;--------------------------------------- ;ARITHMETICS BLOCK: DEL128 ;i:[DE,HL]/128 ; o:[DE,HL] ; BC - Remainder LD A,L:EXA LD A,L,L,H,H,E,E,D,D,0 RLA RL L,H,E,D EXA AND 127 LD B,0,C,A RET ;------- DEL512 ;i:[DE,HL]/512 LD A,L,L,H,H,E,E,D,D,0 LD BC,1:OR A:CALL NZ,ADD4B LD A,2 ;------- DELITX2 ;i:[DE,HL]/A ; A - Power of Two ; o:[DE,HL] CP 2:RET C LD C,0 SRL A L33T SRL D:RR E,H,L,C SRL A:JR NC,L33T LD A,C:OR A:RET Z LD BC,1:CALL ADD4B RET ;------- UMNOX2 ;i:[DE,HL]*A ; A - Power of Two ; o:[DE,HL] CP 2:RET C SRL A L33t SLA L:RL H,E,D SRL A:JR NC,L33t RET ;------- ;UMNOG ;HL*BC=HL DEdest ;LD DE,HL ;LD A,B,B,C,C,A:INC C ;XOR A:DEC B:JR Z,ODN ;BSR ADD HL,DE ;DJNZ BSR ;ODN LD B,A ;DEC C ;JR NZ,BSR ;RET INC4b LD B,4 EkE INC (HL):RET NZ:INC HL:DJNZ EkE RET ADD4B ADD HL,BC:RET NC:INC DE RET ADD4BF ;i:[DE,HL]+[CLDE,CLHL] ; o:[DE,HL] EX DE,HL LD BC,(CLDE) ADD HL,BC EX DE,HL LD BC,(CLHL) ADD HL,BC:JR NC,KNH INC DE KNH LD (CLHL),HL LD (CLDE),DE RET ;==============UMN4B================= UMN4B ;i: ; [DE,HL]*BC ; o: ; [DE,HL] LD A,B,B,C,C,A:INC C OR A:JR NZ,TEKNO DEC B:JR Z,UMN1 INC B TEKNO XOR A CP B:JR NZ,TYS DEC C TYS DEC B PUSH HL,BC LD HL,DE CP B:JR Z,NEGRY EFRO ADD HL,DE DJNZ EFRO LD B,A NEGRY DEC C:JR NZ,EFRO LD (REZDE),HL POP BC,HL LD DE,HL CP B:JR Z,NEGRA OFER ADD HL,DE JR C,INCDE ENJO DJNZ OFER LD B,A NEGRA DEC C:JR NZ,OFER LD DE,(REZDE) UMN1 RET INCDE EXX LD HL,(REZDE) INC HL LD (REZDE),HL EXX JR ENJO ;=================TOS=================== ; (NSDC) <-0; (EOC)<-0 TOS XOR A:LD (NSDC),A,(EOC),A:RET ;=================XPOZI================= ;i ;DE HL - Cluster Number XPOZI LD (LTHL),HL,(LTDE),DE PROZ LD (BLKNUM),HL,(BLKNUM+2),DE RET ;======================================= ;NOPING XOR A:LD (HL),A:INC HL:DJNZ $-2 ; RET NOPIDE LD A,32,(DE),A:INC DE:DJNZ $-2 RET ;------------------------------------------------------------ INCLUDE "tsfat/DSDTS.ASM" ;INCLUDE "DSDTS_DMA.ASM" ;-----------LoCALL EQU LOBE+512 ---------------------------- LDMD EQU LoCALL;2 GARY EQU LDMD+2;2;see MKSG DABC EQU GARY+2;2;see CHTOSE DAHL EQU DABC+2;2;see HDD proc. DADE EQU DAHL+2;2; / ZES EQU DADE+2;1;/ PGO EQU ZES+1;2;Temp Page PGR EQU PGO+2;2;Restore Page CRRR EQU PGR+2;4 SPBU EQU CRRR+4;2 ;--------------------------------------- END \ No newline at end of file diff --git a/src/memory/arbiter.v b/src/memory/arbiter.v new file mode 100644 index 0000000..81bb18d --- /dev/null +++ b/src/memory/arbiter.v @@ -0,0 +1,256 @@ + +// PentEvo project (c) NedoPC 2008-2011 +// +// DRAM arbiter. Shares DRAM between CPU, video data fetcher and other devices +// + +// Arbitration is made on full 8-cycle access blocks. Each cycle is defined by dram.v and consists of 4 fpga clocks. +// During each access block, there can be either no videodata access, 1 videodata access, 2, 4 or 8 accesses. +// All spare cycles can be used by CPU or other devices. If no device uses memory in the given cycle, refresh cycle is performed. +// +// In each access block, videodata accesses are spreaded all over the block so that CPU receives cycle +// as fast as possible, until there is absolute need to fetch remaining video data. +// +// Examples: +// +// | access block | 4 video accesses during block, no processor accesses. video accesses are done +// | vid | vid | vid | vid | ref | ref | ref | ref | as soon as possible, spare cycles are refresh ones +// +// | access block | 4 video accesses during block, processor requests access every other cycle +// | vid | prc | vid | prc | vid | prc | vid | prc | +// +// | access block | 4 video accesses, processor begins requesting cycles continously from second one +// | vid | prc | prc | prc | prc | vid | vid | vid | so it is given cycles while there is such possibility. after that processor +// can't access mem until the end of access block and stalls +// +// | access block | 8 video accesses, processor stalls, if it is requesting cycles +// | vid | vid | vid | vid | vid | vid | vid | vid | +// +// | access block | 2 video accesses, single processor request, other cycles are refresh ones +// | vid | vid | ref | ref | cpu | ref | ref | ref | +// +// | access block | 4 video accesses, single processor request, other cycles are refresh ones +// | vid | vid | cpu | vid | vid | ref | ref | ref | +// +// access block begins at any dram cycle, then blocks go back-to-back +// +// key signals are go and XXX_req, sampled at the end of each dram cycle. Must be set to the module at c3 clock cycle. + +// CPU can have either normal or lower access priority to the DRAM. +// At the INT active (32 of 3.5MHz clocks) the priority is raised to normal, so that CPU won't miss its interrupt. +// This should be considered if dummy RAM access used for waiting for the end of DMA operation instead of status bit polling. +// +// DRAM access priority: +// Z80 normal Z80 low +// - VIDEO - VIDEO +// - CPU - TS +// - TM - TM +// - TS - DMA +// - DMA - CPU + + +module arbiter( + + input wire clk, + input wire c0, + input wire c1, + input wire c2, + input wire c3, + +// dram.v interface + output wire [23:0] dram_addr, // address for dram access + output wire dram_req, // dram request + output wire dram_rnw, // Read-NotWrite + output wire [ 1:0] dram_bsel, // byte select: bsel[1] for wrdata[15:8], bsel[0] for wrdata[7:0] + output wire [15:0] dram_wrdata, // data to be written + +// video + input wire [23:0] video_addr, // during access block, only when video_strobe==1 + input wire go, // start video access blocks + input wire [ 4:0] video_bw, // [4:3] - total cycles: 11 = 8 / 01 = 4 / 00 = 2 + // [2:0] - need cycles + output wire video_pre_next, // (c1) + output wire video_next, // (c2) at this signal video_addr may be changed; it is one clock leading the video_strobe + output wire video_strobe, // (c3) one-cycle strobe meaning that video_data is available + output wire video_next_strobe, // (c3) one-cycle strobe meaning that video_data is available + output wire next_vid, // used for TM prefetch + +// CPU + input wire [23:0] cpu_addr, + input wire [ 7:0] cpu_wrdata, + input wire cpu_req, + input wire cpu_rnw, + input wire cpu_wrbsel, + output reg cpu_next, // next cycle is allowed to be used by CPU + output reg cpu_strobe, // c2 strobe + output reg cpu_latch, // c2-c3 strobe + output wire curr_cpu_o, // +// DMA + input wire [23:0] dma_addr, + input wire [15:0] dma_wrdata, + input wire dma_req, + input wire dma_z80_lp, + input wire dma_rnw, + output wire dma_next, + +// TS + input wire [23:0] ts_addr, + input wire ts_req, + input wire ts_z80_lp, + output wire ts_pre_next, + output wire ts_next, + +// TM + input wire [23:0] tm_addr, + input wire tm_req, + output wire tm_next, + +//----- + output wire [7:0] TST + +); + + assign curr_cpu_o = curr_cpu; + + assign TST[0] = curr_dma; + assign TST[1] = curr_cpu; + assign TST[2] = dram_rnw; + assign TST[7:3] = 5'b00000; + + localparam CYCLES = 5; + + localparam CYC_CPU = 5'b00001; + localparam CYC_VID = 5'b00010; + localparam CYC_TS = 5'b00100; + localparam CYC_TM = 5'b01000; + localparam CYC_DMA = 5'b10000; + localparam CYC_FREE = 5'b00000; + + localparam CPU = 0; + localparam VIDEO = 1; + localparam TS = 2; + localparam TM = 3; + localparam DMA = 4; + + reg [CYCLES-1:0] curr_cycle; // type of the cycle in progress + reg [CYCLES-1:0] next_cycle; // type of the next cycle + + wire next_cpu = next_cycle[CPU]; + assign next_vid = next_cycle[VIDEO]; +// wire next_ts = next_cycle[TS]; +// wire next_tm = next_cycle[TM]; + wire next_dma = next_cycle[DMA]; + + wire curr_cpu = curr_cycle[CPU]; + wire curr_vid = curr_cycle[VIDEO]; + wire curr_ts = curr_cycle[TS]; + wire curr_tm = curr_cycle[TM]; + wire curr_dma = curr_cycle[DMA]; + + +// track blk_rem counter: +// how many cycles left to the end of block (7..0) + wire [2:0] blk_nrem = (video_start && go) ? {video_bw[4:3], 1'b1} : (video_start ? 3'd0 : (blk_rem - 3'd1)); + wire bw_full = ~|{video_bw[4] & video_bw[2], video_bw[3] & video_bw[1], video_bw[0]}; // stall when 000/00/0 + wire video_start = ~|blk_rem; + wire video_only = stall || (vid_rem == blk_rem); + wire video_idle = ~|vid_rem; + + reg [2:0] blk_rem; // remaining accesses in a block (7..0) + reg stall; + always @(posedge clk) if (c3) + begin + blk_rem <= blk_nrem; + if (video_start) + stall <= bw_full & go; + end + + +// track vid_rem counter +// how many video cycles left to the end of block (7..0) + wire [2:0] vid_nrem = (go && video_start) ? vid_nrem_start : (next_vid ? vid_nrem_next : vid_rem); + wire [2:0] vid_nrem_start = (cpu_req && !dev_over_cpu) ? vidmax : (vidmax - 3'd1); + wire [2:0] vid_nrem_next = video_idle ? 3'd0 : (vid_rem - 3'd1); + wire [2:0] vidmax = {video_bw[2:0]}; // number of cycles for video access + + reg [2:0] vid_rem; // remaining video accesses in block + always @(posedge clk) if (c3) + vid_rem <= vid_nrem; + + +// next cycle decision + wire [CYCLES-1:0] cyc_dev = tm_req ? CYC_TM : (ts_req ? CYC_TS : CYC_DMA); + wire dev_req = ts_req || tm_req || dma_req; + // wire dev_over_cpu = (((ts_req || tm_req) && ts_z80_lp) || (dma_req && dma_z80_lp)) && int_n; // CPU gets higher priority to acknowledge the INT + wire dev_over_cpu = 0; + + always @* + if (video_start) // video burst start + if (go) // video active line - 38us-ON, 26us-ON + begin + cpu_next = dev_over_cpu ? 1'b0 : !bw_full; + next_cycle = dev_over_cpu ? CYC_VID : (bw_full ? CYC_VID : (cpu_req ? CYC_CPU : CYC_VID)); + end + + else // video idle + begin + cpu_next = !dev_over_cpu; + next_cycle = dev_over_cpu ? cyc_dev : (cpu_req ? CYC_CPU : (dev_req ? cyc_dev : CYC_FREE)); + end + + else // video burst in progress + begin + cpu_next = dev_over_cpu ? 1'b0 : !video_only; + next_cycle = video_only ? CYC_VID : (dev_over_cpu ? cyc_dev : (cpu_req ? CYC_CPU : (!video_idle ? CYC_VID : (dev_req ? cyc_dev : CYC_FREE)))); + end + + always @(posedge clk) if (c3) + curr_cycle <= next_cycle; +// DRAM interface + assign dram_wrdata = curr_dma ? dma_wrdata : {2{cpu_wrdata[7:0]}}; // write data has to be clocked at c0 in dram.v + //assign dram_wrdata = curr_dma ? 16'h0000 : {2{cpu_wrdata[7:0]}}; // write data has to be clocked at c0 in dram.v + assign dram_bsel[1:0] = curr_dma ? 2'b11 : {cpu_wrbsel, ~cpu_wrbsel}; + assign dram_addr = {24{curr_cpu}} & cpu_addr + | {24{curr_vid}} & video_addr + | {24{curr_ts}} & ts_addr + | {24{curr_tm}} & tm_addr + | {24{curr_dma}} & dma_addr; + //==================================================== + assign dram_req = |next_cycle; //for c3=1, rising edge + assign dram_rnw = next_cpu ? cpu_rnw : (next_dma ? dma_rnw : 1'b1); + //assign dram_req = |curr_cycle; + //assign dram_rnw = curr_cpu ? cpu_rnw : (curr_dma ? dma_rnw : 1'b1); + + + reg cpu_rnw_r; + always @(posedge clk) if (c3) + cpu_rnw_r <= cpu_rnw; + + +// generation of read strobes: for video and cpu + always @(posedge clk) + if (c1) + begin + cpu_strobe <= curr_cpu && cpu_rnw_r; + cpu_latch <= curr_cpu && cpu_rnw_r; + end + else if (c2) + cpu_strobe <= 1'b0; + else if (c3) + cpu_latch <= 1'b0; + + + assign video_pre_next = curr_vid & c1; + assign video_next = curr_vid & c2; + assign video_strobe = curr_vid && c3; + assign video_next_strobe = next_vid && c3; + + assign ts_pre_next = curr_ts & c1; + assign ts_next = curr_ts & c2; + + assign tm_next = curr_tm & c2; + + assign dma_next = curr_dma & c2; + + +endmodule diff --git a/src/memory/dma.v b/src/memory/dma.v new file mode 100644 index 0000000..c46dda0 --- /dev/null +++ b/src/memory/dma.v @@ -0,0 +1,310 @@ +// This module serves direct DRAM-to-device data transfer + +// to do +// - probably add the extra 8 bit counter for number of bursts + +module dma ( + +// clocks + input wire clk, + input wire c2, + input wire reset, + +// interface + input wire [8:0] dmaport_wr, + output wire dma_act, + output reg [15:0] data, + output wire [ 7:0] wraddr, + output wire int_start, + +// Z80 + input wire [7:0] zdata, + +// DRAM interface + output wire [20:0] dram_addr, + input wire [15:0] dram_rddata, + output wire [15:0] dram_wrdata, + output wire dram_req, + output reg dma_z80_lp, + output wire dram_rnw, + input wire dram_next, + +// SPI interface + input wire [7:0] spi_rddata, + output wire [7:0] spi_wrdata, + output wire spi_req, + input wire spi_stb, + input wire spi_start, + +// IDE interface + input wire [15:0] ide_in, + output wire [15:0] ide_out, + output wire ide_req, + output wire ide_rnw, + input wire ide_stb, + +// CRAM interface + output wire cram_we, + +// SFILE interface + output wire sfile_we, + //--------------------- + output wire [3:0] TST +); + + assign TST[0] = dma_act; + assign TST[1] = dma_len; + assign TST[2] = b_len[7]; + assign TST[3] = b_ctr[7]; +// mode: +// 0 - device to RAM (read from device) +// 1 - RAM to device (write to device) + + assign wraddr = d_addr[7:0]; + // wire [8:0] dma_wr = dmaport_wr & {9{!dma_act}}; // blocking of DMA regs write strobes while DMA active + wire [8:0] dma_wr = dmaport_wr; + + wire dma_saddrl = dma_wr[0]; + wire dma_saddrh = dma_wr[1]; + wire dma_saddrx = dma_wr[2]; + wire dma_daddrl = dma_wr[3]; + wire dma_daddrh = dma_wr[4]; + wire dma_daddrx = dma_wr[5]; + wire dma_len = dma_wr[6]; + wire dma_launch = dma_wr[7]; + wire dma_num = dma_wr[8]; + +// DRAM + assign dram_addr = state_rd ? ((!dv_blt || !phase_blt) ? s_addr : d_addr) : d_addr; + assign dram_wrdata = data; + assign dram_req = dma_act && state_mem; + assign dram_rnw = state_rd; + +// devices + wire [3:0] devsel = {dma_wnr, device}; + wire dv_ram = (device == 3'b001) || (devsel == 4'b0100); + wire dv_blt = (devsel == 4'b1001); + wire dv_fil = (devsel == 4'b0100); + wire dv_spi = (device == 3'b010); + wire dv_ide = (device == 3'b011); + wire dv_crm = (devsel == 4'b1100); + wire dv_sfl = (devsel == 4'b1101); + + wire dev_req = dma_act && state_dev; + wire dev_stb = cram_we || sfile_we || ide_int_stb || (spi_int_stb && bsel); + + wire spi_int_stb = dv_spi && spi_stb; + wire spi_int_start = dv_spi && spi_start; + wire ide_int_stb = dv_ide && ide_stb; + assign cram_we = dev_req && dv_crm && state_wr; + assign sfile_we = dev_req && dv_sfl && state_wr; + + // SPI + assign spi_wrdata = {8{state_rd}} | (bsel ? data[15:8] : data[7:0]); // send FF on read cycles + assign spi_req = dev_req && dv_spi; + + // IDE + assign ide_out = data; + assign ide_req = dev_req && dv_ide; + assign ide_rnw = state_rd; + + // blitter + wire [15:0] blt_rddata = {blt_data_h, blt_data_l}; + wire [7:0] blt_data_h = dma_asz ? blt_data32 : {blt_data3, blt_data2}; + wire [7:0] blt_data_l = dma_asz ? blt_data10 : {blt_data1, blt_data0}; + wire [7:0] blt_data32 = |data[15:8] ? data[15:8] : dram_rddata[15:8]; + wire [7:0] blt_data10 = |data[7:0] ? data[7:0] : dram_rddata[7:0]; + wire [3:0] blt_data3 = |data[15:12] ? data[15:12] : dram_rddata[15:12]; + wire [3:0] blt_data2 = |data[11:8] ? data[11:8] : dram_rddata[11:8]; + wire [3:0] blt_data1 = |data[7:4] ? data[7:4] : dram_rddata[7:4]; + wire [3:0] blt_data0 = |data[3:0] ? data[3:0] : dram_rddata[3:0]; + +// data aquiring + always @(posedge clk) + if (state_rd) + begin + if (dram_next) + data <= (dv_blt && phase_blt) ? blt_rddata : dram_rddata; + + if (ide_int_stb) + data <= ide_in; + + if (spi_int_start) // data that is already read from SPI, just get it + begin + if (bsel) + data[15:8] <= spi_rddata; + else + data[7:0] <= spi_rddata; + end + end + +// states + wire state_rd = ~phase; + wire state_wr = phase; + wire state_dev = !dv_ram && (dma_wnr ^ !phase); + wire state_mem = dv_ram || (dma_wnr ^ phase); + +// states processing + wire phase_end = phase_end_ram || phase_end_dev; + wire phase_end_ram = state_mem && dram_next && !blt_hook; + wire phase_end_dev = state_dev && dev_stb; + wire blt_hook = dv_blt && !phase_blt && !phase; + wire fil_hook = dv_fil && phase; + wire phase_blt_end = state_mem && dram_next && !phase; + + // blitter cycles: + // phase phase_blt blt_hook activity + // 0 0 1 read src + // 0 1 0 read dst + // 1 1 0 write dst + + reg [2:0] device; + reg dma_wnr; // 0 - device to RAM / 1 - RAM to device + reg dma_salgn; + reg dma_dalgn; + reg dma_asz; + reg phase; // 0 - read / 1 - write + reg phase_blt; // 0 - source / 1 - destination + reg bsel; // 0 - lsb / 1 - msb + + always @(posedge clk) + if (dma_launch) // write to DMACtrl - launch of DMA burst + begin + dma_wnr <= zdata[7]; + dma_z80_lp <= zdata[6]; + dma_salgn <= zdata[5]; + dma_dalgn <= zdata[4]; + dma_asz <= zdata[3]; + device <= zdata[2:0]; + phase <= 1'b0; + phase_blt <= 1'b0; + bsel <= 1'b0; + end + + else + begin + if (phase_end && !fil_hook) + phase <= ~phase; + if (phase_blt_end) + phase_blt <= ~phase_blt; + if (spi_int_stb) + bsel <= ~bsel; + end + + +// counter processing + reg [7:0] b_len; // length of burst + reg [7:0] b_num; // number of bursts + reg [7:0] b_ctr; // counter for cycles in burst + reg [8:0] n_ctr; // counter for bursts + + assign dma_act = ~n_ctr[8]; + wire [7:0] b_ctr_next = next_burst ? b_len : b_ctr_dec[7:0]; + wire [8:0] b_ctr_dec = {1'b0, b_ctr[7:0]} - 9'b1; + wire [8:0] n_ctr_dec = n_ctr - next_burst; + wire next_burst = b_ctr_dec[8]; + + always @(posedge clk) + if (reset) + n_ctr[8] <= 1'b1; // disable DMA on RESET + + else + if (dma_launch) // launch of DMA burst + begin + b_ctr <= b_len; + n_ctr <= {1'b0, b_num}; + end + + else if (phase && phase_end) // cycle processed + begin + b_ctr <= b_ctr_next; + n_ctr <= n_ctr_dec; + end + + +// loading of burst parameters + always @(posedge clk) + begin + if (dma_len) + b_len <= zdata; + + if (dma_num) + b_num <= zdata; + end + + +// address processing + + // source + wire [20:0] s_addr_next = {s_addr_next_h[13:1], s_addr_next_m, s_addr_next_l[6:0]}; + wire [13:0] s_addr_next_h = s_addr[20:7] + s_addr_add_h; + wire [1:0] s_addr_add_h = dma_salgn ? {next_burst && dma_asz, next_burst && !dma_asz} : {s_addr_inc_l[8], 1'b0}; + wire s_addr_next_m = dma_salgn ? (dma_asz ? s_addr_next_l[7] : s_addr_next_h[0]) : s_addr_inc_l[7]; + wire [7:0] s_addr_next_l = (dma_salgn && next_burst) ? s_addr_r : s_addr_inc_l[7:0]; + wire [8:0] s_addr_inc_l = {1'b0, s_addr[7:0]} + 9'b1; + + reg [20:0] s_addr; // current source address + reg [7:0] s_addr_r; // source lower address + + always @(posedge clk) + if ((dram_next || dev_stb) && state_rd && (!dv_blt || !phase_blt)) // increment RAM source addr + s_addr <= s_addr_next; + + else + begin + if (dma_saddrl) + begin + s_addr[6:0] <= zdata[7:1]; + s_addr_r[6:0] <= zdata[7:1]; + end + + if (dma_saddrh) + begin + s_addr[12:7] <= zdata[5:0]; + s_addr_r[7] <= zdata[0]; + end + + if (dma_saddrx) + s_addr[20:13] <= zdata; + end + + // destination + wire [20:0] d_addr_next = {d_addr_next_h[13:1], d_addr_next_m, d_addr_next_l[6:0]}; + wire [13:0] d_addr_next_h = d_addr[20:7] + d_addr_add_h; + wire [1:0] d_addr_add_h = dma_dalgn ? {next_burst && dma_asz, next_burst && !dma_asz} : {d_addr_inc_l[8], 1'b0}; + wire d_addr_next_m = dma_dalgn ? (dma_asz ? d_addr_next_l[7] : d_addr_next_h[0]) : d_addr_inc_l[7]; + wire [7:0] d_addr_next_l = (dma_dalgn && next_burst) ? d_addr_r : d_addr_inc_l[7:0]; + wire [8:0] d_addr_inc_l = {1'b0, d_addr[7:0]} + 9'b1; + + reg [20:0] d_addr; // current dest address + reg [7:0] d_addr_r; // dest lower address + + always @(posedge clk) + if ((dram_next || dev_stb) && state_wr) // increment RAM dest addr + d_addr <= d_addr_next; + else + begin + if (dma_daddrl) + begin + d_addr[6:0] <= zdata[7:1]; + d_addr_r[6:0] <= zdata[7:1]; + end + + if (dma_daddrh) + begin + d_addr[12:7] <= zdata[5:0]; + d_addr_r[7] <= zdata[0]; + end + + if (dma_daddrx) + d_addr[20:13] <= zdata; + end + + // INT generation + reg dma_act_r; + always @(posedge clk) + dma_act_r <= dma_act; + + assign int_start = !dma_act && dma_act_r; + +endmodule diff --git a/src/rom.vhd b/src/rom.vhd new file mode 100644 index 0000000..fce7590 --- /dev/null +++ b/src/rom.vhd @@ -0,0 +1,144 @@ +-- megafunction wizard: %ROM: 1-PORT% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altsyncram + +-- ============================================================ +-- File Name: rom.vhd +-- Megafunction Name(s): +-- altsyncram +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 17.0.1 Build 598 06/07/2017 SJ Standard Edition +-- ************************************************************ + + +--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. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.altera_mf_components.all; + +ENTITY rom IS + PORT + ( + address : IN STD_LOGIC_VECTOR (12 DOWNTO 0); + clock : IN STD_LOGIC := '1'; + q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) + ); +END rom; + + +ARCHITECTURE SYN OF rom IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0); + +BEGIN + q <= sub_wire0(7 DOWNTO 0); + + altsyncram_component : altsyncram + GENERIC MAP ( + address_aclr_a => "NONE", + clock_enable_input_a => "BYPASS", + clock_enable_output_a => "BYPASS", + init_file => "./loader_fat32/loader.hex", + intended_device_family => "Cyclone IV E", + lpm_hint => "ENABLE_RUNTIME_MOD=NO", + lpm_type => "altsyncram", + numwords_a => 8192, + operation_mode => "ROM", + outdata_aclr_a => "NONE", + outdata_reg_a => "UNREGISTERED", + widthad_a => 13, + width_a => 8, + width_byteena_a => 1 + ) + PORT MAP ( + address_a => address, + clock0 => clock, + q_a => sub_wire0 + ); + + + +END SYN; + +-- ============================================================ +-- CNX file retrieval info +-- ============================================================ +-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0" +-- Retrieval info: PRIVATE: AclrByte NUMERIC "0" +-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +-- Retrieval info: PRIVATE: Clken NUMERIC "0" +-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" +-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +-- Retrieval info: PRIVATE: MIFfilename STRING "./src/loader_fat32/loader.hex" +-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "8192" +-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +-- Retrieval info: PRIVATE: RegAddr NUMERIC "1" +-- Retrieval info: PRIVATE: RegOutput NUMERIC "0" +-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +-- Retrieval info: PRIVATE: SingleClock NUMERIC "1" +-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0" +-- Retrieval info: PRIVATE: WidthAddr NUMERIC "13" +-- Retrieval info: PRIVATE: WidthData NUMERIC "8" +-- Retrieval info: PRIVATE: rden NUMERIC "0" +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" +-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" +-- Retrieval info: CONSTANT: INIT_FILE STRING "./src/loader_fat32/loader.hex" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "8192" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM" +-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" +-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED" +-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "13" +-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" +-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +-- Retrieval info: USED_PORT: address 0 0 13 0 INPUT NODEFVAL "address[12..0]" +-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]" +-- Retrieval info: CONNECT: @address_a 0 0 13 0 address 0 0 13 0 +-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +-- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0 +-- Retrieval info: GEN_FILE: TYPE_NORMAL rom.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL rom.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL rom.cmp FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL rom.bsf FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL rom_inst.vhd FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/src/rtc/CMOS.bin b/src/rtc/CMOS.bin new file mode 100644 index 0000000..e210311 Binary files /dev/null and b/src/rtc/CMOS.bin differ diff --git a/src/rtc/CMOS.hex b/src/rtc/CMOS.hex new file mode 100644 index 0000000..ac094d1 --- /dev/null +++ b/src/rtc/CMOS.hex @@ -0,0 +1,9 @@ +:200000000000000000000000000000000000000000AA000000000000000000000000000036 +:200020000000000000000000000000000000000000000000000000000000000000000000C0 +:200040000000000000000000000000000000000000000000000000000000000000000000A0 +:20006000000000000000000000000000000000000000000000000000000000000000000080 +:20008000000000000000000000000000000000000000000000000000000000000000000060 +:2000A00000000000000000000000000000000000000100010300000001000002FFFFFFFF3C +:2000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFF000042088410C61808214A298C31CE392104ED +:2000E000630CA514E71C29256B2DAD35EF3D6BA200000000000000000000000000000000D4 +:00000001FF diff --git a/src/rtc/CMOS.vhd b/src/rtc/CMOS.vhd new file mode 100644 index 0000000..040aeea --- /dev/null +++ b/src/rtc/CMOS.vhd @@ -0,0 +1,235 @@ +-- megafunction wizard: %RAM: 2-PORT% +-- GENERATION: STANDARD +-- VERSION: WM1.0 +-- MODULE: altsyncram + +-- ============================================================ +-- File Name: CMOS.vhd +-- Megafunction Name(s): +-- altsyncram +-- +-- Simulation Library Files(s): +-- altera_mf +-- ============================================================ +-- ************************************************************ +-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +-- +-- 11.0 Build 157 04/27/2011 SJ Full Version +-- ************************************************************ + + +--Copyright (C) 1991-2011 Altera Corporation +--Your use of Altera 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 Altera Program License +--Subscription Agreement, Altera 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 Altera and sold by +--Altera or its authorized distributors. Please refer to the +--applicable agreement for further details. + + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.all; + +ENTITY CMOS IS + PORT + ( + clock : IN STD_LOGIC := '1'; + data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); + rdaddress : IN STD_LOGIC_VECTOR (7 DOWNTO 0); + wraddress : IN STD_LOGIC_VECTOR (7 DOWNTO 0); + wren : IN STD_LOGIC := '0'; + q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) + ); +END CMOS; + + +ARCHITECTURE SYN OF cmos IS + + SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0); + + + + COMPONENT altsyncram + GENERIC ( + address_aclr_b : STRING; + address_reg_b : STRING; + clock_enable_input_a : STRING; + clock_enable_input_b : STRING; + clock_enable_output_b : STRING; + init_file : STRING; + intended_device_family : STRING; + lpm_type : STRING; + numwords_a : NATURAL; + numwords_b : NATURAL; + operation_mode : STRING; + outdata_aclr_b : STRING; + outdata_reg_b : STRING; + power_up_uninitialized : STRING; + read_during_write_mode_mixed_ports : STRING; + widthad_a : NATURAL; + widthad_b : NATURAL; + width_a : NATURAL; + width_b : NATURAL; + width_byteena_a : NATURAL + ); + PORT ( + address_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0); + clock0 : IN STD_LOGIC ; + data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0); + q_b : OUT STD_LOGIC_VECTOR (7 DOWNTO 0); + wren_a : IN STD_LOGIC ; + address_b : IN STD_LOGIC_VECTOR (7 DOWNTO 0) + ); + END COMPONENT; + +BEGIN + q <= sub_wire0(7 DOWNTO 0); + + altsyncram_component : altsyncram + GENERIC MAP ( + address_aclr_b => "NONE", + address_reg_b => "CLOCK0", + clock_enable_input_a => "BYPASS", + clock_enable_input_b => "BYPASS", + clock_enable_output_b => "BYPASS", + init_file => "src/rtc/CMOS.hex", + intended_device_family => "Cyclone IV E", + lpm_type => "altsyncram", + numwords_a => 256, + numwords_b => 256, + operation_mode => "DUAL_PORT", + outdata_aclr_b => "NONE", + outdata_reg_b => "UNREGISTERED", + power_up_uninitialized => "FALSE", + read_during_write_mode_mixed_ports => "DONT_CARE", + widthad_a => 8, + widthad_b => 8, + width_a => 8, + width_b => 8, + width_byteena_a => 1 + ) + PORT MAP ( + address_a => wraddress, + clock0 => clock, + data_a => data, + wren_a => wren, + address_b => rdaddress, + q_b => sub_wire0 + ); + + + +END SYN; + +-- ============================================================ +-- CNX file retrieval info +-- ============================================================ +-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +-- Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +-- Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +-- Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +-- Retrieval info: PRIVATE: CLRdata NUMERIC "0" +-- Retrieval info: PRIVATE: CLRq NUMERIC "0" +-- Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +-- Retrieval info: PRIVATE: CLRrren NUMERIC "0" +-- Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +-- Retrieval info: PRIVATE: CLRwren NUMERIC "0" +-- Retrieval info: PRIVATE: Clock NUMERIC "0" +-- Retrieval info: PRIVATE: Clock_A NUMERIC "0" +-- Retrieval info: PRIVATE: Clock_B NUMERIC "0" +-- Retrieval info: PRIVATE: ECC NUMERIC "0" +-- Retrieval info: PRIVATE: ECC_PIPELINE_STAGE NUMERIC "0" +-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +-- Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +-- Retrieval info: PRIVATE: MEMSIZE NUMERIC "2048" +-- Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +-- Retrieval info: PRIVATE: MIFfilename STRING "../rtl/rtc/CMOS.hex" +-- Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +-- Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0" +-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +-- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +-- Retrieval info: PRIVATE: REGdata NUMERIC "1" +-- Retrieval info: PRIVATE: REGq NUMERIC "0" +-- Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +-- Retrieval info: PRIVATE: REGrren NUMERIC "1" +-- Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +-- Retrieval info: PRIVATE: REGwren NUMERIC "1" +-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +-- Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +-- Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +-- Retrieval info: PRIVATE: VarWidth NUMERIC "0" +-- Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8" +-- Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8" +-- Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8" +-- Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8" +-- Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +-- Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +-- Retrieval info: PRIVATE: enable NUMERIC "0" +-- Retrieval info: PRIVATE: rden NUMERIC "0" +-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +-- Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" +-- Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" +-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +-- Retrieval info: CONSTANT: INIT_FILE STRING "../rtl/rtc/CMOS.hex" +-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" +-- Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "256" +-- Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +-- Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +-- Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED" +-- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +-- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE" +-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" +-- Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "8" +-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" +-- Retrieval info: CONSTANT: WIDTH_B NUMERIC "8" +-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +-- Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]" +-- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]" +-- Retrieval info: USED_PORT: rdaddress 0 0 8 0 INPUT NODEFVAL "rdaddress[7..0]" +-- Retrieval info: USED_PORT: wraddress 0 0 8 0 INPUT NODEFVAL "wraddress[7..0]" +-- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +-- Retrieval info: CONNECT: @address_a 0 0 8 0 wraddress 0 0 8 0 +-- Retrieval info: CONNECT: @address_b 0 0 8 0 rdaddress 0 0 8 0 +-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +-- Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0 +-- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +-- Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0 +-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.vhd TRUE +-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.inc FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.cmp FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS.bsf FALSE +-- Retrieval info: GEN_FILE: TYPE_NORMAL CMOS_inst.vhd FALSE +-- Retrieval info: LIB_FILE: altera_mf diff --git a/src/rtc/mc146818a.vhd b/src/rtc/mc146818a.vhd new file mode 100644 index 0000000..1d94ba5 --- /dev/null +++ b/src/rtc/mc146818a.vhd @@ -0,0 +1,303 @@ +-------------------------------------------------------------------[18.10.2014] +-- MC146818A REAL-TIME CLOCK PLUS RAM +------------------------------------------------------------------------------- +-- V0.1 05.10.2011 Initial version +-- V0.2 06.09.2014 Added General Purpose RAM + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use IEEE.std_logic_unsigned.all; + +entity mc146818a is +port ( + RESET : in std_logic; + CLK : in std_logic; + ENA : in std_logic; + CS : in std_logic; + + RTC : in std_logic_vector(64 downto 0); + CMOSCfg : in std_logic_vector(31 downto 0); + + + KEYSCANCODE : in std_logic_vector(7 downto 0); + WR : in std_logic; + A : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0)); +end; + +architecture rtl of mc146818a is + signal pre_scaler : std_logic_vector(18 downto 0); + signal leap_reg : std_logic_vector(1 downto 0); + signal seconds_reg : std_logic_vector(7 downto 0); -- 00 + signal seconds_alarm_reg : std_logic_vector(7 downto 0); -- 01 + signal minutes_reg : std_logic_vector(7 downto 0); -- 02 + signal minutes_alarm_reg : std_logic_vector(7 downto 0); -- 03 + signal hours_reg : std_logic_vector(7 downto 0); -- 04 + signal hours_alarm_reg : std_logic_vector(7 downto 0); -- 05 + signal weeks_reg : std_logic_vector(7 downto 0); -- 06 + signal days_reg : std_logic_vector(7 downto 0); -- 07 + signal month_reg : std_logic_vector(7 downto 0); -- 08 + signal year_reg : std_logic_vector(7 downto 0); -- 09 + signal a_reg : std_logic_vector(7 downto 0); -- 0A + signal b_reg : std_logic_vector(7 downto 0); -- 0B + signal c_reg : std_logic_vector(7 downto 0); -- 0C + + signal CMOS_Dout : std_logic_vector(7 downto 0); + signal Dout : std_logic_vector(7 downto 0); + + +begin + DO <= Dout; + + process(CLK, A, seconds_reg, seconds_alarm_reg, minutes_reg, minutes_alarm_reg, hours_reg, hours_alarm_reg, weeks_reg, days_reg, month_reg, year_reg, KEYSCANCODE, CMOS_Dout, a_reg, b_reg, c_reg, CMOSCfg) + begin + -- 14 Bytes of Clock and Control Registers Read + case A(7 downto 0) is + when x"00" => Dout <= seconds_reg; + when x"01" => Dout <= seconds_alarm_reg; + when x"02" => Dout <= minutes_reg; + when x"03" => Dout <= minutes_alarm_reg; + when x"04" => Dout <= hours_reg; + when x"05" => Dout <= hours_alarm_reg; + when x"06" => Dout <= weeks_reg; + when x"07" => Dout <= days_reg; + when x"08" => Dout <= month_reg; + when x"09" => Dout <= year_reg; + when x"0a" => Dout <= a_reg; + when x"0b" => Dout <= b_reg; + when x"0c" => Dout <= c_reg; + when x"0d" => Dout <= "10000000"; + + when x"b1" => Dout <= "000000" & CMOSCfg(7 downto 6); -- CPU Speed + when x"b2" => Dout <= "00000000"; -- Boot device + when x"b3" => Dout <= "0000000" & CMOSCfg(8); -- CPU Cache + + when x"b4" => Dout <= "00000" & CMOSCfg(13 downto 11); -- F11 + when x"b5" => Dout <= "000000" & CMOSCfg(15 downto 14); -- F11 bank + when x"b6" => Dout <= "00000" & CMOSCfg(18 downto 16); -- Shift+F11 + when x"b7" => Dout <= "000000" & CMOSCfg(20 downto 19); -- Shift+F11 bank + + when x"b8" => Dout <= "000000" & CMOSCfg(10 downto 9); -- #7FFD + when x"b9" => Dout <= "00000" & CMOSCfg(23 downto 21); -- ZX Palette + when x"ba" => Dout <= "0000000" & CMOSCfg(24); -- NGS Reset + when x"bb" => Dout <= "00000" & CMOSCfg(27 downto 25); -- INT offset + + when x"f0" => Dout <= KEYSCANCODE; + when others => Dout <= CMOS_Dout; + end case; + end process; + + process(CLK, ENA, RESET) + variable flg : std_logic := '0'; + begin + if CLK'event and CLK = '1' then + if flg /= RTC(64) then + seconds_reg <= RTC(7 downto 0); + minutes_reg <= RTC(15 downto 8); + hours_reg <= RTC(23 downto 16); + days_reg <= RTC(31 downto 24); + month_reg <= RTC(39 downto 32); + year_reg <= RTC(47 downto 40); + weeks_reg <= RTC(55 downto 48) + "1"; + b_reg <= "00000010"; + end if; + + flg := RTC(64); + if RESET = '1' then + b_reg <= "00000010"; + -- RTC register write + elsif WR = '1' and CS = '1' then + case A(7 downto 0) is + when x"00" => seconds_reg <= DI; + when x"01" => seconds_alarm_reg <= DI; + when x"02" => minutes_reg <= DI; + when x"03" => minutes_alarm_reg <= DI; + when x"04" => hours_reg <= DI; + when x"05" => hours_alarm_reg <= DI; + when x"06" => weeks_reg <= DI; + when x"07" => days_reg <= DI; + when x"08" => month_reg <= DI; + when x"09" => year_reg <= DI; + when x"0b" => b_reg <= DI; + + if b_reg(2) = '0' then -- BCD to BIN convertion + if DI(4) = '0' then + leap_reg <= DI(1 downto 0); + else + leap_reg <= (not DI(1)) & DI(0); + end if; + else + leap_reg <= DI(1 downto 0); + end if; + + when others => null; + end case; + end if; + + if RESET = '1' then + a_reg <= "00100110"; + c_reg <= (others => '0'); + elsif b_reg(7) = '0' and ENA = '1' then + if pre_scaler /= X"000000" then + pre_scaler <= pre_scaler - 1; + a_reg(7) <= '0'; + else + pre_scaler <= "1101010110011111100"; --(0.4375MHz) + a_reg(7) <= '1'; + c_reg(4) <= '1'; + -- alarm + if ((seconds_reg = seconds_alarm_reg) and + (minutes_reg = minutes_alarm_reg) and + (hours_reg = hours_alarm_reg)) then + c_reg(5) <= '1'; + end if; + -- DM binary-coded-decimal (BCD) data mode + if b_reg(2) = '0' then + if seconds_reg(3 downto 0) /= "1001" then + seconds_reg(3 downto 0) <= seconds_reg(3 downto 0) + 1; + else + seconds_reg(3 downto 0) <= (others => '0'); + if seconds_reg(6 downto 4) /= "101" then + seconds_reg(6 downto 4) <= seconds_reg(6 downto 4) + 1; + else + seconds_reg(6 downto 4) <= (others => '0'); + if minutes_reg(3 downto 0) /= "1001" then + minutes_reg(3 downto 0) <= minutes_reg(3 downto 0) + 1; + else + minutes_reg(3 downto 0) <= (others => '0'); + if minutes_reg(6 downto 4) /= "101" then + minutes_reg(6 downto 4) <= minutes_reg(6 downto 4) + 1; + else + minutes_reg(6 downto 4) <= (others => '0'); + if hours_reg(3 downto 0) = "1001" then + hours_reg(3 downto 0) <= (others => '0'); + hours_reg(5 downto 4) <= hours_reg(5 downto 4) + 1; + elsif b_reg(1) & hours_reg(7) & hours_reg(4 downto 0) = "0010010" then + hours_reg(4 downto 0) <= "00001"; + hours_reg(7) <= not hours_reg(7); + elsif ((b_reg(1) & hours_reg(7) & hours_reg(4 downto 0) /= "0110010") and + (b_reg(1) & hours_reg(5 downto 0) /= "1100011")) then + hours_reg(3 downto 0) <= hours_reg(3 downto 0) + 1; + else + if b_reg(1) = '0' then + hours_reg(7 downto 0) <= "00000001"; + else + hours_reg(5 downto 0) <= (others => '0'); + end if; + if weeks_reg(2 downto 0) /= "111" then + weeks_reg(2 downto 0) <= weeks_reg(2 downto 0) + 1; + else + weeks_reg(2 downto 0) <= "001"; + end if; + if ((month_reg & days_reg & leap_reg = X"0228" & "01") or + (month_reg & days_reg & leap_reg = X"0228" & "10") or + (month_reg & days_reg & leap_reg = X"0228" & "11") or + (month_reg & days_reg & leap_reg = X"0229" & "00") or + (month_reg & days_reg = X"0430") or + (month_reg & days_reg = X"0630") or + (month_reg & days_reg = X"0930") or + (month_reg & days_reg = X"1130") or + ( days_reg = X"31")) then + days_reg(5 downto 0) <= "000001"; + if month_reg(3 downto 0) = "1001" then + month_reg(4 downto 0) <= "10000"; + elsif month_reg(4 downto 0) /= "10010" then + month_reg(3 downto 0) <= month_reg(3 downto 0) + 1; + else + month_reg(4 downto 0) <= "00001"; + leap_reg(1 downto 0) <= leap_reg(1 downto 0) + 1; + if year_reg(3 downto 0) /= "1001" then + year_reg(3 downto 0) <= year_reg(3 downto 0) + 1; + else + year_reg(3 downto 0) <= "0000"; + if year_reg(7 downto 4) /= "1001" then + year_reg(7 downto 4) <= year_reg(7 downto 4) + 1; + else + year_reg(7 downto 4) <= "0000"; + end if; + end if; + end if; + elsif days_reg(3 downto 0) /= "1001" then + days_reg(3 downto 0) <= days_reg(3 downto 0) + 1; + else + days_reg(3 downto 0) <= (others => '0'); + days_reg(5 downto 4) <= days_reg(5 downto 4) + 1; + end if; + end if; + end if; + end if; + end if; + end if; + -- DM binary data mode + else + if seconds_reg /= x"3B" then + seconds_reg <= seconds_reg + 1; + else + seconds_reg <= (others => '0'); + if minutes_reg /= x"3B" then + minutes_reg <= minutes_reg + 1; + else + minutes_reg <= (others => '0'); + if b_reg(1) & hours_reg(7) & hours_reg(3 downto 0) = "001100" then + hours_reg(7 downto 0) <= "10000001"; + elsif ((b_reg(1) & hours_reg(7) & hours_reg(3 downto 0) /= "011100") and + (b_reg(1) & hours_reg(4 downto 0) /= "110111")) then + hours_reg(4 downto 0) <= hours_reg(4 downto 0) + 1; + else + if b_reg(1) = '0' then + hours_reg(7 downto 0) <= "00000001"; + else + hours_reg <= (others => '0'); + end if; + if weeks_reg /= x"07" then + weeks_reg <= weeks_reg + 1; + else + weeks_reg <= x"01"; -- Sunday = 1 + end if; + if ((month_reg & days_reg & leap_reg = X"021C" & "01") or + (month_reg & days_reg & leap_reg = X"021C" & "10") or + (month_reg & days_reg & leap_reg = X"021C" & "11") or + (month_reg & days_reg & leap_reg = X"021D" & "00") or + (month_reg & days_reg = X"041E") or + (month_reg & days_reg = X"061E") or + (month_reg & days_reg = X"091E") or + (month_reg & days_reg = X"0B1E") or + ( days_reg = X"1F")) then + days_reg <= x"01"; + if month_reg /= x"0C" then + month_reg <= month_reg + 1; + else + month_reg <= x"01"; + leap_reg(1 downto 0) <= leap_reg(1 downto 0) + 1; + if year_reg /= x"63" then + year_reg <= year_reg + 1; + else + year_reg <= x"00"; + end if; + end if; + else + days_reg <= days_reg + 1; + end if; + end if; + end if; + end if; + end if; + end if; + end if; + end if; + end process; + +-- 50 Bytes of General Purpose RAM +SE11: entity work.CMOS +port map ( + clock => CLK, + data => DI, + rdaddress => A, + wraddress => A, + wren => WR and CS, + q => CMOS_Dout + ); + +end rtl; \ No newline at end of file diff --git a/src/sdram.vhd b/src/sdram.vhd new file mode 100644 index 0000000..f846192 --- /dev/null +++ b/src/sdram.vhd @@ -0,0 +1,254 @@ +-------------------------------------------------------------------[03.08.2014] +-- SDRAM Controller +------------------------------------------------------------------------------- +-- V1.0 03.08.2014 Initial release +-- modified for 8Mb SDRAM 15.03.2015 (Ivan Gorodetsky) + +-- CLK = 84 MHz = 11.9 ns +-- WR/RD = 5T = 59.5 ns +-- RFSH = 6T = 71.4 ns + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity sdram is + port( + CLK : in std_logic; + clk_28MHz : in std_logic; + c0 : in std_logic; + c1 : in std_logic; + c2 : in std_logic; + c3 : in std_logic; + curr_cpu : in std_logic; + -- Memory port + loader : in std_logic; + bsel : in std_logic_vector(1 downto 0); -- Active HI + A : in std_logic_vector(23 downto 0); + DI : in std_logic_vector(15 downto 0); + DO : out std_logic_vector(15 downto 0); + DO_cpu : out std_logic_vector(15 downto 0); + dram_stb : out std_logic; + ---------------------------- + REQ : in std_logic; + RNW : in std_logic; + RFSH : in std_logic; --< REFRESH command NOT USED + RFSHREQ : out std_logic; --> request for refresh + IDLE : out std_logic; --> + -- SDRAM Pin + CK : out std_logic; + CKE : out std_logic; + RAS_n : out std_logic; + CAS_n : out std_logic; + WE_n : out std_logic; + BA1 : out std_logic; + BA0 : out std_logic; + MA : out std_logic_vector(12 downto 0); + DQ : inout std_logic_vector(15 downto 0); + DQML : out std_logic; + DQMH : out std_logic; + -- + TST : out std_logic_vector(3 downto 0) + ); +end sdram; + +architecture rtl of sdram is + signal state : unsigned(4 downto 0) := "00000"; + signal addr_in : std_logic_vector(23 downto 0); + signal address : std_logic_vector(23 downto 0); + signal bsel_int : std_logic_vector(1 downto 0); + signal rfsh_cnt : unsigned(9 downto 0) := "0000000000"; + signal rfsh_req : std_logic := '0'; + signal data_reg : std_logic_vector(15 downto 0); + signal cpu_reg : std_logic_vector(15 downto 0); + signal data_in : std_logic_vector(15 downto 0); + signal idle1 : std_logic; + signal st_rfsh : std_logic; + signal req_dis : std_logic; + ------------------------------ + signal WR_in : std_logic; + signal WR_in1 : std_logic; +-- signal WR_r : std_logic; + signal RD_in : std_logic; + signal RD_in1 : std_logic; +-- signal RD_r : std_logic; + signal REQ_in : std_logic; + signal RNW_in : std_logic; + signal rd_op : std_logic; + signal RFSH_in : std_logic; + -- SD-RAM control signals + signal sdr_cmd : std_logic_vector(2 downto 0); + signal sdr_ba0 : std_logic; + signal sdr_ba1 : std_logic; + signal sdr_dqml : std_logic; + signal sdr_dqmh : std_logic; + signal sdr_a : std_logic_vector(12 downto 0); + signal sdr_dq : std_logic_vector(15 downto 0); + + constant SdrCmd_xx : std_logic_vector(2 downto 0) := "111"; -- no operation + constant SdrCmd_ac : std_logic_vector(2 downto 0) := "011"; -- activate + constant SdrCmd_rd : std_logic_vector(2 downto 0) := "101"; -- read + constant SdrCmd_wr : std_logic_vector(2 downto 0) := "100"; -- write + constant SdrCmd_pr : std_logic_vector(2 downto 0) := "010"; -- precharge all + constant SdrCmd_re : std_logic_vector(2 downto 0) := "001"; -- refresh + constant SdrCmd_ms : std_logic_vector(2 downto 0) := "000"; -- mode regiser set + +-- Init------------------------------------------------------------------- Idle Read------- Write------ Refresh------- +-- 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 16 17 1B 1C 16 17 13 14 15 16 17 +-- pr xx xx re xx xx xx xx xx xx re xx xx xx xx xx xx ms xx xx xx xx xx xx xx/ac/re xx rd xx xx xx wr xx xx xx xx xx xx xx + +begin + + TST(0) <= WR_in; --idle1; --RD_in; + TST(1) <= data_in(0); --idle1; -- + TST(2) <= idle1; -- + TST(3) <= st_rfsh; + + process (clk_28MHz, c3, DI, A, c0) + begin + if rising_edge (clk_28MHz) and (c3 = '1') then --next_cycle + if (REQ = '1' and RNW = '1') then + RD_in <= '1'; + elsif (REQ = '1' and RNW = '0') then + WR_in <= '1'; + else + RFSH_in <= '1'; + end if; + end if; + data_in <= DI; + addr_in <= A; + if rising_edge (clk_28MHz) and (c0 = '1') then --NOT WORK + RD_in <= '0'; + WR_in <= '0'; + RFSH_in <= '0'; + end if; + end process; + + process (CLK) + begin + if CLK'event and CLK = '0' then + --------------------------------------------------------- + case state is + -- Init + when "00000" => -- s00 + sdr_cmd <= SdrCmd_pr; -- PRECHARGE + sdr_a <= "1111111111111"; + sdr_ba1 <= '0'; + sdr_ba0 <= '0'; + sdr_dqml <= '1'; + sdr_dqmh <= '1'; + state <= state + 1; + when "00011" | "01010" => -- s03 s0A + sdr_cmd <= SdrCmd_re; -- REFRESH + state <= state + 1; + when "10001" => -- s11 + sdr_cmd <= SdrCmd_ms; -- LOAD MODE REGISTER + sdr_a <= "000" & "1" & "00" & "010" & "0" & "000"; + state <= state + 1; + + -- Idle + when "11000" => -- s18 + sdr_dq <= (others => 'Z'); + if RD_in = '1' then + idle1 <= '0'; + bsel_int <= bsel; + address <= addr_in; -- LOCK ADDR + sdr_cmd <= SdrCmd_ac; -- ACTIVE + sdr_ba1 <= addr_in(10); -- A(11) + sdr_ba0 <= addr_in(9); -- A(10) +-- sdr_a <= addr_in(23 downto 11); -- RAW_ADDR(12..0) + sdr_a <= "0"&addr_in(23)&addr_in(20 downto 11)&addr_in(8); -- RAW_ADDR(12..0) + state <= "11001"; -- s19 Read = when "11010" + elsif WR_in = '1' and (loader = '1' or addr_in(23) = '0') then --Rising UP + idle1 <= '0'; + rd_op <= '0'; + bsel_int <= bsel; + address <= addr_in; + sdr_cmd <= SdrCmd_ac; -- ACTIVE + sdr_ba1 <= addr_in(10); + sdr_ba0 <= addr_in(9); +-- sdr_a <= addr_in(23 downto 11); + sdr_a <= "0"&addr_in(23)&addr_in(20 downto 11)&addr_in(8); -- RAW_ADDR(12..0) + state <= "11011"; -- s1B Write + elsif RFSH_in = '1' then + idle1 <= '0'; + rd_op <= '0'; + st_rfsh <= '1'; + rfsh_req <= '0'; + sdr_cmd <= SdrCmd_re; -- REFRESH + state <= "10011"; -- s13 + else + sdr_cmd <= SdrCmd_xx; -- NOP + idle1 <= '1'; + rd_op <= '0'; + st_rfsh <= '0'; + end if; + + -- A24 A23 A22 A21 A20 A19 A18 A17 A16 A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 + -- -----------------------ROW------------------------- BA1 BA0 -----------COLUMN------------ + -- Single read - with auto precharge + when "11010" => -- s1A + sdr_cmd <= SdrCmd_rd; -- READ (A10 = 1 enable auto precharge; A9..0 = column) +-- sdr_a <= "0010" & address(8 downto 0); + sdr_a <= "00100" & address(7 downto 0); + sdr_dqml <= '0'; + sdr_dqmh <= '0'; + state <= "10110"; -- s16 + rd_op <= '1'; + -- Single write - with auto precharge + when "11100" => -- s1C + sdr_cmd <= SdrCmd_wr; -- WRITE (A10 = 1 enable auto precharge; A9..0 = column) +-- sdr_a <= "0010" & address(8 downto 0); + sdr_a <= "00100" & address(7 downto 0); + sdr_dqml <= not bsel_int(0); + sdr_dqmh <= not bsel_int(1); + sdr_dq <= data_in; + state <= "10110"; -- s16 + + when others => + sdr_dq <= (others => 'Z'); + sdr_cmd <= SdrCmd_xx; -- NOP + state <= state + 1; + end case; + + -- Providing a distributed AUTO REFRESH command every 7.81us + if rfsh_cnt = "1010010001" then -- (84MHz * 1000 * 64 / 8192) = 657 %10 1001 0001 + rfsh_cnt <= (others => '0'); + rfsh_req <= '1'; + else + rfsh_cnt <= rfsh_cnt + 1; + end if; + + end if; + end process; + + process (CLK, rd_op) + begin --------------CLK = '0'------OK------------ + if CLK'event and CLK = '1' and rd_op = '1' then ---idle1 = '0' then + if state = "11000" then -- s18 + data_reg <= DQ; + if curr_cpu = '1' then + cpu_reg <= DQ; + end if; + end if; + end if; + end process; + + IDLE <= idle1; + DO <= data_reg; + DO_cpu <= cpu_reg; + RFSHREQ <= rfsh_req; + CK <= CLK; + CKE <= '1'; + RAS_n <= sdr_cmd(2); + CAS_n <= sdr_cmd(1); + WE_n <= sdr_cmd(0); + DQML <= sdr_dqml; + DQMH <= sdr_dqmh; + BA1 <= sdr_ba1; + BA0 <= sdr_ba0; + MA <= sdr_a; + DQ <= sdr_dq; + dram_stb <= rd_op; + +end rtl; \ No newline at end of file diff --git a/src/sound/ay8910.vhd b/src/sound/ay8910.vhd new file mode 100644 index 0000000..1b925cd --- /dev/null +++ b/src/sound/ay8910.vhd @@ -0,0 +1,314 @@ +-------------------------------------------------------------------[07.09.2013] +-- AY3-8910 +------------------------------------------------------------------------------- +-- V0.1 15.10.2011 + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity ay8910 is + port( + CLK : in std_logic; -- System Clock + ENA : in std_logic; -- PSG Clock + RESET : in std_logic; -- Chip Reset (set all Registers to '0', active hi) + BDIR : in std_logic; -- Bus Direction (0 - read , 1 - write) + CS : in std_logic; -- Chip Select (active hi) + BC : in std_logic; -- Bus control + DI : in std_logic_vector(7 downto 0); -- Data In + DO : out std_logic_vector(7 downto 0); -- Data Out + OUT_A : out std_logic_vector(7 downto 0); -- PSG Output channel A + OUT_B : out std_logic_vector(7 downto 0); -- PSG Output channel B + OUT_C : out std_logic_vector(7 downto 0) -- PSG Output channel C + ); +end ay8910; + +architecture rtl of ay8910 is + + signal ClockDiv : unsigned (3 downto 0); -- Divide ENA + +-- AY Registers + signal Period_A : std_logic_vector (11 downto 0); -- Channel A Tone Period (R1:R0) + signal Period_B : std_logic_vector (11 downto 0); -- Channel B Tone Period (R3:R2) + signal Period_C : std_logic_vector (11 downto 0); -- Channel C Tone Period (R5:R4) + signal Period_N : std_logic_vector (4 downto 0); -- Noise Period (R6) + signal Enable : std_logic_vector (7 downto 0); -- Enable (R7) + signal Volume_A : std_logic_vector (4 downto 0); -- Channel A Amplitude (R10) + signal Volume_B : std_logic_vector (4 downto 0); -- Channel B Amplitude (R11) + signal Volume_C : std_logic_vector (4 downto 0); -- Channel C Amplitude (R12) + signal Period_E : std_logic_vector (15 downto 0); -- Envelope Period (R14:R13) + signal Shape : std_logic_vector (3 downto 0); -- Envelope Shape/Cycle (R15) +-- signal Port_A : std_logic_vector (7 downto 0); -- I/O Port A Data Store (R16) +-- signal Port_B : std_logic_vector (7 downto 0); -- I/O Port B Data Store (R17) +-- + signal Address : std_logic_vector (3 downto 0); -- Selected Register + + alias Continue : std_logic is Shape(3); -- Envelope Control + alias Attack : std_logic is Shape(2); + alias Alternate : std_logic is Shape(1); + alias Hold : std_logic is Shape(0); + + signal Reset_Req : std_logic; -- Envelope Reset Required + signal Reset_Ack : std_logic; -- Envelope Reset Acknoledge + signal Volume_E : std_logic_vector (3 downto 0); -- Envelope Volume + + signal Freq_A : std_logic; -- Tone Generator A Output + signal Freq_B : std_logic; -- Tone Generator B Output + signal Freq_C : std_logic; -- Tone Generator C Output + signal Freq_N : std_logic; -- Noise Generator Output + + function VolumeTable (value : std_logic_vector(3 downto 0)) return std_logic_vector is + variable result : std_logic_vector (7 downto 0); + begin + case value is -- Volume Table + when "1111" => result := "11111111"; + when "1110" => result := "10110100"; + when "1101" => result := "01111111"; + when "1100" => result := "01011010"; + when "1011" => result := "00111111"; + when "1010" => result := "00101101"; + when "1001" => result := "00011111"; + when "1000" => result := "00010110"; + when "0111" => result := "00001111"; + when "0110" => result := "00001011"; + when "0101" => result := "00000111"; + when "0100" => result := "00000101"; + when "0011" => result := "00000011"; + when "0010" => result := "00000010"; + when "0001" => result := "00000001"; + when "0000" => result := "00000000"; + when others => null; + end case; + return result; + end VolumeTable; + +begin + +-- Write to AY +process (RESET , CLK) +begin + if RESET = '1' then + Address <= "0000"; + Period_A <= "000000000000"; + Period_B <= "000000000000"; + Period_C <= "000000000000"; + Period_N <= "00000"; + Enable <= "00000000"; + Volume_A <= "00000"; + Volume_B <= "00000"; + Volume_C <= "00000"; + Period_E <= "0000000000000000"; + Shape <= "0000"; +-- Port_A <= "00000000"; +-- Port_B <= "00000000"; + Reset_Req <= '0'; + elsif rising_edge(CLK) then + if CS = '1' and BDIR = '1' then + if BC = '1' then + Address <= DI (3 downto 0); -- Latch Address + else + case Address is -- Latch Registers + when "0000" => Period_A (7 downto 0) <= DI; + when "0001" => Period_A (11 downto 8) <= DI (3 downto 0); + when "0010" => Period_B (7 downto 0) <= DI; + when "0011" => Period_B (11 downto 8) <= DI (3 downto 0); + when "0100" => Period_C (7 downto 0) <= DI; + when "0101" => Period_C (11 downto 8) <= DI (3 downto 0); + when "0110" => Period_N <= DI (4 downto 0); + when "0111" => Enable <= DI; + when "1000" => Volume_A <= DI (4 downto 0); + when "1001" => Volume_B <= DI (4 downto 0); + when "1010" => Volume_C <= DI (4 downto 0); + when "1011" => Period_E (7 downto 0) <= DI; + when "1100" => Period_E (15 downto 8) <= DI; + when "1101" => Shape <= DI (3 downto 0); + Reset_Req <= not Reset_Ack; -- Reset Envelope Generator +-- when "1110" => Port_A <= DI; +-- when "1111" => Port_B <= DI; + when others => null; + end case; + end if; + end if; + end if; +end process; + +-- Read from AY +DO <= Period_A (7 downto 0) when Address = "0000" and CS = '1' else + "0000" & Period_A (11 downto 8) when Address = "0001" and CS = '1' else + Period_B (7 downto 0) when Address = "0010" and CS = '1' else + "0000" & Period_B (11 downto 8) when Address = "0011" and CS = '1' else + Period_C (7 downto 0) when Address = "0100" and CS = '1' else + "0000" & Period_C (11 downto 8) when Address = "0101" and CS = '1' else + "000" & Period_N when Address = "0110" and CS = '1' else + Enable when Address = "0111" and CS = '1' else + "000" & Volume_A when Address = "1000" and CS = '1' else + "000" & Volume_B when Address = "1001" and CS = '1' else + "000" & Volume_C when Address = "1010" and CS = '1' else + Period_E (7 downto 0) when Address = "1011" and CS = '1' else + Period_E (15 downto 8) when Address = "1100" and CS = '1' else + "0000" & Shape when Address = "1101" and CS = '1' else + "11111111"; + +-- Divide ENA +process (RESET, CLK) +begin + if RESET = '1' then + ClockDiv <= "0000"; + elsif rising_edge(CLK) then + if ENA = '1' then + ClockDiv <= ClockDiv - 1; + end if; + end if; +end process; + +-- Tone Generator +process (RESET, CLK) + variable Counter_A : unsigned (11 downto 0); + variable Counter_B : unsigned (11 downto 0); + variable Counter_C : unsigned (11 downto 0); +begin + if RESET = '1' then + Counter_A := "000000000000"; + Counter_B := "000000000000"; + Counter_C := "000000000000"; + Freq_A <= '0'; + Freq_B <= '0'; + Freq_C <= '0'; + elsif rising_edge(CLK) then + if ClockDiv(2 downto 0) = "000" and ENA = '1' then + + -- Channel A Counter + if (Counter_A /= X"000") then + Counter_A := Counter_A - 1; + elsif (Period_A /= X"000") then + Counter_A := unsigned(Period_A) - 1; + end if; + if (Counter_A = X"000") then + Freq_A <= not Freq_A; + end if; + + -- Channel B Counter + if (Counter_B /= X"000") then + Counter_B := Counter_B - 1; + elsif (Period_B /= X"000") then + Counter_B := unsigned(Period_B) - 1; + end if; + if (Counter_B = X"000") then + Freq_B <= not Freq_B; + end if; + + -- Channel C Counter + if (Counter_C /= X"000") then + Counter_C := Counter_C - 1; + elsif (Period_C /= X"000") then + Counter_C := unsigned(Period_C) - 1; + end if; + if (Counter_C = X"000") then + Freq_C <= not Freq_C; + end if; + + end if; + end if; +end process; + +-- Noise Generator +process (RESET, CLK) + variable NoiseShift : unsigned (16 downto 0); + variable Counter_N : unsigned (4 downto 0); +begin + if RESET = '1' then + Counter_N := "00000"; + NoiseShift := "00000000000000001"; + elsif rising_edge(CLK) then + if ClockDiv(2 downto 0) = "000" and ENA = '1' then + if (Counter_N /= "00000") then + Counter_N := Counter_N - 1; + elsif (Period_N /= "00000") then + Counter_N := unsigned(Period_N) - 1; + end if; + if Counter_N = "00000" then + NoiseShift := (NoiseShift(0) xor NoiseShift(2)) & NoiseShift(16 downto 1); + end if; + Freq_N <= NoiseShift(0); + end if; + end if; +end process; + +-- Envelope Generator +process (RESET , CLK) + variable EnvCounter : unsigned(15 downto 0); + variable EnvWave : unsigned(4 downto 0); +begin + if RESET = '1' then + EnvCounter := "0000000000000000"; + EnvWave := "11111"; + Volume_E <= "0000"; + Reset_Ack <= '0'; + elsif rising_edge(CLK) then + if ClockDiv = "0000" and ENA = '1' then + -- Envelope Period Counter + if (EnvCounter /= X"0000" and Reset_Req = Reset_Ack) then + EnvCounter := EnvCounter - 1; + elsif (Period_E /= X"0000") then + EnvCounter := unsigned(Period_E) - 1; + end if; + + -- Envelope Phase Counter + if (Reset_Req /= Reset_Ack) then + EnvWave := (others => '1'); + elsif (EnvCounter = X"0000" and (EnvWave(4) = '1' or (Hold = '0' and Continue = '1'))) then + EnvWave := EnvWave - 1; + end if; + + -- Envelope Amplitude Counter + for I in 3 downto 0 loop + if (EnvWave(4) = '0' and Continue = '0') then + Volume_E(I) <= '0'; + elsif (EnvWave(4) = '1' or (Alternate xor Hold) = '0') then + Volume_E(I) <= EnvWave(I) xor Attack; + else + Volume_E(I) <= EnvWave(I) xor Attack xor '1'; + end if; + end loop; + Reset_Ack <= Reset_Req; + end if; + end if; +end process; + +-- Mixer +process (RESET , CLK) +begin + if RESET = '1' then + OUT_A <= "00000000"; + OUT_B <= "00000000"; + OUT_C <= "00000000"; + elsif rising_edge(CLK) then + if ENA = '1' then + if (((Enable(0) or Freq_A) and (Enable(3) or Freq_N)) = '0') then + OUT_A <= "00000000"; + elsif (Volume_A(4) = '0') then + OUT_A <= VolumeTable(Volume_A(3 downto 0)); + else + OUT_A <= VolumeTable(Volume_E); + end if; + + if (((Enable(1) or Freq_B) and (Enable(4) or Freq_N)) = '0') then + OUT_B <= "00000000"; + elsif (Volume_B(4) = '0') then + OUT_B <= VolumeTable(Volume_B(3 downto 0)); + else + OUT_B <= VolumeTable(Volume_E); + end if; + + if (((Enable(2) or Freq_C) and (Enable(5) or Freq_N)) = '0') then + OUT_C <= "00000000"; + elsif (Volume_C(4) = '0') then + OUT_C <= VolumeTable(Volume_C(3 downto 0)); + else + OUT_C <= VolumeTable(Volume_E); + end if; + end if; + end if; +end process; + +end rtl; \ No newline at end of file diff --git a/src/sound/soundrive.vhd b/src/sound/soundrive.vhd new file mode 100644 index 0000000..456c288 --- /dev/null +++ b/src/sound/soundrive.vhd @@ -0,0 +1,62 @@ +-------------------------------------------------------------------[27.10.2011] +-- Soundrive 1.05 +------------------------------------------------------------------------------- +-- V0.1 05.10.2011 + +-- SOUNDRIVE 1.05 PORTS mode 1 +-- #0F = left channel A (stereo covox channel 1) +-- #1F = left channel B +-- #4F = right channel C (stereo covox channel 2) +-- #5F = right channel D + +-- #FB = right channel D + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity soundrive is + Port ( + RESET : in std_logic; + CLK : in std_logic; + CS : in std_logic; + A : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + WR_n : in std_logic; + IORQ_n : in std_logic; + DOS : in std_logic; + OUTA : out std_logic_vector(7 downto 0); + OUTB : out std_logic_vector(7 downto 0); + OUTC : out std_logic_vector(7 downto 0); + OUTD : out std_logic_vector(7 downto 0)); +end soundrive; + +architecture soundrive_unit of soundrive is + signal outa_reg : std_logic_vector (7 downto 0); + signal outb_reg : std_logic_vector (7 downto 0); + signal outc_reg : std_logic_vector (7 downto 0); + signal outd_reg : std_logic_vector (7 downto 0); +begin + process (CLK, RESET, CS) + begin + if RESET = '1' or CS = '0' then + outa <= (others => '0'); + outb <= (others => '0'); + outc <= (others => '0'); + outd <= (others => '0'); + elsif CLK'event and CLK = '1' then + if A = X"0F" and IORQ_n = '0' and WR_n = '0' and DOS = '0' then + outa <= DI; + elsif A = X"1F" and IORQ_n = '0' and WR_n = '0' and DOS = '0' then + outb <= DI; + elsif A = X"4F" and IORQ_n = '0' and WR_n = '0' and DOS = '0' then + outc <= DI; + elsif A = X"5F" and IORQ_n = '0' and WR_n = '0' and DOS = '0' then + outd <= DI; + elsif A = X"FB" and IORQ_n = '0' and WR_n = '0' and DOS = '0' then + outd <= DI; + end if; + end if; + end process; + +end soundrive_unit; \ No newline at end of file diff --git a/src/sound/turbosound.vhd b/src/sound/turbosound.vhd new file mode 100644 index 0000000..bb500f0 --- /dev/null +++ b/src/sound/turbosound.vhd @@ -0,0 +1,78 @@ +-------------------------------------------------------------------[07.09.2013] +-- TurboSound +------------------------------------------------------------------------------- +-- V0.1 15.10.2011 Initial version + +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +entity turbosound is +port( + RESET : in std_logic; + CLK : in std_logic; + ENA : in std_logic; + A : in std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + WR_n : in std_logic; + IORQ_n : in std_logic; + M1_n : in std_logic; + SEL : out std_logic; + CN0_DO : out std_logic_vector(7 downto 0); + CN0_A : out std_logic_vector(7 downto 0); + CN0_B : out std_logic_vector(7 downto 0); + CN0_C : out std_logic_vector(7 downto 0); + CN1_DO : out std_logic_vector(7 downto 0); + CN1_A : out std_logic_vector(7 downto 0); + CN1_B : out std_logic_vector(7 downto 0); + CN1_C : out std_logic_vector(7 downto 0)); +end turbosound; + +architecture turbosound_arch of turbosound is + signal bc1 : std_logic; + signal bdir : std_logic; + signal ssg : std_logic; +begin + bc1 <= '1' when (IORQ_n = '0' and A(15) = '1' and A(1) = '0' and M1_n = '1' and A(14) = '1') else '0'; + bdir <= '1' when (IORQ_n = '0' and A(15) = '1' and A(1) = '0' and M1_n = '1' and WR_n = '0') else '0'; + SEL <= ssg; + + process(CLK, RESET) + begin + if (RESET = '1') then + ssg <= '0'; + elsif (CLK'event and CLK = '1') then + if (DI(7 downto 1) = "1111111" and bdir = '1' and bc1 = '1') then + ssg <= DI(0); + end if; + end if; + end process; + +ssg0_unit: entity work.ay8910(rtl) + port map( + RESET => RESET, + CLK => CLK, + DI => DI, + DO => CN0_DO, + ENA => ENA, + CS => not ssg, + BDIR => bdir, + BC => bc1, + OUT_A => CN0_A, + OUT_B => CN0_B, + OUT_C => CN0_C); + +ssg1_unit: entity work.ay8910(rtl) + port map( + RESET => RESET, + CLK => CLK, + DI => DI, + DO => CN1_DO, + ENA => ENA, + CS => ssg, + BDIR => bdir, + BC => bc1, + OUT_A => CN1_A, + OUT_B => CN1_B, + OUT_C => CN1_C); +end turbosound_arch; \ No newline at end of file diff --git a/src/spi.v b/src/spi.v new file mode 100644 index 0000000..c503e86 --- /dev/null +++ b/src/spi.v @@ -0,0 +1,192 @@ +// part of NeoGS project (c) 2007-2008 NedoPC +// + +// SPI mode 0 8-bit master module +// +// short diagram for speed=0 (Fclk/Fspi=2, no rdy shown) +// +// clk: ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ (positive edges) +// counter: 00|00|00|10|11|12|13|14|15|16|17|18|19|1A|1B|1C|1D|1E|1F|00|00|00 // internal! +// sck: ___________/``\__/``\__/``\__/``\__/``\__/``\__/``\__/``\_______ +// sdo: --------< do7 | do6 | do5 | do4 | do3 | do2 | do1 | do0 >------- +// sdi: --------< di7 | di6 | di5 | di4 | di3 | di2 | di1 | di0 >------- +// bsync: ________/`````\_________________________________________________ +// start: _____/``\_______________________________________________________ +// din: ------------------------------------------------------------ +// dout: old old old old old old old old old old old old old | new new new +// +// data on sdo must be latched by slave on rising sck edge. data on sdo changes on falling edge of sck +// +// data from sdi is latched by master on positive edge of sck, while slave changes it on falling edge. +// WARNING: slave must emit valid di7 bit BEFORE first pulse on sck! +// +// bsync is 1 while do7 is outting, otherwise it is 0 +// +// start is synchronous pulse, which starts all transfer and also latches din data on the same clk edge +// as it is registered high. start can be given anytime (only when speed=0), +// so it is functioning then as synchronous reset. when speed!=0, there is global enable for majority of +// flipflops in the module, so start can't be accepted at any time +// +// dout updates with freshly received data at the clk edge in which sck goes high for the last time, thus +// latching last bit on sdi. +// +// sdo emits last bit shifted out after the transfer end +// +// when speed=0, data transfer rate could be as fast as one byte every 16 clk pulses. To achieve that, +// start must be pulsed high simultaneously with the last high pulse of sck +// +// speed[1:0] determines Fclk/Fspi +// +// speed | Fclk/Fspi +// ------+---------- +// 2'b00 | 2 +// 2'b01 | 4 +// 2'b10 | 8 +// 2'b11 | 16 +// +// for speed=0 you can start new transfer as fast as every 16 clks +// for speed=1 - every 34 clks. +// alternatively, you can check rdy output: it goes to 0 after start pulse and when it goes back to 1, you can +// issue another start at the next clk cycle. See spi2_modelled.png and .zip (modelsim project) +// +// warning: if using rdy-driven transfers and speed=0, new transfer will be started every 18 clks. +// it is recommended to use rdy-driven transfers when speed!=0 +// +// warning: this module does not contain asynchronous reset. Provided clk is stable, start=0 +// and speed=0, module returns to initial ready state after maximum of 18+8=26 clks. To reset module +// to the known state from any operational state, set speed=0 and start=1 for 8 clks +// (that starts Fclk/Fspi=2 speed transfer for sure), then remain start=0, speed=0 for at least 18 clks. + +//`include "../include/tune.v" + + +module spi( +// SPI wires + input wire clk, // system clk + output wire sck, // SPI bus pins... + output wire sdo, // + input wire sdi, // +// controls + output wire stb, // ready strobe, 1 clock length + output wire start, // start strobe, 1 clock length + // output wire rdy, // ready (idle) - when module can accept data + output reg bsync, // for vs1001 +// DMA interface + input wire dma_req, + input wire [7:0] dma_din, +// Z80 interface + input wire cpu_req, + input wire [7:0] cpu_din, + output reg [7:0] dout, +// configuration + input wire [1:0] speed, // =2'b00 - sck full speed (1/2 of clk), =2'b01 - half (1/4 of clk), =2'b10 - one fourth (1/8 of clk), =2'b11 - one eighth (1/16 of clk) + output reg [2:0] tst +); + + always @* + if (stb) + tst = 5; + else if (start) + tst = 3; + else if (dma_req) + tst = 1; + else if (cpu_req) + tst = 4; + else tst = 0; + + wire req = cpu_req || dma_req; + wire [7:0] din = dma_req ? dma_din : cpu_din; + + //initial // for simulation only! + //begin + // counter = 5'b10000; + // shiftout = 8'd0; + // shiftout = 7'd0; + // bsync = 1'd0; + // dout = 1'b0; + //end + + // sdo is high bit of shiftout + assign sdo = shiftout[7]; + wire ena_shout_load = (start || sck) & g_ena; // enable load of shiftout register + assign sck = counter[0]; + wire rdy = counter[4]; // =0 when transmission in progress + assign stb = stb_r && !rdy; + assign start = req && rdy; + + reg [6:0] shiftin; // shifting in data from sdi before emitting it on dout + reg [4:0] counter; // handles transmission + reg stb_r; + always @(posedge clk) + begin + if (g_ena) + begin + if (start) + begin + counter <= 5'b0; // rdy = 0; sck = 0; + bsync <= 1'b1; // begin bsync pulse + stb_r <= 1'b0; + end + else + begin + if (!sck) // on the rising edge of sck + begin + shiftin[6:0] <= {shiftin[5:0], sdi}; + if (&counter[3:1] && !rdy) + begin + dout <= {shiftin[6:0], sdi}; // update dout at the last sck rising edge + stb_r <= 1'b1; + end + end + else // on the falling edge of sck + begin + bsync <= 1'b0; + end + if (!rdy) + counter <= counter + 5'd1; + end + end + end + + + // shiftout treatment is done so just to save LCELLs in acex1k + reg [7:0] shiftout; // shifting out data to the sdo + always @(posedge clk) + begin + if (ena_shout_load) + begin + if (start) + shiftout <= din; + else // sck + shiftout[7:0] <= {shiftout[6:0], shiftout[0]}; // last bit remains after end of exchange + end + end + + + // slow speeds - controlled by g_ena + reg [2:0] wcnt; + always @(posedge clk) + begin + if (|speed) + begin + if (start) + wcnt <= 3'b001; + else if (rdy) + wcnt <= 3'b000; + else + wcnt <= wcnt + 3'd1; + end + else + wcnt <= 3'b000; + end + + + wire g_ena = g_en[speed]; + wire g_en[0:3]; + assign g_en[0] = 1'b1; + assign g_en[1] = ~|wcnt[0]; + assign g_en[2] = ~|wcnt[1:0]; + assign g_en[3] = ~|wcnt[2:0]; + + +endmodule diff --git a/src/t80/T80.vhd b/src/t80/T80.vhd new file mode 100644 index 0000000..3335d96 --- /dev/null +++ b/src/t80/T80.vhd @@ -0,0 +1,1139 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized 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. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software 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 AUTHOR 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. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0210 : Fixed wait and halt +-- +-- 0211 : Fixed Refresh addition and IM 1 +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson +-- +-- 0235 : Added clock enable and IM 2 fix by Mike Johnson +-- +-- 0237 : Changed 8080 I/O address output, added IntE output +-- +-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag +-- +-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode +-- +-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM +-- +-- 0247 : Fixed bus req/ack cycle +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80 is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic; + + SavePC : out std_logic_vector(15 downto 0); + SaveINT : out std_logic_vector(7 downto 0); + RestorePC : in std_logic_vector(15 downto 0); + RestoreINT : in std_logic_vector(7 downto 0); + + RestorePC_n : in std_logic + ); +end T80; + +architecture rtl of T80 is + + constant aNone : std_logic_vector(2 downto 0) := "111"; + constant aBC : std_logic_vector(2 downto 0) := "000"; + constant aDE : std_logic_vector(2 downto 0) := "001"; + constant aXY : std_logic_vector(2 downto 0) := "010"; + constant aIOA : std_logic_vector(2 downto 0) := "100"; + constant aSP : std_logic_vector(2 downto 0) := "101"; + constant aZI : std_logic_vector(2 downto 0) := "110"; + + -- Registers + signal ACC, F : std_logic_vector(7 downto 0); + signal Ap, Fp : std_logic_vector(7 downto 0); + signal I : std_logic_vector(7 downto 0); + signal R : unsigned(7 downto 0); + signal SP, PC : unsigned(15 downto 0); + signal RegDIH : std_logic_vector(7 downto 0); + signal RegDIL : std_logic_vector(7 downto 0); + signal RegBusA : std_logic_vector(15 downto 0); + signal RegBusB : std_logic_vector(15 downto 0); + signal RegBusC : std_logic_vector(15 downto 0); + signal RegAddrA_r : std_logic_vector(2 downto 0); + signal RegAddrA : std_logic_vector(2 downto 0); + signal RegAddrB_r : std_logic_vector(2 downto 0); + signal RegAddrB : std_logic_vector(2 downto 0); + signal RegAddrC : std_logic_vector(2 downto 0); + signal RegWEH : std_logic; + signal RegWEL : std_logic; + signal Alternate : std_logic; + + -- Help Registers + signal TmpAddr : std_logic_vector(15 downto 0); -- Temporary address register + signal IR : std_logic_vector(7 downto 0); -- Instruction register + signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector + signal RegBusA_r : std_logic_vector(15 downto 0); + + signal ID16 : signed(15 downto 0); + signal Save_Mux : std_logic_vector(7 downto 0); + + signal TState : unsigned(2 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal IntE_FF1 : std_logic; + signal IntE_FF2 : std_logic; + signal Halt_FF : std_logic; + signal BusReq_s : std_logic; + signal BusAck : std_logic; + signal ClkEn : std_logic; + signal NMI_s : std_logic; + signal INT_s : std_logic; + signal IStatus : std_logic_vector(1 downto 0); + + signal DI_Reg : std_logic_vector(7 downto 0); + signal T_Res : std_logic; + signal XY_State : std_logic_vector(1 downto 0); + signal Pre_XY_F_M : std_logic_vector(2 downto 0); + signal NextIs_XY_Fetch : std_logic; + signal XY_Ind : std_logic; + signal No_BTR : std_logic; + signal BTR_r : std_logic; + signal Auto_Wait : std_logic; + signal Auto_Wait_t1 : std_logic; + signal Auto_Wait_t2 : std_logic; + signal IncDecZ : std_logic; + + -- ALU signals + signal BusB : std_logic_vector(7 downto 0); + signal BusA : std_logic_vector(7 downto 0); + signal ALU_Q : std_logic_vector(7 downto 0); + signal F_Out : std_logic_vector(7 downto 0); + + -- Registered micro code outputs + signal Read_To_Reg_r : std_logic_vector(4 downto 0); + signal Arith16_r : std_logic; + signal Z16_r : std_logic; + signal ALU_Op_r : std_logic_vector(3 downto 0); + signal Save_ALU_r : std_logic; + signal PreserveC_r : std_logic; + signal MCycles : std_logic_vector(2 downto 0); + + -- Micro code outputs + signal MCycles_d : std_logic_vector(2 downto 0); + signal TStates : std_logic_vector(2 downto 0); + signal IntCycle : std_logic; + signal NMICycle : std_logic; + signal Inc_PC : std_logic; + signal Inc_WZ : std_logic; + signal IncDec_16 : std_logic_vector(3 downto 0); + signal Prefix : std_logic_vector(1 downto 0); + signal Read_To_Acc : std_logic; + signal Read_To_Reg : std_logic; + signal Set_BusB_To : std_logic_vector(3 downto 0); + signal Set_BusA_To : std_logic_vector(3 downto 0); + signal ALU_Op : std_logic_vector(3 downto 0); + signal Save_ALU : std_logic; + signal PreserveC : std_logic; + signal Arith16 : std_logic; + signal Set_Addr_To : std_logic_vector(2 downto 0); + signal Jump : std_logic; + signal JumpE : std_logic; + signal JumpXY : std_logic; + signal Call : std_logic; + signal RstP : std_logic; + signal LDZ : std_logic; + signal LDW : std_logic; + signal LDSPHL : std_logic; + signal IORQ_i : std_logic; + signal Special_LD : std_logic_vector(2 downto 0); + signal ExchangeDH : std_logic; + signal ExchangeRp : std_logic; + signal ExchangeAF : std_logic; + signal ExchangeRS : std_logic; + signal I_DJNZ : std_logic; + signal I_CPL : std_logic; + signal I_CCF : std_logic; + signal I_SCF : std_logic; + signal I_RETN : std_logic; + signal I_BT : std_logic; + signal I_BC : std_logic; + signal I_BTR : std_logic; + signal I_RLD : std_logic; + signal I_RRD : std_logic; + signal I_INRC : std_logic; + signal SetDI : std_logic; + signal SetEI : std_logic; + signal IMode : std_logic_vector(1 downto 0); + signal Halt : std_logic; + signal XYbit_undoc : std_logic; + +begin + + mcode : T80_MCode + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + IR => IR, + ISet => ISet, + MCycle => MCycle, + F => F, + NMICycle => NMICycle, + IntCycle => IntCycle, + XY_State => XY_State, + MCycles => MCycles_d, + TStates => TStates, + Prefix => Prefix, + Inc_PC => Inc_PC, + Inc_WZ => Inc_WZ, + IncDec_16 => IncDec_16, + Read_To_Acc => Read_To_Acc, + Read_To_Reg => Read_To_Reg, + Set_BusB_To => Set_BusB_To, + Set_BusA_To => Set_BusA_To, + ALU_Op => ALU_Op, + Save_ALU => Save_ALU, + PreserveC => PreserveC, + Arith16 => Arith16, + Set_Addr_To => Set_Addr_To, + IORQ => IORQ_i, + Jump => Jump, + JumpE => JumpE, + JumpXY => JumpXY, + Call => Call, + RstP => RstP, + LDZ => LDZ, + LDW => LDW, + LDSPHL => LDSPHL, + Special_LD => Special_LD, + ExchangeDH => ExchangeDH, + ExchangeRp => ExchangeRp, + ExchangeAF => ExchangeAF, + ExchangeRS => ExchangeRS, + I_DJNZ => I_DJNZ, + I_CPL => I_CPL, + I_CCF => I_CCF, + I_SCF => I_SCF, + I_RETN => I_RETN, + I_BT => I_BT, + I_BC => I_BC, + I_BTR => I_BTR, + I_RLD => I_RLD, + I_RRD => I_RRD, + I_INRC => I_INRC, + SetDI => SetDI, + SetEI => SetEI, + IMode => IMode, + Halt => Halt, + NoRead => NoRead, + Write => Write, + XYbit_undoc => XYbit_undoc); + + alu : T80_ALU + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + Arith16 => Arith16_r, + Z16 => Z16_r, + ALU_Op => ALU_Op_r, + IR => IR(5 downto 0), + ISet => ISet, + BusA => BusA, + BusB => BusB, + F_In => F, + Q => ALU_Q, + F_Out => F_Out); + + ClkEn <= CEN and not BusAck; + + T_Res <= '1' when TState = unsigned(TStates) else '0'; + + NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and + ((Set_Addr_To = aXY) or + (MCycle = "001" and IR = "11001011") or + (MCycle = "001" and IR = "00110110")) else '0'; + + Save_Mux <= BusB when ExchangeRp = '1' else + DI_Reg when Save_ALU_r = '0' else + ALU_Q; + + process (RESET_n, RestorePC_n, CLK_n) + begin + + if CLK_n'event and CLK_n = '1' then + + if RESET_n = '0' then + PC <= (others => '0'); -- Program Counter + A <= (others => '0'); + TmpAddr <= (others => '0'); + IR <= "00000000"; + ISet <= "00"; + XY_State <= "00"; + IStatus <= "00"; + MCycles <= "000"; + DO <= "00000000"; + + ACC <= (others => '1'); + F <= (others => '1'); + Ap <= (others => '1'); + Fp <= (others => '1'); + I <= (others => '0'); + R <= (others => '0'); + SP <= (others => '1'); + Alternate <= '0'; + + Read_To_Reg_r <= "00000"; + F <= (others => '1'); + Arith16_r <= '0'; + BTR_r <= '0'; + Z16_r <= '0'; + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + PreserveC_r <= '0'; + XY_Ind <= '0'; + + elsif RestorePC_n = '0' then + PC <= unsigned( RestorePC ); + A <= RestorePC; + IStatus <= RestoreInt(1 downto 0); + + elsif ClkEn = '1' then + + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + Read_To_Reg_r <= "00000"; + + MCycles <= MCycles_d; + + if IMode /= "11" then + IStatus <= IMode; + end if; + + Arith16_r <= Arith16; + PreserveC_r <= PreserveC; + if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then + Z16_r <= '1'; + else + Z16_r <= '0'; + end if; + + if MCycle = "001" and TState(2) = '0' then + -- MCycle = 1 and TState = 1, 2, or 3 + + if TState = 2 and Wait_n = '1' then + if Mode < 2 then + A(7 downto 0) <= std_logic_vector(R); + A(15 downto 8) <= I; + R(6 downto 0) <= R(6 downto 0) + 1; + end if; + + if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then + PC <= PC + 1; + end if; + + if IntCycle = '1' and IStatus = "01" then + IR <= "11111111"; + elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then + IR <= "00000000"; + else + IR <= DInst; + end if; + + ISet <= "00"; + if Prefix /= "00" then + if Prefix = "11" then + if IR(5) = '1' then + XY_State <= "10"; + else + XY_State <= "01"; + end if; + else + if Prefix = "10" then + XY_State <= "00"; + XY_Ind <= '0'; + end if; + ISet <= Prefix; + end if; + else + XY_State <= "00"; + XY_Ind <= '0'; + end if; + end if; + + else + -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) + + if MCycle = "110" then + XY_Ind <= '1'; + if Prefix = "01" then + ISet <= "01"; + end if; + end if; + + if T_Res = '1' then + BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; + if Jump = '1' then + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= TmpAddr(7 downto 0); + PC(15 downto 8) <= unsigned(DI_Reg); + PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); + elsif JumpXY = '1' then + A <= RegBusC; + PC <= unsigned(RegBusC); + elsif Call = '1' or RstP = '1' then + A <= TmpAddr; + PC <= unsigned(TmpAddr); + elsif MCycle = MCycles and NMICycle = '1' then + A <= "0000000001100110"; + PC <= "0000000001100110"; + elsif MCycle = "011" and IntCycle = '1' and IStatus = "10" then + A(15 downto 8) <= I; + A(7 downto 0) <= TmpAddr(7 downto 0); + PC(15 downto 8) <= unsigned(I); + PC(7 downto 0) <= unsigned(TmpAddr(7 downto 0)); + else + case Set_Addr_To is + when aXY => + if XY_State = "00" then + A <= RegBusC; + else + if NextIs_XY_Fetch = '1' then + A <= std_logic_vector(PC); + else + A <= TmpAddr; + end if; + end if; + when aIOA => + if Mode = 3 then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + elsif Mode = 2 then + -- Duplicate I/O address on 8080 + A(15 downto 8) <= DI_Reg; + else + A(15 downto 8) <= ACC; + end if; + A(7 downto 0) <= DI_Reg; + when aSP => + A <= std_logic_vector(SP); + when aBC => + if Mode = 3 and IORQ_i = '1' then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + A(7 downto 0) <= RegBusC(7 downto 0); + else + A <= RegBusC; + end if; + when aDE => + A <= RegBusC; + when aZI => + if Inc_WZ = '1' then + A <= std_logic_vector(unsigned(TmpAddr) + 1); + else + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= TmpAddr(7 downto 0); + end if; + when others => + A <= std_logic_vector(PC); + end case; + end if; + + Save_ALU_r <= Save_ALU; + ALU_Op_r <= ALU_Op; + + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_Y) <= not ACC(5); + F(Flag_H) <= '1'; + F(Flag_X) <= not ACC(3); + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_Y) <= ACC(5); + F(Flag_H) <= F(Flag_C); + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_Y) <= ACC(5); + F(Flag_H) <= '0'; + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + end if; + + if TState = 2 and Wait_n = '1' then + if ISet = "01" and MCycle = "111" then + IR <= DInst; + end if; + if JumpE = '1' then + PC <= unsigned(signed(PC) + signed(DI_Reg)); + elsif Inc_PC = '1' then + PC <= PC + 1; + end if; + if BTR_r = '1' then + PC <= PC - 2; + end if; + if RstP = '1' then + TmpAddr <= (others =>'0'); + TmpAddr(5 downto 3) <= IR(5 downto 3); + end if; + end if; + if TState = 3 and MCycle = "110" then + TmpAddr <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); + end if; + + if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then + if IncDec_16(2 downto 0) = "111" then + if IncDec_16(3) = '1' then + SP <= SP - 1; + else + SP <= SP + 1; + end if; + end if; + end if; + + if LDSPHL = '1' then + SP <= unsigned(RegBusC); + end if; + if ExchangeAF = '1' then + Ap <= ACC; + ACC <= Ap; + Fp <= F; + F <= Fp; + end if; + if ExchangeRS = '1' then + Alternate <= not Alternate; + end if; + end if; + + if TState = 3 then + if LDZ = '1' then + TmpAddr(7 downto 0) <= DI_Reg; + end if; + if LDW = '1' then + TmpAddr(15 downto 8) <= DI_Reg; + end if; + + if Special_LD(2) = '1' then + case Special_LD(1 downto 0) is + when "00" => + ACC <= I; + F(Flag_P) <= IntE_FF2; + F(Flag_S) <= I(7); + + if I = x"00" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + + when "01" => + ACC <= std_logic_vector(R); + F(Flag_P) <= IntE_FF2; + F(Flag_S) <= R(7); + + if R = x"00" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + + when "10" => + I <= ACC; + when others => + R <= unsigned(ACC); + end case; + end if; + end if; + + if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then + if Mode = 3 then + F(6) <= F_Out(6); + F(5) <= F_Out(5); + F(7) <= F_Out(7); + if PreserveC_r = '0' then + F(4) <= F_Out(4); + end if; + else + F(7 downto 1) <= F_Out(7 downto 1); + if PreserveC_r = '0' then + F(Flag_C) <= F_Out(0); + end if; + end if; + end if; + if T_Res = '1' and I_INRC = '1' then + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + if DI_Reg(7 downto 0) = "00000000" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + F(Flag_S) <= DI_Reg(7); + F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor + DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); + end if; + + if TState = 1 and Auto_Wait_t1 = '0' then + DO <= BusB; + if I_RLD = '1' then + DO(3 downto 0) <= BusA(3 downto 0); + DO(7 downto 4) <= BusB(3 downto 0); + end if; + if I_RRD = '1' then + DO(3 downto 0) <= BusB(7 downto 4); + DO(7 downto 4) <= BusA(3 downto 0); + end if; + end if; + + if T_Res = '1' then + Read_To_Reg_r(3 downto 0) <= Set_BusA_To; + Read_To_Reg_r(4) <= Read_To_Reg; + if Read_To_Acc = '1' then + Read_To_Reg_r(3 downto 0) <= "0111"; + Read_To_Reg_r(4) <= '1'; + end if; + end if; + + if TState = 1 and I_BT = '1' then + F(Flag_X) <= ALU_Q(3); + F(Flag_Y) <= ALU_Q(1); + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + if I_BC = '1' or I_BT = '1' then + F(Flag_P) <= IncDecZ; + end if; + + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10111" => + ACC <= Save_Mux; + when "10110" => + DO <= Save_Mux; + when "11000" => + SP(7 downto 0) <= unsigned(Save_Mux); + when "11001" => + SP(15 downto 8) <= unsigned(Save_Mux); + when "11011" => + F <= Save_Mux; + when others => + end case; + if XYbit_undoc='1' then + DO <= ALU_Q; + end if; + end if; + + end if; + + end if; + + end process; + +--------------------------------------------------------------------------- +-- +-- BC('), DE('), HL('), IX and IY +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if ClkEn = '1' then + -- Bus A / Write + RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then + RegAddrA_r <= XY_State(1) & "11"; + end if; + + -- Bus B + RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then + RegAddrB_r <= XY_State(1) & "11"; + end if; + + -- Address from register + RegAddrC <= Alternate & Set_Addr_To(1 downto 0); + -- Jump (HL), LD SP,HL + if (JumpXY = '1' or LDSPHL = '1') then + RegAddrC <= Alternate & "10"; + end if; + if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then + RegAddrC <= XY_State(1) & "11"; + end if; + + if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then + IncDecZ <= F_Out(Flag_Z); + end if; + if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then + if ID16 = 0 then + IncDecZ <= '0'; + else + IncDecZ <= '1'; + end if; + end if; + + RegBusA_r <= RegBusA; + end if; + end if; + end process; + + RegAddrA <= + -- 16 bit increment/decrement + XY_State(1) & "11" when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" and XY_State /= "00" else + Alternate & IncDec_16(1 downto 0) when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) else + -- EX HL,DL + Alternate & "10" when ExchangeDH = '1' and TState = 3 else + Alternate & "01" when ExchangeDH = '1' and TState = 4 else + -- Bus A / Write + RegAddrA_r; + + RegAddrB <= + -- EX HL,DL + Alternate & "01" when ExchangeDH = '1' and TState = 3 else + -- Bus B + RegAddrB_r; + + ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else + signed(RegBusA) + 1; + + process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + begin + RegWEH <= '0'; + RegWEL <= '0'; + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => + RegWEH <= not Read_To_Reg_r(0); + RegWEL <= Read_To_Reg_r(0); + when others => + end case; + end if; + + if ExchangeDH = '1' and (TState = 3 or TState = 4) then + RegWEH <= '1'; + RegWEL <= '1'; + end if; + + if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + case IncDec_16(1 downto 0) is + when "00" | "01" | "10" => + RegWEH <= '1'; + RegWEL <= '1'; + when others => + end case; + end if; + end process; + + process (Save_Mux, RegBusB, RegBusA_r, ID16, + ExchangeDH, IncDec_16, MCycle, TState, Wait_n) + begin + RegDIH <= Save_Mux; + RegDIL <= Save_Mux; + + if ExchangeDH = '1' and TState = 3 then + RegDIH <= RegBusB(15 downto 8); + RegDIL <= RegBusB(7 downto 0); + end if; + if ExchangeDH = '1' and TState = 4 then + RegDIH <= RegBusA_r(15 downto 8); + RegDIL <= RegBusA_r(7 downto 0); + end if; + + if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + RegDIH <= std_logic_vector(ID16(15 downto 8)); + RegDIL <= std_logic_vector(ID16(7 downto 0)); + end if; + end process; + + Regs : T80_Reg + port map( + Clk => CLK_n, + CEN => ClkEn, + WEH => RegWEH, + WEL => RegWEL, + AddrA => RegAddrA, + AddrB => RegAddrB, + AddrC => RegAddrC, + DIH => RegDIH, + DIL => RegDIL, + DOAH => RegBusA(15 downto 8), + DOAL => RegBusA(7 downto 0), + DOBH => RegBusB(15 downto 8), + DOBL => RegBusB(7 downto 0), + DOCH => RegBusC(15 downto 8), + DOCL => RegBusC(7 downto 0)); + +--------------------------------------------------------------------------- +-- +-- Buses +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if ClkEn = '1' then + case Set_BusB_To is + when "0111" => + BusB <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusB_To(0) = '1' then + BusB <= RegBusB(7 downto 0); + else + BusB <= RegBusB(15 downto 8); + end if; + when "0110" => + BusB <= DI_Reg; + when "1000" => + BusB <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusB <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusB <= "00000001"; + when "1011" => + BusB <= F; + when "1100" => + BusB <= std_logic_vector(PC(7 downto 0)); + when "1101" => + BusB <= std_logic_vector(PC(15 downto 8)); + when "1110" => + BusB <= "00000000"; + when others => + BusB <= "--------"; + end case; + + case Set_BusA_To is + when "0111" => + BusA <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusA_To(0) = '1' then + BusA <= RegBusA(7 downto 0); + else + BusA <= RegBusA(15 downto 8); + end if; + when "0110" => + BusA <= DI_Reg; + when "1000" => + BusA <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusA <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusA <= "00000000"; + when others => + BusB <= "--------"; + end case; + if XYbit_undoc='1' then + BusA <= DI_Reg; + BusB <= DI_Reg; + end if; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- +-- Generate external control signals +-- +--------------------------------------------------------------------------- + process (RESET_n,CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if RESET_n = '0' then + RFSH_n <= '1'; + + elsif CEN = '1' then + if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then + RFSH_n <= '0'; + else + RFSH_n <= '1'; + end if; + end if; + end if; + end process; + + MC <= std_logic_vector(MCycle); + TS <= std_logic_vector(TState); + DI_Reg <= DI; + HALT_n <= not Halt_FF; + BUSAK_n <= not BusAck; + IntCycle_n <= not IntCycle; + IntE <= IntE_FF1; + IORQ <= IORQ_i; + Stop <= I_DJNZ; + + SavePC <= std_logic_vector( PC ); + SaveINT <= "0000" & IntE_FF2 & IntE_FF1 & IStatus when MCycle = "001" and TState = "001" and Prefix = "00" and IntCycle = '0' and NMICycle = '0' else + "1111" & IntE_FF2 & IntE_FF1 & IStatus; + +------------------------------------------------------------------------- +-- +-- Syncronise inputs +-- +------------------------------------------------------------------------- + process (RESET_n, CLK_n) + variable OldNMI_n : std_logic; + begin + if CLK_n'event and CLK_n = '1' then + + if RESET_n = '0' then + BusReq_s <= '0'; + INT_s <= '0'; + NMI_s <= '0'; + OldNMI_n := '0'; + + elsif CEN = '1' then + BusReq_s <= not BUSRQ_n; + INT_s <= not INT_n; + if NMICycle = '1' then + NMI_s <= '0'; + elsif NMI_n = '0' and OldNMI_n = '1' then + NMI_s <= '1'; + end if; + OldNMI_n := NMI_n; + end if; + + end if; + end process; + +------------------------------------------------------------------------- +-- +-- Main state machine +-- +------------------------------------------------------------------------- + process (RESET_n, RestorePC_n, CLK_n) + begin + + if CLK_n'event and CLK_n = '1' then + if RESET_n = '0' then + MCycle <= "001"; + TState <= "000"; + Pre_XY_F_M <= "000"; + Halt_FF <= '0'; + BusAck <= '0'; + NMICycle <= '0'; + IntCycle <= '0'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + No_BTR <= '0'; + Auto_Wait_t1 <= '0'; + Auto_Wait_t2 <= '0'; + M1_n <= '1'; + + elsif RestorePC_n = '0' then + MCycle <= "001"; + TState <= "001"; + NMICycle <= '0'; + IntCycle <= '0'; + IntE_FF1 <= RestoreINT(2); + IntE_FF2 <= RestoreINT(3); + + Pre_XY_F_M <= "000"; + Halt_FF <= '0'; + BusAck <= '0'; + No_BTR <= '0'; + Auto_Wait_t1 <= '0'; + Auto_Wait_t2 <= '0'; + + elsif CEN = '1' then + if T_Res = '1' then + Auto_Wait_t1 <= '0'; + else + Auto_Wait_t1 <= Auto_Wait or IORQ_i; + end if; + Auto_Wait_t2 <= Auto_Wait_t1; + No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or + (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or + (I_BTR and (not IR(4) or F(Flag_Z))); + if TState = 2 then + if SetEI = '1' then + IntE_FF1 <= '1'; + IntE_FF2 <= '1'; + end if; + if I_RETN = '1' then + IntE_FF1 <= IntE_FF2; + end if; + end if; + if TState = 3 then + if SetDI = '1' then + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + end if; + if IntCycle = '1' or NMICycle = '1' then + Halt_FF <= '0'; + end if; + if MCycle = "001" and TState = 2 and Wait_n = '1' then + M1_n <= '1'; + end if; + if BusReq_s = '1' and BusAck = '1' then + else + BusAck <= '0'; + if TState = 2 and Wait_n = '0' then + elsif T_Res = '1' then + if Halt = '1' then + Halt_FF <= '1'; + end if; + if BusReq_s = '1' then + BusAck <= '1'; + else + TState <= "001"; + + if NextIs_XY_Fetch = '1' then + MCycle <= "110"; + Pre_XY_F_M <= MCycle; + if IR = "00110110" and Mode = 0 then + Pre_XY_F_M <= "010"; + end if; + elsif (MCycle = MCycles) or + No_BTR = '1' or + (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') or + ( MCycle = "111" and MCycles= "001" and Pre_XY_F_M = "001" ) then + M1_n <= '0'; + MCycle <= "001"; + IntCycle <= '0'; + NMICycle <= '0'; + if NMI_s = '1' and Prefix = "00" then + NMICycle <= '1'; + IntE_FF1 <= '0'; + elsif (IntE_FF1 = '1' and INT_s = '1') and Prefix = "00" and SetEI = '0' then + IntCycle <= '1'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + elsif (MCycle = "111") or + (MCycle = "110" and Mode = 1 and ISet /= "01") then + MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); + else + MCycle <= std_logic_vector(unsigned(MCycle) + 1); + end if; + end if; + else + if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor + (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then + TState <= TState + 1; + end if; + end if; + end if; + if TState = 0 then + M1_n <= '0'; + end if; + end if; + end if; + end process; + + process (IntCycle, NMICycle, MCycle) + begin + Auto_Wait <= '0'; + if IntCycle = '1' or NMICycle = '1' then + if MCycle = "001" then + Auto_Wait <= '1'; + end if; + end if; + end process; + +end; diff --git a/src/t80/T8080se.vhd b/src/t80/T8080se.vhd new file mode 100644 index 0000000..2b6d28f --- /dev/null +++ b/src/t80/T8080se.vhd @@ -0,0 +1,185 @@ +-- +-- 8080 compatible microprocessor core, synchronous top level with clock enable +-- Different timing than the original 8080 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0242 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized 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. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software 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 AUTHOR 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. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- STACK status output not supported +-- +-- File history : +-- +-- 0237 : First version +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T8080se is + generic( + Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + ); + port( + RESET_n : in std_logic; + CLK : in std_logic; + CLKEN : in std_logic; + READY : in std_logic; + HOLD : in std_logic; + INT : in std_logic; + INTE : out std_logic; + DBIN : out std_logic; + SYNC : out std_logic; + VAIT : out std_logic; + HLDA : out std_logic; + WR_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T8080se; + +architecture rtl of T8080se is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal INT_n : std_logic; + signal HALT_n : std_logic; + signal BUSRQ_n : std_logic; + signal BUSAK_n : std_logic; + signal DO_i : std_logic_vector(7 downto 0); + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + signal One : std_logic; + +begin + + INT_n <= not INT; + BUSRQ_n <= HOLD; + HLDA <= not BUSAK_n; + SYNC <= '1' when TState = "001" else '0'; + VAIT <= '1' when TState = "010" else '0'; + One <= '1'; + + DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA + DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n + DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!! + DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA + DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT + DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1 + DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP + DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR + + u0 : T80 + generic map( + Mode => Mode, + IOWait => 0) + port map( + CEN => CLKEN, + M1_n => open, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => open, + HALT_n => HALT_n, + WAIT_n => READY, + INT_n => INT_n, + NMI_n => One, + RESET_n => RESET_n, + BUSRQ_n => One, + BUSAK_n => BUSAK_n, + CLK_n => CLK, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO_i, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n, + IntE => INTE); + + process (RESET_n, CLK) + begin + if RESET_n = '0' then + DBIN <= '0'; + WR_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK'event and CLK = '1' then + if CLKEN = '1' then + DBIN <= '0'; + WR_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and READY = '0') then + DBIN <= IntCycle_n; + end if; + else + if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then + DBIN <= '1'; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + end if; + else + if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then + WR_n <= '0'; + end if; + end if; + end if; + if TState = "010" and READY = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; + +end; diff --git a/src/t80/T80_ALU.vhd b/src/t80/T80_ALU.vhd new file mode 100644 index 0000000..86fddce --- /dev/null +++ b/src/t80/T80_ALU.vhd @@ -0,0 +1,351 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized 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. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software 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 AUTHOR 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. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0238 : Fixed zero flag for 16 bit SBC and ADC +-- +-- 0240 : Added GB operations +-- +-- 0242 : Cleanup +-- +-- 0247 : Cleanup +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_ALU is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + ALU_Op : in std_logic_vector(3 downto 0); + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); +end T80_ALU; + +architecture rtl of T80_ALU is + + procedure AddSub(A : std_logic_vector; + B : std_logic_vector; + Sub : std_logic; + Carry_In : std_logic; + signal Res : out std_logic_vector; + signal Carry : out std_logic) is + variable B_i : unsigned(A'length - 1 downto 0); + variable Res_i : unsigned(A'length + 1 downto 0); + begin + if Sub = '1' then + B_i := not unsigned(B); + else + B_i := unsigned(B); + end if; + Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); + Carry <= Res_i(A'length + 1); + Res <= std_logic_vector(Res_i(A'length downto 1)); + end; + + -- AddSub variables (temporary signals) + signal UseCarry : std_logic; + signal Carry7_v : std_logic; + signal Overflow_v : std_logic; + signal HalfCarry_v : std_logic; + signal Carry_v : std_logic; + signal Q_v : std_logic_vector(7 downto 0); + + signal BitMask : std_logic_vector(7 downto 0); + +begin + + with IR(5 downto 3) select BitMask <= "00000001" when "000", + "00000010" when "001", + "00000100" when "010", + "00001000" when "011", + "00010000" when "100", + "00100000" when "101", + "01000000" when "110", + "10000000" when others; + + UseCarry <= not ALU_Op(2) and ALU_Op(0); + AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); + AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); + AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); + OverFlow_v <= Carry_v xor Carry7_v; + + process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16) + variable Q_t : std_logic_vector(7 downto 0); + variable DAA_Q : unsigned(8 downto 0); + begin + Q_t := "--------"; + F_Out <= F_In; + DAA_Q := "---------"; + case ALU_Op is + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => + F_Out(Flag_N) <= '0'; + F_Out(Flag_C) <= '0'; + case ALU_OP(2 downto 0) is + when "000" | "001" => -- ADD, ADC + Q_t := Q_v; + F_Out(Flag_C) <= Carry_v; + F_Out(Flag_H) <= HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "010" | "011" | "111" => -- SUB, SBC, CP + Q_t := Q_v; + F_Out(Flag_N) <= '1'; + F_Out(Flag_C) <= not Carry_v; + F_Out(Flag_H) <= not HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "100" => -- AND + Q_t(7 downto 0) := BusA and BusB; + F_Out(Flag_H) <= '1'; + when "101" => -- XOR + Q_t(7 downto 0) := BusA xor BusB; + F_Out(Flag_H) <= '0'; + when others => -- OR "110" + Q_t(7 downto 0) := BusA or BusB; + F_Out(Flag_H) <= '0'; + end case; + if ALU_Op(2 downto 0) = "111" then -- CP + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + else + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + end if; + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + if Z16 = '1' then + F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC + end if; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + case ALU_Op(2 downto 0) is + when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP + when others => + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + end case; + if Arith16 = '1' then + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + F_Out(Flag_P) <= F_In(Flag_P); + end if; + when "1100" => + -- DAA + F_Out(Flag_H) <= F_In(Flag_H); + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if (DAA_Q(3 downto 0) > 9) then + F_Out(Flag_H) <= '1'; + else + F_Out(Flag_H) <= '0'; + end if; + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if DAA_Q(3 downto 0) > 5 then + F_Out(Flag_H) <= '0'; + end if; + DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; + end if; + if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 352; -- 0x160 + end if; + end if; + F_Out(Flag_X) <= DAA_Q(3); + F_Out(Flag_Y) <= DAA_Q(5); + F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); + Q_t := std_logic_vector(DAA_Q(7 downto 0)); + if DAA_Q(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= DAA_Q(7); + F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor + DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); + when "1101" | "1110" => + -- RLD, RRD + Q_t(7 downto 4) := BusA(7 downto 4); + if ALU_Op(0) = '1' then + Q_t(3 downto 0) := BusB(7 downto 4); + else + Q_t(3 downto 0) := BusB(3 downto 0); + end if; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + when "1001" => + -- BIT + Q_t(7 downto 0) := BusB and BitMask; + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + F_Out(Flag_P) <= '1'; + else + F_Out(Flag_Z) <= '0'; + F_Out(Flag_P) <= '0'; + end if; + F_Out(Flag_H) <= '1'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= '0'; + F_Out(Flag_Y) <= '0'; + if IR(2 downto 0) /= "110" then + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + end if; + when "1010" => + -- SET + Q_t(7 downto 0) := BusB or BitMask; + when "1011" => + -- RES + Q_t(7 downto 0) := BusB and not BitMask; + when "1000" => + -- ROT + case IR(5 downto 3) is + when "000" => -- RLC + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := BusA(7); + F_Out(Flag_C) <= BusA(7); + when "010" => -- RL + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(7); + when "001" => -- RRC + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(0); + F_Out(Flag_C) <= BusA(0); + when "011" => -- RR + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(0); + when "100" => -- SLA + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '0'; + F_Out(Flag_C) <= BusA(7); + when "110" => -- SLL (Undocumented) / SWAP + if Mode = 3 then + Q_t(7 downto 4) := BusA(3 downto 0); + Q_t(3 downto 0) := BusA(7 downto 4); + F_Out(Flag_C) <= '0'; + else + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '1'; + F_Out(Flag_C) <= BusA(7); + end if; + when "101" => -- SRA + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(7); + F_Out(Flag_C) <= BusA(0); + when others => -- SRL + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := '0'; + F_Out(Flag_C) <= BusA(0); + end case; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + if ISet = "00" then + F_Out(Flag_P) <= F_In(Flag_P); + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + end if; + when others => + null; + end case; + Q <= Q_t; + end process; + +end; diff --git a/src/t80/T80_MCode.vhd b/src/t80/T80_MCode.vhd new file mode 100644 index 0000000..ab5aaf6 --- /dev/null +++ b/src/t80/T80_MCode.vhd @@ -0,0 +1,2048 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized 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. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software 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 AUTHOR 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. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0211 : Fixed IM 1 +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- +-- 0235 : Added IM 2 fix by Mike Johnson +-- +-- 0238 : Added NoRead signal +-- +-- 0238b: Fixed instruction timing for POP and DJNZ +-- +-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes +-- +-- 0242 : Fixed I/O instruction timing, cleanup +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_MCode is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + XY_State : in std_logic_vector(1 downto 0); + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,CB,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + XYbit_undoc : out std_logic + ); +end T80_MCode; + +architecture rtl of T80_MCode is + + constant aNone : std_logic_vector(2 downto 0) := "111"; + constant aBC : std_logic_vector(2 downto 0) := "000"; + constant aDE : std_logic_vector(2 downto 0) := "001"; + constant aXY : std_logic_vector(2 downto 0) := "010"; + constant aIOA : std_logic_vector(2 downto 0) := "100"; + constant aSP : std_logic_vector(2 downto 0) := "101"; + constant aZI : std_logic_vector(2 downto 0) := "110"; +-- constant aNone : std_logic_vector(2 downto 0) := "000"; +-- constant aXY : std_logic_vector(2 downto 0) := "001"; +-- constant aIOA : std_logic_vector(2 downto 0) := "010"; +-- constant aSP : std_logic_vector(2 downto 0) := "011"; +-- constant aBC : std_logic_vector(2 downto 0) := "100"; +-- constant aDE : std_logic_vector(2 downto 0) := "101"; +-- constant aZI : std_logic_vector(2 downto 0) := "110"; + + function is_cc_true( + F : std_logic_vector(7 downto 0); + cc : bit_vector(2 downto 0) + ) return boolean is + begin + if Mode = 3 then + case cc is + when "000" => return F(7) = '0'; -- NZ + when "001" => return F(7) = '1'; -- Z + when "010" => return F(4) = '0'; -- NC + when "011" => return F(4) = '1'; -- C + when "100" => return false; + when "101" => return false; + when "110" => return false; + when "111" => return false; + end case; + else + case cc is + when "000" => return F(6) = '0'; -- NZ + when "001" => return F(6) = '1'; -- Z + when "010" => return F(0) = '0'; -- NC + when "011" => return F(0) = '1'; -- C + when "100" => return F(2) = '0'; -- PO + when "101" => return F(2) = '1'; -- PE + when "110" => return F(7) = '0'; -- P + when "111" => return F(7) = '1'; -- M + end case; + end if; + end; + +begin + + process (IR, ISet, MCycle, F, NMICycle, IntCycle) + variable DDD : std_logic_vector(2 downto 0); + variable SSS : std_logic_vector(2 downto 0); + variable DPair : std_logic_vector(1 downto 0); + variable IRB : bit_vector(7 downto 0); + begin + DDD := IR(5 downto 3); + SSS := IR(2 downto 0); + DPair := IR(5 downto 4); + IRB := to_bitvector(IR); + + MCycles <= "001"; + if MCycle = "001" then + TStates <= "100"; + else + TStates <= "011"; + end if; + Prefix <= "00"; + Inc_PC <= '0'; + Inc_WZ <= '0'; + IncDec_16 <= "0000"; + Read_To_Acc <= '0'; + Read_To_Reg <= '0'; + Set_BusB_To <= "0000"; + Set_BusA_To <= "0000"; + ALU_Op <= "0" & IR(5 downto 3); + Save_ALU <= '0'; + PreserveC <= '0'; + Arith16 <= '0'; + IORQ <= '0'; + Set_Addr_To <= aNone; + Jump <= '0'; + JumpE <= '0'; + JumpXY <= '0'; + Call <= '0'; + RstP <= '0'; + LDZ <= '0'; + LDW <= '0'; + LDSPHL <= '0'; + Special_LD <= "000"; + ExchangeDH <= '0'; + ExchangeRp <= '0'; + ExchangeAF <= '0'; + ExchangeRS <= '0'; + I_DJNZ <= '0'; + I_CPL <= '0'; + I_CCF <= '0'; + I_SCF <= '0'; + I_RETN <= '0'; + I_BT <= '0'; + I_BC <= '0'; + I_BTR <= '0'; + I_RLD <= '0'; + I_RRD <= '0'; + I_INRC <= '0'; + SetDI <= '0'; + SetEI <= '0'; + IMode <= "11"; + Halt <= '0'; + NoRead <= '0'; + Write <= '0'; + XYbit_undoc <= '0'; + + case ISet is + when "00" => + +------------------------------------------------------------------------------ +-- +-- Unprefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is +-- 8 BIT LOAD GROUP + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- LD r,r' + Set_BusB_To(2 downto 0) <= SSS; + ExchangeRp <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => + -- LD r,n + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => + -- LD r,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => + -- LD (HL),r + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110110" => + -- LD (HL),n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00001010" => + -- LD A,(BC) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00011010" => + -- LD A,(DE) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00111010" => + if Mode = 3 then + -- LDD A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end if; + when "00000010" => + -- LD (BC),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00010010" => + -- LD (DE),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110010" => + if Mode = 3 then + -- LDD (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + end if; + +-- 16 BIT LOAD GROUP + when "00000001"|"00010001"|"00100001"|"00110001" => + -- LD dd,nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1000"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1001"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "00101010" => + if Mode = 3 then + -- LDI A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD HL,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Set_BusA_To(2 downto 0) <= "101"; -- L + Read_To_Reg <= '1'; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Set_BusA_To(2 downto 0) <= "100"; -- H + Read_To_Reg <= '1'; + when others => null; + end case; + end if; + when "00100010" => + if Mode = 3 then + -- LDI (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD (nn),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "0101"; -- L + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "0100"; -- H + when 5 => + Write <= '1'; + when others => null; + end case; + end if; + when "11111001" => + -- LD SP,HL + TStates <= "110"; + LDSPHL <= '1'; + when "11000101"|"11010101"|"11100101"|"11110101" => + -- PUSH qq + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 2 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 3 => + Write <= '1'; + when others => null; + end case; + when "11000001"|"11010001"|"11100001"|"11110001" => + -- POP qq + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1011"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + IncDec_16 <= "0111"; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "0111"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + +-- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP + when "11101011" => + if Mode /= 3 then + -- EX DE,HL + ExchangeDH <= '1'; + end if; + when "00001000" => + if Mode = 3 then + -- LD (nn),SP + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "1000"; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "1001"; + when 5 => + Write <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EX AF,AF' + ExchangeAF <= '1'; + end if; + when "11011001" => + if Mode = 3 then + -- RETI + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + I_RETN <= '1'; + SetEI <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EXX + ExchangeRS <= '1'; + end if; + when "11100011" => + if Mode /= 3 then + -- EX (SP),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + Read_To_Reg <= '1'; + Set_BusA_To <= "0101"; + Set_BusB_To <= "0101"; + Set_Addr_To <= aSP; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + TStates <= "100"; + Write <= '1'; + when 4 => + Read_To_Reg <= '1'; + Set_BusA_To <= "0100"; + Set_BusB_To <= "0100"; + Set_Addr_To <= aSP; + when 5 => + IncDec_16 <= "1111"; + TStates <= "101"; + Write <= '1'; + when others => null; + end case; + end if; + +-- 8 BIT ARITHMETIC AND LOGICAL GROUP + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- ADD A,r + -- ADC A,r + -- SUB A,r + -- SBC A,r + -- AND A,r + -- OR A,r + -- XOR A,r + -- CP A,r + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- ADD A,(HL) + -- ADC A,(HL) + -- SUB A,(HL) + -- SBC A,(HL) + -- AND A,(HL) + -- OR A,(HL) + -- XOR A,(HL) + -- CP A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + when others => null; + end case; + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- ADD A,n + -- ADC A,n + -- SUB A,n + -- SBC A,n + -- AND A,n + -- OR A,n + -- XOR A,n + -- CP A,n + MCycles <= "010"; + if MCycle = "010" then + Inc_PC <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + end if; + when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => + -- INC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + when "00110100" => + -- INC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => + -- DEC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0010"; + when "00110101" => + -- DEC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + ALU_Op <= "0010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + +-- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS + when "00100111" => + -- DAA + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + ALU_Op <= "1100"; + Save_ALU <= '1'; + when "00101111" => + -- CPL + I_CPL <= '1'; + when "00111111" => + -- CCF + I_CCF <= '1'; + when "00110111" => + -- SCF + I_SCF <= '1'; + when "00000000" => + if NMICycle = '1' then + -- NMI + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + TStates <= "100"; + Write <= '1'; + when others => null; + end case; + elsif IntCycle = '1' then + -- INT (IM 2) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + LDZ <= '1'; + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + --TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + --TStates <= "100"; + Write <= '1'; + when 4 => + Inc_PC <= '1'; + LDZ <= '1'; + when 5 => + Jump <= '1'; + when others => null; + end case; + else + -- NOP + end if; + when "01110110" => + -- HALT + Halt <= '1'; + when "11110011" => + -- DI + SetDI <= '1'; + when "11111011" => + -- EI + SetEI <= '1'; + +-- 16 BIT ARITHMETIC GROUP + when "00001001"|"00011001"|"00101001"|"00111001" => + -- ADD HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; + when others => + end case; + when "00000011"|"00010011"|"00100011"|"00110011" => + -- INC ss + TStates <= "110"; + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + when "00001011"|"00011011"|"00101011"|"00111011" => + -- DEC ss + TStates <= "110"; + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + +-- ROTATE AND SHIFT GROUP + when "00000111" + -- RLCA + |"00010111" + -- RLA + |"00001111" + -- RRCA + |"00011111" => + -- RRA + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + +-- JUMP GROUP + when "11000011" => + -- JP nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + Jump <= '1'; + when others => null; + end case; + when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+C),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IORQ <= '1'; + when others => + end case; + when "01" => + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + when "10" => + -- LD A,($FF00+C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + Read_To_Acc <= '1'; + IORQ <= '1'; + when others => + end case; + when "11" => + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end case; + else + -- JP cc,nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Jump <= '1'; + end if; + when others => null; + end case; + end if; + when "00011000" => + if Mode /= 2 then + -- JR e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00111000" => + if Mode /= 2 then + -- JR C,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '0' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00110000" => + if Mode /= 2 then + -- JR NC,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '1' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00101000" => + if Mode /= 2 then + -- JR Z,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '0' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00100000" => + if Mode /= 2 then + -- JR NZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '1' then + MCycles <= "010"; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "11101001" => + -- JP (HL) + JumpXY <= '1'; + when "00010000" => + if Mode = 3 then + I_DJNZ <= '1'; + elsif Mode < 2 then + -- DJNZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + I_DJNZ <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= "000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + I_DJNZ <= '1'; + Inc_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + +-- CALL AND RETURN GROUP + when "11001101" => + -- CALL nn + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + IncDec_16 <= "1111"; + Inc_PC <= '1'; + TStates <= "100"; + Set_Addr_To <= aSP; + LDW <= '1'; + Set_BusB_To <= "1101"; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => + if IR(5) = '0' or Mode /= 3 then + -- CALL cc,nn + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + LDW <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + TStates <= "100"; + Set_BusB_To <= "1101"; + else + MCycles <= "011"; + end if; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + end if; + when "11001001" => + -- RET + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + --TStates <= "101"; + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+nn),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + when others => null; + end case; + when "01" => + -- ADD SP,n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + ALU_Op <= "0000"; + Inc_PC <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To <= "1000"; + Set_BusB_To <= "0110"; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To <= "1001"; + Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!! + when others => + end case; + when "10" => + -- LD A,($FF00+nn) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "11" => + -- LD HL,SP+n -- Not correct !!!!!!!!!!!!!!!!!!! + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Set_BusA_To(2 downto 0) <= "101"; -- L + Read_To_Reg <= '1'; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Set_BusA_To(2 downto 0) <= "100"; -- H + Read_To_Reg <= '1'; + when others => null; + end case; + end case; + else + -- RET cc + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "001"; + end if; + TStates <= "101"; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; + when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => + -- RST p + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + +-- INPUT AND OUTPUT GROUP + when "11011011" => + if Mode /= 3 then + -- IN A,(n) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + when "11010011" => + if Mode /= 3 then + -- OUT (n),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- MULTIBYTE INSTRUCTIONS +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + + when "11001011" => + if Mode /= 2 then + Prefix <= "01"; + end if; + + when "11101101" => + if Mode < 2 then + Prefix <= "10"; + end if; + + when "11011101"|"11111101" => + if Mode < 2 then + Prefix <= "11"; + end if; + + end case; + + when "01" => + +------------------------------------------------------------------------------ +-- +-- CB prefixed instructions +-- +------------------------------------------------------------------------------ + + Set_BusA_To(2 downto 0) <= IR(2 downto 0); + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => + -- RLC r + -- RL r + -- RRC r + -- RR r + -- SLA r + -- SRA r + -- SRL r + -- SLL r (Undocumented) / SWAP r + if XY_State="00" then + if MCycle = "001" or MCycle = "111" then + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + else + -- R/S (IX+d),Reg, undocumented + MCycles <= "011"; + XYbit_undoc <= '1'; + case to_integer(unsigned(MCycle)) is + when 1 | 7=> + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + end if; + + when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => + -- RLC (HL) + -- RL (HL) + -- RRC (HL) + -- RR (HL) + -- SRA (HL) + -- SRL (HL) + -- SLA (HL) + -- SLL (HL) (Undocumented) / SWAP (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- BIT b,r + if XY_State="00" then + if MCycle = "001" or MCycle = "111" then + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + ALU_Op <= "1001"; + end if; + else + -- BIT b,(IX+d), undocumented + MCycles <= "010"; + XYbit_undoc <= '1'; + case to_integer(unsigned(MCycle)) is + when 1 | 7=> + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1001"; + TStates <= "100"; + when others => null; + end case; + end if; + + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => + -- BIT b,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1001"; + TStates <= "100"; + when others => null; + end case; + when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" + |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" + |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" + |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" + |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => + -- SET b,r + if XY_State="00" then + if MCycle = "001" then + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + else + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 7 => + Set_Addr_To <= aXY; + when 2 => + Set_BusB_To(2 downto 0) <= "110"; + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Set_Addr_To <= aXY; + when 4 => + Write <= '1'; + when others => null; + end case; + end if; + else + -- SET b,(IX+d),Reg, undocumented + MCycles <= "011"; + XYbit_undoc <= '1'; + case to_integer(unsigned(MCycle)) is + when 1 | 7=> + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + end if; + + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- SET b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- RES b,r + if XY_State="00" then + if MCycle = "001" then + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + else + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 7 => + Set_Addr_To <= aXY; + when 2 => + Set_BusB_To(2 downto 0) <= "110"; + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Set_Addr_To <= aXY; + when 4 => + Write <= '1'; + when others => null; + end case; + end if; + else + -- RES b,(IX+d),Reg, undocumented + MCycles <= "011"; + XYbit_undoc <= '1'; + case to_integer(unsigned(MCycle)) is + when 1 | 7=> + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + end if; + + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- RES b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + end case; + + when others => + +------------------------------------------------------------------------------ +-- +-- ED prefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" + + + |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" + | "10100100"|"10100101"|"10100110"|"10100111" + | "10101100"|"10101101"|"10101110"|"10101111" + | "10110100"|"10110101"|"10110110"|"10110111" + | "10111100"|"10111101"|"10111110"|"10111111" + |"11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111" + |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" + |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" + |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" + |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => + null; -- NOP, undocumented + when "01111110"|"01111111" => + -- NOP, undocumented + null; +-- 8 BIT LOAD GROUP + when "01010111" => + -- LD A,I + Special_LD <= "100"; + TStates <= "101"; + when "01011111" => + -- LD A,R + Special_LD <= "101"; + TStates <= "101"; + when "01000111" => + -- LD I,A + Special_LD <= "110"; + TStates <= "101"; + when "01001111" => + -- LD R,A + Special_LD <= "111"; + TStates <= "101"; +-- 16 BIT LOAD GROUP + when "01001011"|"01011011"|"01101011"|"01111011" => + -- LD dd,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1000"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '1'; + end if; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1001"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "01000011"|"01010011"|"01100011"|"01110011" => + -- LD (nn),dd + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1000"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1001"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 5 => + Write <= '1'; + when others => null; + end case; + when "10100000" | "10101000" | "10110000" | "10111000" => + -- LDI, LDD, LDIR, LDDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0000"; + Set_Addr_To <= aDE; + if IR(3) = '0' then + IncDec_16 <= "0110"; -- IX + else + IncDec_16 <= "1110"; + end if; + when 3 => + I_BT <= '1'; + TStates <= "101"; + Write <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0101"; -- DE + else + IncDec_16 <= "1101"; + end if; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100001" | "10101001" | "10110001" | "10111001" => + -- CPI, CPD, CPIR, CPDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0111"; + Save_ALU <= '1'; + PreserveC <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + when 3 => + NoRead <= '1'; + I_BC <= '1'; + TStates <= "101"; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => + -- NEG + Alu_OP <= "0010"; + Set_BusB_To <= "0111"; + Set_BusA_To <= "1010"; + Read_To_Acc <= '1'; + Save_ALU <= '1'; + when "01000110"|"01001110"|"01100110"|"01101110" => + -- IM 0 + IMode <= "00"; + when "01010110"|"01110110" => + -- IM 1 + IMode <= "01"; + when "01011110"|"01110111" => + -- IM 2 + IMode <= "10"; +-- 16 bit arithmetic + when "01001010"|"01011010"|"01101010"|"01111010" => + -- ADC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0001"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01000010"|"01010010"|"01100010"|"01110010" => + -- SBC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + when 3 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01101111" => + -- RLD + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + NoRead <= '1'; + Set_Addr_To <= aXY; + when 3 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1101"; + TStates <= "100"; + Set_Addr_To <= aXY; + Save_ALU <= '1'; + when 4 => + I_RLD <= '1'; + Write <= '1'; + when others => + end case; + when "01100111" => + -- RRD + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Set_Addr_To <= aXY; + when 3 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1110"; + TStates <= "100"; + Set_Addr_To <= aXY; + Save_ALU <= '1'; + when 4 => + I_RRD <= '1'; + Write <= '1'; + when others => + end case; + when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => + -- RETI, RETN + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + I_RETN <= '1'; + when others => null; + end case; + when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => + -- IN r,(C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + IORQ <= '1'; + if IR(5 downto 3) /= "110" then + Read_To_Reg <= '1'; + Set_BusA_To(2 downto 0) <= IR(5 downto 3); + end if; + I_INRC <= '1'; + when others => + end case; + when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => + -- OUT (C),r + -- OUT (C),0 + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To(2 downto 0) <= IR(5 downto 3); + if IR(5 downto 3) = "110" then + Set_BusB_To(3) <= '1'; + end if; + when 2 => + Write <= '1'; + IORQ <= '1'; + when others => + end case; + when "10100010" | "10101010" | "10110010" | "10111010" => + -- INI, IND, INIR, INDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + IORQ <= '1'; + Set_BusB_To <= "0110"; + Set_Addr_To <= aXY; + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + TStates <= "100"; + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100011" | "10101011" | "10110011" | "10111011" => + -- OUTI, OUTD, OTIR, OTDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + Set_Addr_To <= aXY; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + Set_BusB_To <= "0110"; + Set_Addr_To <= aBC; + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + IORQ <= '1'; + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + end case; + + end case; + + if Mode = 1 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "011"; + end if; + end if; + + if Mode = 3 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "100"; + end if; + end if; + + if Mode < 2 then + if MCycle = "110" then + Inc_PC <= '1'; + if Mode = 1 then + Set_Addr_To <= aXY; + TStates <= "100"; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + end if; + if IRB = "00110110" or IRB = "11001011" then + Set_Addr_To <= aNone; + end if; + end if; + if MCycle = "111" then + if Mode = 0 then + TStates <= "101"; + end if; + if ISet /= "01" then + Set_Addr_To <= aXY; + end if; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + if IRB = "00110110" or ISet = "01" then + -- LD (HL),n + Inc_PC <= '1'; + else + NoRead <= '1'; + end if; + end if; + end if; + + end process; + +end; diff --git a/src/t80/T80_Pack.vhd b/src/t80/T80_Pack.vhd new file mode 100644 index 0000000..ca18e3a --- /dev/null +++ b/src/t80/T80_Pack.vhd @@ -0,0 +1,217 @@ +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized 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. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software 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 AUTHOR 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. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +package T80_Pack is + + component T80 + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic; + + SavePC : out std_logic_vector(15 downto 0); + SaveINT : out std_logic_vector(7 downto 0); + RestorePC : in std_logic_vector(15 downto 0); + RestoreINT : in std_logic_vector(7 downto 0); + + RestorePC_n : in std_logic + ); + end component; + + component T80_Reg + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0) + ); + end component; + + component T80_MCode + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + XY_State : in std_logic_vector(1 downto 0); + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + XYbit_undoc : out std_logic + ); + end component; + + component T80_ALU + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + ALU_Op : in std_logic_vector(3 downto 0); + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); + end component; + +end; diff --git a/src/t80/T80_Reg.vhd b/src/t80/T80_Reg.vhd new file mode 100644 index 0000000..828485f --- /dev/null +++ b/src/t80/T80_Reg.vhd @@ -0,0 +1,105 @@ +-- +-- T80 Registers, technology independent +-- +-- Version : 0244 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized 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. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software 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 AUTHOR 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. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0242 : Initial release +-- +-- 0244 : Changed to single register file +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_Reg is + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0) + ); +end T80_Reg; + +architecture rtl of T80_Reg is + + type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); + signal RegsH : Register_Image(0 to 7); + signal RegsL : Register_Image(0 to 7); + +begin + + process (Clk) + begin + if Clk'event and Clk = '1' then + if CEN = '1' then + if WEH = '1' then + RegsH(to_integer(unsigned(AddrA))) <= DIH; + end if; + if WEL = '1' then + RegsL(to_integer(unsigned(AddrA))) <= DIL; + end if; + end if; + end if; + end process; + + DOAH <= RegsH(to_integer(unsigned(AddrA))); + DOAL <= RegsL(to_integer(unsigned(AddrA))); + DOBH <= RegsH(to_integer(unsigned(AddrB))); + DOBL <= RegsL(to_integer(unsigned(AddrB))); + DOCH <= RegsH(to_integer(unsigned(AddrC))); + DOCL <= RegsL(to_integer(unsigned(AddrC))); + +end; diff --git a/src/t80/T80a.vhd b/src/t80/T80a.vhd new file mode 100644 index 0000000..414e590 --- /dev/null +++ b/src/t80/T80a.vhd @@ -0,0 +1,268 @@ +-- +-- Z80 compatible microprocessor core, asynchronous top level +-- +-- Version : 0247 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized 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. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software 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 AUTHOR 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. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0211 : Fixed interrupt cycle +-- +-- 0235 : Updated for T80 interface change +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- +-- 0247 : Fixed bus req/ack cycle +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80a is + generic( + Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + D : inout std_logic_vector(7 downto 0); + + SavePC : out std_logic_vector(15 downto 0); + SaveINT : out std_logic_vector(7 downto 0); + RestorePC : in std_logic_vector(15 downto 0); + RestoreINT : in std_logic_vector(7 downto 0); + + RestorePC_n : in std_logic + + ); +end T80a; + +architecture rtl of T80a is + + signal CEN : std_logic; + signal Reset_s : std_logic; + signal IntCycle_n : std_logic; + signal IORQ : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal MREQ : std_logic; + signal MReq_Inhibit : std_logic; + signal Req_Inhibit : std_logic; + signal RD : std_logic; + signal MREQ_n_i : std_logic; + signal IORQ_n_i : std_logic; + signal RD_n_i : std_logic; + signal WR_n_i : std_logic; + signal RFSH_n_i : std_logic; + signal BUSAK_n_i : std_logic; + signal A_i : std_logic_vector(15 downto 0); + signal DO : std_logic_vector(7 downto 0); + signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser + signal Wait_s : std_logic; + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + CEN <= '1'; + + BUSAK_n <= BUSAK_n_i; + MREQ_n_i <= not MREQ or (Req_Inhibit and MReq_Inhibit); + RD_n_i <= not RD or Req_Inhibit; + + MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; + IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z'; + RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z'; + WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z'; + RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z'; + A <= A_i when BUSAK_n_i = '1' else (others => 'Z'); + D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + Reset_s <= '0'; + elsif CLK_n'event and CLK_n = '1' then + Reset_s <= '1'; + end if; + end process; + + u0 : T80 + generic map( + Mode => Mode, + IOWait => 1) + port map( + CEN => CEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n_i, + HALT_n => HALT_n, + WAIT_n => Wait_s, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => Reset_s, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n_i, + CLK_n => CLK_n, + A => A_i, + DInst => D, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n, + + SavePC => SavePC, + SaveINT => SaveINT, + RestorePC => RestorePC, + RestoreINT => RestoreINT, + + RestorePC_n => RestorePC_n ); + + process (CLK_n) + begin + if CLK_n'event and CLK_n = '0' then + Wait_s <= WAIT_n; + if TState = "011" and BUSAK_n_i = '1' then + DI_Reg <= to_x01(D); + end if; + end if; + end process; + + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + WR_n_i <= '1'; + elsif CLK_n'event and CLK_n = '1' then + WR_n_i <= '1'; + if TState = "001" then -- To short for IO writes !!!!!!!!!!!!!!!!!!! + WR_n_i <= not Write; + end if; + end if; + end process; + + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + Req_Inhibit <= '0'; + elsif CLK_n'event and CLK_n = '1' then + if MCycle = "001" and TState = "010" then + Req_Inhibit <= '1'; + else + Req_Inhibit <= '0'; + end if; + end if; + end process; + + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + MReq_Inhibit <= '0'; + elsif CLK_n'event and CLK_n = '0' then + if MCycle = "001" and TState = "010" then + MReq_Inhibit <= '1'; + else + MReq_Inhibit <= '0'; + end if; + end if; + end process; + + process(Reset_s,CLK_n) + begin + if Reset_s = '0' then + RD <= '0'; + IORQ_n_i <= '1'; + MREQ <= '0'; + elsif CLK_n'event and CLK_n = '0' then + + if MCycle = "001" then + if TState = "001" then + RD <= IntCycle_n; + MREQ <= IntCycle_n; + IORQ_n_i <= IntCycle_n; + end if; + if TState = "011" then + RD <= '0'; + IORQ_n_i <= '1'; + MREQ <= '1'; + end if; + if TState = "100" then + MREQ <= '0'; + end if; + else + if TState = "001" and NoRead = '0' then + RD <= not Write; + IORQ_n_i <= not IORQ; + MREQ <= not IORQ; + end if; + if TState = "011" then + RD <= '0'; + IORQ_n_i <= '1'; + MREQ <= '0'; + end if; + end if; + end if; + end process; + +end; diff --git a/src/t80/T80s.vhd b/src/t80/T80s.vhd new file mode 100644 index 0000000..df6bd14 --- /dev/null +++ b/src/t80/T80s.vhd @@ -0,0 +1,204 @@ +-- +-- Z80 compatible microprocessor core, synchronous top level +-- Different timing than the original z80 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized 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. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software 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 AUTHOR 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. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0210 : Fixed read with wait +-- +-- 0211 : Fixed interrupt cycle +-- +-- 0235 : Updated for T80 interface change +-- +-- 0236 : Added T2Write generic +-- +-- 0237 : Fixed T2Write with wait state +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80s is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + + SavePC : out std_logic_vector(15 downto 0); + SaveINT : out std_logic_vector(7 downto 0); + RestorePC : in std_logic_vector(15 downto 0); + RestoreINT : in std_logic_vector(7 downto 0); + + RestorePC_n : in std_logic + ); +end T80s; + +architecture rtl of T80s is + + signal CEN : std_logic; + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + CEN <= '1'; + + u0 : T80 + generic map( + Mode => Mode, + IOWait => IOWait) + port map( + CEN => CEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + WAIT_n => Wait_n, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK_n, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n, + + SavePC => SavePC, + SaveINT => SaveINT, + RestorePC => RestorePC, + RestoreINT => RestoreINT, + + RestorePC_n => RestorePC_n ); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK_n'event and CLK_n = '1' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and Wait_n = '0') then + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + IORQ_n <= IntCycle_n; + end if; + if TState = "011" then + MREQ_n <= '0'; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then + RD_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + end if; + end if; + if TState = "010" and Wait_n = '1' then + DI_Reg <= DI; + end if; + end if; + end process; + +end; diff --git a/src/t80/T80se.vhd b/src/t80/T80se.vhd new file mode 100644 index 0000000..c47a56e --- /dev/null +++ b/src/t80/T80se.vhd @@ -0,0 +1,200 @@ +-- +-- Z80 compatible microprocessor core, synchronous top level with clock enable +-- Different timing than the original z80 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized 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. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software 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 AUTHOR 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. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0235 : First release +-- +-- 0236 : Added T2Write generic +-- +-- 0237 : Fixed T2Write with wait state +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80se is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CLKEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + + SavePC : out std_logic_vector(15 downto 0); + SaveINT : out std_logic_vector(7 downto 0); + RestorePC : in std_logic_vector(15 downto 0); + RestoreINT : in std_logic_vector(7 downto 0); + + RestorePC_n : in std_logic + ); +end T80se; + +architecture rtl of T80se is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + u0 : T80 + generic map( + Mode => Mode, + IOWait => IOWait) + port map( + CEN => CLKEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + WAIT_n => Wait_n, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK_n, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n, + + SavePC => SavePC, + SaveINT => SaveINT, + RestorePC => RestorePC, + RestoreINT => RestoreINT, + + RestorePC_n => RestorePC_n ); + + + process (CLK_n) + begin + if CLK_n'event and CLK_n = '1' then + if RESET_n = '0' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + elsif CLKEN = '1' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + if MCycle = "001" then + if TState = "001" or TState = "010" then + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + IORQ_n <= IntCycle_n; + end if; + if TState = "011" then + MREQ_n <= '0'; + end if; + else + if (TState = "001" or TState = "010") and NoRead = '0' and Write = '0' then + RD_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + else + if (TState = "001" or TState = "010") and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + end if; + end if; + if TState = "010" and Wait_n = '1' then + DI_Reg <= DI; + end if; + + end if; + end if; + end process; + +end; diff --git a/src/tsconf.vhd b/src/tsconf.vhd new file mode 100644 index 0000000..265e758 --- /dev/null +++ b/src/tsconf.vhd @@ -0,0 +1,1475 @@ +-------------------------------------------------------------------[02.11.2014] +-- u16-TSConf Version 0.2.9 +-- DEVBOARD ReVerSE-U16 By MVV +------------------------------------------------------------------------------- +-- V0.1.0 27.07.2014 первая версия +-- V0.2.0 31.07.2014 добавлен транслятор PS/2, HDMI +-- V0.2.1 03.08.2014 добавлен Delta-Sigma DAC, I2C +-- V0.2.3 11.08.2014 добавлен enc424j600 +-- V0.2.4 24.08.2014 добавлена поддержка IDE Video DAC (zports.v, video_out.v) +-- V0.2.5 07.09.2014 добавлен порт #0001=key_scan, изменения в keyboard.vhd +-- V0.2.6 09.09.2014 исправлен вывод палитры в (lut.vhd) +-- V0.2.7 13.09.2014 дрожание мультиколора на tv80s, заменил на t80s +-- V0.2.8 19.10.2014 инвентирован CLK в модулях video_tmbuf, video_sfile и добавлены регистры на выходе +-- V0.2.9 02.11.2014 замена t80s, исправления в zint.v, zports.v, delta-sigma (приводит к намагничиванию динамиков) +-- WXEDA 10.03.2015 порт на девборду WXEDA + +-- http://tslabs.info/forum/viewtopic.php?f=31&t=401 +-- http://zx-pk.ru/showthread.php?t=23528 + +-- Copyright (c) 2014 MVV, TS-Labs, dsp, waybester, palsw +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- * Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- * Redistributions in synthesized 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. +-- +-- * Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written agreement from the author. +-- +-- * License is granted for non-commercial use only. A fee may not be charged +-- for redistributions as source code or in synthesized/hardware form without +-- specific prior written agreement from the author. +-- +-- 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 AUTHOR 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. + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_unsigned.all; +use IEEE.numeric_std.all; + + +entity tsconf is +port +( + -- Clock (24MHz) + clk_84mhz : in std_logic; + clk_28mhz : in std_logic; + + -- SDRAM (32MB 16x16bit) + SDRAM_DQ : inout std_logic_vector(15 downto 0); + SDRAM_A : out std_logic_vector(12 downto 0); + SDRAM_BA : out std_logic_vector(1 downto 0); + SDRAM_CLK : out std_logic; + SDRAM_DQML : out std_logic; + SDRAM_DQMH : out std_logic; + SDRAM_WE_N : out std_logic; + SDRAM_CAS_N : out std_logic; + SDRAM_RAS_N : out std_logic; + SDRAM_CKE : out std_logic; + SDRAM_CS_N : out std_logic; + + -- VGA + VGA_R : out std_logic_vector(7 downto 0); + VGA_G : out std_logic_vector(7 downto 0); + VGA_B : out std_logic_vector(7 downto 0); + VGA_HS : out std_logic; + VGA_VS : out std_logic; + VGA_HBLANK : out std_logic; + VGA_VBLANK : out std_logic; + VGA_CEPIX : out std_logic; + + -- SD/MMC Memory Card + SD_SO : in std_logic; + SD_SI : out std_logic; + SD_CLK : out std_logic; + SD_CS_N : out std_logic; + + -- External I/O + SOUND_L : out std_logic_vector(10 downto 0); + SOUND_R : out std_logic_vector(10 downto 0); + + ARESET : in std_logic; + RESET_OUT : out std_logic; + RTC : in std_logic_vector(64 downto 0); + + CMOSCfg : in std_logic_vector(31 downto 0); + + -- PS/2 Keyboard + PS2_KEY : in std_logic_vector(10 downto 0); + PS2_MOUSE : in std_logic_vector(24 downto 0); + joystick : in std_logic_vector(5 downto 0) +); + +end tsconf; + +architecture rtl of tsconf is +-- CPU0 +signal cpu_a_bus : std_logic_vector(15 downto 0); +signal cpu_do_bus : std_logic_vector(7 downto 0); +signal cpu_di_bus : std_logic_vector(7 downto 0); +signal cpu_mreq_n : std_logic; +signal cpu_iorq_n : std_logic; +signal cpu_wr_n : std_logic; +signal cpu_rd_n : std_logic; +signal cpu_int_n_TS : std_logic; +signal cpu_m1_n : std_logic; +signal cpu_rfsh_n : std_logic; +signal turbo : std_logic_vector(1 downto 0); +signal im2vect : std_logic_vector(7 downto 0); +-- zsignal +signal cpu_stall : std_logic; -- zmem -> zclock +signal cpu_req : std_logic; -- zmem -> arbiter +signal cpu_wrbsel : std_logic; -- zmem -> arbiter +signal cpu_next : std_logic; -- arbiter -> zmem +signal cpu_current : std_logic; -- arbiter -> zmem +signal cpu_strobe : std_logic; -- arbiter -> zmem +signal cpu_latch : std_logic; -- arbiter -> zmem +signal cpu_addr : std_logic_vector(23 downto 0); +signal cpu_addr_20 : std_logic_vector(20 downto 0); +signal cpu_addr_ext : std_logic_vector(2 downto 0); +signal csvrom : std_logic; +signal curr_cpu : std_logic; +-- Memory +signal rom_do_bus : std_logic_vector(7 downto 0); +signal cacheconf : std_logic_vector(3 downto 0); +-- SDRAM +signal sdr_do_bus : std_logic_vector(7 downto 0); +signal sdr_do_bus_16 : std_logic_vector(15 downto 0); +signal sdr2cpu_do_bus_16 : std_logic_vector(15 downto 0); +signal sdr_wr : std_logic; +signal sdr_rd : std_logic; +signal req : std_logic; +signal rnw : std_logic; +signal dram_addr : std_logic_vector(23 downto 0); +signal dram_bsel : std_logic_vector(1 downto 0); +signal dram_wrdata : std_logic_vector(15 downto 0); +signal dram_req : std_logic; +signal dram_rnw : std_logic; +-- Port +signal port_xxfe_reg : std_logic_vector(7 downto 0); +signal port_xx01_reg : std_logic_vector(7 downto 0) := "00000000"; +signal ena_1_75mhz : std_logic; +signal ena_cnt : std_logic_vector(5 downto 0); +-- System +signal reset : std_logic; +--signal key_reset : std_logic; +signal loader : std_logic := '1'; +signal zports_loader : std_logic := '0'; +signal dos : std_logic := '1'; +--signal xtpage_0 : std_logic_vector(7 downto 0); +-- PS/2 Keyboard +signal kb_do_bus : std_logic_vector(4 downto 0); +signal kb_f_bus : std_logic_vector(4 downto 0); +signal key_scancode : std_logic_vector(7 downto 0); +-- MC146818A +signal mc146818a_wr : std_logic; +--signal mc146818a_rd : std_logic; +signal mc146818a_do_bus : std_logic_vector(7 downto 0); +signal port_bff7 : std_logic; +signal port_eff7_reg : std_logic_vector(7 downto 0); +signal ena_0_4375mhz : std_logic; +signal gluclock_addr : std_logic_vector(7 downto 0); +-- Soundrive +signal covox_a : std_logic_vector(7 downto 0); +signal covox_b : std_logic_vector(7 downto 0); +signal covox_c : std_logic_vector(7 downto 0); +signal covox_d : std_logic_vector(7 downto 0); +-- TurboSound +signal ssg_sel : std_logic; +signal ssg_cn0_bus : std_logic_vector(7 downto 0); +signal ssg_cn0_a : std_logic_vector(7 downto 0); +signal ssg_cn0_b : std_logic_vector(7 downto 0); +signal ssg_cn0_c : std_logic_vector(7 downto 0); +signal ssg_cn1_bus : std_logic_vector(7 downto 0); +signal ssg_cn1_a : std_logic_vector(7 downto 0); +signal ssg_cn1_b : std_logic_vector(7 downto 0); +signal ssg_cn1_c : std_logic_vector(7 downto 0); +-- clock +signal f0 : std_logic; +signal f1 : std_logic; +signal h0 : std_logic; +signal h1 : std_logic; +signal c0 : std_logic; +signal c1 : std_logic; +signal c2 : std_logic; +signal c3 : std_logic; +signal ay_clk : std_logic; +signal zclk : std_logic; +signal zpos : std_logic; +signal zneg : std_logic; +--signal dos_on : std_logic; +--signal dos_off : std_logic; +signal vdos : std_logic; +signal pre_vdos : std_logic; +signal vdos_off : std_logic; +signal vdos_on : std_logic; +signal dos_change : std_logic; +--signal dos_stall : std_logic; +-- out zsignals +signal m1 : std_logic; +--signal rfsh : std_logic; +signal rd : std_logic; +signal wr : std_logic; +signal iorq : std_logic; +signal mreq : std_logic; +signal rdwr : std_logic; +signal iord : std_logic; +signal iowr : std_logic; +signal iorw : std_logic; +signal memrd : std_logic; +signal memwr : std_logic; +--signal memrw : std_logic; +signal opfetch : std_logic; +signal intack : std_logic; +-- strobre +signal iorq_s : std_logic; +--signal mreq_s : std_logic; +signal iord_s : std_logic; +signal iowr_s : std_logic; +signal iorw_s : std_logic; +--signal memrd_s : std_logic; +signal memwr_s : std_logic; +--signal memrw_s : std_logic; +signal opfetch_s : std_logic; +-- zports OUT +signal dout_ports : std_logic_vector(7 downto 0); +signal ena_ports : std_logic; +signal xt_page : std_logic_vector(31 downto 0); +signal fmaddr : std_logic_vector(4 downto 0); +signal sysconf : std_logic_vector(7 downto 0); +signal memconf : std_logic_vector(7 downto 0); +--signal fddvirt : std_logic_vector(3 downto 0); +--signal im2v_frm : std_logic_vector(2 downto 0); +--signal im2v_lin : std_logic_vector(2 downto 0); +--signal im2v_dma : std_logic_vector(2 downto 0); +signal intmask : std_logic_vector(7 downto 0); +signal dmaport_wr : std_logic_vector(8 downto 0); +--signal mus_in_TS : std_logic_vector(7 downto 0); +-- VIDEO_TS +signal go : std_logic; +signal go_arbiter : std_logic; +-- z80 +signal zmd : std_logic_vector(15 downto 0); +signal zma : std_logic_vector(7 downto 0); +signal cram_we : std_logic; +signal sfile_we : std_logic; +signal zborder_wr : std_logic; +signal border_wr : std_logic; +signal zvpage_wr : std_logic; +signal vpage_wr : std_logic; +signal vconf_wr : std_logic; +signal gx_offsl_wr : std_logic; +signal gx_offsh_wr : std_logic; +signal gy_offsl_wr : std_logic; +signal gy_offsh_wr : std_logic; +signal t0x_offsl_wr : std_logic; +signal t0x_offsh_wr : std_logic; +signal t0y_offsl_wr : std_logic; +signal t0y_offsh_wr : std_logic; +signal t1x_offsl_wr : std_logic; +signal t1x_offsh_wr : std_logic; +signal t1y_offsl_wr : std_logic; +signal t1y_offsh_wr : std_logic; +signal tsconf_wr : std_logic; +signal palsel_wr : std_logic; +signal tmpage_wr : std_logic; +signal t0gpage_wr : std_logic; +signal t1gpage_wr : std_logic; +signal sgpage_wr : std_logic; +signal hint_beg_wr : std_logic; +signal vint_begl_wr : std_logic; +signal vint_begh_wr : std_logic; +-- ZX controls +signal res : std_logic; +signal int_start_frm : std_logic; +signal int_start_lin : std_logic; +-- DRAM interface +signal video_addr : std_logic_vector(20 downto 0); +signal video_bw : std_logic_vector(4 downto 0); +signal video_go : std_logic; +signal dram_rdata : std_logic_vector(15 downto 0); -- raw, should be latched by c2 (video_next) +signal video_next : std_logic; +signal video_pre_next: std_logic; +signal next_video : std_logic; +signal video_strobe : std_logic; +signal video_next_strobe : std_logic; +-- TS +signal ts_addr : std_logic_vector(20 downto 0); +signal ts_req : std_logic; +signal ts_z80_lp : std_logic; +-- IN +signal ts_pre_next : std_logic; +signal ts_next : std_logic; +-- TM +signal tm_addr : std_logic_vector(20 downto 0); +signal tm_req : std_logic; +-- Video +signal tm_next : std_logic; +-- DMA +signal dma_rnw : std_logic; +signal dma_req : std_logic; +signal dma_z80_lp : std_logic; +signal dma_wrdata : std_logic_vector(15 downto 0); +signal dma_addr : std_logic_vector(20 downto 0); +signal dma_next : std_logic; +signal dma_act : std_logic; +signal dma_cram_we : std_logic; +signal dma_sfile_we : std_logic; +-- zmap +signal dma_data : std_logic_vector(15 downto 0); +signal dma_wraddr : std_logic_vector(7 downto 0); +signal int_start_dma : std_logic; +-- SPI +signal sdcs_n_TS : std_logic; +signal spi_stb : std_logic; +signal spi_start : std_logic; +signal dma_spi_req : std_logic; +signal dma_spi_din : std_logic_vector(7 downto 0); +signal cpu_spi_req : std_logic; +signal cpu_spi_din : std_logic_vector(7 downto 0); +signal spi_dout : std_logic_vector(7 downto 0); +-- Keys +signal key_f : std_logic_vector(4 downto 0); +signal key : std_logic_vector(4 downto 0) := "00000"; +-- HDMI +signal clk_hdmi : std_logic; +signal csync_ts : std_logic; +signal hdmi_d1_sig : std_logic; +-- I2C +signal i2c_do_bus : std_logic_vector(7 downto 0); +signal i2c_wr : std_logic; + +signal mouse_do : std_logic_vector(7 downto 0); +------------------------------------------------------------------------------- +-- COMPONENTS TS Lab +------------------------------------------------------------------------------- +component clock is +port ( + clk : in std_logic; + ay_mod : in std_logic_vector(1 downto 0); + f0 : out std_logic; + f1 : out std_logic; + h0 : out std_logic; + h1 : out std_logic; + c0 : out std_logic; + c1 : out std_logic; + c2 : out std_logic; + c3 : out std_logic; + ay_clk : out std_logic); +end component; + +component zclock is +port ( + clk : in std_logic; + zclk_out : out std_logic; + c1 : in std_logic; + c3 : in std_logic; + c14Mhz : in std_logic; + iorq_s : in std_logic; + external_port : in std_logic; + zpos : out std_logic; + zneg : out std_logic; + dos_stall_o : out std_logic; + cpu_stall : in std_logic; + ide_stall : in std_logic; + dos_on : in std_logic; + vdos_off : in std_logic; + turbo : in std_logic_vector(1 downto 0)); -- input [1:0] turbo 2'b00 - 3.5 MHz, 2'b01 - 7.0 MHz, 2'b1x - 14.0 MHz +end component; + +component zsignals is +port ( + clk : in std_logic; + zpos : in std_logic; + iorq_n : in std_logic; + mreq_n : in std_logic; + m1_n : in std_logic; + rfsh_n : in std_logic; + rd_n : in std_logic; + wr_n : in std_logic; + m1 : out std_logic; + rfsh : out std_logic; + rd : out std_logic; + wr : out std_logic; + iorq : out std_logic; + mreq : out std_logic; + rdwr : out std_logic; + iord : out std_logic; + iowr : out std_logic; + iorw : out std_logic; + memrd : out std_logic; + memwr : out std_logic; + memrw : out std_logic; + opfetch : out std_logic; + intack : out std_logic; + iorq_s : out std_logic; + mreq_s : out std_logic; + iord_s : out std_logic; + iowr_s : out std_logic; + iorw_s : out std_logic; + memrd_s : out std_logic; + memwr_s : out std_logic; + memrw_s : out std_logic; + opfetch_s : out std_logic); +end component; + +component zports is +port ( + zclk : in std_logic; + clk : in std_logic; + din : in std_logic_vector(7 downto 0); + dout : out std_logic_vector(7 downto 0); + dataout : out std_logic; + a : in std_logic_vector(15 downto 0); + rst : in std_logic; + loader : in std_logic; + opfetch : in std_logic; + rd : in std_logic; + wr : in std_logic; + rdwr : in std_logic; + iorq : in std_logic; + iorq_s : in std_logic; + iord : in std_logic; + iord_s : in std_logic; + iowr : in std_logic; + iowr_s : in std_logic; + iorw : in std_logic; + iorw_s : in std_logic; + porthit : out std_logic; -- when internal port hit occurs, this is 1, else 0; used for iorq1_n iorq2_n on zxbus + external_port : out std_logic; -- asserts for AY and VG93 accesses + zborder_wr : out std_logic; + border_wr : out std_logic; + zvpage_wr : out std_logic; + vpage_wr : out std_logic; + vconf_wr : out std_logic; + gx_offsl_wr : out std_logic; + gx_offsh_wr : out std_logic; + gy_offsl_wr : out std_logic; + gy_offsh_wr : out std_logic; + t0x_offsl_wr: out std_logic; + t0x_offsh_wr: out std_logic; + t0y_offsl_wr: out std_logic; + t0y_offsh_wr: out std_logic; + t1x_offsl_wr: out std_logic; + t1x_offsh_wr: out std_logic; + t1y_offsl_wr: out std_logic; + t1y_offsh_wr: out std_logic; + tsconf_wr : out std_logic; + palsel_wr : out std_logic; + tmpage_wr : out std_logic; + t0gpage_wr : out std_logic; + t1gpage_wr : out std_logic; + sgpage_wr : out std_logic; + hint_beg_wr : out std_logic; + vint_begl_wr: out std_logic; + vint_begh_wr: out std_logic; + xt_page : out std_logic_vector(31 downto 0); + fmaddr : out std_logic_vector(4 downto 0); + sysconf : out std_logic_vector(7 downto 0); + memconf : out std_logic_vector(7 downto 0); + cacheconf : out std_logic_vector(3 downto 0); + fddvirt : out std_logic_vector(3 downto 0); + --im2v_frm : out std_logic_vector(2 downto 0); + --im2v_lin : out std_logic_vector(2 downto 0); + --im2v_dma : out std_logic_vector(2 downto 0); + intmask : out std_logic_vector(7 downto 0); + dmaport_wr : out std_logic_vector(8 downto 0); + dma_act : in std_logic; + dos : in std_logic; + vdos : in std_logic; + vdos_on : out std_logic; + vdos_off : out std_logic; + ay_bdir : out std_logic; + ay_bc1 : out std_logic; + covox_wr : out std_logic; + beeper_wr : out std_logic; + rstrom : in std_logic_vector(1 downto 0); + tape_read : in std_logic; +-- ide_in : in std_logic_vector(15 downto 0); +-- ide_out : out std_logic_vector(15 downto 0); +-- ide_cs0_n : out std_logic; +-- ide_cs1_n : out std_logic; +-- ide_req : out std_logic; +-- ide_stb : in std_logic; +-- ide_ready : in std_logic; +-- ide_stall : out std_logic; + keys_in : in std_logic_vector(4 downto 0); -- keys (port FE) + mus_in : in std_logic_vector(7 downto 0); -- mouse (xxDF) + kj_in : in std_logic_vector(5 downto 0); + vg_intrq : in std_logic; + vg_drq : in std_logic; -- from vg93 module - drq + irq read + vg_cs_n : out std_logic; + vg_wrFF : out std_logic; + drive_sel : out std_logic_vector(1 downto 0); -- disk drive selection + sdcs_n : out std_logic; + sd_start : out std_logic; + sd_datain : out std_logic_vector(7 downto 0); + sd_dataout : in std_logic_vector(7 downto 0); + gluclock_addr : out std_logic_vector(7 downto 0); + comport_addr : out std_logic_vector(2 downto 0); + wait_start_gluclock : out std_logic; -- begin wait from some ports + wait_start_comport : out std_logic; + wait_write : out std_logic_vector(7 downto 0); + wait_read : in std_logic_vector(7 downto 0) ; + com_data_rx : in std_logic_vector(7 downto 0); + com_status : in std_logic_vector(7 downto 0); + TST : out std_logic_vector(7 downto 0); + lock_conf : in std_logic); +end component; + +component zmem is +port ( + clk : in std_logic; + c0 : in std_logic; + c1 : in std_logic; + c2 : in std_logic; + c3 : in std_logic; + zneg : in std_logic; + zpos : in std_logic; + rst : in std_logic; + za : in std_logic_vector(15 downto 0); + zd_out : out std_logic_vector(7 downto 0); -- output to Z80 bus + zd_ena : out std_logic; -- output to Z80 bus enable + opfetch : in std_logic; + opfetch_s : in std_logic; + mreq : in std_logic; + memrd : in std_logic; + memwr : in std_logic; + memwr_s : in std_logic; + turbo : in std_logic_vector(1 downto 0); + cache_en : in std_logic_vector(3 downto 0); + memconf : in std_logic_vector(3 downto 0); + xt_page : in std_logic_vector(31 downto 0); + xtpage_0 : out std_logic_vector(7 downto 0); + rompg : out std_logic_vector(4 downto 0); -- 32page = 512kB + csrom : out std_logic; + romoe_n : out std_logic; + romwe_n : out std_logic; + csvrom : out std_logic; + dos : out std_logic; -- DOS + dos_on : out std_logic; + dos_off : out std_logic; + dos_change : out std_logic; -- state is shanging + vdos : out std_logic; -- Virtual DOS + pre_vdos : out std_logic; -- Virtual DOS + vdos_on : in std_logic; + vdos_off : in std_logic; + cpu_req : out std_logic; + cpu_addr : out std_logic_vector(20 downto 0); + cpu_wrbsel : out std_logic; -- for 16bit data + cpu_rddata : in std_logic_vector(15 downto 0); -- RD + cpu_next : in std_logic; + cpu_strobe : in std_logic; -- from ARBITER + cpu_latch : in std_logic; -- from ARBITER + cpu_stall : out std_logic; -- for Zclock if HI-> SRALL (ZCLK) + loader : in std_logic; + testkey : in std_logic; + intt : in std_logic; + tst : out std_logic_vector(3 downto 0)); +end component; + +component arbiter is +port ( + clk : in std_logic; + c0 : in std_logic; + c1 : in std_logic; + c2 : in std_logic; + c3 : in std_logic; + dram_addr : out std_logic_vector(23 downto 0); -- address for dram access + dram_req : out std_logic; -- dram request + dram_rnw : out std_logic; -- Read-NotWrite + dram_bsel : out std_logic_vector(1 downto 0); -- byte select: bsel[1] for wrdata[15:8], bsel[0] for wrdata[7:0] + dram_wrdata : out std_logic_vector(15 downto 0); -- data to be written + video_addr : in std_logic_vector(23 downto 0); -- during access block, only when video_strobe==1 + go : in std_logic; -- start video access blocks + video_bw : in std_logic_vector(4 downto 0); -- [4:3] -total cycles: 11 = 8 / 01 = 4 / 00 = 2 + video_pre_next : out std_logic; -- (c1) + video_next : out std_logic; -- (c2) at this signal video_addr may be changed; it is one clock leading the video_strobe + video_strobe: out std_logic; -- (c3) one-cycle strobe meaning that video_data is available + video_next_strobe : out std_logic; -- OUT + next_vid : out std_logic; -- used for TM prefetch + cpu_addr : in std_logic_vector(23 downto 0); + cpu_wrdata : in std_logic_vector(7 downto 0); + cpu_req : in std_logic; + cpu_rnw : in std_logic; + cpu_wrbsel : in std_logic; + cpu_next : out std_logic; -- next cycle is allowed to be used by CPU + cpu_strobe : out std_logic; -- c2 strobe + cpu_latch : out std_logic; -- c2-c3 strobe + curr_cpu_o : out std_logic; -- c0,c1,c2 strobe + dma_addr : in std_logic_vector(23 downto 0); + dma_wrdata : in std_logic_vector(15 downto 0); + dma_req : in std_logic; + dma_z80_lp : in std_logic; + dma_rnw : in std_logic; + dma_next : out std_logic; + ts_addr : in std_logic_vector(23 downto 0); + ts_req : in std_logic; + ts_z80_lp : in std_logic; + ts_pre_next : out std_logic; + ts_next : out std_logic; + tm_addr : in std_logic_vector(23 downto 0); + tm_req : in std_logic; + tm_next : out std_logic; + TST : out std_logic_vector(7 downto 0)); +end component; + +component video_top is +port ( + clk : in std_logic; + f0 : in std_logic; + f1 : in std_logic; + h0 : in std_logic; + h1 : in std_logic; + c0 : in std_logic; + c1 : in std_logic; + c2 : in std_logic; + c3 : in std_logic; + vred : out std_logic_vector(7 downto 0); + vgrn : out std_logic_vector(7 downto 0); + vblu : out std_logic_vector(7 downto 0); + hsync : out std_logic; + vsync : out std_logic; + csync : out std_logic; + hblank : out std_logic; + vblank : out std_logic; + pix_stb : out std_logic; + a : in std_logic_vector(15 downto 0); + d : in std_logic_vector(7 downto 0); + zmd : in std_logic_vector(15 downto 0); + zma : in std_logic_vector(7 downto 0); + cram_we : in std_logic; + sfile_we : in std_logic; + zborder_wr : in std_logic; + border_wr : in std_logic; + zvpage_wr : in std_logic; + vpage_wr : in std_logic; + vconf_wr : in std_logic; + gx_offsl_wr : in std_logic; + gx_offsh_wr : in std_logic; + gy_offsl_wr : in std_logic; + gy_offsh_wr : in std_logic; + t0x_offsl_wr: in std_logic; + t0x_offsh_wr: in std_logic; + t0y_offsl_wr: in std_logic; + t0y_offsh_wr: in std_logic; + t1x_offsl_wr: in std_logic; + t1x_offsh_wr: in std_logic; + t1y_offsl_wr: in std_logic; + t1y_offsh_wr: in std_logic; + tsconf_wr : in std_logic; + palsel_wr : in std_logic; + tmpage_wr : in std_logic; + t0gpage_wr : in std_logic; + t1gpage_wr : in std_logic; + sgpage_wr : in std_logic; + hint_beg_wr : in std_logic; + vint_begl_wr: in std_logic; + vint_begh_wr: in std_logic; + res : in std_logic; + int_start : out std_logic; + line_start_s: out std_logic; + video_addr : out std_logic_vector(20 downto 0); + video_bw : out std_logic_vector(4 downto 0); + video_go : out std_logic; + dram_rdata : in std_logic_vector(15 downto 0); -- raw, should be latched by c2 (video_next) + video_next : in std_logic; + video_pre_next : in std_logic; + next_video : in std_logic; + video_strobe: in std_logic; + video_next_strobe : in std_logic; -- INPUT + ts_addr : out std_logic_vector(20 downto 0); + ts_req : out std_logic; + ts_z80_lp : out std_logic; + ts_pre_next : in std_logic; + ts_next : in std_logic; + tm_addr : out std_logic_vector(20 downto 0); + tm_req : out std_logic; + tm_next : in std_logic; + cfg_60hz : in std_logic; + sync_pol : in std_logic; + vga_on : in std_logic; + tst : out std_logic_vector(3 downto 0)); +end component; + +component dma is +port ( + clk : in std_logic; + c2 : in std_logic; + reset : in std_logic; + dmaport_wr : in std_logic_vector(8 downto 0); + dma_act : out std_logic; + data : out std_logic_vector(15 downto 0); + wraddr : out std_logic_vector(7 downto 0); + int_start : out std_logic; + zdata : in std_logic_vector(7 downto 0); + dram_addr : out std_logic_vector(20 downto 0); + dram_rddata : in std_logic_vector(15 downto 0); + dram_wrdata : out std_logic_vector(15 downto 0); + dram_req : out std_logic; + dma_z80_lp : out std_logic; + dram_rnw : out std_logic; + dram_next : in std_logic; + spi_rddata : in std_logic_vector(7 downto 0); + spi_wrdata : out std_logic_vector(7 downto 0); + spi_req : out std_logic; + spi_stb : in std_logic; + spi_start : in std_logic; + ide_in : in std_logic_vector(15 downto 0); + ide_out : out std_logic_vector(15 downto 0); + ide_req : out std_logic; + ide_rnw : out std_logic; + ide_stb : in std_logic; + cram_we : out std_logic; + sfile_we : out std_logic; + TST : out std_logic_vector(3 downto 0)); +end component; + +component zmaps is +port ( + clk : in std_logic; + memwr_s : in std_logic; + a : in std_logic_vector(15 downto 0); + d : in std_logic_vector(7 downto 0); + fmaddr : in std_logic_vector(4 downto 0); + zmd : out std_logic_vector(15 downto 0); + zma : out std_logic_vector(7 downto 0); + dma_data : in std_logic_vector(15 downto 0); + dma_wraddr : in std_logic_vector(7 downto 0); + dma_cram_we : in std_logic; + dma_sfile_we: in std_logic; + cram_we : out std_logic; + sfile_we : out std_logic); +end component; + +component spi is +port ( + clk : in std_logic; -- system clk + sck : out std_logic; -- SPI bus pins... + sdo : out std_logic; + sdi : in std_logic; + stb : out std_logic; -- ready strobe, 1 clock length + start : out std_logic; -- start strobe, 1 clock length + bsync : out std_logic; -- for vs1001 + dma_req : in std_logic; + dma_din : in std_logic_vector(7 downto 0); + cpu_req : in std_logic; + cpu_din : in std_logic_vector(7 downto 0); + dout : out std_logic_vector(7 downto 0); + speed : in std_logic_vector(1 downto 0); + tst : out std_logic_vector(2 downto 0)); +end component; + +component zint is +port ( + clk : in std_logic; + zclk : in std_logic; + res : in std_logic; + int_start_frm : in std_logic; + int_start_lin : in std_logic; + int_start_dma : in std_logic; + vdos : in std_logic; + intack : in std_logic; + --im2v_frm : in std_logic_vector(2 downto 0); + --im2v_lin : in std_logic_vector(2 downto 0); + --im2v_dma : in std_logic_vector(2 downto 0); + intmask : in std_logic_vector(7 downto 0); + im2vect : out std_logic_vector(7 downto 0); + int_n : out std_logic); +end component; + +component kempston_mouse is +port ( + clk_sys : in std_logic; + reset : in std_logic; + ps2_mouse : in std_logic_vector(24 downto 0); + addr : in std_logic_vector(2 downto 0); + sel : out std_logic; + dout : out std_logic_vector(7 downto 0)); +end component; + +------------------------------------------------------------------------------- + +begin + +TS01: clock +port map ( + clk => clk_28mhz, + ay_mod => "00", + f0 => f0, + f1 => f1, + h0 => h0, + h1 => h1, + c0 => c0, + c1 => c1, + c2 => c2, + c3 => c3, + ay_clk => open); + +TS02: zclock +port map ( + clk => clk_28mhz, + c1 => c1, + c3 => c3, + c14Mhz => c1, + zclk_out => zclk, + zpos => zpos, + zneg => zneg, + dos_stall_o => open, + iorq_s => iorq_s, + dos_on => dos_change, + vdos_off => vdos_off, + cpu_stall => cpu_stall, + ide_stall => '0', + external_port => '0', + turbo => turbo); + +z80_unit: entity work.T80s +generic map ( + Mode => 0, -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write => 1, -- 0 => WR_n active in T3, 1 => WR_n active in T2 + IOWait => 1) -- 0 => Single cycle I/O, 1 => Std I/O cycle +port map ( + RESET_n => not reset, + CLK_n => zclk, + WAIT_n => '1', + INT_n => cpu_int_n_TS, + NMI_n => '1', + BUSRQ_n => '1', + M1_n => cpu_m1_n, + MREQ_n => cpu_mreq_n, + IORQ_n => cpu_iorq_n, + RD_n => cpu_rd_n, + WR_n => cpu_wr_n, + RFSH_n => cpu_rfsh_n, + HALT_n => open, + BUSAK_n => open, + A => cpu_a_bus, + DI => cpu_di_bus, + DO => cpu_do_bus, + SavePC => open, + SaveINT => open, + RestorePC => (others => '1'), + RestoreINT => (others => '1'), + RestorePC_n => '1'); + +TS04: zsignals +port map ( + clk => clk_28mhz, + zpos => zpos, + iorq_n => cpu_iorq_n, + mreq_n => cpu_mreq_n, + m1_n => cpu_m1_n, + rfsh_n => cpu_rfsh_n, + rd_n => cpu_rd_n, + wr_n => cpu_wr_n, + m1 => open, + rfsh => open, + rd => rd, + wr => wr, + iorq => iorq, + mreq => mreq, + rdwr => rdwr, + iord => iord, + iowr => iowr, + iorw => iorw, + memrd => memrd, + memwr => memwr, + memrw => open, + opfetch => opfetch, + intack => intack, + iorq_s => iorq_s, + mreq_s => open, + iord_s => iord_s, + iowr_s => iowr_s, + iorw_s => iorw_s, + memrd_s => open, + memwr_s => memwr_s, + memrw_s => open, + opfetch_s => opfetch_s); + +TS05: zports +port map ( + zclk => zclk, + clk => clk_28mhz, + din => cpu_do_bus, + dout => dout_ports, + dataout => ena_ports, + a => cpu_a_bus, + rst => reset, + loader => zports_loader,--loader, -- for load ROM, SPI should be enable ; хак для загрузки с fat32 + opfetch => opfetch, -- from zsignals + rd => rd, + wr => wr, + rdwr => rdwr, + iorq => iorq, + iorq_s => iorq_s, + iord => iord, + iord_s => iord_s, + iowr => iowr, + iowr_s => iowr_s, + iorw => iorw, + iorw_s => iorw_s, + porthit => open, -- when internal port hit occurs, this is 1, else 0; used for iorq1_n iorq2_n on zxbus + external_port => open, -- asserts for AY and VG93 accesses + zborder_wr => zborder_wr, + border_wr => border_wr, + zvpage_wr => zvpage_wr, + vpage_wr => vpage_wr, + vconf_wr => vconf_wr, + gx_offsl_wr => gx_offsl_wr, + gx_offsh_wr => gx_offsh_wr, + gy_offsl_wr => gy_offsl_wr, + gy_offsh_wr => gy_offsh_wr, + t0x_offsl_wr=> t0x_offsl_wr, + t0x_offsh_wr=> t0x_offsh_wr, + t0y_offsl_wr=> t0y_offsl_wr, + t0y_offsh_wr=> t0y_offsh_wr, + t1x_offsl_wr=> t1x_offsl_wr, + t1x_offsh_wr=> t1x_offsh_wr, + t1y_offsl_wr=> t1y_offsl_wr, + t1y_offsh_wr=> t1y_offsh_wr, + tsconf_wr => tsconf_wr, + palsel_wr => palsel_wr, + tmpage_wr => tmpage_wr, + t0gpage_wr => t0gpage_wr, + t1gpage_wr => t1gpage_wr, + sgpage_wr => sgpage_wr, + hint_beg_wr => hint_beg_wr, + vint_begl_wr=> vint_begl_wr, + vint_begh_wr=> vint_begh_wr, + xt_page => xt_page, + fmaddr => fmaddr, + sysconf => sysconf, + memconf => memconf, + cacheconf => cacheconf, + fddvirt => open, + --im2v_frm => im2v_frm, + --im2v_lin => im2v_lin, + --im2v_dma => im2v_dma, + intmask => intmask, + dmaport_wr => dmaport_wr, -- dmaport_wr + dma_act => dma_act, -- from DMA (status of DMA) + dos => dos, + vdos => vdos, + vdos_on => vdos_on, + vdos_off => vdos_off, + ay_bdir => open, + ay_bc1 => open, + covox_wr => open, + beeper_wr => open, + rstrom => "11", + tape_read => '1', +-- ide_in => "0000000000000000", +-- ide_out => open, +-- ide_cs0_n => open, +-- ide_cs1_n => open, +-- ide_req => open, +-- ide_stb => '0', +-- ide_ready => '0', +-- ide_stall => open, + keys_in => kb_do_bus, -- keys (port FE) + mus_in => mouse_do, -- mouse (xxDF) + kj_in => joystick, + vg_intrq => '0', + vg_drq => '0', -- from vg93 module - drq + irq read + vg_cs_n => open, + vg_wrFF => open, + drive_sel => open, -- disk drive selection + sdcs_n => sdcs_n_TS, -- to SD card + sd_start => cpu_spi_req, -- to SPI + sd_datain => cpu_spi_din, -- to SPI(7 downto 0); + sd_dataout => spi_dout, -- from SPI(7 downto 0); + gluclock_addr => gluclock_addr, + comport_addr => open, + wait_start_gluclock => open, -- begin wait from some ports + wait_start_comport => open, + wait_write => open, + wait_read => mc146818a_do_bus, + com_data_rx => "00000000", --uart_do_bus, + com_status => "10010000", --'1' & uart_tx_empty & uart_tx_fifo_empty & "1000" & uart_rx_avail, + --com_status=> '0' & uart_tx_empty & uart_tx_fifo_empty & "0000" & '1', + TST => open, + lock_conf => '1'); + +TS06: zmem +port map ( + clk => clk_28mhz, + c0 => c0, + c1 => c1, + c2 => c2, + c3 => c3, + zneg => zneg, + zpos => zpos, + rst => reset, -- PLL locked + za => cpu_a_bus, -- from CPU + zd_out => sdr_do_bus, -- output to Z80 bus 8bit ==> + zd_ena => open, -- output to Z80 bus enable + opfetch => opfetch, -- from zsignals + opfetch_s => opfetch_s, -- from zsignals + mreq => mreq, -- from zsignals + memrd => memrd, -- from zsignals + memwr => memwr, -- from zsignals + memwr_s => memwr_s, -- from zsignals + turbo => turbo, + cache_en => cacheconf, -- from zport + memconf => memconf(3 downto 0), + xt_page => xt_page, + xtpage_0 => open, + rompg => open, -- 32page = 512kB + csrom => open, + romoe_n => open, + romwe_n => open, + csvrom => csvrom, + dos => dos, + dos_on => open, + dos_off => open, + dos_change => dos_change, + vdos => vdos, + pre_vdos => pre_vdos, + vdos_on => vdos_on, + vdos_off => vdos_off, + cpu_req => cpu_req, + cpu_addr => cpu_addr_20, + cpu_wrbsel => cpu_wrbsel, -- for 16bit data + --cpu_rddata=> sdr_do_bus_16, -- RD from SDRAM (cpu_strobe=HI and clk) + cpu_rddata => sdr2cpu_do_bus_16, + cpu_next => cpu_next, + cpu_strobe => cpu_strobe, -- from ARBITER ACTIVE=HI + cpu_latch => cpu_latch, + cpu_stall => cpu_stall, -- for Zclock if HI-> STALL (ZCLK) + loader => loader, -- ROM for loader active + testkey => '1', + intt => '0', + tst => open); + +TS07: arbiter +port map ( + clk => clk_28mhz, + c0 => c0, + c1 => c1, + c2 => c2, + c3 => c3, + dram_addr => dram_addr, + dram_req => dram_req, + dram_rnw => dram_rnw, + dram_bsel => dram_bsel, + dram_wrdata => dram_wrdata, -- data to be written + video_addr => "000" & video_addr, -- during access block, only when video_strobe==1 + go => go_arbiter, -- start video access blocks + video_bw => video_bw, -- ZX="11001", [4:3] -total cycles: 11 = 8 / 01 = 4 / 00 = 2 + video_pre_next => video_pre_next, + video_next => video_next, -- (c2) at this signal video_addr may be changed; it is one clock leading the video_strobe + video_strobe=> video_strobe, -- (c3) one-cycle strobe meaning that video_data is available + video_next_strobe => video_next_strobe, + next_vid => next_video, -- used for TM prefetch + --cpu_addr => cpu_addr, + cpu_addr => cpu_addr_ext & cpu_addr_20, + cpu_wrdata => cpu_do_bus, + cpu_req => cpu_req, + cpu_rnw => rd, + cpu_wrbsel => cpu_wrbsel, + cpu_next => cpu_next, -- next cycle is allowed to be used by CPU + cpu_strobe => cpu_strobe, -- c2 strobe + cpu_latch => cpu_latch, -- c2-c3 strobe + curr_cpu_o => curr_cpu, + dma_addr => "000" & dma_addr, + dma_wrdata => dma_wrdata, + dma_req => dma_req, + dma_z80_lp => dma_z80_lp, + dma_rnw => dma_rnw, + dma_next => dma_next, + ts_addr => "000" & ts_addr, + ts_req => ts_req, + ts_z80_lp => ts_z80_lp, + ts_pre_next => ts_pre_next, + ts_next => ts_next, + tm_addr => "000" & tm_addr, + tm_req => tm_req, + tm_next => tm_next, + TST => open); + +TS08: video_top +port map ( + clk => clk_28mhz, + f0 => f0, + f1 => f1, + h0 => h0, + h1 => h1, + c0 => c0, + c1 => c1, + c2 => c2, + c3 => c3, + vred => VGA_R, + vgrn => VGA_G, + vblu => VGA_B, + hsync => VGA_HS, + vsync => VGA_VS, + hblank => VGA_HBLANK, + vblank => VGA_VBLANK, + pix_stb => VGA_CEPIX, + a => cpu_a_bus, + d => cpu_do_bus, + zmd => zmd, + zma => zma, + cram_we => cram_we, + sfile_we => sfile_we, + zborder_wr => zborder_wr, + border_wr => border_wr, + zvpage_wr => zvpage_wr, + vpage_wr => vpage_wr, + vconf_wr => vconf_wr, + gx_offsl_wr => gx_offsl_wr, + gx_offsh_wr => gx_offsh_wr, + gy_offsl_wr => gy_offsl_wr, + gy_offsh_wr => gy_offsh_wr, + t0x_offsl_wr=> t0x_offsl_wr, + t0x_offsh_wr=> t0x_offsh_wr, + t0y_offsl_wr=> t0y_offsl_wr, + t0y_offsh_wr=> t0y_offsh_wr, + t1x_offsl_wr=> t1x_offsl_wr, + t1x_offsh_wr=> t1x_offsh_wr, + t1y_offsl_wr=> t1y_offsl_wr, + t1y_offsh_wr=> t1y_offsh_wr, + tsconf_wr => tsconf_wr, + palsel_wr => palsel_wr, + tmpage_wr => tmpage_wr, + t0gpage_wr => t0gpage_wr, + t1gpage_wr => t1gpage_wr, + sgpage_wr => sgpage_wr, + hint_beg_wr => hint_beg_wr, + vint_begl_wr=> vint_begl_wr, + vint_begh_wr=> vint_begh_wr, + res => reset, + int_start => int_start_frm, + line_start_s=> int_start_lin, + video_addr => video_addr, + video_bw => video_bw, + video_go => go, + dram_rdata => dram_rdata, -- raw, should be latched by c2 (video_next) + video_next => video_next, + video_pre_next => video_pre_next, + next_video => next_video, + video_strobe=> video_strobe, + video_next_strobe => video_next_strobe, + ts_addr => ts_addr, + ts_req => ts_req, + ts_z80_lp => ts_z80_lp, + ts_pre_next => ts_pre_next, + ts_next => ts_next, + tm_addr => tm_addr, + tm_req => tm_req, + tm_next => tm_next, + cfg_60hz => '1', -- 0-60Hz, 1-48Hz + sync_pol => '0', -- 0-positive, 1-negative + vga_on => '0', -- 1-31kHZ + tst => open); + +TS09: dma +port map ( + clk => clk_28mhz, + c2 => c2, + reset => reset, + dmaport_wr => dmaport_wr, + dma_act => dma_act, + data => dma_data, + wraddr => dma_wraddr, + int_start => int_start_dma, + zdata => cpu_do_bus, + dram_addr => dma_addr, + dram_rddata => sdr_do_bus_16, + dram_wrdata => dma_wrdata, + dram_req => dma_req, + dma_z80_lp => dma_z80_lp, + dram_rnw => dma_rnw, + dram_next => dma_next, + spi_rddata => spi_dout, + spi_wrdata => dma_spi_din, + spi_req => dma_spi_req, + spi_stb => spi_stb, + spi_start => spi_start, + ide_in => "0000000000000000", + ide_out => open, + ide_req => open, + ide_rnw => open, + ide_stb => '0', + cram_we => dma_cram_we, + sfile_we => dma_sfile_we, + TST => open); + +TS10: zmaps +port map ( + clk => clk_28mhz, + memwr_s => memwr_s, + a => cpu_a_bus, + d => cpu_do_bus, + fmaddr => fmaddr, + zmd => zmd, + zma => zma, + dma_data => dma_data, + dma_wraddr => dma_wraddr, + dma_cram_we => dma_cram_we, + dma_sfile_we=> dma_sfile_we, + cram_we => cram_we, + sfile_we => sfile_we); + +TS11: spi +port map ( + clk => clk_28mhz, + sck => SD_CLK, + sdo => SD_SI, + sdi => SD_SO, + stb => spi_stb, + start => spi_start, + bsync => open, + dma_req => dma_spi_req, + dma_din => dma_spi_din, + cpu_req => cpu_spi_req, + cpu_din => cpu_spi_din, + dout => spi_dout, + speed => "00", + tst => open); + +TS13: zint +port map ( + clk => clk_28mhz, + zclk => zclk, + res => reset, + int_start_frm => int_start_frm, --< N1 VIDEO + int_start_lin => int_start_lin, --< N2 VIDEO + int_start_dma => int_start_dma, --< N3 DMA + vdos => pre_vdos, -- vdos,--pre_vdos + intack => intack, --< zsignals === (intack ? im2vect : 8'hFF))); + --im2v_frm => im2v_frm, --< ZPORT (2 downto 0); + --im2v_lin => im2v_lin, --< ZPORT (2 downto 0); + --im2v_dma => im2v_dma, --< ZPORT (2 downto 0); + intmask => intmask, --< ZPORT (7 downto 0); + im2vect => im2vect, --> CPU Din (2 downto 0); + int_n => cpu_int_n_TS); + +-- ROM +SE1: entity work.rom +port map ( + address => cpu_a_bus(12 downto 0), + clock => clk_28mhz, + q => rom_do_bus); + +-- SDRAM Controller +SE4: entity work.sdram +port map ( + CLK => clk_84mhz, + clk_28MHz=> clk_28mhz, + c0 => c0, + c1 => c1, + c2 => c2, + c3 => c3, + curr_cpu => curr_cpu, -- from arbiter for luch DO_cpu + loader => loader, -- loader = 1: wr to ROM + bsel => dram_bsel, + A => dram_addr, + DI => dram_wrdata, + DO => sdr_do_bus_16, + DO_cpu => sdr2cpu_do_bus_16, + REQ => dram_req, + RNW => dram_rnw, + RFSH => not cpu_rfsh_n, + RFSHREQ => open, + IDLE => open, + CK => SDRAM_CLK, + CKE => open, + RAS_n => SDRAM_RAS_N, + CAS_n => SDRAM_CAS_N, + WE_n => SDRAM_WE_N, + BA1 => SDRAM_BA(1), + BA0 => SDRAM_BA(0), + MA => SDRAM_A, + DQ => SDRAM_DQ(15 downto 0), + DQML => SDRAM_DQML, + DQMH => SDRAM_DQMH, + dram_stb => open, + TST => open); + +SE5: entity work.keyboard +port map( + CLK => clk_28mhz, + RESET => areset, + A => cpu_a_bus(15 downto 8), + KEYB => kb_do_bus, + KEYF => kb_f_bus, + SCANCODE => key_scancode, + PS2_KEY => PS2_KEY); + +KM: kempston_mouse +port map ( + clk_sys => clk_28mhz, + reset => reset, + ps2_mouse=> PS2_MOUSE, + addr => cpu_a_bus(10 downto 8), + dout => mouse_do); + +SE9: entity work.mc146818a +port map ( + RESET => reset, + CLK => clk_28mhz, + ENA => ena_0_4375mhz, + CS => '1', + KEYSCANCODE => key_scancode, + RTC => RTC, + CMOSCfg => CMOSCfg, + WR => mc146818a_wr, + A => gluclock_addr(7 downto 0), + DI => cpu_do_bus, + DO => mc146818a_do_bus); + +-- Soundrive +SE10: entity work.soundrive +port map ( + RESET => reset, + CLK => clk_28mhz, + CS => '1', + WR_n => cpu_wr_n, + A => cpu_a_bus(7 downto 0), + DI => cpu_do_bus, + IORQ_n => cpu_iorq_n, + DOS => dos, + OUTA => covox_a, + OUTB => covox_b, + OUTC => covox_c, + OUTD => covox_d); + +-- TurboSound +SE12: entity work.turbosound +port map ( + RESET => reset, + CLK => clk_28mhz, + ENA => ena_1_75mhz, + A => cpu_a_bus, + DI => cpu_do_bus, + WR_n => cpu_wr_n, + IORQ_n => cpu_iorq_n, + M1_n => cpu_m1_n, + SEL => ssg_sel, + CN0_DO => ssg_cn0_bus, + CN0_A => ssg_cn0_a, + CN0_B => ssg_cn0_b, + CN0_C => ssg_cn0_c, + CN1_DO => ssg_cn1_bus, + CN1_A => ssg_cn1_a, + CN1_B => ssg_cn1_b, + CN1_C => ssg_cn1_c); + +-- I2C Controller +--U12: entity work.i2c +--port map ( +-- RESET => reset, +-- CLK => clk_28mhz, +-- ENA => ena_0_4375mhz, +-- A => cpu_a_bus(4), +-- DI => cpu_do_bus, +-- DO => i2c_do_bus, +-- WR => i2c_wr, +-- I2C_SCL => SCL, +-- I2C_SDA => SDA); + +SDRAM_CKE <= '1'; -- pullup +SDRAM_CS_N <= '0'; -- pulldown + +------------------------------------------------------------------------------- +-- Global +------------------------------------------------------------------------------- +reset <= areset or kb_f_bus(1); -- Reset +go_arbiter <= go; + +process (clk_28mhz) +begin + if clk_28mhz' event and clk_28mhz = '0' then + ena_cnt <= ena_cnt + 1; + ena_1_75mhz <= not ena_cnt(3) and ena_cnt(2) and ena_cnt(1) and ena_cnt(0); + ena_0_4375mhz <= not ena_cnt(5) and ena_cnt(4) and ena_cnt(3) and ena_cnt(2) and ena_cnt(1) and ena_cnt(0); + end if; +end process; + +-- CPU interface +--cpu_addr_ext <= "100" when (loader = '1' and cpu_a_bus(15 downto 14) = "11") else csvrom & "00"; --- ROM csrom (only for BANK0) +--cpu_addr_ext <= "100" when loader = '1' else csvrom & "00"; --- ROM csrom (only for BANK0) ; хак для загрузки с fat32 +cpu_addr_ext <= "100" when (loader = '1' and (cpu_a_bus(15 downto 14) = "10" or cpu_a_bus(15 downto 14) = "11")) else csvrom & "00"; -- (c) VBI + +dram_rdata <= sdr_do_bus_16; + +cpu_di_bus <= rom_do_bus when (loader = '1' and cpu_mreq_n = '0' and cpu_rd_n = '0' and cpu_a_bus(15 downto 13) = "000") else + sdr_do_bus when (cpu_mreq_n = '0' and cpu_rd_n = '0') else -- SDRAM + im2vect when intack = '1' else + X"FF" when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus( 7 downto 0) = X"02") else + X"FF" when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus( 7 downto 0) = X"03") else + mc146818a_do_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and port_bff7 = '1' and port_eff7_reg(7) = '1') else -- MC146818A + ssg_cn0_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus = "1111111111111101" and ssg_sel = '0') else -- TurboSound + ssg_cn1_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus = "1111111111111101" and ssg_sel = '1') else + key_scancode when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus = X"0001") else + i2c_do_bus when (cpu_iorq_n = '0' and cpu_rd_n = '0' and cpu_a_bus( 7 downto 5) = "100" and cpu_a_bus(3 downto 0) = "1100") else -- RTC + dout_ports when ena_ports = '1' else + "11111111"; + +zports_loader <= '1' when loader = '1' and port_xx01_reg(0) = '0' else '0'; -- enable zports_loader only for SPI flash loading mode + +process (areset, clk_28mhz, cpu_a_bus, cpu_mreq_n, cpu_wr_n, cpu_do_bus, port_xx01_reg) +begin + if areset = '1' then + port_xx01_reg <= "00000001"; -- bit2 = (0:Loader ON, 1:Loader OFF); bit0 = (0:FLASH, 1:SD) + loader <= '1'; + elsif clk_28mhz'event and clk_28mhz = '1' then + if cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(7 downto 0) = "00000001" then port_xx01_reg <= cpu_do_bus; end if; + if cpu_m1_n = '0' and cpu_mreq_n = '0' and cpu_a_bus = X"0000" and port_xx01_reg(2) = '1' then loader <= '0'; end if; + end if; +end process; + +process (reset, clk_28mhz) +begin + if reset = '1' then + port_xxfe_reg <= "00000000"; + port_eff7_reg <= "00000000"; + elsif clk_28mhz'event and clk_28mhz = '1' then + if cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus(7 downto 0) = "11111110" then port_xxfe_reg <= cpu_do_bus; end if; + if cpu_iorq_n = '0' and cpu_wr_n = '0' and cpu_a_bus = "1110111111110111" then port_eff7_reg <= cpu_do_bus; end if; --for RTC + end if; +end process; + +-- TURBO +turbo <= "11" when loader = '1' else sysconf(1 downto 0); + +-- Fx Keys +process (clk_28mhz, key, kb_f_bus, key_f) +begin + if (clk_28mhz'event and clk_28mhz = '1') then + key <= kb_f_bus; + if (kb_f_bus /= key) then + key_f <= key_f xor key; + end if; + end if; +end process; + +-- RTC +mc146818a_wr <= '1' when (port_bff7 = '1' and cpu_wr_n = '0') else '0'; +--mc146818a_rd <= '1' when (port_bff7 = '1' and cpu_rd_n = '0') else '0'; +port_bff7 <= '1' when (cpu_iorq_n = '0' and cpu_a_bus = X"BFF7" and cpu_m1_n = '1' and port_eff7_reg(7) = '1') else '0'; + +-- Z-Controller +--SD_CS_N <= sdcs_n_TS or loader; +SD_CS_N <= sdcs_n_TS; + +-- I2C +i2c_wr <= '1' when (cpu_a_bus(7 downto 5) = "100" and cpu_a_bus(3 downto 0) = "1100" and cpu_wr_n = '0' and cpu_iorq_n = '0') else '0'; -- Port xx8C/xx9C[xxxxxxxx_100n1100] + +SOUND_L <= ("000" & port_xxfe_reg(4) & "0000000") + ("000" & ssg_cn0_a) + ("000" & ssg_cn0_b) + ("000" & ssg_cn1_a) + ("000" & ssg_cn1_b) + ("000" & covox_a) + ("000" & covox_b); +SOUND_R <= ("000" & port_xxfe_reg(4) & "0000000") + ("000" & ssg_cn0_c) + ("000" & ssg_cn0_b) + ("000" & ssg_cn1_c) + ("000" & ssg_cn1_b) + ("000" & covox_c) + ("000" & covox_d); +RESET_OUT<=reset; + +end rtl; \ No newline at end of file diff --git a/src/video/mem/video_cram.mif b/src/video/mem/video_cram.mif new file mode 100644 index 0000000..5322591 --- /dev/null +++ b/src/video/mem/video_cram.mif @@ -0,0 +1,280 @@ +-- Copyright (C) 1991-2007 Altera Corporation +-- Your use of Altera 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 Altera Program License +-- Subscription Agreement, Altera 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 Altera and sold by +-- Altera or its authorized distributors. Please refer to the +-- applicable agreement for further details. + +-- Quartus II generated Memory Initialization File (.mif) + +WIDTH=16; +DEPTH=256; + +ADDRESS_RADIX=HEX; +DATA_RADIX=HEX; + +CONTENT BEGIN + 000 : 0000; + 001 : 0008; + 002 : 0010; + 003 : 0018; + 004 : 2000; + 005 : 2008; + 006 : 2010; + 007 : 2018; + 008 : 4000; + 009 : 4008; + 00A : 4010; + 00B : 4018; + 00C : 6000; + 00D : 6008; + 00E : 6010; + 00F : 6018; + 010 : 0100; + 011 : 0108; + 012 : 0110; + 013 : 0118; + 014 : 2100; + 015 : 2108; + 016 : 2110; + 017 : 2118; + 018 : 4100; + 019 : 4108; + 01A : 4110; + 01B : 4118; + 01C : 6100; + 01D : 6108; + 01E : 6110; + 01F : 6118; + 020 : 0200; + 021 : 0208; + 022 : 0210; + 023 : 0218; + 024 : 2200; + 025 : 2208; + 026 : 2210; + 027 : 2218; + 028 : 4200; + 029 : 4208; + 02A : 4210; + 02B : 4218; + 02C : 6200; + 02D : 6208; + 02E : 6210; + 02F : 6218; + 030 : 0300; + 031 : 0308; + 032 : 0310; + 033 : 0318; + 034 : 2300; + 035 : 2308; + 036 : 2310; + 037 : 2318; + 038 : 4300; + 039 : 4308; + 03A : 4310; + 03B : 4318; + 03C : 6300; + 03D : 6308; + 03E : 6310; + 03F : 6318; + 040 : 0000; + 041 : 0010; + 042 : 4000; + 043 : 4010; + 044 : 0200; + 045 : 0210; + 046 : 4200; + 047 : 4210; + 048 : 2108; + 049 : 0018; + 04A : 6000; + 04B : 6018; + 04C : 0300; + 04D : 0318; + 04E : 6300; + 04F : 6318; + 050 : 0000; + 051 : 0010; + 052 : 4000; + 053 : 4010; + 054 : 0200; + 055 : 0210; + 056 : 4200; + 057 : 4210; + 058 : 0000; + 059 : 0018; + 05A : 6000; + 05B : 6018; + 05C : 0300; + 05D : 0318; + 05E : 6300; + 05F : 6318; + 060 : 0000; + 061 : 0010; + 062 : 4000; + 063 : 4010; + 064 : 0200; + 065 : 0210; + 066 : 4200; + 067 : 4210; + 068 : 2108; + 069 : 0018; + 06A : 6000; + 06B : 6018; + 06C : 0300; + 06D : 0318; + 06E : 6300; + 06F : 6318; + 070 : 0000; + 071 : 0010; + 072 : 4000; + 073 : 4010; + 074 : 0200; + 075 : 0210; + 076 : 4200; + 077 : 4210; + 078 : 0000; + 079 : 0018; + 07A : 6000; + 07B : 6018; + 07C : 0300; + 07D : 0318; + 07E : 6300; + 07F : 6318; + 080 : 0000; + 081 : 0010; + 082 : 4000; + 083 : 4010; + 084 : 0200; + 085 : 0210; + 086 : 4200; + 087 : 4210; + 088 : 2108; + 089 : 0018; + 08A : 6000; + 08B : 6018; + 08C : 0300; + 08D : 0318; + 08E : 6300; + 08F : 6318; + 090 : 0000; + 091 : 0010; + 092 : 4000; + 093 : 4010; + 094 : 0200; + 095 : 0210; + 096 : 4200; + 097 : 4210; + 098 : 0000; + 099 : 0018; + 09A : 6000; + 09B : 6018; + 09C : 0300; + 09D : 0318; + 09E : 6300; + 09F : 6318; + 0A0 : 0000; + 0A1 : 0010; + 0A2 : 4000; + 0A3 : 4010; + 0A4 : 0200; + 0A5 : 0210; + 0A6 : 4200; + 0A7 : 4210; + 0A8 : 2108; + 0A9 : 0018; + 0AA : 6000; + 0AB : 6018; + 0AC : 0300; + 0AD : 0318; + 0AE : 6300; + 0AF : 6318; + 0B0 : 0000; + 0B1 : 0010; + 0B2 : 4000; + 0B3 : 4010; + 0B4 : 0200; + 0B5 : 0210; + 0B6 : 4200; + 0B7 : 4210; + 0B8 : 0000; + 0B9 : 0018; + 0BA : 6000; + 0BB : 6018; + 0BC : 0300; + 0BD : 0318; + 0BE : 6300; + 0BF : 6318; + 0C0 : 0000; + 0C1 : 0010; + 0C2 : 4000; + 0C3 : 4010; + 0C4 : 0200; + 0C5 : 0210; + 0C6 : 4200; + 0C7 : 4210; + 0C8 : 2108; + 0C9 : 0018; + 0CA : 6000; + 0CB : 6018; + 0CC : 0300; + 0CD : 0318; + 0CE : 6300; + 0CF : 6318; + 0D0 : 0000; + 0D1 : 0010; + 0D2 : 4000; + 0D3 : 4010; + 0D4 : 0200; + 0D5 : 0210; + 0D6 : 4200; + 0D7 : 4210; + 0D8 : 0000; + 0D9 : 0018; + 0DA : 6000; + 0DB : 6018; + 0DC : 0300; + 0DD : 0318; + 0DE : 6300; + 0DF : 6318; + 0E0 : 0000; + 0E1 : 0010; + 0E2 : 4000; + 0E3 : 4010; + 0E4 : 0200; + 0E5 : 0210; + 0E6 : 4200; + 0E7 : 4210; + 0E8 : 2108; + 0E9 : 0018; + 0EA : 6000; + 0EB : 6018; + 0EC : 0300; + 0ED : 0318; + 0EE : 6300; + 0EF : 6318; + 0F0 : 0000; + 0F1 : 0010; + 0F2 : 4000; + 0F3 : 4010; + 0F4 : 0200; + 0F5 : 0210; + 0F6 : 4200; + 0F7 : 4210; + 0F8 : 0000; + 0F9 : 0018; + 0FA : 6000; + 0FB : 6018; + 0FC : 0300; + 0FD : 0318; + 0FE : 6300; + 0FF : 6318; +END; diff --git a/src/video/mem/video_cram.qip b/src/video/mem/video_cram.qip new file mode 100644 index 0000000..d1a7891 --- /dev/null +++ b/src/video/mem/video_cram.qip @@ -0,0 +1,3 @@ +set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT" +set_global_assignment -name IP_TOOL_VERSION "11.0" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "video_cram.v"] diff --git a/src/video/mem/video_cram.v b/src/video/mem/video_cram.v new file mode 100644 index 0000000..d3319ac --- /dev/null +++ b/src/video/mem/video_cram.v @@ -0,0 +1,219 @@ +// megafunction wizard: %RAM: 2-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: video_cram.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 11.0 Build 157 04/27/2011 SJ Full Version +// ************************************************************ + + +//Copyright (C) 1991-2011 Altera Corporation +//Your use of Altera 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 Altera Program License +//Subscription Agreement, Altera 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 Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module video_cram ( + clock, + data, + rdaddress, + wraddress, + wren, + q); + + input clock; + input [14:0] data; + input [7:0] rdaddress; + input [7:0] wraddress; + input wren; + output [14:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri0 wren; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [14:0] sub_wire0; + wire [14:0] q = sub_wire0[14:0]; + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({15{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.init_file = "src/video/mem/video_cram.mif", + altsyncram_component.intended_device_family = "Cyclone IV E", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 256, + altsyncram_component.numwords_b = 256, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + altsyncram_component.widthad_a = 8, + altsyncram_component.widthad_b = 8, + altsyncram_component.width_a = 15, + altsyncram_component.width_b = 15, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLRdata NUMERIC "0" +// Retrieval info: PRIVATE: CLRq NUMERIC "0" +// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRrren NUMERIC "0" +// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRwren NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "0" +// Retrieval info: PRIVATE: Clock_A NUMERIC "0" +// Retrieval info: PRIVATE: Clock_B NUMERIC "0" +// Retrieval info: PRIVATE: ECC NUMERIC "0" +// Retrieval info: PRIVATE: ECC_PIPELINE_STAGE NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MEMSIZE NUMERIC "3840" +// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "../rtl/ts/video/mem/video_cram.mif" +// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +// Retrieval info: PRIVATE: REGdata NUMERIC "1" +// Retrieval info: PRIVATE: REGq NUMERIC "0" +// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +// Retrieval info: PRIVATE: REGrren NUMERIC "1" +// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +// Retrieval info: PRIVATE: REGwren NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +// Retrieval info: PRIVATE: VarWidth NUMERIC "0" +// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "15" +// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "15" +// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "15" +// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "15" +// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: enable NUMERIC "0" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: INIT_FILE STRING "../rtl/ts/video/mem/video_cram.mif" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" +// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "256" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" +// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "15" +// Retrieval info: CONSTANT: WIDTH_B NUMERIC "15" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 15 0 INPUT NODEFVAL "data[14..0]" +// Retrieval info: USED_PORT: q 0 0 15 0 OUTPUT NODEFVAL "q[14..0]" +// Retrieval info: USED_PORT: rdaddress 0 0 8 0 INPUT NODEFVAL "rdaddress[7..0]" +// Retrieval info: USED_PORT: wraddress 0 0 8 0 INPUT NODEFVAL "wraddress[7..0]" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +// Retrieval info: CONNECT: @address_a 0 0 8 0 wraddress 0 0 8 0 +// Retrieval info: CONNECT: @address_b 0 0 8 0 rdaddress 0 0 8 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 15 0 data 0 0 15 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 15 0 @q_b 0 0 15 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_bb.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_waveforms.html FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_cram_wave*.jpg FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/src/video/mem/video_sfile.v b/src/video/mem/video_sfile.v new file mode 100644 index 0000000..80d1161 --- /dev/null +++ b/src/video/mem/video_sfile.v @@ -0,0 +1,217 @@ +// megafunction wizard: %RAM: 2-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: video_sfile.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 11.0 Build 208 07/03/2011 SP 1 SJ Full Version +// ************************************************************ + + +//Copyright (C) 1991-2011 Altera Corporation +//Your use of Altera 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 Altera Program License +//Subscription Agreement, Altera 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 Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module video_sfile ( + clock, + data, + rdaddress, + wraddress, + wren, + q); + + input clock; + input [15:0] data; + input [7:0] rdaddress; + input [7:0] wraddress; + input wren; + output [15:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri0 wren; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [15:0] sub_wire0; + wire [15:0] q = sub_wire0[15:0]; + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({16{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone IV E", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 256, + altsyncram_component.numwords_b = 256, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "CLOCK0", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + altsyncram_component.widthad_a = 8, + altsyncram_component.widthad_b = 8, + altsyncram_component.width_a = 16, + altsyncram_component.width_b = 16, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLRdata NUMERIC "0" +// Retrieval info: PRIVATE: CLRq NUMERIC "0" +// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRrren NUMERIC "0" +// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRwren NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "0" +// Retrieval info: PRIVATE: Clock_A NUMERIC "0" +// Retrieval info: PRIVATE: Clock_B NUMERIC "0" +// Retrieval info: PRIVATE: ECC NUMERIC "0" +// Retrieval info: PRIVATE: ECC_PIPELINE_STAGE NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MEMSIZE NUMERIC "4096" +// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "" +// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +// Retrieval info: PRIVATE: REGdata NUMERIC "1" +// Retrieval info: PRIVATE: REGq NUMERIC "1" +// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +// Retrieval info: PRIVATE: REGrren NUMERIC "1" +// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +// Retrieval info: PRIVATE: REGwren NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +// Retrieval info: PRIVATE: VarWidth NUMERIC "0" +// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "16" +// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: enable NUMERIC "0" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" +// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "256" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" +// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_B NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]" +// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]" +// Retrieval info: USED_PORT: rdaddress 0 0 8 0 INPUT NODEFVAL "rdaddress[7..0]" +// Retrieval info: USED_PORT: wraddress 0 0 8 0 INPUT NODEFVAL "wraddress[7..0]" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +// Retrieval info: CONNECT: @address_a 0 0 8 0 wraddress 0 0 8 0 +// Retrieval info: CONNECT: @address_b 0 0 8 0 rdaddress 0 0 8 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 16 0 @q_b 0 0 16 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL video_sfile.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_sfile.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_sfile.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_sfile.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_sfile_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_sfile_bb.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_sfile_waveforms.html FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_sfile_wave*.jpg FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/src/video/mem/video_tmbuf.v b/src/video/mem/video_tmbuf.v new file mode 100644 index 0000000..3ae8130 --- /dev/null +++ b/src/video/mem/video_tmbuf.v @@ -0,0 +1,217 @@ +// megafunction wizard: %RAM: 2-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: video_tmbuf.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 11.0 Build 208 07/03/2011 SP 1 SJ Full Version +// ************************************************************ + + +//Copyright (C) 1991-2011 Altera Corporation +//Your use of Altera 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 Altera Program License +//Subscription Agreement, Altera 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 Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module video_tmbuf ( + clock, + data, + rdaddress, + wraddress, + wren, + q); + + input clock; + input [15:0] data; + input [8:0] rdaddress; + input [8:0] wraddress; + input wren; + output [15:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri0 wren; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [15:0] sub_wire0; + wire [15:0] q = sub_wire0[15:0]; + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({16{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone IV E", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 512, + altsyncram_component.numwords_b = 512, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "CLOCK0", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + altsyncram_component.widthad_a = 9, + altsyncram_component.widthad_b = 9, + altsyncram_component.width_a = 16, + altsyncram_component.width_b = 16, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLRdata NUMERIC "0" +// Retrieval info: PRIVATE: CLRq NUMERIC "0" +// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRrren NUMERIC "0" +// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRwren NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "0" +// Retrieval info: PRIVATE: Clock_A NUMERIC "0" +// Retrieval info: PRIVATE: Clock_B NUMERIC "0" +// Retrieval info: PRIVATE: ECC NUMERIC "0" +// Retrieval info: PRIVATE: ECC_PIPELINE_STAGE NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MEMSIZE NUMERIC "8192" +// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "" +// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +// Retrieval info: PRIVATE: REGdata NUMERIC "1" +// Retrieval info: PRIVATE: REGq NUMERIC "1" +// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +// Retrieval info: PRIVATE: REGrren NUMERIC "1" +// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +// Retrieval info: PRIVATE: REGwren NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +// Retrieval info: PRIVATE: VarWidth NUMERIC "0" +// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "16" +// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "16" +// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: enable NUMERIC "0" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "512" +// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "512" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "9" +// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "9" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_B NUMERIC "16" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]" +// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]" +// Retrieval info: USED_PORT: rdaddress 0 0 9 0 INPUT NODEFVAL "rdaddress[8..0]" +// Retrieval info: USED_PORT: wraddress 0 0 9 0 INPUT NODEFVAL "wraddress[8..0]" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +// Retrieval info: CONNECT: @address_a 0 0 9 0 wraddress 0 0 9 0 +// Retrieval info: CONNECT: @address_b 0 0 9 0 rdaddress 0 0 9 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 16 0 @q_b 0 0 16 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tmbuf.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tmbuf.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tmbuf.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tmbuf.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tmbuf_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tmbuf_bb.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tmbuf_waveforms.html FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tmbuf_wave*.jpg FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/src/video/mem/video_tsline0.v b/src/video/mem/video_tsline0.v new file mode 100644 index 0000000..92c4f30 --- /dev/null +++ b/src/video/mem/video_tsline0.v @@ -0,0 +1,216 @@ +// megafunction wizard: %RAM: 2-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: video_tsline0.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 10.1 Build 153 11/29/2010 SJ Full Version +// ************************************************************ + + +//Copyright (C) 1991-2010 Altera Corporation +//Your use of Altera 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 Altera Program License +//Subscription Agreement, Altera 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 Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module video_tsline0 ( + clock, + data, + rdaddress, + wraddress, + wren, + q); + + input clock; + input [7:0] data; + input [8:0] rdaddress; + input [8:0] wraddress; + input wren; + output [7:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri0 wren; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [7:0] sub_wire0; + wire [7:0] q = sub_wire0[7:0]; + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({8{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone IV E", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 512, + altsyncram_component.numwords_b = 512, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + 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; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLRdata NUMERIC "0" +// Retrieval info: PRIVATE: CLRq NUMERIC "0" +// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRrren NUMERIC "0" +// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRwren NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "0" +// Retrieval info: PRIVATE: Clock_A NUMERIC "0" +// Retrieval info: PRIVATE: Clock_B NUMERIC "0" +// Retrieval info: PRIVATE: ECC NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MEMSIZE NUMERIC "4096" +// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "" +// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +// Retrieval info: PRIVATE: REGdata NUMERIC "1" +// Retrieval info: PRIVATE: REGq NUMERIC "0" +// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +// Retrieval info: PRIVATE: REGrren NUMERIC "1" +// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +// Retrieval info: PRIVATE: REGwren NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +// Retrieval info: PRIVATE: VarWidth NUMERIC "0" +// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8" +// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8" +// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8" +// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8" +// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: enable NUMERIC "0" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "512" +// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "512" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "9" +// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "9" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_B NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]" +// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]" +// Retrieval info: USED_PORT: rdaddress 0 0 9 0 INPUT NODEFVAL "rdaddress[8..0]" +// Retrieval info: USED_PORT: wraddress 0 0 9 0 INPUT NODEFVAL "wraddress[8..0]" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +// Retrieval info: CONNECT: @address_a 0 0 9 0 wraddress 0 0 9 0 +// Retrieval info: CONNECT: @address_b 0 0 9 0 rdaddress 0 0 9 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline0.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline0.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline0.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline0.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline0_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline0_bb.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline0_waveforms.html FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline0_wave*.jpg FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/src/video/mem/video_tsline1.v b/src/video/mem/video_tsline1.v new file mode 100644 index 0000000..bdf5ef6 --- /dev/null +++ b/src/video/mem/video_tsline1.v @@ -0,0 +1,216 @@ +// megafunction wizard: %RAM: 2-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: video_tsline1.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 10.1 Build 153 11/29/2010 SJ Full Version +// ************************************************************ + + +//Copyright (C) 1991-2010 Altera Corporation +//Your use of Altera 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 Altera Program License +//Subscription Agreement, Altera 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 Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module video_tsline1 ( + clock, + data, + rdaddress, + wraddress, + wren, + q); + + input clock; + input [7:0] data; + input [8:0] rdaddress; + input [8:0] wraddress; + input wren; + output [7:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri0 wren; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [7:0] sub_wire0; + wire [7:0] q = sub_wire0[7:0]; + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({8{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone IV E", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 512, + altsyncram_component.numwords_b = 512, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "UNREGISTERED", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + 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; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLRdata NUMERIC "0" +// Retrieval info: PRIVATE: CLRq NUMERIC "0" +// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRrren NUMERIC "0" +// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRwren NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "0" +// Retrieval info: PRIVATE: Clock_A NUMERIC "0" +// Retrieval info: PRIVATE: Clock_B NUMERIC "0" +// Retrieval info: PRIVATE: ECC NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MEMSIZE NUMERIC "4096" +// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "" +// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +// Retrieval info: PRIVATE: REGdata NUMERIC "1" +// Retrieval info: PRIVATE: REGq NUMERIC "0" +// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +// Retrieval info: PRIVATE: REGrren NUMERIC "1" +// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +// Retrieval info: PRIVATE: REGwren NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +// Retrieval info: PRIVATE: VarWidth NUMERIC "0" +// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8" +// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8" +// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8" +// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8" +// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: enable NUMERIC "0" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "512" +// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "512" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "9" +// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "9" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_B NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]" +// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]" +// Retrieval info: USED_PORT: rdaddress 0 0 9 0 INPUT NODEFVAL "rdaddress[8..0]" +// Retrieval info: USED_PORT: wraddress 0 0 9 0 INPUT NODEFVAL "wraddress[8..0]" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +// Retrieval info: CONNECT: @address_a 0 0 9 0 wraddress 0 0 9 0 +// Retrieval info: CONNECT: @address_b 0 0 9 0 rdaddress 0 0 9 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline1.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline1.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline1.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline1.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline1_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline1_bb.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline1_waveforms.html FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_tsline1_wave*.jpg FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/src/video/mem/video_vmem.qip b/src/video/mem/video_vmem.qip new file mode 100644 index 0000000..00d0a83 --- /dev/null +++ b/src/video/mem/video_vmem.qip @@ -0,0 +1,3 @@ +set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT" +set_global_assignment -name IP_TOOL_VERSION "11.0" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "video_vmem.v"] diff --git a/src/video/mem/video_vmem.v b/src/video/mem/video_vmem.v new file mode 100644 index 0000000..d83888b --- /dev/null +++ b/src/video/mem/video_vmem.v @@ -0,0 +1,217 @@ +// megafunction wizard: %RAM: 2-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: video_vmem.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 11.0 Build 157 04/27/2011 SJ Full Version +// ************************************************************ + + +//Copyright (C) 1991-2011 Altera Corporation +//Your use of Altera 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 Altera Program License +//Subscription Agreement, Altera 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 Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module video_vmem ( + clock, + data, + rdaddress, + wraddress, + wren, + q); + + input clock; + input [7:0] data; + input [9:0] rdaddress; + input [9:0] wraddress; + input wren; + output [7:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; + tri0 wren; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [7:0] sub_wire0; + wire [7:0] q = sub_wire0[7:0]; + + altsyncram altsyncram_component ( + .address_a (wraddress), + .clock0 (clock), + .data_a (data), + .wren_a (wren), + .address_b (rdaddress), + .q_b (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({8{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_b = "NONE", + altsyncram_component.address_reg_b = "CLOCK0", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.intended_device_family = "Cyclone IV E", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 1024, + altsyncram_component.numwords_b = 1024, + altsyncram_component.operation_mode = "DUAL_PORT", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_b = "CLOCK0", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE", + altsyncram_component.widthad_a = 10, + altsyncram_component.widthad_b = 10, + altsyncram_component.width_a = 8, + altsyncram_component.width_b = 8, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "1" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLRdata NUMERIC "0" +// Retrieval info: PRIVATE: CLRq NUMERIC "0" +// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRrren NUMERIC "0" +// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRwren NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "0" +// Retrieval info: PRIVATE: Clock_A NUMERIC "0" +// Retrieval info: PRIVATE: Clock_B NUMERIC "0" +// Retrieval info: PRIVATE: ECC NUMERIC "0" +// Retrieval info: PRIVATE: ECC_PIPELINE_STAGE NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MEMSIZE NUMERIC "8192" +// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "" +// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2" +// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +// Retrieval info: PRIVATE: REGdata NUMERIC "1" +// Retrieval info: PRIVATE: REGq NUMERIC "1" +// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1" +// Retrieval info: PRIVATE: REGrren NUMERIC "1" +// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +// Retrieval info: PRIVATE: REGwren NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +// Retrieval info: PRIVATE: VarWidth NUMERIC "0" +// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8" +// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8" +// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8" +// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8" +// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0" +// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: enable NUMERIC "0" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "1024" +// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "1024" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK0" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "10" +// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "10" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_B NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]" +// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]" +// Retrieval info: USED_PORT: rdaddress 0 0 10 0 INPUT NODEFVAL "rdaddress[9..0]" +// Retrieval info: USED_PORT: wraddress 0 0 10 0 INPUT NODEFVAL "wraddress[9..0]" +// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren" +// Retrieval info: CONNECT: @address_a 0 0 10 0 wraddress 0 0 10 0 +// Retrieval info: CONNECT: @address_b 0 0 10 0 rdaddress 0 0 10 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL video_vmem.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_vmem.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_vmem.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_vmem.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_vmem_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_vmem_bb.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_vmem_waveforms.html FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL video_vmem_wave*.jpg FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/src/video/video_fetch.v b/src/video/video_fetch.v new file mode 100644 index 0000000..63d9b39 --- /dev/null +++ b/src/video/video_fetch.v @@ -0,0 +1,38 @@ +// This module fetches video data from DRAM + +module video_fetch ( + +// clocks + input wire clk, + +// control + input wire [3:0] f_sel, + input wire [1:0] b_sel, + input wire fetch_stb, + +// video data + output reg [31:0] fetch_data, + output reg [31:0] fetch_temp, + +// DRAM interface + input wire video_strobe, + input wire [15:0] video_data + +); + + +// fetching data + + always @(posedge clk) if (video_strobe) + begin + if (f_sel[0]) fetch_temp[ 7: 0] <= b_sel[0] ? video_data[15:8] : video_data[ 7:0]; + if (f_sel[1]) fetch_temp[15: 8] <= b_sel[1] ? video_data[15:8] : video_data[ 7:0]; + if (f_sel[2]) fetch_temp[23:16] <= video_data[ 7:0]; + if (f_sel[3]) fetch_temp[31:24] <= video_data[15:8]; + end + + + always @(posedge clk) if (fetch_stb) + fetch_data <= fetch_temp; + +endmodule \ No newline at end of file diff --git a/src/video/video_mode.v b/src/video/video_mode.v new file mode 100644 index 0000000..19abc63 --- /dev/null +++ b/src/video/video_mode.v @@ -0,0 +1,232 @@ + +// This module decodes video modes + +module video_mode ( + +// clocks + input wire clk, f1, c3, + +// video config + input wire [7:0] vpage, + input wire [7:0] vconf, + input wire v60hz, + +// video parameters & mode controls + input wire [8:0] gx_offs, + output wire [9:0] x_offs_mode, + output wire [8:0] hpix_beg, + output wire [8:0] hpix_end, + output wire [8:0] vpix_beg, + output wire [8:0] vpix_end, + output wire [5:0] x_tiles, + output wire [4:0] go_offs, + output wire [3:0] fetch_sel, + output wire [1:0] fetch_bsl, + input wire [3:0] fetch_cnt, + input wire pix_start, + input wire line_start_s, + output wire tv_hires, + output reg vga_hires, + output wire [1:0] render_mode, + output wire pix_stb, + output wire fetch_stb, + +// video data + input wire [15:0] txt_char, + +// video counters + input wire [7:0] cnt_col, + input wire [8:0] cnt_row, + input wire cptr, + +// DRAM interface + output wire [20:0] video_addr, + output wire [ 4:0] video_bw +); + + + wire [1:0] vmod = vconf[1:0]; + wire [1:0] rres = vconf[7:6]; + +// clocking strobe for pixels (TV) + assign pix_stb = tv_hires ? f1 : c3; + + always @(posedge clk) + if (line_start_s) + vga_hires <= tv_hires; + +// Modes + localparam M_ZX = 2'h0; // ZX + localparam M_HC = 2'h1; // 16c + localparam M_XC = 2'h2; // 256c + localparam M_TX = 2'h3; // Text + + +// Render modes (affects 'video_render.v') + localparam R_ZX = 2'h0; + localparam R_HC = 2'h1; + localparam R_XC = 2'h2; + localparam R_TX = 2'h3; + + +// fetch strobes + wire ftch[0:3]; + assign fetch_stb = (pix_start | ftch[render_mode]) && c3; + assign ftch[R_ZX] = &fetch_cnt[3:0]; + assign ftch[R_HC] = &fetch_cnt[1:0]; + assign ftch[R_XC] = fetch_cnt[0]; + assign ftch[R_TX] = &fetch_cnt[3:0]; + + +// fetch window + wire [4:0] g_offs[0:3]; + // these values are from a thin air!!! recheck them occasionally! + assign g_offs[M_ZX] = 5'd18; + assign g_offs[M_HC] = 5'd6; + assign g_offs[M_XC] = 5'd4; + assign g_offs[M_TX] = 5'd10; + assign go_offs = g_offs[vmod]; + + +// fetch selectors +// Attention: counter is already incremented at the time of video data fetching! + + // wire m_c = (vmod == M_HC) | (vmod == M_XC); + // assign fetch_sel = vmod == M_TX ? f_txt_sel[cnt_col[1:0]] : {~cptr, ~cptr, cptr | m_c, cptr | m_c}; + + // wire [3:0] f_sel[0:7]; + wire [3:0] f_sel[0:3]; + assign f_sel[M_ZX] = {~cptr, ~cptr, cptr, cptr}; + assign f_sel[M_HC] = {~cptr, ~cptr, 2'b11}; + assign f_sel[M_XC] = {~cptr, ~cptr, 2'b11}; + assign f_sel[M_TX] = f_txt_sel[cnt_col[1:0]]; + assign fetch_sel = f_sel[vmod]; + + assign fetch_bsl = (vmod == M_TX) ? f_txt_bsl[cnt_col[1:0]] : 2'b10; + + // wire [1:0] f_bsl[0:7]; + // assign f_bsl[M_ZX] = 2'b10; + // assign f_bsl[M_HC] = 2'b10; + // assign f_bsl[M_XC] = 2'b10; + // assign f_bsl[M_TX] = f_txt_bsl[cnt_col[1:0]]; + // assign fetch_bsl = f_bsl[vmod]; + + wire [3:0] f_txt_sel[0:3]; + assign f_txt_sel[1] = 4'b0011; // char + assign f_txt_sel[2] = 4'b1100; // attr + assign f_txt_sel[3] = 4'b0001; // gfx0 + assign f_txt_sel[0] = 4'b0010; // gfx1 + + wire [1:0] f_txt_bsl[0:3]; + assign f_txt_bsl[1] = 2'b10; // char + assign f_txt_bsl[2] = 2'b10; // attr + assign f_txt_bsl[3] = {2{cnt_row[0]}}; // gfx0 + assign f_txt_bsl[0] = {2{cnt_row[0]}}; // gfx1 + + +// X offset + assign x_offs_mode = {vmod == M_XC ? {gx_offs[8:1], 1'b0} : {1'b0, gx_offs[8:1]}, gx_offs[0]}; + + +// DRAM bandwidth usage + localparam BW2 = 2'b00; + localparam BW4 = 2'b01; + localparam BW8 = 2'b11; + + localparam BU1 = 3'b001; + localparam BU2 = 3'b010; + localparam BU4 = 3'b100; + + // [4:3] - total cycles: 11 = 8 / 01 = 4 / 00 = 2 + // [2:0] - need cycles + wire [4:0] bw[0:3]; + assign bw[M_ZX] = {BW8, BU1}; // '1 of 8' (ZX) + assign bw[M_HC] = {BW4, BU1}; // '1 of 4' (16c) + assign bw[M_XC] = {BW2, BU1}; // '1 of 2' (256c) + assign bw[M_TX] = {BW8, BU4}; // '4 of 8' (text) + assign video_bw = bw[vmod]; + + +// pixelrate + wire [3:0] pixrate = 4'b1000; // change these if you change the modes indexes! + assign tv_hires = pixrate[vmod]; + + +// render mode + // wire [1:0] r_mode[0:7]; + wire [1:0] r_mode[0:3]; + assign r_mode[M_ZX] = R_ZX; + assign r_mode[M_HC] = R_HC; + assign r_mode[M_XC] = R_XC; + assign r_mode[M_TX] = R_TX; + assign render_mode = r_mode[vmod]; + + +// raster resolution + wire [8:0] hp_beg[0:3]; + wire [8:0] hp_end[0:3]; + wire [8:0] vp_beg[0:3]; + wire [8:0] vp_end[0:3]; + wire [5:0] x_tile[0:3]; + + assign hp_beg[0] = 9'd140; // 256 (88-52-256-52) + assign hp_beg[1] = 9'd108; // 320 (88-20-320-20) + assign hp_beg[2] = 9'd108; // 320 (88-20-320-20) + assign hp_beg[3] = 9'd88; // 360 (88-0-360-0) + + assign hp_end[0] = 9'd396; // 256 + assign hp_end[1] = 9'd428; // 320 + assign hp_end[2] = 9'd428; // 320 + assign hp_end[3] = 9'd448; // 360 + + assign vp_beg[0] = v60hz ? 9'd046 : 9'd080; // 192 (22-24-192-24)/(32-48-192-48) (blank-border-pixels-border) + assign vp_beg[1] = v60hz ? 9'd042 : 9'd076; // 200 (22-20-200-20)/(32-44-200-44) + assign vp_beg[2] = v60hz ? 9'd022 : 9'd056; // 240 (22-0-240-0)/(32-24-240-24) + assign vp_beg[3] = v60hz ? 9'd022 : 9'd032; // 288 (22-0-240-0)/(32-0-288-0) + + assign vp_end[0] = v60hz ? 9'd238 : 9'd272; // 192 + assign vp_end[1] = v60hz ? 9'd242 : 9'd276; // 200 + assign vp_end[2] = v60hz ? 9'd262 : 9'd296; // 240 + assign vp_end[3] = v60hz ? 9'd262 : 9'd320; // 240/288 + + assign x_tile[0] = 6'd34; // 256 + assign x_tile[1] = 6'd42; // 320 + assign x_tile[2] = 6'd42; // 320 + assign x_tile[3] = 6'd47; // 360 + + assign hpix_beg = hp_beg[rres]; + assign hpix_end = hp_end[rres]; + assign vpix_beg = vp_beg[rres]; + assign vpix_end = vp_end[rres]; + assign x_tiles = x_tile[rres]; + + +// videomode addresses + wire [20:0] v_addr[0:3]; + assign v_addr[M_ZX] = addr_zx; + assign v_addr[M_HC] = addr_16c; + assign v_addr[M_XC] = addr_256c; + assign v_addr[M_TX] = addr_text; + assign video_addr = v_addr[vmod]; + + // ZX + wire [20:0] addr_zx = {vpage, 1'b0, ~cnt_col[0] ? addr_zx_gfx : addr_zx_atr}; + wire [11:0] addr_zx_gfx = {cnt_row[7:6], cnt_row[2:0], cnt_row[5:3], cnt_col[4:1]}; + wire [11:0] addr_zx_atr = {3'b110, cnt_row[7:3], cnt_col[4:1]}; + + // 16c + wire [20:0] addr_16c = {vpage[7:3], cnt_row, cnt_col[6:0]}; + + // 256c + wire [20:0] addr_256c = {vpage[7:4], cnt_row, cnt_col[7:0]}; + + // Textmode + wire [20:0] addr_text = {vpage[7:1], addr_tx[cnt_col[1:0]]}; + wire [13:0] addr_tx[0:3]; + assign addr_tx[0] = {vpage[0], cnt_row[8:3], 1'b0, cnt_col[7:2]}; // char codes, data[15:0] + assign addr_tx[1] = {vpage[0], cnt_row[8:3], 1'b1, cnt_col[7:2]}; // char attributes, data[31:16] + assign addr_tx[2] = {~vpage[0], 3'b000, (txt_char[7:0]), cnt_row[2:1]}; // char0 graphics, data[7:0] + assign addr_tx[3] = {~vpage[0], 3'b000, (txt_char[15:8]), cnt_row[2:1]}; // char1 graphics, data[15:8] + + +endmodule diff --git a/src/video/video_out.v b/src/video/video_out.v new file mode 100644 index 0000000..895a66c --- /dev/null +++ b/src/video/video_out.v @@ -0,0 +1,75 @@ + +// This module generates video for DAC +// MVV corrected 24bpp 24.08.2014 + +module video_out ( + +// clocks + input wire clk, f0, c3, + +// video controls + input wire vga_on, + input wire tv_blank, + input wire vga_blank, + input wire [1:0] plex_sel_in, + +// mode controls + input wire tv_hires, + input wire vga_hires, + input wire [3:0] palsel, + +// Z80 pins + input wire [14:0] cram_data_in, + input wire [7:0] cram_addr_in, + input wire cram_we, + +// video data + input wire [7:0] vplex_in, //<====== INPUT + input wire [7:0] vgaplex, //<====== INPUT VGA + + output wire [7:0] vred, + output wire [7:0] vgrn, + output wire [7:0] vblu, + //--------------------- + output wire [3:0] tst +); + + assign tst[0] = clk; ////phase[0]; + assign tst[1] = cram_we; //phase[1]; + assign tst[2] = cram_addr_in[0]; // + assign tst[3] = cram_data_in[0]; //pwm[3][{phase, 1'b0}]; //!pwm[igrn][{phase, 1'b1}]; + + + // TV/VGA mux + reg [7:0] vplex; + always @(posedge clk) if (c3) vplex <= vplex_in; + + wire [7:0] plex = vga_on ? vgaplex : vplex; + wire plex_sel = vga_on ? plex_sel_in[0] : plex_sel_in[1]; + wire hires = vga_on ? vga_hires : tv_hires; + wire [7:0] vdata = hires ? {palsel, plex_sel ? plex[3:0] : plex[7:4]} : plex; + + // CRAM ===================================================================== + wire [14:0] vpixel; + + video_cram video_cram( + .clock (clk), + .wraddress(cram_addr_in), + .data (cram_data_in), + .wren (cram_we), + .rdaddress(vdata), //-= HSYNC_BEG) && (hcount < HSYNC_END); + wire vs = (vcount >= vsync_beg) && (vcount < vsync_end); + + assign tv_hblank = (hcount > HBLNK_BEG) && (hcount <= HBLNK_END); + assign tv_vblank = (vcount >= vblnk_beg) && (vcount < vblnk_end); + + wire vga_hblank1 = (cnt_out > 9'd359); + always @(posedge clk) if (f1) // fix me - bydlocode !!! + vga_hblank <= vga_hblank1; + + wire hs_vga = ((hcount >= HSYNCV_BEG) && (hcount < HSYNCV_END)) || + ((hcount >= (HSYNCV_BEG + HPERIOD/2)) && (hcount < (HSYNCV_END + HPERIOD/2))); + + wire vga_pix_start = ((hcount == (HBLNKV_END)) || (hcount == (HBLNKV_END + HPERIOD/2))); + + assign vga_line = (hcount >= HPERIOD/2); + + assign hvpix = hpix && vpix; + + assign hpix = (hcount >= hpix_beg) && (hcount < hpix_end); + + assign vpix = (vcount >= vpix_beg) && (vcount < vpix_end); // vertical pixels window + assign v_ts = (vcount >= (vpix_beg - 1)) && (vcount < (vpix_end - 1)); // vertical TS window + assign v_pf = (vcount >= (vpix_beg - 17)) && (vcount < (vpix_end - 9)); // vertical tilemap prefetch window + + always @(posedge clk) + video_go <= (hcount >= (hpix_beg - go_offs - x_offs)) && (hcount < (hpix_end - go_offs - x_offs + 4)) && vpix && !nogfx; + + wire line_start = hcount == (HPERIOD - 1); + assign line_start_s = line_start && c3; + wire line_start2 = hcount == (HSYNC_END - 1); + assign frame_start = line_start && (vcount == (vperiod - 1)); + wire vis_start = line_start && (vcount == (vblnk_end - 1)); + assign pix_start = hcount == (hpix_beg - x_offs - 1); + wire ts_start_coarse = hcount == (hpix_beg - 1); + assign ts_start = c3 && ts_start_coarse; + assign int_start = (hcount == {hint_beg, 1'b0}) && (vcount == vint_beg) && c0; + + + always @(posedge clk) if (line_start_s) // fix me - bydlocode !!! + vga_vblank <= tv_vblank; + + + always @(posedge clk) + begin + hsync <= sync_pol ^ (vga_on ? hs_vga : hs); + vsync <= sync_pol ^ vs; + csync <= ~(vs ^ hs); + end + + +endmodule diff --git a/src/video/video_top.v b/src/video/video_top.v new file mode 100644 index 0000000..4682eaf --- /dev/null +++ b/src/video/video_top.v @@ -0,0 +1,500 @@ + +// This module is a video top-level + + +module video_top +( + // clocks + input wire clk, + input wire f0, f1, + input wire h0, h1, + input wire c0, c1, c2, c3, + // input wire t0, // debug!!! + + // video DAC + output wire [7:0] vred, + output wire [7:0] vgrn, + output wire [7:0] vblu, + + // video syncs + output wire hsync, + output wire vsync, + output wire csync, + output wire hblank, + output wire vblank, + output wire pix_stb, + + // Z80 controls + input wire [15:0] a, + input wire [ 7:0] d, + input wire [15:0] zmd, + input wire [ 7:0] zma, + input wire cram_we, + input wire sfile_we, + + // port write strobes + input wire zborder_wr, + input wire border_wr, + input wire zvpage_wr, + input wire vpage_wr, + input wire vconf_wr, + input wire gx_offsl_wr, + input wire gx_offsh_wr, + input wire gy_offsl_wr, + input wire gy_offsh_wr, + input wire t0x_offsl_wr, + input wire t0x_offsh_wr, + input wire t0y_offsl_wr, + input wire t0y_offsh_wr, + input wire t1x_offsl_wr, + input wire t1x_offsh_wr, + input wire t1y_offsl_wr, + input wire t1y_offsh_wr, + input wire tsconf_wr, + input wire palsel_wr, + input wire tmpage_wr, + input wire t0gpage_wr, + input wire t1gpage_wr, + input wire sgpage_wr, + input wire hint_beg_wr , + input wire vint_begl_wr, + input wire vint_begh_wr, + + // ZX controls + input wire res, + output wire int_start, + output wire line_start_s, + + // DRAM interface + output wire [20:0] video_addr, + output wire [ 4:0] video_bw, + output wire video_go, + input wire [15:0] dram_rdata, // raw, should be latched by c2 (video_next) + input wire video_next, + input wire video_pre_next, + input wire next_video, + input wire video_strobe, + input wire video_next_strobe, + output wire [20:0] ts_addr, + output wire ts_req, + output wire ts_z80_lp, + input wire ts_pre_next, + input wire ts_next, + output wire [20:0] tm_addr, + output wire tm_req, + input wire tm_next, + + // video controls + input wire cfg_60hz, + input wire sync_pol, + input wire vga_on, + + output wire [3:0] tst +); + + // wire [2:0] tst; + + + assign ts_z80_lp = tsconf[4]; + +// video config + wire [7:0] vpage; // re-latched at line_start + wire [7:0] vconf; // + wire [8:0] gx_offs; // + wire [8:0] gy_offs; // + wire [7:0] palsel; // + wire [8:0] t0x_offs; // + wire [8:0] t1x_offs; // + wire [7:0] t0gpage; // + wire [7:0] t1gpage; // + wire [7:0] sgpage; // * not yet !!! + wire [8:0] t0y_offs; + wire [8:0] t1y_offs; + wire [7:0] tsconf; + wire [7:0] tmpage; + wire [7:0] hint_beg; + wire [8:0] vint_beg; + wire [8:0] hpix_beg; + wire [8:0] hpix_end; + wire [8:0] vpix_beg; + wire [8:0] vpix_end; + wire [5:0] x_tiles; + wire [9:0] x_offs_mode; + wire [4:0] go_offs; + wire [1:0] render_mode; + wire tv_hires; + wire vga_hires; + wire v60hz; + //===zx-evo-fpga-564db5e984ef === + wire nogfx = vconf[5]; + wire notsu = vconf[4]; + wire gfxovr = vconf[3]; + //wire gfxovr; + //=============================== + wire tv_hblank; + wire tv_vblank; + wire vga_hblank; + wire vga_vblank; + +// counters + wire [7:0] cnt_col; + wire [8:0] cnt_row; + wire cptr; + wire [3:0] scnt; + wire [8:0] lcount; + +// synchro + wire pix_start; + wire tv_pix_start; + wire vga_pix_start; + wire ts_start; + wire v_ts; + wire v_pf; + wire hpix; + wire vpix; + wire hvpix; + wire flash; + +// fetcher + wire [31:0] fetch_data; + wire [31:0] fetch_temp; + wire [3:0] fetch_sel; + wire [1:0] fetch_bsl; + wire fetch_stb; + +// video data + wire [7:0] border; + wire [7:0] vplex; + wire [7:0] vgaplex; + +// TS + wire tsr_go; + wire [5:0] tsr_addr; + wire [8:0] tsr_line; + wire [7:0] tsr_page; + wire [8:0] tsr_x; + wire [2:0] tsr_xs; + wire tsr_xf; + wire [3:0] tsr_pal; + wire tsr_rdy; + +// TS-line + // wire [8:0] ts_waddr = a[8:0]; + // wire [7:0] ts_wdata = {d[7:1], 1'b1}; + // wire ts_we = c3; + wire [8:0] ts_waddr; + wire [7:0] ts_wdata; + wire ts_we; + wire [8:0] ts_raddr; + +// VGA-line + wire [9:0] vga_cnt_in; + wire [9:0] vga_cnt_out; + + video_ports video_ports ( + .clk (clk), + .d (d), + .res (res), + .line_start_s (line_start_s), + .border_wr (border_wr), + .zborder_wr (zborder_wr), + .zvpage_wr (zvpage_wr), + .vpage_wr (vpage_wr), + .vconf_wr (vconf_wr), + .gx_offsl_wr (gx_offsl_wr), + .gx_offsh_wr (gx_offsh_wr), + .gy_offsl_wr (gy_offsl_wr), + .gy_offsh_wr (gy_offsh_wr), + .t0x_offsl_wr (t0x_offsl_wr), + .t0x_offsh_wr (t0x_offsh_wr), + .t0y_offsl_wr (t0y_offsl_wr), + .t0y_offsh_wr (t0y_offsh_wr), + .t1x_offsl_wr (t1x_offsl_wr), + .t1x_offsh_wr (t1x_offsh_wr), + .t1y_offsl_wr (t1y_offsl_wr), + .t1y_offsh_wr (t1y_offsh_wr), + .palsel_wr (palsel_wr), + .hint_beg_wr (hint_beg_wr), + .vint_begl_wr (vint_begl_wr), + .vint_begh_wr (vint_begh_wr), + .tsconf_wr (tsconf_wr), + .tmpage_wr (tmpage_wr), + .t0gpage_wr (t0gpage_wr), + .t1gpage_wr (t1gpage_wr), + .sgpage_wr (sgpage_wr), + .border (border), + .vpage (vpage), + .vconf (vconf), + .gx_offs (gx_offs), + .gy_offs (gy_offs), + .t0x_offs (t0x_offs), + .t1x_offs (t1x_offs), + .t0y_offs (t0y_offs), + .t1y_offs (t1y_offs), + .palsel (palsel), + .hint_beg (hint_beg), + .vint_beg (vint_beg), + // .int_start (int_start), // uncomment to enable VSINT auto-increment + .tsconf (tsconf), + .tmpage (tmpage), + .t0gpage (t0gpage), + .t1gpage (t1gpage), + .sgpage (sgpage) +); + + + video_mode video_mode ( + .clk (clk), + .f1 (f1), + .c3 (c3), + .vpage (vpage), + .vconf (vconf), + .v60hz (v60hz), + .fetch_sel (fetch_sel), + .fetch_bsl (fetch_bsl), + .fetch_cnt (scnt), + .fetch_stb (fetch_stb), + .txt_char (fetch_temp[15:0]), + .gx_offs (gx_offs), + .x_offs_mode (x_offs_mode), + .hpix_beg (hpix_beg), + .hpix_end (hpix_end), + .vpix_beg (vpix_beg), + .vpix_end (vpix_end), + .x_tiles (x_tiles), + .go_offs (go_offs), + .cnt_col (cnt_col), + .cnt_row (cnt_row), + .cptr (cptr), + .line_start_s (line_start_s), + .pix_start (pix_start), + .tv_hires (tv_hires), + .vga_hires (vga_hires), + .pix_stb (pix_stb), + .render_mode (render_mode), + .video_addr (video_addr), + .video_bw (video_bw) +); + + + video_sync video_sync ( + .clk (clk), + .f1 (f1), + .c0 (c0), + .c1 (c1), + .c3 (c3), + .hpix_beg (hpix_beg), + .hpix_end (hpix_end), + .vpix_beg (vpix_beg), + .vpix_end (vpix_end), + .go_offs (go_offs), + .x_offs (x_offs_mode[1:0]), + .y_offs_wr (gy_offsl_wr || gy_offsh_wr), + .line_start_s (line_start_s), + .hint_beg (hint_beg), + .vint_beg (vint_beg), + .hsync (hsync), + .vsync (vsync), + .csync (csync), + .tv_hblank (tv_hblank), + .tv_vblank (tv_vblank), + .vga_hblank (vga_hblank), + .vga_vblank (vga_vblank), + .vga_cnt_in (vga_cnt_in), + .vga_cnt_out (vga_cnt_out), + .ts_raddr (ts_raddr), + .lcount (lcount), + .cnt_col (cnt_col), + .cnt_row (cnt_row), + .cptr (cptr), + .scnt (scnt), + .flash (flash), + .pix_stb (pix_stb), + .pix_start (pix_start), + .ts_start (ts_start), + .cstart (x_offs_mode[9:2]), + .rstart (gy_offs), + .int_start (int_start), + .v_pf (v_pf), + .hpix (hpix), + .v_ts (v_ts), + .vpix (vpix), + .hvpix (hvpix), + .nogfx (nogfx), + .cfg_60hz (cfg_60hz), + .sync_pol (sync_pol), + .v60hz (v60hz), + .vga_on (vga_on), + .video_go (video_go), + .video_pre_next (video_pre_next) +); + + + video_fetch video_fetch ( + .clk (clk), + .f_sel (fetch_sel), + .b_sel (fetch_bsl), + .fetch_stb (fetch_stb), + .fetch_data (fetch_data), + .fetch_temp (fetch_temp), + .video_strobe (video_strobe), + .video_data (dram_rdata) + //.video_data (16'b0000111100001111) //-OK +); + + video_ts video_ts ( + .clk (clk), + .start (ts_start), + .line (lcount), + .v_ts (v_ts), + + .tsconf (tsconf), + .t0gpage (t0gpage), + .t1gpage (t1gpage), + .sgpage (sgpage), + .tmpage (tmpage), + .num_tiles (x_tiles), + .v_pf (v_pf), + .t0x_offs (t0x_offs), + .t1x_offs (t1x_offs), + .t0y_offs (t0y_offs), + .t1y_offs (t1y_offs), + .t0_palsel (palsel[5:4]), + .t1_palsel (palsel[7:6]), + + .dram_addr (tm_addr), + .dram_req (tm_req), + .dram_next (tm_next), + .dram_rdata (dram_rdata), + + .tsr_go (tsr_go), + .tsr_addr (tsr_addr), + .tsr_line (tsr_line), + .tsr_page (tsr_page), + .tsr_pal (tsr_pal), + .tsr_x (tsr_x), + .tsr_xs (tsr_xs), + .tsr_xf (tsr_xf), + .tsr_rdy (tsr_rdy), + + .sfile_addr_in (zma), + .sfile_data_in (zmd), + .sfile_we (sfile_we) +); + + + video_ts_render video_ts_render ( + .clk (clk), + + .reset (ts_start), + + .tsr_go (tsr_go), + .addr (tsr_addr), + .line (tsr_line), + .page (tsr_page), + .pal (tsr_pal), + .x_coord (tsr_x), + .x_size (tsr_xs), + .flip (tsr_xf), + .mem_rdy (tsr_rdy), + + .ts_waddr (ts_waddr), + .ts_wdata (ts_wdata), + .ts_we (ts_we), + + .dram_addr (ts_addr), + .dram_req (ts_req), + .dram_pre_next (ts_pre_next), + .dram_next (ts_next), + .dram_rdata (dram_rdata) +); + + + video_render video_render ( + .clk (clk), + .c1 (c1), + .hvpix (hvpix), + .nogfx (nogfx), + .notsu (notsu), + .gfxovr (gfxovr), + .flash (flash), + .hires (tv_hires), + .psel (scnt), + .palsel (palsel[3:0]), + .render_mode (render_mode), + .data (fetch_data), + .border_in (border), + .tsdata_in (ts_rdata), + .vplex_out (vplex) +); + + video_out video_out ( + .clk (clk), + .f0 (f0), + .c3 (c3), + .vga_on (vga_on), + .tv_blank (tv_hblank|tv_vblank), + .vga_blank (vga_hblank|vga_vblank), + .palsel (palsel[3:0]), + .plex_sel_in ({h1, f1}), + .tv_hires (tv_hires), + .vga_hires (vga_hires), + .cram_addr_in (zma), + .cram_data_in (zmd[14:0]), + .cram_we (cram_we), + .vplex_in (vplex), + .vgaplex (vgaplex), + .vred (vred), + .vgrn (vgrn), + .vblu (vblu), + .tst (tst) +); + +assign hblank = vga_on ? vga_hblank : tv_hblank; +assign vblank = vga_on ? vga_vblank : tv_vblank; + +// 2 buffers: 512 pixels * 8 bits (9x8) - used as bitmap buffer for TS overlay over graphics +// (2 altdprams) + wire tl_act0 = lcount[0]; + wire tl_act1 = ~lcount[0]; + wire [8:0] ts_waddr0 = tl_act0 ? ts_raddr : ts_waddr; + wire [7:0] ts_wdata0 = tl_act0 ? 8'd0 : ts_wdata; + wire ts_we0 = tl_act0 ? c3 : ts_we; + wire [8:0] ts_waddr1 = tl_act1 ? ts_raddr : ts_waddr; + wire [7:0] ts_wdata1 = tl_act1 ? 8'd0 : ts_wdata; + wire ts_we1 = tl_act1 ? c3 : ts_we; + wire [7:0] ts_rdata = tl_act0 ? ts_rdata0 : ts_rdata1; + wire [7:0] ts_rdata0, ts_rdata1; + + + video_tsline0 video_tsline0 ( + .clock (clk), + .wraddress (ts_waddr0), + .data (ts_wdata0), + .wren (ts_we0), + .rdaddress (ts_raddr), + .q (ts_rdata0) +); + video_tsline1 video_tsline1 ( + .clock (clk), + .wraddress (ts_waddr1), + .data (ts_wdata1), + .wren (ts_we1), + .rdaddress (ts_raddr), + .q (ts_rdata1) +); + + +// 2 lines * 512 pix * 8 bit (10x8) - used for VGA doubler +// (1 altdpram) + video_vmem video_vmem( + .clock (clk), + .wraddress (vga_cnt_in), + .data (vplex), + .wren (c3), + .rdaddress (vga_cnt_out), + .q (vgaplex) +); + + +endmodule diff --git a/src/video/video_ts.v b/src/video/video_ts.v new file mode 100644 index 0000000..6f00918 --- /dev/null +++ b/src/video/video_ts.v @@ -0,0 +1,403 @@ + +// This is the Tile Sprite Processing Unit + +// Tiles map address: +// bits desc +// 20:13 tmpage +// 12: + +// Graphics address: +// bits desc +// 20:13 Xgpage +// 15:7 line (bits 15:13 are added) - 512 lines +// 6:0 word within line - 128 words = 512 pixels + + +module video_ts ( + +// clocks + input wire clk, + +// video controls + input wire start, + input wire [8:0] line, // = vcount - vpix_beg + 9'b1; + input wire v_ts, + input wire v_pf, // vertical tilemap prefetch window + +// video config + input wire [7:0] tsconf, + input wire [7:0] t0gpage, + input wire [7:0] t1gpage, + input wire [7:0] sgpage, + input wire [7:0] tmpage, + input wire [5:0] num_tiles, + input wire [8:0] t0x_offs, + input wire [8:0] t1x_offs, + input wire [8:0] t0y_offs, + input wire [8:0] t1y_offs, + input wire [1:0] t0_palsel, + input wire [1:0] t1_palsel, + +// SFYS interface + input wire [7:0] sfile_addr_in, + input wire [15:0] sfile_data_in, + input wire sfile_we, + +// renderer interface + output wire tsr_go, + output wire [5:0] tsr_addr, // graphics address within the line + output wire [8:0] tsr_line, // bitmap line + output wire [7:0] tsr_page, // bitmap 1st page + output wire [8:0] tsr_x, // addr in buffer (0-359 visibles) + output wire [2:0] tsr_xs, // size (8-64 pix) + output wire tsr_xf, // X flip + output wire [3:0] tsr_pal, // palette + input wire tsr_rdy, // renderer is done and ready to receive a new task + +// DRAM interface + output wire [20:0] dram_addr, + output wire dram_req, + input wire dram_next, + input wire [15:0] dram_rdata, + + output wire [2:0] tst +); + + +// config + wire s_en = tsconf[7]; + wire t1_en = tsconf[6]; + wire t0_en = tsconf[5]; + wire t1z_en = tsconf[3]; + wire t0z_en = tsconf[2]; + + +// TS renderer interface + assign tsr_go = sprite_go || tile_go; + assign tsr_x = sprites ? sprites_x : tile_x; + assign tsr_xs = sprites ? sprites_xs : 3'd0; + assign tsr_xf = sprites ? sprites_xf : t_xflp; + assign tsr_page = sprites ? sgpage : tile_page; + assign tsr_line = sprites ? sprites_line : tile_line; + assign tsr_addr = sprites ? sprites_addr : tile_addr; + assign tsr_pal = sprites ? s_pal : tile_pal; + + +// Layer selectors control + + // DEBUG !!! + assign tst = lyr; + reg [2:0] lyr; + always@* + // if (layer_active[S0]) + // lyr = 2; + // else if (layer_active[S1]) + // lyr = 6; + // else if (layer_active[S2]) + // lyr = 4; + // else if (layer_active[TM]) + // lyr = 1; + // else if (layer_active[T0]) + // lyr = 3; + // else if (layer_active[T1]) + // lyr = 5; + // else lyr = 0; + lyr = 0; + // lyr = sr_valid; + + localparam LAYERS = 6; // Total number of layers to process + localparam TM = 0; // Individual layers + localparam S0 = 1; + localparam T0 = 2; + localparam S1 = 3; + localparam T1 = 4; + localparam S2 = 5; + + wire tmap = layer_active[TM]; + wire sprites = layer_active[S0] || layer_active[S1] || layer_active[S2]; + wire tiles = layer_active[T0] || layer_active[T1]; + + reg [LAYERS-1:0] layer; + always @(posedge clk) + if (start) + layer <= 1; + else if (|(layer & layer_skip)) + layer <= {layer[LAYERS-2:0], 1'b0}; + + reg [LAYERS-1:0] layer_active; + always @(posedge clk) + if (start) + layer_active <= 0; + else + layer_active <= layer & ~layer_skip; + + wire [LAYERS-1:0] layer_enabled = {s_en, t1_en, s_en, t0_en, s_en, t1_en || t0_en}; + wire [LAYERS-1:0] layer_allowed = {{5{v_ts}}, v_pf}; + wire [LAYERS-1:0] layer_end = {spr_end[2], tile_end[1], spr_end[1], tile_end[0], spr_end[0], tm_end}; + + reg [LAYERS-1:0] layer_skip; + always @(posedge clk) + if (start) + layer_skip <= ~(layer_enabled & layer_allowed); + else + layer_skip <= layer_skip | layer_end; + + +// --- Tile map prefetch --- + + // DRAM controls + assign dram_addr = {tmpage, tm_b_row, tm_layer, tm_b_line, tm_num}; // 20:13 - page, 12:7 - row, 6 - layer, 5:0 - column (burst number : number in burst) + assign dram_req = tmap; + + // TMB control + wire [8:0] tmb_waddr = {tm_line[4:3], tm_b_line, tm_num, tm_layer}; // 8:7 - buffer #, 6:4 - burst number (of 8 bursts), 3:1 - number in burst (8 tiles per burst), 0 - layer + wire [8:0] tm_line = line + 9'd16; + wire [2:0] tm_b_line = tm_line[2:0]; + wire [5:0] tm_b_row = tm_line[8:3] + (tm_layer ? t1y_offs[8:3] : t0y_offs[8:3]); + wire [2:0] tm_num = tm_x[2:0]; + wire tm_layer = tm_x[3]; + + // internal layers control + wire tm_end = tm_x == (t1_en ? 5'd16 : 5'd8); + wire tm_next = dram_next && tmap; + + reg [1:0] m_layer; + always @(posedge clk) + if (start) + m_layer <= 2'b1; + else if (tm_end) + m_layer <= {m_layer[0], 1'b0}; + + // tilemap X coordinate + reg [4:0] tm_x; + always @(posedge clk) + if (start) + tm_x <= t0_en ? 5'd0 : 5'd8; + else if (tm_next) + tm_x <= tm_x + 5'd1; + + +// --- Tiles --- + + // tile descriptor fields + wire [11:0] t_tnum = tmb_rdata[11:0]; + wire [1:0] t_pal = tmb_rdata[13:12]; + wire t_xflp = tmb_rdata[14]; + wire t_yflp = tmb_rdata[15]; + + // TSR control + wire [7:0] tile_page = t_sel ? t0gpage : t1gpage; + wire [8:0] tile_line = {t_tnum[11:6], (t_line[2:0] ^ {3{t_yflp}})}; + wire [5:0] tile_addr = t_tnum[5:0]; + wire [8:0] tile_x = {(tx - 6'd1), 3'd0} - tx_offs[2:0]; + wire [3:0] tile_pal = {t_sel ? t0_palsel : t1_palsel, t_pal}; + + // TMB control + wire [8:0] tmb_raddr = {t_line[4:3], tx + tx_offs[8:3], ~t_sel}; + + // layer parameter selectors + wire [8:0] tx_offs = t_sel ? t0x_offs : t1x_offs; + wire [3:0] ty_offs = t_sel ? t0y_offs[2:0] : t1y_offs[2:0]; + wire t_sel = t_layer[0]; + + // internal layers control + wire [1:0] tile_end = {2{t_layer_end}} & t_layer[1:0]; + wire t_layer_end = tx == num_tiles; + wire t_layer_start = start || t_layer_end; + + reg [1:0] t_layer; + always @(posedge clk) + if (start) + t_layer <= t0_en ? 2'b01 : 2'b10; + else if (t_layer_end) + t_layer <= {t_layer[0], 1'b0}; + + // TMBUF control + // condition write to tx write to tm_valid + // t_layer_start 0 TM_PRE_VALID + // tm_pre_valid tx+1 TM_VALID + // tile_skip tx+1 - + // tile_go tx+1 TM_VALID + // tile_wait tx-1 TM_PRE_VALID + + localparam TM_PRE_VALID = 2'b01; + localparam TM_VALID = 2'b10; + + wire tile_go = tile_good && tsr_allowed; + wire tile_wait = tile_good && !tsr_allowed; + wire tile_good = tm_valid && tile_valid; + wire tile_skip = tm_valid && !tile_valid; + wire tsr_allowed = tiles && tsr_rdy; + wire tile_valid = |t_tnum || (t_sel ? t0z_en : t1z_en); + + wire tm_pre_valid = tm_valid_r[0]; + wire tm_valid = tm_valid_r[1]; + + reg [1:0] tm_valid_r; + always @(posedge clk) + if (t_layer_start || tile_wait) + tm_valid_r <= TM_PRE_VALID; + else if (tm_pre_valid || tile_go) + tm_valid_r <= TM_VALID; + + reg [5:0] tx; + always @(posedge clk) + if (t_layer_start) + tx <= 6'd0; + else if (tm_pre_valid || tile_skip || tile_go) + tx <= tx + 6'd1; + else if (tile_wait) + tx <= tx - 6'd1; + + // tile Y geometry + wire [4:0] t_line = line[4:0] + ty_offs; + + +// --- Sprites --- + + // sprite descriptor fields + // R0 + wire [8:0] s_ycrd = sfile_rdata[8:0]; + wire [2:0] s_ysz = sfile_rdata[11:9]; + wire s_act = sfile_rdata[13]; + wire s_leap = sfile_rdata[14]; + wire s_yflp = sfile_rdata[15]; + // R1 + wire [8:0] s_xcrd = sfile_rdata[8:0]; + wire [2:0] s_xsz = sfile_rdata[11:9]; + wire s_xflp = sfile_rdata[15]; + // R2 + wire [11:0] s_tnum = sfile_rdata[11:0]; + wire [3:0] s_pal = sfile_rdata[15:12]; + + // TSR control + reg [8:0] sprites_x; + reg [2:0] sprites_xs; + reg sprites_xf; + wire [5:0] sprites_addr = s_tnum[5:0]; + + // internal layers control + wire [2:0] spr_end = ({3{s_layer_end}} & s_layer[2:0]) | {3{sprites_last}}; + wire s_layer_end = (sr0_valid && !spr_valid && s_leap) || (sprite_go && s_leap_r); + wire sprites_last = sreg == 8'd255; + + reg [2:0] s_layer; + always @(posedge clk) + if (start) + s_layer <= 3'b1; + else if (s_layer_end) + s_layer <= {s_layer[1:0], 1'b0}; + + // SFile registers control + // condition write to sreg write to sr_valid action + // start 0 SR0_PRE_VALID Start + // sr0_pre_valid sreg+3 SR0_VALID SR0 pre-read + // sr0_valid && !spr_valid sreg+3 - Skip sprite + // sr0_valid && spr_valid sreg-2 SR1_PRE_VALID SR1 pre-read + // sr1_pre_valid sreg+1 SR1_VALID SR1 read + // sr1_valid sreg+1 SR2_VALID SR2 pre-read + // sr2_valid && !tsr_rdy - - Wait for TSR ready + // sr2_valid && tsr_rdy sreg+1 SR0_PRE_VALID Next sprite + // sprites_last - NONE_VALID End + + localparam NONE_VALID = 5'b00000; + localparam SR0_PRE_VALID = 5'b00001; + localparam SR0_VALID = 5'b00010; + localparam SR1_PRE_VALID = 5'b00100; + localparam SR1_VALID = 5'b01000; + localparam SR2_VALID = 5'b10000; + + wire sprite_go = sr2_valid && sprites && tsr_rdy; // kick to renderer + wire spr_valid = s_visible && s_act; + + wire sr0_pre_valid = sr_valid[0]; + wire sr0_valid = sr_valid[1]; + wire sr1_pre_valid = sr_valid[2]; + wire sr1_valid = sr_valid[3]; + wire sr2_valid = sr_valid[4]; + + reg [4:0] sr_valid; + always @(posedge clk) + if (start) + sr_valid <= SR0_PRE_VALID; + else if (sprites_last) + sr_valid <= NONE_VALID; + else if (sr0_pre_valid) + sr_valid <= SR0_VALID; + else if (sr0_valid && spr_valid) + sr_valid <= SR1_PRE_VALID; + else if (sr1_pre_valid) + sr_valid <= SR1_VALID; + else if (sr1_valid) + sr_valid <= SR2_VALID; + else if (sprite_go) + sr_valid <= SR0_PRE_VALID; + + reg [7:0] sreg; + always @(posedge clk) + if (start) + sreg <= 8'd0; + else if (sr0_pre_valid) + sreg <= sreg + 8'd3; + else if (sr0_valid) + sreg <= spr_valid ? (sreg - 8'd2) : (sreg + 8'd3); + else if (sr1_pre_valid || sprite_go) + sreg <= sreg + 8'd1; + + // SFile control + reg [5:0] s_bmline_offset_r; + reg s_leap_r; + + always @(posedge clk) + begin + if (sr0_valid) + begin + s_leap_r <= s_leap; + s_bmline_offset_r <= s_bmline_offset; + end + + if (sr1_valid) + begin + sprites_x <= s_xcrd; + sprites_xs <= s_xsz; + sprites_xf <= s_xflp; + end + end + + // sprite Y geometry + wire [8:0] s_line = line - s_ycrd; // visible line of sprite in current video line + wire s_visible = (s_line <= s_ymax); // check if sprite line is within Y size + wire [5:0] s_ymax = {s_ysz, 3'b111}; + + wire [8:0] sprites_line = {s_tnum[11:6], 3'b0} + s_bmline_offset_r; + wire [5:0] s_bmline_offset = s_yflp ? (s_ymax - s_line[5:0]) : s_line[5:0]; + + +// SFile + wire [15:0] sfile_rdata; + +video_sfile video_sfile ( + .clock (!clk), // MVV 18.10.2014 + .wraddress (sfile_addr_in), + .data (sfile_data_in), + .wren (sfile_we), + .rdaddress (sreg), + .q (sfile_rdata) +); + + +// 4 buffers * 2 tile-planes * 64 tiles * 16 bits (9x16) - used to prefetch tiles +// (2 altdprams) + wire [15:0] tmb_rdata; + + video_tmbuf video_tmbuf ( + .clock (!clk), // MVV 18.10.2014 + .data (dram_rdata), + // .data (0), + .wraddress (tmb_waddr), + .wren (tm_next), + .rdaddress (tmb_raddr), + .q (tmb_rdata) +); + +endmodule diff --git a/src/video/video_ts_render.v b/src/video/video_ts_render.v new file mode 100644 index 0000000..4066a36 --- /dev/null +++ b/src/video/video_ts_render.v @@ -0,0 +1,155 @@ + +// This module renders pixels into TS-line for tiles/sprites +// Task execution is initiated by 'tsr_go' (one 'clk' period strobe). +// Inputs (only valid by 'tsr_go'): +// - DRAM address of graphics data (including page, line, word) +// - number of cycles to render (one cycle is 2 words = 8 pixels; 8 cycles = 64 pixels max) +// - X coordinate +// - X flip bit +// - palette selector +// Address in TS-line is calculated from X coordinate respecting the X flip. +// Inc/dec direction is set automatically. +// At the 'c2' of last DRAM cycle 'mem_rdy' is asserted. +// It should be used in comb to generate next cycle 'tsr_go' strobe for continuous renderer operation. +// First 'tsr_go' may be issued at any DRAM cycle, but the operation starts only +// after TS request recognized and processed by DRAM controller. +// It is recommended to assert 'tsr_go' at 'c2'. + +module video_ts_render ( + +// clocks + input wire clk, + +// controls + input wire reset, // line start strobe, inits the machine + + input wire [ 8:0] x_coord, // address in TS-line where render to, auto-flipped to match 'flip' times 'x_size' + input wire [ 2:0] x_size, // number of rendering cycles (each cycle is 8 pixels, 0 = 1 cycle) + input wire flip, // indicates that sprite is X-flipped + + input wire tsr_go, // 1 clk 28MHz strobe for render start. Should be issued along with 'mem_rdy' for continuous process + input wire [ 5:0] addr, // address of dword within the line (dword = 8 pix) + input wire [ 8:0] line, // line of bitmap + input wire [ 7:0] page, // 1st page of bitmap (TxGpage or SGpage) + input wire [ 3:0] pal, // palette selector, bits[7:4] of CRAM address + output wire mem_rdy, // ready to receive new task + +// TS-Line interface + output reg [ 8:0] ts_waddr, + output wire [ 7:0] ts_wdata, + output wire ts_we, + +// DRAM interface + output wire [20:0] dram_addr, + output wire dram_req, + input wire [15:0] dram_rdata, + input wire dram_pre_next, + input wire dram_next + +); + + +// DRAM request + assign dram_req = tsr_go || !mem_rdy; + + +// DRAM addressing + assign dram_addr = tsr_go ? addr_in : addr_next; + wire [20:0] addr_in = {addr_offset, addr, 1'b0}; + wire [13:0] addr_offset = {page[7:3], line}; + wire [20:0] addr_next = {addr_reg[20:7], addr_reg[6:0] + dram_next}; + // as renderer can't move outside the single bitmap line, only 7 bits are processed + + reg [20:0] addr_reg; + always @(posedge clk) + addr_reg <= dram_addr; + + +// DRAM cycles counter + assign mem_rdy = cyc[4]; + + reg [4:0] cyc; + always @(posedge clk) + if (reset) + cyc <= 5'b10000; + else if (tsr_go) + cyc <= {1'b0, x_size, 1'b1}; + else if (dram_pre_next) + cyc <= cyc - 5'd1; + + +// DRAM data fetching + reg [15:0] data; + always @(posedge clk) + if (dram_next) + data <= dram_rdata; + + +// pixel render counter + assign ts_we = render_on && |pix; // write signal for TS-line + wire render_on = !cnt[2]; + + reg [2:0] cnt; + always @(posedge clk) + if (reset) + cnt <= 3'b100; + else if (dram_next) + cnt <= 3'b000; + else if (render_on) + cnt <= cnt + 3'd1; + + +// renderer reload + reg tsr_rld; + always @(posedge clk) + if (reset) + tsr_rld <= 1'b0; + else if (tsr_go) + tsr_rld <= 1'b1; + else if (dram_next) + tsr_rld <= 1'b0; + + +// delayed values + reg [8:0] x_coord_d; + reg [3:0] pal_d; + reg flip_d; + always @(posedge clk) + if (tsr_go) + begin + x_coord_d <= x_coord + (flip ? {x_size, 3'b111} : 6'd0); + pal_d <= pal; + flip_d <= flip; + end + + +// TS-line address + wire [8:0] ts_waddr_mx = tsr_rld_stb ? x_coord_d : (render_on ? x_next : ts_waddr); + wire [8:0] x_next = ts_waddr + {{8{flip_r}}, 1'b1}; + wire tsr_rld_stb = tsr_rld && dram_next; + + always @(posedge clk) + ts_waddr <= ts_waddr_mx; + + reg [3:0] pal_r; + reg flip_r; + always @(posedge clk) + if (tsr_rld_stb) + begin + pal_r <= pal_d; + flip_r <= flip_d; + end + + +// renderer mux + assign ts_wdata = {pal_r, pix}; + wire [3:0] pix = pix_m[cnt[1:0]]; + + wire [3:0] pix_m[0:3]; + assign pix_m[0] = data[7:4]; + assign pix_m[1] = data[3:0]; + assign pix_m[2] = data[15:12]; + assign pix_m[3] = data[11:8]; + + +endmodule diff --git a/sys/build_id.tcl b/sys/build_id.tcl new file mode 100644 index 0000000..3705e4c --- /dev/null +++ b/sys/build_id.tcl @@ -0,0 +1,69 @@ + +# Build TimeStamp Verilog Module +# Jeff Wiencrot - 8/1/2011 +proc generateBuildID_Verilog {} { + + # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) + set buildDate [ clock format [ clock seconds ] -format %y%m%d ] + set buildTime [ clock format [ clock seconds ] -format %H%M%S ] + + # Create a Verilog file for output + set outputFileName "build_id.v" + set outputFile [open $outputFileName "w"] + + # Output the Verilog source + puts $outputFile "`define BUILD_DATE \"$buildDate\"" + puts $outputFile "`define BUILD_TIME \"$buildTime\"" + close $outputFile + + # Send confirmation message to the Messages window + post_message "Generated build identification Verilog module: [pwd]/$outputFileName" + post_message "Date: $buildDate" + post_message "Time: $buildTime" +} + +# Build CDF file +# Sorgelig - 17/2/2018 +proc generateCDF {revision device outpath} { + + set outputFileName "jtag.cdf" + set outputFile [open $outputFileName "w"] + + puts $outputFile "JedecChain;" + puts $outputFile " FileRevision(JESD32A);" + puts $outputFile " DefaultMfr(6E);" + puts $outputFile "" + puts $outputFile " P ActionCode(Ign)" + puts $outputFile " Device PartName(SOCVHPS) MfrSpec(OpMask(0));" + puts $outputFile " P ActionCode(Cfg)" + puts $outputFile " Device PartName($device) Path(\"$outpath/\") File(\"$revision.sof\") MfrSpec(OpMask(1));" + puts $outputFile "ChainEnd;" + puts $outputFile "" + puts $outputFile "AlteraBegin;" + puts $outputFile " ChainType(JTAG);" + puts $outputFile "AlteraEnd;" +} + +set project_name [lindex $quartus(args) 1] +set revision [lindex $quartus(args) 2] + +if {[project_exists $project_name]} { + if {[string equal "" $revision]} { + project_open $project_name -revision [get_current_revision $project_name] + } else { + project_open $project_name -revision $revision + } +} else { + post_message -type error "Project $project_name does not exist" + exit +} + +set device [get_global_assignment -name DEVICE] +set outpath [get_global_assignment -name PROJECT_OUTPUT_DIRECTORY] + +if [is_project_open] { + project_close +} + +generateBuildID_Verilog +generateCDF $revision $device $outpath diff --git a/sys/hdmi_config.sv b/sys/hdmi_config.sv new file mode 100644 index 0000000..0321792 --- /dev/null +++ b/sys/hdmi_config.sv @@ -0,0 +1,202 @@ + +module hdmi_config +( + // Host Side + input iCLK, + input iRST_N, + + input dvi_mode, + input audio_96k, + + // I2C Side + output I2C_SCL, + inout I2C_SDA +); + +// Internal Registers/Wires +reg mI2C_GO = 0; +wire mI2C_END; +wire mI2C_ACK; +reg [15:0] LUT_DATA; +reg [7:0] LUT_INDEX = 0; + +i2c #(50_000_000, 20_000) i2c_av +( + .CLK(iCLK), + + .I2C_SCL(I2C_SCL), // I2C CLOCK + .I2C_SDA(I2C_SDA), // I2C DATA + + .I2C_DATA({8'h72,init_data[LUT_INDEX]}), // DATA:[SLAVE_ADDR,SUB_ADDR,DATA]. 0x72 is the Slave Address of the ADV7513 chip! + .START(mI2C_GO), // START transfer + .END(mI2C_END), // END transfer + .ACK(mI2C_ACK) // ACK +); + +////////////////////// Config Control //////////////////////////// +always@(posedge iCLK or negedge iRST_N) begin + reg [1:0] mSetup_ST = 0; + + if(!iRST_N) begin + LUT_INDEX <= 0; + mSetup_ST <= 0; + mI2C_GO <= 0; + end else begin + if(init_data[LUT_INDEX] != 16'hFFFF) begin + case(mSetup_ST) + 0: begin + mI2C_GO <= 1; + mSetup_ST <= 1; + end + 1: if(~mI2C_END) mSetup_ST <= 2; + 2: begin + mI2C_GO <= 0; + if(mI2C_END) begin + mSetup_ST <= 0; + if(!mI2C_ACK) LUT_INDEX <= LUT_INDEX + 8'd1; + end + end + endcase + end + end +end + +//////////////////////////////////////////////////////////////////// +///////////////////// Config Data LUT ////////////////////////// + +wire [15:0] init_data[58] = +'{ + 16'h9803, // ADI required Write. + + {8'hD6, 8'b1100_0000}, // [7:6] HPD Control... + // 00 = HPD is from both HPD pin or CDC HPD + // 01 = HPD is from CDC HPD + // 10 = HPD is from HPD pin + // 11 = HPD is always high + + 16'h4110, // Power Down control + 16'h9A70, // ADI required Write. + 16'h9C30, // ADI required Write. + {8'h9D, 8'b0110_0001}, // [7:4] must be b0110!. + // [3:2] b00 = Input clock not divided. b01 = Clk divided by 2. b10 = Clk divided by 4. b11 = invalid! + // [1:0] must be b01! + 16'hA2A4, // ADI required Write. + 16'hA3A4, // ADI required Write. + 16'hE0D0, // ADI required Write. + + + 16'h35_40, + 16'h36_D9, + 16'h37_0A, + 16'h38_00, + 16'h39_2D, + 16'h3A_00, + + {8'h16, 8'b0011_1000}, // Output Format 444 [7]=0. + // [6] must be 0! + // Colour Depth for Input Video data [5:4] b11 = 8-bit. + // Input Style [3:2] b10 = Style 1 (ignored when using 444 input). + // DDR Input Edge falling [1]=0 (not using DDR atm). + // Output Colour Space RGB [0]=0. + + {8'h17, 8'b01100010}, // Aspect ratio 16:9 [1]=1, 4:3 [1]=0 + + {8'h18, 8'b0100_0110}, // CSC disabled [7]=0. + // CSC Scaling Factor [6:5] b10 = +/- 4.0, -16384 - 16380. + // CSC Equation 3 [4:0] b00110. + + + {8'h3B, 8'b0000_0000}, // Pixel repetition [6:5] b00 AUTO. [4:3] b00 x1 mult of input clock. [2:1] b00 x1 pixel rep to send to HDMI Rx. + + 16'h4000, // General Control Packet Enable + + {8'h48, 8'b0000_1000}, // [6]=0 Normal bus order! + // [5] DDR Alignment. + // [4:3] b01 Data right justified (for YCbCr 422 input modes). + + 16'h49A8, // ADI required Write. + 16'h4C00, // ADI required Write. + + {8'h55, 8'b0001_0000}, // [7] must be 0!. Set RGB444 in AVinfo Frame [6:5], Set active format [4]. + // AVI InfoFrame Valid [4]. + // Bar Info [3:2] b00 Bars invalid. b01 Bars vertical. b10 Bars horizontal. b11 Bars both. + // Scan Info [1:0] b00 (No data). b01 TV. b10 PC. b11 None. + + 16'h7301, + + {8'h94, 8'b1000_0000}, // [7]=1 HPD Interrupt ENabled. + + 16'h9902, // ADI required Write. + 16'h9B18, // ADI required Write. + + 16'h9F00, // ADI required Write. + + {8'hA1, 8'b0000_0000}, // [6]=1 Monitor Sense Power Down DISabled. + + 16'hA408, // ADI required Write. + 16'hA504, // ADI required Write. + 16'hA600, // ADI required Write. + 16'hA700, // ADI required Write. + 16'hA800, // ADI required Write. + 16'hA900, // ADI required Write. + 16'hAA00, // ADI required Write. + 16'hAB40, // ADI required Write. + + {8'hAF, 6'b0001_01,~dvi_mode,1'b0}, // [7]=0 HDCP Disabled. + // [6:5] must be b00! + // [4]=1 Current frame IS HDCP encrypted!??? (HDCP disabled anyway?) + // [3:2] must be b01! + // [1]=1 HDMI Mode. + // [0] must be b0! + + 16'hB900, // ADI required Write. + + {8'hBA, 8'b0110_0000}, // [7:5] Input Clock delay... + // b000 = -1.2ns. + // b001 = -0.8ns. + // b010 = -0.4ns. + // b011 = No delay. + // b100 = 0.4ns. + // b101 = 0.8ns. + // b110 = 1.2ns. + // b111 = 1.6ns. + + 16'hBB00, // ADI required Write. + + 16'hDE9C, // ADI required Write. + 16'hE460, // ADI required Write. + 16'hFA7D, // Nbr of times to search for good phase + + + // (Audio stuff on Programming Guide, Page 66)... + + {8'h0A, 8'b0000_0000}, // [6:4] Audio Select. b000 = I2S. + // [3:2] Audio Mode. (HBR stuff, leave at 00!). + + {8'h0B, 8'b0000_1110}, // + + {8'h0C, 8'b0000_0100}, // [7] 0 = Use sampling rate from I2S stream. 1 = Use samp rate from I2C Register. + // [6] 0 = Use Channel Status bits from stream. 1 = Use Channel Status bits from I2C register. + // [2] 1 = I2S0 Enable. + // [1:0] I2S Format: 00 = Standard. 01 = Right Justified. 10 = Left Justified. 11 = AES. + + {8'h0D, 8'b0001_0000}, // [4:0] I2S Bit (Word) Width for Right-Justified. + {8'h14, 8'b0000_0010}, // [3:0] Audio Word Length. b0010 = 16 bits. + {8'h15, audio_96k, 7'b010_0000}, // I2S Sampling Rate [7:4]. b0000 = (44.1KHz). b0010 = 48KHz. + // Input ID [3:1] b000 (0) = 24-bit RGB 444 or YCrCb 444 with Separate Syncs. + + // Audio Clock Config + 16'h0100, // + audio_96k ? 16'h0230 : 16'h0218, // Set N Value 12288/6144 + 16'h0300, // + + 16'h0701, // + 16'h0822, // Set CTS Value 74250 + 16'h090A, // + + 16'hFFFF // END +}; + +//////////////////////////////////////////////////////////////////// + +endmodule \ No newline at end of file diff --git a/sys/hdmi_lite.sv b/sys/hdmi_lite.sv new file mode 100644 index 0000000..96eb441 --- /dev/null +++ b/sys/hdmi_lite.sv @@ -0,0 +1,395 @@ +//============================================================================ +// +// 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,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 +// 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 . +// +/////////////////////////////////////////////////////////////////////// + +// +// Use buffer to access SD card. It's time-critical part. +// +// for synchronous projects default value for PS2DIV is fine for any frequency of system clock. +// clk_ps2 = CLK_SYS/(PS2DIV*2) +// + +// WIDE=1 for 16 bit file I/O +// VDNUM 1-4 +module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0) +( + input clk_sys, + inout [44:0] HPS_BUS, + + // parameter STRLEN and the actual length of conf_str have to match + input [(8*STRLEN)-1:0] conf_str, + + output reg [15:0] joystick_0, + output reg [15:0] joystick_1, + output reg [15:0] joystick_analog_0, + output reg [15:0] joystick_analog_1, + + output [1:0] buttons, + output forced_scandoubler, + + output reg [31:0] status, + + //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 + output reg img_readonly, // mounted as read only. valid only for active bit in img_mounted + output reg [63:0] img_size, // size of image in bytes. valid only for active bit in img_mounted + + // SD block level access + input [31:0] sd_lba, + 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, + output reg sd_ack_conf, + + // SD byte level access. Signals for 2-PORT altsyncram. + output reg [AW:0] sd_buff_addr, + output reg [DW:0] sd_buff_dout, + input [DW:0] sd_buff_din, + output reg sd_buff_wr, + + // ARM -> FPGA download + output reg ioctl_download = 0, // signal indicating an active download + output reg [7:0] ioctl_index, // menu index used to upload the file + 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 + output reg [64:0] RTC, + + // Seconds since 1970-01-01 00:00:00 + output reg [32:0] TIMESTAMP, + + // ps2 keyboard emulation + output ps2_kbd_clk_out, + output ps2_kbd_data_out, + input ps2_kbd_clk_in, + input ps2_kbd_data_in, + + input [2:0] ps2_kbd_led_status, + input [2:0] ps2_kbd_led_use, + + output ps2_mouse_clk_out, + output ps2_mouse_data_out, + input ps2_mouse_clk_in, + input ps2_mouse_data_in, + + // ps2 alternative interface. + + // [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 +); + +localparam DW = (WIDE) ? 15 : 7; +localparam AW = (WIDE) ? 7 : 8; +localparam VD = VDNUM-1; + +wire io_wait = ioctl_wait; +wire io_enable= |HPS_BUS[35:34]; +wire io_strobe= HPS_BUS[33]; +wire io_wide = (WIDE) ? 1'b1 : 1'b0; +wire [15:0] io_din = HPS_BUS[31:16]; +reg [15:0] io_dout; + +assign HPS_BUS[37] = io_wait; +assign HPS_BUS[36] = clk_sys; +assign HPS_BUS[32] = io_wide; +assign HPS_BUS[15:0] = io_dout; + +reg [7:0] cfg; +assign buttons = cfg[1:0]; +//cfg[2] - vga_scaler handled in sys_top +//cfg[3] - csync handled in sys_top +assign forced_scandoubler = cfg[4]; +//cfg[5] - ypbpr handled in sys_top + +// command byte read by the io controller +wire [15:0] sd_cmd = +{ + 2'b00, + (VDNUM>=4) ? sd_wr[3] : 1'b0, + (VDNUM>=3) ? sd_wr[2] : 1'b0, + (VDNUM>=2) ? sd_wr[1] : 1'b0, + + (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] +}; + +///////////////// calc video parameters ////////////////// + +wire clk_100 = HPS_BUS[43]; +wire clk_vid = HPS_BUS[42]; +wire ce_pix = HPS_BUS[41]; +wire de = HPS_BUS[40]; +wire hs = HPS_BUS[39]; +wire vs = HPS_BUS[38]; +wire vs_hdmi = HPS_BUS[44]; + +reg [31:0] vid_hcnt = 0; +reg [31:0] vid_vcnt = 0; +reg [7:0] vid_nres = 0; +integer hcnt; + +always @(posedge clk_vid) begin + integer vcnt; + reg old_vs= 0, old_de = 0, old_vmode = 0; + reg calch = 0; + + if(ce_pix) begin + old_vs <= vs; + old_de <= de; + + if(~vs & ~old_de & de) vcnt <= vcnt + 1; + if(calch & de) hcnt <= hcnt + 1; + if(old_de & ~de) calch <= 0; + + if(old_vs & ~vs) begin + if(hcnt && vcnt) begin + old_vmode <= new_vmode; + if(vid_hcnt != hcnt || vid_vcnt != vcnt || old_vmode != new_vmode) vid_nres <= vid_nres + 1'd1; + vid_hcnt <= hcnt; + vid_vcnt <= vcnt; + end + vcnt <= 0; + hcnt <= 0; + calch <= 1; + end + end +end + +reg [31:0] vid_htime = 0; +reg [31:0] vid_vtime = 0; +reg [31:0] vid_pix = 0; + +always @(posedge clk_100) begin + integer vtime, htime, hcnt; + reg old_vs, old_hs, old_vs2, old_hs2, old_de, old_de2; + reg calch = 0; + + old_vs <= vs; + old_hs <= hs; + + old_vs2 <= old_vs; + old_hs2 <= old_hs; + + vtime <= vtime + 1'd1; + htime <= htime + 1'd1; + + if(~old_vs2 & old_vs) begin + vid_pix <= hcnt; + vid_vtime <= vtime; + vtime <= 0; + hcnt <= 0; + end + + if(old_vs2 & ~old_vs) calch <= 1; + + if(~old_hs2 & old_hs) begin + vid_htime <= htime; + htime <= 0; + end + + old_de <= de; + old_de2 <= old_de; + + if(calch & old_de) hcnt <= hcnt + 1; + if(old_de2 & ~old_de) calch <= 0; +end + +reg [31:0] vid_vtime_hdmi; +always @(posedge clk_100) begin + integer vtime; + reg old_vs, old_vs2; + + old_vs <= vs_hdmi; + old_vs2 <= old_vs; + + vtime <= vtime + 1'd1; + + if(~old_vs2 & old_vs) begin + vid_vtime_hdmi <= vtime; + vtime <= 0; + end +end + + +///////////////////////////////////////////////////////// + +reg [31:0] ps2_key_raw = 0; +wire pressed = (ps2_key_raw[15:8] != 8'hf0); +wire extended = (~pressed ? (ps2_key_raw[23:16] == 8'he0) : (ps2_key_raw[15:8] == 8'he0)); + +always@(posedge clk_sys) begin + reg [15:0] cmd; + reg [9:0] byte_cnt; // counts bytes + reg [2:0] b_wr; + reg [2:0] stick_idx; + reg ps2skip = 0; + + 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 + ps2_key <= {~ps2_key[10], pressed, extended, ps2_key_raw[7:0]}; + if(ps2_key_raw == 'hE012E07C) ps2_key[9:0] <= 'h37C; // prnscr pressed + if(ps2_key_raw == 'h7CE0F012) ps2_key[9:0] <= 'h17C; // prnscr released + if(ps2_key_raw == 'hF014F077) ps2_key[9:0] <= 'h377; // pause pressed + end + if(cmd == 'h22) RTC[64] <= ~RTC[64]; + if(cmd == 'h24) TIMESTAMP[32] <= ~TIMESTAMP[32]; + cmd <= 0; + byte_cnt <= 0; + sd_ack <= 0; + sd_ack_conf <= 0; + io_dout <= 0; + ps2skip <= 0; + end else begin + if(io_strobe) begin + + io_dout <= 0; + if(~&byte_cnt) byte_cnt <= byte_cnt + 1'd1; + + if(byte_cnt == 0) begin + cmd <= io_din; + + case(io_din) + 'h19: sd_ack_conf <= 1; + 'h17, + 'h18: sd_ack <= 1; + endcase + + sd_buff_addr <= 0; + img_mounted <= 0; + if(io_din == 5) ps2_key_raw <= 0; + end else begin + + case(cmd) + // buttons and switches + 'h01: cfg <= io_din[7:0]; + 'h02: joystick_0 <= io_din; + 'h03: joystick_1 <= io_din; + + // store incoming ps2 mouse bytes + 'h04: begin + mouse_data <= io_din[7:0]; + mouse_we <= 1; + if(&io_din[15:8]) ps2skip <= 1; + if(~&io_din[15:8] & ~ps2skip) begin + case(byte_cnt) + 1: ps2_mouse[7:0] <= io_din[7:0]; + 2: ps2_mouse[15:8] <= io_din[7:0]; + 3: ps2_mouse[23:16] <= io_din[7:0]; + endcase + end + end + + // 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]}; + kbd_data <= io_din[7:0]; + 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 sd card status + 'h16: begin + 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 + // sd card knows data is config if sd_dout_strobe is asserted + // with sd_ack still being inactive (low) + 'h19, + // send sector IO -> FPGA + // flag that download begins + 'h17: begin + sd_buff_dout <= io_din[DW:0]; + b_wr <= 1; + end + + // reading sd card write data + 'h18: begin + if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; + io_dout <= sd_buff_din; + 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 + + // notify image selection + 'h1c: begin + img_mounted <= io_din[VD:0] ? io_din[VD:0] : 1'b1; + img_readonly <= io_din[7]; + end + + // send image info + 'h1d: if(byte_cnt<5) img_size[{byte_cnt-1'b1, 4'b0000} +:16] <= io_din; + + // status, 32bit version + 'h1e: if(byte_cnt==1) status[15:0] <= io_din; + else if(byte_cnt==2) status[31:16] <= io_din; + + // reading keyboard LED status + '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 + io_dout <= kbd_data_host; + kbd_rd <= 1; + end + + 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 + + //RTC + 'h24: TIMESTAMP[(byte_cnt-6'd1)<<4 +:16] <= io_din; + endcase + end + end + end +end + + +/////////////////////////////// PS2 /////////////////////////////// +reg clk_ps2; +always @(negedge clk_sys) begin + integer cnt; + cnt <= cnt + 1'd1; + if(cnt == PS2DIV) begin + clk_ps2 <= ~clk_ps2; + cnt <= 0; + end +end + +reg [7:0] kbd_data; +reg kbd_we; +wire [8:0] kbd_data_host; +reg kbd_rd; + +ps2_device keyboard +( + .clk_sys(clk_sys), + + .wdata(kbd_data), + .we(kbd_we), + + .ps2_clk(clk_ps2), + .ps2_clk_out(ps2_kbd_clk_out), + .ps2_dat_out(ps2_kbd_data_out), + + .ps2_clk_in(ps2_kbd_clk_in || !PS2WE), + .ps2_dat_in(ps2_kbd_data_in || !PS2WE), + + .rdata(kbd_data_host), + .rd(kbd_rd) +); + +reg [7:0] mouse_data; +reg mouse_we; +wire [8:0] mouse_data_host; +reg mouse_rd; + +ps2_device mouse +( + .clk_sys(clk_sys), + + .wdata(mouse_data), + .we(mouse_we), + + .ps2_clk(clk_ps2), + .ps2_clk_out(ps2_mouse_clk_out), + .ps2_dat_out(ps2_mouse_data_out), + + .ps2_clk_in(ps2_mouse_clk_in || !PS2WE), + .ps2_dat_in(ps2_mouse_data_in || !PS2WE), + + .rdata(mouse_data_host), + .rd(mouse_rd) +); + + +/////////////////////////////// DOWNLOADING /////////////////////////////// + +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; + + ioctl_wr <= wr; + wr <= 0; + + if(~io_enable) has_cmd <= 0; + else begin + if(io_strobe) 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]; + end + + UIO_FILE_TX: + begin + if(io_din[7:0]) begin + addr <= 0; + ioctl_download <= 1; + end else begin + ioctl_addr <= addr; + ioctl_download <= 0; + end + end + + UIO_FILE_TX_DAT: + begin + ioctl_addr <= addr; + ioctl_dout <= io_din[DW:0]; + wr <= 1; + addr <= addr + (WIDE ? 2'd2 : 2'd1); + end + endcase + end + end + end +end + +endmodule + +////////////////////////////////////////////////////////////////////////////////// + + +module ps2_device #(parameter PS2_FIFO_BITS=5) +( + input clk_sys, + + input [7:0] wdata, + input we, + + input ps2_clk, + output reg ps2_clk_out, + output reg ps2_dat_out, + output reg tx_empty, + + input ps2_clk_in, + input ps2_dat_in, + + output [8:0] rdata, + input rd +); + + +(* ramstyle = "logic" *) reg [7:0] fifo[1<= 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]) + parity <= !parity; + end + + // transmission of parity + if(tx_state == 9) ps2_dat_out <= parity; + + // transmission of stop bit + if(tx_state == 10) ps2_dat_out <= 1; // stop bit is 1 + + // advance state machine + if(tx_state < 11) tx_state <= tx_state + 1'd1; + else tx_state <= 0; + end + end + end + + if(~old_clk & ps2_clk) ps2_clk_out <= 1; + if(old_clk & ~ps2_clk) ps2_clk_out <= ((tx_state == 0) && (rx_state<2)); + +end + +endmodule diff --git a/sys/hq2x.sv b/sys/hq2x.sv new file mode 100644 index 0000000..ece54f9 --- /dev/null +++ b/sys/hq2x.sv @@ -0,0 +1,385 @@ +// +// +// Copyright (c) 2012-2013 Ludvig Strigeus +// Copyright (c) 2017,2018 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on + +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 hblank, + output [DWIDTH:0] outpixel +); + + +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, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43 +}; + +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] cyc; + +reg curbuf; +reg prevbuf = 0; +wire iobuf = !curbuf; + +wire diff0, 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 = (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); + +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; +reg wrin_en; + +function [23:0] h2rgb; + input [11:0] v; +begin + h2rgb = mono ? {v[7:0], v[7:0], v[7:0]} : {v[11:8],v[11:8],v[7:4],v[7:4],v[3:0],v[3:0]}; +end +endfunction + +function [11:0] rgb2h; + input [23:0] v; +begin + rgb2h = mono ? {4'b0000, v[23:20], v[19:16]} : {v[23:20], v[15:12], v[7:4]}; +end +endfunction + +hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in +( + .clk(clk), + + .rdaddr(offs), + .rdbuf0(prevbuf), + .rdbuf1(curbuf), + .q0(Curr20tmp), + .q1(Curr21tmp), + + .wraddr(wrin_addr2), + .wrbuf(iobuf), + .data(wrpix), + .wren(wrin_en) +); + +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; + +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 +( + .clock(clk), + + .rdaddress({read_x[AWIDTH+1:1],read_y[1]}), + .q(outpixel_x4), + + .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 old_reset_line; + reg old_reset_frame; + + wrout_en <= 0; + wrin_en <= 0; + + if(ce_x4) begin + + pattern <= new_pattern; + if(read_x[0]) outpixel_x2 <= read_y[0] ? outpixel_x4[DWIDTH1*4-1:DWIDTH1*2] : outpixel_x4[DWIDTH1*2-1:0]; + + if(~&offs) begin + if (cyc == 1) begin + Prev2 <= Curr20; + Curr2 <= Curr21; + Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel; + wrpix <= inputpixel; + wrin_addr2 <= offs; + wrin_en <= 1; + end + + 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 + end + + 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}; + {Prev0, Prev1} <= {Prev1, Prev2}; + {Curr0, Curr1} <= {Curr1, Curr2}; + {Next0, Next1} <= {Next1, Next2}; + end else begin + nextpatt <= {nextpatt[5], nextpatt[3], nextpatt[0], nextpatt[6], nextpatt[1], nextpatt[7], nextpatt[4], nextpatt[2]}; + {B, F, H, D} <= {F, H, D, B}; + end + + cyc <= cyc + 1'b1; + if(old_reset_line && ~reset_line) begin + old_reset_frame <= reset_frame; + offs <= 0; + cyc <= 0; + curbuf <= ~curbuf; + prevbuf <= curbuf; + {Prev0, Prev1, Prev2, Curr0, Curr1, Curr2, Next0, Next1, Next2} <= '0; + if(old_reset_frame & ~reset_frame) begin + 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 +end + +endmodule + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +module hq2x_in #(parameter LENGTH, parameter DWIDTH) +( + input clk, + + input [AWIDTH:0] rdaddr, + input rdbuf0, rdbuf1, + output[DWIDTH:0] q0,q1, + + input [AWIDTH:0] wraddr, + input wrbuf, + input [DWIDTH:0] data, + input wren +); + + 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_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH) +( + input clock, + input [DWIDTH:0] data, + input [AWIDTH:0] rdaddress, + input [AWIDTH:0] wraddress, + input wren, + output logic [DWIDTH:0] q +); + +logic [DWIDTH:0] ram[0:NUMWORDS-1]; + +always_ff@(posedge clock) begin + if(wren) ram[wraddress] <= data; + q <= ram[rdaddress]; +end + +endmodule + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +module DiffCheck +( + input [23:0] rgb1, + input [23:0] rgb2, + output result +); + + wire [7:0] r = rgb1[7:1] - rgb2[7:1]; + wire [7:0] g = rgb1[15:9] - rgb2[15:9]; + wire [7:0] b = rgb1[23:17] - rgb2[23:17]; + wire [8:0] t = $signed(r) + $signed(b); + wire [8:0] gx = {g[7], g}; + wire [9:0] y = $signed(t) + $signed(gx); + wire [8:0] u = $signed(r) - $signed(b); + wire [9:0] v = $signed({g, 1'b0}) - $signed(t); + + // if y is inside (-96..96) + wire y_inside = (y < 10'h60 || y >= 10'h3a0); + + // if u is inside (-16, 16) + wire u_inside = (u < 9'h10 || u >= 9'h1f0); + + // if v is inside (-24, 24) + wire v_inside = (v < 10'h18 || v >= 10'h3e8); + assign result = !(y_inside && u_inside && v_inside); +endmodule + +module InnerBlend +( + input [8:0] Op, + input [7:0] A, + input [7:0] B, + input [7:0] C, + output [7:0] O +); + + function [10:0] mul8x3; + input [7:0] op1; + input [2:0] op2; + begin + mul8x3 = 11'd0; + if(op2[0]) mul8x3 = mul8x3 + op1; + if(op2[1]) mul8x3 = mul8x3 + {op1, 1'b0}; + if(op2[2]) mul8x3 = mul8x3 + {op1, 2'b00}; + end + endfunction + + wire OpOnes = Op[4]; + wire [10:0] Amul = mul8x3(A, Op[7:5]); + wire [10:0] Bmul = mul8x3(B, {Op[3:2], 1'b0}); + wire [10:0] Cmul = mul8x3(C, {Op[1:0], 1'b0}); + wire [10:0] At = Amul; + wire [10:0] Bt = (OpOnes == 0) ? Bmul : {3'b0, B}; + wire [10:0] Ct = (OpOnes == 0) ? Cmul : {3'b0, C}; + wire [11:0] Res = {At, 1'b0} + Bt + Ct; + assign O = Op[8] ? A : Res[11:4]; +endmodule + +module Blend +( + input [5:0] rule, + input disable_hq2x, + input [23:0] E, + input [23:0] A, + input [23:0] B, + input [23:0] D, + input [23:0] F, + input [23:0] H, + output [23:0] Result +); + + reg [1:0] input_ctrl; + reg [8:0] op; + localparam BLEND0 = 9'b1_xxx_x_xx_xx; // 0: A + localparam BLEND1 = 9'b0_110_0_10_00; // 1: (A * 12 + B * 4) >> 4 + localparam BLEND2 = 9'b0_100_0_10_10; // 2: (A * 8 + B * 4 + C * 4) >> 4 + localparam BLEND3 = 9'b0_101_0_10_01; // 3: (A * 10 + B * 4 + C * 2) >> 4 + localparam BLEND4 = 9'b0_110_0_01_01; // 4: (A * 12 + B * 2 + C * 2) >> 4 + localparam BLEND5 = 9'b0_010_0_11_11; // 5: (A * 4 + (B + C) * 6) >> 4 + localparam BLEND6 = 9'b0_111_1_xx_xx; // 6: (A * 14 + B + C) >> 4 + localparam AB = 2'b00; + localparam AD = 2'b01; + localparam DB = 2'b10; + localparam BD = 2'b11; + wire is_diff; + DiffCheck diff_checker(rule[1] ? B : H, rule[0] ? D : F, is_diff); + + always @* begin + case({!is_diff, rule[5:2]}) + 1,17: {op, input_ctrl} = {BLEND1, AB}; + 2,18: {op, input_ctrl} = {BLEND1, DB}; + 3,19: {op, input_ctrl} = {BLEND1, BD}; + 4,20: {op, input_ctrl} = {BLEND2, DB}; + 5,21: {op, input_ctrl} = {BLEND2, AB}; + 6,22: {op, input_ctrl} = {BLEND2, AD}; + + 8: {op, input_ctrl} = {BLEND0, 2'bxx}; + 9: {op, input_ctrl} = {BLEND0, 2'bxx}; + 10: {op, input_ctrl} = {BLEND0, 2'bxx}; + 11: {op, input_ctrl} = {BLEND1, AB}; + 12: {op, input_ctrl} = {BLEND1, AB}; + 13: {op, input_ctrl} = {BLEND1, AB}; + 14: {op, input_ctrl} = {BLEND1, DB}; + 15: {op, input_ctrl} = {BLEND1, BD}; + + 24: {op, input_ctrl} = {BLEND2, DB}; + 25: {op, input_ctrl} = {BLEND5, DB}; + 26: {op, input_ctrl} = {BLEND6, DB}; + 27: {op, input_ctrl} = {BLEND2, DB}; + 28: {op, input_ctrl} = {BLEND4, DB}; + 29: {op, input_ctrl} = {BLEND5, DB}; + 30: {op, input_ctrl} = {BLEND3, BD}; + 31: {op, input_ctrl} = {BLEND3, DB}; + default: {op, input_ctrl} = {11{1'bx}}; + endcase + + // Setting op[8] effectively disables HQ2X because blend will always return E. + if (disable_hq2x) op[8] = 1; + end + + // Generate inputs to the inner blender. Valid combinations. + // 00: E A B + // 01: E A D + // 10: E D B + // 11: E B D + wire [23:0] Input1 = E; + wire [23:0] Input2 = !input_ctrl[1] ? A : + !input_ctrl[0] ? D : B; + + wire [23:0] Input3 = !input_ctrl[0] ? B : D; + InnerBlend inner_blend1(op, Input1[7:0], Input2[7:0], Input3[7:0], Result[7:0]); + InnerBlend inner_blend2(op, Input1[15:8], Input2[15:8], Input3[15:8], Result[15:8]); + InnerBlend inner_blend3(op, Input1[23:16], Input2[23:16], Input3[23:16], Result[23:16]); +endmodule diff --git a/sys/i2c.v b/sys/i2c.v new file mode 100644 index 0000000..ace6293 --- /dev/null +++ b/sys/i2c.v @@ -0,0 +1,69 @@ + +module i2c +( + input CLK, + + input START, + input [23:0] I2C_DATA, + output reg END = 1, + output reg ACK = 0, + + //I2C bus + output I2C_SCL, + inout I2C_SDA +); + + +// Clock Setting +parameter CLK_Freq = 50_000_000; // 50 MHz +parameter I2C_Freq = 400_000; // 400 KHz + +reg I2C_CLOCK; +always@(negedge CLK) begin + integer mI2C_CLK_DIV = 0; + if(mI2C_CLK_DIV < (CLK_Freq/I2C_Freq)) begin + mI2C_CLK_DIV <= mI2C_CLK_DIV + 1; + end else begin + mI2C_CLK_DIV <= 0; + I2C_CLOCK <= ~I2C_CLOCK; + end +end + +assign I2C_SCL = SCLK | I2C_CLOCK; +assign I2C_SDA = SDO ? 1'bz : 1'b0; + +reg SCLK = 1, SDO = 1; + +always @(posedge CLK) begin + reg old_clk; + reg old_st; + + reg [5:0] SD_COUNTER = 'b111111; + reg [0:31] SD; + + old_clk <= I2C_CLOCK; + old_st <= START; + + if(~old_st && START) begin + SCLK <= 1; + SDO <= 1; + ACK <= 0; + END <= 0; + SD <= {2'b10, I2C_DATA[23:16], 1'b1, I2C_DATA[15:8], 1'b1, I2C_DATA[7:0], 4'b1011}; + SD_COUNTER <= 0; + end else begin + if(~old_clk && I2C_CLOCK && ~&SD_COUNTER) begin + SD_COUNTER <= SD_COUNTER + 6'd1; + case(SD_COUNTER) + 01: SCLK <= 0; + 10,19,28: ACK <= ACK | I2C_SDA; + 29: SCLK <= 1; + 32: END <= 1; + endcase + end + + if(old_clk && ~I2C_CLOCK && ~SD_COUNTER[5]) SDO <= SD[SD_COUNTER[4:0]]; + end +end + +endmodule diff --git a/sys/i2s.v b/sys/i2s.v new file mode 100644 index 0000000..b4c2d95 --- /dev/null +++ b/sys/i2s.v @@ -0,0 +1,136 @@ + +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 diff --git a/sys/ip/avalon_combiner.v b/sys/ip/avalon_combiner.v new file mode 100644 index 0000000..164906c --- /dev/null +++ b/sys/ip/avalon_combiner.v @@ -0,0 +1,60 @@ +// 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 new file mode 100644 index 0000000..5eede9c --- /dev/null +++ b/sys/ip/avalon_combiner_hw.tcl @@ -0,0 +1,204 @@ +# 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 new file mode 100644 index 0000000..a166ca0 --- /dev/null +++ b/sys/ip/de10_hps_hw.tcl @@ -0,0 +1,3706 @@ +# (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 new file mode 100644 index 0000000..9e141e4 --- /dev/null +++ b/sys/ip/in_split.v @@ -0,0 +1,52 @@ +// 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 new file mode 100644 index 0000000..403555a --- /dev/null +++ b/sys/ip/in_split_hw.tcl @@ -0,0 +1,104 @@ +# 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 new file mode 100644 index 0000000..280a3d5 --- /dev/null +++ b/sys/ip/out_mix.v @@ -0,0 +1,44 @@ +// 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 new file mode 100644 index 0000000..b388891 --- /dev/null +++ b/sys/ip/out_mix_hw.tcl @@ -0,0 +1,97 @@ +# 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 new file mode 100644 index 0000000..569eb9c --- /dev/null +++ b/sys/ip/reset_source.v @@ -0,0 +1,50 @@ +// 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 new file mode 100644 index 0000000..cba39f7 --- /dev/null +++ b/sys/ip/reset_source_hw.tcl @@ -0,0 +1,152 @@ +# 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 new file mode 100644 index 0000000..2a32981 --- /dev/null +++ b/sys/lpf48k.sv @@ -0,0 +1,100 @@ +// 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 new file mode 100644 index 0000000..f6e8915 --- /dev/null +++ b/sys/osd.v @@ -0,0 +1,199 @@ +// A simple OSD implementation. Can be hooked up between a cores +// VGA output and the physical VGA pins + +module osd +( + input clk_sys, + + input io_osd, + input io_strobe, + input [15:0] io_din, + + input clk_video, + input [23:0] din, + output [23:0] dout, + input de_in, + output reg de_out +); + +parameter OSD_COLOR = 3'd4; +parameter OSD_X_OFFSET = 12'd0; +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 highres = 0; +reg info = 0; +reg [8:0] infoh; +reg [8:0] infow; +reg [11:0] infox; +reg [21:0] infoy; + +always@(posedge clk_sys) begin + reg [11:0] bcnt; + reg [7:0] cmd; + reg has_cmd; + reg old_strobe; + + old_strobe <= io_strobe; + + if(~io_osd) begin + bcnt <= 0; + has_cmd <= 0; + cmd <= 0; + if(cmd[7:4] == 4) osd_enable <= cmd[0]; + end else begin + if(~old_strobe & io_strobe) begin + if(!has_cmd) begin + has_cmd <= 1; + cmd <= io_din[7:0]; + // command 0x40: OSDCMDENABLE, OSDCMDDISABLE + if(io_din[7:4] == 4) begin + if(!io_din[0]) highres <= 0; + info <= io_din[2]; + bcnt <= 0; + end + // command 0x20: OSDCMDWRITE + if(io_din[7:4] == 2) begin + if(io_din[3]) highres <= 1; + bcnt <= {io_din[3:0], 8'h00}; + end + end else begin + // command 0x40: OSDCMDENABLE, OSDCMDDISABLE + if(cmd[7:4] == 4) begin + if(bcnt == 0) infox <= io_din[11:0]; + if(bcnt == 1) infoy <= io_din[11:0]; + if(bcnt == 2) infow <= {io_din[5:0], 3'b000}; + if(bcnt == 3) infoh <= {io_din[5:0], 3'b000}; + end + + // command 0x20: OSDCMDWRITE + if(cmd[7:4] == 2) osd_buffer[bcnt] <= io_din[7:0]; + + bcnt <= bcnt + 1'd1; + end + end + end +end + +reg ce_pix; +always @(negedge clk_video) begin + integer cnt = 0; + integer pixsz, pixcnt; + reg deD; + + cnt <= cnt + 1; + deD <= de_in; + + pixcnt <= pixcnt + 1; + if(pixcnt == pixsz) pixcnt <= 0; + ce_pix <= !pixcnt; + + if(~deD && de_in) cnt <= 0; + + if(deD && ~de_in) begin + pixsz <= (((cnt+1'b1) >> 9) > 1) ? (((cnt+1'b1) >> 9) - 1) : 0; + pixcnt <= 0; + end +end + +reg [23:0] h_cnt; +reg [21:0] v_cnt; +reg [21:0] dsp_width; +reg [21:0] dsp_height; +reg [7:0] osd_byte; +reg [21:0] osd_vcnt; +reg [21:0] fheight; + +reg [21:0] finfoy; +wire [21:0] hrheight = info ? infoh : (OSD_HEIGHT< {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 + end + else begin + fheight <= 0; + 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; + 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]}]; + 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]}}; + de_out <= de_in; +end + +endmodule diff --git a/sys/pattern_vg.v b/sys/pattern_vg.v new file mode 100644 index 0000000..6379278 --- /dev/null +++ b/sys/pattern_vg.v @@ -0,0 +1,120 @@ +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.qip b/sys/pll.qip new file mode 100644 index 0000000..774e449 --- /dev/null +++ b/sys/pll.qip @@ -0,0 +1,337 @@ +set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_VERSION "17.0" +set_global_assignment -entity "pll" -library "pll" -name IP_TOOL_ENV "mwpim" +set_global_assignment -library "pll" -name MISC_FILE [file join $::quartus(qip_path) "pll.cmp"] +set_global_assignment -entity "pll" -library "pll" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V" +set_global_assignment -entity "pll" -library "pll" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" +set_global_assignment -entity "pll" -library "pll" -name IP_QSYS_MODE "UNKNOWN" +set_global_assignment -name SYNTHESIS_ONLY_QIP ON +set_global_assignment -entity "pll" -library "pll" -name IP_COMPONENT_NAME "cGxs" +set_global_assignment -entity "pll" -library "pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" +set_global_assignment -entity "pll" -library "pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "pll" -library "pll" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "pll" -library "pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "pll" -library "pll" -name IP_COMPONENT_VERSION "MTcuMA==" +set_global_assignment -entity "pll" -library "pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_NAME "cGxsXzAwMDI=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_VERSION "MTcuMA==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfcHJpbnRfb3V0cHV0::ZmFsc2U=::ZGVidWdfcHJpbnRfb3V0cHV0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k::ZmFsc2U=::ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZGV2aWNl::NUNFQkEyRjE3QTc=::ZGV2aWNl" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9tb2Rl::RnJhY3Rpb25hbC1OIFBMTA==::UExMIE1vZGU=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==::dHJ1ZQ==::ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmVyZW5jZV9jbG9ja19mcmVxdWVuY3k=::NTAuMA==::UmVmZXJlbmNlIENsb2NrIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==::NTAuMCBNSHo=::cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2NoYW5uZWxfc3BhY2luZw==::MC4w::Q2hhbm5lbCBTcGFjaW5n" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX29wZXJhdGlvbl9tb2Rl::ZGlyZWN0::T3BlcmF0aW9uIE1vZGU=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZlZWRiYWNrX2Nsb2Nr::R2xvYmFsIENsb2Nr::RmVlZGJhY2sgQ2xvY2s=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWN0aW9uYWxfY291dA==::MzI=::RnJhY3Rpb25hbCBjYXJyeSBvdXQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RzbV9vdXRfc2Vs::MXN0X29yZGVy::RFNNIE9yZGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3BlcmF0aW9uX21vZGU=::ZGlyZWN0::b3BlcmF0aW9uX21vZGU=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9sb2NrZWQ=::dHJ1ZQ==::RW5hYmxlIGxvY2tlZCBvdXRwdXQgcG9ydA==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Fkdl9wYXJhbXM=::ZmFsc2U=::RW5hYmxlIHBoeXNpY2FsIG91dHB1dCBjbG9jayBwYXJhbWV0ZXJz" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::NA==::TnVtYmVyIE9mIENsb2Nrcw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::NA==::bnVtYmVyX29mX2Nsb2Nrcw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX211bHRpcGx5X2ZhY3Rvcg==::MQ==::TXVsdGlwbHkgRmFjdG9yIChNLUNvdW50ZXIp" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWNfbXVsdGlwbHlfZmFjdG9y::MQ==::RnJhY3Rpb25hbCBNdWx0aXBseSBGYWN0b3IgKEsp" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3Jfbg==::MQ==::RGl2aWRlIEZhY3RvciAoTi1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjA=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kw::ODQuMA==::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzA=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iw::MjY=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjA=::Mzc3OTU3MTEzNQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMA==::MTY=::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzA=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDA=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUw::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kx::ODQuMA==::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Ix::MjY=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE=::Mzc3OTU3MTEzNQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMQ==::MTY=::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MQ==::LTQyMDA=::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE=::MTgwLjA=::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUx::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjI=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3ky::NTYuMA==::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzI=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::MjY=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjI=::Mzc3OTU3MTEzNQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::MjQ=::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mg==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mg==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzI=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDI=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUy::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjM=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kz::MjguMA==::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzM=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iz::MjY=::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjM=::Mzc3OTU3MTEzNQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMw==::NDg=::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mw==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzM=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDM=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUz::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjQ=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k0::My41Nzk1NDU=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzQ=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I0::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjQ=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzQ=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDQ=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU0::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjU=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k1::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzU=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I1::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjU=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzU=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDU=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU1::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjY=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k2::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzY=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I2::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjY=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Ng==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Ng==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzY=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDY=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU2::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjc=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k3::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzc=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I3::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjc=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNw==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Nw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Nw==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzc=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDc=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU3::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjg=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k4::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzg=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I4::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjg=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzg=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDg=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU4::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjk=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k5::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzk=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I5::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjk=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzk=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDk=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU5::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEw::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEw::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEw::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTA=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTA=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTA=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTA=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEw::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEw::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMA==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEx::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEx::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEx::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTE=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTE=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTE=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTE=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEx::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEx::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMQ==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEy::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEy::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEy::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTI=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTI=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTI=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTI=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEy::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEy::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMg==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEz::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEz::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEz::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTM=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTM=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTM=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTM=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEz::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEz::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMw==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE0::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE0::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE0::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTQ=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTQ=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTQ=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTQ=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE0::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE0::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNA==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE1::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE1::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE1::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTU=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTU=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTU=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTU=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE1::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE1::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNQ==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE2::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE2::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE2::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTY=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTY=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTY=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTY=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE2::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE2::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNg==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE3::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE3::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE3::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTc=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTc=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTc=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTc=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE3::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE3::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNw==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=::ODQuMDAwMDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQw::MCBwcw==::cGhhc2Vfc2hpZnQw" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTA=::NTA=::ZHV0eV9jeWNsZTA=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=::ODQuMDAwMDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQx::LTQxODUgcHM=::cGhhc2Vfc2hpZnQx" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE=::NTA=::ZHV0eV9jeWNsZTE=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::NTYuMDAwMDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQy::MCBwcw==::cGhhc2Vfc2hpZnQy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTI=::NTA=::ZHV0eV9jeWNsZTI=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=::MjguMDAwMDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQz::MCBwcw==::cGhhc2Vfc2hpZnQz" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTM=::NTA=::ZHV0eV9jeWNsZTM=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ0::MCBwcw==::cGhhc2Vfc2hpZnQ0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTQ=::NTA=::ZHV0eV9jeWNsZTQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ1::MCBwcw==::cGhhc2Vfc2hpZnQ1" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTU=::NTA=::ZHV0eV9jeWNsZTU=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ2::MCBwcw==::cGhhc2Vfc2hpZnQ2" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTY=::NTA=::ZHV0eV9jeWNsZTY=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ3::MCBwcw==::cGhhc2Vfc2hpZnQ3" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTc=::NTA=::ZHV0eV9jeWNsZTc=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ4::MCBwcw==::cGhhc2Vfc2hpZnQ4" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTg=::NTA=::ZHV0eV9jeWNsZTg=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ5::MCBwcw==::cGhhc2Vfc2hpZnQ5" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTk=::NTA=::ZHV0eV9jeWNsZTk=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMA==::MCBwcw==::cGhhc2Vfc2hpZnQxMA==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEw::NTA=::ZHV0eV9jeWNsZTEw" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMQ==::MCBwcw==::cGhhc2Vfc2hpZnQxMQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEx::NTA=::ZHV0eV9jeWNsZTEx" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMg==::MCBwcw==::cGhhc2Vfc2hpZnQxMg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEy::NTA=::ZHV0eV9jeWNsZTEy" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMw==::MCBwcw==::cGhhc2Vfc2hpZnQxMw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEz::NTA=::ZHV0eV9jeWNsZTEz" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNA==::MCBwcw==::cGhhc2Vfc2hpZnQxNA==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE0::NTA=::ZHV0eV9jeWNsZTE0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNQ==::MCBwcw==::cGhhc2Vfc2hpZnQxNQ==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE1::NTA=::ZHV0eV9jeWNsZTE1" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNg==::MCBwcw==::cGhhc2Vfc2hpZnQxNg==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE2::NTA=::ZHV0eV9jeWNsZTE2" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNw==::MCBwcw==::cGhhc2Vfc2hpZnQxNw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE3::NTA=::ZHV0eV9jeWNsZTE3" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9hdXRvX3Jlc2V0::T24=::UExMIEF1dG8gUmVzZXQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9iYW5kd2lkdGhfcHJlc2V0::QXV0bw==::UExMIEJhbmR3aWR0aCBQcmVzZXQ=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3JlY29uZg==::ZmFsc2U=::RW5hYmxlIGR5bmFtaWMgcmVjb25maWd1cmF0aW9uIG9mIFBMTA==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Rwc19wb3J0cw==::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBkeW5hbWljIHBoYXNlIHNoaWZ0IHBvcnRz" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3Bob3V0X3BvcnRz::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBQTEwgRFBBIG91dHB1dCBwb3J0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGxsX3R5cGU=::R2VuZXJhbA==::UExMIFRZUEU=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "cGxsX3N1YnR5cGU=::R2VuZXJhbA==::UExMIFNVQlRZUEU=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTIgSGkgRGl2aWRlLEMtQ291bnRlci0yIExvdyBEaXZpZGUsQy1Db3VudGVyLTIgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0yIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTIgSW5wdXQgU291cmNlLEMtQ291bnRlci0yIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTMgSGkgRGl2aWRlLEMtQ291bnRlci0zIExvdyBEaXZpZGUsQy1Db3VudGVyLTMgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0zIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTMgSW5wdXQgU291cmNlLEMtQ291bnRlci0zIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTMgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::MTMsMTMsMjU2LDI1NixmYWxzZSx0cnVlLGZhbHNlLGZhbHNlLDgsOCwxLDAscGhfbXV4X2NsayxmYWxzZSxmYWxzZSw4LDgsMTEsMyxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDEyLDEyLDEsMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDI0LDI0LDEsMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDEsMjAsNDAwMCwxMzQzLjk5OTk5OSBNSHosMzc3OTU3MTEzNSxub25lLGdsYixtX2NudCxwaF9tdXhfY2xrLHRydWU=::UGFyYW1ldGVyIFZhbHVlcw==" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX21pZl9nZW5lcmF0ZQ==::ZmFsc2U=::R2VuZXJhdGUgTUlGIGZpbGU=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9taWZfZHBz::ZmFsc2U=::RW5hYmxlIER5bmFtaWMgUGhhc2UgU2hpZnQgZm9yIE1JRiBzdHJlYW1pbmc=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19jbnRy::QzA=::RFBTIENvdW50ZXIgU2VsZWN0aW9u" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19udW0=::MQ==::TnVtYmVyIG9mIER5bmFtaWMgUGhhc2UgU2hpZnRz" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19kaXI=::UG9zaXRpdmU=::RHluYW1pYyBQaGFzZSBTaGlmdCBEaXJlY3Rpb24=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmNsa19zd2l0Y2g=::ZmFsc2U=::Q3JlYXRlIGEgc2Vjb25kIGlucHV0IGNsayAncmVmY2xrMSc=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX291dA==::ZmFsc2U=::Q3JlYXRlIGEgJ2Nhc2NhZGVfb3V0JyBzaWduYWwgdG8gY29ubmVjdCB3aXRoIGEgZG93bnN0cmVhbSBQTEw=" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX2lu::ZmFsc2U=::Q3JlYXRlIGFuIGFkanBsbGluIG9yIGNjbGsgc2lnbmFsIHRvIGNvbm5lY3Qgd2l0aCBhbiB1cHN0cmVhbSBQTEw=" + +set_global_assignment -library "pll" -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"] +set_global_assignment -library "pll" -name VERILOG_FILE [file join $::quartus(qip_path) "pll/pll_0002.v"] +set_global_assignment -library "pll" -name QIP_FILE [file join $::quartus(qip_path) "pll/pll_0002.qip"] + +set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_VERSION "17.0" +set_global_assignment -entity "pll_0002" -library "pll" -name IP_TOOL_ENV "mwpim" diff --git a/sys/pll.v b/sys/pll.v new file mode 100644 index 0000000..76845b0 --- /dev/null +++ b/sys/pll.v @@ -0,0 +1,259 @@ +// megafunction wizard: %Altera PLL v17.0% +// GENERATION: XML +// pll.v + +// Generated using ACDS version 17.0 598 + +`timescale 1 ps / 1 ps +module pll ( + input wire refclk, // refclk.clk + input wire rst, // reset.reset + output wire outclk_0, // outclk0.clk + output wire outclk_1, // outclk1.clk + output wire outclk_2, // outclk2.clk + output wire outclk_3, // outclk3.clk + output wire locked // locked.export + ); + + pll_0002 pll_inst ( + .refclk (refclk), // refclk.clk + .rst (rst), // reset.reset + .outclk_0 (outclk_0), // outclk0.clk + .outclk_1 (outclk_1), // outclk1.clk + .outclk_2 (outclk_2), // outclk2.clk + .outclk_3 (outclk_3), // outclk3.clk + .locked (locked) // locked.export + ); + +endmodule +// Retrieval info: +// +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// IPFS_FILES : pll.vo +// RELATED_FILES: pll.v, pll_0002.v diff --git a/sys/pll/pll_0002.qip b/sys/pll/pll_0002.qip new file mode 100644 index 0000000..9f8ded1 --- /dev/null +++ b/sys/pll/pll_0002.qip @@ -0,0 +1,4 @@ +set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_AUTO_RESET ON -to "*pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*pll_0002*|altera_pll:altera_pll_i*|*" diff --git a/sys/pll/pll_0002.v b/sys/pll/pll_0002.v new file mode 100644 index 0000000..b916f92 --- /dev/null +++ b/sys/pll/pll_0002.v @@ -0,0 +1,96 @@ +`timescale 1ns/10ps +module pll_0002( + + // interface 'refclk' + input wire refclk, + + // interface 'reset' + input wire rst, + + // interface 'outclk0' + output wire outclk_0, + + // interface 'outclk1' + output wire outclk_1, + + // interface 'outclk2' + output wire outclk_2, + + // interface 'outclk3' + output wire outclk_3, + + // interface 'locked' + output wire locked +); + + altera_pll #( + .fractional_vco_multiplier("true"), + .reference_clock_frequency("50.0 MHz"), + .operation_mode("direct"), + .number_of_clocks(4), + .output_clock_frequency0("84.000000 MHz"), + .phase_shift0("0 ps"), + .duty_cycle0(50), + .output_clock_frequency1("84.000000 MHz"), + .phase_shift1("-4185 ps"), + .duty_cycle1(50), + .output_clock_frequency2("56.000000 MHz"), + .phase_shift2("0 ps"), + .duty_cycle2(50), + .output_clock_frequency3("28.000000 MHz"), + .phase_shift3("0 ps"), + .duty_cycle3(50), + .output_clock_frequency4("0 MHz"), + .phase_shift4("0 ps"), + .duty_cycle4(50), + .output_clock_frequency5("0 MHz"), + .phase_shift5("0 ps"), + .duty_cycle5(50), + .output_clock_frequency6("0 MHz"), + .phase_shift6("0 ps"), + .duty_cycle6(50), + .output_clock_frequency7("0 MHz"), + .phase_shift7("0 ps"), + .duty_cycle7(50), + .output_clock_frequency8("0 MHz"), + .phase_shift8("0 ps"), + .duty_cycle8(50), + .output_clock_frequency9("0 MHz"), + .phase_shift9("0 ps"), + .duty_cycle9(50), + .output_clock_frequency10("0 MHz"), + .phase_shift10("0 ps"), + .duty_cycle10(50), + .output_clock_frequency11("0 MHz"), + .phase_shift11("0 ps"), + .duty_cycle11(50), + .output_clock_frequency12("0 MHz"), + .phase_shift12("0 ps"), + .duty_cycle12(50), + .output_clock_frequency13("0 MHz"), + .phase_shift13("0 ps"), + .duty_cycle13(50), + .output_clock_frequency14("0 MHz"), + .phase_shift14("0 ps"), + .duty_cycle14(50), + .output_clock_frequency15("0 MHz"), + .phase_shift15("0 ps"), + .duty_cycle15(50), + .output_clock_frequency16("0 MHz"), + .phase_shift16("0 ps"), + .duty_cycle16(50), + .output_clock_frequency17("0 MHz"), + .phase_shift17("0 ps"), + .duty_cycle17(50), + .pll_type("General"), + .pll_subtype("General") + ) altera_pll_i ( + .rst (rst), + .outclk ({outclk_3, outclk_2, outclk_1, outclk_0}), + .locked (locked), + .fboutclk ( ), + .fbclk (1'b0), + .refclk (refclk) + ); +endmodule + diff --git a/sys/pll_hdmi.qip b/sys/pll_hdmi.qip new file mode 100644 index 0000000..be34aeb --- /dev/null +++ b/sys/pll_hdmi.qip @@ -0,0 +1,483 @@ +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 "17.0" +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 -entity "pll_hdmi" -library "pll_hdmi" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_QSYS_MODE "UNKNOWN" +set_global_assignment -name SYNTHESIS_ONLY_QIP ON +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_COMPONENT_NAME "cGxsX2hkbWk=" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_COMPONENT_VERSION "MTcuMA==" +set_global_assignment -entity "pll_hdmi" -library "pll_hdmi" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_NAME "cGxsX2hkbWlfMDAwMg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_VERSION "MTcuMA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZGVidWdfcHJpbnRfb3V0cHV0::ZmFsc2U=::ZGVidWdfcHJpbnRfb3V0cHV0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k::ZmFsc2U=::ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZGV2aWNl::NUNFQkEyRjE3QTc=::ZGV2aWNl" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9tb2Rl::RnJhY3Rpb25hbC1OIFBMTA==::UExMIE1vZGU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==::dHJ1ZQ==::ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmVyZW5jZV9jbG9ja19mcmVxdWVuY3k=::NTAuMA==::UmVmZXJlbmNlIENsb2NrIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==::NTAuMCBNSHo=::cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2NoYW5uZWxfc3BhY2luZw==::MC4w::Q2hhbm5lbCBTcGFjaW5n" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX29wZXJhdGlvbl9tb2Rl::ZGlyZWN0::T3BlcmF0aW9uIE1vZGU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2ZlZWRiYWNrX2Nsb2Nr::R2xvYmFsIENsb2Nr::RmVlZGJhY2sgQ2xvY2s=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWN0aW9uYWxfY291dA==::MzI=::RnJhY3Rpb25hbCBjYXJyeSBvdXQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX2ZyYWN0aW9uYWxfY291dA==::MzI=::cGxsX2ZyYWN0aW9uYWxfY291dA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RzbV9vdXRfc2Vs::MXN0X29yZGVy::RFNNIE9yZGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX2RzbV9vdXRfc2Vs::MXN0X29yZGVy::cGxsX2RzbV9vdXRfc2Vs" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3BlcmF0aW9uX21vZGU=::ZGlyZWN0::b3BlcmF0aW9uX21vZGU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9sb2NrZWQ=::ZmFsc2U=::RW5hYmxlIGxvY2tlZCBvdXRwdXQgcG9ydA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Fkdl9wYXJhbXM=::ZmFsc2U=::RW5hYmxlIHBoeXNpY2FsIG91dHB1dCBjbG9jayBwYXJhbWV0ZXJz" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::MQ==::TnVtYmVyIE9mIENsb2Nrcw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::MQ==::bnVtYmVyX29mX2Nsb2Nrcw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX211bHRpcGx5X2ZhY3Rvcg==::MQ==::TXVsdGlwbHkgRmFjdG9yIChNLUNvdW50ZXIp" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWNfbXVsdGlwbHlfZmFjdG9y::MQ==::RnJhY3Rpb25hbCBNdWx0aXBseSBGYWN0b3IgKEsp" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3Jfbg==::MQ==::RGl2aWRlIEZhY3RvciAoTi1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjA=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kw::MTQ4LjU=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzA=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iw::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjA=::MzkwODQyMDE1Mw==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMA==::Mw==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzA=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDA=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUw::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kx::NjUuMA==::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Ix::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUx::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjI=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3ky::MjcuMA==::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzI=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjI=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mg==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mg==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzI=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDI=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUy::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjM=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kz::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzM=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iz::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjM=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMw==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mw==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzM=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDM=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUz::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjQ=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k0::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzQ=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I0::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjQ=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzQ=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDQ=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU0::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjU=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k1::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzU=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I1::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjU=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzU=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDU=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU1::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjY=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k2::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzY=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I2::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjY=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Ng==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Ng==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzY=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDY=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU2::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjc=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k3::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzc=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I3::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjc=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNw==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Nw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Nw==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzc=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDc=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU3::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjg=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k4::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzg=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I4::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjg=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzg=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDg=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU4::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjk=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k5::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzk=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I5::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjk=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzk=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDk=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU5::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEw::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEw::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEw::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTA=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTA=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTA=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTA=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEw::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEw::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMA==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEx::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEx::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEx::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTE=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTE=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTE=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTE=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEx::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEx::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMQ==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEy::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEy::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEy::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTI=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTI=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTI=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTI=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEy::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEy::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMg==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEz::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEz::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEz::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTM=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTM=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTM=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTM=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEz::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEz::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMw==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE0::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE0::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE0::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTQ=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTQ=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTQ=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTQ=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE0::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE0::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNA==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE1::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE1::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE1::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTU=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTU=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTU=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTU=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE1::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE1::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNQ==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE2::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE2::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE2::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTY=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTY=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTY=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTY=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE2::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE2::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNg==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE3::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE3::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE3::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTc=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTc=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTc=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTc=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE3::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE3::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNw==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=::MTQ4LjUwMDAwMCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQw::MCBwcw==::cGhhc2Vfc2hpZnQw" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTA=::NTA=::ZHV0eV9jeWNsZTA=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQx::MCBwcw==::cGhhc2Vfc2hpZnQx" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE=::NTA=::ZHV0eV9jeWNsZTE=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQy::MCBwcw==::cGhhc2Vfc2hpZnQy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTI=::NTA=::ZHV0eV9jeWNsZTI=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQz::MCBwcw==::cGhhc2Vfc2hpZnQz" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTM=::NTA=::ZHV0eV9jeWNsZTM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ0::MCBwcw==::cGhhc2Vfc2hpZnQ0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTQ=::NTA=::ZHV0eV9jeWNsZTQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ1::MCBwcw==::cGhhc2Vfc2hpZnQ1" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTU=::NTA=::ZHV0eV9jeWNsZTU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ2::MCBwcw==::cGhhc2Vfc2hpZnQ2" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTY=::NTA=::ZHV0eV9jeWNsZTY=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ3::MCBwcw==::cGhhc2Vfc2hpZnQ3" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTc=::NTA=::ZHV0eV9jeWNsZTc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ4::MCBwcw==::cGhhc2Vfc2hpZnQ4" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTg=::NTA=::ZHV0eV9jeWNsZTg=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ5::MCBwcw==::cGhhc2Vfc2hpZnQ5" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTk=::NTA=::ZHV0eV9jeWNsZTk=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMA==::MCBwcw==::cGhhc2Vfc2hpZnQxMA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEw::NTA=::ZHV0eV9jeWNsZTEw" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMQ==::MCBwcw==::cGhhc2Vfc2hpZnQxMQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEx::NTA=::ZHV0eV9jeWNsZTEx" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMg==::MCBwcw==::cGhhc2Vfc2hpZnQxMg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEy::NTA=::ZHV0eV9jeWNsZTEy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMw==::MCBwcw==::cGhhc2Vfc2hpZnQxMw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEz::NTA=::ZHV0eV9jeWNsZTEz" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNA==::MCBwcw==::cGhhc2Vfc2hpZnQxNA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE0::NTA=::ZHV0eV9jeWNsZTE0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNQ==::MCBwcw==::cGhhc2Vfc2hpZnQxNQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE1::NTA=::ZHV0eV9jeWNsZTE1" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNg==::MCBwcw==::cGhhc2Vfc2hpZnQxNg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE2::NTA=::ZHV0eV9jeWNsZTE2" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNw==::MCBwcw==::cGhhc2Vfc2hpZnQxNw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE3::NTA=::ZHV0eV9jeWNsZTE3" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9hdXRvX3Jlc2V0::T24=::UExMIEF1dG8gUmVzZXQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9iYW5kd2lkdGhfcHJlc2V0::QXV0bw==::UExMIEJhbmR3aWR0aCBQcmVzZXQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3JlY29uZg==::dHJ1ZQ==::RW5hYmxlIGR5bmFtaWMgcmVjb25maWd1cmF0aW9uIG9mIFBMTA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Rwc19wb3J0cw==::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBkeW5hbWljIHBoYXNlIHNoaWZ0IHBvcnRz" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3Bob3V0X3BvcnRz::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBQTEwgRFBBIG91dHB1dCBwb3J0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX3R5cGU=::Q3ljbG9uZSBW::UExMIFRZUEU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX3N1YnR5cGU=::UmVjb25maWd1cmFibGU=::UExMIFNVQlRZUEU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bV9jbnRfaGlfZGl2::NA==::bV9jbnRfaGlfZGl2" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bV9jbnRfbG9fZGl2::NA==::bV9jbnRfbG9fZGl2" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bl9jbnRfaGlfZGl2::MjU2::bl9jbnRfaGlfZGl2" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bl9jbnRfbG9fZGl2::MjU2::bl9jbnRfbG9fZGl2" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bV9jbnRfYnlwYXNzX2Vu::ZmFsc2U=::bV9jbnRfYnlwYXNzX2Vu" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bl9jbnRfYnlwYXNzX2Vu::dHJ1ZQ==::bl9jbnRfYnlwYXNzX2Vu" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bV9jbnRfb2RkX2Rpdl9kdXR5X2Vu::ZmFsc2U=::bV9jbnRfb2RkX2Rpdl9kdXR5X2Vu" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bl9jbnRfb2RkX2Rpdl9kdXR5X2Vu::ZmFsc2U=::bl9jbnRfb2RkX2Rpdl9kdXR5X2Vu" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MA==::Mg==::Y19jbnRfaGlfZGl2MA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MA==::MQ==::Y19jbnRfbG9fZGl2MA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDA=::MQ==::Y19jbnRfcHJzdDA=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Qw::MA==::Y19jbnRfcGhfbXV4X3Byc3Qw" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMA==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMA==::ZmFsc2U=::Y19jbnRfYnlwYXNzX2VuMA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMA==::dHJ1ZQ==::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MQ==::MQ==::Y19jbnRfaGlfZGl2MQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MQ==::MQ==::Y19jbnRfbG9fZGl2MQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDE=::MQ==::Y19jbnRfcHJzdDE=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Qx::MA==::Y19jbnRfcGhfbXV4X3Byc3Qx" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMQ==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMQ==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMQ==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2Mg==::MQ==::Y19jbnRfaGlfZGl2Mg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2Mg==::MQ==::Y19jbnRfbG9fZGl2Mg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDI=::MQ==::Y19jbnRfcHJzdDI=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Qy::MA==::Y19jbnRfcGhfbXV4X3Byc3Qy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMg==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMg==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMg==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2Mw==::MQ==::Y19jbnRfaGlfZGl2Mw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2Mw==::MQ==::Y19jbnRfbG9fZGl2Mw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDM=::MQ==::Y19jbnRfcHJzdDM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Qz::MA==::Y19jbnRfcGhfbXV4X3Byc3Qz" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMw==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMw==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMw==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2NA==::MQ==::Y19jbnRfaGlfZGl2NA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2NA==::MQ==::Y19jbnRfbG9fZGl2NA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDQ=::MQ==::Y19jbnRfcHJzdDQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Q0::MA==::Y19jbnRfcGhfbXV4X3Byc3Q0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjNA==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjNA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuNA==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuNA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNA==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2NQ==::MQ==::Y19jbnRfaGlfZGl2NQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2NQ==::MQ==::Y19jbnRfbG9fZGl2NQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDU=::MQ==::Y19jbnRfcHJzdDU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Q1::MA==::Y19jbnRfcGhfbXV4X3Byc3Q1" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjNQ==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjNQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuNQ==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuNQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNQ==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2Ng==::MQ==::Y19jbnRfaGlfZGl2Ng==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2Ng==::MQ==::Y19jbnRfbG9fZGl2Ng==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDY=::MQ==::Y19jbnRfcHJzdDY=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Q2::MA==::Y19jbnRfcGhfbXV4X3Byc3Q2" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjNg==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjNg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuNg==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuNg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNg==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2Nw==::MQ==::Y19jbnRfaGlfZGl2Nw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2Nw==::MQ==::Y19jbnRfbG9fZGl2Nw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDc=::MQ==::Y19jbnRfcHJzdDc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Q3::MA==::Y19jbnRfcGhfbXV4X3Byc3Q3" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjNw==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjNw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuNw==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuNw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNw==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuNw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2OA==::MQ==::Y19jbnRfaGlfZGl2OA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2OA==::MQ==::Y19jbnRfbG9fZGl2OA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDg=::MQ==::Y19jbnRfcHJzdDg=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Q4::MA==::Y19jbnRfcGhfbXV4X3Byc3Q4" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjOA==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjOA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuOA==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuOA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuOA==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuOA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2OQ==::MQ==::Y19jbnRfaGlfZGl2OQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2OQ==::MQ==::Y19jbnRfbG9fZGl2OQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDk=::MQ==::Y19jbnRfcHJzdDk=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3Q5::MA==::Y19jbnRfcGhfbXV4X3Byc3Q5" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjOQ==::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjOQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuOQ==::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuOQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuOQ==::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuOQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MTA=::MQ==::Y19jbnRfaGlfZGl2MTA=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MTA=::MQ==::Y19jbnRfbG9fZGl2MTA=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDEw::MQ==::Y19jbnRfcHJzdDEw" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3QxMA==::MA==::Y19jbnRfcGhfbXV4X3Byc3QxMA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMTA=::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMTA=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMTA=::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMTA=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTA=::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTA=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MTE=::MQ==::Y19jbnRfaGlfZGl2MTE=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MTE=::MQ==::Y19jbnRfbG9fZGl2MTE=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDEx::MQ==::Y19jbnRfcHJzdDEx" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3QxMQ==::MA==::Y19jbnRfcGhfbXV4X3Byc3QxMQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMTE=::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMTE=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMTE=::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMTE=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTE=::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTE=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MTI=::MQ==::Y19jbnRfaGlfZGl2MTI=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MTI=::MQ==::Y19jbnRfbG9fZGl2MTI=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDEy::MQ==::Y19jbnRfcHJzdDEy" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3QxMg==::MA==::Y19jbnRfcGhfbXV4X3Byc3QxMg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMTI=::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMTI=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMTI=::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMTI=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTI=::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTI=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MTM=::MQ==::Y19jbnRfaGlfZGl2MTM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MTM=::MQ==::Y19jbnRfbG9fZGl2MTM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDEz::MQ==::Y19jbnRfcHJzdDEz" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3QxMw==::MA==::Y19jbnRfcGhfbXV4X3Byc3QxMw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMTM=::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMTM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMTM=::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMTM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTM=::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTM=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MTQ=::MQ==::Y19jbnRfaGlfZGl2MTQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MTQ=::MQ==::Y19jbnRfbG9fZGl2MTQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDE0::MQ==::Y19jbnRfcHJzdDE0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3QxNA==::MA==::Y19jbnRfcGhfbXV4X3Byc3QxNA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMTQ=::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMTQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMTQ=::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMTQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTQ=::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MTU=::MQ==::Y19jbnRfaGlfZGl2MTU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MTU=::MQ==::Y19jbnRfbG9fZGl2MTU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDE1::MQ==::Y19jbnRfcHJzdDE1" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3QxNQ==::MA==::Y19jbnRfcGhfbXV4X3Byc3QxNQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMTU=::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMTU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMTU=::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMTU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTU=::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MTY=::MQ==::Y19jbnRfaGlfZGl2MTY=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MTY=::MQ==::Y19jbnRfbG9fZGl2MTY=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDE2::MQ==::Y19jbnRfcHJzdDE2" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3QxNg==::MA==::Y19jbnRfcGhfbXV4X3Byc3QxNg==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMTY=::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMTY=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMTY=::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMTY=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTY=::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTY=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaGlfZGl2MTc=::MQ==::Y19jbnRfaGlfZGl2MTc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfbG9fZGl2MTc=::MQ==::Y19jbnRfbG9fZGl2MTc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcHJzdDE3::MQ==::Y19jbnRfcHJzdDE3" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfcGhfbXV4X3Byc3QxNw==::MA==::Y19jbnRfcGhfbXV4X3Byc3QxNw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfaW5fc3JjMTc=::cGhfbXV4X2Nsaw==::Y19jbnRfaW5fc3JjMTc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfYnlwYXNzX2VuMTc=::dHJ1ZQ==::Y19jbnRfYnlwYXNzX2VuMTc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTc=::ZmFsc2U=::Y19jbnRfb2RkX2Rpdl9kdXR5X2VuMTc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX3Zjb19kaXY=::Mg==::cGxsX3Zjb19kaXY=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX2NwX2N1cnJlbnQ=::MjA=::cGxsX2NwX2N1cnJlbnQ=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX2J3Y3RybA==::NDAwMA==::cGxsX2J3Y3RybA==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX291dHB1dF9jbGtfZnJlcXVlbmN5::NDQ1LjQ5OTk5OSBNSHo=::cGxsX291dHB1dF9jbGtfZnJlcXVlbmN5" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX2ZyYWN0aW9uYWxfZGl2aXNpb24=::MzkwODQyMDE1Mw==::cGxsX2ZyYWN0aW9uYWxfZGl2aXNpb24=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "bWltaWNfZmJjbGtfdHlwZQ==::bm9uZQ==::bWltaWNfZmJjbGtfdHlwZQ==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX2ZiY2xrX211eF8x::Z2xi::cGxsX2ZiY2xrX211eF8x" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX2ZiY2xrX211eF8y::bV9jbnQ=::cGxsX2ZiY2xrX211eF8y" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX21fY250X2luX3NyYw==::cGhfbXV4X2Nsaw==::cGxsX21fY250X2luX3NyYw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "cGxsX3NsZl9yc3Q=::dHJ1ZQ==::cGxsX3NsZl9yc3Q=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::NCw0LDI1NiwyNTYsZmFsc2UsdHJ1ZSxmYWxzZSxmYWxzZSwyLDEsMSwwLHBoX211eF9jbGssZmFsc2UsdHJ1ZSwyLDIwLDQwMDAsNDQ1LjQ5OTk5OSBNSHosMzkwODQyMDE1Myxub25lLGdsYixtX2NudCxwaF9tdXhfY2xrLHRydWU=::UGFyYW1ldGVyIFZhbHVlcw==" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX21pZl9nZW5lcmF0ZQ==::ZmFsc2U=::R2VuZXJhdGUgTUlGIGZpbGU=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9taWZfZHBz::ZmFsc2U=::RW5hYmxlIER5bmFtaWMgUGhhc2UgU2hpZnQgZm9yIE1JRiBzdHJlYW1pbmc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19jbnRy::QzA=::RFBTIENvdW50ZXIgU2VsZWN0aW9u" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19udW0=::MQ==::TnVtYmVyIG9mIER5bmFtaWMgUGhhc2UgU2hpZnRz" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19kaXI=::UG9zaXRpdmU=::RHluYW1pYyBQaGFzZSBTaGlmdCBEaXJlY3Rpb24=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmNsa19zd2l0Y2g=::ZmFsc2U=::Q3JlYXRlIGEgc2Vjb25kIGlucHV0IGNsayAncmVmY2xrMSc=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX291dA==::ZmFsc2U=::Q3JlYXRlIGEgJ2Nhc2NhZGVfb3V0JyBzaWduYWwgdG8gY29ubmVjdCB3aXRoIGEgZG93bnN0cmVhbSBQTEw=" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX2lu::ZmFsc2U=::Q3JlYXRlIGFuIGFkanBsbGluIG9yIGNjbGsgc2lnbmFsIHRvIGNvbm5lY3Qgd2l0aCBhbiB1cHN0cmVhbSBQTEw=" + +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.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 "17.0" +set_global_assignment -entity "pll_hdmi_0002" -library "pll_hdmi" -name IP_TOOL_ENV "mwpim" diff --git a/sys/pll_hdmi.v b/sys/pll_hdmi.v new file mode 100644 index 0000000..0cefd25 --- /dev/null +++ b/sys/pll_hdmi.v @@ -0,0 +1,256 @@ +// megafunction wizard: %Altera PLL v17.0% +// GENERATION: XML +// pll_hdmi.v + +// Generated using ACDS version 17.0 598 + +`timescale 1 ps / 1 ps +module pll_hdmi ( + input wire refclk, // refclk.clk + input wire rst, // reset.reset + output wire outclk_0, // outclk0.clk + input wire [63:0] reconfig_to_pll, // reconfig_to_pll.reconfig_to_pll + output wire [63:0] reconfig_from_pll // reconfig_from_pll.reconfig_from_pll + ); + + pll_hdmi_0002 pll_hdmi_inst ( + .refclk (refclk), // refclk.clk + .rst (rst), // reset.reset + .outclk_0 (outclk_0), // outclk0.clk + .reconfig_to_pll (reconfig_to_pll), // reconfig_to_pll.reconfig_to_pll + .reconfig_from_pll (reconfig_from_pll), // reconfig_from_pll.reconfig_from_pll + .locked () // (terminated) + ); + +endmodule +// Retrieval info: +// +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// IPFS_FILES : pll_hdmi.vo +// RELATED_FILES: pll_hdmi.v, pll_hdmi_0002.v diff --git a/sys/pll_hdmi/pll_hdmi_0002.qip b/sys/pll_hdmi/pll_hdmi_0002.qip new file mode 100644 index 0000000..3cb7073 --- /dev/null +++ b/sys/pll_hdmi/pll_hdmi_0002.qip @@ -0,0 +1,2 @@ +set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name UNFORCE_MERGE_PLL_OUTPUT_COUNTER ON -to "*pll_hdmi_0002*|altera_pll:altera_pll_i*|*" diff --git a/sys/pll_hdmi/pll_hdmi_0002.v b/sys/pll_hdmi/pll_hdmi_0002.v new file mode 100644 index 0000000..9347c76 --- /dev/null +++ b/sys/pll_hdmi/pll_hdmi_0002.v @@ -0,0 +1,241 @@ +`timescale 1ns/10ps +module pll_hdmi_0002( + + // interface 'refclk' + input wire refclk, + + // interface 'reset' + input wire rst, + + // interface 'outclk0' + output wire outclk_0, + + // interface 'locked' + output wire locked, + + // interface 'reconfig_to_pll' + input wire [63:0] reconfig_to_pll, + + // interface 'reconfig_from_pll' + output wire [63:0] reconfig_from_pll +); + + altera_pll #( + .fractional_vco_multiplier("true"), + .reference_clock_frequency("50.0 MHz"), + .pll_fractional_cout(32), + .pll_dsm_out_sel("1st_order"), + .operation_mode("direct"), + .number_of_clocks(1), + .output_clock_frequency0("148.500000 MHz"), + .phase_shift0("0 ps"), + .duty_cycle0(50), + .output_clock_frequency1("0 MHz"), + .phase_shift1("0 ps"), + .duty_cycle1(50), + .output_clock_frequency2("0 MHz"), + .phase_shift2("0 ps"), + .duty_cycle2(50), + .output_clock_frequency3("0 MHz"), + .phase_shift3("0 ps"), + .duty_cycle3(50), + .output_clock_frequency4("0 MHz"), + .phase_shift4("0 ps"), + .duty_cycle4(50), + .output_clock_frequency5("0 MHz"), + .phase_shift5("0 ps"), + .duty_cycle5(50), + .output_clock_frequency6("0 MHz"), + .phase_shift6("0 ps"), + .duty_cycle6(50), + .output_clock_frequency7("0 MHz"), + .phase_shift7("0 ps"), + .duty_cycle7(50), + .output_clock_frequency8("0 MHz"), + .phase_shift8("0 ps"), + .duty_cycle8(50), + .output_clock_frequency9("0 MHz"), + .phase_shift9("0 ps"), + .duty_cycle9(50), + .output_clock_frequency10("0 MHz"), + .phase_shift10("0 ps"), + .duty_cycle10(50), + .output_clock_frequency11("0 MHz"), + .phase_shift11("0 ps"), + .duty_cycle11(50), + .output_clock_frequency12("0 MHz"), + .phase_shift12("0 ps"), + .duty_cycle12(50), + .output_clock_frequency13("0 MHz"), + .phase_shift13("0 ps"), + .duty_cycle13(50), + .output_clock_frequency14("0 MHz"), + .phase_shift14("0 ps"), + .duty_cycle14(50), + .output_clock_frequency15("0 MHz"), + .phase_shift15("0 ps"), + .duty_cycle15(50), + .output_clock_frequency16("0 MHz"), + .phase_shift16("0 ps"), + .duty_cycle16(50), + .output_clock_frequency17("0 MHz"), + .phase_shift17("0 ps"), + .duty_cycle17(50), + .pll_type("Cyclone V"), + .pll_subtype("Reconfigurable"), + .m_cnt_hi_div(4), + .m_cnt_lo_div(4), + .n_cnt_hi_div(256), + .n_cnt_lo_div(256), + .m_cnt_bypass_en("false"), + .n_cnt_bypass_en("true"), + .m_cnt_odd_div_duty_en("false"), + .n_cnt_odd_div_duty_en("false"), + .c_cnt_hi_div0(2), + .c_cnt_lo_div0(1), + .c_cnt_prst0(1), + .c_cnt_ph_mux_prst0(0), + .c_cnt_in_src0("ph_mux_clk"), + .c_cnt_bypass_en0("false"), + .c_cnt_odd_div_duty_en0("true"), + .c_cnt_hi_div1(1), + .c_cnt_lo_div1(1), + .c_cnt_prst1(1), + .c_cnt_ph_mux_prst1(0), + .c_cnt_in_src1("ph_mux_clk"), + .c_cnt_bypass_en1("true"), + .c_cnt_odd_div_duty_en1("false"), + .c_cnt_hi_div2(1), + .c_cnt_lo_div2(1), + .c_cnt_prst2(1), + .c_cnt_ph_mux_prst2(0), + .c_cnt_in_src2("ph_mux_clk"), + .c_cnt_bypass_en2("true"), + .c_cnt_odd_div_duty_en2("false"), + .c_cnt_hi_div3(1), + .c_cnt_lo_div3(1), + .c_cnt_prst3(1), + .c_cnt_ph_mux_prst3(0), + .c_cnt_in_src3("ph_mux_clk"), + .c_cnt_bypass_en3("true"), + .c_cnt_odd_div_duty_en3("false"), + .c_cnt_hi_div4(1), + .c_cnt_lo_div4(1), + .c_cnt_prst4(1), + .c_cnt_ph_mux_prst4(0), + .c_cnt_in_src4("ph_mux_clk"), + .c_cnt_bypass_en4("true"), + .c_cnt_odd_div_duty_en4("false"), + .c_cnt_hi_div5(1), + .c_cnt_lo_div5(1), + .c_cnt_prst5(1), + .c_cnt_ph_mux_prst5(0), + .c_cnt_in_src5("ph_mux_clk"), + .c_cnt_bypass_en5("true"), + .c_cnt_odd_div_duty_en5("false"), + .c_cnt_hi_div6(1), + .c_cnt_lo_div6(1), + .c_cnt_prst6(1), + .c_cnt_ph_mux_prst6(0), + .c_cnt_in_src6("ph_mux_clk"), + .c_cnt_bypass_en6("true"), + .c_cnt_odd_div_duty_en6("false"), + .c_cnt_hi_div7(1), + .c_cnt_lo_div7(1), + .c_cnt_prst7(1), + .c_cnt_ph_mux_prst7(0), + .c_cnt_in_src7("ph_mux_clk"), + .c_cnt_bypass_en7("true"), + .c_cnt_odd_div_duty_en7("false"), + .c_cnt_hi_div8(1), + .c_cnt_lo_div8(1), + .c_cnt_prst8(1), + .c_cnt_ph_mux_prst8(0), + .c_cnt_in_src8("ph_mux_clk"), + .c_cnt_bypass_en8("true"), + .c_cnt_odd_div_duty_en8("false"), + .c_cnt_hi_div9(1), + .c_cnt_lo_div9(1), + .c_cnt_prst9(1), + .c_cnt_ph_mux_prst9(0), + .c_cnt_in_src9("ph_mux_clk"), + .c_cnt_bypass_en9("true"), + .c_cnt_odd_div_duty_en9("false"), + .c_cnt_hi_div10(1), + .c_cnt_lo_div10(1), + .c_cnt_prst10(1), + .c_cnt_ph_mux_prst10(0), + .c_cnt_in_src10("ph_mux_clk"), + .c_cnt_bypass_en10("true"), + .c_cnt_odd_div_duty_en10("false"), + .c_cnt_hi_div11(1), + .c_cnt_lo_div11(1), + .c_cnt_prst11(1), + .c_cnt_ph_mux_prst11(0), + .c_cnt_in_src11("ph_mux_clk"), + .c_cnt_bypass_en11("true"), + .c_cnt_odd_div_duty_en11("false"), + .c_cnt_hi_div12(1), + .c_cnt_lo_div12(1), + .c_cnt_prst12(1), + .c_cnt_ph_mux_prst12(0), + .c_cnt_in_src12("ph_mux_clk"), + .c_cnt_bypass_en12("true"), + .c_cnt_odd_div_duty_en12("false"), + .c_cnt_hi_div13(1), + .c_cnt_lo_div13(1), + .c_cnt_prst13(1), + .c_cnt_ph_mux_prst13(0), + .c_cnt_in_src13("ph_mux_clk"), + .c_cnt_bypass_en13("true"), + .c_cnt_odd_div_duty_en13("false"), + .c_cnt_hi_div14(1), + .c_cnt_lo_div14(1), + .c_cnt_prst14(1), + .c_cnt_ph_mux_prst14(0), + .c_cnt_in_src14("ph_mux_clk"), + .c_cnt_bypass_en14("true"), + .c_cnt_odd_div_duty_en14("false"), + .c_cnt_hi_div15(1), + .c_cnt_lo_div15(1), + .c_cnt_prst15(1), + .c_cnt_ph_mux_prst15(0), + .c_cnt_in_src15("ph_mux_clk"), + .c_cnt_bypass_en15("true"), + .c_cnt_odd_div_duty_en15("false"), + .c_cnt_hi_div16(1), + .c_cnt_lo_div16(1), + .c_cnt_prst16(1), + .c_cnt_ph_mux_prst16(0), + .c_cnt_in_src16("ph_mux_clk"), + .c_cnt_bypass_en16("true"), + .c_cnt_odd_div_duty_en16("false"), + .c_cnt_hi_div17(1), + .c_cnt_lo_div17(1), + .c_cnt_prst17(1), + .c_cnt_ph_mux_prst17(0), + .c_cnt_in_src17("ph_mux_clk"), + .c_cnt_bypass_en17("true"), + .c_cnt_odd_div_duty_en17("false"), + .pll_vco_div(2), + .pll_cp_current(20), + .pll_bwctrl(4000), + .pll_output_clk_frequency("445.499999 MHz"), + .pll_fractional_division("3908420153"), + .mimic_fbclk_type("none"), + .pll_fbclk_mux_1("glb"), + .pll_fbclk_mux_2("m_cnt"), + .pll_m_cnt_in_src("ph_mux_clk"), + .pll_slf_rst("true") + ) altera_pll_i ( + .rst (rst), + .outclk ({outclk_0}), + .locked (locked), + .reconfig_to_pll (reconfig_to_pll), + .fboutclk ( ), + .fbclk (1'b0), + .refclk (refclk), + .reconfig_from_pll (reconfig_from_pll) + ); +endmodule + diff --git a/sys/pll_hdmi_cfg.qip b/sys/pll_hdmi_cfg.qip new file mode 100644 index 0000000..f6447f5 --- /dev/null +++ b/sys/pll_hdmi_cfg.qip @@ -0,0 +1,44 @@ +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TOOL_NAME "altera_pll_reconfig" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TOOL_VERSION "17.0" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TOOL_ENV "mwpim" +set_global_assignment -library "pll_hdmi_cfg" -name MISC_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg.cmp"] +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_QSYS_MODE "UNKNOWN" +set_global_assignment -name SYNTHESIS_ONLY_QIP ON +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_NAME "cGxsX2hkbWlfY2Zn" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTCBSZWNvbmZpZw==" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_VERSION "MTcuMA==" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIFJlY29uZmlndXJhdGlvbiBCbG9jayhBTFRFUkFfUExMX1JFQ09ORklHKQ==" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0JZVEVFTkFCTEU=::ZmFsc2U=::QWRkIGJ5dGVlbmFibGUgcG9ydA==" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "QllURUVOQUJMRV9XSURUSA==::NA==::QllURUVOQUJMRV9XSURUSA==" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfQUREUl9XSURUSA==::Ng==::UkVDT05GSUdfQUREUl9XSURUSA==" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfREFUQV9XSURUSA==::MzI=::UkVDT05GSUdfREFUQV9XSURUSA==" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "cmVjb25mX3dpZHRo::NjQ=::cmVjb25mX3dpZHRo" +set_global_assignment -entity "pll_hdmi_cfg" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "V0FJVF9GT1JfTE9DSw==::dHJ1ZQ==::V0FJVF9GT1JfTE9DSw==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_NAME "YWx0ZXJhX3BsbF9yZWNvbmZpZ190b3A=" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTCBSZWNvbmZpZw==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_VERSION "MTcuMA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIFJlY29uZmlndXJhdGlvbiBCbG9jayhBTFRFUkFfUExMX1JFQ09ORklHKQ==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "ZGV2aWNlX2ZhbWlseQ==::Q3ljbG9uZSBW::ZGV2aWNlX2ZhbWlseQ==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX01JRg==::ZmFsc2U=::RW5hYmxlIE1JRiBTdHJlYW1pbmc=" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "RU5BQkxFX0JZVEVFTkFCTEU=::ZmFsc2U=::QWRkIGJ5dGVlbmFibGUgcG9ydA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "QllURUVOQUJMRV9XSURUSA==::NA==::QllURUVOQUJMRV9XSURUSA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfQUREUl9XSURUSA==::Ng==::UkVDT05GSUdfQUREUl9XSURUSA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "UkVDT05GSUdfREFUQV9XSURUSA==::MzI=::UkVDT05GSUdfREFUQV9XSURUSA==" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "cmVjb25mX3dpZHRo::NjQ=::cmVjb25mX3dpZHRo" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_COMPONENT_PARAMETER "V0FJVF9GT1JfTE9DSw==::dHJ1ZQ==::V0FJVF9GT1JfTE9DSw==" + +set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg.v"] +set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg/altera_pll_reconfig_top.v"] +set_global_assignment -library "pll_hdmi_cfg" -name VERILOG_FILE [file join $::quartus(qip_path) "pll_hdmi_cfg/altera_pll_reconfig_core.v"] + +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_TOOL_NAME "altera_pll_reconfig" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_TOOL_VERSION "17.0" +set_global_assignment -entity "altera_pll_reconfig_top" -library "pll_hdmi_cfg" -name IP_TOOL_ENV "mwpim" diff --git a/sys/pll_hdmi_cfg.v b/sys/pll_hdmi_cfg.v new file mode 100644 index 0000000..1ebf6f0 --- /dev/null +++ b/sys/pll_hdmi_cfg.v @@ -0,0 +1,86 @@ +// megafunction wizard: %Altera PLL Reconfig v17.0% +// GENERATION: XML +// pll_hdmi_cfg.v + +// Generated using ACDS version 17.0 598 + +`timescale 1 ps / 1 ps +module pll_hdmi_cfg #( + parameter ENABLE_BYTEENABLE = 0, + parameter BYTEENABLE_WIDTH = 4, + parameter RECONFIG_ADDR_WIDTH = 6, + parameter RECONFIG_DATA_WIDTH = 32, + parameter reconf_width = 64, + parameter WAIT_FOR_LOCK = 1 + ) ( + input wire mgmt_clk, // mgmt_clk.clk + input wire mgmt_reset, // mgmt_reset.reset + output wire mgmt_waitrequest, // mgmt_avalon_slave.waitrequest + input wire mgmt_read, // .read + input wire mgmt_write, // .write + output wire [31:0] mgmt_readdata, // .readdata + input wire [5:0] mgmt_address, // .address + input wire [31:0] mgmt_writedata, // .writedata + output wire [63:0] reconfig_to_pll, // reconfig_to_pll.reconfig_to_pll + input wire [63:0] reconfig_from_pll // reconfig_from_pll.reconfig_from_pll + ); + + altera_pll_reconfig_top #( + .device_family ("Cyclone V"), + .ENABLE_MIF (0), + .MIF_FILE_NAME ("sys/pll_hdmi_cfg.mif"), + .ENABLE_BYTEENABLE (ENABLE_BYTEENABLE), + .BYTEENABLE_WIDTH (BYTEENABLE_WIDTH), + .RECONFIG_ADDR_WIDTH (RECONFIG_ADDR_WIDTH), + .RECONFIG_DATA_WIDTH (RECONFIG_DATA_WIDTH), + .reconf_width (reconf_width), + .WAIT_FOR_LOCK (WAIT_FOR_LOCK) + ) pll_hdmi_cfg_inst ( + .mgmt_clk (mgmt_clk), // mgmt_clk.clk + .mgmt_reset (mgmt_reset), // mgmt_reset.reset + .mgmt_waitrequest (mgmt_waitrequest), // mgmt_avalon_slave.waitrequest + .mgmt_read (mgmt_read), // .read + .mgmt_write (mgmt_write), // .write + .mgmt_readdata (mgmt_readdata), // .readdata + .mgmt_address (mgmt_address), // .address + .mgmt_writedata (mgmt_writedata), // .writedata + .reconfig_to_pll (reconfig_to_pll), // reconfig_to_pll.reconfig_to_pll + .reconfig_from_pll (reconfig_from_pll), // reconfig_from_pll.reconfig_from_pll + .mgmt_byteenable (4'b0000) // (terminated) + ); + +endmodule +// Retrieval info: +// +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// IPFS_FILES : pll_hdmi_cfg.vo +// RELATED_FILES: pll_hdmi_cfg.v, altera_pll_reconfig_top.v, altera_pll_reconfig_core.v, altera_std_synchronizer.v diff --git a/sys/pll_hdmi_cfg/altera_pll_reconfig_core.v b/sys/pll_hdmi_cfg/altera_pll_reconfig_core.v new file mode 100644 index 0000000..4bc1fbb --- /dev/null +++ b/sys/pll_hdmi_cfg/altera_pll_reconfig_core.v @@ -0,0 +1,2184 @@ +// (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. + + +`timescale 1ps/1ps + +module altera_pll_reconfig_core +#( + parameter reconf_width = 64, + parameter device_family = "Stratix V", + // MIF Streaming parameters + parameter RECONFIG_ADDR_WIDTH = 6, + parameter RECONFIG_DATA_WIDTH = 32, + parameter ROM_ADDR_WIDTH = 9, + parameter ROM_DATA_WIDTH = 32, + parameter ROM_NUM_WORDS = 512 +) ( + + //input + input wire mgmt_clk, + input wire mgmt_reset, + + + //conduits + output wire [reconf_width-1:0] reconfig_to_pll, + input wire [reconf_width-1:0] reconfig_from_pll, + + // user data (avalon-MM slave interface) + output wire [31:0] mgmt_readdata, + output wire mgmt_waitrequest, + input wire [5:0] mgmt_address, + input wire mgmt_read, + input wire mgmt_write, + input wire [31:0] mgmt_writedata, + + //other + output wire mif_start_out, + output reg [ROM_ADDR_WIDTH-1:0] mif_base_addr +); + localparam mode_WR = 1'b0; + localparam mode_POLL = 1'b1; + localparam MODE_REG = 6'b000000; + localparam STATUS_REG = 6'b000001; + localparam START_REG = 6'b000010; + localparam N_REG = 6'b000011; + localparam M_REG = 6'b000100; + localparam C_COUNTERS_REG = 6'b000101; + localparam DPS_REG = 6'b000110; + localparam DSM_REG = 6'b000111; + localparam BWCTRL_REG = 6'b001000; + localparam CP_CURRENT_REG = 6'b001001; + localparam ANY_DPRIO = 6'b100000; + localparam CNT_BASE = 5'b001010; + localparam VCO_REG = 6'b011100; + localparam MIF_REG = 6'b011111; + + //C Counters + localparam number_of_counters = 5'd18; + localparam CNT_0 = 1'd0, CNT_1 = 5'd1, CNT_2 = 5'd2, + CNT_3 = 5'd3, CNT_4 = 5'd4, CNT_5 = 5'd5, + CNT_6 = 5'd6, CNT_7 = 5'd7, CNT_8 = 5'd8, + CNT_9 = 5'd9, CNT_10 = 5'd10, CNT_11 = 5'd11, + CNT_12 = 5'd12, CNT_13 = 5'd13, CNT_14 = 5'd14, + CNT_15 = 5'd15, CNT_16 = 5'd16, CNT_17 = 5'd17; + //C counter addresses + localparam C_CNT_0_DIV_ADDR = 5'h00; + localparam C_CNT_0_DIV_ADDR_DPRIO_1 = 5'h11; + localparam C_CNT_0_3_BYPASS_EN_ADDR = 5'h15; + localparam C_CNT_0_3_ODD_DIV_EN_ADDR = 5'h17; + localparam C_CNT_4_17_BYPASS_EN_ADDR = 5'h14; + localparam C_CNT_4_17_ODD_DIV_EN_ADDR = 5'h16; + //N counter addresses + localparam N_CNT_DIV_ADDR = 5'h13; + localparam N_CNT_BYPASS_EN_ADDR = 5'h15; + localparam N_CNT_ODD_DIV_EN_ADDR = 5'h17; + //M counter addresses + localparam M_CNT_DIV_ADDR = 5'h12; + localparam M_CNT_BYPASS_EN_ADDR = 5'h15; + localparam M_CNT_ODD_DIV_EN_ADDR = 5'h17; + + //DSM address + localparam DSM_K_FRACTIONAL_DIVISION_ADDR_0 = 5'h18; + localparam DSM_K_FRACTIONAL_DIVISION_ADDR_1 = 5'h19; + localparam DSM_K_READY_ADDR = 5'h17; + localparam DSM_K_DITHER_ADDR = 5'h17; + localparam DSM_OUT_SEL_ADDR = 6'h30; + + //Other DSM params + localparam DSM_K_READY_BIT_INDEX = 4'd11; + //BWCTRL address + //Bit 0-3 of addr + localparam BWCTRL_ADDR = 6'h30; + //CP_CURRENT address + //Bit 0-2 of addr + localparam CP_CURRENT_ADDR = 6'h31; + + // VCODIV address + localparam VCO_ADDR = 5'h17; + + localparam DPRIO_IDLE = 3'd0, ONE = 3'd1, TWO = 3'd2, THREE = 3'd3, FOUR = 3'd4, + FIVE = 3'd5, SIX = 3'd6, SEVEN = 3'd7, EIGHT = 4'd8, NINE = 4'd9, TEN = 4'd10, + ELEVEN = 4'd11, TWELVE = 4'd12, THIRTEEN = 4'd13, FOURTEEN = 4'd14, DPRIO_DONE = 4'd15; + localparam IDLE = 2'b00, WAIT_ON_LOCK = 2'b01, LOCKED = 2'b10; + + wire clk; + wire reset; + wire gnd; + + wire [5: 0] slave_address; + wire slave_read; + wire slave_write; + wire [31: 0] slave_writedata; + + reg [31: 0] slave_readdata_d; + reg [31: 0] slave_readdata_q; + wire slave_waitrequest; + reg slave_mode; + + assign clk = mgmt_clk; + + assign slave_address = mgmt_address; + assign slave_read = mgmt_read; + assign slave_write = mgmt_write; + assign slave_writedata = mgmt_writedata; + + reg read_waitrequest; + // Outputs + assign mgmt_readdata = slave_readdata_q; + assign mgmt_waitrequest = slave_waitrequest | read_waitrequest; //Read waitrequest asserted in polling mode + + //internal signals + wire locked_orig; + wire locked; + + wire pll_start; + wire pll_start_valid; + reg status_read; + wire read_slave_mode_asserted; + + wire pll_start_asserted; + + reg [1:0] current_state; + reg [1:0] next_state; + + reg status;//0=busy, 1=ready + //user_mode_init user_mode_init_inst (clk, reset, dprio_mdio_dis, ser_shift_load); + //declaring the init wires. These will have 0 on them for 64 clk cycles + wire [ 5:0] init_dprio_address; + wire init_dprio_read; + wire [ 1:0] init_dprio_byteen; + wire init_dprio_write; + wire [15:0] init_dprio_writedata; + + wire init_atpgmode; + wire init_mdio_dis; + wire init_scanen; + wire init_ser_shift_load; + wire dprio_init_done; + + //DPRIO output signals after initialization is done + wire dprio_clk; + reg avmm_dprio_write; + reg avmm_dprio_read; + reg [5:0] avmm_dprio_address; + reg [15:0] avmm_dprio_writedata; + reg [1:0] avmm_dprio_byteen; + wire avmm_atpgmode; + wire avmm_mdio_dis; + wire avmm_scanen; + + //Final output wires that are muxed between the init and avmm wires. + wire dprio_init_reset; + wire [5:0] dprio_address /*synthesis keep*/; + wire dprio_read/*synthesis keep*/; + wire [1:0] dprio_byteen/*synthesis keep*/; + wire dprio_write/*synthesis keep*/; + wire [15:0] dprio_writedata/*synthesis keep*/; + wire dprio_mdio_dis/*synthesis keep*/; + wire dprio_ser_shift_load/*synthesis keep*/; + wire dprio_atpgmode/*synthesis keep*/; + wire dprio_scanen/*synthesis keep*/; + + + //other PLL signals for dyn ph shift + wire phase_done/*synthesis keep*/; + wire phase_en/*synthesis keep*/; + wire up_dn/*synthesis keep*/; + wire [4:0] cnt_sel; + + //DPRIO input signals + wire [15:0] dprio_readdata; + + //internal logic signals + //storage registers for user sent data + reg dprio_temp_read_1; + reg dprio_temp_read_2; + reg dprio_start; + reg mif_start_assert; + reg dps_start_assert; + wire usr_valid_changes; + reg [3:0] dprio_cur_state; + reg [3:0] dprio_next_state; + reg [15:0] dprio_temp_m_n_c_readdata_1_d; + reg [15:0] dprio_temp_m_n_c_readdata_2_d; + reg [15:0] dprio_temp_m_n_c_readdata_1_q; + reg [15:0] dprio_temp_m_n_c_readdata_2_q; + reg dprio_write_done; + //C counters signals + reg [7:0] usr_c_cnt_lo; + reg [7:0] usr_c_cnt_hi; + reg usr_c_cnt_bypass_en; + reg usr_c_cnt_odd_duty_div_en; + reg [7:0] temp_c_cnt_lo [0:17]; + reg [7:0] temp_c_cnt_hi [0:17]; + reg temp_c_cnt_bypass_en [0:17]; + reg temp_c_cnt_odd_duty_div_en [0:17]; + reg any_c_cnt_changed; + reg all_c_cnt_done_q; + reg all_c_cnt_done_d; + reg [17:0] c_cnt_changed; + reg [17:0] c_cnt_done_d; + reg [17:0] c_cnt_done_q; + //N counter signals + reg [7:0] usr_n_cnt_lo; + reg [7:0] usr_n_cnt_hi; + reg usr_n_cnt_bypass_en; + reg usr_n_cnt_odd_duty_div_en; + reg n_cnt_changed; + reg n_cnt_done_d; + reg n_cnt_done_q; + //M counter signals + reg [7:0] usr_m_cnt_lo; + reg [7:0] usr_m_cnt_hi; + reg usr_m_cnt_bypass_en; + reg usr_m_cnt_odd_duty_div_en; + reg m_cnt_changed; + reg m_cnt_done_d; + reg m_cnt_done_q; + //dyn phase regs + reg [15:0] usr_num_shifts; + reg [4:0] usr_cnt_sel /*synthesis preserve*/; + reg usr_up_dn; + reg dps_changed; + wire dps_changed_valid; + wire dps_done; + + //DSM Signals + reg [31:0] usr_k_value; + reg dsm_k_changed; + reg dsm_k_done_d; + reg dsm_k_done_q; + reg dsm_k_ready_false_done_d; + //BW signals + reg [3:0] usr_bwctrl_value; + reg bwctrl_changed; + reg bwctrl_done_d; + reg bwctrl_done_q; + //CP signals + reg [2:0] usr_cp_current_value; + reg cp_current_changed; + reg cp_current_done_d; + reg cp_current_done_q; + //VCO signals + reg usr_vco_value; + reg vco_changed; + reg vco_done_d; + reg vco_done_q; + //Manual DPRIO signals + reg manual_dprio_done_q; + reg manual_dprio_done_d; + reg manual_dprio_changed; + reg [5:0] usr_dprio_address; + reg [15:0] usr_dprio_writedata_0; + reg usr_r_w; + //keeping track of which operation happened last + reg [5:0] operation_address; + // Address wires for all C_counter DPRIO registers + // These are outputs of LUTS, changing depending + // on whether PLL_0 or PLL_1 being used + + + //Fitter will tell if FPLL1 is being used + wire fpll_1; + + // other + reg mif_reg_asserted; + // MAIN FSM + + // Synchronize locked signal + altera_std_synchronizer #( + .depth(3) + ) altera_std_synchronizer_inst ( + .clk(mgmt_clk), + .reset_n(~mgmt_reset), + .din(locked_orig), + .dout(locked) + ); + + always @(posedge clk) + begin + if (reset) + begin + dprio_cur_state <= DPRIO_IDLE; + current_state <= IDLE; + end + else + begin + current_state <= next_state; + dprio_cur_state <= dprio_next_state; + end + end + + always @(*) + begin + case(current_state) + IDLE: + begin + if (pll_start & !slave_waitrequest & usr_valid_changes) + next_state = WAIT_ON_LOCK; + else + next_state = IDLE; + end + WAIT_ON_LOCK: + begin + if (locked & dps_done & dprio_write_done) // received locked high from PLL + begin + if (slave_mode==mode_WR) //if the mode is waitrequest, then + // goto IDLE state directly + next_state = IDLE; + else + next_state = LOCKED; //otherwise go the locked state + end + else + next_state = WAIT_ON_LOCK; + end + + LOCKED: + begin + if (status_read) // stay in LOCKED until user reads status + next_state = IDLE; + else + next_state = LOCKED; + end + + default: next_state = 2'bxx; + + endcase + end + + + // ask the pll to start reconfig + assign pll_start = (pll_start_asserted & (current_state==IDLE)) ; + assign pll_start_valid = (pll_start & (next_state==WAIT_ON_LOCK)) ; + + + + // WRITE OPERATIONS + assign pll_start_asserted = slave_write & (slave_address == START_REG); + assign mif_start_out = pll_start & mif_reg_asserted; + + //reading the mode register to determine what mode the slave will operate + //in. + always @(posedge clk) + begin + if (reset) + slave_mode <= mode_WR; + else if (slave_write & (slave_address == MODE_REG) & !slave_waitrequest) + slave_mode <= slave_writedata[0]; + end + + //record which values user wants to change. + + //reading in the actual values that need to be reconfigged and sending + //them to the PLL + always @(posedge clk) + begin + if (reset) + begin + //reset all regs here + //BW signals reset + usr_bwctrl_value <= 0; + bwctrl_changed <= 0; + bwctrl_done_q <= 0; + //CP signals reset + usr_cp_current_value <= 0; + cp_current_changed <= 0; + cp_current_done_q <= 0; + //VCO signals reset + usr_vco_value <= 0; + vco_changed <= 0; + vco_done_q <= 0; + //DSM signals reset + usr_k_value <= 0; + dsm_k_changed <= 0; + dsm_k_done_q <= 0; + //N counter signals reset + usr_n_cnt_lo <= 0; + usr_n_cnt_hi <= 0; + usr_n_cnt_bypass_en <= 0; + usr_n_cnt_odd_duty_div_en <= 0; + n_cnt_changed <= 0; + n_cnt_done_q <= 0; + //M counter signals reset + usr_m_cnt_lo <= 0; + usr_m_cnt_hi <= 0; + usr_m_cnt_bypass_en <= 0; + usr_m_cnt_odd_duty_div_en <= 0; + m_cnt_changed <= 0; + m_cnt_done_q <= 0; + //C counter signals reset + usr_c_cnt_lo <= 0; + usr_c_cnt_hi <= 0; + usr_c_cnt_bypass_en <= 0; + usr_c_cnt_odd_duty_div_en <= 0; + any_c_cnt_changed <= 0; + all_c_cnt_done_q <= 0; + c_cnt_done_q <= 0; + //generic signals + dprio_start <= 0; + mif_start_assert <= 0; + dps_start_assert <= 0; + dprio_temp_m_n_c_readdata_1_q <= 0; + dprio_temp_m_n_c_readdata_2_q <= 0; + c_cnt_done_q <= 0; + //DPS signals + usr_up_dn <= 0; + usr_cnt_sel <= 0; + usr_num_shifts <= 0; + dps_changed <= 0; + //manual DPRIO signals + manual_dprio_changed <= 0; + usr_dprio_address <= 0; + usr_dprio_writedata_0 <= 0; + usr_r_w <= 0; + operation_address <= 0; + mif_reg_asserted <= 0; + mif_base_addr <= 0; + end + else + begin + if (dprio_temp_read_1) + begin + dprio_temp_m_n_c_readdata_1_q <= dprio_temp_m_n_c_readdata_1_d; + end + if (dprio_temp_read_2) + begin + dprio_temp_m_n_c_readdata_2_q <= dprio_temp_m_n_c_readdata_2_d; + end + if ((dps_done)) dps_changed <= 0; + if (dsm_k_done_d) dsm_k_done_q <= dsm_k_done_d; + if (n_cnt_done_d) n_cnt_done_q <= n_cnt_done_d; + if (m_cnt_done_d) m_cnt_done_q <= m_cnt_done_d; + if (all_c_cnt_done_d) all_c_cnt_done_q <= all_c_cnt_done_d; + if (c_cnt_done_d != 0) c_cnt_done_q <= c_cnt_done_q | c_cnt_done_d; + if (bwctrl_done_d) bwctrl_done_q <= bwctrl_done_d; + if (cp_current_done_d) cp_current_done_q <= cp_current_done_d; + if (vco_done_d) vco_done_q <= vco_done_d; + if (manual_dprio_done_d) manual_dprio_done_q <= manual_dprio_done_d; + + if (mif_start_out == 1'b1) + mif_start_assert <= 0; // Signaled MIF block to start, so deassert on next cycle + + if (dps_done != 1'b1) + dps_start_assert <= 0; // DPS has started, so dessert its start signal on next cycle + + if (dprio_next_state == ONE) + dprio_start <= 0; + if (dprio_write_done) + begin + bwctrl_done_q <= 0; + cp_current_done_q <= 0; + vco_done_q <= 0; + dsm_k_done_q <= 0; + dsm_k_done_q <= 0; + n_cnt_done_q <= 0; + m_cnt_done_q <= 0; + all_c_cnt_done_q <= 0; + c_cnt_done_q <= 0; + dsm_k_changed <= 0; + n_cnt_changed <= 0; + m_cnt_changed <= 0; + any_c_cnt_changed <= 0; + bwctrl_changed <= 0; + cp_current_changed <= 0; + vco_changed <= 0; + manual_dprio_changed <= 0; + manual_dprio_done_q <= 0; + if (dps_changed | dps_changed_valid | !dps_done ) + begin + usr_cnt_sel <= usr_cnt_sel; + end + else + begin + usr_cnt_sel <= 0; + end + mif_reg_asserted <= 0; + end + else + begin + dsm_k_changed <= dsm_k_changed; + n_cnt_changed <= n_cnt_changed; + m_cnt_changed <= m_cnt_changed; + any_c_cnt_changed <= any_c_cnt_changed; + manual_dprio_changed <= manual_dprio_changed; + mif_reg_asserted <= mif_reg_asserted; + usr_cnt_sel <= usr_cnt_sel; + end + + + if(slave_write & !slave_waitrequest) + begin + case(slave_address) + //read in the values here from the user and act on them + DSM_REG: + begin + operation_address <= DSM_REG; + usr_k_value <= slave_writedata[31:0]; + dsm_k_changed <= 1'b1; + dsm_k_done_q <= 0; + dprio_start <= 1'b1; + end + N_REG: + begin + operation_address <= N_REG; + usr_n_cnt_lo <= slave_writedata[7:0]; + usr_n_cnt_hi <= slave_writedata[15:8]; + usr_n_cnt_bypass_en <= slave_writedata[16]; + usr_n_cnt_odd_duty_div_en <= slave_writedata[17]; + n_cnt_changed <= 1'b1; + n_cnt_done_q <= 0; + dprio_start <= 1'b1; + end + M_REG: + begin + operation_address <= M_REG; + usr_m_cnt_lo <= slave_writedata[7:0]; + usr_m_cnt_hi <= slave_writedata[15:8]; + usr_m_cnt_bypass_en <= slave_writedata[16]; + usr_m_cnt_odd_duty_div_en <= slave_writedata[17]; + m_cnt_changed <= 1'b1; + m_cnt_done_q <= 0; + dprio_start <= 1'b1; + end + DPS_REG: + begin + operation_address <= DPS_REG; + usr_num_shifts <= slave_writedata[15:0]; + usr_cnt_sel <= slave_writedata[20:16]; + usr_up_dn <= slave_writedata[21]; + dps_changed <= 1; + dps_start_assert <= 1; + end + C_COUNTERS_REG: + begin + operation_address <= C_COUNTERS_REG; + usr_c_cnt_lo <= slave_writedata[7:0]; + usr_c_cnt_hi <= slave_writedata[15:8]; + usr_c_cnt_bypass_en <= slave_writedata[16]; + usr_c_cnt_odd_duty_div_en <= slave_writedata[17]; + usr_cnt_sel <= slave_writedata[22:18]; + any_c_cnt_changed <= 1'b1; + all_c_cnt_done_q <= 0; + dprio_start <= 1'b1; + end + BWCTRL_REG: + begin + usr_bwctrl_value <= slave_writedata[3:0]; + bwctrl_changed <= 1'b1; + bwctrl_done_q <= 0; + dprio_start <= 1'b1; + operation_address <= BWCTRL_REG; + end + CP_CURRENT_REG: + begin + usr_cp_current_value <= slave_writedata[2:0]; + cp_current_changed <= 1'b1; + cp_current_done_q <= 0; + dprio_start <= 1'b1; + operation_address <= CP_CURRENT_REG; + end + VCO_REG: + begin + usr_vco_value <= slave_writedata[0]; + vco_changed <= 1'b1; + vco_done_q <= 0; + dprio_start <= 1'b1; + operation_address <= VCO_REG; + end + ANY_DPRIO: + begin + operation_address <= ANY_DPRIO; + manual_dprio_changed <= 1'b1; + usr_dprio_address <= slave_writedata[5:0]; + usr_dprio_writedata_0 <= slave_writedata[21:6]; + usr_r_w <= slave_writedata[22]; + manual_dprio_done_q <= 0; + dprio_start <= 1'b1; + end + MIF_REG: + begin + mif_reg_asserted <= 1'b1; + mif_base_addr <= slave_writedata[ROM_ADDR_WIDTH-1:0]; + mif_start_assert <= 1'b1; + end + endcase + end + end + end + //C Counter assigning values to the 2-d array of values for each C counter + + reg [4:0] j; + always @(posedge clk) + begin + + if (reset) + begin + c_cnt_changed[17:0] <= 0; + for (j = 0; j < number_of_counters; j = j + 1'b1) + begin : c_cnt_reset + temp_c_cnt_bypass_en[j] <= 0; + temp_c_cnt_odd_duty_div_en[j] <= 0; + temp_c_cnt_lo[j][7:0] <= 0; + temp_c_cnt_hi[j][7:0] <= 0; + end + end + else + begin + if (dprio_write_done) + begin + c_cnt_changed <= 0; + end + if (any_c_cnt_changed && (operation_address == C_COUNTERS_REG)) + begin + case (cnt_sel) + CNT_0: + begin + temp_c_cnt_lo [0] <= usr_c_cnt_lo; + temp_c_cnt_hi [0] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [0] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [0] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [0] <= 1'b1; + end + CNT_1: + begin + temp_c_cnt_lo [1] <= usr_c_cnt_lo; + temp_c_cnt_hi [1] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [1] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [1] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [1] <= 1'b1; + end + CNT_2: + begin + temp_c_cnt_lo [2] <= usr_c_cnt_lo; + temp_c_cnt_hi [2] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [2] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [2] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [2] <= 1'b1; + end + CNT_3: + begin + temp_c_cnt_lo [3] <= usr_c_cnt_lo; + temp_c_cnt_hi [3] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [3] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [3] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [3] <= 1'b1; + end + CNT_4: + begin + temp_c_cnt_lo [4] <= usr_c_cnt_lo; + temp_c_cnt_hi [4] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [4] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [4] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [4] <= 1'b1; + end + CNT_5: + begin + temp_c_cnt_lo [5] <= usr_c_cnt_lo; + temp_c_cnt_hi [5] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [5] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [5] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [5] <= 1'b1; + end + CNT_6: + begin + temp_c_cnt_lo [6] <= usr_c_cnt_lo; + temp_c_cnt_hi [6] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [6] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [6] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [6] <= 1'b1; + end + CNT_7: + begin + temp_c_cnt_lo [7] <= usr_c_cnt_lo; + temp_c_cnt_hi [7] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [7] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [7] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [7] <= 1'b1; + end + CNT_8: + begin + temp_c_cnt_lo [8] <= usr_c_cnt_lo; + temp_c_cnt_hi [8] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [8] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [8] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [8] <= 1'b1; + end + CNT_9: + begin + temp_c_cnt_lo [9] <= usr_c_cnt_lo; + temp_c_cnt_hi [9] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [9] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [9] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [9] <= 1'b1; + end + CNT_10: + begin + temp_c_cnt_lo [10] <= usr_c_cnt_lo; + temp_c_cnt_hi [10] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [10] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [10] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [10] <= 1'b1; + end + CNT_11: + begin + temp_c_cnt_lo [11] <= usr_c_cnt_lo; + temp_c_cnt_hi [11] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [11] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [11] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [11] <= 1'b1; + end + CNT_12: + begin + temp_c_cnt_lo [12] <= usr_c_cnt_lo; + temp_c_cnt_hi [12] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [12] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [12] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [12] <= 1'b1; + end + CNT_13: + begin + temp_c_cnt_lo [13] <= usr_c_cnt_lo; + temp_c_cnt_hi [13] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [13] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [13] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [13] <= 1'b1; + end + CNT_14: + begin + temp_c_cnt_lo [14] <= usr_c_cnt_lo; + temp_c_cnt_hi [14] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [14] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [14] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [14] <= 1'b1; + end + CNT_15: + begin + temp_c_cnt_lo [15] <= usr_c_cnt_lo; + temp_c_cnt_hi [15] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [15] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [15] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [15] <= 1'b1; + end + CNT_16: + begin + temp_c_cnt_lo [16] <= usr_c_cnt_lo; + temp_c_cnt_hi [16] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [16] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [16] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [16] <= 1'b1; + end + CNT_17: + begin + temp_c_cnt_lo [17] <= usr_c_cnt_lo; + temp_c_cnt_hi [17] <= usr_c_cnt_hi; + temp_c_cnt_bypass_en [17] <= usr_c_cnt_bypass_en; + temp_c_cnt_odd_duty_div_en [17] <= usr_c_cnt_odd_duty_div_en; + c_cnt_changed [17] <= 1'b1; + end + endcase + + end + end + end + + + //logic to handle which writes the user indicated and wants to start. + assign usr_valid_changes =dsm_k_changed| any_c_cnt_changed |n_cnt_changed | m_cnt_changed | dps_changed_valid |manual_dprio_changed |cp_current_changed|bwctrl_changed|vco_changed; + + + //start the reconfig operations by writing to the DPRIO + reg break_loop; + reg [4:0] i; + always @(*) + begin + dprio_temp_read_1 = 0; + dprio_temp_read_2 = 0; + dprio_temp_m_n_c_readdata_1_d = 0; + dprio_temp_m_n_c_readdata_2_d = 0; + break_loop = 0; + dprio_next_state = DPRIO_IDLE; + avmm_dprio_write = 0; + avmm_dprio_read = 0; + avmm_dprio_address = 0; + avmm_dprio_writedata = 0; + avmm_dprio_byteen = 0; + dprio_write_done = 1; + manual_dprio_done_d = 0; + n_cnt_done_d = 0; + dsm_k_done_d = 0; + dsm_k_ready_false_done_d = 0; + m_cnt_done_d = 0; + c_cnt_done_d[17:0] = 0; + all_c_cnt_done_d = 0; + bwctrl_done_d = 0; + cp_current_done_d = 0; + vco_done_d = 0; + i = 0; + + // Deassert dprio_write_done so it doesn't reset mif_reg_asserted (toggled writes) + if (dprio_start | mif_start_assert) + dprio_write_done = 0; + + if (current_state == WAIT_ON_LOCK) + begin + case (dprio_cur_state) + ONE: + begin + if (n_cnt_changed & !n_cnt_done_q) + begin + dprio_write_done = 0; + avmm_dprio_write = 1'b1; + avmm_dprio_byteen = 2'b11; + dprio_next_state = TWO; + avmm_dprio_address = N_CNT_DIV_ADDR; + avmm_dprio_writedata[7:0] = usr_n_cnt_lo; + avmm_dprio_writedata[15:8] = usr_n_cnt_hi; + end + else if (m_cnt_changed & !m_cnt_done_q) + begin + dprio_write_done = 0; + avmm_dprio_write = 1'b1; + avmm_dprio_byteen = 2'b11; + dprio_next_state = TWO; + avmm_dprio_address = M_CNT_DIV_ADDR; + avmm_dprio_writedata[7:0] = usr_m_cnt_lo; + avmm_dprio_writedata[15:8] = usr_m_cnt_hi; + end + else if (any_c_cnt_changed & !all_c_cnt_done_q) + begin + + for (i = 0; (i < number_of_counters) & !break_loop; i = i + 1'b1) + begin : c_cnt_write_hilo + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + dprio_write_done = 0; + avmm_dprio_write = 1'b1; + avmm_dprio_byteen = 2'b11; + dprio_next_state = TWO; + if (fpll_1) avmm_dprio_address = C_CNT_0_DIV_ADDR + C_CNT_0_DIV_ADDR_DPRIO_1 - i; + else avmm_dprio_address = C_CNT_0_DIV_ADDR + i; + avmm_dprio_writedata[7:0] = temp_c_cnt_lo[i]; + avmm_dprio_writedata[15:8] = temp_c_cnt_hi[i]; + //To break from the loop, since only one counter + //is addressed at a time + break_loop = 1'b1; + end + end + end + else if (dsm_k_changed & !dsm_k_done_q) + begin + dprio_write_done = 0; + avmm_dprio_write = 0; + dprio_next_state = TWO; + end + else if (bwctrl_changed & !bwctrl_done_q) + begin + dprio_write_done = 0; + avmm_dprio_write = 0; + dprio_next_state = TWO; + end + else if (cp_current_changed & !cp_current_done_q) + begin + dprio_write_done = 0; + avmm_dprio_write = 0; + dprio_next_state = TWO; + end + else if (vco_changed & !vco_done_q) + begin + dprio_write_done = 0; + avmm_dprio_write = 0; + dprio_next_state = TWO; + end + else if (manual_dprio_changed & !manual_dprio_done_q) + begin + dprio_write_done = 0; + avmm_dprio_byteen = 2'b11; + dprio_next_state = TWO; + avmm_dprio_write = usr_r_w; + avmm_dprio_address = usr_dprio_address; + avmm_dprio_writedata[15:0] = usr_dprio_writedata_0; + end + else dprio_next_state = DPRIO_IDLE; + end + + TWO: + begin + //handle reading the two setting bits on n_cnt, then + //writing them back while preserving other bits. + //Issue two consecutive reads then wait; readLatency=3 + dprio_write_done = 0; + dprio_next_state = THREE; + avmm_dprio_byteen = 2'b11; + avmm_dprio_read = 1'b1; + if (n_cnt_changed & !n_cnt_done_q) + begin + avmm_dprio_address = N_CNT_BYPASS_EN_ADDR; + end + else if (m_cnt_changed & !m_cnt_done_q) + begin + avmm_dprio_address = M_CNT_BYPASS_EN_ADDR; + end + + else if (any_c_cnt_changed & !all_c_cnt_done_q) + begin + for (i = 0; (i < number_of_counters) & !break_loop; i = i + 1'b1) + begin : c_cnt_read_bypass + if (fpll_1) + begin + if (i > 13) + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_0_3_BYPASS_EN_ADDR; + break_loop = 1'b1; + end + end + else + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_4_17_BYPASS_EN_ADDR; + break_loop = 1'b1; + end + end + end + else + begin + if (i < 4) + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_0_3_BYPASS_EN_ADDR; + break_loop = 1'b1; + end + end + else + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_4_17_BYPASS_EN_ADDR; + break_loop = 1'b1; + end + end + end + end + end + //reading the K ready 16 bit word. Need to write 0 to it + //afterwards to indicate that K has not been done writing + else if (dsm_k_changed & !dsm_k_done_q) + begin + avmm_dprio_address = DSM_K_READY_ADDR; + dprio_next_state = FOUR; + end + else if (bwctrl_changed & !bwctrl_done_q) + begin + avmm_dprio_address = BWCTRL_ADDR; + dprio_next_state = FOUR; + end + else if (cp_current_changed & !cp_current_done_q) + begin + avmm_dprio_address = CP_CURRENT_ADDR; + dprio_next_state = FOUR; + end + else if (vco_changed & !vco_done_q) + begin + avmm_dprio_address = VCO_ADDR; + dprio_next_state = FOUR; + end + else if (manual_dprio_changed & !manual_dprio_done_q) + begin + avmm_dprio_read = ~usr_r_w; + avmm_dprio_address = usr_dprio_address; + dprio_next_state = DPRIO_DONE; + end + else dprio_next_state = DPRIO_IDLE; + end + THREE: + begin + dprio_write_done = 0; + avmm_dprio_byteen = 2'b11; + avmm_dprio_read = 1'b1; + dprio_next_state = FOUR; + if (n_cnt_changed & !n_cnt_done_q) + begin + avmm_dprio_address = N_CNT_ODD_DIV_EN_ADDR; + end + else if (m_cnt_changed & !m_cnt_done_q) + begin + avmm_dprio_address = M_CNT_ODD_DIV_EN_ADDR; + end + else if (any_c_cnt_changed & !all_c_cnt_done_q) + begin + for (i = 0; (i < number_of_counters) & !break_loop; i = i + 1'b1) + begin : c_cnt_read_odd_div + if (fpll_1) + begin + if (i > 13) + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_0_3_ODD_DIV_EN_ADDR; + break_loop = 1'b1; + end + end + else + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_4_17_ODD_DIV_EN_ADDR; + break_loop = 1'b1; + end + end + end + else + begin + if (i < 4) + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_0_3_ODD_DIV_EN_ADDR; + break_loop = 1'b1; + end + end + else + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_4_17_ODD_DIV_EN_ADDR; + break_loop = 1'b1; + end + end + end + end + end + else dprio_next_state = DPRIO_IDLE; + end + FOUR: + begin + dprio_temp_read_1 = 1'b1; + dprio_write_done = 0; + if (vco_changed|cp_current_changed|bwctrl_changed|dsm_k_changed|n_cnt_changed|m_cnt_changed|any_c_cnt_changed) + begin + dprio_temp_m_n_c_readdata_1_d = dprio_readdata; + dprio_next_state = FIVE; + end + else dprio_next_state = DPRIO_IDLE; + end + FIVE: + begin + dprio_write_done = 0; + dprio_temp_read_2 = 1'b1; + if (vco_changed|cp_current_changed|bwctrl_changed|dsm_k_changed|n_cnt_changed|m_cnt_changed|any_c_cnt_changed) + begin + //this is where DSM ready value comes. + //Need to store in a register to be used later + dprio_temp_m_n_c_readdata_2_d = dprio_readdata; + dprio_next_state = SIX; + end + else dprio_next_state = DPRIO_IDLE; + end + SIX: + begin + dprio_write_done = 0; + avmm_dprio_write = 1'b1; + avmm_dprio_byteen = 2'b11; + dprio_next_state = SEVEN; + avmm_dprio_writedata = dprio_temp_m_n_c_readdata_1_q; + if (n_cnt_changed & !n_cnt_done_q) + begin + avmm_dprio_address = N_CNT_BYPASS_EN_ADDR; + avmm_dprio_writedata[5] = usr_n_cnt_bypass_en; + end + else if (m_cnt_changed & !m_cnt_done_q) + begin + avmm_dprio_address = M_CNT_BYPASS_EN_ADDR; + avmm_dprio_writedata[4] = usr_m_cnt_bypass_en; + end + else if (any_c_cnt_changed & !all_c_cnt_done_q) + begin + for (i = 0; (i < number_of_counters) & !break_loop; i = i + 1'b1) + begin : c_cnt_write_bypass + if (fpll_1) + begin + if (i > 13) + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_0_3_BYPASS_EN_ADDR; + avmm_dprio_writedata[i-14] = temp_c_cnt_bypass_en[i]; + break_loop = 1'b1; + end + end + else + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_4_17_BYPASS_EN_ADDR; + avmm_dprio_writedata[i] = temp_c_cnt_bypass_en[i]; + break_loop = 1'b1; + end + end + end + else + begin + if (i < 4) + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_0_3_BYPASS_EN_ADDR; + avmm_dprio_writedata[3-i] = temp_c_cnt_bypass_en[i]; + break_loop = 1'b1; + end + end + else + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_4_17_BYPASS_EN_ADDR; + avmm_dprio_writedata[17-i] = temp_c_cnt_bypass_en[i]; + break_loop = 1'b1; + end + end + end + end + end + else if (dsm_k_changed & !dsm_k_done_q) + begin + avmm_dprio_write = 0; + end + else if (bwctrl_changed & !bwctrl_done_q) + begin + avmm_dprio_write = 0; + end + else if (cp_current_changed & !cp_current_done_q) + begin + avmm_dprio_write = 0; + end + else if (vco_changed & !vco_done_q) + begin + avmm_dprio_write = 0; + end + else dprio_next_state = DPRIO_IDLE; + end + SEVEN: + begin + dprio_write_done = 0; + dprio_next_state = EIGHT; + avmm_dprio_write = 1'b1; + avmm_dprio_byteen = 2'b11; + avmm_dprio_writedata = dprio_temp_m_n_c_readdata_2_q; + if (n_cnt_changed & !n_cnt_done_q) + begin + avmm_dprio_address = N_CNT_ODD_DIV_EN_ADDR; + avmm_dprio_writedata[5] = usr_n_cnt_odd_duty_div_en; + n_cnt_done_d = 1'b1; + end + else if (m_cnt_changed & !m_cnt_done_q) + begin + avmm_dprio_address = M_CNT_ODD_DIV_EN_ADDR; + avmm_dprio_writedata[4] = usr_m_cnt_odd_duty_div_en; + m_cnt_done_d = 1'b1; + end + + else if (any_c_cnt_changed & !all_c_cnt_done_q) + begin + for (i = 0; (i < number_of_counters) & !break_loop; i = i + 1'b1) + begin : c_cnt_write_odd_div + if (fpll_1) + begin + if (i > 13) + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_0_3_ODD_DIV_EN_ADDR; + avmm_dprio_writedata[i-14] = temp_c_cnt_odd_duty_div_en[i]; + c_cnt_done_d[i] = 1'b1; + //have to OR the signals to prevent + //overwriting of previous dones + c_cnt_done_d = c_cnt_done_d | c_cnt_done_q; + break_loop = 1'b1; + end + end + else + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_4_17_ODD_DIV_EN_ADDR; + avmm_dprio_writedata[i] = temp_c_cnt_odd_duty_div_en[i]; + c_cnt_done_d[i] = 1'b1; + c_cnt_done_d = c_cnt_done_d | c_cnt_done_q; + break_loop = 1'b1; + end + end + end + else + begin + if (i < 4) + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_0_3_ODD_DIV_EN_ADDR; + avmm_dprio_writedata[3-i] = temp_c_cnt_odd_duty_div_en[i]; + c_cnt_done_d[i] = 1'b1; + //have to OR the signals to prevent + //overwriting of previous dones + c_cnt_done_d = c_cnt_done_d | c_cnt_done_q; + break_loop = 1'b1; + end + end + else + begin + if (c_cnt_changed[i] & !c_cnt_done_q[i]) + begin + avmm_dprio_address = C_CNT_4_17_ODD_DIV_EN_ADDR; + avmm_dprio_writedata[17-i] = temp_c_cnt_odd_duty_div_en[i]; + c_cnt_done_d[i] = 1'b1; + c_cnt_done_d = c_cnt_done_d | c_cnt_done_q; + break_loop = 1'b1; + end + end + end + end + end + else if (dsm_k_changed & !dsm_k_done_q) + begin + avmm_dprio_address = DSM_K_READY_ADDR; + avmm_dprio_writedata[DSM_K_READY_BIT_INDEX] = 1'b0; + dsm_k_ready_false_done_d = 1'b1; + end + else if (bwctrl_changed & !bwctrl_done_q) + begin + avmm_dprio_address = BWCTRL_ADDR; + avmm_dprio_writedata[3:0] = usr_bwctrl_value; + bwctrl_done_d = 1'b1; + end + else if (cp_current_changed & !cp_current_done_q) + begin + avmm_dprio_address = CP_CURRENT_ADDR; + avmm_dprio_writedata[2:0] = usr_cp_current_value; + cp_current_done_d = 1'b1; + end + else if (vco_changed & !vco_done_q) + begin + avmm_dprio_address = VCO_ADDR; + avmm_dprio_writedata[8] = usr_vco_value; + vco_done_d = 1'b1; + end + + + //if all C_cnt that were changed are done, then assert all_c_cnt_done + if (c_cnt_done_d == c_cnt_changed) + all_c_cnt_done_d = 1'b1; + if (n_cnt_changed & n_cnt_done_d) + dprio_next_state = DPRIO_DONE; + if (any_c_cnt_changed & !all_c_cnt_done_d & !all_c_cnt_done_q) + dprio_next_state = ONE; + else if (m_cnt_changed & !m_cnt_done_d & !m_cnt_done_q) + dprio_next_state = ONE; + else if (dsm_k_changed & !dsm_k_ready_false_done_d) + dprio_next_state = TWO; + else if (dsm_k_changed & !dsm_k_done_q) + dprio_next_state = EIGHT; + else if (bwctrl_changed & !bwctrl_done_d) + dprio_next_state = TWO; + else if (cp_current_changed & !cp_current_done_d) + dprio_next_state = TWO; + else if (vco_changed & !vco_done_d) + dprio_next_state = TWO; + else + begin + dprio_next_state = DPRIO_DONE; + dprio_write_done = 1'b1; + end + end + //finish the rest of the DSM reads/writes + //writing k value, writing k_ready to 1. + EIGHT: + begin + dprio_write_done = 0; + dprio_next_state = NINE; + avmm_dprio_write = 1'b1; + avmm_dprio_byteen = 2'b11; + if (dsm_k_changed & !dsm_k_done_q) + begin + avmm_dprio_address = DSM_K_FRACTIONAL_DIVISION_ADDR_0; + avmm_dprio_writedata[15:0] = usr_k_value[15:0]; + end + end + NINE: + begin + dprio_write_done = 0; + dprio_next_state = TEN; + avmm_dprio_write = 1'b1; + avmm_dprio_byteen = 2'b11; + if (dsm_k_changed & !dsm_k_done_q) + begin + avmm_dprio_address = DSM_K_FRACTIONAL_DIVISION_ADDR_1; + avmm_dprio_writedata[15:0] = usr_k_value[31:16]; + end + end + TEN: + begin + dprio_write_done = 0; + dprio_next_state = ONE; + avmm_dprio_write = 1'b1; + avmm_dprio_byteen = 2'b11; + if (dsm_k_changed & !dsm_k_done_q) + begin + avmm_dprio_address = DSM_K_READY_ADDR; + //already have the readdata for DSM_K_READY_ADDR since we read it + //earlier. Just reuse here + avmm_dprio_writedata = dprio_temp_m_n_c_readdata_2_q; + avmm_dprio_writedata[DSM_K_READY_BIT_INDEX] = 1'b1; + dsm_k_done_d = 1'b1; + end + end + DPRIO_DONE: + begin + dprio_write_done = 1'b1; + if (dprio_start) dprio_next_state = DPRIO_IDLE; + else dprio_next_state = DPRIO_DONE; + end + DPRIO_IDLE: + begin + if (dprio_start) dprio_next_state = ONE; + else dprio_next_state = DPRIO_IDLE; + end + default: dprio_next_state = 4'bxxxx; + endcase + end + + end + + + //assert the waitreq signal according to the state of the slave + assign slave_waitrequest = (slave_mode==mode_WR) ? ((locked === 1'b1) ? (((current_state==WAIT_ON_LOCK) & !dprio_write_done) | !dps_done |reset|!dprio_init_done) : 1'b1) : 1'b0; + + // Read operations + always @(*) + begin + status = 0; + if (slave_mode == mode_POLL) + //asserting status to 1 if the slave is done. + status = (current_state == LOCKED); + end + //************************************************************// + //************************************************************// + //******************** READ STATE MACHINE ********************// + //************************************************************// + //************************************************************// + reg [1:0] current_read_state; + reg [1:0] next_read_state; + reg [5:0] slave_address_int_d; + reg [5:0] slave_address_int_q; + reg dprio_read_1; + reg [5:0] dprio_address_1; + reg [1:0] dprio_byteen_1; + reg [4:0] usr_cnt_sel_1; + localparam READ = 2'b00, READ_WAIT = 2'b01, READ_IDLE = 2'b10, READ_POST_WAIT = 2'b11; + + always @(*) + begin + if(next_read_state == READ_IDLE) + begin + read_waitrequest <= 1'b0; + end + else + begin + read_waitrequest <= 1'b1; + end + end + + always @(posedge clk) + begin + if (reset) + begin + current_read_state <= READ_IDLE; + slave_address_int_q <= 0; + slave_readdata_q <= 0; + end + else + begin + current_read_state <= next_read_state; + slave_address_int_q <= slave_address_int_d; + slave_readdata_q <= slave_readdata_d; + end + end + always @(*) + begin + dprio_read_1 = 0; + dprio_address_1 = 0; + dprio_byteen_1 = 0; + slave_address_int_d = 0; + slave_readdata_d = 0; + status_read = 0; + usr_cnt_sel_1 = 0; + case(current_read_state) + READ_IDLE: + begin + slave_address_int_d = 0; + next_read_state = READ_IDLE; + if ((current_state != WAIT_ON_LOCK) && slave_read) + begin + slave_address_int_d = slave_address; + if ((slave_address >= CNT_BASE) && (slave_address < CNT_BASE+18)) + begin + next_read_state = READ_WAIT; + dprio_byteen_1 = 2'b11; + dprio_read_1 = 1'b1; + usr_cnt_sel_1 = (slave_address[4:0] - CNT_BASE); + if (fpll_1) dprio_address_1 = C_CNT_0_DIV_ADDR + C_CNT_0_DIV_ADDR_DPRIO_1 - cnt_sel; + else dprio_address_1 = C_CNT_0_DIV_ADDR + cnt_sel; + end + else + begin + case (slave_address) + MODE_REG: + begin + next_read_state = READ_WAIT; + slave_readdata_d = slave_mode; + end + STATUS_REG: + begin + next_read_state = READ_WAIT; + status_read = 1'b1; + slave_readdata_d = status; + end + N_REG: + begin + dprio_byteen_1 = 2'b11; + dprio_read_1 = 1'b1; + dprio_address_1 = N_CNT_DIV_ADDR; + next_read_state = READ_WAIT; + end + M_REG: + begin + dprio_byteen_1 = 2'b11; + dprio_read_1 = 1'b1; + dprio_address_1 = M_CNT_DIV_ADDR; + next_read_state = READ_WAIT; + end + BWCTRL_REG: + begin + dprio_byteen_1 = 2'b11; + dprio_read_1 = 1'b1; + dprio_address_1 = BWCTRL_ADDR; + next_read_state = READ_WAIT; + end + CP_CURRENT_REG: + begin + dprio_byteen_1 = 2'b11; + dprio_read_1 = 1'b1; + dprio_address_1 = CP_CURRENT_ADDR; + next_read_state = READ_WAIT; + end + VCO_REG: + begin + dprio_byteen_1 = 2'b11; + dprio_read_1 = 1'b1; + dprio_address_1 = VCO_ADDR; + next_read_state = READ_WAIT; + end + ANY_DPRIO: + begin + dprio_byteen_1 = 2'b11; + dprio_read_1 = ~slave_writedata[22]; + dprio_address_1 = slave_writedata[5:0]; + next_read_state = READ_WAIT; + end + default : next_read_state = READ_IDLE; + endcase + end + end + else + next_read_state = READ_IDLE; + end + READ_WAIT: + begin + next_read_state = READ; + slave_address_int_d = slave_address_int_q; + case (slave_address_int_q) + MODE_REG: + begin + slave_readdata_d = slave_readdata_q; + end + STATUS_REG: + begin + slave_readdata_d = slave_readdata_q; + end + endcase + end + READ: + begin + next_read_state = READ_POST_WAIT; + slave_address_int_d = slave_address_int_q; + slave_readdata_d = dprio_readdata; + case (slave_address_int_q) + MODE_REG: + begin + slave_readdata_d = slave_readdata_q; + end + STATUS_REG: + begin + slave_readdata_d = slave_readdata_q; + end + BWCTRL_REG: + begin + slave_readdata_d = dprio_readdata[3:0]; + end + CP_CURRENT_REG: + begin + slave_readdata_d = dprio_readdata[2:0]; + end + VCO_REG: + begin + slave_readdata_d = dprio_readdata[8]; + end + ANY_DPRIO: + begin + slave_readdata_d = dprio_readdata; + end + endcase + end + READ_POST_WAIT: + begin + next_read_state = READ_IDLE; + end + default: next_read_state = 2'bxx; + endcase + end + + + dyn_phase_shift dyn_phase_shift_inst ( + .clk(clk), + .reset(reset), + .phase_done(phase_done), + .pll_start_valid(pll_start_valid), + .dps_changed(dps_changed), + .dps_changed_valid(dps_changed_valid), + .dprio_write_done(dprio_write_done), + .usr_num_shifts(usr_num_shifts), + .usr_cnt_sel(usr_cnt_sel|usr_cnt_sel_1), + .usr_up_dn(usr_up_dn), + .locked(locked), + .dps_done(dps_done), + .phase_en(phase_en), + .up_dn(up_dn), + .cnt_sel(cnt_sel)); + defparam dyn_phase_shift_inst.device_family = device_family; + + assign dprio_clk = clk; + self_reset self_reset_inst (mgmt_reset, clk, reset, dprio_init_reset); + + dprio_mux dprio_mux_inst ( + .init_dprio_address(init_dprio_address), + .init_dprio_read(init_dprio_read), + .init_dprio_byteen(init_dprio_byteen), + .init_dprio_write(init_dprio_write), + .init_dprio_writedata(init_dprio_writedata), + + + .init_atpgmode(init_atpgmode), + .init_mdio_dis(init_mdio_dis), + .init_scanen(init_scanen), + .init_ser_shift_load(init_ser_shift_load), + .dprio_init_done(dprio_init_done), + + // Inputs from avmm master + .avmm_dprio_address(avmm_dprio_address | dprio_address_1), + .avmm_dprio_read(avmm_dprio_read | dprio_read_1), + .avmm_dprio_byteen(avmm_dprio_byteen | dprio_byteen_1), + .avmm_dprio_write(avmm_dprio_write), + .avmm_dprio_writedata(avmm_dprio_writedata), + + .avmm_atpgmode(avmm_atpgmode), + .avmm_mdio_dis(avmm_mdio_dis), + .avmm_scanen(avmm_scanen), + + // Outputs to fpll + .dprio_address(dprio_address), + .dprio_read(dprio_read), + .dprio_byteen(dprio_byteen), + .dprio_write(dprio_write), + .dprio_writedata(dprio_writedata), + + .atpgmode(dprio_atpgmode), + .mdio_dis(dprio_mdio_dis), + .scanen(dprio_scanen), + .ser_shift_load(dprio_ser_shift_load) + ); + + + fpll_dprio_init fpll_dprio_init_inst ( + .clk(clk), + .reset_n(~reset), + .locked(locked), + + //outputs + .dprio_address(init_dprio_address), + .dprio_read(init_dprio_read), + .dprio_byteen(init_dprio_byteen), + .dprio_write(init_dprio_write), + .dprio_writedata(init_dprio_writedata), + + .atpgmode(init_atpgmode), + .mdio_dis(init_mdio_dis), + .scanen(init_scanen), + .ser_shift_load(init_ser_shift_load), + .dprio_init_done(dprio_init_done)); + + //address luts, to be reconfigged by the Fitter + //FPLL_1 or 0 address lut + generic_lcell_comb lcell_fpll_0_1 ( + .dataa(1'b0), + .combout (fpll_1)); + defparam lcell_fpll_0_1.lut_mask = 64'hAAAAAAAAAAAAAAAA; + defparam lcell_fpll_0_1.dont_touch = "on"; + defparam lcell_fpll_0_1.family = device_family; + + + wire dprio_read_combout; + generic_lcell_comb lcell_dprio_read ( + .dataa(fpll_1), + .datab(dprio_read), + .datac(1'b0), + .datad(1'b0), + .datae(1'b0), + .dataf(1'b0), + .combout (dprio_read_combout)); + defparam lcell_dprio_read.lut_mask = 64'hCCCCCCCCCCCCCCCC; + defparam lcell_dprio_read.dont_touch = "on"; + defparam lcell_dprio_read.family = device_family; + + + + + + //assign reconfig_to_pll signals + assign reconfig_to_pll[0] = dprio_clk; + assign reconfig_to_pll[1] = ~dprio_init_reset; + assign reconfig_to_pll[2] = dprio_write; + assign reconfig_to_pll[3] = dprio_read_combout; + assign reconfig_to_pll[9:4] = dprio_address; + assign reconfig_to_pll[25:10] = dprio_writedata; + assign reconfig_to_pll[27:26] = dprio_byteen; + assign reconfig_to_pll[28] = dprio_ser_shift_load; + assign reconfig_to_pll[29] = dprio_mdio_dis; + assign reconfig_to_pll[30] = phase_en; + assign reconfig_to_pll[31] = up_dn; + assign reconfig_to_pll[36:32] = cnt_sel; + assign reconfig_to_pll[37] = dprio_scanen; + assign reconfig_to_pll[38] = dprio_atpgmode; + //assign reconfig_to_pll[40:37] = clken; + assign reconfig_to_pll[63:39] = 0; + + //assign reconfig_from_pll signals + assign dprio_readdata = reconfig_from_pll [15:0]; + assign locked_orig = reconfig_from_pll [16]; + assign phase_done = reconfig_from_pll [17]; + +endmodule +module self_reset (input wire mgmt_reset, input wire clk, output wire reset, output wire init_reset); + + localparam RESET_COUNTER_VALUE = 3'd2; + localparam INITIAL_WAIT_VALUE = 9'd340; + reg [9:0]counter; + reg local_reset; + reg usr_mode_init_wait; + initial + begin + local_reset = 1'b1; + counter = 0; + usr_mode_init_wait = 0; + end + + always @(posedge clk) + begin + if (mgmt_reset) + begin + counter <= 0; + end + else + begin + if (!usr_mode_init_wait) + begin + if (counter == INITIAL_WAIT_VALUE) + begin + local_reset <= 0; + usr_mode_init_wait <= 1'b1; + counter <= 0; + end + else + begin + counter <= counter + 1'b1; + end + end + else + begin + if (counter == RESET_COUNTER_VALUE) + local_reset <= 0; + else + counter <= counter + 1'b1; + end + end + end + assign reset = mgmt_reset | local_reset; + assign init_reset = local_reset; +endmodule + +module dprio_mux ( + // Inputs from init block + input [ 5:0] init_dprio_address, + input init_dprio_read, + input [ 1:0] init_dprio_byteen, + input init_dprio_write, + input [15:0] init_dprio_writedata, + + input init_atpgmode, + input init_mdio_dis, + input init_scanen, + input init_ser_shift_load, + input dprio_init_done, + + // Inputs from avmm master + input [ 5:0] avmm_dprio_address, + input avmm_dprio_read, + input [ 1:0] avmm_dprio_byteen, + input avmm_dprio_write, + input [15:0] avmm_dprio_writedata, + + input avmm_atpgmode, + input avmm_mdio_dis, + input avmm_scanen, + input avmm_ser_shift_load, + + // Outputs to fpll + output [ 5:0] dprio_address, + output dprio_read, + output [ 1:0] dprio_byteen, + output dprio_write, + output [15:0] dprio_writedata, + + output atpgmode, + output mdio_dis, + output scanen, + output ser_shift_load +); + + assign dprio_address = dprio_init_done ? avmm_dprio_address : init_dprio_address; + assign dprio_read = dprio_init_done ? avmm_dprio_read : init_dprio_read; + assign dprio_byteen = dprio_init_done ? avmm_dprio_byteen : init_dprio_byteen; + assign dprio_write = dprio_init_done ? avmm_dprio_write : init_dprio_write; + assign dprio_writedata = dprio_init_done ? avmm_dprio_writedata : init_dprio_writedata; + + assign atpgmode = init_atpgmode; + assign scanen = init_scanen; + assign mdio_dis = init_mdio_dis; + assign ser_shift_load = init_ser_shift_load ; +endmodule +module fpll_dprio_init ( + input clk, + input reset_n, + input locked, + + output [ 5:0] dprio_address, + output dprio_read, + output [ 1:0] dprio_byteen, + output dprio_write, + output [15:0] dprio_writedata, + + output reg atpgmode, + output reg mdio_dis, + output reg scanen, + output reg ser_shift_load, + output reg dprio_init_done +); + + reg [1:0] rst_n = 2'b00; + reg [6:0] count = 7'd0; + reg init_done_forever; + + // Internal versions of control signals + wire int_mdio_dis; + wire int_ser_shift_load; + wire int_dprio_init_done; + wire int_atpgmode/*synthesis keep*/; + wire int_scanen/*synthesis keep*/; + + + assign dprio_address = count[6] ? 5'b0 : count[5:0] ; + assign dprio_byteen = 2'b11; // always enabled + assign dprio_write = ~count[6] & reset_n ; // write for first 64 cycles + assign dprio_read = 1'b0; + assign dprio_writedata = 16'd0; + + assign int_ser_shift_load = count[6] ? |count[2:1] : 1'b1; + assign int_mdio_dis = count[6] ? ~count[2] : 1'b1; + assign int_dprio_init_done = ~init_done_forever ? (count[6] ? &count[2:0] : 1'b0) + : 1'b1; + assign int_atpgmode = 0; + assign int_scanen = 0; + + initial begin + count = 7'd0; + init_done_forever = 0; + mdio_dis = 1'b1; + ser_shift_load = 1'b1; + dprio_init_done = 1'b0; + scanen = 1'b0; + atpgmode = 1'b0; + end + + // reset synch. + always @(posedge clk or negedge reset_n) + if(!reset_n) rst_n <= 2'b00; + else rst_n <= {rst_n[0],1'b1}; + + // counter + always @(posedge clk) + begin + if (!rst_n[1]) + init_done_forever <= 1'b0; + else + begin + if (count[6] && &count[1:0]) + init_done_forever <= 1'b1; + end + end + always @(posedge clk or negedge rst_n[1]) + begin + if(!rst_n[1]) + begin + count <= 7'd0; + end + else if(~int_dprio_init_done) + begin + count <= count + 7'd1; + end + else + begin + count <= count; + end + end + + // outputs + always @(posedge clk) begin + mdio_dis <= int_mdio_dis; + ser_shift_load <= int_ser_shift_load; + dprio_init_done <= int_dprio_init_done; + atpgmode <= int_atpgmode; + scanen <= int_scanen; + end + +endmodule +module dyn_phase_shift +#( + parameter device_family = "Stratix V" +) ( + + input wire clk, + input wire reset, + input wire phase_done, + input wire pll_start_valid, + input wire dps_changed, + input wire dprio_write_done, + input wire [15:0] usr_num_shifts, + input wire [4:0] usr_cnt_sel, + input wire usr_up_dn, + input wire locked, + + //output + output wire dps_done, + output reg phase_en, + output wire up_dn, + output wire dps_changed_valid, + output wire [4:0] cnt_sel); + + + + reg first_phase_shift_d; + reg first_phase_shift_q; + reg [15:0] phase_en_counter; + reg [3:0] dps_current_state; + reg [3:0] dps_next_state; + localparam DPS_START = 4'd0, DPS_WAIT_PHASE_DONE = 4'd1, DPS_DONE = 4'd2, DPS_WAIT_PHASE_EN = 4'd3, DPS_WAIT_DPRIO_WRITING = 4'd4, DPS_CHANGED = 4'd5; + localparam PHASE_EN_WAIT_COUNTER = 5'd1; + + reg [15:0] shifts_done_counter; + reg phase_done_final; + wire gnd /*synthesis keep*/; + + //fsm + //always block controlling the state regs + always @(posedge clk) + begin + if (reset) + begin + dps_current_state <= DPS_DONE; + end + else + begin + dps_current_state <= dps_next_state; + end + end + //the combinational part. assigning the next state + //this turns on the phase_done_final signal when phase_done does this: + //_____ ______ + // |______| + always @(*) + begin + phase_done_final = 0; + first_phase_shift_d = 0; + phase_en = 0; + dps_next_state = DPS_DONE; + case (dps_current_state) + DPS_START: + begin + phase_en = 1'b1; + dps_next_state = DPS_WAIT_PHASE_EN; + end + DPS_WAIT_PHASE_EN: + begin + phase_en = 1'b1; + if (first_phase_shift_q) + begin + first_phase_shift_d = 1'b1; + dps_next_state = DPS_WAIT_PHASE_EN; + end + else + begin + if (phase_en_counter == PHASE_EN_WAIT_COUNTER) + dps_next_state = DPS_WAIT_PHASE_DONE; + else dps_next_state = DPS_WAIT_PHASE_EN; + end + end + DPS_WAIT_PHASE_DONE: + begin + if (!phase_done | !locked) + begin + dps_next_state = DPS_WAIT_PHASE_DONE; + end + else + begin + if ((usr_num_shifts != shifts_done_counter) & (usr_num_shifts != 0)) + begin + dps_next_state = DPS_START; + phase_done_final = 1'b1; + end + else + begin + dps_next_state = DPS_DONE; + end + + end + end + DPS_DONE: + begin + phase_done_final = 0; + if (dps_changed) + dps_next_state = DPS_CHANGED; + else dps_next_state = DPS_DONE; + + end + DPS_CHANGED: + begin + if (pll_start_valid) + dps_next_state = DPS_WAIT_DPRIO_WRITING; + else + dps_next_state = DPS_CHANGED; + end + DPS_WAIT_DPRIO_WRITING: + begin + if (dprio_write_done) + dps_next_state = DPS_START; + else + dps_next_state = DPS_WAIT_DPRIO_WRITING; + end + + default: dps_next_state = 4'bxxxx; + endcase + + + end + + always @(posedge clk) + begin + + + if (dps_current_state == DPS_WAIT_PHASE_DONE) + phase_en_counter <= 0; + else if (dps_current_state == DPS_WAIT_PHASE_EN) + phase_en_counter <= phase_en_counter + 1'b1; + + if (reset) + begin + phase_en_counter <= 0; + shifts_done_counter <= 1'b1; + first_phase_shift_q <= 1; + end + else + begin + if (first_phase_shift_d) + first_phase_shift_q <= 0; + if (dps_done) + begin + shifts_done_counter <= 1'b1; + end + else + begin + if (phase_done_final & (dps_next_state!= DPS_DONE)) + shifts_done_counter <= shifts_done_counter + 1'b1; + else + shifts_done_counter <= shifts_done_counter; + end + end + end + + assign dps_changed_valid = (dps_current_state == DPS_CHANGED); + assign dps_done =(dps_current_state == DPS_DONE) | (dps_current_state == DPS_CHANGED); + assign up_dn = usr_up_dn; + assign gnd = 1'b0; + + //cnt select luts (5) + generic_lcell_comb lcell_cnt_sel_0 ( + .dataa(usr_cnt_sel[0]), + .datab(usr_cnt_sel[1]), + .datac(usr_cnt_sel[2]), + .datad(usr_cnt_sel[3]), + .datae(usr_cnt_sel[4]), + .dataf(gnd), + .combout (cnt_sel[0])); + defparam lcell_cnt_sel_0.lut_mask = 64'hAAAAAAAAAAAAAAAA; + defparam lcell_cnt_sel_0.dont_touch = "on"; + defparam lcell_cnt_sel_0.family = device_family; + generic_lcell_comb lcell_cnt_sel_1 ( + .dataa(usr_cnt_sel[0]), + .datab(usr_cnt_sel[1]), + .datac(usr_cnt_sel[2]), + .datad(usr_cnt_sel[3]), + .datae(usr_cnt_sel[4]), + .dataf(gnd), + .combout (cnt_sel[1])); + defparam lcell_cnt_sel_1.lut_mask = 64'hCCCCCCCCCCCCCCCC; + defparam lcell_cnt_sel_1.dont_touch = "on"; + defparam lcell_cnt_sel_1.family = device_family; + generic_lcell_comb lcell_cnt_sel_2 ( + .dataa(usr_cnt_sel[0]), + .datab(usr_cnt_sel[1]), + .datac(usr_cnt_sel[2]), + .datad(usr_cnt_sel[3]), + .datae(usr_cnt_sel[4]), + .dataf(gnd), + .combout (cnt_sel[2])); + defparam lcell_cnt_sel_2.lut_mask = 64'hF0F0F0F0F0F0F0F0; + defparam lcell_cnt_sel_2.dont_touch = "on"; + defparam lcell_cnt_sel_2.family = device_family; + generic_lcell_comb lcell_cnt_sel_3 ( + .dataa(usr_cnt_sel[0]), + .datab(usr_cnt_sel[1]), + .datac(usr_cnt_sel[2]), + .datad(usr_cnt_sel[3]), + .datae(usr_cnt_sel[4]), + .dataf(gnd), + .combout (cnt_sel[3])); + defparam lcell_cnt_sel_3.lut_mask = 64'hFF00FF00FF00FF00; + defparam lcell_cnt_sel_3.dont_touch = "on"; + defparam lcell_cnt_sel_3.family = device_family; + generic_lcell_comb lcell_cnt_sel_4 ( + .dataa(usr_cnt_sel[0]), + .datab(usr_cnt_sel[1]), + .datac(usr_cnt_sel[2]), + .datad(usr_cnt_sel[3]), + .datae(usr_cnt_sel[4]), + .dataf(gnd), + .combout (cnt_sel[4])); + defparam lcell_cnt_sel_4.lut_mask = 64'hFFFF0000FFFF0000; + defparam lcell_cnt_sel_4.dont_touch = "on"; + defparam lcell_cnt_sel_4.family = device_family; + + +endmodule + +module generic_lcell_comb +#( + //parameter + parameter family = "Stratix V", + parameter lut_mask = 64'hAAAAAAAAAAAAAAAA, + parameter dont_touch = "on" +) ( + + input dataa, + input datab, + input datac, + input datad, + input datae, + input dataf, + + output combout +); + + generate + if (family == "Stratix V") + begin + stratixv_lcell_comb lcell_inst ( + .dataa(dataa), + .datab(datab), + .datac(datac), + .datad(datad), + .datae(datae), + .dataf(dataf), + .combout (combout)); + defparam lcell_inst.lut_mask = lut_mask; + defparam lcell_inst.dont_touch = dont_touch; + end + else if (family == "Arria V") + begin + arriav_lcell_comb lcell_inst ( + .dataa(dataa), + .datab(datab), + .datac(datac), + .datad(datad), + .datae(datae), + .dataf(dataf), + .combout (combout)); + defparam lcell_inst.lut_mask = lut_mask; + defparam lcell_inst.dont_touch = dont_touch; + end + else if (family == "Arria V GZ") + begin + arriavgz_lcell_comb lcell_inst ( + .dataa(dataa), + .datab(datab), + .datac(datac), + .datad(datad), + .datae(datae), + .dataf(dataf), + .combout (combout)); + defparam lcell_inst.lut_mask = lut_mask; + defparam lcell_inst.dont_touch = dont_touch; + end + else if (family == "Cyclone V") + begin + cyclonev_lcell_comb lcell_inst ( + .dataa(dataa), + .datab(datab), + .datac(datac), + .datad(datad), + .datae(datae), + .dataf(dataf), + .combout (combout)); + defparam lcell_inst.lut_mask = lut_mask; + defparam lcell_inst.dont_touch = dont_touch; + end + endgenerate +endmodule diff --git a/sys/pll_hdmi_cfg/altera_pll_reconfig_top.v b/sys/pll_hdmi_cfg/altera_pll_reconfig_top.v new file mode 100644 index 0000000..c1bfa8b --- /dev/null +++ b/sys/pll_hdmi_cfg/altera_pll_reconfig_top.v @@ -0,0 +1,428 @@ +// (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. + + +`timescale 1ps/1ps + +module altera_pll_reconfig_top +#( + parameter reconf_width = 64, + parameter device_family = "Stratix V", + parameter RECONFIG_ADDR_WIDTH = 6, + parameter RECONFIG_DATA_WIDTH = 32, + + parameter ROM_ADDR_WIDTH = 9, + parameter ROM_DATA_WIDTH = 32, + parameter ROM_NUM_WORDS = 512, + + parameter ENABLE_MIF = 0, + parameter MIF_FILE_NAME = "", + + parameter ENABLE_BYTEENABLE = 0, + parameter BYTEENABLE_WIDTH = 4, + parameter WAIT_FOR_LOCK = 1 +) ( + + //input + input wire mgmt_clk, + input wire mgmt_reset, + + + //conduits + output wire [reconf_width-1:0] reconfig_to_pll, + input wire [reconf_width-1:0] reconfig_from_pll, + + // user data (avalon-MM slave interface) + output wire [RECONFIG_DATA_WIDTH-1:0] mgmt_readdata, + output wire mgmt_waitrequest, + input wire [RECONFIG_ADDR_WIDTH-1:0] mgmt_address, + input wire mgmt_read, + input wire mgmt_write, + input wire [RECONFIG_DATA_WIDTH-1:0] mgmt_writedata, + + //conditional input + input wire [BYTEENABLE_WIDTH-1:0] mgmt_byteenable +); + +localparam NM28_START_REG = 6'b000010; +localparam NM20_START_REG = 9'b000000000; +localparam NM20_MIFSTART_ADDR = 9'b000010000; + +localparam MIF_STATE_DONE = 2'b00; +localparam MIF_STATE_START = 2'b01; +localparam MIF_STATE_BUSY = 2'b10; + +wire mgmt_byteenable_write; +assign mgmt_byteenable_write = (ENABLE_BYTEENABLE == 1) ? + ((mgmt_byteenable == {BYTEENABLE_WIDTH{1'b1}}) ? mgmt_write : 1'b0) : + mgmt_write; + +generate +if (device_family == "Arria 10") +begin:nm20_reconfig + if(ENABLE_MIF == 1) + begin:mif_reconfig_20nm // Generate Reconfig with MIF + + // MIF-related regs/wires + reg [RECONFIG_ADDR_WIDTH-1:0] reconfig_mgmt_addr; + reg reconfig_mgmt_read; + reg reconfig_mgmt_write; + reg [RECONFIG_DATA_WIDTH-1:0] reconfig_mgmt_writedata; + wire reconfig_mgmt_waitrequest; + wire [RECONFIG_DATA_WIDTH-1:0] reconfig_mgmt_readdata; + + wire [RECONFIG_ADDR_WIDTH-1:0] mif2reconfig_addr; + wire mif_busy; + wire mif2reconfig_read; + wire mif2reconfig_write; + wire [RECONFIG_DATA_WIDTH-1:0] mif2reconfig_writedata; + wire [ROM_ADDR_WIDTH-1:0] mif_base_addr; + reg mif_select; + //wire mif_user_start; // start signal provided by user to start mif + //reg user_start; + + reg [1:0] mif_curstate; + reg [1:0] mif_nextstate; + + wire mif_start; //start signal to mif reader + + assign mgmt_waitrequest = reconfig_mgmt_waitrequest | mif_busy;// | user_start; + // Don't output readdata if MIF streaming is taking place + assign mgmt_readdata = (mif_select) ? 32'b0 : reconfig_mgmt_readdata; + + //user must lower this by the time mif streaming is done - suggest to lower after 1 cycle + assign mif_start = mgmt_byteenable_write & (mgmt_address == NM20_MIFSTART_ADDR); + + //mif base addr is initially specified by the user + assign mif_base_addr = mgmt_writedata[ROM_ADDR_WIDTH-1:0]; + + //MIF statemachine + always @(posedge mgmt_clk) + begin + if(mgmt_reset) + mif_curstate <= MIF_STATE_DONE; + else + mif_curstate <= mif_nextstate; + end + + always @(*) + begin + case (mif_curstate) + MIF_STATE_DONE: + begin + if(mif_start) + mif_nextstate <= MIF_STATE_START; + else + mif_nextstate <= MIF_STATE_DONE; + end + MIF_STATE_START: + begin + mif_nextstate <= MIF_STATE_BUSY; + end + MIF_STATE_BUSY: + begin + if(mif_busy) + mif_nextstate <= MIF_STATE_BUSY; + else + mif_nextstate <= MIF_STATE_DONE; + end + endcase + end + + //Mif muxes + always @(*) + begin + if (mgmt_reset) + begin + reconfig_mgmt_addr <= 0; + reconfig_mgmt_read <= 0; + reconfig_mgmt_write <= 0; + reconfig_mgmt_writedata <= 0; + //user_start <= 0; + end + else + begin + reconfig_mgmt_addr <= (mif_select) ? mif2reconfig_addr : mgmt_address; + reconfig_mgmt_read <= (mif_select) ? mif2reconfig_read : mgmt_read; + reconfig_mgmt_write <= (mif_select) ? mif2reconfig_write : mgmt_byteenable_write; + reconfig_mgmt_writedata <= (mif_select) ? mif2reconfig_writedata : mgmt_writedata; + //user_start <= (mgmt_address == NM20_START_REG && mgmt_write == 1'b1) ? 1'b1 : 1'b0; + end + end + + always @(*) + begin + if (mgmt_reset) + begin + mif_select <= 0; + end + else + begin + mif_select <= (mif_start || mif_busy) ? 1'b1 : 1'b0; + end + end + + twentynm_pll_reconfig_mif_reader + #( + .RECONFIG_ADDR_WIDTH(RECONFIG_ADDR_WIDTH), + .RECONFIG_DATA_WIDTH(RECONFIG_DATA_WIDTH), + .ROM_ADDR_WIDTH(ROM_ADDR_WIDTH), + .ROM_DATA_WIDTH(ROM_DATA_WIDTH), + .ROM_NUM_WORDS(ROM_NUM_WORDS), + .DEVICE_FAMILY(device_family), + .ENABLE_MIF(ENABLE_MIF), + .MIF_FILE_NAME(MIF_FILE_NAME) + ) twentynm_pll_reconfig_mif_reader_inst0 ( + .mif_clk(mgmt_clk), + .mif_rst(mgmt_reset), + + //Altera_PLL Reconfig interface + //inputs + .reconfig_waitrequest(reconfig_mgmt_waitrequest), + //.reconfig_read_data(reconfig_mgmt_readdata), + //outputs + .reconfig_write_data(mif2reconfig_writedata), + .reconfig_addr(mif2reconfig_addr), + .reconfig_write(mif2reconfig_write), + .reconfig_read(mif2reconfig_read), + + //MIF Ctrl Interface + //inputs + .mif_base_addr(mif_base_addr), + .mif_start(mif_start), + //outputs + .mif_busy(mif_busy) + ); + + // ------ END MIF-RELATED MANAGEMENT ------ + + twentynm_iopll_reconfig_core + #( + .WAIT_FOR_LOCK(WAIT_FOR_LOCK) + ) twentynm_iopll_reconfig_core_inst ( + // Inputs + .mgmt_clk(mgmt_clk), + .mgmt_rst_n(~mgmt_reset), + .mgmt_read(reconfig_mgmt_read), + .mgmt_write(reconfig_mgmt_write), + .mgmt_address(reconfig_mgmt_addr), + .mgmt_writedata(reconfig_mgmt_writedata), + + // Outputs + .mgmt_readdata(reconfig_mgmt_readdata), + .mgmt_waitrequest(reconfig_mgmt_waitrequest), + + // PLL Conduits + .reconfig_to_pll(reconfig_to_pll), + .reconfig_from_pll(reconfig_from_pll) + ); + + end // End generate reconfig with MIF + else + begin:reconfig_core_20nm + twentynm_iopll_reconfig_core + #( + .WAIT_FOR_LOCK(WAIT_FOR_LOCK) + ) twentynm_iopll_reconfig_core_inst ( + // Inputs + .mgmt_clk(mgmt_clk), + .mgmt_rst_n(~mgmt_reset), + .mgmt_read(mgmt_read), + .mgmt_write(mgmt_byteenable_write), + .mgmt_address(mgmt_address), + .mgmt_writedata(mgmt_writedata), + + // Outputs + .mgmt_readdata(mgmt_readdata), + .mgmt_waitrequest(mgmt_waitrequest), + + // PLL Conduits + .reconfig_to_pll(reconfig_to_pll), + .reconfig_from_pll(reconfig_from_pll) + ); + end +end // 20nm reconfig +else +begin:NM28_reconfig + if (ENABLE_MIF == 1) + begin:mif_reconfig // Generate Reconfig with MIF + + // MIF-related regs/wires + reg [RECONFIG_ADDR_WIDTH-1:0] reconfig_mgmt_addr; + reg reconfig_mgmt_read; + reg reconfig_mgmt_write; + reg [RECONFIG_DATA_WIDTH-1:0] reconfig_mgmt_writedata; + wire reconfig_mgmt_waitrequest; + wire [RECONFIG_DATA_WIDTH-1:0] reconfig_mgmt_readdata; + + wire [RECONFIG_ADDR_WIDTH-1:0] mif2reconfig_addr; + wire mif2reconfig_busy; + wire mif2reconfig_read; + wire mif2reconfig_write; + wire [RECONFIG_DATA_WIDTH-1:0] mif2reconfig_writedata; + wire [ROM_ADDR_WIDTH-1:0] mif_base_addr; + reg mif_select; + reg user_start; + + wire reconfig2mif_start_out; + + assign mgmt_waitrequest = reconfig_mgmt_waitrequest | mif2reconfig_busy | user_start; + // Don't output readdata if MIF streaming is taking place + assign mgmt_readdata = (mif_select) ? 32'b0 : reconfig_mgmt_readdata; + + always @(posedge mgmt_clk) + begin + if (mgmt_reset) + begin + reconfig_mgmt_addr <= 0; + reconfig_mgmt_read <= 0; + reconfig_mgmt_write <= 0; + reconfig_mgmt_writedata <= 0; + user_start <= 0; + end + else + begin + reconfig_mgmt_addr <= (mif_select) ? mif2reconfig_addr : mgmt_address; + reconfig_mgmt_read <= (mif_select) ? mif2reconfig_read : mgmt_read; + reconfig_mgmt_write <= (mif_select) ? mif2reconfig_write : mgmt_byteenable_write; + reconfig_mgmt_writedata <= (mif_select) ? mif2reconfig_writedata : mgmt_writedata; + user_start <= (mgmt_address == NM28_START_REG && mgmt_byteenable_write == 1'b1) ? 1'b1 : 1'b0; + end + end + + always @(*) + begin + if (mgmt_reset) + begin + mif_select <= 0; + end + else + begin + mif_select <= (reconfig2mif_start_out || mif2reconfig_busy) ? 1'b1 : 1'b0; + end + end + + altera_pll_reconfig_mif_reader + #( + .RECONFIG_ADDR_WIDTH(RECONFIG_ADDR_WIDTH), + .RECONFIG_DATA_WIDTH(RECONFIG_DATA_WIDTH), + .ROM_ADDR_WIDTH(ROM_ADDR_WIDTH), + .ROM_DATA_WIDTH(ROM_DATA_WIDTH), + .ROM_NUM_WORDS(ROM_NUM_WORDS), + .DEVICE_FAMILY(device_family), + .ENABLE_MIF(ENABLE_MIF), + .MIF_FILE_NAME(MIF_FILE_NAME) + ) altera_pll_reconfig_mif_reader_inst0 ( + .mif_clk(mgmt_clk), + .mif_rst(mgmt_reset), + + //Altera_PLL Reconfig interface + //inputs + .reconfig_busy(reconfig_mgmt_waitrequest), + .reconfig_read_data(reconfig_mgmt_readdata), + //outputs + .reconfig_write_data(mif2reconfig_writedata), + .reconfig_addr(mif2reconfig_addr), + .reconfig_write(mif2reconfig_write), + .reconfig_read(mif2reconfig_read), + + //MIF Ctrl Interface + //inputs + .mif_base_addr(mif_base_addr), + .mif_start(reconfig2mif_start_out), + //outputs + .mif_busy(mif2reconfig_busy) + ); + + // ------ END MIF-RELATED MANAGEMENT ------ + + + altera_pll_reconfig_core + #( + .reconf_width(reconf_width), + .device_family(device_family), + .RECONFIG_ADDR_WIDTH(RECONFIG_ADDR_WIDTH), + .RECONFIG_DATA_WIDTH(RECONFIG_DATA_WIDTH), + .ROM_ADDR_WIDTH(ROM_ADDR_WIDTH), + .ROM_DATA_WIDTH(ROM_DATA_WIDTH), + .ROM_NUM_WORDS(ROM_NUM_WORDS) + ) altera_pll_reconfig_core_inst0 ( + //inputs + .mgmt_clk(mgmt_clk), + .mgmt_reset(mgmt_reset), + + //PLL interface conduits + .reconfig_to_pll(reconfig_to_pll), + .reconfig_from_pll(reconfig_from_pll), + + //User data outputs + .mgmt_readdata(reconfig_mgmt_readdata), + .mgmt_waitrequest(reconfig_mgmt_waitrequest), + + //User data inputs + .mgmt_address(reconfig_mgmt_addr), + .mgmt_read(reconfig_mgmt_read), + .mgmt_write(reconfig_mgmt_write), + .mgmt_writedata(reconfig_mgmt_writedata), + + // other + .mif_start_out(reconfig2mif_start_out), + .mif_base_addr(mif_base_addr) + ); + + end // End generate reconfig with MIF + else + begin:reconfig_core // Generate Reconfig core only + + wire reconfig2mif_start_out; + wire [ROM_ADDR_WIDTH-1:0] mif_base_addr; + + altera_pll_reconfig_core + #( + .reconf_width(reconf_width), + .device_family(device_family), + .RECONFIG_ADDR_WIDTH(RECONFIG_ADDR_WIDTH), + .RECONFIG_DATA_WIDTH(RECONFIG_DATA_WIDTH), + .ROM_ADDR_WIDTH(ROM_ADDR_WIDTH), + .ROM_DATA_WIDTH(ROM_DATA_WIDTH), + .ROM_NUM_WORDS(ROM_NUM_WORDS) + ) altera_pll_reconfig_core_inst0 ( + //inputs + .mgmt_clk(mgmt_clk), + .mgmt_reset(mgmt_reset), + + //PLL interface conduits + .reconfig_to_pll(reconfig_to_pll), + .reconfig_from_pll(reconfig_from_pll), + + //User data outputs + .mgmt_readdata(mgmt_readdata), + .mgmt_waitrequest(mgmt_waitrequest), + + //User data inputs + .mgmt_address(mgmt_address), + .mgmt_read(mgmt_read), + .mgmt_write(mgmt_byteenable_write), + .mgmt_writedata(mgmt_writedata), + + // other + .mif_start_out(reconfig2mif_start_out), + .mif_base_addr(mif_base_addr) + ); + + + end // End generate reconfig core only +end // End 28nm Reconfig +endgenerate + +endmodule + diff --git a/sys/scandoubler.v b/sys/scandoubler.v new file mode 100644 index 0000000..50f1b84 --- /dev/null +++ b/sys/scandoubler.v @@ -0,0 +1,190 @@ +// +// scandoubler.v +// +// Copyright (c) 2015 Till Harbaum +// Copyright (c) 2017 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 +// 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 . + +// TODO: Delay vsync one line + +module scandoubler #(parameter LENGTH, parameter HALF_DEPTH) +( + // system interface + input clk_sys, + input ce_pix, + output ce_pix_out, + + input hq2x, + + // shifter video interface + input hs_in, + input vs_in, + input hb_in, + input vb_in, + + input [DWIDTH:0] r_in, + input [DWIDTH:0] g_in, + input [DWIDTH:0] b_in, + input mono, + + // output interface + output reg hs_out, + output vs_out, + output hb_out, + output vb_out, + output [DWIDTH:0] r_out, + output [DWIDTH:0] g_out, + output [DWIDTH:0] b_out +); + + +localparam DWIDTH = HALF_DEPTH ? 3 : 7; + +assign vs_out = vso[3]; +assign ce_pix_out = hq2x ? ce_x4 : ce_x2; + +//Compensate picture shift after HQ2x +assign vb_out = vbo[2]; +assign hb_out = hq2x ? hbo[4] : hbo[2]; + +reg [7:0] pix_len = 0; +wire [7:0] pl = pix_len + 1'b1; + +reg ce_x1, ce_x4, ce_x2; +reg req_line_reset; +always @(negedge clk_sys) begin + reg old_ce; + reg [2:0] ce_cnt; + + reg [7:0] pixsz2, pixsz4 = 0; + + old_ce <= ce_pix; + if(~&pix_len) pix_len <= pix_len + 1'd1; + + 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; + end + + if(pl == pixsz2) begin + ce_x2 <= 1; + end + + if(~old_ce & ce_pix) begin + pixsz2 <= {1'b0, pl[7:1]}; + pixsz4 <= {2'b00, pl[7:2]}; + ce_x1 <= 1; + ce_x2 <= 1; + ce_x4 <= 1; + pix_len <= 0; + req_line_reset <= 0; + + if(hb_in) req_line_reset <= 1; + end +end + +Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x +( + .clk(clk_sys), + .ce_x4(ce_x4), + .inputpixel({b_d,g_d,r_d}), + .mono(mono), + .disable_hq2x(~hq2x), + .reset_frame(vs_in), + .reset_line(req_line_reset), + .read_y(sd_line), + .hblank(hbo[0]), + .outpixel({b_out,g_out,r_out}) +); + +reg [1:0] sd_line; +reg [2:0] vbo; +reg [4:0] hbo; + +reg [DWIDTH:0] r_d; +reg [DWIDTH:0] g_d; +reg [DWIDTH:0] b_d; + +reg [3:0] vso; + +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 hs, hs2, vs, hb; + + if(ce_x1) begin + hs <= hs_in; + hb <= 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 + vso <= (vso<<1) | vs_in; + 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[4:1] <= hbo[3:0]; + + // output counter synchronous to input and at twice the rate + sd_hcnt <= sd_hcnt + 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_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; + end +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/sigma_delta_dac.v b/sys/sigma_delta_dac.v new file mode 100644 index 0000000..d0d6be0 --- /dev/null +++ b/sys/sigma_delta_dac.v @@ -0,0 +1,33 @@ +// +// PWM DAC +// +// MSBI is the highest bit number. NOT amount of bits! +// +module sigma_delta_dac #(parameter MSBI=7, parameter INV=1'b1) +( + output reg DACout, //Average Output feeding analog lowpass + input [MSBI:0] DACin, //DAC input (excess 2**MSBI) + input CLK, + input RESET +); + +reg [MSBI+2:0] DeltaAdder; //Output of Delta Adder +reg [MSBI+2:0] SigmaAdder; //Output of Sigma Adder +reg [MSBI+2:0] SigmaLatch; //Latches output of Sigma Adder +reg [MSBI+2:0] DeltaB; //B input of Delta Adder + +always @(*) DeltaB = {SigmaLatch[MSBI+2], SigmaLatch[MSBI+2]} << (MSBI+1); +always @(*) DeltaAdder = DACin + DeltaB; +always @(*) SigmaAdder = DeltaAdder + SigmaLatch; + +always @(posedge CLK or posedge RESET) begin + if(RESET) begin + SigmaLatch <= 1'b1 << (MSBI+1); + DACout <= INV; + end else begin + SigmaLatch <= SigmaAdder; + DACout <= SigmaLatch[MSBI+2] ^ INV; + end +end + +endmodule diff --git a/sys/spdif.v b/sys/spdif.v new file mode 100644 index 0000000..671dcb2 --- /dev/null +++ b/sys/spdif.v @@ -0,0 +1,426 @@ +//----------------------------------------------------------------- +// SPDIF Transmitter +// V0.1 +// Ultra-Embedded.com +// Copyright 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for +// use in closed source commercial applications please contact me +// for details. +//----------------------------------------------------------------- +// +// This file is open source HDL; 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 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 file; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +//----------------------------------------------------------------- +// altera message_off 10762 +// 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, + + // SPDIF bit output enable + // Single cycle pulse synchronous to clk_i which drives + // the output bit rate. + // For 44.1KHz, 44100×32×2×2 = 5,644,800Hz + // For 48KHz, 48000×32×2×2 = 6,144,000Hz + input bit_out_en_i, + + // Output + output spdif_o, + + // Audio interface (16-bit x 2 = RL) + input [31:0] sample_i, + output reg sample_req_o +); + +//----------------------------------------------------------------- +// Registers +//----------------------------------------------------------------- +reg [15:0] audio_sample_q; +reg [8:0] subframe_count_q; + +reg load_subframe_q; +reg [7:0] preamble_q; +wire [31:0] subframe_w; + +reg [5:0] bit_count_q; +reg bit_toggle_q; + +reg spdif_out_q; + +reg [5:0] parity_count_q; + +//----------------------------------------------------------------- +// Subframe Counter +//----------------------------------------------------------------- +always @ (posedge rst_i or posedge clk_i ) +begin + if (rst_i == 1'b1) + subframe_count_q <= 9'd0; + else if (load_subframe_q) + begin + // 192 frames (384 subframes) in an audio block + if (subframe_count_q == 9'd383) + subframe_count_q <= 9'd0; + else + subframe_count_q <= subframe_count_q + 9'd1; + end +end + +//----------------------------------------------------------------- +// Sample capture +//----------------------------------------------------------------- +reg [15:0] sample_buf_q; + +always @ (posedge rst_i or posedge clk_i ) +begin + if (rst_i == 1'b1) + begin + audio_sample_q <= 16'h0000; + sample_buf_q <= 16'h0000; + sample_req_o <= 1'b0; + end + else if (load_subframe_q) + begin + // Start of frame (first subframe)? + if (subframe_count_q[0] == 1'b0) + begin + // Use left sample + audio_sample_q <= sample_i[15:0]; + + // Store right sample + sample_buf_q <= sample_i[31:16]; + + // Request next sample + sample_req_o <= 1'b1; + end + else + begin + // Use right sample + audio_sample_q <= sample_buf_q; + + sample_req_o <= 1'b0; + end + end + else + sample_req_o <= 1'b0; +end + +// Timeslots 3 - 0 = Preamble +assign subframe_w[3:0] = 4'b0000; + +// Timeslots 7 - 4 = 24-bit audio LSB +assign subframe_w[7:4] = 4'b0000; + +// Timeslots 11 - 8 = 20-bit audio LSB +assign subframe_w[11:8] = 4'b0000; + +// Timeslots 27 - 12 = 16-bit audio +assign subframe_w[27:12] = audio_sample_q; + +// Timeslots 28 = Validity +assign subframe_w[28] = 1'b0; // Valid + +// Timeslots 29 = User bit +assign subframe_w[29] = 1'b0; + +// Timeslots 30 = Channel status bit +assign subframe_w[30] = 1'b0; + +// Timeslots 31 = Even Parity bit (31:4) +assign subframe_w[31] = 1'b0; + +//----------------------------------------------------------------- +// Preamble +//----------------------------------------------------------------- +localparam PREAMBLE_Z = 8'b00010111; +localparam PREAMBLE_Y = 8'b00100111; +localparam PREAMBLE_X = 8'b01000111; + +reg [7:0] preamble_r; + +always @ * +begin + // Start of audio block? + // Z(B) - Left channel + if (subframe_count_q == 9'd0) + preamble_r = PREAMBLE_Z; // Z(B) + // Right Channel? + else if (subframe_count_q[0] == 1'b1) + preamble_r = PREAMBLE_Y; // Y(W) + // Left Channel (but not start of block)? + else + preamble_r = PREAMBLE_X; // X(M) +end + +always @ (posedge rst_i or posedge clk_i ) +if (rst_i == 1'b1) + preamble_q <= 8'h00; +else if (load_subframe_q) + preamble_q <= preamble_r; + +//----------------------------------------------------------------- +// Parity Counter +//----------------------------------------------------------------- +always @ (posedge rst_i or posedge clk_i ) +begin + if (rst_i == 1'b1) + begin + parity_count_q <= 6'd0; + end + // Time to output a bit? + else if (bit_out_en_i) + begin + // Preamble bits? + if (bit_count_q < 6'd8) + begin + parity_count_q <= 6'd0; + end + // Normal timeslots + else if (bit_count_q < 6'd62) + begin + // On first pass through this timeslot, count number of high bits + if (bit_count_q[0] == 0 && subframe_w[bit_count_q / 2] == 1'b1) + parity_count_q <= parity_count_q + 6'd1; + end + end +end + +//----------------------------------------------------------------- +// Bit Counter +//----------------------------------------------------------------- +always @ (posedge rst_i or posedge clk_i) +begin + if (rst_i == 1'b1) + begin + bit_count_q <= 6'b0; + load_subframe_q <= 1'b1; + end + // Time to output a bit? + else if (bit_out_en_i) + begin + // 32 timeslots (x2 for double frequency) + if (bit_count_q == 6'd63) + begin + bit_count_q <= 6'd0; + load_subframe_q <= 1'b1; + end + else + begin + bit_count_q <= bit_count_q + 6'd1; + load_subframe_q <= 1'b0; + end + end + else + load_subframe_q <= 1'b0; +end + +//----------------------------------------------------------------- +// Bit half toggle +//----------------------------------------------------------------- +always @ (posedge rst_i or posedge clk_i) +if (rst_i == 1'b1) + bit_toggle_q <= 1'b0; +// Time to output a bit? +else if (bit_out_en_i) + bit_toggle_q <= ~bit_toggle_q; + +//----------------------------------------------------------------- +// Output bit (BMC encoded) +//----------------------------------------------------------------- +reg bit_r; + +always @ * +begin + bit_r = spdif_out_q; + + // Time to output a bit? + if (bit_out_en_i) + begin + // Preamble bits? + if (bit_count_q < 6'd8) + begin + bit_r = preamble_q[bit_count_q[2:0]]; + end + // Normal timeslots + else if (bit_count_q < 6'd62) + begin + if (subframe_w[bit_count_q / 2] == 1'b0) + begin + if (bit_toggle_q == 1'b0) + bit_r = ~spdif_out_q; + else + bit_r = spdif_out_q; + end + else + bit_r = ~spdif_out_q; + end + // Parity timeslot + else + begin + // Even number of high bits, make odd + if (parity_count_q[0] == 1'b0) + begin + if (bit_toggle_q == 1'b0) + bit_r = ~spdif_out_q; + else + bit_r = spdif_out_q; + end + else + bit_r = ~spdif_out_q; + end + end +end + +always @ (posedge rst_i or posedge clk_i ) +if (rst_i == 1'b1) + spdif_out_q <= 1'b0; +else + spdif_out_q <= bit_r; + +assign spdif_o = spdif_out_q; + +endmodule diff --git a/sys/sync_vg.v b/sys/sync_vg.v new file mode 100644 index 0000000..54fc614 --- /dev/null +++ b/sys/sync_vg.v @@ -0,0 +1,78 @@ +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 new file mode 100644 index 0000000..86b463a --- /dev/null +++ b/sys/sys.qip @@ -0,0 +1,24 @@ +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/sd_card.v +set_global_assignment -name VERILOG_FILE sys/hps_io.v diff --git a/sys/sys_top.sdc b/sys/sys_top.sdc new file mode 100644 index 0000000..4380a19 --- /dev/null +++ b/sys/sys_top.sdc @@ -0,0 +1,55 @@ +# Specify root clocks +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] + +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}] + +create_generated_clock -source [get_pins -compatibility_mode {*|pll|pll_inst|altera_pll_i|general[2].gpll~PLL_OUTPUT_COUNTER|divclk}] \ + -name ZCLK -divide_by 2 -duty_cycle 50 [get_nets {emu:emu|tsconf:tsconf|zclock:TS02|zclk_o}] + +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 ZCLK}] \ + -group [get_clocks { pll_hdmi|pll_hdmi_inst|altera_pll_i|cyclonev_pll|counter[0].output_counter|divclk VID_CLK}] \ + -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}] + +# Put constraints on input ports +set_false_path -from [get_ports {KEY*}] -to * +set_false_path -from [get_ports {BTN_*}] -to * + +# Put constraints on output ports +set_false_path -from * -to [get_ports {LED_*}] +set_false_path -from * -to [get_ports {VGA_*}] +set_false_path -from * -to [get_ports {AUDIO_SPDIF}] +set_false_path -from * -to [get_ports {AUDIO_L}] +set_false_path -from * -to [get_ports {AUDIO_R}] diff --git a/sys/sys_top.v b/sys/sys_top.v new file mode 100644 index 0000000..2af99b1 --- /dev/null +++ b/sys/sys_top.v @@ -0,0 +1,953 @@ +//============================================================================ +// +// 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; + +`ifndef HDMI_LITE + +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_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) +); + +`endif + +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) + +`ifdef HDMI_LITE + , + // 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 + +); + +`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 ? {24{HDMI_TX_DE}} & 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 diff --git a/sys/sysmem.sv b/sys/sysmem.sv new file mode 100644 index 0000000..0f60f65 --- /dev/null +++ b/sys/sysmem.sv @@ -0,0 +1,531 @@ +`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 + + 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_cold_req, // reset.cold_req + output reset_reset, // .reset + input reset_reset_req, // .reset_req + input reset_warm_req, // .warm_req + + 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 + + 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 diff --git a/sys/vga_out.sv b/sys/vga_out.sv new file mode 100644 index 0000000..e316000 --- /dev/null +++ b/sys/vga_out.sv @@ -0,0 +1,65 @@ + +module vga_out +( + input ypbpr_full, + input ypbpr_en, + + input [23:0] din, + output [23:0] dout +); + +wire [5:0] yuv_full[225] = '{ + 6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1, + 6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4, + 6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6, + 6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8, + 6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11, + 6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13, + 6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15, + 6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17, + 6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20, + 6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22, + 6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24, + 6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27, + 6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29, + 6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31, + 6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33, + 6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36, + 6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38, + 6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40, + 6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42, + 6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45, + 6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47, + 6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49, + 6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52, + 6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54, + 6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56, + 6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58, + 6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61, + 6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63, + 6'd63 +}; + +wire [5:0] red = din[23:18]; +wire [5:0] green = din[15:10]; +wire [5:0] blue = din[7:2]; + +// http://marsee101.blog19.fc2.com/blog-entry-2311.html +// Y = 16 + 0.257*R + 0.504*G + 0.098*B (Y = 0.299*R + 0.587*G + 0.114*B) +// Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B) +// Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B) + +wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0}); +wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0}); +wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0}); + +wire [7:0] y = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8]; +wire [7:0] pb = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8]; +wire [7:0] pr = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8]; + +assign dout[23:16] = ypbpr_en ? {(ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]), 2'b00} : din[23:16]; +assign dout[15:8] = ypbpr_en ? {(ypbpr_full ? yuv_full[y -8'd16] : y[7:2]), 2'b00} : din[15:8]; +assign dout[7:0] = ypbpr_en ? {(ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]), 2'b00} : din[7:0]; + + +endmodule diff --git a/sys/video_mixer.sv b/sys/video_mixer.sv new file mode 100644 index 0000000..8f48f11 --- /dev/null +++ b/sys/video_mixer.sv @@ -0,0 +1,167 @@ +// +// +// Copyright (c) 2017 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +`timescale 1ns / 1ps + +// +// LINE_LENGTH: Length of display line in pixels +// Usually it's length from HSync to HSync. +// May be less if line_start is used. +// +// HALF_DEPTH: If =1 then color dept is 4 bits per component +// For half depth 8 bits monochrome is available with +// mono signal enabled and color = {G, R} + +module video_mixer +#( + parameter LINE_LENGTH = 768, + parameter HALF_DEPTH = 0 +) +( + // master clock + // it should be multiple by (ce_pix*4). + input clk_sys, + + // Pixel clock or clock_enable (both are accepted). + input ce_pix, + output ce_pix_out, + + input scandoubler, + + // scanlines (00-none 01-25% 10-50% 11-75%) + input [1:0] scanlines, + + // High quality 2x scaling + input hq2x, + + // color + input [DWIDTH:0] R, + input [DWIDTH:0] G, + input [DWIDTH:0] B, + + // Monochrome mode (for HALF_DEPTH only) + input mono, + + // Positive pulses. + 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 reg VGA_DE +); + +localparam DWIDTH = HALF_DEPTH ? 3 : 7; + +wire [DWIDTH:0] R_sd; +wire [DWIDTH:0] G_sd; +wire [DWIDTH:0] B_sd; +wire hs_sd, vs_sd, hb_sd, vb_sd, ce_pix_sd; + +scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) sd +( + .*, + .hs_in(HSync), + .vs_in(VSync), + .hb_in(HBlank), + .vb_in(VBlank), + .r_in(R), + .g_in(G), + .b_in(B), + + .ce_pix_out(ce_pix_sd), + .hs_out(hs_sd), + .vs_out(vs_sd), + .hb_out(hb_sd), + .vb_out(vb_sd), + .r_out(R_sd), + .g_out(G_sd), + .b_out(B_sd) +); + +wire [DWIDTH:0] rt = (scandoubler ? R_sd : R); +wire [DWIDTH:0] gt = (scandoubler ? G_sd : G); +wire [DWIDTH:0] bt = (scandoubler ? B_sd : B); + +generate + if(HALF_DEPTH) begin + wire [7:0] r = mono ? {gt,rt} : {rt,rt}; + wire [7:0] g = mono ? {gt,rt} : {gt,gt}; + wire [7:0] b = mono ? {gt,rt} : {bt,bt}; + end else begin + wire [7:0] r = rt; + wire [7:0] g = gt; + wire [7:0] b = bt; + end +endgenerate + +wire hs = (scandoubler ? hs_sd : HSync); +wire vs = (scandoubler ? vs_sd : VSync); + +assign ce_pix_out = scandoubler ? ce_pix_sd : ce_pix; + + +reg scanline = 0; +always @(posedge clk_sys) begin + reg old_hs, old_vs; + + old_hs <= hs; + old_vs <= vs; + + if(old_hs && ~hs) scanline <= ~scanline; + if(old_vs && ~vs) scanline <= 0; +end + +wire hde = scandoubler ? ~hb_sd : ~HBlank; +wire vde = scandoubler ? ~vb_sd : ~VBlank; + +always @(posedge clk_sys) begin + reg old_hde; + + case(scanlines & {scanline, scanline}) + 1: begin // reduce 25% = 1/2 + 1/4 + VGA_R <= {1'b0, r[7:1]} + {2'b00, r[7:2]}; + VGA_G <= {1'b0, g[7:1]} + {2'b00, g[7:2]}; + VGA_B <= {1'b0, b[7:1]} + {2'b00, b[7:2]}; + end + + 2: begin // reduce 50% = 1/2 + VGA_R <= {1'b0, r[7:1]}; + VGA_G <= {1'b0, g[7:1]}; + VGA_B <= {1'b0, b[7:1]}; + end + + 3: begin // reduce 75% = 1/4 + VGA_R <= {2'b00, r[7:2]}; + VGA_G <= {2'b00, g[7:2]}; + VGA_B <= {2'b00, b[7:2]}; + end + + default: begin + VGA_R <= r; + VGA_G <= g; + VGA_B <= b; + end + endcase + + VGA_VS <= vs; + VGA_HS <= hs; + + old_hde <= hde; + if(~old_hde && hde) VGA_DE <= vde; + if(old_hde && ~hde) VGA_DE <= 0; +end + +endmodule diff --git a/sys/vip.qsys b/sys/vip.qsys new file mode 100644 index 0000000..47306be --- /dev/null +++ b/sys/vip.qsys @@ -0,0 +1,1177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 new file mode 100644 index 0000000..89bf241 --- /dev/null +++ b/sys/vip_config.sv @@ -0,0 +1,159 @@ + +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