mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-27 04:12:10 +00:00
Gyruss: a quick port
This commit is contained in:
31
Arcade_MiST/Konami Gyruss/Gyruss.qpf
Normal file
31
Arcade_MiST/Konami Gyruss/Gyruss.qpf
Normal file
@@ -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 = "Gyruss"
|
||||
|
||||
253
Arcade_MiST/Konami Gyruss/Gyruss.qsf
Normal file
253
Arcade_MiST/Konami Gyruss/Gyruss.qsf
Normal file
@@ -0,0 +1,253 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# 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:
|
||||
# Gyruss_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 SP4.26"
|
||||
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 Gyruss_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/sndcpu.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(Gyruss_MiST)
|
||||
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
|
||||
# Fitter Assignments
|
||||
# ==================
|
||||
|
||||
# start DESIGN_PARTITION(Top)
|
||||
# ---------------------------
|
||||
|
||||
# Incremental Compilation Assignments
|
||||
# ===================================
|
||||
|
||||
# end DESIGN_PARTITION(Top)
|
||||
# -------------------------
|
||||
|
||||
# end ENTITY(Gyruss_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 SYSTEMVERILOG_FILE rtl/Gyruss_MiST.sv
|
||||
set_global_assignment -name QIP_FILE rtl/pll.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Gyruss.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/jtframe_frac_cen.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/jt49_dcrm2.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/hiscore.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Gyruss_SND.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Gyruss_CPU.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/Filters/gyruss_lpf.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/Filters/gyruss_lpf_medium.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/Filters/gyruss_lpf_light.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/Filters/gyruss_lpf_heavy.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/Filters/audio_iir_filter.v
|
||||
set_global_assignment -name QIP_FILE rtl/custom/gyruss_custom.qip
|
||||
set_global_assignment -name VHDL_FILE rtl/ram_rom/spram.vhd
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/ram_rom/rom_loader.sv
|
||||
set_global_assignment -name QIP_FILE rtl/ram_rom/gyruss_ram_rom.qip
|
||||
set_global_assignment -name VHDL_FILE rtl/ram_rom/dpram_dc.vhd
|
||||
set_global_assignment -name QIP_FILE ../../common/mist/mist.qip
|
||||
set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip
|
||||
set_global_assignment -name QIP_FILE ../../common/CPU/t48/i8039.qip
|
||||
set_global_assignment -name QIP_FILE ../../common/Sound/JT49/jt49.qip
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/sndcpu.stp
|
||||
set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
136
Arcade_MiST/Konami Gyruss/Gyruss.sdc
Normal file
136
Arcade_MiST/Konami Gyruss/Gyruss.sdc
Normal file
@@ -0,0 +1,136 @@
|
||||
## 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 sys_clk "pll|altpll_component|auto_generated|pll1|clk[0]"
|
||||
set sdram_clk "pll|altpll_component|auto_generated|pll1|clk[0]"
|
||||
set aud_clk "pll|altpll_component|auto_generated|pll1|clk[0]"
|
||||
#**************************************************************
|
||||
# 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 $aud_clk] 1.000 [get_ports {AUDIO_L}]
|
||||
set_output_delay -clock [get_clocks $aud_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_clock_groups -asynchronous -group [get_clocks $sys_clk] -group [get_clocks $aud_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
|
||||
#**************************************************************
|
||||
|
||||
11
Arcade_MiST/Konami Gyruss/README.md
Normal file
11
Arcade_MiST/Konami Gyruss/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# MiST port of Konami Gyruss by ACE
|
||||
|
||||
https://github.com/MiSTer-devel/Arcade-Gyruss_MiSTer
|
||||
|
||||
## Usage
|
||||
|
||||
- Create ROM and ARC files from the MRA files using the MRA utility.
|
||||
Example: mra -A -z /path/to/mame/roms "Gyruss.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/
|
||||
75
Arcade_MiST/Konami Gyruss/meta/Gyruss.mra
Normal file
75
Arcade_MiST/Konami Gyruss/meta/Gyruss.mra
Normal file
@@ -0,0 +1,75 @@
|
||||
<misterromdescription>
|
||||
<name>Gyruss</name>
|
||||
<region></region>
|
||||
<homebrew>no</homebrew>
|
||||
<bootleg>no</bootleg>
|
||||
<version></version>
|
||||
<alternative></alternative>
|
||||
<platform></platform>
|
||||
<series></series>
|
||||
<year>1983</year>
|
||||
<manufacturer>Konami</manufacturer>
|
||||
<category>Shooter - Tube</category>
|
||||
|
||||
<setname>gyruss</setname>
|
||||
<parent>gyruss</parent>
|
||||
<mameversion>0218</mameversion>
|
||||
<rbf>Gyruss</rbf>
|
||||
<about author="MrX-8B" source="https://github.com/MrX-8B/MiSTer-Arcade-Gyruss" twitter="@MrX_8B" webpage="https://patreon.com/MrX_8B"></about>
|
||||
<about author="Ace" twitter="@Ace9921Tweets"></about>
|
||||
|
||||
<resolution>15kHz</resolution>
|
||||
<rotation>vertical (cw)</rotation>
|
||||
<flip>no</flip>
|
||||
|
||||
<players>2 (alternating)</players>
|
||||
<joystick>4-way</joystick>
|
||||
<special_controls></special_controls>
|
||||
<num_buttons>1</num_buttons>
|
||||
<buttons default="B,Start,R,Select,L" names="Fire,Start P1,Coin,Start P2,Pause"></buttons>
|
||||
|
||||
<switches default="00,34,00" base="8" page_id="1" page_name="Switches">
|
||||
<dip bits="0,3" name="Credits A" ids="1c/1cr,1c/2cr,1c/3cr,1c/4cr,1c/5cr,1c/7cr,1c/6cr,2c/1cr,2c/3cr,3c/1cr,2c/5cr,3c/2cr,3c/4cr,4c/3cr,4c/1cr,Free Play"/>
|
||||
<dip bits="4,7" name="Credits B" ids="1c/1cr,1c/2cr,1c/3cr,1c/4cr,1c/5cr,1c/6cr,1c/7cr,2c/1cr,2c/3cr,2c/5cr,3c/1cr,3c/2cr,3c/4cr,4c/1cr,4c/3cr,Free Play"/>
|
||||
<dip bits="8,9" name="Lives" ids="3,4,5,255 (Cheat)"/>
|
||||
<dip bits="10" name="Cabinet type" ids="Cocktail,Upright"/>
|
||||
<dip bits="11" name="Bonus" ids="30K/90K/60K+,40K/110K/70K+"/>
|
||||
<dip bits="12,14" name="Difficulty" ids="1 (Easiest),2,3,4,5,6,7,8 (Hardest)"/>
|
||||
<dip bits="15" name="Attract mode sound" ids="Off,On"/>
|
||||
<dip bits="16" name="Attract mode music" ids="Off,On"/>
|
||||
</switches>
|
||||
|
||||
<rom index="1"></rom>
|
||||
<rom index="0" md5="none" type="merged" zip="gyruss.zip">
|
||||
<part crc="c673b43d" name="gyrussk.1"></part>
|
||||
<part crc="a4ec03e4" name="gyrussk.2"></part>
|
||||
<part crc="27454a98" name="gyrussk.3"></part>
|
||||
<part crc="822bF27e" name="gyrussk.9"></part>
|
||||
<part crc="27d8329b" name="gyrussk.4"></part>
|
||||
<part crc="c949db10" name="gyrussk.6"></part>
|
||||
<part crc="4f22411a" name="gyrussk.5"></part>
|
||||
<part crc="47cd1fbc" name="gyrussk.8"></part>
|
||||
<part crc="8e8d388c" name="gyrussk.7"></part>
|
||||
<part crc="f4ae1c17" name="gyrussk.1a"></part>
|
||||
<part crc="ba498115" name="gyrussk.2a"></part>
|
||||
<part crc="3f9b5dea" name="gyrussk.3a"></part>
|
||||
<part crc="de823a81" name="gyrussk.pr2"></part>
|
||||
<part crc="7ed057de" name="gyrussk.pr1"></part>
|
||||
<part crc="98782db3" name="gyrussk.pr3"></part>
|
||||
</rom>
|
||||
<rom index="2"></rom>
|
||||
<rom index="3" md5="none">
|
||||
<part>
|
||||
01 00 00 00 00 FF 00 02 00 02 00 01 00 FF 00 00
|
||||
00 00 94 88 00 28 00 83
|
||||
00 00 94 0B 00 03 00 01
|
||||
</part>
|
||||
</rom>
|
||||
<rom index="4"></rom>
|
||||
|
||||
<nvram index="4" size="43"/>
|
||||
|
||||
<remark></remark>
|
||||
|
||||
<mratimestamp>20210430005030</mratimestamp>
|
||||
</misterromdescription>
|
||||
173
Arcade_MiST/Konami Gyruss/rtl/Filters/audio_iir_filter.v
Normal file
173
Arcade_MiST/Konami Gyruss/rtl/Filters/audio_iir_filter.v
Normal file
@@ -0,0 +1,173 @@
|
||||
/*MIT License
|
||||
|
||||
Copyright (c) 2019 Gregory Hogan (Soltan_G42)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software 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 Software.
|
||||
|
||||
THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.*/
|
||||
|
||||
module iir_1st_order
|
||||
#(
|
||||
parameter COEFF_WIDTH = 18,
|
||||
parameter COEFF_SCALE = 15,
|
||||
parameter DATA_WIDTH = 16,
|
||||
parameter COUNT_BITS = 10
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input reset,
|
||||
input [COUNT_BITS - 1 : 0] div,
|
||||
input signed [COEFF_WIDTH - 1 : 0] A2, B1, B2,
|
||||
input signed [DATA_WIDTH - 1 :0] in,
|
||||
output [DATA_WIDTH - 1:0] out
|
||||
);
|
||||
|
||||
reg signed [DATA_WIDTH-1:0] x0,x1,y0;
|
||||
reg signed [DATA_WIDTH + COEFF_WIDTH - 1 : 0] out32;
|
||||
reg [COUNT_BITS - 1:0] count;
|
||||
|
||||
// Usage:
|
||||
// Design your 1st order iir low/high-pass with a tool that will give you the
|
||||
// filter coefficients for the difference equation. Filter coefficients can
|
||||
// be generated in Octave/matlab/scipy using a command similar to
|
||||
// [B, A] = butter( 1, 3500/(106528/2), 'low') for a 3500 hz 1st order low-pass
|
||||
// assuming 106528Hz sample rate.
|
||||
//
|
||||
// The Matlab output is:
|
||||
// B = [0.093863 0.093863]
|
||||
// A = [1.00000 -0.81227]
|
||||
//
|
||||
// Then scale coefficients by multiplying by 2^COEFF_SCALE and round to nearest integer
|
||||
//
|
||||
// B = [3076 3076]
|
||||
// A = [32768 -26616]
|
||||
//
|
||||
// Discard A(1) because it is assumed 1.0 before scaling
|
||||
//
|
||||
// This leaves you with A2 = -26616 , B1 = 3076 , B2 = 3076
|
||||
// B1 + B2 - A2 should sum to 2^COEFF_SCALE = 32768
|
||||
//
|
||||
// Sample frequency is "clk rate/div": for Genesis this is 53.69mhz/504 = 106528hz
|
||||
//
|
||||
// COEFF_WIDTH must be at least COEFF_SCALE+1 and must be large enough to
|
||||
// handle temporary overflow during this computation: out32 <= (B1*x0 + B2*x1) - A2*y0
|
||||
|
||||
assign out = y0;
|
||||
|
||||
always @ (*) begin
|
||||
out32 <= (B1*x0 + B2*x1) - A2*y0; //Previous output is y0 not y1
|
||||
end
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if(reset) begin
|
||||
count <= 0;
|
||||
x0 <= 0;
|
||||
x1 <= 0;
|
||||
y0 <= 0;
|
||||
end
|
||||
else begin
|
||||
count <= count + 1'd1;
|
||||
if (count == div - 1) begin
|
||||
count <= 0;
|
||||
y0 <= {out32[DATA_WIDTH + COEFF_WIDTH - 1] , out32[COEFF_SCALE + DATA_WIDTH - 2 : COEFF_SCALE]};
|
||||
x1 <= x0;
|
||||
x0 <= in;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule //iir_1st_order
|
||||
|
||||
module iir_2nd_order
|
||||
#(
|
||||
parameter COEFF_WIDTH = 18,
|
||||
parameter COEFF_SCALE = 14,
|
||||
parameter DATA_WIDTH = 16,
|
||||
parameter COUNT_BITS = 10
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input reset,
|
||||
input [COUNT_BITS - 1 : 0] div,
|
||||
input signed [COEFF_WIDTH - 1 : 0] A2, A3, B1, B2, B3,
|
||||
input signed [DATA_WIDTH - 1 : 0] in,
|
||||
output [DATA_WIDTH - 1 : 0] out
|
||||
);
|
||||
|
||||
reg signed [DATA_WIDTH-1 : 0] x0,x1,x2;
|
||||
reg signed [DATA_WIDTH-1 : 0] y0,y1;
|
||||
reg signed [(DATA_WIDTH + COEFF_WIDTH - 1) : 0] out32;
|
||||
reg [COUNT_BITS : 0] count;
|
||||
|
||||
|
||||
// Usage:
|
||||
// Design your 1st order iir low/high-pass with a tool that will give you the
|
||||
// filter coefficients for the difference equation. Filter coefficients can
|
||||
// be generated in Octave/matlab/scipy using a command similar to
|
||||
// [B, A] = butter( 2, 5000/(48000/2), 'low') for a 5000 hz 2nd order low-pass
|
||||
// assuming 48000Hz sample rate.
|
||||
//
|
||||
// Output is:
|
||||
// B = [ 0.072231 0.144462 0.072231]
|
||||
// A = [1.00000 -1.10923 0.39815]
|
||||
//
|
||||
// Then scale coefficients by multiplying by 2^COEFF_SCALE and round to nearest integer
|
||||
// Make sure your coefficients can be stored as a signed number with COEFF_WIDTH bits.
|
||||
//
|
||||
// B = [1183 2367 1183]
|
||||
// A = [16384 -18174 6523]
|
||||
//
|
||||
// Discard A(1) because it is assumed 1.0 before scaling
|
||||
//
|
||||
// This leaves you with A2 = -18174 , A3 = 6523, B1 = 1183 , B2 = 2367 , B3 = 1183
|
||||
// B1 + B2 + B3 - A2 - A3 should sum to 2^COEFF_SCALE = 16384
|
||||
//
|
||||
// Sample frequency is "clk rate/div"
|
||||
//
|
||||
// COEFF_WIDTH must be at least COEFF_SCALE+1 and must be large enough to
|
||||
// handle temporary overflow during this computation:
|
||||
// out32 <= (B1*x0 + B2*x1 + B3*x2) - (A2*y0 + A3*y1);
|
||||
|
||||
assign out = y0;
|
||||
|
||||
always @ (*) begin
|
||||
out32 <= (B1*x0 + B2*x1 + B3*x2) - (A2*y0 + A3*y1); //Previous output is y0 not y1
|
||||
end
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if(reset) begin
|
||||
count <= 0;
|
||||
x0 <= 0;
|
||||
x1 <= 0;
|
||||
x2 <= 0;
|
||||
y0 <= 0;
|
||||
y1 <= 0;
|
||||
end
|
||||
else begin
|
||||
count <= count + 1'd1;
|
||||
if (count == div - 1) begin
|
||||
count <= 0;
|
||||
y1 <= y0;
|
||||
y0 <= {out32[DATA_WIDTH + COEFF_WIDTH - 1] , out32[(DATA_WIDTH + COEFF_SCALE - 2) : COEFF_SCALE]};
|
||||
x2 <= x1;
|
||||
x1 <= x0;
|
||||
x0 <= in;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule //iir_2nd_order
|
||||
60
Arcade_MiST/Konami Gyruss/rtl/Filters/gyruss_lpf.v
Normal file
60
Arcade_MiST/Konami Gyruss/rtl/Filters/gyruss_lpf.v
Normal file
@@ -0,0 +1,60 @@
|
||||
/*MIT License
|
||||
|
||||
Copyright (c) 2019 Gregory Hogan (Soltan_G42)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software 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 Software.
|
||||
THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.*/
|
||||
|
||||
//This is a variation of Gregory Hogan's MISTer Genesis core low-pass filter
|
||||
//tuned to remove aliasing on Gyruss.
|
||||
|
||||
module gyruss_lpf(
|
||||
input clk,
|
||||
input reset,
|
||||
input signed [15:0] in,
|
||||
output signed [15:0] out);
|
||||
|
||||
localparam div = 10'd220; //Sample at 49.152/220 = 223418Hz
|
||||
|
||||
//Coefficients computed with Octave/Matlab/Online filter calculators.
|
||||
//or with scipy.signal.bessel or similar tools
|
||||
|
||||
//0.045425748, 0.045425748
|
||||
//1.0000000, -0.90914850
|
||||
reg signed [17:0] A2;
|
||||
reg signed [17:0] B2;
|
||||
reg signed [17:0] B1;
|
||||
|
||||
wire signed [15:0] audio_post_lpf1;
|
||||
|
||||
always @ (*) begin
|
||||
A2 = -18'd18211;
|
||||
B1 = 18'd7278;
|
||||
B2 = 18'd7278;
|
||||
end
|
||||
|
||||
iir_1st_order lpf6db(.clk(clk),
|
||||
.reset(reset),
|
||||
.div(div),
|
||||
.A2(A2),
|
||||
.B1(B1),
|
||||
.B2(B2),
|
||||
.in(in),
|
||||
.out(audio_post_lpf1));
|
||||
|
||||
assign out = audio_post_lpf1;
|
||||
|
||||
endmodule
|
||||
60
Arcade_MiST/Konami Gyruss/rtl/Filters/gyruss_lpf_heavy.v
Normal file
60
Arcade_MiST/Konami Gyruss/rtl/Filters/gyruss_lpf_heavy.v
Normal file
@@ -0,0 +1,60 @@
|
||||
/*MIT License
|
||||
|
||||
Copyright (c) 2019 Gregory Hogan (Soltan_G42)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software 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 Software.
|
||||
THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.*/
|
||||
|
||||
//This is a variation of Gregory Hogan's MISTer Genesis core low-pass filter
|
||||
//tuned to match the heaviest low-pass filter on Gyruss.
|
||||
|
||||
module gyruss_lpf_heavy(
|
||||
input clk,
|
||||
input reset,
|
||||
input signed [15:0] in,
|
||||
output signed [15:0] out);
|
||||
|
||||
localparam div = 10'd220; //Sample at 49.152/220 = 223418Hz
|
||||
|
||||
//Coefficients computed with Octave/Matlab/Online filter calculators.
|
||||
//or with scipy.signal.bessel or similar tools
|
||||
|
||||
//0.0041276697, 0.0041276697
|
||||
//1.0000000, -0.99174466
|
||||
reg signed [17:0] A2;
|
||||
reg signed [17:0] B2;
|
||||
reg signed [17:0] B1;
|
||||
|
||||
wire signed [15:0] audio_post_lpf1;
|
||||
|
||||
always @ (*) begin
|
||||
A2 = -18'd32498;
|
||||
B1 = 18'd135;
|
||||
B2 = 18'd135;
|
||||
end
|
||||
|
||||
iir_1st_order lpf6db(.clk(clk),
|
||||
.reset(reset),
|
||||
.div(div),
|
||||
.A2(A2),
|
||||
.B1(B1),
|
||||
.B2(B2),
|
||||
.in(in),
|
||||
.out(audio_post_lpf1));
|
||||
|
||||
assign out = audio_post_lpf1;
|
||||
|
||||
endmodule
|
||||
60
Arcade_MiST/Konami Gyruss/rtl/Filters/gyruss_lpf_light.v
Normal file
60
Arcade_MiST/Konami Gyruss/rtl/Filters/gyruss_lpf_light.v
Normal file
@@ -0,0 +1,60 @@
|
||||
/*MIT License
|
||||
|
||||
Copyright (c) 2019 Gregory Hogan (Soltan_G42)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software 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 Software.
|
||||
THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.*/
|
||||
|
||||
//This is a variation of Gregory Hogan's MISTer Genesis core low-pass filter
|
||||
//tuned to match the lightest low-pass filter on Gyruss.
|
||||
|
||||
module gyruss_lpf_light(
|
||||
input clk,
|
||||
input reset,
|
||||
input signed [15:0] in,
|
||||
output signed [15:0] out);
|
||||
|
||||
localparam div = 10'd220; //Sample at 49.152/220 = 223418Hz
|
||||
|
||||
//Coefficients computed with Octave/Matlab/Online filter calculators.
|
||||
//or with scipy.signal.bessel or similar tools
|
||||
|
||||
//0.017174022, 0.017174022
|
||||
//1.0000000, -0.96565196
|
||||
reg signed [17:0] A2;
|
||||
reg signed [17:0] B2;
|
||||
reg signed [17:0] B1;
|
||||
|
||||
wire signed [15:0] audio_post_lpf1;
|
||||
|
||||
always @ (*) begin
|
||||
A2 = -18'd31642;
|
||||
B1 = 18'd563;
|
||||
B2 = 18'd563;
|
||||
end
|
||||
|
||||
iir_1st_order lpf6db(.clk(clk),
|
||||
.reset(reset),
|
||||
.div(div),
|
||||
.A2(A2),
|
||||
.B1(B1),
|
||||
.B2(B2),
|
||||
.in(in),
|
||||
.out(audio_post_lpf1));
|
||||
|
||||
assign out = audio_post_lpf1;
|
||||
|
||||
endmodule
|
||||
60
Arcade_MiST/Konami Gyruss/rtl/Filters/gyruss_lpf_medium.v
Normal file
60
Arcade_MiST/Konami Gyruss/rtl/Filters/gyruss_lpf_medium.v
Normal file
@@ -0,0 +1,60 @@
|
||||
/*MIT License
|
||||
|
||||
Copyright (c) 2019 Gregory Hogan (Soltan_G42)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software 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 Software.
|
||||
THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.*/
|
||||
|
||||
//This is a variation of Gregory Hogan's MISTer Genesis core low-pass filter
|
||||
//tuned to match the middle low-pass filter on Gyruss.
|
||||
|
||||
module gyruss_lpf_medium(
|
||||
input clk,
|
||||
input reset,
|
||||
input signed [15:0] in,
|
||||
output signed [15:0] out);
|
||||
|
||||
localparam div = 10'd220; //Sample at 49.152/220 = 223418Hz
|
||||
|
||||
//Coefficients computed with Octave/Matlab/Online filter calculators.
|
||||
//or with scipy.signal.bessel or similar tools
|
||||
|
||||
//0.0053024160, 0.0053024160
|
||||
//1.0000000, -0.98939517
|
||||
reg signed [17:0] A2;
|
||||
reg signed [17:0] B2;
|
||||
reg signed [17:0] B1;
|
||||
|
||||
wire signed [15:0] audio_post_lpf1;
|
||||
|
||||
always @ (*) begin
|
||||
A2 = -18'd32420;
|
||||
B1 = 18'd174;
|
||||
B2 = 18'd174;
|
||||
end
|
||||
|
||||
iir_1st_order lpf6db(.clk(clk),
|
||||
.reset(reset),
|
||||
.div(div),
|
||||
.A2(A2),
|
||||
.B1(B1),
|
||||
.B2(B2),
|
||||
.in(in),
|
||||
.out(audio_post_lpf1));
|
||||
|
||||
assign out = audio_post_lpf1;
|
||||
|
||||
endmodule
|
||||
192
Arcade_MiST/Konami Gyruss/rtl/Gyruss.sv
Normal file
192
Arcade_MiST/Konami Gyruss/rtl/Gyruss.sv
Normal file
@@ -0,0 +1,192 @@
|
||||
//============================================================================
|
||||
//
|
||||
// Gyruss top-level module
|
||||
// Copyright (C) 2021 Ace
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//Module declaration, I/O ports
|
||||
module Gyruss
|
||||
(
|
||||
input reset,
|
||||
input clk_49m, //Actual frequency: 49.152MHz
|
||||
input [1:0] coin, //0 = coin 1, 1 = coin 2
|
||||
input [1:0] start_buttons, //0 = Player 1, 1 = Player 2
|
||||
input [3:0] p1_joystick, p2_joystick, //0 = up, 1 = down, 2 = left, 3 = right
|
||||
input p1_fire,
|
||||
input p2_fire,
|
||||
input btn_service,
|
||||
input [23:0] dip_sw,
|
||||
output video_hsync, video_vsync, video_csync,
|
||||
output video_hblank, video_vblank,
|
||||
output ce_pix,
|
||||
output [2:0] video_r, video_g,
|
||||
output [1:0] video_b,
|
||||
output signed [15:0] sound_l, sound_r,
|
||||
|
||||
//Screen centering (alters HSync, VSync and VBlank timing in the Konami 082 to reposition the video output)
|
||||
input [3:0] h_center, v_center,
|
||||
|
||||
input [24:0] ioctl_addr,
|
||||
input [7:0] ioctl_data,
|
||||
input ioctl_wr,
|
||||
|
||||
input pause,
|
||||
|
||||
input [10:0] hs_address,
|
||||
input [7:0] hs_data_in,
|
||||
output [7:0] hs_data_out,
|
||||
input hs_write,
|
||||
input hs_access,
|
||||
|
||||
output [15:0] main_cpu_rom_addr,
|
||||
input [7:0] main_cpu_rom_do,
|
||||
output [12:0] sub_cpu_rom_addr,
|
||||
input [7:0] sub_cpu_rom_do,
|
||||
output [12:0] sp_rom_addr,
|
||||
input [31:0] sp_rom_do
|
||||
);
|
||||
|
||||
//Linking signals between PCBs
|
||||
wire A5, A6, irq_trigger, cs_sounddata, cs_controls_dip1, cs_dip2, cs_dip3;
|
||||
wire [7:0] controls_dip, cpubrd_D;
|
||||
|
||||
//ROM loader signals for MISTer (loads ROMs from SD card)
|
||||
wire ep1_cs_i, ep2_cs_i, ep3_cs_i, ep4_cs_i, ep5_cs_i, ep6_cs_i, ep7_cs_i, ep8_cs_i, ep9_cs_i,
|
||||
ep10_cs_i, ep11_cs_i, ep12_cs_i;
|
||||
wire cp_cs_i, tl_cs_i, sl_cs_i;
|
||||
|
||||
//MiSTer data write selector
|
||||
selector DLSEL
|
||||
(
|
||||
.ioctl_addr(ioctl_addr),
|
||||
.ep1_cs(ep1_cs_i),
|
||||
.ep2_cs(ep2_cs_i),
|
||||
.ep3_cs(ep3_cs_i),
|
||||
.ep4_cs(ep4_cs_i),
|
||||
.ep5_cs(ep5_cs_i),
|
||||
.ep6_cs(ep6_cs_i),
|
||||
.ep7_cs(ep7_cs_i),
|
||||
.ep8_cs(ep8_cs_i),
|
||||
.ep9_cs(ep9_cs_i),
|
||||
.ep10_cs(ep10_cs_i),
|
||||
.ep11_cs(ep11_cs_i),
|
||||
.ep12_cs(ep12_cs_i),
|
||||
.cp_cs(cp_cs_i),
|
||||
.tl_cs(tl_cs_i),
|
||||
.sl_cs(sl_cs_i)
|
||||
);
|
||||
|
||||
//Instantiate main PCB
|
||||
Gyruss_CPU main_pcb
|
||||
(
|
||||
.reset(reset),
|
||||
.clk_49m(clk_49m),
|
||||
.red(video_r),
|
||||
.green(video_g),
|
||||
.blue(video_b),
|
||||
.video_hsync(video_hsync),
|
||||
.video_vsync(video_vsync),
|
||||
.video_csync(video_csync),
|
||||
.video_hblank(video_hblank),
|
||||
.video_vblank(video_vblank),
|
||||
.ce_pix(ce_pix),
|
||||
|
||||
.h_center(h_center),
|
||||
.v_center(v_center),
|
||||
|
||||
.controls_dip(controls_dip),
|
||||
.cpubrd_Dout(cpubrd_D),
|
||||
.cpubrd_A5(A5),
|
||||
.cpubrd_A6(A6),
|
||||
.cs_sounddata(cs_sounddata),
|
||||
.irq_trigger(irq_trigger),
|
||||
.cs_dip2(cs_dip2),
|
||||
.cs_dip3(cs_dip3),
|
||||
.cs_controls_dip1(cs_controls_dip1),
|
||||
|
||||
.ep1_cs_i(ep1_cs_i),
|
||||
.ep2_cs_i(ep2_cs_i),
|
||||
.ep3_cs_i(ep3_cs_i),
|
||||
.ep4_cs_i(ep4_cs_i),
|
||||
.ep5_cs_i(ep5_cs_i),
|
||||
.ep6_cs_i(ep6_cs_i),
|
||||
.ep7_cs_i(ep7_cs_i),
|
||||
.ep8_cs_i(ep8_cs_i),
|
||||
.ep9_cs_i(ep9_cs_i),
|
||||
.cp_cs_i(cp_cs_i),
|
||||
.tl_cs_i(tl_cs_i),
|
||||
.sl_cs_i(sl_cs_i),
|
||||
.ioctl_addr(ioctl_addr),
|
||||
.ioctl_wr(ioctl_wr),
|
||||
.ioctl_data(ioctl_data),
|
||||
|
||||
.pause(pause),
|
||||
|
||||
.hs_address(hs_address),
|
||||
.hs_data_in(hs_data_in),
|
||||
.hs_data_out(hs_data_out),
|
||||
.hs_write(hs_write),
|
||||
.hs_access(hs_access),
|
||||
|
||||
.main_cpu_rom_addr(main_cpu_rom_addr),
|
||||
.main_cpu_rom_do(main_cpu_rom_do),
|
||||
.sub_cpu_rom_addr(sub_cpu_rom_addr),
|
||||
.sub_cpu_rom_do(sub_cpu_rom_do),
|
||||
.sp_rom_addr(sp_rom_addr),
|
||||
.sp_rom_do(sp_rom_do)
|
||||
);
|
||||
|
||||
//Instantiate sound PCB
|
||||
Gyruss_SND sound_pcb
|
||||
(
|
||||
.reset(reset),
|
||||
.clk_49m(clk_49m),
|
||||
.irq_trigger(irq_trigger),
|
||||
.cs_sounddata(cs_sounddata),
|
||||
.dip_sw(dip_sw),
|
||||
.coin(coin),
|
||||
.start_buttons(start_buttons),
|
||||
.p1_joystick(p1_joystick),
|
||||
.p2_joystick(p2_joystick),
|
||||
.p1_fire(p1_fire),
|
||||
.p2_fire(p2_fire),
|
||||
.btn_service(btn_service),
|
||||
|
||||
.cs_controls_dip1(cs_controls_dip1),
|
||||
.cs_dip2(cs_dip2),
|
||||
.cs_dip3(cs_dip3),
|
||||
.cpubrd_A5(A5),
|
||||
.cpubrd_A6(A6),
|
||||
.cpubrd_Din(cpubrd_D),
|
||||
.controls_dip(controls_dip),
|
||||
.sound_l(sound_l),
|
||||
.sound_r(sound_r),
|
||||
|
||||
.ep10_cs_i(ep10_cs_i),
|
||||
.ep11_cs_i(ep11_cs_i),
|
||||
.ep12_cs_i(ep12_cs_i),
|
||||
.ioctl_addr(ioctl_addr),
|
||||
.ioctl_wr(ioctl_wr),
|
||||
.ioctl_data(ioctl_data)
|
||||
);
|
||||
|
||||
endmodule
|
||||
996
Arcade_MiST/Konami Gyruss/rtl/Gyruss_CPU.sv
Normal file
996
Arcade_MiST/Konami Gyruss/rtl/Gyruss_CPU.sv
Normal file
@@ -0,0 +1,996 @@
|
||||
//============================================================================
|
||||
//
|
||||
// Gyruss main PCB model
|
||||
// Copyright (C) 2021 Ace
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//Module declaration, I/O ports
|
||||
module Gyruss_CPU
|
||||
(
|
||||
input reset,
|
||||
input clk_49m, //Actual frequency: 49.152MHz
|
||||
output [2:0] red, green, //8-bit RGB, 3 bits per color for red and green,
|
||||
output [1:0] blue, //2 bits for blue
|
||||
output video_hsync, video_vsync, video_csync, //CSync not needed for MISTer
|
||||
output video_hblank, video_vblank,
|
||||
output ce_pix,
|
||||
|
||||
input [7:0] controls_dip,
|
||||
output [7:0] cpubrd_Dout,
|
||||
output cpubrd_A5, cpubrd_A6,
|
||||
output cs_sounddata, irq_trigger,
|
||||
output cs_dip3, cs_dip2, cs_controls_dip1,
|
||||
|
||||
//Screen centering (alters HSync, VSync and VBlank timing in the Konami 082 to reposition the video output)
|
||||
input [3:0] h_center, v_center,
|
||||
|
||||
input ep1_cs_i,
|
||||
input ep2_cs_i,
|
||||
input ep3_cs_i,
|
||||
input ep4_cs_i,
|
||||
input ep5_cs_i,
|
||||
input ep6_cs_i,
|
||||
input ep7_cs_i,
|
||||
input ep8_cs_i,
|
||||
input ep9_cs_i,
|
||||
input cp_cs_i,
|
||||
input tl_cs_i,
|
||||
input sl_cs_i,
|
||||
input [24:0] ioctl_addr,
|
||||
input [7:0] ioctl_data,
|
||||
input ioctl_wr,
|
||||
|
||||
input pause,
|
||||
|
||||
input [12:0] hs_address,
|
||||
input [7:0] hs_data_in,
|
||||
output [7:0] hs_data_out,
|
||||
input hs_write,
|
||||
input hs_access,
|
||||
|
||||
output [15:0] main_cpu_rom_addr,
|
||||
input [7:0] main_cpu_rom_do,
|
||||
output [12:0] sub_cpu_rom_addr,
|
||||
input [7:0] sub_cpu_rom_do,
|
||||
output [12:0] sp_rom_addr,
|
||||
input [31:0] sp_rom_do
|
||||
);
|
||||
|
||||
//------------------------------------------------------- Signal outputs -------------------------------------------------------//
|
||||
|
||||
//Assign active high HBlank and VBlank outputs
|
||||
assign video_hblank = hblk;
|
||||
assign video_vblank = vblk;
|
||||
|
||||
//Output pixel clock enable
|
||||
assign ce_pix = cen_6m;
|
||||
|
||||
//Output select lines for player inputs and DIP switches to sound board
|
||||
assign cs_controls_dip1 = (~n_k501_enable & z80_A[14]) & (z80_A[8:7] == 2'b01) & n_ram_write;
|
||||
assign cs_dip2 = (~n_k501_enable & z80_A[14]) & (z80_A[8:7] == 2'b00) & n_ram_write;
|
||||
assign cs_dip3 = (~n_k501_enable & z80_A[14]) & (z80_A[8:7] == 2'b10) & n_ram_write;
|
||||
|
||||
//Output primary MC6809E address lines A5 and A6 to sound board
|
||||
assign cpubrd_A5 = z80_A[5];
|
||||
assign cpubrd_A6 = z80_A[6];
|
||||
|
||||
//Assign CPU board data output to sound board
|
||||
assign cpubrd_Dout = z80_Dout;
|
||||
|
||||
//Generate and output chip select for latching sound data to sound CPU
|
||||
assign cs_sounddata = (~n_k501_enable & z80_A[14]) & (z80_A[8:7] == 2'b10) & ~n_ram_write;
|
||||
|
||||
//Generate sound IRQ trigger
|
||||
wire cs_soundirq = (~n_k501_enable & z80_A[14]) & (z80_A[8:7] == 2'b01) & ~n_ram_write;
|
||||
reg sound_irq = 1;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(n_cen_3m) begin
|
||||
if(cs_soundirq)
|
||||
sound_irq <= 1;
|
||||
else
|
||||
sound_irq <= 0;
|
||||
end
|
||||
end
|
||||
assign irq_trigger = sound_irq;
|
||||
|
||||
//------------------------------------------------------- Clock division -------------------------------------------------------//
|
||||
|
||||
//Generate 12.288MHz, 6.144MHz, 3.072MHz and 1.576MHz clock enables
|
||||
reg [4:0] div = 5'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
div <= div + 5'd1;
|
||||
end
|
||||
reg [3:0] n_div = 4'd0;
|
||||
always_ff @(negedge clk_49m) begin
|
||||
n_div <= n_div + 4'd1;
|
||||
end
|
||||
wire cen_12m = !div[1:0];
|
||||
wire cen_6m = !div[2:0];
|
||||
wire cen_3m = !div[3:0];
|
||||
wire n_cen_3m = !n_div;
|
||||
wire cen_1m5 = !div;
|
||||
|
||||
//Generate E and Q clock enables for KONAMI-1 (code adapted from Sorgelig's phase generator used in the MiSTer Vectrex core)
|
||||
reg k1_E, k1_Q;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
reg [1:0] clk_phase = 0;
|
||||
k1_E <= 0;
|
||||
k1_Q <= 0;
|
||||
if(cen_6m) begin
|
||||
clk_phase <= clk_phase + 1'd1;
|
||||
case(clk_phase)
|
||||
2'b01: k1_Q <= 1;
|
||||
2'b10: k1_E <= 1;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//------------------------------------------------------------ CPUs ------------------------------------------------------------//
|
||||
|
||||
//Primary CPU - Zilog Z80 (uses T80s version of the T80 soft core)
|
||||
wire [15:0] z80_A;
|
||||
wire [7:0] z80_Dout;
|
||||
wire n_mreq, n_rd, n_rfsh;
|
||||
T80s u13G
|
||||
(
|
||||
.RESET_n(reset),
|
||||
.CLK(clk_49m),
|
||||
.CEN(n_cen_3m & ~pause),
|
||||
.NMI_n(z80_nmi),
|
||||
.WAIT_n(n_wait),
|
||||
.MREQ_n(n_mreq),
|
||||
.RD_n(n_rd),
|
||||
.RFSH_n(n_rfsh),
|
||||
.A(z80_A),
|
||||
.DI(z80_Din),
|
||||
.DO(z80_Dout)
|
||||
);
|
||||
//Address decoding for Z80
|
||||
wire cs_rom1 = ~n_mreq & n_rfsh & (z80_A[15:13] == 3'b000);
|
||||
wire cs_rom2 = ~n_mreq & n_rfsh & (z80_A[15:13] == 3'b001);
|
||||
wire cs_rom3 = ~n_mreq & n_rfsh & (z80_A[15:13] == 3'b010);
|
||||
wire n_cs_k501 = ~(~n_mreq & n_rfsh & z80_A[15]);
|
||||
wire cs_mainlatch = (~n_k501_enable & z80_A[14]) & (z80_A[8:7] == 2'b11) & ~n_ram_write;
|
||||
wire cs_z80sharedram = (z80_A[14:13] == 2'b01) & ~n_k501_enable;
|
||||
wire n_cs_vram_wram = ~((z80_A[14:13] == 2'b00) & ~n_k501_enable);
|
||||
//Part of the RAM decoding is handled by the Konami 501 custom chip - instantiate an instance of this IC here
|
||||
wire n_wait, n_ram_write, n_k501_enable;
|
||||
wire [7:0] k501_D, k501_Dout;
|
||||
k501 u11E
|
||||
(
|
||||
.CLK(clk_49m),
|
||||
.CEN(cen_12m),
|
||||
.H1(h_cnt[0]),
|
||||
.H2(h_cnt[1]),
|
||||
.RAM(n_cs_k501),
|
||||
.RD(n_rd),
|
||||
.WAIT(n_wait),
|
||||
.WRITE(n_ram_write),
|
||||
.ENABLE(n_k501_enable),
|
||||
.Di(z80_Dout),
|
||||
.XDi(k501_Din),
|
||||
.Do(k501_Dout),
|
||||
.XDo(k501_D)
|
||||
);
|
||||
//Multiplex data inputs to Z80
|
||||
wire [7:0] z80_Din = cs_rom1 ? eprom1_D:
|
||||
cs_rom2 ? eprom2_D:
|
||||
cs_rom3 ? eprom3_D:
|
||||
~n_cs_k501 ? k501_Dout:
|
||||
8'hFF;
|
||||
|
||||
assign main_cpu_rom_addr = z80_A[14:0];
|
||||
//Z80 ROMs
|
||||
//ROM 1/3
|
||||
wire [7:0] eprom1_D = main_cpu_rom_do;
|
||||
/*
|
||||
eprom_1 u11J
|
||||
(
|
||||
.ADDR(z80_A[12:0]),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom1_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep1_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);*/
|
||||
//ROM 2/3
|
||||
wire [7:0] eprom2_D = main_cpu_rom_do;
|
||||
/*
|
||||
eprom_2 u12J
|
||||
(
|
||||
.ADDR(z80_A[12:0]),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom2_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep2_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);*/
|
||||
//ROM 3/3
|
||||
wire [7:0] eprom3_D = main_cpu_rom_do;
|
||||
/*
|
||||
eprom_3 u13J
|
||||
(
|
||||
.ADDR(z80_A[12:0]),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom3_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep3_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);*/
|
||||
|
||||
//Multiplex data input to Konami 501 data bus passthrough
|
||||
wire [7:0] k501_Din = (~n_cs_vram_wram & cs_wram0 & n_vram_wram_wr) ? wram0_D:
|
||||
(~n_cs_vram_wram & cs_wram1 & n_vram_wram_wr) ? wram1_D:
|
||||
(~n_cs_vram_wram & ~n_cs_vram & n_vram_wram_wr) ? vram_D:
|
||||
(cs_z80sharedram & n_z80_sharedram_wr) ? z80_sharedram_D:
|
||||
(cs_controls_dip1 | cs_dip2 | cs_dip3) ? controls_dip:
|
||||
8'hFF;
|
||||
|
||||
//Main latch
|
||||
reg z80_nmi_mask = 0;
|
||||
reg flip = 0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(!reset) begin
|
||||
z80_nmi_mask <= 0;
|
||||
flip <= 0;
|
||||
end
|
||||
else if(n_cen_3m) begin
|
||||
if(cs_mainlatch)
|
||||
case(z80_A[2:0])
|
||||
3'b000: z80_nmi_mask <= k501_D[0];
|
||||
3'b101: flip <= k501_D[0];
|
||||
default:;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//Generate VBlank NMI for Z80
|
||||
reg z80_nmi = 1;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m) begin
|
||||
if(!z80_nmi_mask)
|
||||
z80_nmi <= 1;
|
||||
else if(vblank_irq_en)
|
||||
z80_nmi <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
//VRAM
|
||||
wire [7:0] vram_D;
|
||||
spram #(8, 11) u5J
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(~n_cs_vram_wram & ~n_cs_vram & ~n_vram_wram_wr),
|
||||
.addr(vram_wram_A),
|
||||
.data(k501_D),
|
||||
.q(vram_D)
|
||||
);
|
||||
//Z80 work RAM
|
||||
//Bank 0
|
||||
|
||||
// Hiscore mux
|
||||
wire [10:0] u3J_addr = hs_access ? hs_address[10:0] : vram_wram_A;
|
||||
wire [7:0] u3J_din = hs_access ? hs_data_in : k501_D;
|
||||
wire u3J_wren = hs_access ? hs_write : (~n_cs_vram_wram & cs_wram0 & ~n_vram_wram_wr);
|
||||
wire [7:0] u3J_dout;
|
||||
assign wram0_D = hs_access ? 8'h00 : u3J_dout;
|
||||
assign hs_data_out = hs_access ? u3J_dout : 8'h00;
|
||||
|
||||
wire [7:0] wram0_D;
|
||||
spram #(8, 11) u3J
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(u3J_wren),
|
||||
.addr(u3J_addr),
|
||||
.data(u3J_din),
|
||||
.q(u3J_dout)
|
||||
);
|
||||
//Bank 1
|
||||
wire [7:0] wram1_D;
|
||||
spram #(8, 11) u2J
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(~n_cs_vram_wram & cs_wram1 & ~n_vram_wram_wr),
|
||||
.addr(vram_wram_A),
|
||||
.data(k501_D),
|
||||
.q(wram1_D)
|
||||
);
|
||||
//Generate select lines and write enable for work RAM and VRAM
|
||||
wire n_cs_vram = z80_A[12] & ~h_cnt[1];
|
||||
wire cs_wram0 = n_cs_vram & ~z80_A[11];
|
||||
wire cs_wram1 = n_cs_vram & z80_A[11];
|
||||
wire n_vram_wram_wr = n_cs_vram_wram | n_ram_write;
|
||||
|
||||
//Shared RAM
|
||||
wire [7:0] z80_sharedram_D, k1_sharedram_D;
|
||||
dpram_dc #(.widthad_a(11)) u17C
|
||||
(
|
||||
.clock_a(clk_49m),
|
||||
.address_a(z80_A[10:0]),
|
||||
.data_a(k501_D),
|
||||
.q_a(z80_sharedram_D),
|
||||
.wren_a(cs_z80sharedram & ~n_z80_sharedram_wr),
|
||||
|
||||
.clock_b(clk_49m),
|
||||
.address_b(k1_A[10:0]),
|
||||
.data_b(k1_Dout),
|
||||
.q_b(k1_sharedram_D),
|
||||
.wren_b(cs_k1sharedram & ~k1_rw & h_cnt[1])
|
||||
);
|
||||
//Generate write enable for Z80 section of shared RAM (active low)
|
||||
wire n_z80_sharedram_wr = ~cs_z80sharedram | n_ram_write;
|
||||
|
||||
//Secondary CPU - KONAMI-1 custom encrypted MC6809E (uses synchronous version of Greg Miller's cycle-accurate MC6809E made by
|
||||
//Sorgelig with a wrapper to decrypt XOR/XNOR-encrypted opcodes and a further modification to Greg's MC6809E to directly
|
||||
//accept the opcodes)
|
||||
wire k1_rw;
|
||||
wire [15:0] k1_A;
|
||||
wire [7:0] k1_Dout;
|
||||
KONAMI1 u18F
|
||||
(
|
||||
.CLK(clk_49m),
|
||||
.fallE_en(k1_E),
|
||||
.fallQ_en(k1_Q),
|
||||
.D(k1_Din),
|
||||
.DOut(k1_Dout),
|
||||
.ADDR(k1_A),
|
||||
.RnW(k1_rw),
|
||||
.nIRQ(k1_irq),
|
||||
.nFIRQ(1),
|
||||
.nNMI(1),
|
||||
.nHALT(1),
|
||||
.nRESET(reset)
|
||||
);
|
||||
|
||||
//Address decoding for KONAMI-1
|
||||
wire cs_beam = (k1_A[15:13] == 3'b000) & k1_rw;
|
||||
wire cs_k1irqmask = (k1_A[15:13] == 3'b001) & ~k1_rw;
|
||||
wire cs_spriteram = (k1_A[15:13] == 3'b010);
|
||||
wire cs_k1sharedram = (k1_A[15:13] == 3'b011);
|
||||
wire cs_rom4 = (k1_A[15:13] == 3'b111);
|
||||
//Multiplex data inputs to KONAMI-1
|
||||
wire [7:0] k1_Din = cs_beam ? v_cnt:
|
||||
(cs_spriteram & cs_spriteram0 & ~spriteram0_wr) ? spriteram_D[7:0]:
|
||||
(cs_spriteram & cs_spriteram1 & ~spriteram1_wr) ? spriteram_D[15:8]:
|
||||
(cs_k1sharedram & k1_rw & h_cnt[1]) ? k1_sharedram_D:
|
||||
cs_rom4 ? eprom4_D:
|
||||
8'hFF;
|
||||
|
||||
assign sub_cpu_rom_addr = k1_A[12:0];
|
||||
//KONAMI-1 ROM
|
||||
wire [7:0] eprom4_D = sub_cpu_rom_do;
|
||||
/*
|
||||
eprom_4 u19E
|
||||
(
|
||||
.ADDR(k1_A[12:0]),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom4_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep4_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
*/
|
||||
//Generate write enable for all KONAMI-1 RAM (active low)
|
||||
wire k1_rw1 = h1d | k1_rw;
|
||||
|
||||
//Generate IRQ mask for KONAMI-1
|
||||
reg k1_irq_mask;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(!reset)
|
||||
k1_irq_mask <= 0;
|
||||
else if(cen_3m && cs_k1irqmask)
|
||||
k1_irq_mask <= k1_Dout[0];
|
||||
end
|
||||
|
||||
//Generate VBlank IRQ for KONAMI-1
|
||||
reg k1_irq = 1;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m) begin
|
||||
if(!k1_irq_mask)
|
||||
k1_irq <= 1;
|
||||
else if(vblank_irq_en)
|
||||
k1_irq <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
//-------------------------------------------------------- Video timing --------------------------------------------------------//
|
||||
|
||||
//Konami 082 custom chip - responsible for all video timings
|
||||
wire vblk, vblank_irq_en;
|
||||
wire [8:0] h_cnt;
|
||||
wire [7:0] v_cnt;
|
||||
k082 u11G
|
||||
(
|
||||
.reset(1),
|
||||
.clk(clk_49m),
|
||||
.cen(cen_6m),
|
||||
.h_center(h_center),
|
||||
.v_center(v_center),
|
||||
.n_vsync(video_vsync),
|
||||
.sync(video_csync),
|
||||
.n_hsync(video_hsync),
|
||||
.vblk(vblk),
|
||||
.vblk_irq_en(vblank_irq_en),
|
||||
.h1(h_cnt[0]),
|
||||
.h2(h_cnt[1]),
|
||||
.h4(h_cnt[2]),
|
||||
.h8(h_cnt[3]),
|
||||
.h16(h_cnt[4]),
|
||||
.h32(h_cnt[5]),
|
||||
.h64(h_cnt[6]),
|
||||
.h128(h_cnt[7]),
|
||||
.n_h256(h_cnt[8]),
|
||||
.v1(v_cnt[0]),
|
||||
.v2(v_cnt[1]),
|
||||
.v4(v_cnt[2]),
|
||||
.v8(v_cnt[3]),
|
||||
.v16(v_cnt[4]),
|
||||
.v32(v_cnt[5]),
|
||||
.v64(v_cnt[6]),
|
||||
.v128(v_cnt[7])
|
||||
);
|
||||
|
||||
//Latch vertical counter from 082 custom chip when the horizontal counter hits 256
|
||||
reg [7:0] vcnt_lat = 8'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m && h_cnt == 9'd256)
|
||||
vcnt_lat <= v_cnt;
|
||||
end
|
||||
|
||||
//Latch least significant bit of horizontal counter (to be used for sprite RAM logic)
|
||||
reg h1d;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m)
|
||||
h1d <= h_cnt[0];
|
||||
end
|
||||
|
||||
//XOR horizontal counter bits [7:2] with HFLIP flag
|
||||
wire [7:2] hcnt_x = h_cnt[7:2] ^ {6{flip}};
|
||||
|
||||
//XOR latched vertical counter bits with VFLIP flag
|
||||
wire [7:0] vcnt_x = vcnt_lat ^ {8{flip}};
|
||||
|
||||
//--------------------------------------------------------- Tile layer ---------------------------------------------------------//
|
||||
|
||||
//Generate addresses for VRAM
|
||||
wire [10:0] vram_wram_A = h_cnt[1] ? {h_cnt[2], vcnt_x[7:3], hcnt_x[7:3]} : z80_A[10:0];
|
||||
|
||||
//LDO, labelled D1 in the Time Pilot schematics, signals to the tilemap logic when to latch tilemap codes from VRAM. It pulses
|
||||
//low when the lower 3 bits of the horizontal counter are all 1, then on the rising edge, tilemap codes are latched.
|
||||
//Set LDO as a register and latch a 0 when the 3 least significant bits of the horizontal counter are set to 1, otherwise latch
|
||||
//a 1
|
||||
reg ldo = 1;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(h_cnt[2:0] == 3'b111)
|
||||
ldo <= 0;
|
||||
else
|
||||
ldo <= 1;
|
||||
end
|
||||
|
||||
//Latch tilemap code from VRAM at every rising edge of LDO (equivalent to when LDO is low and the 3 least significant bits of
|
||||
//the horizontal counter are all set to 0)
|
||||
reg [7:0] tile_code = 8'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(!ldo && h_cnt[2:0] == 3'b000)
|
||||
tile_code <= vram_D;
|
||||
end
|
||||
|
||||
//Latch tilemap attributes from VRAM at the rising edge of bit 2 of the horizontal counter when !H256 is high
|
||||
reg tile_attrib_latch = 1;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(h_cnt[2:0] == 3'b011)
|
||||
tile_attrib_latch <= 0;
|
||||
else
|
||||
tile_attrib_latch <= 1;
|
||||
end
|
||||
reg [7:0] tile_attrib = 8'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(h_cnt[8] && !tile_attrib_latch && h_cnt[2:0] == 3'b100)
|
||||
tile_attrib <= vram_D;
|
||||
end
|
||||
|
||||
//Latch tile color information, tilemap enable and flip signal for tilemap 083 custom chip every 8 pixels
|
||||
wire tile_flip = tile_hflip ^ ~flip;
|
||||
reg tile_083_flip = 0;
|
||||
reg tilemap_en = 0;
|
||||
reg [3:0] tile_color = 4'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m) begin
|
||||
if(h_cnt[2:0] == 3'b011) begin
|
||||
tile_083_flip <= tile_flip;
|
||||
tile_color <= tile_attrib[3:0];
|
||||
tilemap_en <= tile_attrib[4];
|
||||
end
|
||||
else begin
|
||||
tile_083_flip <= tile_083_flip;
|
||||
tile_color <= tile_color;
|
||||
tilemap_en <= tilemap_en;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//Generate address lines A1 - A3 of tilemap ROMs, CRA and tile flip attributes on the falling edge of horizontal
|
||||
//counter bit 2
|
||||
reg v1l, v2l, v4l, cra, tile_hflip, tile_vflip;
|
||||
reg old_h4;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
old_h4 <= h_cnt[2];
|
||||
if(old_h4 && !h_cnt[2]) begin
|
||||
v1l <= vcnt_x[0];
|
||||
v2l <= vcnt_x[1];
|
||||
v4l <= vcnt_x[2];
|
||||
tile_hflip <= tile_attrib[6];
|
||||
tile_vflip <= tile_attrib[7];
|
||||
cra <= tile_attrib[5];
|
||||
end
|
||||
end
|
||||
|
||||
//Address tilemap ROMs
|
||||
assign tilerom_A[12] = cra;
|
||||
assign tilerom_A[11:4] = tile_code;
|
||||
assign tilerom_A[3:0] = {hcnt_x[2] ^ tile_hflip, v4l ^ tile_vflip, v2l ^ tile_vflip, v1l ^ tile_vflip};
|
||||
|
||||
//Tilemap ROM
|
||||
wire [12:0] tilerom_A;
|
||||
wire [7:0] eprom5_D;
|
||||
|
||||
eprom_5 u2H
|
||||
(
|
||||
.ADDR(tilerom_A),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom5_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep5_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
|
||||
//Konami 083 custom chip 1/2 - this one shifts the pixel data from tilemap ROMs
|
||||
k083 u3G
|
||||
(
|
||||
.CK(clk_49m),
|
||||
.CEN(cen_6m),
|
||||
.LOAD(h_cnt[1:0] == 2'b11),
|
||||
.FLIP(tile_083_flip),
|
||||
.DB0i(eprom5_D),
|
||||
.DSH0(tile_lut_A[1:0])
|
||||
);
|
||||
|
||||
//Tilemap lookup PROM
|
||||
wire [7:0] tile_lut_A;
|
||||
assign tile_lut_A[7:6] = 2'b00;
|
||||
assign tile_lut_A[5:2] = tile_color;
|
||||
wire [3:0] tile_D;
|
||||
tile_lut_prom u3E
|
||||
(
|
||||
.ADDR(tile_lut_A),
|
||||
.CLK(clk_49m),
|
||||
.DATA(tile_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(tl_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
|
||||
//-------------------------------------------------------- Sprite layer --------------------------------------------------------//
|
||||
|
||||
//Generate sprite RAM enables (both active low)
|
||||
wire n_cs_spriteram = ~cs_spriteram | ~h_cnt[1];
|
||||
wire cs_spriteram0 = ~n_cs_spriteram & k1_A[1];
|
||||
wire cs_spriteram1 = ~n_cs_spriteram & ~k1_A[1];
|
||||
|
||||
//Generate write enables for sprite RAM (active low)
|
||||
wire spriteram0_wr = ~n_cs_spriteram & ~k1_rw1 & k1_A[1];
|
||||
wire spriteram1_wr = ~n_cs_spriteram & ~k1_rw1 & ~k1_A[1];
|
||||
|
||||
//Sprite RAM
|
||||
wire [15:0] spriteram_D;
|
||||
wire [9:0] spriteram_A;
|
||||
assign spriteram_A = h_cnt[1] ? {k1_A[10:2], k1_A[0]} : {3'b000, h_cnt[7], (h_cnt[8] ^ h_cnt[7]), h_cnt[6], h_cnt[3], h_cnt[4], h_cnt[5], h_cnt[2]};
|
||||
//Bank 0 (lower 4 bits)
|
||||
spram #(4, 10) u13A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(cs_spriteram & cs_spriteram0 & spriteram0_wr),
|
||||
.addr(spriteram_A),
|
||||
.data(k1_Dout[3:0]),
|
||||
.q(spriteram_D[3:0])
|
||||
);
|
||||
//Bank 0 (upper 4 bits)
|
||||
spram #(4, 10) u14A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(cs_spriteram & cs_spriteram0 & spriteram0_wr),
|
||||
.addr(spriteram_A),
|
||||
.data(k1_Dout[7:4]),
|
||||
.q(spriteram_D[7:4])
|
||||
);
|
||||
//Bank 1 (lower 4 bits)
|
||||
spram #(4, 10) u11A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(cs_spriteram & cs_spriteram1 & spriteram1_wr),
|
||||
.addr(spriteram_A),
|
||||
.data(k1_Dout[3:0]),
|
||||
.q(spriteram_D[11:8])
|
||||
);
|
||||
//Bank 1 (upper 4 bits)
|
||||
spram #(4, 10) u12A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(cs_spriteram & cs_spriteram1 & spriteram1_wr),
|
||||
.addr(spriteram_A),
|
||||
.data(k1_Dout[7:4]),
|
||||
.q(spriteram_D[15:12])
|
||||
);
|
||||
|
||||
//Latch all data output from sprite RAM at 1/4 of the pixel clock
|
||||
reg [15:0] spriteram_reg = 16'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_1m5)
|
||||
spriteram_reg <= spriteram_D;
|
||||
end
|
||||
|
||||
//Konami 503 custom chip - generates sprite addresses for lower half of sprite ROMs, sprite line buffer control, enable for
|
||||
//sprite write and sprite flip for 083 custom chip.
|
||||
wire cs_linebuffer, sprite_flip;
|
||||
wire [5:0] k503_R;
|
||||
k503 u9F
|
||||
(
|
||||
.OB(spriteram_reg[7:0]),
|
||||
.VCNT(vcnt_lat),
|
||||
.H4(h_cnt[2]),
|
||||
.H8(0),
|
||||
.LD(h_cnt[1:0] != 2'b11),
|
||||
.OCS(cs_linebuffer),
|
||||
.OFLP(sprite_flip),
|
||||
.R(k503_R)
|
||||
);
|
||||
assign spriterom_A[5] = k503_R[5];
|
||||
assign spriterom_A[3:0] = k503_R[3:0];
|
||||
|
||||
//Latch sprite code from sprite RAM bank 1 every 8 pixels
|
||||
reg [7:0] sprite_code = 8'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(h_cnt[2:0] == 3'b000)
|
||||
sprite_code <= spriteram_reg[15:8];
|
||||
end
|
||||
|
||||
//Assign sprite code to address the upper 7 bits and bit 4 of the sprite ROMs
|
||||
assign spriterom_A[12:6] = sprite_code[7:1];
|
||||
assign spriterom_A[4] = sprite_code[0];
|
||||
|
||||
assign sp_rom_addr = spriterom_A;
|
||||
//Sprite ROMs
|
||||
wire [12:0] spriterom_A;
|
||||
//ROM 1/4
|
||||
wire [7:0] eprom6_D = sp_rom_do[7:0];
|
||||
/*
|
||||
eprom_6 u9C
|
||||
(
|
||||
.ADDR(spriterom_A),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom6_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep6_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
*/
|
||||
//ROM 2/4
|
||||
wire [7:0] eprom7_D = sp_rom_do[15:8];
|
||||
/*
|
||||
eprom_7 u8C
|
||||
(
|
||||
.ADDR(spriterom_A),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom7_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep7_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
*/
|
||||
//ROM 3/4
|
||||
wire [7:0] eprom8_D = sp_rom_do[23:16];
|
||||
/*
|
||||
eprom_8 u7C
|
||||
(
|
||||
.ADDR(spriterom_A),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom8_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep8_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);*/
|
||||
//ROM 4/4
|
||||
wire [7:0] eprom9_D = sp_rom_do[31:24];
|
||||
/*
|
||||
eprom_9 u6C
|
||||
(
|
||||
.ADDR(spriterom_A),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom9_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep9_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
*/
|
||||
//Latch sprite attributes and horizontal position every 8 pixels
|
||||
reg [4:0] sprite_attrib = 5'd0;
|
||||
reg [7:0] sprite_hpos = 8'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(h_cnt[2:0] == 3'b100) begin
|
||||
sprite_attrib <= {spriteram_reg[5], spriteram_reg[3:0]};
|
||||
sprite_hpos <= spriteram_reg[15:8];
|
||||
end
|
||||
end
|
||||
|
||||
//Multiplex sprite ROM data outputs based on the state of sprite attribute bit 4
|
||||
reg spriterom_sel = 0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(h_cnt[2:0] == 3'b000)
|
||||
spriterom_sel <= sprite_attrib[4];
|
||||
end
|
||||
wire [15:0] spriterom_D = spriterom_sel ? {eprom9_D, eprom7_D} : {eprom8_D, eprom6_D};
|
||||
|
||||
//Konami 083 custom chip 2/2 - shifts the pixel data from sprite ROMs
|
||||
k083 u7F
|
||||
(
|
||||
.CK(clk_49m),
|
||||
.CEN(cen_6m),
|
||||
.LOAD(h_cnt[1:0] == 2'b11),
|
||||
.FLIP(sprite_k083_flip),
|
||||
.DB0i(spriterom_D[7:0]),
|
||||
.DB1i(spriterom_D[15:8]),
|
||||
.DSH0(sprite_lut_A[1:0]),
|
||||
.DSH1(sprite_lut_A[3:2])
|
||||
);
|
||||
|
||||
//Latch sprite color information, enable for sprite line buffer, sprite 083 flip at every 8 pixels
|
||||
reg [3:0] sprite_color = 4'd0;
|
||||
reg sprite_lbuff_en, sprite_k083_flip;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m) begin
|
||||
if(h_cnt[2:0] == 3'b011) begin
|
||||
sprite_color <= sprite_attrib[3:0];
|
||||
sprite_lbuff_en <= cs_linebuffer;
|
||||
sprite_k083_flip <= sprite_flip;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//Assign sprite color information to the upper 4 bits of the sprite lookup PROM
|
||||
assign sprite_lut_A[7:4] = sprite_color;
|
||||
|
||||
//Sprite lookup PROM
|
||||
wire [7:0] sprite_lut_A;
|
||||
wire [3:0] sprite_lut_D;
|
||||
sprite_lut_prom u6F
|
||||
(
|
||||
.ADDR(sprite_lut_A),
|
||||
.CLK(clk_49m),
|
||||
.DATA(sprite_lut_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(sl_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
|
||||
//Konami 502 custom chip, responsible for generating sprites (sits between sprite ROMs and the sprite line buffer)
|
||||
wire [7:0] sprite_lbuff_Do;
|
||||
wire [4:0] sprite_D;
|
||||
wire sprite_lbuff_sel, sprite_lbuff_dec0, sprite_lbuff_dec1;
|
||||
k502 u6B
|
||||
(
|
||||
.RESET(1),
|
||||
.CK1(clk_49m),
|
||||
.CK2(clk_49m),
|
||||
.CEN(cen_6m),
|
||||
.LD0(h_cnt[2:0] == 3'b000),
|
||||
.H2(h_cnt[1]),
|
||||
.H256(h_cnt[8]),
|
||||
.SPAL(sprite_lut_D),
|
||||
.SPLBi({sprite_lbuff1_D, sprite_lbuff0_D}),
|
||||
.SPLBo(sprite_lbuff_Do),
|
||||
.OSEL(sprite_lbuff_sel),
|
||||
.OLD(sprite_lbuff_dec1),
|
||||
.OCLR(sprite_lbuff_dec0),
|
||||
.COL(sprite_D)
|
||||
);
|
||||
|
||||
//----------------------------------------------------- Sprite line buffer -----------------------------------------------------//
|
||||
|
||||
//Generate load and clear signals for counters generating addresses to sprite line buffer
|
||||
reg sprite_lbuff0_ld, sprite_lbuff1_ld, sprite_lbuff0_clr, sprite_lbuff1_clr;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(h_cnt[1:0] == 2'b11) begin
|
||||
if(sprite_lbuff_dec0 && !sprite_lbuff_dec1) begin
|
||||
sprite_lbuff0_clr <= 0;
|
||||
sprite_lbuff1_clr <= 1;
|
||||
end
|
||||
else if(!sprite_lbuff_dec0 && sprite_lbuff_dec1) begin
|
||||
sprite_lbuff0_clr <= 1;
|
||||
sprite_lbuff1_clr <= 0;
|
||||
end
|
||||
else begin
|
||||
sprite_lbuff0_clr <= 0;
|
||||
sprite_lbuff1_clr <= 0;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
sprite_lbuff0_clr <= 0;
|
||||
sprite_lbuff1_clr <= 0;
|
||||
end
|
||||
if(h_cnt[2:0] == 3'b011) begin
|
||||
if(!sprite_lbuff_dec1) begin
|
||||
sprite_lbuff0_ld <= 1;
|
||||
sprite_lbuff1_ld <= 0;
|
||||
end
|
||||
else begin
|
||||
sprite_lbuff0_ld <= 0;
|
||||
sprite_lbuff1_ld <= 1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
sprite_lbuff0_ld <= 0;
|
||||
sprite_lbuff1_ld <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
//Generate addresses for sprite line buffer
|
||||
//Bank 0, lower 4 bits
|
||||
reg [3:0] linebuffer0_l = 4'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m) begin
|
||||
if(sprite_lbuff0_clr)
|
||||
linebuffer0_l <= 4'd0;
|
||||
else
|
||||
if(sprite_lbuff0_ld)
|
||||
linebuffer0_l <= sprite_hpos[3:0];
|
||||
else
|
||||
linebuffer0_l <= linebuffer0_l + 4'd1;
|
||||
end
|
||||
end
|
||||
//Bank 0, upper 4 bits
|
||||
reg [3:0] linebuffer0_h = 4'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m) begin
|
||||
if(sprite_lbuff0_clr)
|
||||
linebuffer0_h <= 4'd0;
|
||||
else
|
||||
if(sprite_lbuff0_ld)
|
||||
linebuffer0_h <= sprite_hpos[7:4];
|
||||
else if(linebuffer0_l == 4'hF)
|
||||
linebuffer0_h <= linebuffer0_h + 4'd1;
|
||||
end
|
||||
end
|
||||
wire [7:0] sprite_lbuff0_A = {linebuffer0_h, linebuffer0_l};
|
||||
//Bank 1, lower 4 bits
|
||||
reg [3:0] linebuffer1_l = 4'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m) begin
|
||||
if(sprite_lbuff1_clr)
|
||||
linebuffer1_l <= 4'd0;
|
||||
else
|
||||
if(sprite_lbuff1_ld)
|
||||
linebuffer1_l <= sprite_hpos[3:0];
|
||||
else
|
||||
linebuffer1_l <= linebuffer1_l + 4'd1;
|
||||
end
|
||||
end
|
||||
//Bank 1, upper 4 bits
|
||||
reg [3:0] linebuffer1_h = 4'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m) begin
|
||||
if(sprite_lbuff1_clr)
|
||||
linebuffer1_h <= 4'd0;
|
||||
else
|
||||
if(sprite_lbuff1_ld)
|
||||
linebuffer1_h <= sprite_hpos[7:4];
|
||||
else if(linebuffer1_l == 4'hF)
|
||||
linebuffer1_h <= linebuffer1_h + 4'd1;
|
||||
end
|
||||
end
|
||||
wire [7:0] sprite_lbuff1_A = {linebuffer1_h, linebuffer1_l};
|
||||
|
||||
//Generate chip select signals for sprite line buffer
|
||||
wire cs_sprite_lbuff0 = ~(sprite_lbuff_en & sprite_lbuff_sel);
|
||||
wire cs_sprite_lbuff1 = ~(sprite_lbuff_en & ~sprite_lbuff_sel);
|
||||
|
||||
//Sprite line buffer bank 0
|
||||
wire [3:0] sprite_lbuff0_D;
|
||||
spram #(4, 8) u7A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(cen_6m & cs_sprite_lbuff0),
|
||||
.addr(sprite_lbuff0_A),
|
||||
.data(sprite_lbuff_Do[3:0]),
|
||||
.q(sprite_lbuff0_D)
|
||||
);
|
||||
|
||||
//Sprite line buffer bank 1
|
||||
wire [3:0] sprite_lbuff1_D;
|
||||
spram #(4, 8) u7B
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(cen_6m & cs_sprite_lbuff1),
|
||||
.addr(sprite_lbuff1_A),
|
||||
.data(sprite_lbuff_Do[7:4]),
|
||||
.q(sprite_lbuff1_D)
|
||||
);
|
||||
|
||||
//----------------------------------------------------- Final video output -----------------------------------------------------//
|
||||
|
||||
//Generate HBlank (active high) while the horizontal counter is between 141 and 268
|
||||
wire hblk = (h_cnt > 140 && h_cnt < 269);
|
||||
|
||||
//Multiplex tile and sprite data
|
||||
wire tile_sprite_sel = (tilemap_en | sprite_D[4]);
|
||||
wire [3:0] tile_sprite_D = tile_sprite_sel ? tile_D[3:0] : sprite_D[3:0];
|
||||
|
||||
//Latch pixel data for color PROM
|
||||
reg [4:0] pixel_D;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_6m)
|
||||
pixel_D <= {tile_sprite_sel, tile_sprite_D};
|
||||
end
|
||||
|
||||
//Color PROM
|
||||
wire [4:0] color_A = pixel_D;
|
||||
wire [2:0] prom_red, prom_green;
|
||||
wire [1:0] prom_blue;
|
||||
color_prom u2A
|
||||
(
|
||||
.ADDR(color_A),
|
||||
.CLK(clk_49m),
|
||||
.DATA({prom_blue, prom_green, prom_red}),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(cp_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
|
||||
//Output video signal from color PROMs, otherwise output black if in HBlank or VBlank
|
||||
assign red = (hblk | vblk) ? 3'h0 : prom_red;
|
||||
assign green = (hblk | vblk) ? 3'h0 : prom_green;
|
||||
assign blue = (hblk | vblk) ? 2'h0 : prom_blue;
|
||||
|
||||
endmodule
|
||||
277
Arcade_MiST/Konami Gyruss/rtl/Gyruss_MiST.sv
Normal file
277
Arcade_MiST/Konami Gyruss/rtl/Gyruss_MiST.sv
Normal file
@@ -0,0 +1,277 @@
|
||||
module Gyruss_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 = {
|
||||
"GYRUSS;;",
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scanlines,Off,25%,50%,75%;",
|
||||
"O5,Blend,Off,On;",
|
||||
"O6,Joystick Swap,Off,On;",
|
||||
"O7,Service,Off,On;",
|
||||
"DIP;",
|
||||
"T0,Reset;",
|
||||
"V,v1.00.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire rotate = status[2];
|
||||
wire [1:0] scanlines = status[4:3];
|
||||
wire blend = status[5];
|
||||
wire joyswap = status[6];
|
||||
wire service = status[7];
|
||||
wire [1:0] orientation = 2'b11;
|
||||
wire [23:0] dip_sw = ~status[31:8];
|
||||
|
||||
assign LED = ~ioctl_downl;
|
||||
assign SDRAM_CLK = clock_49;
|
||||
assign SDRAM_CKE = 1;
|
||||
|
||||
wire clock_49, pll_locked;
|
||||
pll pll(
|
||||
.inclk0(CLOCK_27),
|
||||
.c0(clock_49),//49.152MHz
|
||||
.locked(pll_locked)
|
||||
);
|
||||
|
||||
wire [31:0] status;
|
||||
wire [1:0] buttons;
|
||||
wire [1:0] switches;
|
||||
wire [7:0] joystick_0;
|
||||
wire [7:0] joystick_1;
|
||||
wire scandoublerD;
|
||||
wire ypbpr;
|
||||
wire no_csync;
|
||||
wire [6:0] core_mod;
|
||||
wire [15:0] audio_l, audio_r;
|
||||
wire hs, vs, cs;
|
||||
wire hb, vb;
|
||||
wire blankn = ~(hb | vb);
|
||||
wire [2:0] r, g;
|
||||
wire [1:0] b;
|
||||
wire key_strobe;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
|
||||
wire [15:0] main_rom_addr;
|
||||
wire [15:0] main_rom_do;
|
||||
wire [12:0] sub_rom_addr;
|
||||
wire [15:0] sub_rom_do;
|
||||
wire [12:0] sp_addr;
|
||||
wire [31:0] sp_do;
|
||||
|
||||
wire ioctl_downl;
|
||||
wire [7:0] ioctl_index;
|
||||
wire ioctl_wr;
|
||||
wire [24:0] ioctl_addr;
|
||||
wire [7:0] ioctl_dout;
|
||||
|
||||
data_io data_io(
|
||||
.clk_sys ( clock_49 ),
|
||||
.SPI_SCK ( SPI_SCK ),
|
||||
.SPI_SS2 ( SPI_SS2 ),
|
||||
.SPI_DI ( SPI_DI ),
|
||||
.ioctl_download( ioctl_downl ),
|
||||
.ioctl_index ( ioctl_index ),
|
||||
.ioctl_wr ( ioctl_wr ),
|
||||
.ioctl_addr ( ioctl_addr ),
|
||||
.ioctl_dout ( ioctl_dout )
|
||||
);
|
||||
wire [24:0] bg_ioctl_addr = ioctl_addr - 16'hA000;
|
||||
|
||||
reg port1_req, port2_req;
|
||||
sdram #(49) sdram(
|
||||
.*,
|
||||
.init_n ( pll_locked ),
|
||||
.clk ( clock_49 ),
|
||||
|
||||
.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 : {2'b00, main_rom_addr[14:1]} ),
|
||||
.cpu1_q ( main_rom_do ),
|
||||
.cpu2_addr ( ioctl_downl ? 16'hffff : sub_rom_addr[12:1] + 16'h3000 ),
|
||||
.cpu2_q ( sub_rom_do ),
|
||||
.cpu3_addr ( ),
|
||||
.cpu3_q ( ),
|
||||
|
||||
// port2 for sprite graphics
|
||||
.port2_req ( port2_req ),
|
||||
.port2_ack ( ),
|
||||
.port2_a ( {bg_ioctl_addr[23:15], bg_ioctl_addr[12:0], bg_ioctl_addr[14]} ), // merge sprite roms to 32-bit wide words
|
||||
.port2_ds ( {bg_ioctl_addr[13], ~bg_ioctl_addr[13]} ),
|
||||
.port2_we ( ioctl_downl ),
|
||||
.port2_d ( {ioctl_dout, ioctl_dout} ),
|
||||
.port2_q ( ),
|
||||
|
||||
.sp_addr ( ioctl_downl ? 16'hffff : sp_addr ),
|
||||
.sp_q ( sp_do )
|
||||
);
|
||||
|
||||
// ROM download controller
|
||||
always @(posedge clock_49) 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 clock_49) begin
|
||||
reg ioctl_downlD;
|
||||
ioctl_downlD <= ioctl_downl;
|
||||
if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1;
|
||||
reset <= status[0] | buttons[1] | ~rom_loaded;
|
||||
end
|
||||
|
||||
Gyruss Gyruss(
|
||||
.reset(~reset),
|
||||
.clk_49m(clock_49),
|
||||
.coin({~m_coin2,~m_coin1}),
|
||||
.start_buttons({~m_two_players,~m_one_player}),
|
||||
.p1_joystick({~m_right, ~m_left, ~m_down, ~m_up}),
|
||||
.p2_joystick({~m_right2, ~m_left2, ~m_down2, ~m_up2}),
|
||||
.p1_fire(~m_fireA),
|
||||
.p2_fire(~m_fire2A),
|
||||
.btn_service(~service),
|
||||
.dip_sw(dip_sw),
|
||||
.video_hsync(hs),
|
||||
.video_vsync(vs),
|
||||
.video_csync(cs),
|
||||
.video_hblank(hb),
|
||||
.video_vblank(vb),
|
||||
.video_r(r),
|
||||
.video_g(g),
|
||||
.video_b(b),
|
||||
.sound_l(audio_l),
|
||||
.sound_r(audio_r),
|
||||
.ioctl_addr(ioctl_addr),
|
||||
.ioctl_data(ioctl_dout),
|
||||
.ioctl_wr(ioctl_wr),
|
||||
|
||||
.main_cpu_rom_addr(main_rom_addr),
|
||||
.main_cpu_rom_do(main_rom_addr[0] ? main_rom_do[15:8] : main_rom_do[7:0]),
|
||||
.sub_cpu_rom_addr(sub_rom_addr),
|
||||
.sub_cpu_rom_do(sub_rom_addr[0] ? sub_rom_do[15:8] : sub_rom_do[7:0]),
|
||||
.sp_rom_addr(sp_addr),
|
||||
.sp_rom_do(sp_do)
|
||||
);
|
||||
|
||||
mist_video #(.COLOR_DEPTH(3), .SD_HCNT_WIDTH(10)) mist_video(
|
||||
.clk_sys ( clock_49 ),
|
||||
.SPI_SCK ( SPI_SCK ),
|
||||
.SPI_SS3 ( SPI_SS3 ),
|
||||
.SPI_DI ( SPI_DI ),
|
||||
.R ( blankn ? r : 0 ),
|
||||
.G ( blankn ? g : 0 ),
|
||||
.B ( blankn ? {b, b[1]} : 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 )
|
||||
);
|
||||
|
||||
user_io #(.STRLEN(($size(CONF_STR)>>3)))user_io(
|
||||
.clk_sys (clock_49 ),
|
||||
.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 )
|
||||
);
|
||||
|
||||
dac #(.C_bits(16))dac_l(
|
||||
.clk_i(clock_49),
|
||||
.res_n_i(1'b1),
|
||||
.dac_i({~audio_l[15], audio_l[14:0]}),
|
||||
.dac_o(AUDIO_L)
|
||||
);
|
||||
|
||||
dac #(.C_bits(16))dac_r(
|
||||
.clk_i(clock_49),
|
||||
.res_n_i(1'b1),
|
||||
.dac_i({~audio_r[15], audio_r[14:0]}),
|
||||
.dac_o(AUDIO_R)
|
||||
);
|
||||
|
||||
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF;
|
||||
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F;
|
||||
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 ( clock_49 ),
|
||||
.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_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
|
||||
.player2 ( {m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} )
|
||||
);
|
||||
|
||||
endmodule
|
||||
762
Arcade_MiST/Konami Gyruss/rtl/Gyruss_SND.sv
Normal file
762
Arcade_MiST/Konami Gyruss/rtl/Gyruss_SND.sv
Normal file
@@ -0,0 +1,762 @@
|
||||
//============================================================================
|
||||
//
|
||||
// Gyruss sound PCB model
|
||||
// Copyright (C) 2021 Ace
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
module Gyruss_SND
|
||||
(
|
||||
input reset,
|
||||
input clk_49m, //Actual frequency: 49.152MHz
|
||||
input [23:0] dip_sw,
|
||||
input [1:0] coin, //0 = coin 1, 1 = coin 2
|
||||
input [1:0] start_buttons, //0 = Player 1, 1 = Player 2
|
||||
input [3:0] p1_joystick, p2_joystick, //0 = up, 1 = down, 2 = left, 3 = right
|
||||
input p1_fire,
|
||||
input p2_fire,
|
||||
input btn_service,
|
||||
input cpubrd_A5, cpubrd_A6,
|
||||
input cs_controls_dip1, cs_dip2, cs_dip3,
|
||||
input irq_trigger, cs_sounddata,
|
||||
input [7:0] cpubrd_Din,
|
||||
|
||||
output [7:0] controls_dip,
|
||||
output signed [15:0] sound_l, sound_r,
|
||||
|
||||
input ep10_cs_i,
|
||||
input ep11_cs_i,
|
||||
input ep12_cs_i,
|
||||
input [24:0] ioctl_addr,
|
||||
input [7:0] ioctl_data,
|
||||
input ioctl_wr
|
||||
//The sound board contains a video passthrough but video will instead be tapped
|
||||
//straight from the CPU board implementation (this passthrough is redundant for
|
||||
//an FPGA implementation)
|
||||
);
|
||||
|
||||
//------------------------------------------------------- Signal outputs -------------------------------------------------------//
|
||||
|
||||
//Multiplex controls and DIP switches to be output to CPU board
|
||||
assign controls_dip = cs_controls_dip1 ? controls_dip1:
|
||||
cs_dip2 ? dip_sw[15:8]:
|
||||
cs_dip3 ? dip_sw[23:16]:
|
||||
8'hFF;
|
||||
|
||||
//------------------------------------------------------- Clock division -------------------------------------------------------//
|
||||
|
||||
//Generate clock enables for sound data and IRQ logic, and DC offset removal
|
||||
reg [8:0] div = 9'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
div <= div + 9'd1;
|
||||
end
|
||||
reg [3:0] n_div = 4'd0;
|
||||
always_ff @(negedge clk_49m) begin
|
||||
n_div <= n_div + 4'd1;
|
||||
end
|
||||
wire n_cen_3m = !n_div;
|
||||
wire cen_dcrm = !div;
|
||||
|
||||
//Generate 3.579545MHz clock enable for Z80, 1.789772MHz clock enable for AY-3-8910s, clock enable for AY-3-8910 timer
|
||||
//(uses Jotego's fractional clock divider from JTFRAME)
|
||||
wire cen_3m58, cen_1m79, cen_timer;
|
||||
jtframe_frac_cen #(11) sound_cen
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.n(10'd60),
|
||||
.m(10'd824),
|
||||
.cen({cen_timer, 8'bZZZZZZZZ, cen_1m79, cen_3m58})
|
||||
);
|
||||
|
||||
//Also use Jotego's fractional clock divider to generate an 8MHz clock enable for the i8039 MCU
|
||||
wire cen_8m;
|
||||
jtframe_frac_cen #(2) i8039_cen
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.n(10'd42),
|
||||
.m(10'd258),
|
||||
.cen({1'bZ, cen_8m})
|
||||
);
|
||||
|
||||
//------------------------------------------------------------ CPU -------------------------------------------------------------//
|
||||
|
||||
//Sound CPU - Zilog Z80 (uses T80s version of the T80 soft core)
|
||||
wire [15:0] sound_A;
|
||||
wire [7:0] sound_Dout;
|
||||
wire n_m1, n_mreq, n_iorq, n_rd, n_wr, n_rfsh;
|
||||
T80s u6B
|
||||
(
|
||||
.RESET_n(reset),
|
||||
.CLK(clk_49m),
|
||||
.CEN(cen_3m58),
|
||||
.INT_n(n_irq),
|
||||
.M1_n(n_m1),
|
||||
.MREQ_n(n_mreq),
|
||||
.IORQ_n(n_iorq),
|
||||
.RD_n(n_rd),
|
||||
.WR_n(n_wr),
|
||||
.RFSH_n(n_rfsh),
|
||||
.A(sound_A),
|
||||
.DI(sound_Din),
|
||||
.DO(sound_Dout)
|
||||
);
|
||||
//Address decoding for Z80
|
||||
wire n_rw = n_rd & n_wr;
|
||||
wire cs_soundrom0 = (~n_rw & ~n_mreq & n_rfsh & (sound_A[15:13] == 3'b000));
|
||||
wire cs_soundrom1 = (~n_rw & ~n_mreq & n_rfsh & (sound_A[15:13] == 3'b001));
|
||||
wire cs_soundram = (~n_rw & ~n_mreq & n_rfsh & (sound_A[15:13] == 3'b011));
|
||||
wire cs_sound = (~n_rw & ~n_mreq & n_rfsh & (sound_A[15:13] == 3'b100));
|
||||
wire cs_ay1 = (~n_iorq & n_m1 & (sound_A[4:2] == 3'b000));
|
||||
wire cs_ay2 = (~n_iorq & n_m1 & (sound_A[4:2] == 3'b001));
|
||||
wire cs_ay3 = (~n_iorq & n_m1 & (sound_A[4:2] == 3'b010));
|
||||
wire cs_ay4 = (~n_iorq & n_m1 & (sound_A[4:2] == 3'b011));
|
||||
wire cs_ay5 = (~n_iorq & n_m1 & (sound_A[4:2] == 3'b100));
|
||||
wire cs_i8039_irq = (~n_iorq & n_m1 & (sound_A[4:2] == 3'b101));
|
||||
wire cs_i8039_latch = (~n_iorq & n_m1 & (sound_A[4:2] == 3'b110));
|
||||
//Multiplex data input to Z80
|
||||
wire [7:0] sound_Din = cs_soundrom0 ? eprom10_D:
|
||||
cs_soundrom1 ? eprom11_D:
|
||||
(cs_soundram & n_wr) ? sndram_D:
|
||||
cs_sound ? sound_D:
|
||||
(~ay1_bdir & ay1_bc1) ? ay1_D:
|
||||
(~ay2_bdir & ay2_bc1) ? ay2_D:
|
||||
(~ay3_bdir & ay3_bc1) ? ay3_D:
|
||||
(~ay4_bdir & ay4_bc1) ? ay4_D:
|
||||
(~ay5_bdir & ay5_bc1) ? ay5_D:
|
||||
8'hFF;
|
||||
|
||||
//Sound ROMs
|
||||
//ROM 1/2
|
||||
wire [7:0] eprom10_D;
|
||||
eprom_10 u6A
|
||||
(
|
||||
.ADDR(sound_A[12:0]),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom10_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep10_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
//ROM 2/2
|
||||
wire [7:0] eprom11_D;
|
||||
eprom_11 u8A
|
||||
(
|
||||
.ADDR(sound_A[12:0]),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom11_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep11_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
|
||||
//Sound RAM (lower 4 bits)
|
||||
wire [7:0] sndram_D;
|
||||
spram #(4, 10) u4A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(cs_soundram & ~n_wr),
|
||||
.addr(sound_A[9:0]),
|
||||
.data(sound_Dout[3:0]),
|
||||
.q(sndram_D[3:0])
|
||||
);
|
||||
|
||||
//Sound RAM (upper 4 bits)
|
||||
spram #(4, 10) u5A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.we(cs_soundram & ~n_wr),
|
||||
.addr(sound_A[9:0]),
|
||||
.data(sound_Dout[7:4]),
|
||||
.q(sndram_D[7:4])
|
||||
);
|
||||
|
||||
//Latch sound data coming in from CPU board
|
||||
reg [7:0] sound_D = 8'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(n_cen_3m && cs_sounddata)
|
||||
sound_D <= cpubrd_Din;
|
||||
end
|
||||
|
||||
//Generate Z80 interrupts
|
||||
wire irq_clr = (~reset | ~(n_iorq | n_m1));
|
||||
reg n_irq = 1;
|
||||
always_ff @(posedge clk_49m or posedge irq_clr) begin
|
||||
if(irq_clr)
|
||||
n_irq <= 1;
|
||||
else if(n_cen_3m && irq_trigger)
|
||||
n_irq <= 0;
|
||||
end
|
||||
|
||||
//--------------------------------------------------- Controls & DIP switches --------------------------------------------------//
|
||||
|
||||
//Multiplex player inputs and DIP switch bank 1
|
||||
wire [7:0] controls_dip1 = ({cpubrd_A6, cpubrd_A5} == 2'b00) ? {3'b111, start_buttons, btn_service, coin}:
|
||||
({cpubrd_A6, cpubrd_A5} == 2'b01) ? {3'b111, p1_fire, p1_joystick[1:0], p1_joystick[3:2]}:
|
||||
({cpubrd_A6, cpubrd_A5} == 2'b10) ? {3'b111, p2_fire, p2_joystick[1:0], p2_joystick[3:2]}:
|
||||
({cpubrd_A6, cpubrd_A5} == 2'b11) ? dip_sw[7:0]:
|
||||
8'hFF;
|
||||
|
||||
//--------------------------------------------------------- Sound chips --------------------------------------------------------//
|
||||
|
||||
//Generate BC1 and BDIR signals for the five AY-3-8910s
|
||||
wire ay1_bdir = ~(~cs_ay1 | sound_A[0]);
|
||||
wire ay1_bc1 = ~(~cs_ay1 | sound_A[1]);
|
||||
wire ay2_bdir = ~(~cs_ay2 | sound_A[0]);
|
||||
wire ay2_bc1 = ~(~cs_ay2 | sound_A[1]);
|
||||
wire ay3_bdir = ~(~cs_ay3 | sound_A[0]);
|
||||
wire ay3_bc1 = ~(~cs_ay3 | sound_A[1]);
|
||||
wire ay4_bdir = ~(~cs_ay4 | sound_A[0]);
|
||||
wire ay4_bc1 = ~(~cs_ay4 | sound_A[1]);
|
||||
wire ay5_bdir = ~(~cs_ay5 | sound_A[0]);
|
||||
wire ay5_bc1 = ~(~cs_ay5 | sound_A[1]);
|
||||
|
||||
//AY-3-8910 timer (code adapted from MiSTer-X's Gyruss core)
|
||||
reg [3:0] timer_sel;
|
||||
wire [3:0] timer_val;
|
||||
always_comb begin
|
||||
case(timer_sel)
|
||||
0: timer_val = 4'h0;
|
||||
1: timer_val = 4'h1;
|
||||
2: timer_val = 4'h2;
|
||||
3: timer_val = 4'h3;
|
||||
4: timer_val = 4'h4;
|
||||
5: timer_val = 4'h9;
|
||||
6: timer_val = 4'hA;
|
||||
7: timer_val = 4'hB;
|
||||
8: timer_val = 4'hA;
|
||||
9: timer_val = 4'hD;
|
||||
default: timer_val = 0;
|
||||
endcase
|
||||
end
|
||||
reg [3:0] timer = 4'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_timer) begin
|
||||
timer <= timer_val;
|
||||
timer_sel <= (timer_sel == 4'd9) ? 4'd0 : (timer_sel + 4'd1);
|
||||
end
|
||||
end
|
||||
|
||||
//Sound chip 1 (AY-3-8910 - uses JT49 by Jotego)
|
||||
wire [7:0] ay1_D;
|
||||
wire [7:0] ay1A_raw, ay1B_raw, ay1C_raw;
|
||||
wire [5:0] ay1_filter;
|
||||
jt49_bus #(.COMP(3'b100)) u11D
|
||||
(
|
||||
.rst_n(reset),
|
||||
.clk(clk_49m),
|
||||
.clk_en(cen_1m79),
|
||||
.bdir(ay1_bdir),
|
||||
.bc1(ay1_bc1),
|
||||
.din(sound_Dout),
|
||||
.sel(1),
|
||||
.dout(ay1_D),
|
||||
.A(ay1A_raw),
|
||||
.B(ay1B_raw),
|
||||
.C(ay1C_raw),
|
||||
.IOB_out({2'bZZ, ay1_filter})
|
||||
);
|
||||
|
||||
//Sound chip 2 (AY-3-8910 - uses JT49 by Jotego)
|
||||
wire [7:0] ay2_D;
|
||||
wire [7:0] ay2A_raw, ay2B_raw, ay2C_raw;
|
||||
wire [5:0] ay2_filter;
|
||||
jt49_bus #(.COMP(3'b100)) u12D
|
||||
(
|
||||
.rst_n(reset),
|
||||
.clk(clk_49m),
|
||||
.clk_en(cen_1m79),
|
||||
.bdir(ay2_bdir),
|
||||
.bc1(ay2_bc1),
|
||||
.din(sound_Dout),
|
||||
.sel(1),
|
||||
.dout(ay2_D),
|
||||
.A(ay2A_raw),
|
||||
.B(ay2B_raw),
|
||||
.C(ay2C_raw),
|
||||
.IOB_out({2'bZZ, ay2_filter})
|
||||
);
|
||||
|
||||
//Sound chip 3 (AY-3-8910 - uses JT49 by Jotego)
|
||||
wire [7:0] ay3_D;
|
||||
wire [7:0] ay3A_raw, ay3B_raw, ay3C_raw;
|
||||
jt49_bus #(.COMP(3'b100)) u10B
|
||||
(
|
||||
.rst_n(reset),
|
||||
.clk(clk_49m),
|
||||
.clk_en(cen_1m79),
|
||||
.bdir(ay3_bdir),
|
||||
.bc1(ay3_bc1),
|
||||
.din(sound_Dout),
|
||||
.sel(1),
|
||||
.dout(ay3_D),
|
||||
.A(ay3A_raw),
|
||||
.B(ay3B_raw),
|
||||
.C(ay3C_raw),
|
||||
.IOA_in({4'b0000, timer})
|
||||
);
|
||||
|
||||
//Sound chip 4 (AY-3-8910 - uses JT49 by Jotego)
|
||||
wire [7:0] ay4_D;
|
||||
wire [7:0] ay4A_raw, ay4B_raw, ay4C_raw;
|
||||
jt49_bus #(.COMP(3'b100)) u9B
|
||||
(
|
||||
.rst_n(reset),
|
||||
.clk(clk_49m),
|
||||
.clk_en(cen_1m79),
|
||||
.bdir(ay4_bdir),
|
||||
.bc1(ay4_bc1),
|
||||
.din(sound_Dout),
|
||||
.sel(1),
|
||||
.dout(ay4_D),
|
||||
.A(ay4A_raw),
|
||||
.B(ay4B_raw),
|
||||
.C(ay4C_raw)
|
||||
);
|
||||
|
||||
//Sound chip 5 (AY-3-8910 - uses JT49 by Jotego)
|
||||
wire [7:0] ay5_D;
|
||||
wire [7:0] ay5A_raw, ay5B_raw, ay5C_raw;
|
||||
jt49_bus #(.COMP(3'b100)) u8B
|
||||
(
|
||||
.rst_n(reset),
|
||||
.clk(clk_49m),
|
||||
.clk_en(cen_1m79),
|
||||
.bdir(ay5_bdir),
|
||||
.bc1(ay5_bc1),
|
||||
.din(sound_Dout),
|
||||
.sel(1),
|
||||
.dout(ay5_D),
|
||||
.A(ay5A_raw),
|
||||
.B(ay5B_raw),
|
||||
.C(ay5C_raw)
|
||||
);
|
||||
|
||||
//Sound chip 6 (Intel 8039 MCU - uses t8039_notri variant of T48)
|
||||
wire [7:0] i8039_raw;
|
||||
wire [7:0] i8039_Dout;
|
||||
wire i8039_ale, n_i8039_psen, n_i8039_rd, n_i8039_irq_clr;
|
||||
t8039_notri u7H
|
||||
(
|
||||
.xtal_i(clk_49m),
|
||||
.xtal_en_i(cen_8m),
|
||||
.reset_n_i(reset),
|
||||
.int_n_i(n_i8039_irq),
|
||||
.ea_i(1),
|
||||
.rd_n_o(n_i8039_rd),
|
||||
.psen_n_o(n_i8039_psen),
|
||||
.ale_o(i8039_ale),
|
||||
.db_i(i8039_Din),
|
||||
.db_o(i8039_Dout),
|
||||
.p2_o({n_i8039_irq_clr, 3'bZZZ, eprom12_A[11:8]}),
|
||||
.p1_o(i8039_raw)
|
||||
);
|
||||
//Multiplex data into i8039
|
||||
wire [7:0] i8039_Din = ~n_i8039_psen ? eprom12_D:
|
||||
~n_i8039_rd ? i8039_latch:
|
||||
8'hFF;
|
||||
|
||||
//i8039 ROM
|
||||
wire [11:0] eprom12_A;
|
||||
wire [7:0] eprom12_D;
|
||||
eprom_12 u11H
|
||||
(
|
||||
.ADDR(eprom12_A),
|
||||
.CLK(clk_49m),
|
||||
.DATA(eprom12_D),
|
||||
.ADDR_DL(ioctl_addr),
|
||||
.CLK_DL(clk_49m),
|
||||
.DATA_IN(ioctl_data),
|
||||
.CS_DL(ep12_cs_i),
|
||||
.WR(ioctl_wr)
|
||||
);
|
||||
|
||||
//Latch data from Z80 to i8039
|
||||
reg [7:0] i8039_latch = 8'd0;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(cen_3m58 && cs_i8039_latch)
|
||||
i8039_latch <= sound_Dout;
|
||||
end
|
||||
|
||||
//Latch address lines A[7:0] for MCU ROM
|
||||
reg [7:0] i8039_rom_lat = 8'd0;
|
||||
always_ff @(negedge i8039_ale) begin
|
||||
i8039_rom_lat <= i8039_Dout;
|
||||
end
|
||||
assign eprom12_A[7:0] = i8039_rom_lat;
|
||||
|
||||
//Generate i8039 IRQ
|
||||
reg n_i8039_irq = 1;
|
||||
always_ff @(posedge clk_49m) begin
|
||||
if(!n_i8039_irq_clr)
|
||||
n_i8039_irq <= 1;
|
||||
else if(cen_3m58 && cs_i8039_irq)
|
||||
n_i8039_irq <= 0;
|
||||
end
|
||||
|
||||
//----------------------------------------------------- Final audio output -----------------------------------------------------//
|
||||
|
||||
//Apply gain and remove DC offset from AY-3-8910s and i8039 (uses jt49_dcrm2 from JT49 by Jotego for DC offset removal)
|
||||
wire signed [15:0] ay1A_dcrm, ay1B_dcrm, ay1C_dcrm, ay2A_dcrm, ay2B_dcrm, ay2C_dcrm;
|
||||
wire signed [15:0] ay3A_sound, ay3B_sound, ay3C_sound, ay4A_sound, ay4B_sound, ay4C_sound, ay5A_sound, ay5B_sound, ay5C_sound;
|
||||
wire signed [15:0] i8039_sound;
|
||||
jt49_dcrm2 #(16) dcrm_ay1A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay1A_raw, 4'd0}),
|
||||
.dout(ay1A_dcrm)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay1B
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay1B_raw, 4'd0}),
|
||||
.dout(ay1B_dcrm)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay1C
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay1C_raw, 4'd0}),
|
||||
.dout(ay1C_dcrm)
|
||||
);
|
||||
|
||||
jt49_dcrm2 #(16) dcrm_ay2A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay2A_raw, 4'd0}),
|
||||
.dout(ay2A_dcrm)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay2B
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay2B_raw, 4'd0}),
|
||||
.dout(ay2B_dcrm)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay2C
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay2C_raw, 4'd0}),
|
||||
.dout(ay2C_dcrm)
|
||||
);
|
||||
|
||||
jt49_dcrm2 #(16) dcrm_ay3A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay3A_raw, 4'd0}),
|
||||
.dout(ay3A_sound)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay3B
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay3B_raw, 4'd0}),
|
||||
.dout(ay3B_sound)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay3C
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay3C_raw, 4'd0}),
|
||||
.dout(ay3C_sound)
|
||||
);
|
||||
|
||||
jt49_dcrm2 #(16) dcrm_ay4A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay4A_raw, 4'd0}),
|
||||
.dout(ay4A_sound)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay4B
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay4B_raw, 4'd0}),
|
||||
.dout(ay4B_sound)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay4C
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay4C_raw, 4'd0}),
|
||||
.dout(ay4C_sound)
|
||||
);
|
||||
|
||||
jt49_dcrm2 #(16) dcrm_ay5A
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay5A_raw, 4'd0}),
|
||||
.dout(ay5A_sound)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay5B
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay5B_raw, 4'd0}),
|
||||
.dout(ay5B_sound)
|
||||
);
|
||||
jt49_dcrm2 #(16) dcrm_ay5C
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({4'd0, ay5C_raw, 4'd0}),
|
||||
.dout(ay5C_sound)
|
||||
);
|
||||
|
||||
jt49_dcrm2 #(16) dcrm_i8039
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.cen(cen_dcrm),
|
||||
.rst(~reset),
|
||||
.din({2'd0, i8039_raw, 6'd0}),
|
||||
.dout(i8039_sound)
|
||||
);
|
||||
|
||||
//Two of Gyruss's AY-3-8910s contain selectable low-pass filters with the following cutoff frequencies:
|
||||
//3386.28Hz, 723.43Hz, 596.09Hz
|
||||
//Model this here (the PCB handles this via 3 74HC4066 switching ICs located at 9E, 9F and 10F)
|
||||
wire signed [15:0] ay1A_light, ay1A_med, ay1A_heavy, ay1B_light, ay1B_med, ay1B_heavy, ay1C_light, ay1C_med, ay1C_heavy;
|
||||
wire signed [15:0] ay2A_light, ay2A_med, ay2A_heavy, ay2B_light, ay2B_med, ay2B_heavy, ay2C_light, ay2C_med, ay2C_heavy;
|
||||
wire signed [15:0] ay1A_sound, ay1B_sound, ay1C_sound, ay2A_sound, ay2B_sound, ay2C_sound;
|
||||
gyruss_lpf_light ay1A_lpf_light
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay1A_dcrm),
|
||||
.out(ay1A_light)
|
||||
);
|
||||
gyruss_lpf_medium ay1A_lpf_medium
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay1A_dcrm),
|
||||
.out(ay1A_med)
|
||||
);
|
||||
gyruss_lpf_heavy ay1A_lpf_heavy
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay1A_dcrm),
|
||||
.out(ay1A_heavy)
|
||||
);
|
||||
gyruss_lpf_light ay1B_lpf_light
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay1B_dcrm),
|
||||
.out(ay1B_light)
|
||||
);
|
||||
gyruss_lpf_medium ay1B_lpf_medium
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay1B_dcrm),
|
||||
.out(ay1B_med)
|
||||
);
|
||||
gyruss_lpf_heavy ay1B_lpf_heavy
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay1B_dcrm),
|
||||
.out(ay1B_heavy)
|
||||
);
|
||||
gyruss_lpf_light ay1C_lpf_light
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay1C_dcrm),
|
||||
.out(ay1C_light)
|
||||
);
|
||||
gyruss_lpf_medium ay1C_lpf_medium
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay1C_dcrm),
|
||||
.out(ay1C_med)
|
||||
);
|
||||
gyruss_lpf_heavy ay1C_lpf_heavy
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay1C_dcrm),
|
||||
.out(ay1C_heavy)
|
||||
);
|
||||
|
||||
gyruss_lpf_light ay2A_lpf_light
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay2A_dcrm),
|
||||
.out(ay2A_light)
|
||||
);
|
||||
gyruss_lpf_medium ay2A_lpf_medium
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay2A_dcrm),
|
||||
.out(ay2A_med)
|
||||
);
|
||||
gyruss_lpf_heavy ay2A_lpf_heavy
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay2A_dcrm),
|
||||
.out(ay2A_heavy)
|
||||
);
|
||||
gyruss_lpf_light ay2B_lpf_light
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay2B_dcrm),
|
||||
.out(ay2B_light)
|
||||
);
|
||||
gyruss_lpf_medium ay2B_lpf_medium
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay2B_dcrm),
|
||||
.out(ay2B_med)
|
||||
);
|
||||
gyruss_lpf_heavy ay2B_lpf_heavy
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay2B_dcrm),
|
||||
.out(ay2B_heavy)
|
||||
);
|
||||
gyruss_lpf_light ay2C_lpf_light
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay2C_dcrm),
|
||||
.out(ay2C_light)
|
||||
);
|
||||
gyruss_lpf_medium ay2C_lpf_medium
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay2C_dcrm),
|
||||
.out(ay2C_med)
|
||||
);
|
||||
gyruss_lpf_heavy ay2C_lpf_heavy
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(ay2C_dcrm),
|
||||
.out(ay2C_heavy)
|
||||
);
|
||||
|
||||
//Apply audio filtering based on the state of the low-pass filter controls
|
||||
always_comb begin
|
||||
case(ay1_filter[1:0])
|
||||
2'b00: ay1A_sound = ay1A_dcrm;
|
||||
2'b01: ay1A_sound = ay1A_light <<< 1;
|
||||
2'b10: ay1A_sound = ay1A_med <<< 1;
|
||||
2'b11: ay1A_sound = ay1A_heavy <<< 1;
|
||||
endcase
|
||||
case(ay1_filter[3:2])
|
||||
2'b00: ay1B_sound = ay1B_dcrm;
|
||||
2'b01: ay1B_sound = ay1B_light <<< 1;
|
||||
2'b10: ay1B_sound = ay1B_med <<< 1;
|
||||
2'b11: ay1B_sound = ay1B_heavy <<< 1;
|
||||
endcase
|
||||
case(ay1_filter[5:4])
|
||||
2'b00: ay1C_sound = ay1C_dcrm;
|
||||
2'b01: ay1C_sound = ay1C_light <<< 1;
|
||||
2'b10: ay1C_sound = ay1C_med <<< 1;
|
||||
2'b11: ay1C_sound = ay1C_heavy <<< 1;
|
||||
endcase
|
||||
case(ay2_filter[1:0])
|
||||
2'b00: ay2A_sound = ay2A_dcrm;
|
||||
2'b01: ay2A_sound = ay2A_light <<< 1;
|
||||
2'b10: ay2A_sound = ay2A_med <<< 1;
|
||||
2'b11: ay2A_sound = ay2A_heavy <<< 1;
|
||||
endcase
|
||||
case(ay2_filter[3:2])
|
||||
2'b00: ay2B_sound = ay2B_dcrm;
|
||||
2'b01: ay2B_sound = ay2B_light <<< 1;
|
||||
2'b10: ay2B_sound = ay2B_med <<< 1;
|
||||
2'b11: ay2B_sound = ay2B_heavy <<< 1;
|
||||
endcase
|
||||
case(ay2_filter[5:4])
|
||||
2'b00: ay2C_sound = ay2C_dcrm;
|
||||
2'b01: ay2C_sound = ay2C_light <<< 1;
|
||||
2'b10: ay2C_sound = ay2C_med <<< 1;
|
||||
2'b11: ay2C_sound = ay2C_heavy <<< 1;
|
||||
endcase
|
||||
end
|
||||
|
||||
//Mix the left and right outputs, then apply an antialiasing low-pass filter to eliminate ringing noise from the
|
||||
//AY-3-8910s and output the final result (this game has variable low-pass filtering based on how loud the PCB's volume dials
|
||||
//are set and will be modeled externally)
|
||||
wire signed [15:0] left_mix = (ay2A_sound + ay2B_sound + ay2C_sound + ay5A_sound + ay5B_sound + ay5C_sound + i8039_sound);
|
||||
wire signed [15:0] right_mix = (ay1A_sound + ay1B_sound + ay1C_sound + ay3A_sound + ay3B_sound + ay3C_sound + ay4A_sound +
|
||||
ay4B_sound + ay4C_sound);
|
||||
|
||||
wire signed [15:0] left_lpf, right_lpf;
|
||||
gyruss_lpf aalpf_l
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(left_mix),
|
||||
.out(left_lpf)
|
||||
);
|
||||
|
||||
gyruss_lpf aalpf_r
|
||||
(
|
||||
.clk(clk_49m),
|
||||
.reset(~reset),
|
||||
.in(right_mix),
|
||||
.out(right_lpf)
|
||||
);
|
||||
|
||||
assign sound_l = (ay2A_sound + ay2B_sound + ay2C_sound + ay5A_sound + ay5B_sound + ay5C_sound + i8039_sound);
|
||||
assign sound_r = (ay1A_sound + ay1B_sound + ay1C_sound + ay3A_sound + ay3B_sound + ay3C_sound + ay4A_sound +
|
||||
ay4B_sound + ay4C_sound);
|
||||
//assign sound_l = left_lpf;
|
||||
//assign sound_r = right_lpf;
|
||||
|
||||
endmodule
|
||||
35
Arcade_MiST/Konami Gyruss/rtl/build_id.tcl
Normal file
35
Arcade_MiST/Konami Gyruss/rtl/build_id.tcl
Normal file
@@ -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
|
||||
79
Arcade_MiST/Konami Gyruss/rtl/custom/KONAMI-1/KONAMI1.sv
Normal file
79
Arcade_MiST/Konami Gyruss/rtl/custom/KONAMI-1/KONAMI1.sv
Normal file
@@ -0,0 +1,79 @@
|
||||
//============================================================================
|
||||
//
|
||||
// SystemVerilog implementation of the KONAMI-1 custom chip, a custom MC6809E
|
||||
// variant with XOR/XNOR encryption
|
||||
// Implements MC6809E core by Greg Miller (synchronous version modified by
|
||||
// Sorgelig with further modifications to allow direct injection of opcodes)
|
||||
// Copyright (C) 2021 Ace
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
module KONAMI1
|
||||
(
|
||||
input CLK,
|
||||
input fallE_en,
|
||||
input fallQ_en,
|
||||
|
||||
input [7:0] D,
|
||||
output [7:0] DOut,
|
||||
output [15:0] ADDR,
|
||||
output RnW,
|
||||
output BS,
|
||||
output BA,
|
||||
input nIRQ,
|
||||
input nFIRQ,
|
||||
input nNMI,
|
||||
output AVMA,
|
||||
output BUSY,
|
||||
output LIC,
|
||||
input nHALT,
|
||||
input nRESET
|
||||
);
|
||||
|
||||
//Decrypt XOR/XNOR encrypted opcode
|
||||
wire [7:0] opcode = D ^ {ADDR[1], 1'b0, ~ADDR[1], 1'b0, ADDR[3], 1'b0, ~ADDR[3], 1'b0};
|
||||
|
||||
//Passthrough to modified MC6809is core with direct opcode injection and IS_KONAMI1 parameter set
|
||||
//to TRUE
|
||||
mc6809is #(.IS_KONAMI1("TRUE")) cpucore
|
||||
(
|
||||
.CLK(CLK),
|
||||
.fallE_en(fallE_en),
|
||||
.fallQ_en(fallQ_en),
|
||||
.OP(opcode),
|
||||
.nHALT(nHALT),
|
||||
.nRESET(nRESET),
|
||||
.D(D),
|
||||
.DOut(DOut),
|
||||
.ADDR(ADDR),
|
||||
.RnW(RnW),
|
||||
.BS(BS),
|
||||
.BA(BA),
|
||||
.nIRQ(nIRQ),
|
||||
.nFIRQ(nFIRQ),
|
||||
.nNMI(nNMI),
|
||||
.AVMA(AVMA),
|
||||
.BUSY(BUSY),
|
||||
.LIC(LIC),
|
||||
.nDMABREQ(1)
|
||||
);
|
||||
|
||||
endmodule
|
||||
4162
Arcade_MiST/Konami Gyruss/rtl/custom/KONAMI-1/mc6809isk.v
Normal file
4162
Arcade_MiST/Konami Gyruss/rtl/custom/KONAMI-1/mc6809isk.v
Normal file
File diff suppressed because it is too large
Load Diff
7
Arcade_MiST/Konami Gyruss/rtl/custom/gyruss_custom.qip
Normal file
7
Arcade_MiST/Konami Gyruss/rtl/custom/gyruss_custom.qip
Normal file
@@ -0,0 +1,7 @@
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/custom/k082.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/custom/k083.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/custom/k501.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/custom/k502.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/custom/k503.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/custom/KONAMI-1/KONAMI1.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/custom/KONAMI-1/mc6809isk.v
|
||||
168
Arcade_MiST/Konami Gyruss/rtl/custom/k082.sv
Normal file
168
Arcade_MiST/Konami Gyruss/rtl/custom/k082.sv
Normal file
@@ -0,0 +1,168 @@
|
||||
//============================================================================
|
||||
//
|
||||
// SystemVerilog implementation of the Konami 082 custom chip, used by
|
||||
// several Konami arcade PCBs to generate video timings
|
||||
// Copyright (C) 2020, 2021 Ace
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//Chip pinout:
|
||||
/* _____________
|
||||
_| |_
|
||||
reset |_|1 28|_| VCC
|
||||
_| |_
|
||||
h1 |_|2 27|_| GND
|
||||
_| |_
|
||||
h2 |_|3 26|_| v1
|
||||
_| |_
|
||||
h4 |_|4 25|_| v2
|
||||
_| |_
|
||||
h8 |_|5 24|_| v4
|
||||
_| |_
|
||||
h16 |_|6 23|_| v8
|
||||
_| |_
|
||||
h32 |_|7 22|_| v16
|
||||
_| |_
|
||||
h64 |_|8 21|_| v32
|
||||
_| |_
|
||||
h128 |_|9 20|_| v64
|
||||
_| |_
|
||||
n_h256 |_|10 19|_| v128
|
||||
_| |_
|
||||
h256 |_|11 18|_| n_vsync
|
||||
_| |_
|
||||
VCC |_|12 17|_| sync
|
||||
_| |_
|
||||
clk |_|13 16|_| vblk
|
||||
_| |_
|
||||
GND |_|14 15|_| n_vblk
|
||||
|_____________|
|
||||
|
||||
Note: Pins 12 and 27 may control other features of the 082 - these, if any, have not
|
||||
been modelled yet.
|
||||
*/
|
||||
|
||||
module k082
|
||||
(
|
||||
input reset, //Active low
|
||||
input clk,
|
||||
input cen, //Set to 1 if using this code to replace a real 082
|
||||
input [3:0] h_center, v_center, //These inputs are additions for screen centering and don't exist on the actual 082
|
||||
output n_vsync, sync,
|
||||
output n_hsync, //Not exposed on the original chip
|
||||
output reg vblk = 1,
|
||||
output n_vblk,
|
||||
output reg vblk_irq_en = 0, //This is an extra output not present on the real 082 to signal when to
|
||||
//trigger a VBlank IRQ (signal is active high)
|
||||
output h1, h2, h4, h8, h16, h32, h64, h128, h256, n_h256,
|
||||
output v1, v2, v4, v8, v16, v32, v64, v128
|
||||
);
|
||||
|
||||
//The horizontal and vertical counters are 9 bits wide - delcare them here
|
||||
reg [8:0] h_cnt = 9'd0;
|
||||
reg [8:0] v_cnt = 9'd0;
|
||||
|
||||
//Define the range of values the vertical counter will count between based on the additional vertical center signal
|
||||
//Shift the screen up by 1 line when horizontal centering shifts the screen left
|
||||
wire [8:0] vcnt_start = 9'd248 - v_center;
|
||||
wire [8:0] vcnt_end = 9'd511 - v_center;
|
||||
|
||||
//The horizontal and vertical counters behave as follows at every rising edge of the pixel clock:
|
||||
//-Start at 0, then count to 511 (both counters increment by 1 when the horizontal counter is set to 48)
|
||||
//-Horizontal counter resets to 128 for a total of 383 horizontal lines
|
||||
//-Vertical counter resets to 248 for a total of 263 vertical lines (adjustable with added vertical center signal)
|
||||
//-Vertical counter increments when the horizontal counter equals 176
|
||||
//-VBlank is active when the horizontal counter is between 495 - 511 and 248 - 270
|
||||
//Model this behavior here
|
||||
always_ff @(posedge clk or negedge reset) begin
|
||||
if(!reset) begin
|
||||
h_cnt <= 9'd0;
|
||||
v_cnt <= 9'd0;
|
||||
end
|
||||
else if(cen) begin
|
||||
case(h_cnt)
|
||||
48: begin
|
||||
v_cnt <= v_cnt + 9'd1;
|
||||
h_cnt <= h_cnt + 9'd1;
|
||||
end
|
||||
176: begin
|
||||
h_cnt <= h_cnt + 9'd1;
|
||||
case(v_cnt)
|
||||
16: begin
|
||||
vblk <= 0;
|
||||
v_cnt <= v_cnt + 9'd1;
|
||||
end
|
||||
271: begin
|
||||
vblk <= 0;
|
||||
v_cnt <= v_cnt + 9'd1;
|
||||
end
|
||||
495: begin
|
||||
vblk <= 1;
|
||||
vblk_irq_en <= 1;
|
||||
v_cnt <= v_cnt + 9'd1;
|
||||
end
|
||||
vcnt_end: v_cnt <= vcnt_start;
|
||||
default: v_cnt <= v_cnt + 9'd1;
|
||||
endcase
|
||||
end
|
||||
177: begin
|
||||
vblk_irq_en <= 0;
|
||||
h_cnt <= h_cnt + 9'd1;
|
||||
end
|
||||
511: h_cnt <= 9'd128;
|
||||
default: h_cnt <= h_cnt + 9'd1;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//The Konami 082 has both an active low VBlank and an active high VBlank - generate the active low VBlank by inverting
|
||||
//the active high VBlank generated in the previous sequential block
|
||||
assign n_vblk = ~vblk;
|
||||
|
||||
//Generate active low HSync, VSync and composite sync
|
||||
assign n_hsync = h_center[3] ? ~(h_cnt > (182 - h_center[2:0]) && h_cnt < (215 - h_center[2:0])):
|
||||
~(h_cnt > (175 - h_center[2:0]) && h_cnt < (208 - h_center[2:0]));
|
||||
assign n_vsync = h_center[3] ? ~(v_cnt >= vcnt_start + 9'd1 && v_cnt <= vcnt_start + 9'd9) : ~(v_cnt >= vcnt_start && v_cnt <= vcnt_start + 9'd8);
|
||||
assign sync = n_hsync ^ n_vsync;
|
||||
|
||||
//Assign the individual horizontal counter bits to their respective outputs (also invert bit 8 of the horizontal counter for H256)
|
||||
assign h1 = h_cnt[0];
|
||||
assign h2 = h_cnt[1];
|
||||
assign h4 = h_cnt[2];
|
||||
assign h8 = h_cnt[3];
|
||||
assign h16 = h_cnt[4];
|
||||
assign h32 = h_cnt[5];
|
||||
assign h64 = h_cnt[6];
|
||||
assign h128 = h_cnt[7];
|
||||
assign h256 = ~h_cnt[8];
|
||||
assign n_h256 = h_cnt[8];
|
||||
|
||||
//Assign the individual vertical counter bits to their respective outputs
|
||||
assign v1 = v_cnt[0];
|
||||
assign v2 = v_cnt[1];
|
||||
assign v4 = v_cnt[2];
|
||||
assign v8 = v_cnt[3];
|
||||
assign v16 = v_cnt[4];
|
||||
assign v32 = v_cnt[5];
|
||||
assign v64 = v_cnt[6];
|
||||
assign v128 = v_cnt[7];
|
||||
|
||||
endmodule
|
||||
101
Arcade_MiST/Konami Gyruss/rtl/custom/k083.sv
Normal file
101
Arcade_MiST/Konami Gyruss/rtl/custom/k083.sv
Normal file
@@ -0,0 +1,101 @@
|
||||
//============================================================================
|
||||
//
|
||||
// SystemVerilog implementation of the Konami 083 custom chip, a custom
|
||||
// shift register used on many early Konami arcade PCBs for handling graphics
|
||||
// ROMs
|
||||
// Copyright (C) 2020, 2021 Ace & ElectronAsh
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//Chip pinout:
|
||||
/* _____________
|
||||
_| |_
|
||||
CK |_|1 28|_| VCC
|
||||
_| |_
|
||||
FLIP |_|2 27|_| LOAD
|
||||
_| |_
|
||||
DB1i(4) |_|3 26|_| DB1i(6)
|
||||
_| |_
|
||||
DB1i(0) |_|4 25|_| DB1i(2)
|
||||
_| |_
|
||||
DB0i(4) |_|5 24|_| DB0i(6)
|
||||
_| |_
|
||||
DB0i(6) |_|6 23|_| DB0i(2)
|
||||
_| |_
|
||||
DB1i(5) |_|7 22|_| DB1i(7)
|
||||
_| |_
|
||||
DB1i(1) |_|8 21|_| DB1i(3)
|
||||
_| |_
|
||||
DB0i(5) |_|9 20|_| DB0i(7)
|
||||
_| |_
|
||||
DB0i(1) |_|10 19|_| DB0i(3)
|
||||
_| |_
|
||||
NC |_|11 18|_| NC
|
||||
_| |_
|
||||
DSH1(1) |_|12 17|_| DSH1(0)
|
||||
_| |_
|
||||
DSH0(1) |_|13 16|_| DSH0(0)
|
||||
_| |_
|
||||
GND |_|14 15|_| NC
|
||||
|_____________|
|
||||
*/
|
||||
|
||||
module k083
|
||||
(
|
||||
input CK,
|
||||
input CEN, //Set to 1 if using this code to replace a real 083
|
||||
input FLIP,
|
||||
input LOAD,
|
||||
input [7:0] DB0i, DB1i,
|
||||
output [1:0] DSH0, DSH1
|
||||
);
|
||||
|
||||
//Internal registers (shift right and shift left)
|
||||
reg [7:0] pixel_D0_l, pixel_D0_r;
|
||||
reg [7:0] pixel_D1_l, pixel_D1_r;
|
||||
|
||||
//Latch and shift pixel data
|
||||
always_ff @(posedge CK) begin
|
||||
if(CEN) begin
|
||||
if(LOAD) begin
|
||||
pixel_D0_l <= DB0i;
|
||||
pixel_D1_l <= DB1i;
|
||||
pixel_D0_r <= DB0i;
|
||||
pixel_D1_r <= DB1i;
|
||||
end
|
||||
else begin
|
||||
pixel_D0_l[3:0] <= {pixel_D0_l[2:0], 1'b0};
|
||||
pixel_D0_l[7:4] <= {pixel_D0_l[6:4], 1'b0};
|
||||
pixel_D1_l[3:0] <= {pixel_D1_l[2:0], 1'b0};
|
||||
pixel_D1_l[7:4] <= {pixel_D1_l[6:4], 1'b0};
|
||||
pixel_D0_r[3:0] <= {1'b0, pixel_D0_r[3:1]};
|
||||
pixel_D0_r[7:4] <= {1'b0, pixel_D0_r[7:5]};
|
||||
pixel_D1_r[3:0] <= {1'b0, pixel_D1_r[3:1]};
|
||||
pixel_D1_r[7:4] <= {1'b0, pixel_D1_r[7:5]};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//Output shifted pixel data (reverse the bits if FLIP is low)
|
||||
assign DSH0 = FLIP ? {pixel_D0_l[3], pixel_D0_l[7]} : {pixel_D0_r[0], pixel_D0_r[4]};
|
||||
assign DSH1 = FLIP ? {pixel_D1_l[3], pixel_D1_l[7]} : {pixel_D1_r[0], pixel_D1_r[4]};
|
||||
|
||||
endmodule
|
||||
101
Arcade_MiST/Konami Gyruss/rtl/custom/k501.sv
Normal file
101
Arcade_MiST/Konami Gyruss/rtl/custom/k501.sv
Normal file
@@ -0,0 +1,101 @@
|
||||
//============================================================================
|
||||
//
|
||||
// SystemVerilog implementation of the Konami 501 custom chip, used by some
|
||||
// Konami arcade PCBs for partial address decoding and obfuscation of data
|
||||
// I/O
|
||||
// Copyright (C) 2021 Ace
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//Chip pinout:
|
||||
/* _____________
|
||||
_| |_
|
||||
D[7] |_|1 28|_| VCC
|
||||
_| |_
|
||||
D[6] |_|2 27|_| XD[7]
|
||||
_| |_
|
||||
D[5] |_|3 26|_| XD[6]
|
||||
_| |_
|
||||
D[4] |_|4 25|_| XD[5]
|
||||
_| |_
|
||||
D[3] |_|5 24|_| XD[4]
|
||||
_| |_
|
||||
D[2] |_|6 23|_| XD[3]
|
||||
_| |_
|
||||
D[1] |_|7 22|_| XD[2]
|
||||
_| |_
|
||||
D[0] |_|8 21|_| XD[1]
|
||||
_| |_
|
||||
H2 |_|9 20|_| XD[0]
|
||||
_| |_
|
||||
H1 |_|10 19|_| WAIT
|
||||
_| |_
|
||||
CLK |_|11 18|_| ENABLE
|
||||
_| |_
|
||||
RAM |_|12 17|_| WRITE
|
||||
_| |_
|
||||
RD |_|13 16|_| NC
|
||||
_| |_
|
||||
GND |_|14 15|_| NC
|
||||
|_____________|
|
||||
|
||||
Note: The data bus is bidirectional - this model splits these pins into separate data I/O
|
||||
*/
|
||||
|
||||
module k501
|
||||
(
|
||||
input CLK, //Clock input (add a PLL to multiply the 6.144MHz pixel clock if replacing a real 501)
|
||||
input CEN, //Clock enable at 12.288MHz
|
||||
input H1, H2, //Bits 0 and 1 of the horizontal counter
|
||||
input RAM, //Chip select (active low)
|
||||
input RD, //Z80 read input
|
||||
output WAIT, //Z80 wait output
|
||||
output WRITE, //Write output
|
||||
output ENABLE, //Enable output
|
||||
input [7:0] Di, XDi, //Inputs from data busses
|
||||
output [7:0] Do, XDo //Outputs to data busses
|
||||
);
|
||||
|
||||
//Data bus passthrough
|
||||
assign XDo = Di;
|
||||
assign Do = XDi;
|
||||
|
||||
//Latch bit 0 of the horizontal counter on each edge of the clock and preset to 1 if bit 1 of the horizontal counter
|
||||
//is high
|
||||
reg [1:0] h1_reg = 2'd0;
|
||||
always_ff @(posedge CLK) begin
|
||||
if(H2)
|
||||
h1_reg[0] <= 1;
|
||||
else if(CEN)
|
||||
h1_reg <= {h1_reg[0], H1};
|
||||
end
|
||||
|
||||
//AND both latched instances of H1
|
||||
wire h1_lat = &h1_reg;
|
||||
|
||||
//Generate WAIT output
|
||||
assign WAIT = ~H2 | RAM;
|
||||
|
||||
//Generate WRITE and ENABLE outputs
|
||||
assign WRITE = ~RD | ENABLE;
|
||||
assign ENABLE = h1_lat | RAM;
|
||||
|
||||
endmodule
|
||||
162
Arcade_MiST/Konami Gyruss/rtl/custom/k502.sv
Normal file
162
Arcade_MiST/Konami Gyruss/rtl/custom/k502.sv
Normal file
@@ -0,0 +1,162 @@
|
||||
//============================================================================
|
||||
//
|
||||
// SystemVerilog implementation of the Konami 502 custom chip, used for
|
||||
// generating sprites on a number of '80s Konami arcade PCBs
|
||||
// Copyright (C) 2020, 2021 Ace
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//Chip pinout:
|
||||
/* _____________
|
||||
_| |_
|
||||
SPLB(0) |_|1 28|_| VCC
|
||||
_| |_
|
||||
SPLB(1) |_|2 27|_| RESET
|
||||
_| |_
|
||||
SPLB(2) |_|3 26|_| SPLB(4)
|
||||
_| |_
|
||||
SPLB(3) |_|4 25|_| SPLB(5)
|
||||
_| |_
|
||||
CK1 |_|5 24|_| SPLB(6)
|
||||
_| |_
|
||||
CK2 |_|6 23|_| SPLB(7)
|
||||
_| |_
|
||||
H2 |_|7 22|_| OLD
|
||||
_| |_
|
||||
LD0 |_|8 21|_| OCLR
|
||||
_| |_
|
||||
H256 |_|9 20|_| OSEL
|
||||
_| |_
|
||||
SPAL(3) |_|10 19|_| COL(4)
|
||||
_| |_
|
||||
SPAL(2) |_|11 18|_| COL(3)
|
||||
_| |_
|
||||
SPAL(1) |_|12 17|_| COL(2)
|
||||
_| |_
|
||||
SPAL(0) |_|13 16|_| COL(1)
|
||||
_| |_
|
||||
GND |_|14 15|_| COL(0)
|
||||
|_____________|
|
||||
|
||||
Note: The SPLB pins are bidirectional - this model splits these pins into separate
|
||||
data I/O
|
||||
*/
|
||||
|
||||
module k502
|
||||
(
|
||||
input RESET,
|
||||
input CK1,
|
||||
input CK2,
|
||||
input CEN, //Set to 1 if using this code to replace a real 502
|
||||
input LD0,
|
||||
input H2,
|
||||
input H256,
|
||||
input [3:0] SPAL,
|
||||
input [7:0] SPLBi,
|
||||
output OSEL,
|
||||
output OLD,
|
||||
output OCLR,
|
||||
output [7:0] SPLBo,
|
||||
output [4:0] COL
|
||||
);
|
||||
|
||||
//As the Konami 502 doesn't have a dedicated input for bit 2 of the horizontal counter (H4), generate
|
||||
//this signal internally by dividing H2 by 2
|
||||
reg h2_div = 0;
|
||||
always_ff @(posedge H2) begin
|
||||
h2_div <= ~h2_div;
|
||||
end
|
||||
wire h4 = h2_div;
|
||||
|
||||
//Latch H256 on rising edge of LD0 and delay by one cycle (set to 0 if 502 is held in reset)
|
||||
reg h256_lat = 0;
|
||||
always_ff @(posedge LD0 or negedge RESET) begin
|
||||
if(!RESET)
|
||||
h256_lat <= 0;
|
||||
else
|
||||
h256_lat <= H256;
|
||||
end
|
||||
reg h256_dly = 0;
|
||||
always_ff @(posedge h256_lat or negedge RESET) begin
|
||||
if(!RESET)
|
||||
h256_dly <= 0;
|
||||
else
|
||||
h256_dly <= ~h256_dly;
|
||||
end
|
||||
|
||||
//Generate OSEL, OLD and OCLR
|
||||
reg [1:0] osel_reg;
|
||||
always_ff @(negedge H2 or negedge RESET) begin
|
||||
if(!RESET)
|
||||
osel_reg <= 2'b00;
|
||||
else begin
|
||||
if(!h4)
|
||||
osel_reg[1] <= h256_dly;
|
||||
else
|
||||
osel_reg[0] <= osel_reg[1];
|
||||
end
|
||||
end
|
||||
assign OLD = ~osel_reg[1];
|
||||
assign OSEL = osel_reg[0];
|
||||
assign OCLR = ~osel_reg[0];
|
||||
|
||||
//Multiplex incoming line buffer RAM data
|
||||
wire [3:0] lbuff_Dmux = OCLR ? SPLBi[3:0] : SPLBi[7:4];
|
||||
|
||||
//Latch incoming line buffer RAM data on the falling edge of CK1
|
||||
reg [7:0] lbuff_lat;
|
||||
always_ff @(negedge CK1) begin
|
||||
if(!RESET)
|
||||
lbuff_lat <= 8'd0;
|
||||
else if(CEN)
|
||||
lbuff_lat <= SPLBi;
|
||||
end
|
||||
|
||||
//Latch multiplexed line buffer RAM data on the falling edge of CK2
|
||||
reg [3:0] lbuff_mux_lat;
|
||||
always_ff @(negedge CK2) begin
|
||||
if(!RESET)
|
||||
lbuff_mux_lat <= 4'd0;
|
||||
else if(CEN)
|
||||
lbuff_mux_lat <= lbuff_Dmux;
|
||||
end
|
||||
|
||||
//Assign sprite data output
|
||||
assign COL[4] = ~(|lbuff_mux_lat[3:0]);
|
||||
assign COL[3:0] = lbuff_mux_lat[3:0];
|
||||
|
||||
//Select sprite or palette data based on a 4-way AND of the inverted latched line buffer data
|
||||
//(upper 4 bits and lower 4 bits produce separate select signals)
|
||||
wire sprite_pal_sel2 = (~lbuff_lat[7] & ~lbuff_lat[6] & ~lbuff_lat[5] & ~lbuff_lat[4]);
|
||||
wire sprite_pal_sel1 = (~lbuff_lat[3] & ~lbuff_lat[2] & ~lbuff_lat[1] & ~lbuff_lat[0]);
|
||||
|
||||
//Multiplex sprite data from line buffer with palette data (lower 4 bits)
|
||||
wire [7:0] sprite_pal_mux;
|
||||
assign sprite_pal_mux[3:0] = osel_reg[0] ? (sprite_pal_sel1 ? SPAL : SPLBi[3:0]) : 4'h0;
|
||||
|
||||
//Multiplex sprite data from line buffer with palette data (upper 4 bits)
|
||||
assign sprite_pal_mux[7:4] = ~osel_reg[0] ? (sprite_pal_sel2 ? SPAL : SPLBi[7:4]) : 4'h0;
|
||||
|
||||
//Output data to sprite line buffer
|
||||
assign SPLBo = sprite_pal_mux;
|
||||
|
||||
endmodule
|
||||
|
||||
119
Arcade_MiST/Konami Gyruss/rtl/custom/k503.sv
Normal file
119
Arcade_MiST/Konami Gyruss/rtl/custom/k503.sv
Normal file
@@ -0,0 +1,119 @@
|
||||
//============================================================================
|
||||
//
|
||||
// SystemVerilog implementation of the Konami 503 custom chip, used by
|
||||
// several Konami arcade PCBs for handling sprite data
|
||||
// Copyright (C) 2020, 2021 Ace
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//Chip pinout:
|
||||
/* _____________
|
||||
_| |_
|
||||
OB(7) |_|1 40|_| VCC
|
||||
_| |_
|
||||
OB(6) |_|2 39|_| VCNT(7)
|
||||
_| |_
|
||||
OB(5) |_|3 38|_| VCNT(6)
|
||||
_| |_
|
||||
OB(4) |_|4 37|_| VCNT(5)
|
||||
_| |_
|
||||
OB(3) |_|5 36|_| VCNT(4)
|
||||
_| |_
|
||||
OB(2) |_|6 35|_| VCNT(3)
|
||||
_| |_
|
||||
OB(1) |_|7 34|_| VCNT(2)
|
||||
_| |_
|
||||
OB(0) |_|8 33|_| VCNT(1)
|
||||
_| |_
|
||||
R(5) |_|9 32|_| VCNT(0)
|
||||
_| |_
|
||||
R(4) |_|10 31|_| NC
|
||||
_| |_
|
||||
R(3) |_|11 30|_| OFLP
|
||||
_| |_
|
||||
R(2) |_|12 29|_| OCS
|
||||
_| |_
|
||||
R(1) |_|13 28|_| NC
|
||||
_| |_
|
||||
R(0) |_|14 27|_| NC
|
||||
_| |_
|
||||
LD |_|15 26|_| NC
|
||||
_| |_
|
||||
H4 |_|16 25|_| NC
|
||||
_| |_
|
||||
H8 |_|17 24|_| NC
|
||||
_| |_
|
||||
OCOL |_|18 23|_| NC
|
||||
_| |_
|
||||
ODAT |_|19 22|_| NC
|
||||
_| |_
|
||||
GND |_|20 21|_| NC
|
||||
|_____________|
|
||||
*/
|
||||
|
||||
module k503
|
||||
(
|
||||
input [7:0] OB, //Sprite data input
|
||||
input [7:0] VCNT, //Vertical counter input
|
||||
input H4, H8, //Horizontal counter bits 2 (H4) and 3 (H8)
|
||||
input LD, //LD input (pulses low when bits 0 and 1 of the horizontal counter are both 1)
|
||||
output OCS, //Sprite line buffer chip select output
|
||||
output OFLP, //Sprite flip output
|
||||
output ODAT, //Signal to latch upper bits of sprite address
|
||||
output OCOL, //Signal to load addresses for sprite line buffer
|
||||
output [5:0] R //Lower 6 bits of sprite address
|
||||
);
|
||||
|
||||
//Sum sprite bits with vertical counter
|
||||
wire [7:0] sprite_sum = OB + VCNT;
|
||||
|
||||
//Sprite select signal
|
||||
wire sprite_sel = ~(&sprite_sum[7:4]);
|
||||
|
||||
//Sprite flip control
|
||||
reg hflip, vflip;
|
||||
always_ff @(posedge H4) begin
|
||||
hflip <= OB[6];
|
||||
vflip <= OB[7];
|
||||
end
|
||||
|
||||
//Latch sprite information
|
||||
reg [6:0] sprite;
|
||||
always_ff @(negedge H4) begin
|
||||
sprite <= {sprite_sel, hflip, vflip, sprite_sum[3:0]};
|
||||
end
|
||||
wire sprite_vflip = sprite[4];
|
||||
assign OFLP = sprite[5];
|
||||
assign OCS = sprite[6];
|
||||
|
||||
//Assign OCOL (sprite color) and ODAT (sprite data) outputs
|
||||
assign OCOL = ({H8, H4, LD} != 3'b100);
|
||||
assign ODAT = ({H8, H4, LD} != 3'b010);
|
||||
|
||||
//XOR final output for R
|
||||
assign R[5] = (sprite[3] ^ sprite_vflip);
|
||||
assign R[4] = (OFLP ^ H8);
|
||||
assign R[3] = (OFLP ^ ~H4);
|
||||
assign R[2] = (sprite[2] ^ sprite_vflip);
|
||||
assign R[1] = (sprite[1] ^ sprite_vflip);
|
||||
assign R[0] = (sprite[0] ^ sprite_vflip);
|
||||
|
||||
endmodule
|
||||
602
Arcade_MiST/Konami Gyruss/rtl/hiscore.v
Normal file
602
Arcade_MiST/Konami Gyruss/rtl/hiscore.v
Normal file
@@ -0,0 +1,602 @@
|
||||
//============================================================================
|
||||
// MAME hiscore.dat support for MiSTer arcade cores.
|
||||
//
|
||||
// https://github.com/JimmyStones/Hiscores_MiSTer
|
||||
//
|
||||
// Copyright (c) 2021 Alan Steremberg
|
||||
// Copyright (c) 2021 Jim Gregory
|
||||
//
|
||||
// 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 3 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.
|
||||
//============================================================================
|
||||
/*
|
||||
Version history:
|
||||
0001 - 2021-03-06 - First marked release
|
||||
0002 - 2021-03-06 - Added HS_DUMPFORMAT localparam to identify dump version (for future use)
|
||||
Add HS_CONFIGINDEX and HS_DUMPINDEX parameters to configure ioctl_indexes
|
||||
0003 - 2021-03-10 - Added WRITE_REPEATCOUNT and WRITE_REPEATWAIT to handle tricky write situations
|
||||
0004 - 2021-03-15 - Fix ram_access assignment
|
||||
0005 - 2021-03-18 - Add configurable score table width, clean up some stupid mistakes
|
||||
0006 - 2021-03-27 - Move 'tweakable' parameters into MRA data header
|
||||
0007 - 2021-04-15 - Improve state machine maintainability, add new 'pause padding' states
|
||||
0008 - 2021-05-12 - Feed back core-level pause to halt startup timer
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
module hiscore
|
||||
#(
|
||||
parameter HS_ADDRESSWIDTH=10, // Max size of game RAM address for highscores
|
||||
parameter HS_SCOREWIDTH=8, // Max size of capture RAM For highscore data (default 8 = 256 bytes max)
|
||||
parameter HS_CONFIGINDEX=3, // ioctl_index for config transfer
|
||||
parameter HS_DUMPINDEX=4, // ioctl_index for dump transfer
|
||||
parameter CFG_ADDRESSWIDTH=4, // Max size of RAM address for highscore.dat entries (default 4 = 16 entries max)
|
||||
parameter CFG_LENGTHWIDTH=1 // Max size of length for each highscore.dat entries (default 1 = 256 bytes max)
|
||||
)
|
||||
(
|
||||
input clk,
|
||||
input paused, // Signal from core confirming CPU is paused
|
||||
input reset,
|
||||
|
||||
input ioctl_upload,
|
||||
input ioctl_download,
|
||||
input ioctl_wr,
|
||||
input [24:0] ioctl_addr,
|
||||
input [7:0] ioctl_dout,
|
||||
input [7:0] ioctl_din,
|
||||
input [7:0] ioctl_index,
|
||||
|
||||
output [HS_ADDRESSWIDTH-1:0] ram_address, // Address in game RAM to read/write score data
|
||||
output [7:0] data_to_ram, // Data to write to game RAM
|
||||
output reg ram_write, // Write to game RAM (active high)
|
||||
output ram_access, // RAM read or write required (active high)
|
||||
output reg pause_cpu // Pause core CPU to prepare for/relax after RAM access
|
||||
);
|
||||
|
||||
// Parameters read from config header
|
||||
reg [31:0] START_WAIT =32'd0; // Delay before beginning check process
|
||||
reg [15:0] CHECK_WAIT =16'hFF; // Delay between start/end check attempts
|
||||
reg [15:0] CHECK_HOLD =16'd2; // Hold time for start/end check reads
|
||||
reg [15:0] WRITE_HOLD =16'd2; // Hold time for game RAM writes
|
||||
reg [15:0] WRITE_REPEATCOUNT =16'b1; // Number of times to write score to game RAM
|
||||
reg [15:0] WRITE_REPEATWAIT =16'b1111; // Delay between subsequent write attempts to game RAM
|
||||
reg [7:0] ACCESS_PAUSEPAD =8'd4; // Cycles to wait with paused CPU before and after RAM access
|
||||
|
||||
|
||||
// State machine constants
|
||||
localparam SM_STATEWIDTH = 4; // Width of state machine net
|
||||
|
||||
localparam SM_INIT = 0;
|
||||
localparam SM_TIMER = 1;
|
||||
|
||||
localparam SM_CHECKPREP = 2;
|
||||
localparam SM_CHECKBEGIN = 3;
|
||||
localparam SM_CHECKSTARTVAL = 4;
|
||||
localparam SM_CHECKENDVAL = 5;
|
||||
localparam SM_CHECKCANCEL = 6;
|
||||
|
||||
localparam SM_WRITEPREP = 7;
|
||||
localparam SM_WRITEBEGIN = 8;
|
||||
localparam SM_WRITEREADY = 9;
|
||||
localparam SM_WRITEDONE = 10;
|
||||
localparam SM_WRITECOMPLETE = 11;
|
||||
localparam SM_WRITERETRY = 12;
|
||||
|
||||
localparam SM_STOPPED = 13;
|
||||
|
||||
/*
|
||||
Hiscore config data structure (version 1)
|
||||
-----------------------------------------
|
||||
[16 byte header]
|
||||
[8 byte * no. of entries]
|
||||
|
||||
- Header format
|
||||
00 00 FF FF 00 FF 00 02 00 02 00 01 11 11 00 00
|
||||
[ SW ] [ CW] [ CH] [ WH] [WRC] [WRW] [PAD]
|
||||
4 byte START_WAIT
|
||||
2 byte CHECK_WAIT
|
||||
2 byte CHECK_HOLD
|
||||
2 byte WRITE_HOLD
|
||||
2 byte WRITE_REPEATCOUNT
|
||||
2 byte WRITE_REPEATWAIT
|
||||
2 byte (padding/future use)
|
||||
|
||||
- Entry format (when CFG_LENGTHWIDTH=1)
|
||||
00 00 43 0b 0f 10 01 00
|
||||
00 00 40 23 02 04 12 00
|
||||
[ ADDR ] LEN START END PAD
|
||||
|
||||
4 bytes Address of ram entry (in core memory map)
|
||||
1 byte Length of ram entry in bytes
|
||||
1 byte Start value to check for at start of address range before proceeding
|
||||
1 byte End value to check for at end of address range before proceeding
|
||||
1 byte (padding)
|
||||
|
||||
- Entry format (when CFG_LENGTHWIDTH=2)
|
||||
00 00 43 0b 00 0f 10 01
|
||||
00 00 40 23 00 02 04 12
|
||||
[ ADDR ] [LEN ] START END
|
||||
|
||||
4 bytes Address of ram entry (in core memory map)
|
||||
2 bytes Length of ram entry in bytes
|
||||
1 byte Start value to check for at start of address range before proceeding
|
||||
1 byte End value to check for at end of address range before proceeding
|
||||
|
||||
*/
|
||||
|
||||
localparam HS_VERSION =8; // Version identifier for module
|
||||
localparam HS_DUMPFORMAT =1; // Version identifier for dump format
|
||||
localparam HS_HEADERLENGTH =16; // Size of header chunk (default=16 bytes)
|
||||
|
||||
// HS_DUMPFORMAT = 1 --> No header, just the extracted hiscore data
|
||||
|
||||
// Hiscore config and dump status
|
||||
wire downloading_config;
|
||||
wire parsing_header;
|
||||
wire downloading_dump;
|
||||
wire uploading_dump;
|
||||
reg downloaded_config = 1'b0;
|
||||
reg downloaded_dump = 1'b0;
|
||||
reg uploaded_dump = 1'b0;
|
||||
reg [3:0] initialised;
|
||||
reg writing_scores = 1'b0;
|
||||
reg checking_scores = 1'b0;
|
||||
|
||||
assign downloading_config = ioctl_download && (ioctl_index==HS_CONFIGINDEX);
|
||||
assign parsing_header = downloading_config && (ioctl_addr<=HS_HEADERLENGTH);
|
||||
assign downloading_dump = ioctl_download && (ioctl_index==HS_DUMPINDEX);
|
||||
assign uploading_dump = ioctl_upload && (ioctl_index==HS_DUMPINDEX);
|
||||
assign ram_access = uploading_dump | writing_scores | checking_scores;
|
||||
assign ram_address = ram_addr[HS_ADDRESSWIDTH-1:0];
|
||||
|
||||
reg [(SM_STATEWIDTH-1):0] state = SM_INIT; // Current state machine index
|
||||
reg [(SM_STATEWIDTH-1):0] next_state = SM_INIT; // Next state machine index to move to after wait timer expires
|
||||
reg [31:0] wait_timer; // Wait timer for inital/read/write delays
|
||||
|
||||
reg [CFG_ADDRESSWIDTH-1:0] counter = 1'b0; // Index for current config table entry
|
||||
reg [CFG_ADDRESSWIDTH-1:0] total_entries = 1'b0; // Total count of config table entries
|
||||
reg reset_last = 1'b0; // Last cycle reset
|
||||
reg [7:0] write_counter = 1'b0; // Index of current game RAM write attempt
|
||||
|
||||
reg [7:0] last_ioctl_index; // Last cycle HPS IO index
|
||||
reg last_ioctl_download = 0;// Last cycle HPS IO download
|
||||
reg last_ioctl_upload = 0; // Last cycle HPS IO upload
|
||||
reg [7:0] last_ioctl_dout; // Last cycle HPS IO data out
|
||||
reg [7:0] last_ioctl_dout2; // Last cycle +1 HPS IO data out
|
||||
reg [7:0] last_ioctl_dout3; // Last cycle +2 HPS IO data out
|
||||
|
||||
reg [24:0] ram_addr; // Target RAM address for hiscore read/write
|
||||
reg [24:0] old_io_addr;
|
||||
reg [24:0] base_io_addr;
|
||||
wire [23:0] addr_base;
|
||||
wire [(CFG_LENGTHWIDTH*8)-1:0] length;
|
||||
wire [24:0] end_addr = (addr_base + length - 1'b1);
|
||||
reg [HS_SCOREWIDTH-1:0] local_addr;
|
||||
wire [7:0] start_val;
|
||||
wire [7:0] end_val;
|
||||
|
||||
wire [23:0] address_data_in;
|
||||
wire [(CFG_LENGTHWIDTH*8)-1:0] length_data_in;
|
||||
|
||||
assign address_data_in = {last_ioctl_dout2, last_ioctl_dout, ioctl_dout};
|
||||
assign length_data_in = (CFG_LENGTHWIDTH == 1'b1) ? ioctl_dout : {last_ioctl_dout, ioctl_dout};
|
||||
|
||||
wire address_we = downloading_config & ~parsing_header & (ioctl_addr[2:0] == 3'd3);
|
||||
wire length_we = downloading_config & ~parsing_header & (ioctl_addr[2:0] == 3'd3 + CFG_LENGTHWIDTH);
|
||||
wire startdata_we = downloading_config & ~parsing_header & (ioctl_addr[2:0] == 3'd4 + CFG_LENGTHWIDTH);
|
||||
wire enddata_we = downloading_config & ~parsing_header & (ioctl_addr[2:0] == 3'd5 + CFG_LENGTHWIDTH);
|
||||
|
||||
// RAM chunks used to store configuration data
|
||||
// - address_table
|
||||
// - length_table
|
||||
// - startdata_table
|
||||
// - enddata_table
|
||||
dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(24))
|
||||
address_table(
|
||||
.clk(clk),
|
||||
.addr_a(ioctl_addr[CFG_ADDRESSWIDTH+2:3] - 2'd2),
|
||||
.we_a(address_we & ioctl_wr),
|
||||
.d_a(address_data_in),
|
||||
.addr_b(counter),
|
||||
.q_b(addr_base)
|
||||
);
|
||||
// Length table - variable width depending on CFG_LENGTHWIDTH
|
||||
dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(CFG_LENGTHWIDTH*8))
|
||||
length_table(
|
||||
.clk(clk),
|
||||
.addr_a(ioctl_addr[CFG_ADDRESSWIDTH+2:3] - 2'd2),
|
||||
.we_a(length_we & ioctl_wr),
|
||||
.d_a(length_data_in),
|
||||
.addr_b(counter),
|
||||
.q_b(length)
|
||||
);
|
||||
dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(8))
|
||||
startdata_table(
|
||||
.clk(clk),
|
||||
.addr_a(ioctl_addr[CFG_ADDRESSWIDTH+2:3] - 2'd2),
|
||||
.we_a(startdata_we & ioctl_wr),
|
||||
.d_a(ioctl_dout),
|
||||
.addr_b(counter),
|
||||
.q_b(start_val)
|
||||
);
|
||||
dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(8))
|
||||
enddata_table(
|
||||
.clk(clk),
|
||||
.addr_a(ioctl_addr[CFG_ADDRESSWIDTH+2:3] - 2'd2),
|
||||
.we_a(enddata_we & ioctl_wr),
|
||||
.d_a(ioctl_dout),
|
||||
.addr_b(counter),
|
||||
.q_b(end_val)
|
||||
);
|
||||
|
||||
// RAM chunk used to store hiscore data
|
||||
dpram_hs #(.aWidth(HS_SCOREWIDTH),.dWidth(8))
|
||||
hiscoredata (
|
||||
.clk(clk),
|
||||
.addr_a(ioctl_addr[(HS_SCOREWIDTH-1):0]),
|
||||
.we_a(downloading_dump),
|
||||
.d_a(ioctl_dout),
|
||||
.addr_b(local_addr),
|
||||
.we_b(ioctl_upload),
|
||||
.d_b(ioctl_din),
|
||||
.q_b(data_to_ram)
|
||||
);
|
||||
|
||||
wire [3:0] header_chunk = ioctl_addr[3:0];
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
|
||||
if (downloading_config)
|
||||
begin
|
||||
// Get header chunk data
|
||||
if(parsing_header)
|
||||
begin
|
||||
if(ioctl_wr)
|
||||
begin
|
||||
if(header_chunk == 4'd3) START_WAIT <= { last_ioctl_dout3, last_ioctl_dout2, last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd5) CHECK_WAIT <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd7) CHECK_HOLD <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd9) WRITE_HOLD <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd11) WRITE_REPEATCOUNT <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd13) WRITE_REPEATWAIT <= { last_ioctl_dout, ioctl_dout };
|
||||
if(header_chunk == 4'd14) ACCESS_PAUSEPAD <= ioctl_dout;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
// Keep track of the largest entry during config download
|
||||
total_entries <= ioctl_addr[CFG_ADDRESSWIDTH+2:3] - 2'd2;
|
||||
end
|
||||
end
|
||||
|
||||
// Track completion of configuration and dump download
|
||||
if ((last_ioctl_download != ioctl_download) && (ioctl_download == 1'b0))
|
||||
begin
|
||||
if (last_ioctl_index==HS_CONFIGINDEX) downloaded_config <= 1'b1;
|
||||
if (last_ioctl_index==HS_DUMPINDEX) downloaded_dump <= 1'b1;
|
||||
end
|
||||
|
||||
// Track completion of dump upload
|
||||
if ((last_ioctl_upload != ioctl_upload) && (ioctl_upload == 1'b0))
|
||||
begin
|
||||
if (last_ioctl_index==HS_DUMPINDEX)
|
||||
begin
|
||||
uploaded_dump <= 1'b1;
|
||||
// Mark uploaded dump as readable in case of reset
|
||||
downloaded_dump <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// Track last ioctl values
|
||||
last_ioctl_download <= ioctl_download;
|
||||
last_ioctl_upload <= ioctl_upload;
|
||||
last_ioctl_index <= ioctl_index;
|
||||
if(ioctl_download && ioctl_wr)
|
||||
begin
|
||||
last_ioctl_dout3 = last_ioctl_dout2;
|
||||
last_ioctl_dout2 = last_ioctl_dout;
|
||||
last_ioctl_dout = ioctl_dout;
|
||||
end
|
||||
|
||||
if(downloaded_config)
|
||||
begin
|
||||
// Check for end of state machine reset to initialise state machine
|
||||
reset_last <= reset;
|
||||
if (reset_last == 1'b1 && reset == 1'b0)
|
||||
begin
|
||||
wait_timer <= START_WAIT;
|
||||
next_state <= SM_INIT;
|
||||
state <= SM_TIMER;
|
||||
counter <= 1'b0;
|
||||
initialised <= initialised + 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// Upload scores to HPS
|
||||
if (uploading_dump == 1'b1)
|
||||
begin
|
||||
// generate addresses to read high score from game memory. Base addresses off ioctl_address
|
||||
if (ioctl_addr == 25'b0) begin
|
||||
local_addr <= 0;
|
||||
base_io_addr <= 25'b0;
|
||||
counter <= 1'b0000;
|
||||
end
|
||||
// Move to next entry when last address is reached
|
||||
if (old_io_addr!=ioctl_addr && ram_addr==end_addr[24:0])
|
||||
begin
|
||||
counter <= counter + 1'b1;
|
||||
base_io_addr <= ioctl_addr;
|
||||
end
|
||||
// Set game ram address for reading back to HPS
|
||||
ram_addr <= addr_base + (ioctl_addr - base_io_addr);
|
||||
// Set local addresses to update cached dump in case of reset
|
||||
local_addr <= ioctl_addr[HS_SCOREWIDTH-1:0];
|
||||
end
|
||||
|
||||
if (ioctl_upload == 1'b0 && downloaded_dump == 1'b1 && reset == 1'b0)
|
||||
begin
|
||||
// State machine to write data to game RAM
|
||||
case (state)
|
||||
SM_INIT: // Start state machine
|
||||
begin
|
||||
// Setup base addresses
|
||||
local_addr <= 0;
|
||||
base_io_addr <= 25'b0;
|
||||
// Reset entry counter and states
|
||||
counter <= 0;
|
||||
writing_scores <= 1'b0;
|
||||
checking_scores <= 1'b0;
|
||||
pause_cpu <= 1'b0;
|
||||
state <= SM_CHECKPREP;
|
||||
end
|
||||
|
||||
// Start/end check states
|
||||
// ----------------------
|
||||
SM_CHECKPREP: // Prepare start/end check run - pause CPU in readiness for RAM access
|
||||
begin
|
||||
state <= SM_TIMER;
|
||||
next_state <= SM_CHECKBEGIN;
|
||||
pause_cpu <= 1'b1;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
|
||||
SM_CHECKBEGIN: // Begin start/end check run - enable RAM access
|
||||
begin
|
||||
checking_scores <= 1'b1;
|
||||
ram_addr <= {1'b0, addr_base};
|
||||
state <= SM_CHECKSTARTVAL;
|
||||
wait_timer <= CHECK_HOLD;
|
||||
end
|
||||
|
||||
SM_CHECKSTARTVAL: // Start check
|
||||
begin
|
||||
// Check for matching start value
|
||||
if(wait_timer != CHECK_HOLD & ioctl_din == start_val)
|
||||
begin
|
||||
// Prepare end check
|
||||
ram_addr <= end_addr;
|
||||
state <= SM_CHECKENDVAL;
|
||||
wait_timer <= CHECK_HOLD;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ram_addr <= {1'b0, addr_base};
|
||||
if (wait_timer > 1'b0)
|
||||
begin
|
||||
wait_timer <= wait_timer - 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// - If no match after read wait then stop check run and schedule restart of state machine
|
||||
next_state <= SM_CHECKCANCEL;
|
||||
state <= SM_TIMER;
|
||||
checking_scores <= 1'b0;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SM_CHECKENDVAL: // End check
|
||||
begin
|
||||
// Check for matching end value
|
||||
if (wait_timer != CHECK_HOLD & ioctl_din == end_val)
|
||||
begin
|
||||
if (counter == total_entries)
|
||||
begin
|
||||
// If this was the last entry then move on to writing scores to game ram
|
||||
checking_scores <= 1'b0;
|
||||
state <= SM_WRITEBEGIN; // Bypass SM_WRITEPREP as we are already paused
|
||||
counter <= 1'b0;
|
||||
write_counter <= 1'b0;
|
||||
ram_write <= 1'b0;
|
||||
ram_addr <= {1'b0, addr_base};
|
||||
end
|
||||
else
|
||||
begin
|
||||
// Increment counter and restart state machine to check next entry
|
||||
counter <= counter + 1'b1;
|
||||
state <= SM_CHECKBEGIN;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
ram_addr <= end_addr;
|
||||
if (wait_timer > 1'b0)
|
||||
begin
|
||||
wait_timer <= wait_timer - 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// - If no match after read wait then stop check run and schedule restart of state machine
|
||||
next_state <= SM_CHECKCANCEL;
|
||||
state <= SM_TIMER;
|
||||
checking_scores <= 1'b0;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
SM_CHECKCANCEL: // Cancel start/end check run - disable RAM access and keep CPU paused
|
||||
begin
|
||||
pause_cpu <= 1'b0;
|
||||
next_state <= SM_INIT;
|
||||
state <= SM_TIMER;
|
||||
wait_timer <= CHECK_WAIT;
|
||||
end
|
||||
|
||||
// Write to game RAM states
|
||||
// ----------------------
|
||||
SM_WRITEPREP: // Prepare to write scores - pause CPU in readiness for RAM access (only used on subsequent write attempts)
|
||||
begin
|
||||
state <= SM_TIMER;
|
||||
next_state <= SM_WRITEBEGIN;
|
||||
pause_cpu <= 1'b1;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
|
||||
SM_WRITEBEGIN: // Writing scores to game RAM begins
|
||||
begin
|
||||
writing_scores <= 1'b1; // Enable muxes if necessary
|
||||
write_counter <= write_counter + 1'b1;
|
||||
state <= SM_WRITEREADY;
|
||||
end
|
||||
|
||||
SM_WRITEREADY: // local ram should be correct, start write to game RAM
|
||||
begin
|
||||
ram_addr <= addr_base + (local_addr - base_io_addr);
|
||||
state <= SM_TIMER;
|
||||
next_state <= SM_WRITEDONE;
|
||||
wait_timer <= WRITE_HOLD;
|
||||
ram_write <= 1'b1;
|
||||
end
|
||||
|
||||
SM_WRITEDONE:
|
||||
begin
|
||||
local_addr <= local_addr + 1'b1; // Increment to next byte of entry
|
||||
if (ram_addr == end_addr)
|
||||
begin
|
||||
// End of entry reached
|
||||
if (counter == total_entries)
|
||||
begin
|
||||
state <= SM_WRITECOMPLETE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// Move to next entry
|
||||
counter <= counter + 1'b1;
|
||||
write_counter <= 1'b0;
|
||||
base_io_addr <= local_addr + 1'b1;
|
||||
state <= SM_WRITEBEGIN;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
state <= SM_WRITEREADY;
|
||||
end
|
||||
ram_write <= 1'b0;
|
||||
end
|
||||
|
||||
SM_WRITECOMPLETE: // Hiscore write to RAM completed
|
||||
begin
|
||||
ram_write <= 1'b0;
|
||||
writing_scores <= 1'b0;
|
||||
state <= SM_TIMER;
|
||||
if(write_counter < WRITE_REPEATCOUNT)
|
||||
begin
|
||||
// Schedule next write
|
||||
next_state <= SM_WRITERETRY;
|
||||
local_addr <= 0;
|
||||
wait_timer <= WRITE_REPEATWAIT;
|
||||
end
|
||||
else
|
||||
begin
|
||||
next_state <= SM_STOPPED;
|
||||
wait_timer <= ACCESS_PAUSEPAD;
|
||||
end
|
||||
end
|
||||
|
||||
SM_WRITERETRY: // Stop pause and schedule next write
|
||||
begin
|
||||
pause_cpu <= 1'b0;
|
||||
state <= SM_TIMER;
|
||||
next_state <= SM_WRITEPREP;
|
||||
wait_timer <= WRITE_REPEATWAIT;
|
||||
end
|
||||
|
||||
SM_STOPPED:
|
||||
begin
|
||||
pause_cpu <= 1'b0;
|
||||
end
|
||||
|
||||
SM_TIMER: // timer wait state
|
||||
begin
|
||||
// Do not progress timer if CPU is paused by source other than this module
|
||||
// - Stops initial hiscore load delay being foiled by user pausing/entering OSD
|
||||
if (paused == 1'b0 || pause_cpu == 1'b1)
|
||||
begin
|
||||
if (wait_timer > 1'b0)
|
||||
wait_timer <= wait_timer - 1'b1;
|
||||
else
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
old_io_addr<=ioctl_addr;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module dpram_hs #(
|
||||
parameter dWidth=8,
|
||||
parameter aWidth=8
|
||||
)(
|
||||
input clk,
|
||||
|
||||
input [aWidth-1:0] addr_a,
|
||||
input [dWidth-1:0] d_a,
|
||||
input we_a,
|
||||
output reg [dWidth-1:0] q_a,
|
||||
|
||||
input [aWidth-1:0] addr_b,
|
||||
input [dWidth-1:0] d_b,
|
||||
input we_b,
|
||||
output reg [dWidth-1:0] q_b
|
||||
);
|
||||
|
||||
reg [dWidth-1:0] ram [2**aWidth-1:0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (we_a) begin
|
||||
ram[addr_a] <= d_a;
|
||||
q_a <= d_a;
|
||||
end
|
||||
else
|
||||
begin
|
||||
q_a <= ram[addr_a];
|
||||
end
|
||||
|
||||
if (we_b) begin
|
||||
ram[addr_b] <= d_b;
|
||||
q_b <= d_b;
|
||||
end
|
||||
else
|
||||
begin
|
||||
q_b <= ram[addr_b];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
64
Arcade_MiST/Konami Gyruss/rtl/jt49_dcrm2.v
Normal file
64
Arcade_MiST/Konami Gyruss/rtl/jt49_dcrm2.v
Normal file
@@ -0,0 +1,64 @@
|
||||
/* This file is part of JT49.
|
||||
|
||||
JT49 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.
|
||||
|
||||
JT49 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 JT49. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Jose Tejada Gomez. Twitter: @topapate
|
||||
Version: 1.0
|
||||
Date: 15-Jan-2019
|
||||
|
||||
*/
|
||||
|
||||
// DC removal filter
|
||||
// input is unsigned
|
||||
// output is signed
|
||||
|
||||
module jt49_dcrm2 #(parameter sw=8) (
|
||||
input clk,
|
||||
input cen,
|
||||
input rst,
|
||||
input [sw-1:0] din,
|
||||
output signed [sw-1:0] dout
|
||||
);
|
||||
|
||||
localparam dw=10; // width of the decimal portion
|
||||
|
||||
reg signed [sw+dw:0] integ, exact, error;
|
||||
//reg signed [2*(9+dw)-1:0] mult;
|
||||
// wire signed [sw+dw:0] plus1 = { {sw+dw{1'b0}},1'b1};
|
||||
reg signed [sw:0] pre_dout;
|
||||
// reg signed [sw+dw:0] dout_ext;
|
||||
reg signed [sw:0] q;
|
||||
|
||||
always @(*) begin
|
||||
exact = integ+error;
|
||||
q = exact[sw+dw:dw];
|
||||
pre_dout = { 1'b0, din } - q;
|
||||
//dout_ext = { pre_dout, {dw{1'b0}} };
|
||||
//mult = dout_ext;
|
||||
end
|
||||
|
||||
assign dout = pre_dout[sw-1:0];
|
||||
|
||||
always @(posedge clk)
|
||||
if( rst ) begin
|
||||
integ <= {sw+dw+1{1'b0}};
|
||||
error <= {sw+dw+1{1'b0}};
|
||||
end else if( cen ) begin
|
||||
/* verilator lint_off WIDTH */
|
||||
integ <= integ + pre_dout; //mult[sw+dw*2:dw];
|
||||
/* verilator lint_on WIDTH */
|
||||
error <= exact-{q, {dw{1'b0}}};
|
||||
end
|
||||
|
||||
endmodule
|
||||
58
Arcade_MiST/Konami Gyruss/rtl/jtframe_frac_cen.v
Normal file
58
Arcade_MiST/Konami Gyruss/rtl/jtframe_frac_cen.v
Normal file
@@ -0,0 +1,58 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Fractional clock enable signal
|
||||
// W refers to the number of divided down cen signals available
|
||||
// each one is divided by 2
|
||||
|
||||
module jtframe_frac_cen #(parameter W=2)(
|
||||
input clk,
|
||||
input [9:0] n, // numerator
|
||||
input [9:0] m, // denominator
|
||||
output reg [W-1:0] cen,
|
||||
output reg [W-1:0] cenb // 180 shifted
|
||||
);
|
||||
|
||||
wire [10:0] step={1'b0,n};
|
||||
wire [10:0] lim ={1'b0,m};
|
||||
wire [10:0] absmax = lim+step;
|
||||
|
||||
reg [10:0] cencnt=11'd0;
|
||||
reg [10:0] next;
|
||||
reg [10:0] next2;
|
||||
|
||||
always @(*) begin
|
||||
next = cencnt+step;
|
||||
next2 = next-lim;
|
||||
end
|
||||
|
||||
reg half = 1'b0;
|
||||
wire over = next>=lim;
|
||||
wire halfway = next >= (lim>>1) && !half;
|
||||
|
||||
reg [W-1:0] edgecnt = {W{1'b0}};
|
||||
wire [W-1:0] next_edgecnt = edgecnt + 1'b1;
|
||||
wire [W-1:0] toggle = next_edgecnt & ~edgecnt;
|
||||
|
||||
always @(posedge clk) begin
|
||||
cen <= {W{1'b0}};
|
||||
cenb <= {W{1'b0}};
|
||||
|
||||
if( cencnt >= absmax ) begin
|
||||
// something went wrong: restart
|
||||
cencnt <= 11'd0;
|
||||
end else
|
||||
if( halfway ) begin
|
||||
half <= 1'b1;
|
||||
cenb[0] <= 1'b1;
|
||||
end
|
||||
if( over ) begin
|
||||
cencnt <= next2;
|
||||
half <= 1'b0;
|
||||
edgecnt <= next_edgecnt;
|
||||
cen <= { toggle[W-2:0], 1'b1 };
|
||||
end else begin
|
||||
cencnt <= next;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
4
Arcade_MiST/Konami Gyruss/rtl/pll.qip
Normal file
4
Arcade_MiST/Konami Gyruss/rtl/pll.qip
Normal file
@@ -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"]
|
||||
348
Arcade_MiST/Konami Gyruss/rtl/pll.v
Normal file
348
Arcade_MiST/Konami Gyruss/rtl/pll.v
Normal file
@@ -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 Full Version
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//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 = 105,
|
||||
altpll_component.clk0_duty_cycle = 50,
|
||||
altpll_component.clk0_multiply_by = 191,
|
||||
altpll_component.clk0_phase_shift = "0",
|
||||
altpll_component.clk1_divide_by = 360,
|
||||
altpll_component.clk1_duty_cycle = 50,
|
||||
altpll_component.clk1_multiply_by = 191,
|
||||
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 "360"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "49.114285"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "14.325000"
|
||||
// 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 "191"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "191"
|
||||
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "49.15200000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "14.31818000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
|
||||
// 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 "105"
|
||||
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "191"
|
||||
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "360"
|
||||
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "191"
|
||||
// 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
|
||||
136
Arcade_MiST/Konami Gyruss/rtl/ram_rom/dpram_dc.vhd
Normal file
136
Arcade_MiST/Konami Gyruss/rtl/ram_rom/dpram_dc.vhd
Normal file
@@ -0,0 +1,136 @@
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.all;
|
||||
|
||||
ENTITY dpram_dc IS
|
||||
GENERIC
|
||||
(
|
||||
init_file : string := " ";
|
||||
widthad_a : natural;
|
||||
width_a : natural := 8;
|
||||
outdata_reg_a : string := "UNREGISTERED";
|
||||
outdata_reg_b : string := "UNREGISTERED"
|
||||
);
|
||||
PORT
|
||||
(
|
||||
address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
|
||||
address_b : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0) := (others => '0');
|
||||
clock_a : IN STD_LOGIC ;
|
||||
clock_b : IN STD_LOGIC ;
|
||||
data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) := (others => '0');
|
||||
data_b : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0) := (others => '0');
|
||||
wren_a : IN STD_LOGIC := '0';
|
||||
wren_b : IN STD_LOGIC := '0';
|
||||
byteena_a : IN STD_LOGIC_VECTOR (width_a/8-1 DOWNTO 0) := (others => '1');
|
||||
byteena_b : IN STD_LOGIC_VECTOR (width_a/8-1 DOWNTO 0) := (others => '1');
|
||||
q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
q_b : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0)
|
||||
);
|
||||
END dpram_dc;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF dpram_dc IS
|
||||
|
||||
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
SIGNAL sub_wire1 : STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
|
||||
|
||||
|
||||
COMPONENT altsyncram
|
||||
GENERIC (
|
||||
address_reg_b : STRING;
|
||||
clock_enable_input_a : STRING;
|
||||
clock_enable_input_b : STRING;
|
||||
clock_enable_output_a : STRING;
|
||||
clock_enable_output_b : STRING;
|
||||
indata_reg_b : STRING;
|
||||
init_file : STRING;
|
||||
intended_device_family : STRING;
|
||||
lpm_type : STRING;
|
||||
numwords_a : NATURAL;
|
||||
numwords_b : NATURAL;
|
||||
operation_mode : STRING;
|
||||
outdata_aclr_a : STRING;
|
||||
outdata_aclr_b : STRING;
|
||||
outdata_reg_a : STRING;
|
||||
outdata_reg_b : STRING;
|
||||
power_up_uninitialized : STRING;
|
||||
read_during_write_mode_port_a : STRING;
|
||||
read_during_write_mode_port_b : STRING;
|
||||
widthad_a : NATURAL;
|
||||
widthad_b : NATURAL;
|
||||
width_a : NATURAL;
|
||||
width_b : NATURAL;
|
||||
width_byteena_a : NATURAL;
|
||||
width_byteena_b : NATURAL;
|
||||
wrcontrol_wraddress_reg_b : STRING
|
||||
);
|
||||
PORT (
|
||||
wren_a : IN STD_LOGIC ;
|
||||
clock0 : IN STD_LOGIC ;
|
||||
wren_b : IN STD_LOGIC ;
|
||||
clock1 : IN STD_LOGIC ;
|
||||
address_a : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
|
||||
address_b : IN STD_LOGIC_VECTOR (widthad_a-1 DOWNTO 0);
|
||||
q_a : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
q_b : OUT STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
byteena_a : IN STD_LOGIC_VECTOR (width_a/8-1 DOWNTO 0) ;
|
||||
byteena_b : IN STD_LOGIC_VECTOR (width_a/8-1 DOWNTO 0) ;
|
||||
data_a : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0);
|
||||
data_b : IN STD_LOGIC_VECTOR (width_a-1 DOWNTO 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
BEGIN
|
||||
q_a <= sub_wire0(width_a-1 DOWNTO 0);
|
||||
q_b <= sub_wire1(width_a-1 DOWNTO 0);
|
||||
|
||||
altsyncram_component : altsyncram
|
||||
GENERIC MAP (
|
||||
address_reg_b => "CLOCK1",
|
||||
clock_enable_input_a => "BYPASS",
|
||||
clock_enable_input_b => "BYPASS",
|
||||
clock_enable_output_a => "BYPASS",
|
||||
clock_enable_output_b => "BYPASS",
|
||||
indata_reg_b => "CLOCK1",
|
||||
init_file => init_file,
|
||||
intended_device_family => "Cyclone III",
|
||||
lpm_type => "altsyncram",
|
||||
numwords_a => 2**widthad_a,
|
||||
numwords_b => 2**widthad_a,
|
||||
operation_mode => "BIDIR_DUAL_PORT",
|
||||
outdata_aclr_a => "NONE",
|
||||
outdata_aclr_b => "NONE",
|
||||
outdata_reg_a => outdata_reg_a,
|
||||
outdata_reg_b => outdata_reg_a,
|
||||
power_up_uninitialized => "FALSE",
|
||||
read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ",
|
||||
read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ",
|
||||
widthad_a => widthad_a,
|
||||
widthad_b => widthad_a,
|
||||
width_a => width_a,
|
||||
width_b => width_a,
|
||||
width_byteena_a => width_a/8,
|
||||
width_byteena_b => width_a/8,
|
||||
wrcontrol_wraddress_reg_b => "CLOCK1"
|
||||
)
|
||||
PORT MAP (
|
||||
wren_a => wren_a,
|
||||
clock0 => clock_a,
|
||||
wren_b => wren_b,
|
||||
clock1 => clock_b,
|
||||
address_a => address_a,
|
||||
address_b => address_b,
|
||||
data_a => data_a,
|
||||
data_b => data_b,
|
||||
q_a => sub_wire0,
|
||||
q_b => sub_wire1,
|
||||
byteena_a => byteena_a,
|
||||
byteena_b => byteena_b
|
||||
);
|
||||
|
||||
|
||||
|
||||
END SYN;
|
||||
3
Arcade_MiST/Konami Gyruss/rtl/ram_rom/gyruss_ram_rom.qip
Normal file
3
Arcade_MiST/Konami Gyruss/rtl/ram_rom/gyruss_ram_rom.qip
Normal file
@@ -0,0 +1,3 @@
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/ram_rom/rom_loader.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/ram_rom/spram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/ram_rom/dpram_dc.vhd
|
||||
452
Arcade_MiST/Konami Gyruss/rtl/ram_rom/rom_loader.sv
Normal file
452
Arcade_MiST/Konami Gyruss/rtl/ram_rom/rom_loader.sv
Normal file
@@ -0,0 +1,452 @@
|
||||
//============================================================================
|
||||
//
|
||||
// SD card ROM loader and ROM selector for MISTer.
|
||||
// Copyright (C) 2019, 2020 Kitrinx (aka Rysha)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software 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 Software.
|
||||
//
|
||||
// THE SOFTWARE 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 SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
// Rom layout for Gyruss:
|
||||
// 0x0000 - 0x1FFF = eprom_1
|
||||
// 0x2000 - 0x3FFF = eprom_2
|
||||
// 0x4000 - 0x5FFF = eprom_3
|
||||
// 0x6000 - 0x7FFF = eprom_4
|
||||
// 0x8000 - 0x9FFF = eprom_5
|
||||
// 0xA000 - 0xBFFF = eprom_6
|
||||
// 0xC000 - 0xDFFF = eprom_7
|
||||
// 0xE000 - 0xFFFF = eprom_8
|
||||
// 0x10000 - 0x11FFF = eprom_9
|
||||
// 0x12000 - 0x13FFF = eprom_10
|
||||
// 0x14000 - 0x15FFF = eprom_11
|
||||
// 0x16000 - 0x16FFF = eprom_12
|
||||
// 0x17000 - 0x170FF = tile_lut_prom
|
||||
// 0x17100 - 0x171FF = sprite_lut_prom
|
||||
// 0x17200 - 0x1721F = color_prom
|
||||
|
||||
module selector
|
||||
(
|
||||
input logic [24:0] ioctl_addr,
|
||||
output logic ep1_cs, ep2_cs, ep3_cs, ep4_cs, ep5_cs, ep6_cs, ep7_cs, ep8_cs,
|
||||
ep9_cs, ep10_cs, ep11_cs, ep12_cs, cp_cs, tl_cs, sl_cs
|
||||
);
|
||||
|
||||
always_comb begin
|
||||
{ep1_cs, ep2_cs, ep3_cs, ep4_cs, ep5_cs, ep6_cs, ep7_cs, ep8_cs, ep9_cs,
|
||||
ep10_cs, ep11_cs, ep12_cs, cp_cs, tl_cs, sl_cs} = 0;
|
||||
if(ioctl_addr < 'h2000)
|
||||
ep1_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'h4000)
|
||||
ep2_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'h6000)
|
||||
ep3_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'h8000)
|
||||
ep4_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'hA000)
|
||||
ep5_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'hC000)
|
||||
ep6_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'hE000)
|
||||
ep7_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'h10000)
|
||||
ep8_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'h12000)
|
||||
ep9_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'h14000)
|
||||
ep10_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'h16000)
|
||||
ep11_cs = 1; // 0x2000 13
|
||||
else if(ioctl_addr < 'h17000)
|
||||
ep12_cs = 1; // 0x1000 12
|
||||
else if(ioctl_addr < 'h17100)
|
||||
tl_cs = 1; // 0x100 8
|
||||
else if(ioctl_addr < 'h17200)
|
||||
sl_cs = 1; // 0x100 8
|
||||
else
|
||||
cp_cs = 1; // 0x20 5
|
||||
end
|
||||
endmodule
|
||||
|
||||
////////////
|
||||
// EPROMS //
|
||||
////////////
|
||||
|
||||
module eprom_1
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_1
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_2
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_2
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_3
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_3
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_4
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_4
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_5
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_5
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_6
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_6
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_7
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_7
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_8
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_8
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_9
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_9
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_10
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_10
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_11
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [12:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(13)) eprom_11
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[12:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[12:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module eprom_12
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [11:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(12)) eprom_12
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[11:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[11:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
///////////
|
||||
// PROMS //
|
||||
///////////
|
||||
|
||||
module color_prom
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [4:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [7:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [7:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(5)) color_prom_1
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[4:0]),
|
||||
.q_a(DATA[7:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[4:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module tile_lut_prom
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [7:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [3:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [3:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(8)) tile_lut_prom
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[7:0]),
|
||||
.q_a(DATA[3:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[7:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module sprite_lut_prom
|
||||
(
|
||||
input logic CLK,
|
||||
input logic CLK_DL,
|
||||
input logic [7:0] ADDR,
|
||||
input logic [24:0] ADDR_DL,
|
||||
input logic [3:0] DATA_IN,
|
||||
input logic CS_DL,
|
||||
input logic WR,
|
||||
output logic [3:0] DATA
|
||||
);
|
||||
dpram_dc #(.widthad_a(8)) sprite_lut_prom
|
||||
(
|
||||
.clock_a(CLK),
|
||||
.address_a(ADDR[7:0]),
|
||||
.q_a(DATA[3:0]),
|
||||
|
||||
.clock_b(CLK_DL),
|
||||
.address_b(ADDR_DL[7:0]),
|
||||
.data_b(DATA_IN),
|
||||
.wren_b(WR & CS_DL)
|
||||
);
|
||||
endmodule
|
||||
46
Arcade_MiST/Konami Gyruss/rtl/ram_rom/spram.vhd
Normal file
46
Arcade_MiST/Konami Gyruss/rtl/ram_rom/spram.vhd
Normal file
@@ -0,0 +1,46 @@
|
||||
library ieee;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.std_logic_unsigned.ALL;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
entity spram is
|
||||
|
||||
generic
|
||||
(
|
||||
DATA_WIDTH : natural := 8;
|
||||
ADDR_WIDTH : natural := 10
|
||||
);
|
||||
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
addr : in std_logic_vector((ADDR_WIDTH - 1) downto 0);
|
||||
data : in std_logic_vector((DATA_WIDTH - 1) downto 0);
|
||||
q : out std_logic_vector((DATA_WIDTH - 1) downto 0);
|
||||
we : in std_logic := '0'
|
||||
);
|
||||
|
||||
end spram;
|
||||
|
||||
architecture rtl of spram is
|
||||
|
||||
subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
|
||||
type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;
|
||||
|
||||
shared variable ram : memory_t;
|
||||
|
||||
begin
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if(rising_edge(clk)) then
|
||||
if(we = '1') then
|
||||
ram(to_integer(unsigned(addr))) := data;
|
||||
q <= data;
|
||||
else
|
||||
q <= ram(to_integer(unsigned(addr)));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end rtl;
|
||||
357
Arcade_MiST/Konami Gyruss/rtl/sdram.sv
Normal file
357
Arcade_MiST/Konami Gyruss/rtl/sdram.sv
Normal file
@@ -0,0 +1,357 @@
|
||||
//
|
||||
// sdram.v
|
||||
//
|
||||
// sdram controller implementation for the MiST board
|
||||
// https://github.com/mist-devel/mist-board
|
||||
//
|
||||
// Copyright (c) 2013 Till Harbaum <till@harbaum.org>
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
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 [16:1] cpu3_addr,
|
||||
output reg [15:0] cpu3_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 = 16'd80; // 80 MHz default clock, set it to proper value to calculate refresh rate
|
||||
|
||||
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
|
||||
localparam RFRSH_CYCLES = 16'd78*MHZ/4'd10;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// ------------------------ cycle state machine ------------------------
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
SDRAM state machine for 2 bank interleaved access
|
||||
2 words 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[3];
|
||||
reg [24:1] addr_latch_next[2];
|
||||
reg [16:1] addr_last[4];
|
||||
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 = 3'd0;
|
||||
localparam PORT_CPU1 = 3'd1;
|
||||
localparam PORT_CPU2 = 3'd2;
|
||||
localparam PORT_CPU3 = 3'd3;
|
||||
localparam PORT_SP = 3'd1;
|
||||
localparam PORT_REQ = 3'd4;
|
||||
|
||||
reg [2:0] next_port[2];
|
||||
reg [2: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 if (cpu3_addr != addr_last[PORT_CPU3]) begin
|
||||
next_port[0] = PORT_CPU3;
|
||||
addr_latch_next[0] = { 8'd0, cpu3_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
|
||||
PORT_CPU3: begin cpu3_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
|
||||
Reference in New Issue
Block a user