From 6ff27c18b45b13195079d386d690fa3963f4500b Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Wed, 26 Jan 2022 01:24:21 +0100 Subject: [PATCH] Qbert: new arcade --- Arcade_MiST/Gottlieb Qbert/Qbert.qpf | 31 + Arcade_MiST/Gottlieb Qbert/Qbert.qsf | 251 ++++++ Arcade_MiST/Gottlieb Qbert/Qbert.sdc | 134 +++ Arcade_MiST/Gottlieb Qbert/Readme.md | 23 + .../Gottlieb Qbert/meta/Curve Ball.mra | 42 + Arcade_MiST/Gottlieb Qbert/meta/Insector.mra | 45 + Arcade_MiST/Gottlieb Qbert/meta/Krull.mra | 48 ++ .../Gottlieb Qbert/meta/Mad Planets.mra | 47 + .../meta/Q'bert (US, Set 1).mra | 78 ++ .../Gottlieb Qbert/meta/QBert Qubes.mra | 42 + Arcade_MiST/Gottlieb Qbert/meta/Tylz.mra | 41 + Arcade_MiST/Gottlieb Qbert/rtl/Qbert_MiST.sv | 534 ++++++++++++ Arcade_MiST/Gottlieb Qbert/rtl/build_id.tcl | 35 + Arcade_MiST/Gottlieb Qbert/rtl/dpram.v | 26 + Arcade_MiST/Gottlieb Qbert/rtl/m6532.sv | 168 ++++ Arcade_MiST/Gottlieb Qbert/rtl/ma216_board.v | 143 +++ .../Gottlieb Qbert/rtl/mylstar_board.v | 815 ++++++++++++++++++ Arcade_MiST/Gottlieb Qbert/rtl/pll.qip | 4 + Arcade_MiST/Gottlieb Qbert/rtl/pll.v | 348 ++++++++ Arcade_MiST/Gottlieb Qbert/rtl/ram.v | 29 + Arcade_MiST/Gottlieb Qbert/rtl/sc01.v | 177 ++++ Arcade_MiST/Gottlieb Qbert/rtl/sdram.sv | 349 ++++++++ 22 files changed, 3410 insertions(+) create mode 100644 Arcade_MiST/Gottlieb Qbert/Qbert.qpf create mode 100644 Arcade_MiST/Gottlieb Qbert/Qbert.qsf create mode 100644 Arcade_MiST/Gottlieb Qbert/Qbert.sdc create mode 100644 Arcade_MiST/Gottlieb Qbert/Readme.md create mode 100644 Arcade_MiST/Gottlieb Qbert/meta/Curve Ball.mra create mode 100644 Arcade_MiST/Gottlieb Qbert/meta/Insector.mra create mode 100644 Arcade_MiST/Gottlieb Qbert/meta/Krull.mra create mode 100644 Arcade_MiST/Gottlieb Qbert/meta/Mad Planets.mra create mode 100644 Arcade_MiST/Gottlieb Qbert/meta/Q'bert (US, Set 1).mra create mode 100644 Arcade_MiST/Gottlieb Qbert/meta/QBert Qubes.mra create mode 100644 Arcade_MiST/Gottlieb Qbert/meta/Tylz.mra create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/Qbert_MiST.sv create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/build_id.tcl create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/dpram.v create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/m6532.sv create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/ma216_board.v create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/mylstar_board.v create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/pll.qip create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/pll.v create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/ram.v create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/sc01.v create mode 100644 Arcade_MiST/Gottlieb Qbert/rtl/sdram.sv diff --git a/Arcade_MiST/Gottlieb Qbert/Qbert.qpf b/Arcade_MiST/Gottlieb Qbert/Qbert.qpf new file mode 100644 index 00000000..7234aa0e --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/Qbert.qpf @@ -0,0 +1,31 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2013 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 64-Bit +# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition +# Date created = 00:21:03 December 03, 2019 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "13.1" +DATE = "00:21:03 December 03, 2019" + +# Revisions + +PROJECT_REVISION = "Qbert" + diff --git a/Arcade_MiST/Gottlieb Qbert/Qbert.qsf b/Arcade_MiST/Gottlieb Qbert/Qbert.qsf new file mode 100644 index 00000000..8a7b59db --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/Qbert.qsf @@ -0,0 +1,251 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2014 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 64-Bit +# Version 13.1.4 Build 182 03/12/2014 SJ Full Version +# Date created = 19:54:12 November 22, 2020 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# Qbert_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + + +# Project-Wide Assignments +# ======================== +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" + +# Pin & Location Assignments +# ========================== +set_location_assignment PIN_7 -to LED +set_location_assignment PIN_54 -to CLOCK_27 +set_location_assignment PIN_144 -to VGA_R[5] +set_location_assignment PIN_143 -to VGA_R[4] +set_location_assignment PIN_142 -to VGA_R[3] +set_location_assignment PIN_141 -to VGA_R[2] +set_location_assignment PIN_137 -to VGA_R[1] +set_location_assignment PIN_135 -to VGA_R[0] +set_location_assignment PIN_133 -to VGA_B[5] +set_location_assignment PIN_132 -to VGA_B[4] +set_location_assignment PIN_125 -to VGA_B[3] +set_location_assignment PIN_121 -to VGA_B[2] +set_location_assignment PIN_120 -to VGA_B[1] +set_location_assignment PIN_115 -to VGA_B[0] +set_location_assignment PIN_114 -to VGA_G[5] +set_location_assignment PIN_113 -to VGA_G[4] +set_location_assignment PIN_112 -to VGA_G[3] +set_location_assignment PIN_111 -to VGA_G[2] +set_location_assignment PIN_110 -to VGA_G[1] +set_location_assignment PIN_106 -to VGA_G[0] +set_location_assignment PIN_136 -to VGA_VS +set_location_assignment PIN_119 -to VGA_HS +set_location_assignment PIN_65 -to AUDIO_L +set_location_assignment PIN_80 -to AUDIO_R +set_location_assignment PIN_105 -to SPI_DO +set_location_assignment PIN_88 -to SPI_DI +set_location_assignment PIN_126 -to SPI_SCK +set_location_assignment PIN_127 -to SPI_SS2 +set_location_assignment PIN_91 -to SPI_SS3 +set_location_assignment PIN_13 -to CONF_DATA0 +set_location_assignment PIN_49 -to SDRAM_A[0] +set_location_assignment PIN_44 -to SDRAM_A[1] +set_location_assignment PIN_42 -to SDRAM_A[2] +set_location_assignment PIN_39 -to SDRAM_A[3] +set_location_assignment PIN_4 -to SDRAM_A[4] +set_location_assignment PIN_6 -to SDRAM_A[5] +set_location_assignment PIN_8 -to SDRAM_A[6] +set_location_assignment PIN_10 -to SDRAM_A[7] +set_location_assignment PIN_11 -to SDRAM_A[8] +set_location_assignment PIN_28 -to SDRAM_A[9] +set_location_assignment PIN_50 -to SDRAM_A[10] +set_location_assignment PIN_30 -to SDRAM_A[11] +set_location_assignment PIN_32 -to SDRAM_A[12] +set_location_assignment PIN_83 -to SDRAM_DQ[0] +set_location_assignment PIN_79 -to SDRAM_DQ[1] +set_location_assignment PIN_77 -to SDRAM_DQ[2] +set_location_assignment PIN_76 -to SDRAM_DQ[3] +set_location_assignment PIN_72 -to SDRAM_DQ[4] +set_location_assignment PIN_71 -to SDRAM_DQ[5] +set_location_assignment PIN_69 -to SDRAM_DQ[6] +set_location_assignment PIN_68 -to SDRAM_DQ[7] +set_location_assignment PIN_86 -to SDRAM_DQ[8] +set_location_assignment PIN_87 -to SDRAM_DQ[9] +set_location_assignment PIN_98 -to SDRAM_DQ[10] +set_location_assignment PIN_99 -to SDRAM_DQ[11] +set_location_assignment PIN_100 -to SDRAM_DQ[12] +set_location_assignment PIN_101 -to SDRAM_DQ[13] +set_location_assignment PIN_103 -to SDRAM_DQ[14] +set_location_assignment PIN_104 -to SDRAM_DQ[15] +set_location_assignment PIN_58 -to SDRAM_BA[0] +set_location_assignment PIN_51 -to SDRAM_BA[1] +set_location_assignment PIN_85 -to SDRAM_DQMH +set_location_assignment PIN_67 -to SDRAM_DQML +set_location_assignment PIN_60 -to SDRAM_nRAS +set_location_assignment PIN_64 -to SDRAM_nCAS +set_location_assignment PIN_66 -to SDRAM_nWE +set_location_assignment PIN_59 -to SDRAM_nCS +set_location_assignment PIN_33 -to SDRAM_CKE +set_location_assignment PIN_43 -to SDRAM_CLK +set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component" + +# Classic Timing Assignments +# ========================== +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 + +# Analysis & Synthesis Assignments +# ================================ +set_global_assignment -name FAMILY "Cyclone III" +set_global_assignment -name TOP_LEVEL_ENTITY Qbert_MiST +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 +set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP + +# Fitter Assignments +# ================== +set_global_assignment -name DEVICE EP3C25E144C8 +set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF +set_global_assignment -name ENABLE_NCE_PIN OFF +set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO" + +# Assembler Assignments +# ===================== +set_global_assignment -name GENERATE_RBF_FILE ON +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF + +# SignalTap II Assignments +# ======================== +set_global_assignment -name ENABLE_SIGNALTAP OFF +set_global_assignment -name USE_SIGNALTAP_FILE output_files/snd.stp + +# Power Estimation Assignments +# ============================ +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)" + +# Advanced I/O Timing Assignments +# =============================== +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall + +# ------------------------------ +# start ENTITY(Qbert_MiST) + + # Pin & Location Assignments + # ========================== + + # Fitter Assignments + # ================== + + # start DESIGN_PARTITION(Top) + # --------------------------- + + # Incremental Compilation Assignments + # =================================== + + # end DESIGN_PARTITION(Top) + # ------------------------- + +# end ENTITY(Qbert_MiST) +# ---------------------------- +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON +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_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO +set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING OFF +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE BALANCED +set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON +set_global_assignment -name FITTER_EFFORT "STANDARD FIT" +set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF +set_global_assignment -name VERILOG_MACRO "EXT_ROM=" +set_global_assignment -name FORCE_SYNCH_CLEAR ON +set_global_assignment -name SYSTEMVERILOG_FILE rtl/Qbert_MiST.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv +set_global_assignment -name QIP_FILE rtl/pll.qip +set_global_assignment -name SYSTEMVERILOG_FILE rtl/m6532.sv +set_global_assignment -name VERILOG_FILE rtl/sc01.v +set_global_assignment -name VERILOG_FILE rtl/ram.v +set_global_assignment -name VERILOG_FILE rtl/mylstar_board.v +set_global_assignment -name VERILOG_FILE rtl/ma216_board.v +set_global_assignment -name VERILOG_FILE rtl/dpram.v +set_global_assignment -name QIP_FILE ../../common/CPU/8088/8088.qip +set_global_assignment -name QIP_FILE ../../common/CPU/T65/T65.qip +set_global_assignment -name QIP_FILE ../../common/mist/mist.qip +set_global_assignment -name SIGNALTAP_FILE output_files/snd.stp +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Gottlieb Qbert/Qbert.sdc b/Arcade_MiST/Gottlieb Qbert/Qbert.sdc new file mode 100644 index 00000000..4a373c09 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/Qbert.sdc @@ -0,0 +1,134 @@ +## Generated SDC file "vectrex_MiST.out.sdc" + +## Copyright (C) 1991-2013 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. + + +## VENDOR "Altera" +## PROGRAM "Quartus II" +## VERSION "Version 13.1.0 Build 162 10/23/2013 SJ Web Edition" + +## DATE "Sun Jun 24 12:53:00 2018" + +## +## DEVICE "EP3C25E144C8" +## + +# Clock constraints + +# Automatically constrain PLL and other generated clocks +derive_pll_clocks -create_base_clocks + +# Automatically calculate clock uncertainty to jitter and other effects. +derive_clock_uncertainty + +# tsu/th constraints + +# tco constraints + +# tpd constraints + +#************************************************************** +# Time Information +#************************************************************** + +set_time_format -unit ns -decimal_places 3 + + + +#************************************************************** +# Create Clock +#************************************************************** + +create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}] + +set sdram_clk "pll|altpll_component|auto_generated|pll1|clk[0]" +set sys_clk "pll|altpll_component|auto_generated|pll1|clk[1]" +#************************************************************** +# Create Generated Clock +#************************************************************** + + +#************************************************************** +# Set Clock Latency +#************************************************************** + + + +#************************************************************** +# Set Clock Uncertainty +#************************************************************** + +#************************************************************** +# Set Input Delay +#************************************************************** + +set_input_delay -add_delay -clock_fall -clock [get_clocks {CLOCK_27}] 1.000 [get_ports {CLOCK_27}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {CONF_DATA0}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DI}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SCK}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS2}] +set_input_delay -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_SS3}] + +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 6.6 [get_ports SDRAM_DQ[*]] +set_input_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min 3.5 [get_ports SDRAM_DQ[*]] + +#************************************************************** +# Set Output Delay +#************************************************************** + +set_output_delay -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}] +set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_L}] +set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_R}] +set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {LED}] +set_output_delay -clock [get_clocks $sys_clk] 1.000 [get_ports {VGA_*}] + +set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] +set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}] + +#************************************************************** +# Set Clock Groups +#************************************************************** + +set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {pll|altpll_component|auto_generated|pll1|clk[*]}] + +#************************************************************** +# Set False Path +#************************************************************** + + + +#************************************************************** +# Set Multicycle Path +#************************************************************** + +set_multicycle_path -to {VGA_*[*]} -setup 2 +set_multicycle_path -to {VGA_*[*]} -hold 1 + +#************************************************************** +# Set Maximum Delay +#************************************************************** + + + +#************************************************************** +# Set Minimum Delay +#************************************************************** + + + +#************************************************************** +# Set Input Transition +#************************************************************** + diff --git a/Arcade_MiST/Gottlieb Qbert/Readme.md b/Arcade_MiST/Gottlieb Qbert/Readme.md new file mode 100644 index 00000000..ae683a47 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/Readme.md @@ -0,0 +1,23 @@ +## Q*Bert port to MiST + +Original by [Pierco](https://github.com/MiSTer-devel/Arcade-QBert_MiSTer). + +Fully rewritten using synchronous logic by Gyorgy Szombathelyi. + +M6532 (RIOT) from k7800 (c) by Jamie Blanks + +i8088 core by Ted Fried, MicroCore Labs + +NVRAM for saving high scores and games with background RAM instead of ROM are supported (e.g. Krull). + +## Usage + +- Create ROM and ARC files from the MRA files using the MRA utility. + Example: mra -A -z /path/to/mame/roms "Q'bert (US, Set 1).mra" +- Copy the ROM files to the root of the SD Card +- Copy the RBF and ARC files to the same folder on the SD Card +- MRA utility: https://github.com/sebdel/mra-tools-c/ + +## Issues + +- Votrax chip is cruelly missing, QBert needs his @!#?@! voice!!! diff --git a/Arcade_MiST/Gottlieb Qbert/meta/Curve Ball.mra b/Arcade_MiST/Gottlieb Qbert/meta/Curve Ball.mra new file mode 100644 index 00000000..74d1cfc2 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/meta/Curve Ball.mra @@ -0,0 +1,42 @@ + + + Curve Ball + 0198 + curvebal + 20201231150731 + 1982 + Gottlieb + Platform + qbert + + + + + + + + 4 + + + + + + + 00 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Gottlieb Qbert/meta/Insector.mra b/Arcade_MiST/Gottlieb Qbert/meta/Insector.mra new file mode 100644 index 00000000..cbf8ff85 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/meta/Insector.mra @@ -0,0 +1,45 @@ + + + Insector + 0198 + insector + 20201231150731 + 1982 + Gottlieb + Platform + qbert + + + + + + + + + + + 6 + + + + + + + 00 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Gottlieb Qbert/meta/Krull.mra b/Arcade_MiST/Gottlieb Qbert/meta/Krull.mra new file mode 100644 index 00000000..f3e86cfb --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/meta/Krull.mra @@ -0,0 +1,48 @@ + + + Krull + 0228 + krull + 20201231150731 + 1983 + Gottlieb + Platform + qbert + + + + + + + 3 + + + + + + + + + + + + + + + + + + + 00 + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Gottlieb Qbert/meta/Mad Planets.mra b/Arcade_MiST/Gottlieb Qbert/meta/Mad Planets.mra new file mode 100644 index 00000000..49e049b3 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/meta/Mad Planets.mra @@ -0,0 +1,47 @@ + + + Mad Planets + 0198 + mplanets + 20201231150731 + 1982 + Gottlieb + Platform + qbert + + + + + + + + + + 2 + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Gottlieb Qbert/meta/Q'bert (US, Set 1).mra b/Arcade_MiST/Gottlieb Qbert/meta/Q'bert (US, Set 1).mra new file mode 100644 index 00000000..5e6eecd6 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/meta/Q'bert (US, Set 1).mra @@ -0,0 +1,78 @@ + + Qbert + USA + no + no + Set 1 + + + + 1982 + Gottlieb + Platform - Climb + + qbert + qbert + 0198 + qbert + + + 15kHz + vertical (ccw) + yes + + 2 (alternating) + 4-way diagonal + + 0 + + + + + + + + + + + + 0 + + + + + + + + 00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 20210430005030 + diff --git a/Arcade_MiST/Gottlieb Qbert/meta/QBert Qubes.mra b/Arcade_MiST/Gottlieb Qbert/meta/QBert Qubes.mra new file mode 100644 index 00000000..c420c554 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/meta/QBert Qubes.mra @@ -0,0 +1,42 @@ + + + Qbert Qubes + 0198 + qbertqub + 20201231150731 + 1982 + Gottlieb + Platform + qbert + + + + + + + + + + 1 + + + + + + + 00 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Gottlieb Qbert/meta/Tylz.mra b/Arcade_MiST/Gottlieb Qbert/meta/Tylz.mra new file mode 100644 index 00000000..1a0862c1 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/meta/Tylz.mra @@ -0,0 +1,41 @@ + + + Tylz + 0198 + tylz + 20201231150731 + 1982 + Gottlieb + Platform + qbert + + + + + + + 5 + + + + + + + 00 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Arcade_MiST/Gottlieb Qbert/rtl/Qbert_MiST.sv b/Arcade_MiST/Gottlieb Qbert/rtl/Qbert_MiST.sv new file mode 100644 index 00000000..f95ba29f --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/rtl/Qbert_MiST.sv @@ -0,0 +1,534 @@ +module Qbert_MiST ( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + output SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input CONF_DATA0, + input CLOCK_27, + 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 + +); + +`include "rtl\build_id.v" + +localparam CONF_STR = { + "QBERT;;", + "O2,Rotate Controls,Off,On;", + "O34,Scanlines,Off,25%,50%,75%;", + "O5,Blend,Off,On;", + "O6,Joystick Swap,Off,On;", + "O7,Flip,Off,On;", + "O8,Test mode,Off,On;", + "O9,Diagonal joystick,Off,On;", + "O1,Pause,Off,On;", + "R4096,Save NVRAM;", + "DIP;", + "T0,Reset;", + "V,v1.00.",`BUILD_DATE +}; + +wire pause = status[1]; +wire rotate = status[2]; +wire [1:0] scanlines = status[4:3]; +wire blend = status[5]; +wire joyswap = status[6]; +wire flip = status[7]; +wire service = status[8]; +wire diagonal = status[9]; + +wire [1:0] orientation = {flip, core_mod != mod_tylz && core_mod != mod_insector}; +wire [7:0] dip_sw = status[23:16]; + +assign LED = ~ioctl_downl; +assign SDRAM_CLK = clk_80; +assign SDRAM_CKE = 1; + +wire clk_80, clk_40, pll_locked; +pll pll( + .inclk0(CLOCK_27), + .c0(clk_80), + .c1(clk_40), + .locked(pll_locked) + ); + +wire clk_sys = clk_40; + +reg [3:0] cnt1; +reg cpu_clk; // 5 MHz +reg cen_5, cen_10_p, cen_10_n; +always @(posedge clk_sys) begin + cnt1 <= cnt1 + 1'd1; + if (cnt1 == 7) cnt1 <= 0; + + cpu_clk <= cnt1[2]; + cen_5 <= cnt1 == 7; + cen_10_p <= cnt1 == 3 || cnt1 == 7; + cen_10_n <= cnt1 == 1 || cnt1 == 5; +end + +// derive sound clock from clk_sys +reg [5:0] cnt2; +reg sound_cen; +always @(posedge clk_sys) begin + cnt2 <= cnt2 + 6'd1; + sound_cen <= 1'b0; + if (cnt2 == 6'd44) begin + cnt2 <= 6'd0; + sound_cen <= 1'b1; + end +end + + +localparam mod_qbert = 0; +localparam mod_qub = 1; +localparam mod_mplanets = 2; +localparam mod_krull = 3; +localparam mod_curvebal = 4; +localparam mod_tylz = 5; +localparam mod_insector = 6; + +wire [5:0] OP2720; +wire [7:0] IP1710; +wire [7:0] IP4740; +wire [7:0] IPA1J2; + +always @(*) begin + + IPA1J2 <= 8'd0; + IP4740 <= 8'd0; + + IP1710 <= { + m_fireA, // test 1 + ~service, // test 2 + 2'b0, + m_coin2, // coin 1 + m_coin1, // coin 2 + m_two_players, // p2 + m_one_player // p1 + }; + + if (~diagonal) begin + IP4740 <= { + m_down2, + m_up2, + m_left2, + m_right2, + m_down, + m_up, + m_left, + m_right + }; + end else begin + IP4740 <= { + m_down2 & m_left2, // down + left + m_up2 & m_right2, // up + right + m_left2 & m_up2, // left + up + m_right2 & m_down2, // right + down + m_down & m_left, // down + left + m_up & m_right, // up + right + m_left & m_up, // left + up + m_right & m_down, // right + down + }; + end + + case (core_mod) + mod_qbert: + begin + end + + mod_qub: + begin + end + + mod_mplanets: + begin + IP1710 <= { + ~service, // test 2 + m_fireA, // test 1 + 4'd0, + m_coin2, + m_coin1 + }; + + IP4740 <= { + m_fireB,// button 2 + + m_two_players, // p2 + m_one_player, // p1 + + m_fireA, // button 1 + m_left, + m_down, + m_right, + m_up + }; + + //IPA1J2 <= spinner_0[7:0]; + end + + mod_krull: + begin + IP1710 <= { + m_two_players, + m_one_player, + 2'b00, + m_coin2, + m_coin1, + m_fireA, // select in test mode + ~service + }; + IP4740 <= { + m_left, // left joystick + m_down, + m_right, + m_up, + m_left2 | m_leftB, // right joystick15 + m_down2 | m_downB, + m_right2 | m_rightB, + m_up2 | m_upB + }; + end + + mod_curvebal: + begin + IP1710 <= { + 4'd0, + m_coin2, + m_coin1, // coin 1 + m_fireA, // test 1 + ~service, // test 2 + }; + + IP4740 <= { + 1'b0, // n/a + m_fireD | m_down, // bunt + 1'b0, // n/a + m_fireC | m_right, // pitch right + 1'b0, // n/a + m_fireB | m_left, // pitch left + m_fireA | m_up, // swing + 1'b0 + }; + end + + mod_tylz: + begin + IP1710 <= { // IN1 + 4'd0, + m_coin1, + m_coin2, + m_fireA, // test 1 + ~service + }; + + IP4740 <= { // IN4 + 1'b0, + m_two_players, // p2 + m_one_player, // p1 + + m_fireA, // button 1 + diagonal ? m_left & m_up : m_left, + diagonal ? m_right & m_up : m_up, + diagonal ? m_right & m_down : m_right, + diagonal ? m_left & m_down : m_down + }; + end + + mod_insector: + begin + IP1710 <= { // IN1 + 1'b0, + ~service, + m_fire2B, + m_fire2A, + m_coin2, + m_coin2, + m_fireB, + m_fireA + }; + + IP4740 <= { // IN4 + m_left2, + m_down2, + m_right2, + m_up2, + + m_left, + m_down, + m_right, + m_up + }; + end + default: + begin + end + endcase +end + +wire [31:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [19:0] joystick_0; +wire [19:0] joystick_1; +wire scandoublerD; +wire ypbpr; +wire no_csync; +wire [6:0] core_mod; +wire key_strobe; +wire key_pressed; +wire [7:0] key_code; + +user_io #(.STRLEN(($size(CONF_STR)>>3)))user_io( + .clk_sys (clk_sys ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD), + .ypbpr (ypbpr ), + .no_csync (no_csync ), + .core_mod (core_mod ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); + +wire [15:0] main_rom_addr; +wire [15:0] main_rom_do; +wire [14:0] sub_rom_addr; +wire [15:0] sub_rom_do; +wire [15:1] ch1_addr; +wire [15:0] ch1_do; +wire sp1_req, sp1_ack; +wire [13:0] bg_addr; +wire [31:0] bg_do; + +wire ioctl_downl; +wire ioctl_upl; +wire [7:0] ioctl_index; +wire ioctl_wr; +wire [24:0] ioctl_addr; +wire [7:0] ioctl_din; +wire [7:0] ioctl_dout; + +data_io data_io( + .clk_sys ( clk_sys ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), + .ioctl_download( ioctl_downl ), + .ioctl_upload ( ioctl_upl ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_din ( ioctl_din ), + .ioctl_dout ( ioctl_dout ) +); +wire [24:0] bg_ioctl_addr = ioctl_addr - 17'h10000; + +reg port1_req, port2_req; +sdram #(80) sdram( + .*, + .init_n ( pll_locked ), + .clk ( clk_80 ), + + .port1_req ( port1_req ), + .port1_ack ( ), + .port1_a ( ioctl_addr[23:1] ), + .port1_ds ( {ioctl_addr[0], ~ioctl_addr[0]} ), + .port1_we ( ioctl_downl ), + .port1_d ( {ioctl_dout, ioctl_dout} ), + .port1_q ( ), + + .cpu1_addr ( ioctl_downl ? 16'hffff : {1'b0, main_rom_addr[15:1]} ), + .cpu1_q ( main_rom_do ), + .cpu2_addr ( 16'hffff ), + .cpu2_q ( ), + + // port2 for sprite graphics + .port2_req ( port2_req ), + .port2_ack ( ), + .port2_a ( {bg_ioctl_addr[13:0], bg_ioctl_addr[15]} ), // merge fg roms to 32-bit wide words + .port2_ds ( {bg_ioctl_addr[14], ~bg_ioctl_addr[14]} ), + .port2_we ( ioctl_downl ), + .port2_d ( {ioctl_dout, ioctl_dout} ), + .port2_q ( ), + + .sp_addr ( ioctl_downl ? 14'h3fff : bg_addr ), + .sp_q ( bg_do ) +); + +// ROM download controller +always @(posedge clk_sys) begin + reg ioctl_wr_last = 0; + + ioctl_wr_last <= ioctl_wr; + if (ioctl_downl) begin + if (~ioctl_wr_last && ioctl_wr) begin + port1_req <= ~port1_req; + port2_req <= ~port2_req; + end + end +end + +reg reset = 1; +reg rom_loaded = 0; +always @(posedge clk_sys) begin + reg ioctl_downlD; + ioctl_downlD <= ioctl_downl; + + if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; + reset <= status[0] | buttons[1] | ~rom_loaded; +end + +wire [7:0] audio; +wire hs, vs, cs; +wire hb, vb; +wire blankn = ~(hb | vb); + +wire rom_init = ioctl_downl && (ioctl_index==0); +wire nvram_init = ioctl_downl && (ioctl_index==8'hFF); + +wire [3:0] r; +wire [3:0] g; +wire [3:0] b; + +mylstar_board mylstar_board +( + .clk_sys(clk_sys), + .reset(reset), + .pause(pause), + + .CPU_CORE_CLK(clk_80), + .CPU_CLK(cpu_clk), + .cen_5(cen_5), + .cen_10_p(cen_10_p), + .cen_10_n(cen_10_n), + + .red(r), + .green(g), + .blue(b), + .HBlank(hb), + .VBlank(vb), + .HSync(hs), + .VSync(vs), + + .IP1710(IP1710), + .IP4740(IP4740), + .IPA1J2(IPA1J2), + .OP2720(OP2720), + .OP3337(), + + .dip_switch(dip_sw), + + .rom_init(rom_init), + .nvram_init(nvram_init), + .nvram_upl(ioctl_upl), + .rom_init_address(ioctl_addr), + .rom_init_data(ioctl_dout), + .nvram_data(ioctl_din), + + .vflip(flip), + .hflip(flip), + + .cpu_rom_addr(main_rom_addr), + .cpu_rom_do(main_rom_addr[0] ? main_rom_do[15:8] : main_rom_do[7:0]), + .bg_rom_addr(bg_addr), + .bg_rom_do(bg_do) +); + +// audio board + +ma216_board ma216_board( + .clk(clk_sys), + .cen(sound_cen), + .reset(reset), + .IP2720(OP2720), + .audio(audio), + .rom_init(rom_init), + .rom_init_address(ioctl_addr), + .rom_init_data(ioctl_dout) +); + +mist_video #(.COLOR_DEPTH(4), .SD_HCNT_WIDTH(10)) mist_video( + .clk_sys ( clk_sys ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS3 ( SPI_SS3 ), + .SPI_DI ( SPI_DI ), + .R ( blankn ? r : 0 ), + .G ( blankn ? g : 0 ), + .B ( blankn ? b : 0 ), + .HSync ( ~hs ), + .VSync ( ~vs ), + .VGA_R ( VGA_R ), + .VGA_G ( VGA_G ), + .VGA_B ( VGA_B ), + .VGA_VS ( VGA_VS ), + .VGA_HS ( VGA_HS ), + .ce_divider ( 0 ), + .rotate ( { orientation[1], rotate } ), + .blend ( blend ), + .scandoubler_disable( scandoublerD ), + .scanlines ( scanlines ), + .ypbpr ( ypbpr ), + .no_csync ( no_csync ) + ); + +wire audio_out; +assign AUDIO_L = audio_out; +assign AUDIO_R = audio_out; + +dac #(.C_bits(8))dac( + .clk_i(clk_sys), + .res_n_i(1'b1), + .dac_i(audio), + .dac_o(audio_out) + ); + +wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF, m_fireG, m_upB, m_downB, m_leftB, m_rightB; +wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F, m_fire2G, m_up2B, m_down2B, m_left2B, m_right2B; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; + +arcade_inputs inputs ( + .clk ( clk_sys ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .rotate ( rotate ), + .orientation ( orientation ), + .joyswap ( joyswap ), + .oneplayer ( 1'b0 ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_upB, m_downB, m_leftB, m_rightB, 5'd0, m_fireG, m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ), + .player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, 5'd0, m_fire2G, m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ) +); + +endmodule diff --git a/Arcade_MiST/Gottlieb Qbert/rtl/build_id.tcl b/Arcade_MiST/Gottlieb Qbert/rtl/build_id.tcl new file mode 100644 index 00000000..938515d8 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/rtl/build_id.tcl @@ -0,0 +1,35 @@ +# ================================================================================ +# +# Build ID Verilog Module Script +# Jeff Wiencrot - 8/1/2011 +# +# Generates a Verilog module that contains a timestamp, +# from the current build. These values are available from the build_date, build_time, +# physical_address, and host_name output ports of the build_id module in the build_id.v +# Verilog source file. +# +# ================================================================================ + +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 "rtl/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" +} + +# Comment out this line to prevent the process from automatically executing when the file is sourced: +generateBuildID_Verilog \ No newline at end of file diff --git a/Arcade_MiST/Gottlieb Qbert/rtl/dpram.v b/Arcade_MiST/Gottlieb Qbert/rtl/dpram.v new file mode 100644 index 00000000..ef44b636 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/rtl/dpram.v @@ -0,0 +1,26 @@ + +module dpram #(parameter addr_width=16, parameter data_width=8) ( + input clk, + input [addr_width-1:0] addr, + output [data_width-1:0] dout, + input ce, + input oe, + + input we, + input [addr_width-1:0] waddr, + input [data_width-1:0] wdata, + output reg [data_width-1:0] doutb +); + +reg [data_width-1:0] d; +reg [data_width-1:0] memory[(1<270 && H<290); +assign HBlank = ~EXTH_nBLANK; +assign VBlank = VBLANK; +assign red = G13_Q; +assign green = G15_Q; +assign blue = G14_Q; +assign OP2720 = A10[5:0]; +assign OP4740 = A9[7:0]; +assign OP3337 = A8[4:0]; + +reg CLK5; +wire IOM; +wire RD_n, WR_n; +wire [7:0] cpu_dout, C5_Q, C6_Q, C7_Q, C8_9_Q, C9_10_Q, C10_11_Q; +wire [7:0] C11_12_Q, C12_13_Q, C13_14_Q, C14_15_Q, C16_Q; +wire [3:0] D2_Y, D3_Y, D4_Y, D5_Y, D6_Y, D7_Y, D8_Y, D9_Y, D10_Y; +wire [19:0] addr; +wire J16_co, J17_co, F16_co, H5_co, H6_co; +wire [5:0] G16_Q, G17_Q; +reg [7:0] A8, A9, A10; +wire J13_Q1, J13_Q2, L10_Q1; +wire [7:0] E1_2_Q, E2_3_Q, E4_Q; +wire [3:0] F5_S, E5_S, D16_S, D13_Y; +wire [3:0] G1_Y, G2_Y, G3_Y, G4_Y, G5_Y, G7_Y, G9_Y; +wire [3:0] J1_Q, J2_Q, J3_Q, J4_Q, J5_Q, J6_Q, J10_Q, J11_Q; +wire [3:0] H5_Q, H6_Q, H7_Y, H8_Y, H9_Y, H10_Y, H13_Y; +reg [3:0] H12_Y; +wire [3:0] K1_Q, K2_Q, K3_Q; +wire [3:0] L12_Q; +wire F5_C4; +wire G8_nQ1, G8_Q1, G8_nQ2; +wire [7:0] K4_D, K5_D, K6_D, K7_8_D; +reg [7:0] G11_Q; +wire [3:0] K9_Y, K10_Y, K11_Y, G12_Y, G13_Q, G14_Q, G15_Q; +wire [7:0] E7_Q, E8_Ao, E8_Bo, E9_10_Bo, E10_11_Q, D11_Q, D12_Y, E11_12_Q, E13_Q; + +wire nCOLSEL = ~(ram_io_ce & addr[12:11] == 2'b10); +wire nBOJRSEL1 = ~(ram_io_ce & ~addr[12]); +wire nBOJRWR = nBOJRSEL1 | WR_n; //F6_8 +wire nBRSEL = ~BRSEL; +wire nFRSEL = ~FRSEL; +wire nBRWR = nBRSEL | WR_n; //F6_6 +wire nFRWR = nFRSEL | WR_n; //F6_3 +wire BANK_SEL = A8[4]; +wire VERTFLOP = vflip ? ~A8[2]: A8[2]; +wire HORIZFLIP = hflip ? ~A8[1]: A8[1]; +wire FB_PRIORITY = A8[0]; +wire BLANK = ~(H[8] | VBLANK);//J12_1 +wire HBLANK = H[8]; +wire VBLANK; //~E17_8 +wire nVBLANK = ~VBLANK;//E17_8 +wire nVHBLANK = ~(nVBLANK & ~H[8]);//H14_3 +wire SFBW = H[8] & nVBLANK;//K14_3 +wire SBBW = ~H[8] & VBLANK & ~V[3];//K14_8 +wire LATCH_CLK /* synthesis keep */;// K16_6; +reg SHIFTED_HB; +reg EXTH_nBLANK; +wire S3; //K16_8; +wire S5 = CLK5 | CLK10; //K13_8 +wire RDY1; //J9_8; +reg [8:0] H; +reg [8:0] HH; +reg [2:0] HHx; +wire [7:0] VV; +wire nHH0s = ~HHx[0]; //F15_12; +wire nH0 = ~H[0]; //F15_4 +wire nVV0 = ~VV[0]; //K15_10 + +reg CLK10; + +always @(posedge clk_sys) begin + if (cen_10_p) CLK10 <= 1; + if (cen_10_n) CLK10 <= 0; +end + +//////////////////////// +// CPU/RAM/ROM // +//////////////////////// + +wire [7:0] A1J2 = trackball_sel ? IPA1J2 : 8'd0; + +wire [7:0] ram_dout = C5_Q | C6_Q | C7_Q | C9_10_Q | C8_9_Q | C10_11_Q; +wire [7:0] rom_dout; +wire [7:0] cpu_din = ram_dout | rom_dout | B11 | B12 | B14 | A1J2 | E8_Ao | BGRAMROM_DO; + +always @(posedge clk_sys) begin : A8A9A10 + if (!WR_n) begin + if (op2_sel) A10 <= cpu_dout; + if (op3_sel) A8 <= cpu_dout; + if (op4_sel) A9 <= cpu_dout; + end +end + +i8088 B1( + .CORE_CLK(CPU_CORE_CLK), + .CLK(CPU_CLK), + .RESET(reset), + .READY(RDY1 & ~pause & ~nvram_init & ~nvram_upl), + .INTR(0), + .NMI(VBLANK), + .INTA_n(), + .addr(addr), + .dout(cpu_dout), + .din(cpu_din), + .IOM(IOM), + .RD_n(RD_n), + .WR_n(WR_n) +); + +reg ram0_cs, ram1_cs, ram2_cs, ram3_cs, ram4_cs, ram5_cs, FRSEL, BRSEL; +always @(*) begin : B6 + ram0_cs = 0; + ram1_cs = 0; + ram2_cs = 0; + ram3_cs = 0; + ram4_cs = 0; + ram5_cs = 0; + FRSEL = 0; + BRSEL = 0; + if (~IOM & addr[15:14] == 2'b00) + case (addr[13:11]) + 3'd0: ram0_cs = 1; + 3'd1: ram1_cs = 1; + 3'd2: ram2_cs = 1; + 3'd3: ram3_cs = 1; + 3'd4: ram4_cs = 1; + 3'd5: ram5_cs = 1; + 3'd6: FRSEL = 1; + 3'd7: BRSEL = 1; + default: ; + endcase +end + +reg rom0_ce, rom1_ce, rom2_ce, rom3_ce, rom4_ce, ram_io_ce; +always @(*) begin : B8 + rom0_ce = 0; + rom1_ce = 0; + rom2_ce = 0; + rom3_ce = 0; + rom4_ce = 0; + ram_io_ce = 0; + if (~IOM) + case (addr[15:13]) + 3'd2: ram_io_ce = 1; //4000-5FFF + 3'd3: rom4_ce = 1; //6000-7FFF + 3'd4: rom3_ce = 1; //8000-9FFF + 3'd5: rom2_ce = 1; //A000-BFFF + 3'd6: rom1_ce = 1; //C000-DFFF + 3'd7: rom0_ce = 1; //E000-FFFF + default: ; + endcase +end + +reg wdcl, op1_sel, op2_sel, op3_sel, op4_sel; +always @(*) begin: B9 + // IO write selects + wdcl = 0; + op1_sel = 0; + op2_sel = 0; + op3_sel = 0; + op4_sel = 0; + if (~WR_n & ram_io_ce & addr[12:11] == 2'b11 & ~addr[3]) + case (addr[2:0]) + 3'd0: wdcl = 1; + 3'd1: op1_sel = 1; + 3'd2: op2_sel = 1; + 3'd3: op3_sel = 1; + 3'd4: op4_sel = 1; + default: ; + endcase +end + +reg dip_sel, IP1710_sel, IP4740_sel, trackball_sel; +always @(*) begin : B10 + // IO read selects + dip_sel = 0; + IP1710_sel = 0; + IP4740_sel = 0; + trackball_sel = 0; + if (~RD_n & ram_io_ce & addr[12:11] == 2'b11 & ~addr[3]) + case (addr[2:0]) + 3'd0: dip_sel = 1; + 3'd1: IP1710_sel = 1; + 3'd2: trackball_sel = 1; + 3'd4: IP4740_sel = 1; + default: ; + endcase +end + +wire [7:0] B11 = IP1710_sel ? IP1710 : 8'd0; + +wire [7:0] B12 = dip_sel ? dip_switch : 8'd0; + +wire [7:0] B14 = IP4740_sel ? IP4740 : 8'd0; + +// TODO: load from MRA and fill with $FF if empty +wire [10:0] nvram_addr = (nvram_init | nvram_upl) ? rom_init_address[10:0] : addr[10:0]; +wire [7:0] nvram_din = nvram_init ? rom_init_data : cpu_dout; +wire nvram_nwr = nvram_init ? 1'b0 : WR_n; +wire nvram_nrd = nvram_upl ? 1'b0 : RD_n; +assign nvram_data = C5_Q | C6_Q; + +wire [10:0] ramrom_addr = rom_init ? rom_init_address[10:0] : addr[10:0]; +wire ramrom_nwr = rom_init ? 1'b0 : WR_n; +wire [7:0] ramrom_din = rom_init ? rom_init_data : cpu_dout; + +// nvram 1 - 0000-07FF +ram #(.addr_width(11),.data_width(8)) C5 ( + .clk(clk_sys), + .din(nvram_din), + .addr(nvram_addr), + .cs((nvram_init | nvram_upl) ? ~(rom_init_address < 18'h800) : ~ram0_cs), + .oe(nvram_nrd), + .wr(nvram_nwr), + .Q(C5_Q) +); + +// nvram 2 - 0800-0FFF +ram #(.addr_width(11),.data_width(8)) C6 ( + .clk(clk_sys), + .din(nvram_din), + .addr(nvram_addr), + .cs((nvram_init | nvram_upl) ? ~(rom_init_address >= 18'h800 && rom_init_address < 18'h1000) : ~ram1_cs), + .oe(nvram_nrd), + .wr(nvram_nwr), + .Q(C6_Q) +); + +// RAM or ROM - 1000-17FF +ram #(.addr_width(11),.data_width(8)) C7 ( + .clk(clk_sys), + .din(ramrom_din), + .addr(ramrom_addr), + .cs(rom_init ? ~(rom_init_address < 18'hA800) : ~ram2_cs), + .oe(RD_n), + .wr(ramrom_nwr), + .Q(C7_Q) +); + +// 1800-1FFF +ram #(.addr_width(11),.data_width(8)) C8_9 ( + .clk(clk_sys), + .din(ramrom_din), + .addr(ramrom_addr), + .cs(rom_init ? ~(rom_init_address < 18'hB000) : ~ram3_cs), + .oe(RD_n), + .wr(ramrom_nwr), + .Q(C8_9_Q) +); + +// 2000-27FF +ram #(.addr_width(11),.data_width(8)) C9_10 ( + .clk(clk_sys), + .din(ramrom_din), + .addr(ramrom_addr), + .cs(rom_init ? ~(rom_init_address < 18'hB800) : ~ram4_cs), + .oe(RD_n), + .wr(ramrom_nwr), + .Q(C9_10_Q) +); + +// 2800-2FFF +ram #(.addr_width(11),.data_width(8)) C10_11 ( + .clk(clk_sys), + .din(ramrom_din), + .addr(ramrom_addr), + .cs(rom_init ? ~(rom_init_address < 18'hC000) : ~ram5_cs), + .oe(RD_n), + .wr(ramrom_nwr), + .Q(C10_11_Q) +); + +reg [15:0] CPU_addr; +always @(posedge clk_sys) CPU_addr <= addr[15:0]; + +`ifdef EXT_ROM +assign cpu_rom_addr = {~CPU_addr[15:13], CPU_addr[12:0]}; +assign rom_dout = ((rom0_ce | rom1_ce | rom2_ce | rom3_ce | rom4_ce) & ~RD_n) ? cpu_rom_do : 8'h00; +`else +assign rom_dout = C11_12_Q | C12_13_Q | C13_14_Q | C14_15_Q | C16_Q; + +dpram #(.addr_width(13),.data_width(8)) C11_12 ( + .clk(clk_sys), + .addr(CPU_addr[12:0]), + .dout(C11_12_Q), + .ce(~rom0_ce), + .oe(~RD_n), + .we(rom_init & rom_init_address < 18'h2000), + .waddr(rom_init_address), + .wdata(rom_init_data) +); + +dpram #(.addr_width(13),.data_width(8)) C12_13 ( + .clk(clk_sys), + .addr(CPU_addr[12:0]), + .dout(C12_13_Q), + .ce(~rom1_ce), + .oe(~RD_n), + .we(rom_init & rom_init_address < 18'h4000), + .waddr(rom_init_address), + .wdata(rom_init_data) +); + +dpram #(.addr_width(13),.data_width(8)) C13_14 ( + .clk(clk_sys), + .addr(CPU_addr[12:0]), + .dout(C13_14_Q), + .ce(~rom2_ce), + .oe(~RD_n), + .we(rom_init & rom_init_address < 18'h6000), + .waddr(rom_init_address), + .wdata(rom_init_data) +); + +dpram #(.addr_width(13),.data_width(8)) C14_15 ( + .clk(clk_sys), + .addr(CPU_addr[12:0]), + .dout(C14_15_Q), + .ce(~rom3_ce), + .oe(~RD_n), + .we(rom_init & rom_init_address < 18'h8000), + .waddr(rom_init_address), + .wdata(rom_init_data) +); + +dpram #(.addr_width(13),.data_width(8)) C16 ( + .clk(clk_sys), + .addr(CPU_addr[12:0]), + .dout(C16_Q), + .ce(~rom4_ce), + .oe(~RD_n), + .we(rom_init & rom_init_address < 18'ha000), + .waddr(rom_init_address), + .wdata(rom_init_data) +); +`endif // EXT_ROM + +//////////////////////// +// Horizontal counter // +//////////////////////// + +always @(posedge clk_sys) begin : J16J17K17 + if (cen_10_p) CLK5 <= ~CLK5; + if (cen_5) begin + CLK5 <= 1; + H <= H + 1'd1; + if (H == 9'd317) H <= 0; + end +end + +wire K14_6 = ~&H[7:1] & ~H[8]; + +always @(posedge clk_sys) begin : J13 + if (cen_5) begin + if (H[1:0] == 2'b01) begin // rising edge of H[1] + EXTH_nBLANK <= ~HBLANK; + SHIFTED_HB <= HBLANK; + end + if (~K14_6) EXTH_nBLANK <= 0; + end +end + +always @(posedge clk_sys) begin : G16G17 + if (cen_5) begin + HH <= {K14_6, {8{HORIZFLIP}} ^ H[7:0]}; + HHx <= H[2:0]; + end +end + +assign J13_Q1 = EXTH_nBLANK; + +assign S3 = ~(H[2:0] == 3'b011 & ~CLK5); +assign LATCH_CLK = ~(H[2:0] == 3'b001 & ~CLK5); +wire LATCH_CLK_EN_N = cen_10_p & ~cen_5 & H[2:0] == 3'b001; // next cycle is LATCH_CLK = 0 + +//////////////////////// +// Vertical counter // +//////////////////////// + +reg [7:0] V, Vlatch; +always @(posedge clk_sys) begin : D17F16 + if (cen_5) begin + if (H == 255) V <= V + 1'd1; + end +end + +always @(posedge clk_sys) begin : E16 + if (cen_5) begin + if (~HH[8] & K14_6) Vlatch <= V; // rising edge of HH[8] + end +end + +assign VBLANK = &V[7:4]; +assign D16_S = Vlatch[7:4] + VERTFLOP; + +assign VV = {8{VERTFLOP}} ^ {D16_S, Vlatch[3:0]}; + +////////////////////////// +// Foreground objects // +////////////////////////// + +wire [7:0] E1_2_dout; +assign E1_2_Q = ~E1_2_dout; + +wire [5:0] FGREG_addr = H[5:0]; + +//vertical position reg +dpram #(.addr_width(10),.data_width(8)) E1_2( + .clk(clk_sys), + .addr(FGREG_addr), + .dout(E1_2_dout), + .ce(1'b0), + .oe(1'b0), + .we(~nFRWR & addr[0] & ~addr[1]), + .waddr(addr[7:2]), + .wdata(cpu_dout[7:0]) +); + +wire [7:0] E2_3_dout; +assign E2_3_Q = ~E2_3_dout; +//horizontal position reg +dpram #(.addr_width(10),.data_width(8)) E2_3( + .clk(clk_sys), + .addr(FGREG_addr), + .dout(E2_3_dout), + .ce(1'b0), + .oe(1'b0), + .we(~nFRWR & ~addr[0] & addr[1]), + .waddr(addr[7:2]), + .wdata(cpu_dout[7:0]) +); + +wire [7:0] E4_dout; +assign E4_Q = ~E4_dout; +//object select reg +dpram #(.addr_width(10),.data_width(8)) E4( + .clk(clk_sys), + .addr(FGREG_addr), + .dout(E4_dout), + .ce(1'b0), + .oe(1'b0), + .we(~nFRWR & ~addr[0] & ~addr[1]), + .waddr(addr[7:2]), + .wdata(cpu_dout[7:0]) +); + +wire [7:0] FRBD = VV[7:0] + E4_Q[7:0]; + +wire nENBUF = ~(nVBLANK & HBLANK & (&FRBD[7:4])); + +// line RAM address counter +reg [4:0] linea; +always @(posedge clk_sys) begin : G6G8 + if (cen_5) begin + if (~nENBUF) linea <= linea + 1'd1; + end + if (~HBLANK) linea <= 0; +end + +wire S1 = VBLANK | ~HBLANK; + +wire J8_3 = CLK5 | nENBUF; +wire H14_6 = ~(~H[1] & H[2]); + +wire S2 = S1 ? H14_6 : J8_3; //G9b + +wire [4:0] FBA = S1 ? H[7:3] : linea[4:0]; //G7-G9a +wire [7:0] HPD = S1 ? 8'hFF : E1_2_Q; //G1-G2 +wire [7:0] PND = S1 ? 8'hFF : E2_3_Q; //G3-G4 +wire [3:0] PLD = S1 ? 4'hF : FRBD[3:0]; //G5 + +reg [7:0] VPOSRAM[32]; +reg [7:0] VPOSRAM_DO; +always @(posedge clk_sys) begin : H1H2H3H4 + if (!S2) VPOSRAM[FBA] <= ~HPD; + else VPOSRAM_DO <= VPOSRAM[FBA]; +end + +// line buffer address counter +reg [7:0] LB; +always @(posedge clk_sys) begin : H5H6G8 + if (cen_10_n) begin + if (~&LB) LB <= LB + 1'd1; + if (!S3) LB <= VPOSRAM_DO; + end +end + +wire [7:0] LBAx = SHIFTED_HB ? 8'd0 : VV[0] ? HH[7:0] : LB; //H9-H7 +wire [7:0] LBA = SHIFTED_HB ? 8'd0 : VV[0] ? LB : HH[7:0]; //H10-H8 + +reg [11:0] HPOSRAM[32]; +reg [11:0] HPOSRAM_DO; +always @(posedge clk_sys) begin : J1J2J3J4J5J6 + if (!S2) HPOSRAM[FBA] <= ~{PND, PLD}; + else HPOSRAM_DO <= HPOSRAM[FBA]; +end + +reg [11:0] RAx /* synthesis noprune */; +always @(posedge clk_sys) begin : K1K2K3 + if (LATCH_CLK_EN_N) RAx <= ~HPOSRAM_DO; // negedge of LATCH_CLK +end + +// L11 +wire nSRLD = ~(boons[2:0] == 3'b011); // L11_6 +// wire L11_8 = ~(L12_Q[2] & 1'b1); + +// "Boons counter" +reg [3:0] boons; +always @(posedge clk_sys) begin : L12 + if (cen_10_n) begin + boons <= boons + 1'd1; + if (!LATCH_CLK) boons <= 0; + end +end + +wire [12:0] RA = { RAx, boons[3] }; + +//00000000 1100 0000 0000 0000 +// K4,K5,K6,K7_8 addr_width(14), bit13 = BANK_SEL - fix me! +wire bit13 = BANK_SEL; +reg [13:0] FGROM_addr; +always @(posedge clk_sys) FGROM_addr <= {bit13,RA}; + +`ifdef EXT_ROM +assign bg_rom_addr = FGROM_addr; +assign K4_D = bg_rom_do[7:0]; +assign K5_D = bg_rom_do[15:8]; +assign K6_D = bg_rom_do[23:16]; +assign K7_8_D = bg_rom_do[31:24]; +`else +dpram #(.addr_width(14),.data_width(8)) K4( + .clk(clk_sys), + .addr(FGROM_addr), + .dout(K4_D), + .ce(1'b0), + .oe(1'b0), + .we(rom_init && rom_init_address < 18'h14000), + .waddr(rom_init_address), + .wdata(rom_init_data) +); + +dpram #(.addr_width(14),.data_width(8)) K5( + .clk(clk_sys), + .addr(FGROM_addr), + .dout(K5_D), + .ce(1'b0), + .oe(1'b0), + .we(rom_init && rom_init_address < 18'h18000), + .waddr(rom_init_address), + .wdata(rom_init_data) +); + +dpram #(.addr_width(14),.data_width(8)) K6( + .clk(clk_sys), + .addr(FGROM_addr), + .dout(K6_D), + .ce(1'b0), + .oe(1'b0), + .we(rom_init && rom_init_address < 18'h1C000), + .waddr(rom_init_address), + .wdata(rom_init_data) +); + +dpram #(.addr_width(14),.data_width(8)) K7_8( + .clk(clk_sys), + .addr(FGROM_addr), + .dout(K7_8_D), + .ce(1'b0), + .oe(1'b0), + .we(rom_init & rom_init_address < 18'h20000), + .waddr(rom_init_address), + .wdata(rom_init_data) +); +`endif + +reg [7:0] SR1, SR2, SR3, SR4; +always @(posedge clk_sys) begin : L4_5_6_7_8 + if (cen_10_p) begin + SR1 <= { SR1[6:0], 1'b0 }; + SR2 <= { SR2[6:0], 1'b0 }; + SR3 <= { SR3[6:0], 1'b0 }; + SR4 <= { SR4[6:0], 1'b0 }; + if (!nSRLD) begin + SR1 <= K4_D; + SR2 <= K5_D; + SR3 <= K6_D; + SR4 <= K7_8_D; + end + end +end + +wire K13_11 = ~(SR4[7] | SR3[7] | SR2[7] | SR1[7]) | CLK10; +assign K9_Y = VV[0] ? { 1'b0, S5, 1'b0, K13_11 } : { 1'b0, K13_11, 1'b0, S5 }; +assign K10_Y = nVV0 ? 4'd0 : {SR4[7], SR3[7], SR2[7], SR1[7]}; +assign K11_Y = VV[0] ? 4'd0 : {SR4[7], SR3[7], SR2[7], SR1[7]}; + +// line buffers +ram #(.addr_width(8), .data_width(4)) J10( + .clk(clk_sys), + .din(K10_Y), + .addr(LBA), + .cs(1'b0), + .oe(VV[0]), + .wr(K9_Y[0]), + .Q(J10_Q) +); + +ram #(.addr_width(8), .data_width(4)) J11( + .clk(clk_sys), + .din(K11_Y), + .addr(LBAx), + .cs(1'b0), + .oe(nVV0), + .wr(K9_Y[2]), + .Q(J11_Q) +); + +wire [3:0] FOREVID = J10_Q | J11_Q; + +////////////////////////// +// Background // +////////////////////////// + +wire [7:0] E7_doutb; +dpram #(.addr_width(10),.data_width(8)) E7( + .clk(clk_sys), + .addr({ V[2:0], H[7:1] }), + .dout(E7_Q), + .ce(1'b0), + // .oe(SBBW ? 1'b0 : RD_n), // ? no difference? + .oe(1'b0), + .we(~nBRWR), + // .we(SBBW ? 1'b0 : ~nBRWR), // break test mode + .waddr(addr[9:0]), + .wdata(cpu_dout[7:0]), + .doutb(E7_doutb) +); + +assign E8_Ao = ~nBRSEL & ~RD_n ? E7_doutb : 8'd0; + +dpram #(.addr_width(10),.data_width(8)) E10_11( + .clk(clk_sys), + .addr({ VV[7:3], HH[7:3] }), + .ce(1'b0), + .oe(nVHBLANK), + .dout(E10_11_Q), + .we(SBBW ? ~nH0: 1'b0), // fix rolling cube + .waddr({ V[2:0], H[7:1] }), + .wdata(E7_Q) +); + +reg [8:0] BGRAM_LATCH; +always @(posedge clk_sys) begin : D11L10 + if (cen_5) begin + if (HHx[1:0] == 2'b01) begin // rising edge of HHx[1] + BGRAM_LATCH <= { E10_11_Q[7:0], VV[2] }; + end + end +end + +wire BGA1 = ~HHx[2] ^ HH[1]; //F17_8 + +wire [12:0] E11_12_addr = {BGRAM_LATCH[8:0], VV[1:0], BGA1, ~HH[1]}; + +wire [7:0] BGRAMROM_Q; +wire [7:0] BGRAMROM_DO = nBOJRSEL1 ? 8'd0 : BGRAMROM_Q; + +// This can be either RAM or ROM. +dpram #(.addr_width(13),.data_width(8)) E11_12 ( + .clk(clk_sys), + .addr(E11_12_addr), + .dout(E11_12_Q), + .ce(1'b0), + //.ce(L10_Q1), + .oe(1'b0), + .we(rom_init ? rom_init_address < 18'h10000 : ~nBOJRWR), + .waddr(rom_init ? rom_init_address : addr[12:0]), + .wdata(rom_init ? rom_init_data : cpu_dout), + .doutb(BGRAMROM_Q) +); + +reg [7:0] LBV; +always @(posedge clk_sys) begin : G11 + if (cen_5) begin + if (HH[0]) LBV <= E11_12_Q|E13_Q; // falling edge of HH[0] + end +end + +wire [3:0] BACKVID = nHH0s ? LBV[7:4] : LBV[3:0]; + +//////////////////////// +// Final color output // +//////////////////////// + +wire J12_4 = ~(H11_5 | J12_10); +wire J12_10 = ~(H11_6 | FB_PRIORITY); +wire J12_13 = ~FB_PRIORITY; + +wire H11_5 = ~(|BACKVID|J12_13); +wire H11_6 = ~(|FOREVID); + +// fg/bg priority +always @(posedge clk_sys) begin : H12 + if (cen_10_p & CLK5) begin // falling edge of CLK5 + H12_Y <= J12_4 ? BACKVID : FOREVID; + end +end + +// G13, G14 & G15 are now dpram +wire F6_11 = nCOLSEL | WR_n; +wire J7_2 = ~F6_11; + +// H14 +wire H14_8 = ~(J7_2 & addr[0]); +wire H14_11 = ~(J7_2 & ~addr[0]); + +dpram #(.addr_width(4),.data_width(4)) G13( + .clk(clk_sys), + .addr(H12_Y), + .ce(1'b0), + .oe(1'b0), + .we(~H14_8), + .waddr(addr[4:1]), + .wdata(cpu_dout[3:0]), + .dout(G13_Q) +); + +dpram #(.addr_width(4),.data_width(4)) G14( + .clk(clk_sys), + .addr(H12_Y), + .ce(1'b0), + .oe(1'b0), + .we(~H14_11), + .waddr(addr[4:1]), + .wdata(cpu_dout[3:0]), + .dout(G14_Q) +); + +dpram #(.addr_width(4),.data_width(4)) G15( + .clk(clk_sys), + .addr(H12_Y), + .ce(1'b0), + .oe(1'b0), + .we(~H14_11), + .waddr(addr[4:1]), + .wdata(cpu_dout[7:4]), + .dout(G15_Q) +); + +//////////////////////////// +// Ready logic // +//////////////////////////// + +// J8 +wire J8_6 = J8_11 | nBRSEL; +wire J8_11 = V[3] | nVBLANK; + +// K13 +wire K13_6 = J13_Q1 | nFRSEL; + +// J9 +wire J9_8 = K13_6 & J8_6; + +assign RDY1 = J9_8; + +endmodule diff --git a/Arcade_MiST/Gottlieb Qbert/rtl/pll.qip b/Arcade_MiST/Gottlieb Qbert/rtl/pll.qip new file mode 100644 index 00000000..afd958be --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/rtl/pll.qip @@ -0,0 +1,4 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"] diff --git a/Arcade_MiST/Gottlieb Qbert/rtl/pll.v b/Arcade_MiST/Gottlieb Qbert/rtl/pll.v new file mode 100644 index 00000000..e074cf45 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/rtl/pll.v @@ -0,0 +1,348 @@ +// megafunction wizard: %ALTPLL% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altpll + +// ============================================================ +// File Name: pll.v +// Megafunction Name(s): +// altpll +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.4 Build 182 03/12/2014 SJ Web Edition +// ************************************************************ + + +//Copyright (C) 1991-2014 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 pll ( + areset, + inclk0, + c0, + c1, + locked); + + input areset; + input inclk0; + output c0; + output c1; + output locked; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri0 areset; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [4:0] sub_wire0; + wire sub_wire2; + wire [0:0] sub_wire6 = 1'h0; + wire [0:0] sub_wire3 = sub_wire0[0:0]; + wire [1:1] sub_wire1 = sub_wire0[1:1]; + wire c1 = sub_wire1; + wire locked = sub_wire2; + wire c0 = sub_wire3; + wire sub_wire4 = inclk0; + wire [1:0] sub_wire5 = {sub_wire6, sub_wire4}; + + altpll altpll_component ( + .areset (areset), + .inclk (sub_wire5), + .clk (sub_wire0), + .locked (sub_wire2), + .activeclock (), + .clkbad (), + .clkena ({6{1'b1}}), + .clkloss (), + .clkswitch (1'b0), + .configupdate (1'b0), + .enable0 (), + .enable1 (), + .extclk (), + .extclkena ({4{1'b1}}), + .fbin (1'b1), + .fbmimicbidir (), + .fbout (), + .fref (), + .icdrclk (), + .pfdena (1'b1), + .phasecounterselect ({4{1'b1}}), + .phasedone (), + .phasestep (1'b1), + .phaseupdown (1'b1), + .pllena (1'b1), + .scanaclr (1'b0), + .scanclk (1'b0), + .scanclkena (1'b1), + .scandata (1'b0), + .scandataout (), + .scandone (), + .scanread (1'b0), + .scanwrite (1'b0), + .sclkout0 (), + .sclkout1 (), + .vcooverrange (), + .vcounderrange ()); + defparam + altpll_component.bandwidth_type = "AUTO", + altpll_component.clk0_divide_by = 27, + altpll_component.clk0_duty_cycle = 50, + altpll_component.clk0_multiply_by = 80, + altpll_component.clk0_phase_shift = "0", + altpll_component.clk1_divide_by = 27, + altpll_component.clk1_duty_cycle = 50, + altpll_component.clk1_multiply_by = 40, + altpll_component.clk1_phase_shift = "0", + altpll_component.compensate_clock = "CLK0", + altpll_component.inclk0_input_frequency = 37037, + altpll_component.intended_device_family = "Cyclone III", + altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll", + altpll_component.lpm_type = "altpll", + altpll_component.operation_mode = "NORMAL", + altpll_component.pll_type = "AUTO", + altpll_component.port_activeclock = "PORT_UNUSED", + altpll_component.port_areset = "PORT_USED", + altpll_component.port_clkbad0 = "PORT_UNUSED", + altpll_component.port_clkbad1 = "PORT_UNUSED", + altpll_component.port_clkloss = "PORT_UNUSED", + altpll_component.port_clkswitch = "PORT_UNUSED", + altpll_component.port_configupdate = "PORT_UNUSED", + altpll_component.port_fbin = "PORT_UNUSED", + altpll_component.port_inclk0 = "PORT_USED", + altpll_component.port_inclk1 = "PORT_UNUSED", + altpll_component.port_locked = "PORT_USED", + altpll_component.port_pfdena = "PORT_UNUSED", + altpll_component.port_phasecounterselect = "PORT_UNUSED", + altpll_component.port_phasedone = "PORT_UNUSED", + altpll_component.port_phasestep = "PORT_UNUSED", + altpll_component.port_phaseupdown = "PORT_UNUSED", + altpll_component.port_pllena = "PORT_UNUSED", + altpll_component.port_scanaclr = "PORT_UNUSED", + altpll_component.port_scanclk = "PORT_UNUSED", + altpll_component.port_scanclkena = "PORT_UNUSED", + altpll_component.port_scandata = "PORT_UNUSED", + altpll_component.port_scandataout = "PORT_UNUSED", + altpll_component.port_scandone = "PORT_UNUSED", + altpll_component.port_scanread = "PORT_UNUSED", + altpll_component.port_scanwrite = "PORT_UNUSED", + altpll_component.port_clk0 = "PORT_USED", + altpll_component.port_clk1 = "PORT_USED", + altpll_component.port_clk2 = "PORT_UNUSED", + altpll_component.port_clk3 = "PORT_UNUSED", + altpll_component.port_clk4 = "PORT_UNUSED", + altpll_component.port_clk5 = "PORT_UNUSED", + altpll_component.port_clkena0 = "PORT_UNUSED", + altpll_component.port_clkena1 = "PORT_UNUSED", + altpll_component.port_clkena2 = "PORT_UNUSED", + altpll_component.port_clkena3 = "PORT_UNUSED", + altpll_component.port_clkena4 = "PORT_UNUSED", + altpll_component.port_clkena5 = "PORT_UNUSED", + altpll_component.port_extclk0 = "PORT_UNUSED", + altpll_component.port_extclk1 = "PORT_UNUSED", + altpll_component.port_extclk2 = "PORT_UNUSED", + altpll_component.port_extclk3 = "PORT_UNUSED", + altpll_component.self_reset_on_loss_lock = "OFF", + altpll_component.width_clock = 5; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" +// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "105" +// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "105" +// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "80.000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "40.000000" +// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0" +// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" +// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000" +// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1" +// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps" +// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0" +// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "382" +// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "191" +// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "80.00000000" +// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "40.00000000" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz" +// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg" +// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1" +// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif" +// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0" +// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" +// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" +// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" +// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500" +// Retrieval info: PRIVATE: SPREAD_USE STRING "0" +// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" +// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1" +// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" +// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_CLK0 STRING "1" +// Retrieval info: PRIVATE: USE_CLK1 STRING "1" +// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0" +// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0" +// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "27" +// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "80" +// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "27" +// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "40" +// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF" +// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset" +// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1" +// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" +// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1 +// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf +// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/Arcade_MiST/Gottlieb Qbert/rtl/ram.v b/Arcade_MiST/Gottlieb Qbert/rtl/ram.v new file mode 100644 index 00000000..35902771 --- /dev/null +++ b/Arcade_MiST/Gottlieb Qbert/rtl/ram.v @@ -0,0 +1,29 @@ + +module ram +#( + parameter addr_width=16, + parameter data_width=8 +) +( + input clk, + input [data_width-1:0] din, + input [addr_width-1:0] addr, + input cs, + input oe, + input wr, + output [data_width-1:0] Q +); + +assign Q = ~oe & ~cs ? dout : {data_width{1'b0}}; + +reg [data_width-1:0] memory[(1< +// Copyright (c) 2019 Gyorgy Szombathelyi +// +// 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 . +// + +module sdram ( + + // interface to the MT48LC16M16 chip + inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus + output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus + output reg SDRAM_DQML, // two byte masks + output reg SDRAM_DQMH, // two byte masks + output reg [1:0] SDRAM_BA, // two banks + output SDRAM_nCS, // a single chip select + output SDRAM_nWE, // write enable + output SDRAM_nRAS, // row address select + output SDRAM_nCAS, // columns address select + + // cpu/chipset interface + input init_n, // init signal after FPGA config to initialize RAM + input clk, // sdram clock + + input port1_req, + output reg port1_ack, + input port1_we, + input [23:1] port1_a, + input [1:0] port1_ds, + input [15:0] port1_d, + output reg [15:0] port1_q, + + input [16:1] cpu1_addr, + output reg [15:0] cpu1_q, + input [16:1] cpu2_addr, + output reg [15:0] cpu2_q, + + input port2_req, + output reg port2_ack, + input port2_we, + input [23:1] port2_a, + input [1:0] port2_ds, + input [15:0] port2_d, + output reg [31:0] port2_q, + + input [16:2] sp_addr, + output reg [31:0] sp_q +); +parameter MHZ = 80; // 80 MHz default clock, adjust to calculate the refresh rate correctly + +localparam RASCAS_DELAY = 3'd2; // tRCD=20ns -> 2 cycles@<100MHz +localparam BURST_LENGTH = 3'b001; // 000=1, 001=2, 010=4, 011=8 +localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved +localparam CAS_LATENCY = 3'd2; // 2/3 allowed +localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed +localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write + +localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; + +// 64ms/8192 rows = 7.8us -> 842 cycles@108MHz +localparam RFRSH_CYCLES = 16'd78*MHZ/10; + +// --------------------------------------------------------------------- +// ------------------------ cycle state machine ------------------------ +// --------------------------------------------------------------------- + +/* + SDRAM state machine for 2 bank interleaved access + 1 word burst, CL2 +cmd issued registered + 0 RAS0 cas1 - data0 read burst terminated + 1 ras0 + 2 data1 returned + 3 CAS0 data1 returned + 4 RAS1 cas0 + 5 ras1 + 6 CAS1 data0 returned +*/ + +localparam STATE_RAS0 = 3'd0; // first state in cycle +localparam STATE_RAS1 = 3'd4; // Second ACTIVE command after RAS0 + tRRD (15ns) +localparam STATE_CAS0 = STATE_RAS0 + RASCAS_DELAY + 1'd1; // CAS phase - 3 +localparam STATE_CAS1 = STATE_RAS1 + RASCAS_DELAY; // CAS phase - 6 +localparam STATE_READ0 = 3'd0;// STATE_CAS0 + CAS_LATENCY + 2'd2; // 7 +localparam STATE_READ1 = 3'd3; +localparam STATE_DS1b = 3'd0; +localparam STATE_READ1b = 3'd4; +localparam STATE_LAST = 3'd6; + +reg [2:0] t; + +always @(posedge clk) begin + t <= t + 1'd1; + if (t == STATE_LAST) t <= STATE_RAS0; +end + +// --------------------------------------------------------------------- +// --------------------------- startup/reset --------------------------- +// --------------------------------------------------------------------- + +// wait 1ms (32 8Mhz cycles) after FPGA config is done before going +// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0) +reg [4:0] reset; +reg init = 1'b1; +always @(posedge clk, negedge init_n) begin + if(!init_n) begin + reset <= 5'h1f; + init <= 1'b1; + end else begin + if((t == STATE_LAST) && (reset != 0)) reset <= reset - 5'd1; + init <= !(reset == 0); + end +end + +// --------------------------------------------------------------------- +// ------------------ generate ram control signals --------------------- +// --------------------------------------------------------------------- + +// all possible commands +localparam CMD_INHIBIT = 4'b1111; +localparam CMD_NOP = 4'b0111; +localparam CMD_ACTIVE = 4'b0011; +localparam CMD_READ = 4'b0101; +localparam CMD_WRITE = 4'b0100; +localparam CMD_BURST_TERMINATE = 4'b0110; +localparam CMD_PRECHARGE = 4'b0010; +localparam CMD_AUTO_REFRESH = 4'b0001; +localparam CMD_LOAD_MODE = 4'b0000; + +reg [3:0] sd_cmd; // current command sent to sd ram +reg [15:0] sd_din; +// drive control signals according to current command +assign SDRAM_nCS = sd_cmd[3]; +assign SDRAM_nRAS = sd_cmd[2]; +assign SDRAM_nCAS = sd_cmd[1]; +assign SDRAM_nWE = sd_cmd[0]; + +reg [24:1] addr_latch[2]; +reg [24:1] addr_latch_next[2]; +reg [16:1] addr_last[2]; +reg [16:2] addr_last2[2]; +reg [15:0] din_latch[2]; +reg [1:0] oe_latch; +reg [1:0] we_latch; +reg [1:0] ds[2]; + +reg port1_state; +reg port2_state; + +localparam PORT_NONE = 2'd0; +localparam PORT_CPU1 = 2'd1; +localparam PORT_CPU2 = 2'd2; +localparam PORT_SP = 2'd1; +localparam PORT_REQ = 2'd3; + +reg [1:0] next_port[2]; +reg [1:0] port[2]; + +reg refresh; +reg [10:0] refresh_cnt; +wire need_refresh = (refresh_cnt >= RFRSH_CYCLES); + +// PORT1: bank 0,1 +always @(*) begin + if (refresh) begin + next_port[0] = PORT_NONE; + addr_latch_next[0] = addr_latch[0]; + end else if (port1_req ^ port1_state) begin + next_port[0] = PORT_REQ; + addr_latch_next[0] = { 1'b0, port1_a }; + end else if (cpu1_addr != addr_last[PORT_CPU1]) begin + next_port[0] = PORT_CPU1; + addr_latch_next[0] = { 8'd0, cpu1_addr }; + end else if (cpu2_addr != addr_last[PORT_CPU2]) begin + next_port[0] = PORT_CPU2; + addr_latch_next[0] = { 8'd0, cpu2_addr }; + end else begin + next_port[0] = PORT_NONE; + addr_latch_next[0] = addr_latch[0]; + end +end + +// PORT1: bank 2,3 +always @(*) begin + if (port2_req ^ port2_state) begin + next_port[1] = PORT_REQ; + addr_latch_next[1] = { 1'b1, port2_a }; + end else if (sp_addr != addr_last2[PORT_SP]) begin + next_port[1] = PORT_SP; + addr_latch_next[1] = { 1'b1, 7'd0, sp_addr, 1'b0 }; + end else begin + next_port[1] = PORT_NONE; + addr_latch_next[1] = addr_latch[1]; + end +end + +always @(posedge clk) begin + + // permanently latch ram data to reduce delays + sd_din <= SDRAM_DQ; + SDRAM_DQ <= 16'bZZZZZZZZZZZZZZZZ; + { SDRAM_DQMH, SDRAM_DQML } <= 2'b11; + sd_cmd <= CMD_NOP; // default: idle + refresh_cnt <= refresh_cnt + 1'd1; + + if(init) begin + // initialization takes place at the end of the reset phase + if(t == STATE_RAS0) begin + + if(reset == 15) begin + sd_cmd <= CMD_PRECHARGE; + SDRAM_A[10] <= 1'b1; // precharge all banks + end + + if(reset == 10 || reset == 8) begin + sd_cmd <= CMD_AUTO_REFRESH; + end + + if(reset == 2) begin + sd_cmd <= CMD_LOAD_MODE; + SDRAM_A <= MODE; + SDRAM_BA <= 2'b00; + end + end + end else begin + // RAS phase + // bank 0,1 + if(t == STATE_RAS0) begin + addr_latch[0] <= addr_latch_next[0]; + port[0] <= next_port[0]; + { oe_latch[0], we_latch[0] } <= 2'b00; + + if (next_port[0] != PORT_NONE) begin + sd_cmd <= CMD_ACTIVE; + SDRAM_A <= addr_latch_next[0][22:10]; + SDRAM_BA <= addr_latch_next[0][24:23]; + addr_last[next_port[0]] <= addr_latch_next[0][16:1]; + if (next_port[0] == PORT_REQ) begin + { oe_latch[0], we_latch[0] } <= { ~port1_we, port1_we }; + ds[0] <= port1_ds; + din_latch[0] <= port1_d; + port1_state <= port1_req; + end else begin + { oe_latch[0], we_latch[0] } <= 2'b10; + ds[0] <= 2'b11; + end + end + end + + // bank 2,3 + if(t == STATE_RAS1) begin + refresh <= 1'b0; + addr_latch[1] <= addr_latch_next[1]; + { oe_latch[1], we_latch[1] } <= 2'b00; + port[1] <= next_port[1]; + + if (next_port[1] != PORT_NONE) begin + sd_cmd <= CMD_ACTIVE; + SDRAM_A <= addr_latch_next[1][22:10]; + SDRAM_BA <= addr_latch_next[1][24:23]; + addr_last2[next_port[1]] <= addr_latch_next[1][16:2]; + if (next_port[1] == PORT_REQ) begin + { oe_latch[1], we_latch[1] } <= { ~port1_we, port1_we }; + ds[1] <= port2_ds; + din_latch[1] <= port2_d; + port2_state <= port2_req; + end else begin + { oe_latch[1], we_latch[1] } <= 2'b10; + ds[1] <= 2'b11; + end + end + + if (next_port[1] == PORT_NONE && need_refresh && !we_latch[0] && !oe_latch[0]) begin + refresh <= 1'b1; + refresh_cnt <= 0; + sd_cmd <= CMD_AUTO_REFRESH; + end + end + + // CAS phase + if(t == STATE_CAS0 && (we_latch[0] || oe_latch[0])) begin + sd_cmd <= we_latch[0]?CMD_WRITE:CMD_READ; + { SDRAM_DQMH, SDRAM_DQML } <= ~ds[0]; + if (we_latch[0]) begin + SDRAM_DQ <= din_latch[0]; + port1_ack <= port1_req; + end + SDRAM_A <= { 4'b0010, addr_latch[0][9:1] }; // auto precharge + SDRAM_BA <= addr_latch[0][24:23]; + end + + if(t == STATE_CAS1 && (we_latch[1] || oe_latch[1])) begin + sd_cmd <= we_latch[1]?CMD_WRITE:CMD_READ; + { SDRAM_DQMH, SDRAM_DQML } <= ~ds[1]; + if (we_latch[1]) begin + SDRAM_DQ <= din_latch[1]; + port2_ack <= port2_req; + end + SDRAM_A <= { 4'b0010, addr_latch[1][9:1] }; // auto precharge + SDRAM_BA <= addr_latch[1][24:23]; + end + + // Data returned + if(t == STATE_READ0 && oe_latch[0]) begin + case(port[0]) + PORT_REQ: begin port1_q <= sd_din; port1_ack <= port1_req; end + PORT_CPU1: begin cpu1_q <= sd_din; end + PORT_CPU2: begin cpu2_q <= sd_din; end + default: ; + endcase; + end + + if(t == STATE_READ1 && oe_latch[1]) begin + case(port[1]) + PORT_REQ: port2_q[15:0] <= sd_din; + PORT_SP : sp_q[15:0] <= sd_din; + default: ; + endcase; + end + + if(t == STATE_DS1b && oe_latch[1]) { SDRAM_DQMH, SDRAM_DQML } <= ~ds[1]; + + if(t == STATE_READ1b && oe_latch[1]) begin + case(port[1]) + PORT_REQ: begin port2_q[31:16] <= sd_din; port2_ack <= port2_req; end + PORT_SP : begin sp_q[31:16] <= sd_din; end + default: ; + endcase; + end + end +end + +endmodule