mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-22 02:14:58 +00:00
Merge pull request #127 from gyurco/master
Universal Cosmic + Robotron two-stick gamepad support
This commit is contained in:
commit
b9054f4060
31
Arcade_MiST/Universal Cosmic Hardware/Cosmic.qpf
Normal file
31
Arcade_MiST/Universal Cosmic Hardware/Cosmic.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 = "Cosmic"
|
||||
|
||||
228
Arcade_MiST/Universal Cosmic Hardware/Cosmic.qsf
Normal file
228
Arcade_MiST/Universal Cosmic Hardware/Cosmic.qsf
Normal file
@ -0,0 +1,228 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# 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 = 13:14:18 November 17, 2019
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# Timber_assignment_defaults.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Altera recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus II software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
|
||||
# Project-Wide Assignments
|
||||
# ========================
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl"
|
||||
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
set_location_assignment PIN_7 -to LED
|
||||
set_location_assignment PIN_54 -to CLOCK_27
|
||||
set_location_assignment PIN_144 -to VGA_R[5]
|
||||
set_location_assignment PIN_143 -to VGA_R[4]
|
||||
set_location_assignment PIN_142 -to VGA_R[3]
|
||||
set_location_assignment PIN_141 -to VGA_R[2]
|
||||
set_location_assignment PIN_137 -to VGA_R[1]
|
||||
set_location_assignment PIN_135 -to VGA_R[0]
|
||||
set_location_assignment PIN_133 -to VGA_B[5]
|
||||
set_location_assignment PIN_132 -to VGA_B[4]
|
||||
set_location_assignment PIN_125 -to VGA_B[3]
|
||||
set_location_assignment PIN_121 -to VGA_B[2]
|
||||
set_location_assignment PIN_120 -to VGA_B[1]
|
||||
set_location_assignment PIN_115 -to VGA_B[0]
|
||||
set_location_assignment PIN_114 -to VGA_G[5]
|
||||
set_location_assignment PIN_113 -to VGA_G[4]
|
||||
set_location_assignment PIN_112 -to VGA_G[3]
|
||||
set_location_assignment PIN_111 -to VGA_G[2]
|
||||
set_location_assignment PIN_110 -to VGA_G[1]
|
||||
set_location_assignment PIN_106 -to VGA_G[0]
|
||||
set_location_assignment PIN_136 -to VGA_VS
|
||||
set_location_assignment PIN_119 -to VGA_HS
|
||||
set_location_assignment PIN_65 -to AUDIO_L
|
||||
set_location_assignment PIN_80 -to AUDIO_R
|
||||
set_location_assignment PIN_105 -to SPI_DO
|
||||
set_location_assignment PIN_88 -to SPI_DI
|
||||
set_location_assignment PIN_126 -to SPI_SCK
|
||||
set_location_assignment PIN_127 -to SPI_SS2
|
||||
set_location_assignment PIN_91 -to SPI_SS3
|
||||
set_location_assignment PIN_13 -to CONF_DATA0
|
||||
set_location_assignment PIN_49 -to SDRAM_A[0]
|
||||
set_location_assignment PIN_44 -to SDRAM_A[1]
|
||||
set_location_assignment PIN_42 -to SDRAM_A[2]
|
||||
set_location_assignment PIN_39 -to SDRAM_A[3]
|
||||
set_location_assignment PIN_4 -to SDRAM_A[4]
|
||||
set_location_assignment PIN_6 -to SDRAM_A[5]
|
||||
set_location_assignment PIN_8 -to SDRAM_A[6]
|
||||
set_location_assignment PIN_10 -to SDRAM_A[7]
|
||||
set_location_assignment PIN_11 -to SDRAM_A[8]
|
||||
set_location_assignment PIN_28 -to SDRAM_A[9]
|
||||
set_location_assignment PIN_50 -to SDRAM_A[10]
|
||||
set_location_assignment PIN_30 -to SDRAM_A[11]
|
||||
set_location_assignment PIN_32 -to SDRAM_A[12]
|
||||
set_location_assignment PIN_83 -to SDRAM_DQ[0]
|
||||
set_location_assignment PIN_79 -to SDRAM_DQ[1]
|
||||
set_location_assignment PIN_77 -to SDRAM_DQ[2]
|
||||
set_location_assignment PIN_76 -to SDRAM_DQ[3]
|
||||
set_location_assignment PIN_72 -to SDRAM_DQ[4]
|
||||
set_location_assignment PIN_71 -to SDRAM_DQ[5]
|
||||
set_location_assignment PIN_69 -to SDRAM_DQ[6]
|
||||
set_location_assignment PIN_68 -to SDRAM_DQ[7]
|
||||
set_location_assignment PIN_86 -to SDRAM_DQ[8]
|
||||
set_location_assignment PIN_87 -to SDRAM_DQ[9]
|
||||
set_location_assignment PIN_98 -to SDRAM_DQ[10]
|
||||
set_location_assignment PIN_99 -to SDRAM_DQ[11]
|
||||
set_location_assignment PIN_100 -to SDRAM_DQ[12]
|
||||
set_location_assignment PIN_101 -to SDRAM_DQ[13]
|
||||
set_location_assignment PIN_103 -to SDRAM_DQ[14]
|
||||
set_location_assignment PIN_104 -to SDRAM_DQ[15]
|
||||
set_location_assignment PIN_58 -to SDRAM_BA[0]
|
||||
set_location_assignment PIN_51 -to SDRAM_BA[1]
|
||||
set_location_assignment PIN_85 -to SDRAM_DQMH
|
||||
set_location_assignment PIN_67 -to SDRAM_DQML
|
||||
set_location_assignment PIN_60 -to SDRAM_nRAS
|
||||
set_location_assignment PIN_64 -to SDRAM_nCAS
|
||||
set_location_assignment PIN_66 -to SDRAM_nWE
|
||||
set_location_assignment PIN_59 -to SDRAM_nCS
|
||||
set_location_assignment PIN_33 -to SDRAM_CKE
|
||||
set_location_assignment PIN_43 -to SDRAM_CLK
|
||||
set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component"
|
||||
|
||||
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
|
||||
|
||||
# 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 Cosmic_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
|
||||
|
||||
# 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(DoTron_MiST)
|
||||
|
||||
# start DESIGN_PARTITION(Top)
|
||||
# ---------------------------
|
||||
|
||||
# Incremental Compilation Assignments
|
||||
# ===================================
|
||||
|
||||
# end DESIGN_PARTITION(Top)
|
||||
# -------------------------
|
||||
|
||||
# end ENTITY(DoTron_MiST)
|
||||
# -----------------------
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_global_assignment -name ENABLE_SIGNALTAP OFF
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/Cosmic_MiST.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/Cosmic_video.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/Cosmic.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/bram.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/samples.vhd
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv
|
||||
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 TIMEQUEST_MULTICORNER_ANALYSIS ON
|
||||
set_global_assignment -name SMART_RECOMPILE ON
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
134
Arcade_MiST/Universal Cosmic Hardware/Cosmic.sdc
Normal file
134
Arcade_MiST/Universal Cosmic Hardware/Cosmic.sdc
Normal file
@ -0,0 +1,134 @@
|
||||
## Generated SDC file "vectrex_MiST.out.sdc"
|
||||
|
||||
## Copyright (C) 1991-2013 Altera Corporation
|
||||
## Your use of Altera Corporation's design tools, logic functions
|
||||
## and other software and tools, and its AMPP partner logic
|
||||
## functions, and any output files from any of the foregoing
|
||||
## (including device programming or simulation files), and any
|
||||
## associated documentation or information are expressly subject
|
||||
## to the terms and conditions of the Altera Program License
|
||||
## Subscription Agreement, Altera MegaCore Function License
|
||||
## Agreement, or other applicable license agreement, including,
|
||||
## without limitation, that your use is for the sole purpose of
|
||||
## programming logic devices manufactured by Altera and sold by
|
||||
## Altera or its authorized distributors. Please refer to the
|
||||
## applicable agreement for further details.
|
||||
|
||||
|
||||
## VENDOR "Altera"
|
||||
## PROGRAM "Quartus II"
|
||||
## VERSION "Version 13.1.0 Build 162 10/23/2013 SJ Web Edition"
|
||||
|
||||
## DATE "Sun Jun 24 12:53:00 2018"
|
||||
|
||||
##
|
||||
## DEVICE "EP3C25E144C8"
|
||||
##
|
||||
|
||||
# Clock constraints
|
||||
|
||||
# Automatically constrain PLL and other generated clocks
|
||||
derive_pll_clocks -create_base_clocks
|
||||
|
||||
# Automatically calculate clock uncertainty to jitter and other effects.
|
||||
derive_clock_uncertainty
|
||||
|
||||
# tsu/th constraints
|
||||
|
||||
# tco constraints
|
||||
|
||||
# tpd constraints
|
||||
|
||||
#**************************************************************
|
||||
# Time Information
|
||||
#**************************************************************
|
||||
|
||||
set_time_format -unit ns -decimal_places 3
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Create Clock
|
||||
#**************************************************************
|
||||
|
||||
create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}]
|
||||
|
||||
set sys_clk "pll|altpll_component|auto_generated|pll1|clk[1]"
|
||||
set sdram_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 -add_delay -clock_fall -clock [get_clocks {SPI_SCK}] 1.000 [get_ports {SPI_DO}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_L}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {AUDIO_R}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {LED}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks $sys_clk] 1.000 [get_ports {VGA_*}]
|
||||
|
||||
set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
|
||||
set_output_delay -clock [get_clocks $sdram_clk] -reference_pin [get_ports {SDRAM_CLK}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
|
||||
|
||||
#**************************************************************
|
||||
# Set Clock Groups
|
||||
#**************************************************************
|
||||
|
||||
set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {pll|altpll_component|auto_generated|pll1|clk[*]}]
|
||||
|
||||
#**************************************************************
|
||||
# Set False Path
|
||||
#**************************************************************
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set Multicycle Path
|
||||
#**************************************************************
|
||||
|
||||
set_multicycle_path -to {VGA_*[*]} -setup 2
|
||||
set_multicycle_path -to {VGA_*[*]} -hold 1
|
||||
|
||||
#**************************************************************
|
||||
# Set Maximum Delay
|
||||
#**************************************************************
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set Minimum Delay
|
||||
#**************************************************************
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set Input Transition
|
||||
#**************************************************************
|
||||
|
||||
39
Arcade_MiST/Universal Cosmic Hardware/README.md
Normal file
39
Arcade_MiST/Universal Cosmic Hardware/README.md
Normal file
@ -0,0 +1,39 @@
|
||||
# [Arcade: Universal Cosmic](https://www.arcade-museum.com/game_detail.php?game_id=7398) games (Z80-based) originally for [MiSTer](https://github.com/MiSTer-devel/Main_MiSTer/wiki)
|
||||
|
||||
By [Mike Coates](https://github.com/macrofpga)
|
||||
Current Version - 0.9 - 08/07/2021
|
||||
|
||||
## Description
|
||||
|
||||
This is a recreation of the [Universal](https://www.arcade-museum.com/manuf_detail.php?manuf_id=1703&orig_game_id=7398) games that run on similar hardware.
|
||||
|
||||
The game timing should be very close to the original, but the code is not necessarily identical to the real thing, but achieves the same end result.
|
||||
|
||||
## Controls
|
||||
|
||||
Up, Down, Left, Right, Fire 1, Fire 2 (not all games use all buttons)
|
||||
|
||||
## Games currently supported
|
||||
|
||||
* [Cosmic Alien](https://www.arcade-museum.com/game_detail.php?game_id=7398)
|
||||
* [Magical Spot](https://www.arcade-museum.com/game_detail.php?game_id=8505)
|
||||
* [Space Panic](https://www.arcade-museum.com/game_detail.php?game_id=9676)
|
||||
|
||||
## Known differences/problems
|
||||
|
||||
Sound effects are all implemented using samples (other than the DAC).
|
||||
|
||||
I have added a screen flip option to the sprite code, sprites are flipped by the software on the real hardware, but everything else does have a flip signal. It is implemented as a fake dip switch.
|
||||
|
||||
No Man's Land needs the background video lined up properly in all flip modes.
|
||||
|
||||
Devil Zone and No Man's Land need sound samples sourced and connected up.
|
||||
|
||||
## ROM Files Instructions
|
||||
|
||||
- Create ROM and ARC files from the MRA files in the meta directory using the MRA utility.
|
||||
Example: mra -A -z /path/to/mame/roms "Cosmic Alien.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/
|
||||
51122
Arcade_MiST/Universal Cosmic Hardware/meta/Cosmic Alien.mra
Normal file
51122
Arcade_MiST/Universal Cosmic Hardware/meta/Cosmic Alien.mra
Normal file
File diff suppressed because it is too large
Load Diff
19590
Arcade_MiST/Universal Cosmic Hardware/meta/Magical Spot.mra
Normal file
19590
Arcade_MiST/Universal Cosmic Hardware/meta/Magical Spot.mra
Normal file
File diff suppressed because it is too large
Load Diff
43290
Arcade_MiST/Universal Cosmic Hardware/meta/Space Panic.mra
Normal file
43290
Arcade_MiST/Universal Cosmic Hardware/meta/Space Panic.mra
Normal file
File diff suppressed because it is too large
Load Diff
680
Arcade_MiST/Universal Cosmic Hardware/rtl/Cosmic.vhd
Normal file
680
Arcade_MiST/Universal Cosmic Hardware/rtl/Cosmic.vhd
Normal file
@ -0,0 +1,680 @@
|
||||
--
|
||||
-- A simulation of Universal Cosmic games
|
||||
--
|
||||
-- Mike Coates
|
||||
--
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity cosmic is
|
||||
port
|
||||
(
|
||||
O_VIDEO_R : out std_logic_vector(3 downto 0);
|
||||
O_VIDEO_G : out std_logic_vector(3 downto 0);
|
||||
O_VIDEO_B : out std_logic_vector(3 downto 0);
|
||||
O_HSYNC : out std_logic;
|
||||
O_VSYNC : out std_logic;
|
||||
O_HBLANK : out std_logic;
|
||||
O_VBLANK : out std_logic;
|
||||
O_VCOUNT : out std_logic_vector(8 downto 0);
|
||||
I_H_OFFSET : in std_logic_vector(3 downto 0);
|
||||
I_V_OFFSET : in std_logic_vector(3 downto 0);
|
||||
I_FLIP : in std_logic;
|
||||
--
|
||||
O_SoundPort : out std_logic_vector(15 downto 0);
|
||||
O_SoundStop : out std_logic_vector(15 downto 0);
|
||||
O_Sound_EN : out std_logic;
|
||||
O_AUDIO : out std_logic;
|
||||
--
|
||||
dipsw1 : in std_logic_vector(7 downto 0);
|
||||
dipsw2 : in std_logic_vector(7 downto 0);
|
||||
in0 : in std_logic_vector(7 downto 0);
|
||||
in1 : in std_logic_vector(7 downto 0);
|
||||
in2 : in std_logic_vector(7 downto 0);
|
||||
coin : in std_logic;
|
||||
--
|
||||
dn_addr : in std_logic_vector(15 downto 0);
|
||||
dn_data : in std_logic_vector(7 downto 0);
|
||||
dn_wr : in std_logic;
|
||||
dn_ld : in std_logic;
|
||||
--
|
||||
RESET : in std_logic;
|
||||
PIX_CLK : in std_logic;
|
||||
CPU_ENA : in std_logic;
|
||||
CLK : in std_logic;
|
||||
GAME : in std_logic_vector(7 downto 0);
|
||||
PAUSED : in std_logic;
|
||||
|
||||
-- HISCORE
|
||||
hs_address : in std_logic_vector(15 downto 0);
|
||||
hs_data_out : out std_logic_vector(7 downto 0);
|
||||
hs_data_in : in std_logic_vector(7 downto 0);
|
||||
hs_write : in std_logic;
|
||||
hs_access : in std_logic
|
||||
);
|
||||
end;
|
||||
|
||||
architecture RTL of cosmic is
|
||||
-- timing
|
||||
signal hcnt : std_logic_vector(8 downto 0) := "000000000";
|
||||
signal vcnt : std_logic_vector(8 downto 0) := "000000000";
|
||||
signal hsync : std_logic;
|
||||
signal vsync : std_logic;
|
||||
signal hblank : std_logic;
|
||||
signal vblank : std_logic := '1';
|
||||
signal do_hsync : boolean;
|
||||
signal set_vblank : boolean;
|
||||
|
||||
signal hsync_start : std_logic_vector(8 downto 0);
|
||||
signal hsync_end : std_logic_vector(8 downto 0);
|
||||
signal vsync_start : std_logic_vector(8 downto 0);
|
||||
signal vsync_end : std_logic_vector(8 downto 0);
|
||||
|
||||
-- cpu
|
||||
signal cpu_m1_l : std_logic;
|
||||
signal cpu_mreq_l : std_logic;
|
||||
signal cpu_iorq_l : std_logic;
|
||||
signal cpu_rd_l : std_logic;
|
||||
signal cpu_wr_l : std_logic;
|
||||
signal cpu_rfsh_l : std_logic;
|
||||
signal cpu_int_l : std_logic := '1';
|
||||
signal cpu_nmi_l : std_logic := '1';
|
||||
signal cpu_addr : std_logic_vector(15 downto 0);
|
||||
signal cpu_data_out : std_logic_vector(7 downto 0);
|
||||
signal cpu_data_in : std_logic_vector(7 downto 0) := "00000000";
|
||||
|
||||
-- Memory mapping
|
||||
signal rom_ld : std_logic := '0';
|
||||
signal rom_rd : std_logic := '0';
|
||||
signal ram_rd : std_logic := '0';
|
||||
signal vid_rd : std_logic := '0';
|
||||
signal col_rd : std_logic := '0';
|
||||
signal vector_rd : std_logic := '0';
|
||||
|
||||
signal ram_wr : std_logic := '0';
|
||||
signal vid_wr : std_logic := '0';
|
||||
signal mmr_rd : std_logic := '0';
|
||||
signal mmr_wr : std_logic := '0';
|
||||
signal spr_wr : std_logic := '0';
|
||||
signal snd_wr : std_logic := '0';
|
||||
|
||||
signal rom_data : std_logic_vector(7 downto 0);
|
||||
signal vid_data : std_logic_vector(7 downto 0);
|
||||
signal int_vector : std_logic_vector(7 downto 0);
|
||||
signal reg_data : std_logic_vector(7 downto 0);
|
||||
|
||||
signal bus_ad : std_logic_vector(15 downto 0);
|
||||
|
||||
signal Global_Reset : std_logic;
|
||||
signal irq_cnt : std_logic_vector(3 downto 0);
|
||||
signal lastcoin : std_logic;
|
||||
|
||||
-- watchdog
|
||||
signal watchdog_cnt : std_logic_vector(8 downto 0);
|
||||
signal watchdog_clear : std_logic;
|
||||
signal watchdog_reset_l : std_logic;
|
||||
|
||||
-- Video
|
||||
signal vid_addr : std_logic_vector(12 downto 0);
|
||||
signal v_bitmap_data : std_logic_vector(7 downto 0);
|
||||
signal v_colour_page : std_logic_vector(2 downto 0) := "000";
|
||||
signal v_background : std_logic := '0';
|
||||
signal Sprite_Collision : std_logic_vector(11 downto 0);
|
||||
signal ClearCollision : std_logic := '0';
|
||||
signal Sprite_H : std_logic_vector(7 downto 0) := x"00";
|
||||
signal Sprite_V : std_logic_vector(7 downto 0) := x"00";
|
||||
signal Sprite_C : std_logic_vector(3 downto 0);
|
||||
signal Sprite_I : std_logic_vector(3 downto 0);
|
||||
signal Screen_Flip : std_logic := '0';
|
||||
|
||||
-- Sound
|
||||
signal Sound_EN : std_logic := '0';
|
||||
signal Bomb_Select : std_logic_vector(2 downto 0);
|
||||
|
||||
-- Hiscore system
|
||||
signal vid_a_addr : std_logic_vector(12 downto 0);
|
||||
signal vid_a_q : std_logic_vector(7 downto 0);
|
||||
signal vid_a_data : std_logic_vector(7 downto 0);
|
||||
signal vid_a_wren : std_logic;
|
||||
signal vid_a_en : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
O_HBLANK <= hblank;
|
||||
O_VBLANK <= vblank;
|
||||
O_VCOUNT <= vcnt;
|
||||
|
||||
--Global_Reset <= watchdog_reset_l and (not reset);
|
||||
Global_Reset <= (not reset);
|
||||
|
||||
--
|
||||
-- video timing
|
||||
--
|
||||
|
||||
sync_stop : process(RESET,I_H_OFFSET,I_V_OFFSET)
|
||||
begin
|
||||
-- work out locations for sync pulses
|
||||
hsync_start <= std_logic_vector(to_unsigned(200 + to_integer(signed(I_H_OFFSET)),9));
|
||||
hsync_end <= std_logic_vector(to_unsigned(214 + to_integer(signed(I_H_OFFSET)),9));
|
||||
vsync_start <= std_logic_vector(to_unsigned(252 + to_integer(signed(I_V_OFFSET)),9));
|
||||
vsync_end <= std_logic_vector(to_unsigned(255 + to_integer(signed(I_V_OFFSET)),9));
|
||||
end process;
|
||||
|
||||
p_hvcnt : process
|
||||
variable hcarry,vcarry : boolean;
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
if (PIX_CLK = '1') then
|
||||
hcarry := (hcnt = "111111111");
|
||||
if hcarry then
|
||||
--hcnt <= "011000000"; -- 0C0
|
||||
hcnt <= "010101011"; -- 0AB
|
||||
else
|
||||
hcnt <= hcnt +"1";
|
||||
end if;
|
||||
|
||||
vcarry := (vcnt = "111111111");
|
||||
if do_hsync then
|
||||
if vcarry then
|
||||
vcnt <= "011111000"; -- 0F8
|
||||
else
|
||||
vcnt <= vcnt +"1";
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_sync_comb : process(hcnt, vcnt, hsync_start)
|
||||
begin
|
||||
do_hsync <= (hcnt = hsync_start);
|
||||
set_vblank <= (vcnt = "111100000"); -- 1E0
|
||||
end process;
|
||||
|
||||
p_sync : process
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
-- Timing hardware is coded differently to the real hw
|
||||
if (PIX_CLK = '1') then
|
||||
if (hcnt = "010101100") then
|
||||
hblank <= '1';
|
||||
elsif (hcnt = "011111111") then
|
||||
hblank <= '0';
|
||||
end if;
|
||||
|
||||
if do_hsync then
|
||||
hsync <= '1';
|
||||
elsif (hcnt = hsync_end) then
|
||||
hsync <= '0';
|
||||
end if;
|
||||
|
||||
if do_hsync then
|
||||
if set_vblank then -- 1EF
|
||||
vblank <= '1';
|
||||
elsif (vcnt = "100011111") then
|
||||
vblank <= '0';
|
||||
end if;
|
||||
|
||||
if (vcnt = vsync_start) then
|
||||
vsync <= '0';
|
||||
elsif (vcnt = vsync_end) then
|
||||
vsync <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_video_timing_reg : process
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
-- match output delay in video module
|
||||
if (PIX_CLK = '1') then
|
||||
O_HSYNC <= hsync;
|
||||
O_VSYNC <= vsync;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_cpu_int : process
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
if reset='1' then
|
||||
cpu_int_l <= '1';
|
||||
else
|
||||
-- Space Panic Has 2 interrupts
|
||||
if (GAME = 1) then
|
||||
if (vector_rd = '1') then
|
||||
cpu_int_l <= '1';
|
||||
else
|
||||
if do_hsync and set_vblank then
|
||||
cpu_int_l <= '0';
|
||||
int_vector <= x"D7"; -- RST 10h
|
||||
elsif (hcnt = "011111111") and set_vblank then
|
||||
cpu_int_l <= '0';
|
||||
int_vector <= x"CF"; -- RST 08h
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
-- Other games use NMI for coin
|
||||
lastcoin <= coin;
|
||||
if (lastcoin = '0' and coin = '1') then
|
||||
-- pulse for 16 cycles (done via NE556 timer)
|
||||
irq_cnt <= "1111";
|
||||
cpu_nmi_l <= '0';
|
||||
else
|
||||
if cpu_nmi_l = '0' then
|
||||
if irq_cnt = "0000" then
|
||||
cpu_nmi_l <= '1';
|
||||
else
|
||||
irq_cnt <= irq_cnt - 1;
|
||||
end if ;
|
||||
end if ;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
--
|
||||
-- cpu
|
||||
--
|
||||
cpu : entity work.T80s
|
||||
port map (
|
||||
RESET_n => Global_Reset,
|
||||
CLK => CLK,
|
||||
CEN => CPU_ENA,
|
||||
WAIT_n => not PAUSED,
|
||||
INT_n => cpu_int_l,
|
||||
NMI_n => cpu_nmi_l,
|
||||
BUSRQ_n => '1',
|
||||
MREQ_n => cpu_mreq_l,
|
||||
RD_n => cpu_rd_l,
|
||||
WR_n => cpu_wr_l,
|
||||
RFSH_n => cpu_rfsh_l,
|
||||
A => cpu_addr,
|
||||
DI => cpu_data_in,
|
||||
DO => cpu_data_out,
|
||||
M1_n => cpu_m1_l,
|
||||
IORQ_n => cpu_iorq_l,
|
||||
HALT_n => open,
|
||||
BUSAK_n => open
|
||||
);
|
||||
|
||||
--
|
||||
-- Space Panic mappings
|
||||
--
|
||||
-- map(0x0000, 0x3fff).rom();
|
||||
-- map(0x4000, 0x5fff).ram().share("videoram");
|
||||
-- map(0x6000, 0x601f).writeonly().share("spriteram");
|
||||
-- map(0x6800, 0x6800).portr("P1");
|
||||
-- map(0x6801, 0x6801).portr("P2");
|
||||
-- map(0x6802, 0x6802).portr("DSW");
|
||||
-- map(0x6803, 0x6803).portr("SYSTEM");
|
||||
-- map(0x7000, 0x700b).w(FUNC(cosmic_state::panic_sound_output_w));
|
||||
-- map(0x700c, 0x700e).w(FUNC(cosmic_state::cosmic_color_register_w));
|
||||
-- map(0x700f, 0x700f).w(FUNC(cosmic_state::flip_screen_w));
|
||||
-- map(0x7800, 0x7801).w(FUNC(cosmic_state::panic_sound_output2_w));
|
||||
|
||||
-- Magical Spot mappings
|
||||
-- map(0x0000, 0x2fff).rom();
|
||||
-- map(0x3800, 0x3807).r(FUNC(cosmic_state::magspot_coinage_dip_r));
|
||||
-- map(0x4000, 0x401f).writeonly().share("spriteram");
|
||||
-- map(0x4800, 0x4800).w(FUNC(cosmic_state::dac_w));
|
||||
-- map(0x480c, 0x480d).w(FUNC(cosmic_state::cosmic_color_register_w));
|
||||
-- map(0x480f, 0x480f).w(FUNC(cosmic_state::flip_screen_w));
|
||||
-- map(0x5000, 0x5000).portr("IN0");
|
||||
-- map(0x5001, 0x5001).portr("IN1");
|
||||
-- map(0x5002, 0x5002).portr("IN2");
|
||||
-- map(0x5003, 0x5003).portr("IN3");
|
||||
-- map(0x6000, 0x7fff).ram().share("videoram");
|
||||
|
||||
-- Cosmic Alien
|
||||
-- map(0x0000, 0x3fff).rom();
|
||||
-- map(0x4000, 0x5fff).ram().share("videoram");
|
||||
-- map(0x6000, 0x601f).writeonly().share("spriteram");
|
||||
-- map(0x6800, 0x6800).portr("P1");
|
||||
-- map(0x6801, 0x6801).portr("P2");
|
||||
-- map(0x6802, 0x6802).portr("DSW");
|
||||
-- map(0x6803, 0x6803).r(FUNC(cosmic_state::cosmica_pixel_clock_r));
|
||||
-- map(0x7000, 0x700b).w(FUNC(cosmic_state::cosmica_sound_output_w));
|
||||
-- map(0x700c, 0x700d).w(FUNC(cosmic_state::cosmic_color_register_w));
|
||||
-- map(0x700f, 0x700f).w(FUNC(cosmic_state::flip_screen_w));
|
||||
|
||||
rom_ld <= '1' when dn_addr(15 downto 14) = "00" and dn_ld='1' else '0';
|
||||
bus_ad <= dn_addr(15 downto 0) when dn_ld='1' else cpu_addr;
|
||||
|
||||
p_mem_decode : process(cpu_addr,cpu_iorq_l,cpu_rd_l,cpu_wr_l,cpu_mreq_l,cpu_m1_l,cpu_rfsh_l,GAME)
|
||||
variable address : natural range 0 to 2**15 - 1;
|
||||
begin
|
||||
rom_rd <= '0';
|
||||
vid_rd <= '0';
|
||||
mmr_rd <= '0';
|
||||
|
||||
vid_wr <= '0';
|
||||
mmr_wr <= '0';
|
||||
spr_wr <= '0';
|
||||
snd_wr <= '0';
|
||||
|
||||
vector_rd <= not cpu_iorq_l and not cpu_m1_l;
|
||||
address := to_integer(unsigned(cpu_addr));
|
||||
|
||||
-- Ram/Rom read or write
|
||||
if cpu_mreq_l='0' and cpu_rfsh_l = '1' then
|
||||
if cpu_rd_l='0' then
|
||||
case GAME is
|
||||
when x"01" | x"03" => -- Space Panic, Cosmic Alien
|
||||
case address is
|
||||
when 16#0000# to 16#3FFF# => rom_rd <= '1';
|
||||
when 16#4000# to 16#5FFF# => vid_rd <= '1';
|
||||
when 16#6800# to 16#6803# => mmr_rd <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
when x"02" | x"04"| x"05" => -- Magical Spot, Devil Zone, No Mans Land
|
||||
case address is
|
||||
when 16#0000# to 16#2FFF# => rom_rd <= '1';
|
||||
when 16#3800# to 16#3807# => mmr_rd <= '1';
|
||||
when 16#6000# to 16#7FFF# => vid_rd <= '1';
|
||||
when 16#5000# to 16#5003# => mmr_rd <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
when others => null;
|
||||
end case;
|
||||
elsif cpu_wr_l='0' then
|
||||
case GAME is
|
||||
when x"01" | x"03" => -- Space Panic, Cosmic Alien
|
||||
case address is
|
||||
when 16#4000# to 16#5FFF# => vid_wr <= '1';
|
||||
when 16#6000# to 16#601F# => spr_wr <= '1';
|
||||
when 16#7000# to 16#700B# => snd_wr <= '1';
|
||||
when 16#700C# to 16#700F# => mmr_wr <= '1';
|
||||
when 16#7800# to 16#7801# => snd_wr <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
when x"02" | x"04"| x"05" => -- Magical Spot, Devil Zone, No Mans Land
|
||||
case address is
|
||||
when 16#6000# to 16#7FFF# => vid_wr <= '1';
|
||||
when 16#4000# to 16#401F# => spr_wr <= '1';
|
||||
when 16#4800# to 16#4806# => snd_wr <= '1';
|
||||
when 16#4807# => mmr_wr <= '1';
|
||||
when 16#4808# to 16#480B# => snd_wr <= '1';
|
||||
when 16#480C# to 16#480F# => mmr_wr <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
-- Mux back to CPU
|
||||
p_cpu_src_data_mux : process(rom_data,vid_data,int_vector,reg_data,rom_rd,vid_rd,vector_rd,mmr_rd)
|
||||
begin
|
||||
if rom_rd = '1' then
|
||||
cpu_data_in <= rom_data;
|
||||
elsif vid_rd = '1' then
|
||||
cpu_data_in <= vid_data;
|
||||
elsif vector_rd = '1' then
|
||||
cpu_data_in <= int_vector;
|
||||
elsif mmr_rd = '1' then
|
||||
cpu_data_in <= reg_data;
|
||||
else
|
||||
cpu_data_in <= x"FF";
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- rom : 0000-3FFF
|
||||
program_rom : entity work.spram
|
||||
generic map (
|
||||
addr_width => 14
|
||||
)
|
||||
port map (
|
||||
q => rom_data,
|
||||
data => dn_data(7 downto 0),
|
||||
address => bus_ad(13 downto 0),
|
||||
wren => dn_wr and rom_ld,
|
||||
clock => clk
|
||||
);
|
||||
|
||||
|
||||
-- hiscore mux into video ram port
|
||||
vid_a_addr <= hs_address(12 downto 0) when hs_access = '1' else cpu_addr(12 downto 0);
|
||||
vid_a_data <= hs_data_in when hs_access = '1' else cpu_data_out;
|
||||
hs_data_out <= vid_a_q when hs_access = '1' else "00000000";
|
||||
vid_data <= vid_a_q when hs_access = '0' else "00000000";
|
||||
vid_a_en <= '1' when hs_access = '1' else (vid_wr or vid_rd);
|
||||
vid_a_wren <= hs_write when hs_access = '1' else vid_wr;
|
||||
|
||||
-- program and video ram
|
||||
video_ram : entity work.dpram
|
||||
generic map (
|
||||
addr_width => 13
|
||||
)
|
||||
port map (
|
||||
q_a => vid_a_q,
|
||||
data_a => vid_a_data,
|
||||
address_a => vid_a_addr,
|
||||
wren_a => vid_a_wren,
|
||||
enable_a => vid_a_en,
|
||||
clock => clk,
|
||||
|
||||
address_b => vid_addr(12 downto 0),
|
||||
q_b => v_bitmap_data
|
||||
);
|
||||
|
||||
|
||||
-- Memory mapped registers
|
||||
--
|
||||
MMR_Write : process (CLK)
|
||||
variable address : natural range 0 to 2**15 - 1;
|
||||
begin
|
||||
if rising_edge(CLK) then
|
||||
if (CPU_ENA='1' and mmr_wr='1') then
|
||||
|
||||
address := to_integer(unsigned(cpu_addr));
|
||||
|
||||
case address is
|
||||
when 16#4807# =>
|
||||
v_background <= cpu_data_out(7);
|
||||
when 16#700C# to 16#700E# | 16#480C# to 16#480D# =>
|
||||
v_colour_page(to_integer(unsigned(cpu_addr(1 downto 0)))) <= cpu_data_out(7);
|
||||
when 16#700F# | 16#480F# => Screen_Flip <= cpu_data_out(7);
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
MMR_read : process (cpu_addr, in0, in1, dipsw1, dipsw2, in2)
|
||||
variable address : natural range 0 to 2**15 - 1;
|
||||
begin
|
||||
reg_data <= x"FF";
|
||||
address := to_integer(unsigned(cpu_addr));
|
||||
|
||||
case address is
|
||||
-- Space Panic, Cosmic Alien
|
||||
when 16#6800# | 16#5000# => reg_data <= in0;
|
||||
when 16#6801# | 16#5001# => reg_data <= in1;
|
||||
when 16#6802# | 16#5002# => reg_data <= dipsw1;
|
||||
when 16#6803# | 16#5003# => reg_data <= in2;
|
||||
-- Magical Spot only
|
||||
when 16#3800# => reg_data <= "0000000" & dipsw2(3);
|
||||
when 16#3801# => reg_data <= "0000000" & dipsw2(2);
|
||||
when 16#3802# => reg_data <= "0000000" & dipsw2(1);
|
||||
when 16#3803# => reg_data <= "0000000" & dipsw2(0);
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
-- Sound is memory mapped, but handled seperately
|
||||
--
|
||||
Sound_Write : process (CLK)
|
||||
variable address : natural range 0 to 2**15 - 1;
|
||||
variable SoundBit : std_logic;
|
||||
begin
|
||||
if rising_edge(CLK) then
|
||||
if CPU_ENA='1' then
|
||||
if reset='1' then
|
||||
O_SoundPort <= "0000000000000000";
|
||||
O_AUDIO <= '0';
|
||||
O_SoundStop <= "1111111111111111";
|
||||
Sound_EN <= '0';
|
||||
Bomb_Select <= "000";
|
||||
else
|
||||
O_SoundStop <= "0000000000000000";
|
||||
|
||||
-- Coin sample triggered by coin mech (Space Panic & Magic Spot)
|
||||
if GAME /= 3 then
|
||||
O_SoundPort(0) <= coin;
|
||||
end if;
|
||||
|
||||
if snd_wr='1' then
|
||||
|
||||
address := to_integer(unsigned(cpu_addr));
|
||||
SoundBit := cpu_data_out(7) and Sound_EN; -- used for all except sound enable
|
||||
|
||||
if (GAME = 1) then
|
||||
-- Space Panic sound registers
|
||||
case address is
|
||||
when 16#7000# => O_SoundPort(10) <= SoundBit;
|
||||
when 16#7001# => O_SoundPort(2) <= SoundBit;
|
||||
when 16#7002# => O_SoundPort(6) <= SoundBit;
|
||||
when 16#7003# => O_SoundPort(7) <= SoundBit;
|
||||
when 16#7005# => O_SoundPort(2) <= SoundBit;
|
||||
when 16#7006# => O_SoundPort(8) <= SoundBit;
|
||||
when 16#7007# => O_SoundPort(4) <= SoundBit;
|
||||
when 16#7008# => O_SoundPort(9) <= SoundBit;
|
||||
when 16#7009# => O_SoundPort(5) <= SoundBit;
|
||||
when 16#700A# => O_AUDIO <= SoundBit; -- 1 bit DAC
|
||||
when 16#700B# => Sound_EN <= cpu_data_out(7);
|
||||
if (cpu_data_out(7)='0') then
|
||||
-- Stop all sounds as well
|
||||
O_SoundPort <= "0000000000000000";
|
||||
O_AUDIO <= '0';
|
||||
O_SoundStop <= "1111111111111110";
|
||||
end if;
|
||||
when 16#7800# => O_SoundPort(1) <= SoundBit;
|
||||
when 16#7801# => O_SoundPort(3) <= SoundBit;
|
||||
when others => null;
|
||||
end case;
|
||||
elsif (GAME = 2 or GAME = 4 or GAME = 5) then
|
||||
-- Magic Spot sound registers
|
||||
case address is
|
||||
when 16#4800# => O_AUDIO <= cpu_data_out(7); -- 1 bit DAC
|
||||
when 16#4801# => O_SoundPort(1) <= SoundBit;
|
||||
when 16#4802# => O_SoundPort(3) <= SoundBit;
|
||||
when 16#4803# => O_SoundPort(6) <= SoundBit;
|
||||
when 16#4804# => O_SoundPort(2) <= SoundBit;
|
||||
when 16#4805# => O_SoundPort(5) <= SoundBit;
|
||||
when 16#4806# => O_SoundPort(7) <= SoundBit;
|
||||
--when 16#4808# => O_SoundPort(8) <= SoundBit; -- Ultramoth?
|
||||
when 16#4809# => O_SoundPort(8) <= SoundBit; -- Ultramoth?
|
||||
when 16#480A# => O_SoundPort(4) <= SoundBit;
|
||||
when 16#480B# => Sound_EN <= cpu_data_out(7);
|
||||
if (cpu_data_out(7)='0' and Sound_EN='1') then
|
||||
-- Stop all sounds as well if turning off
|
||||
O_SoundPort <= "0000000000000000";
|
||||
O_AUDIO <= '0';
|
||||
O_SoundStop <= "1111111111111110";
|
||||
end if;
|
||||
-- sort rest
|
||||
when others => null;
|
||||
end case;
|
||||
elsif (GAME = 3) then
|
||||
-- Cosmic Alien
|
||||
case address is
|
||||
when 16#7000# => O_SoundPort(2) <= SoundBit;
|
||||
when 16#7002# =>
|
||||
case Bomb_Select is
|
||||
when "010" => O_SoundStop(3) <= SoundBit;
|
||||
O_SoundPort(3) <= SoundBit;
|
||||
when "011" => O_SoundStop(4) <= SoundBit;
|
||||
O_SoundPort(4) <= SoundBit;
|
||||
when "100" => O_SoundStop(5) <= SoundBit;
|
||||
O_SoundPort(5) <= SoundBit;
|
||||
when "101" => O_SoundStop(6) <= SoundBit;
|
||||
O_SoundPort(6) <= SoundBit;
|
||||
when "110" => O_SoundStop(7) <= SoundBit;
|
||||
O_SoundPort(7) <= SoundBit;
|
||||
when "111" => O_SoundStop(8) <= SoundBit;
|
||||
O_SoundPort(8) <= SoundBit;
|
||||
when others => null;
|
||||
end case;
|
||||
when 16#7003# => Bomb_Select(2) <= cpu_data_out(7);
|
||||
when 16#7004# => Bomb_Select(1) <= cpu_data_out(7);
|
||||
when 16#7005# => Bomb_Select(0) <= cpu_data_out(7);
|
||||
when 16#7006# => O_SoundPort(10) <= SoundBit;
|
||||
when 16#7007# => O_SoundPort(11) <= SoundBit; -- swopped, was 12,11
|
||||
when 16#7008# => O_SoundPort(12) <= SoundBit;
|
||||
when 16#7009# => O_SoundPort(9) <= SoundBit;
|
||||
when 16#700B# => Sound_EN <= cpu_data_out(7);
|
||||
if (cpu_data_out(7)='1') then
|
||||
-- Start background noise
|
||||
O_SoundPort(1) <= '1';
|
||||
elsif Sound_EN='1' then
|
||||
-- Stop all sounds as well if turning off
|
||||
O_SoundPort <= "0000000000000000";
|
||||
O_AUDIO <= '0';
|
||||
O_SoundStop <= "1111111111111110";
|
||||
end if;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
O_Sound_EN <= Sound_EN;
|
||||
|
||||
--
|
||||
-- video subsystem
|
||||
--
|
||||
-- Bitmap graphics using colour prom with 16x16 or 32x32 sprites using pallette
|
||||
--
|
||||
-- needs
|
||||
-- in - x,y,flip,vid_data
|
||||
-- out - vidaddr,R,G,B
|
||||
-- colour rom to load internally, needs to track colourmap change writes (3 bits)
|
||||
|
||||
-- spriteram write
|
||||
|
||||
-- rom load
|
||||
|
||||
video : work.COSMIC_VIDEO
|
||||
port map (
|
||||
I_HCNT => hcnt,
|
||||
I_VCNT => vcnt,
|
||||
--
|
||||
I_S_FLIP => Screen_Flip,
|
||||
I_H_FLIP => I_FLIP,
|
||||
I_BITMAP => v_bitmap_data,
|
||||
I_COL => v_colour_page,
|
||||
I_BACKGND => v_background,
|
||||
O_VADDR => vid_addr,
|
||||
--
|
||||
I_SPR_ADD => cpu_addr(4 downto 0),
|
||||
I_SPR_DAT => cpu_data_out,
|
||||
I_SPR_WR => spr_wr,
|
||||
--
|
||||
dn_addr => dn_addr,
|
||||
dn_data => dn_data,
|
||||
dn_wr => dn_wr,
|
||||
dn_ld => dn_ld,
|
||||
--
|
||||
O_RED => O_VIDEO_R,
|
||||
O_GREEN => O_VIDEO_G,
|
||||
O_BLUE => O_VIDEO_B,
|
||||
--
|
||||
PIX_CLK => PIX_CLK,
|
||||
CLK => CLK,
|
||||
CPU_ENA => CPU_ENA,
|
||||
GAME => GAME,
|
||||
PAUSED => PAUSED
|
||||
);
|
||||
|
||||
end RTL;
|
||||
407
Arcade_MiST/Universal Cosmic Hardware/rtl/Cosmic_MiST.sv
Normal file
407
Arcade_MiST/Universal Cosmic Hardware/rtl/Cosmic_MiST.sv
Normal file
@ -0,0 +1,407 @@
|
||||
// Arcade: Universal Cosmic series (Z80 version)
|
||||
//
|
||||
// Mike Coates.
|
||||
//
|
||||
// MiST port by slingshot
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by the Free
|
||||
// Software Foundation; either version 2 of the License, or (at your option)
|
||||
// any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
// more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//============================================================================
|
||||
|
||||
module Cosmic_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"
|
||||
|
||||
`define CORE_NAME "COSMIIEN"
|
||||
|
||||
localparam CONF_STR = {
|
||||
`CORE_NAME,";;",
|
||||
"O2,Rotate Controls,Off,On;",
|
||||
"O34,Scanlines,Off,25%,50%,75%;",
|
||||
"O5,Blend,Off,On;",
|
||||
"O6,Swap Joysticks,Off,On;",
|
||||
"O7,Flip,Off,On;",
|
||||
"DIP;",
|
||||
"T0,Reset;",
|
||||
"V,v1.0.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire rotate = status[2];
|
||||
wire [1:0] scanlines = status[4:3];
|
||||
wire blend = status[5];
|
||||
wire joyswap = status[6];
|
||||
wire flip = status[7];
|
||||
|
||||
wire [6:0] core_mod;
|
||||
wire [1:0] orientation = {flip, 1'b1}; // [left/right, landscape/portrait]
|
||||
|
||||
wire clk_vid, clk_sys;
|
||||
wire pll_locked;
|
||||
pll_mist pll(
|
||||
.inclk0(CLOCK_27),
|
||||
.areset(0),
|
||||
.c0(clk_vid),//43.264
|
||||
.c1(clk_sys),//10.816
|
||||
.locked(pll_locked)
|
||||
);
|
||||
|
||||
assign SDRAM_CLK = clk_vid;
|
||||
assign LED = ~ioctl_downl;
|
||||
|
||||
wire pix_clk = clk_div[0]; // Pixel clock = 5.408 Mhz
|
||||
|
||||
reg [1:0] clk_div = 2'd0; // Clock divider (for Pixel and CPU speed 2.7Mhz)
|
||||
reg [2:0] clk_div2 = 3'd0; // Clock divider (for CPU speed 1.8 Mhz)
|
||||
reg cpu_ena_27; // 2.7 Mhz
|
||||
reg cpu_ena_18; // 1.8 Mhz
|
||||
|
||||
// Divider for other clocks (7474 and 74161 on PCB)
|
||||
always @(posedge clk_sys) begin
|
||||
cpu_ena_27 <= 1'd0;
|
||||
cpu_ena_18 <= 1'd0;
|
||||
|
||||
clk_div <= clk_div + 1'b1;
|
||||
clk_div2 <= clk_div2 + 1'b1;
|
||||
|
||||
// cpu clocks
|
||||
if (clk_div == 3) cpu_ena_27 <= 1'd1;
|
||||
|
||||
if (clk_div2 == 5) begin
|
||||
cpu_ena_18 <= 1'd1;
|
||||
clk_div2 <= 3'd0;
|
||||
end
|
||||
end
|
||||
|
||||
// Game ID - CPU Speed
|
||||
// 01 = Space Panic - 1.8 Mhz
|
||||
// 02 = Magic Spot - 2.7 Mhz
|
||||
// 03 = Cosmic Alien - 1.8 Mhz
|
||||
// 04 = Devil Zone - 2.7 Mhz
|
||||
// 05 = No Mans Land - 1.8Mhz
|
||||
|
||||
wire cpu_ena = (core_mod==2 || core_mod==4) ? cpu_ena_27 : cpu_ena_18;
|
||||
|
||||
wire [15:0] dip = status[23:8];
|
||||
// Panic
|
||||
wire [7:0] Panic_P1 = {~m_fireB,2'd3,~m_up,~m_down,~m_left,~m_right,~m_fireA};
|
||||
wire [7:0] Panic_P2 = {~m_fire2B,2'd3,~m_up2,~m_down2,~m_left2,~m_right2,~m_fire2A};
|
||||
wire [7:0] Panic_P3 = {1'd1,~m_coin1,4'D15,~m_two_players,~m_one_player};
|
||||
// Magical Spot
|
||||
wire [7:0] MagSpot_P1 = {dip[15:14],~m_right,3'd7,~m_left,1'd1}; // Includes bonus dips
|
||||
wire [7:0] MagSpot_P2 = {2'd3,~m_right2,3'd7,~m_left2,1'd1};
|
||||
wire [7:0] MagSpot_P3 = {~m_fireA,~m_fire2A,5'D31,~vblank};
|
||||
wire [7:0] MagSpot_P4 = {~m_one_player,~m_two_players,dip[5:0]};
|
||||
// Cosmic Alien
|
||||
wire [7:0] Alien_P1 = {5'd31,~m_left,~m_right,~m_fireA};
|
||||
wire [7:0] Alien_P2 = {5'd31,~m_left2,~m_right2,~m_fire2A};
|
||||
wire [7:0] Alien_P3 = {2'd0,VCount[7:2]};
|
||||
|
||||
// Select correct inputs
|
||||
wire [7:0] IN0 = (core_mod==1)? Panic_P1 : (core_mod==2 || core_mod==4 || core_mod==5)? MagSpot_P1 : Alien_P1;
|
||||
wire [7:0] IN1 = (core_mod==1)? Panic_P2 : (core_mod==2 || core_mod==4 || core_mod==5)? MagSpot_P2 : Alien_P2;
|
||||
wire [7:0] IN2 = (core_mod==1)? Panic_P3 : (core_mod==2 || core_mod==4 || core_mod==5)? MagSpot_P3 : Alien_P3;
|
||||
wire [7:0] DIP = (core_mod==1)? dip[7:0] : MagSpot_P4;
|
||||
|
||||
|
||||
wire [63:0] status;
|
||||
wire [1:0] buttons;
|
||||
wire [1:0] switches;
|
||||
wire [19:0] joystick_0;
|
||||
wire [19:0] joystick_1;
|
||||
wire scandoublerD;
|
||||
wire no_csync;
|
||||
wire ypbpr;
|
||||
wire key_pressed;
|
||||
wire [7:0] key_code;
|
||||
wire key_strobe;
|
||||
|
||||
wire mouse_strobe;
|
||||
wire signed [8:0] mouse_x;
|
||||
wire signed [8:0] mouse_y;
|
||||
wire [7:0] mouse_flags;
|
||||
wire mouse_idx;
|
||||
|
||||
user_io #(
|
||||
.STRLEN($size(CONF_STR)>>3))
|
||||
user_io(
|
||||
.clk_sys ( clk_sys ),
|
||||
.conf_str ( CONF_STR ),
|
||||
.SPI_CLK ( SPI_SCK ),
|
||||
.SPI_SS_IO ( CONF_DATA0 ),
|
||||
.SPI_MISO ( SPI_DO ),
|
||||
.SPI_MOSI ( SPI_DI ),
|
||||
.buttons ( buttons ),
|
||||
.switches ( switches ),
|
||||
.scandoubler_disable (scandoublerD ),
|
||||
.ypbpr ( ypbpr ),
|
||||
.no_csync ( no_csync ),
|
||||
.core_mod ( core_mod ),
|
||||
.key_strobe ( key_strobe ),
|
||||
.key_pressed ( key_pressed ),
|
||||
.key_code ( key_code ),
|
||||
.mouse_idx ( mouse_idx ),
|
||||
.mouse_strobe ( mouse_strobe ),
|
||||
.mouse_x ( mouse_x ),
|
||||
.mouse_y ( mouse_y ),
|
||||
.mouse_flags ( mouse_flags ),
|
||||
.joystick_0 ( joystick_0 ),
|
||||
.joystick_1 ( joystick_1 ),
|
||||
.status ( status )
|
||||
);
|
||||
|
||||
wire ioctl_downl;
|
||||
wire ioctl_upl;
|
||||
wire [7:0] ioctl_index;
|
||||
wire ioctl_wr;
|
||||
wire [24:0] ioctl_addr;
|
||||
wire [7:0] ioctl_dout;
|
||||
wire [7:0] ioctl_din;
|
||||
|
||||
data_io data_io (
|
||||
.clk_sys ( clk_sys ),
|
||||
.SPI_SCK ( SPI_SCK ),
|
||||
.SPI_SS2 ( SPI_SS2 ),
|
||||
.SPI_DI ( SPI_DI ),
|
||||
.SPI_DO ( SPI_DO ),
|
||||
.ioctl_download( ioctl_downl ),
|
||||
.ioctl_upload ( ioctl_upl ),
|
||||
.ioctl_index ( ioctl_index ),
|
||||
.ioctl_wr ( ioctl_wr ),
|
||||
.ioctl_addr ( ioctl_addr ),
|
||||
.ioctl_dout ( ioctl_dout ),
|
||||
.ioctl_din ( ioctl_din )
|
||||
);
|
||||
|
||||
reg reset = 1;
|
||||
reg rom_loaded = 0;
|
||||
always @(posedge clk_sys) begin
|
||||
reg ioctl_downlD;
|
||||
ioctl_downlD <= ioctl_downl;
|
||||
|
||||
if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1;
|
||||
reset <= status[0] | buttons[1] | ioctl_downl | ~rom_loaded;
|
||||
end
|
||||
|
||||
wire audio;
|
||||
wire hblank, vblank;
|
||||
wire hs, vs;
|
||||
wire [3:0] r,g,b;
|
||||
wire [8:0] VCount;
|
||||
wire blank = hblank | vblank;
|
||||
|
||||
COSMIC COSMIC
|
||||
(
|
||||
.O_VIDEO_R(r),
|
||||
.O_VIDEO_G(g),
|
||||
.O_VIDEO_B(b),
|
||||
.O_HSYNC(hs),
|
||||
.O_VSYNC(vs),
|
||||
.O_HBLANK(hblank),
|
||||
.O_VBLANK(vblank),
|
||||
.I_H_OFFSET(),
|
||||
.I_V_OFFSET(),
|
||||
.I_FLIP(flip),
|
||||
.O_VCOUNT(VCount),
|
||||
|
||||
.dn_addr(ioctl_addr[15:0]),
|
||||
.dn_data(ioctl_dout),
|
||||
.dn_wr(ioctl_wr && (ioctl_index == 0) && ioctl_addr < table_offset),
|
||||
.dn_ld(ioctl_downl),
|
||||
|
||||
.O_SoundPort(SoundTrigger),
|
||||
.O_SoundStop(SoundStop),
|
||||
.O_AUDIO(audio),
|
||||
.O_Sound_EN(),
|
||||
|
||||
.dipsw1(DIP),
|
||||
.dipsw2(dip[15:8]),
|
||||
.in0(IN0),
|
||||
.in1(IN1),
|
||||
.in2(IN2),
|
||||
.coin(m_coin1),
|
||||
|
||||
.RESET(reset),
|
||||
.PIX_CLK(pix_clk),
|
||||
.CPU_ENA(cpu_ena),
|
||||
.CLK(clk_sys),
|
||||
.GAME(core_mod),
|
||||
|
||||
.PAUSED(),
|
||||
|
||||
.hs_address(),
|
||||
.hs_data_out(),
|
||||
.hs_data_in(),
|
||||
.hs_write(),
|
||||
.hs_access()
|
||||
);
|
||||
|
||||
mist_video #(.COLOR_DEPTH(4), .SD_HCNT_WIDTH(11)) mist_video(
|
||||
.clk_sys ( clk_vid ),
|
||||
.SPI_SCK ( SPI_SCK ),
|
||||
.SPI_SS3 ( SPI_SS3 ),
|
||||
.SPI_DI ( SPI_DI ),
|
||||
.R ( blank ? 4'd0 : r ),
|
||||
.G ( blank ? 4'd0 : g ),
|
||||
.B ( blank ? 4'd0 : b ),
|
||||
.HSync ( hs ),
|
||||
.VSync ( vs ),
|
||||
.VGA_R ( VGA_R ),
|
||||
.VGA_G ( VGA_G ),
|
||||
.VGA_B ( VGA_B ),
|
||||
.VGA_VS ( VGA_VS ),
|
||||
.VGA_HS ( VGA_HS ),
|
||||
.rotate ( {flip,rotate} ),
|
||||
.scandoubler_disable( scandoublerD ),
|
||||
.ce_divider ( 1'b1 ),
|
||||
.no_csync ( no_csync ),
|
||||
.scanlines ( scanlines ),
|
||||
.blend ( blend ),
|
||||
.ypbpr ( ypbpr )
|
||||
);
|
||||
|
||||
// Samples
|
||||
|
||||
wire [24:0] table_offset = core_mod == 3 ? 24'd29696 : 24'd26656;
|
||||
wire [24:0] wav_offset = table_offset + 8'd128;
|
||||
|
||||
wire wav_download = ioctl_downl && (ioctl_index == 0) && ioctl_addr >= wav_offset;
|
||||
reg [24:0] wav_addr;
|
||||
wire [15:0] wav_data;
|
||||
reg wav_want_byte;
|
||||
wire [15:0] samples_left;
|
||||
wire [15:0] samples_right;
|
||||
reg use_samples;
|
||||
reg [15:0] SoundTrigger;
|
||||
reg [15:0] SoundStop;
|
||||
reg Sound_Enable;
|
||||
|
||||
// 8 bit write, 16 bit read
|
||||
|
||||
sdram sdram (
|
||||
.*,
|
||||
.init(~pll_locked),
|
||||
.clk(clk_vid),
|
||||
|
||||
.addr(ioctl_downl ? ioctl_addr-wav_offset : {wav_addr[24:1],1'd0}),
|
||||
.we(wav_download && ioctl_wr),
|
||||
.rd(~ioctl_downl & wav_want_byte),
|
||||
.din(ioctl_dout),
|
||||
.dout(wav_data),
|
||||
|
||||
.ready()
|
||||
);
|
||||
|
||||
// Link to Samples module
|
||||
|
||||
wire samples_download = ioctl_downl && (ioctl_index == 0) && ioctl_addr >= table_offset && ioctl_addr < wav_offset;
|
||||
samples samples
|
||||
(
|
||||
.audio_enabled(1'd1),
|
||||
.audio_port_0(SoundTrigger[7:0]),
|
||||
.audio_port_1(SoundTrigger[15:8]),
|
||||
.audio_stop(SoundStop),
|
||||
|
||||
.wave_addr(wav_addr),
|
||||
.wave_read(wav_want_byte),
|
||||
.wave_data(wav_data),
|
||||
|
||||
.samples_ok(use_samples),
|
||||
|
||||
.dl_addr(ioctl_addr-table_offset),
|
||||
.dl_wr(ioctl_wr),
|
||||
.dl_data(ioctl_dout),
|
||||
.dl_download(samples_download),
|
||||
|
||||
.CLK_SYS(clk_sys),
|
||||
.clock(clk_vid),
|
||||
.reset(reset),
|
||||
|
||||
.audio_in({2'b00, audio, 13'd0}),
|
||||
.audio_out_L(samples_left),
|
||||
.audio_out_R(samples_right)
|
||||
);
|
||||
|
||||
dac #(
|
||||
.C_bits(16))
|
||||
dac_l(
|
||||
.clk_i(clk_sys),
|
||||
.res_n_i(1),
|
||||
.dac_i(samples_left),
|
||||
.dac_o(AUDIO_L)
|
||||
);
|
||||
|
||||
dac #(
|
||||
.C_bits(16))
|
||||
dac_r(
|
||||
.clk_i(clk_sys),
|
||||
.res_n_i(1),
|
||||
.dac_i(samples_right),
|
||||
.dac_o(AUDIO_R)
|
||||
);
|
||||
|
||||
|
||||
// Common inputs
|
||||
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF, m_upB, m_downB, m_leftB, m_rightB;
|
||||
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F, m_up2B, m_down2B, m_left2B, m_right2B;
|
||||
wire m_up3, m_down3, m_left3, m_right3, m_fire3A, m_fire3B, m_fire3C, m_fire3D, m_fire3E, m_fire3F, m_up3B, m_down3B, m_left3B, m_right3B;
|
||||
wire m_up4, m_down4, m_left4, m_right4, m_fire4A, m_fire4B, m_fire4C, m_fire4D, m_fire4E, m_fire4F, m_up4B, m_down4B, m_left4B, m_right4B;
|
||||
wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players;
|
||||
|
||||
arcade_inputs inputs (
|
||||
.clk ( clk_sys ),
|
||||
.key_strobe ( key_strobe ),
|
||||
.key_pressed ( key_pressed ),
|
||||
.key_code ( key_code ),
|
||||
.joystick_0 ( joystick_0 ),
|
||||
.joystick_1 ( joystick_1 ),
|
||||
.rotate ( rotate ),
|
||||
.orientation ( orientation ),
|
||||
.joyswap ( joyswap ),
|
||||
.oneplayer ( 1'b0 ),
|
||||
.controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ),
|
||||
.player1 ( {m_upB, m_downB, m_leftB, m_rightB, 6'd0, m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
|
||||
.player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, 6'd0, m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ),
|
||||
.player3 ( {m_up3B, m_down3B, m_left3B, m_right3B, 6'd0, m_fire3F, m_fire3E, m_fire3D, m_fire3C, m_fire3B, m_fire3A, m_up3, m_down3, m_left3, m_right3} ),
|
||||
.player4 ( {m_up4B, m_down4B, m_left4B, m_right4B, 6'd0, m_fire4F, m_fire4E, m_fire4D, m_fire4C, m_fire4B, m_fire4A, m_up4, m_down4, m_left4, m_right4} )
|
||||
);
|
||||
|
||||
endmodule
|
||||
754
Arcade_MiST/Universal Cosmic Hardware/rtl/Cosmic_video.vhd
Normal file
754
Arcade_MiST/Universal Cosmic Hardware/rtl/Cosmic_video.vhd
Normal file
@ -0,0 +1,754 @@
|
||||
--
|
||||
-- A simulation of Universal Cosmic video hardware
|
||||
--
|
||||
-- Mike Coates
|
||||
--
|
||||
-- version 001 initial release
|
||||
--
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity COSMIC_VIDEO is
|
||||
port (
|
||||
I_HCNT : in std_logic_vector(8 downto 0);
|
||||
I_VCNT : in std_logic_vector(8 downto 0);
|
||||
I_BITMAP : in std_logic_vector(7 downto 0);
|
||||
I_COL : in std_logic_vector(2 downto 0); -- colour page
|
||||
I_H_FLIP : in std_logic;
|
||||
I_S_FLIP : in std_logic;
|
||||
I_BACKGND : in std_logic;
|
||||
O_VADDR : out std_logic_vector(12 downto 0);
|
||||
--
|
||||
I_SPR_ADD : in std_logic_vector(4 downto 0);
|
||||
I_SPR_DAT : in std_logic_vector(7 downto 0);
|
||||
I_SPR_WR : in std_logic;
|
||||
--
|
||||
dn_addr : in std_logic_vector(15 downto 0);
|
||||
dn_data : in std_logic_vector(7 downto 0);
|
||||
dn_wr : in std_logic;
|
||||
dn_ld : in std_logic;
|
||||
--
|
||||
O_RED : out std_logic_vector(3 downto 0);
|
||||
O_GREEN : out std_logic_vector(3 downto 0);
|
||||
O_BLUE : out std_logic_vector(3 downto 0);
|
||||
PIX_CLK : in std_logic;
|
||||
CLK : in std_logic;
|
||||
CPU_ENA : in std_logic;
|
||||
GAME : in std_logic_vector(7 downto 0);
|
||||
PAUSED : in std_logic
|
||||
);
|
||||
end;
|
||||
|
||||
architecture RTL of COSMIC_VIDEO is
|
||||
|
||||
signal col_cs : std_logic;
|
||||
signal map_cs : std_logic;
|
||||
signal sprite_l_cs : std_logic;
|
||||
signal sprite_h_cs : std_logic;
|
||||
signal op_rom1_cs : std_logic;
|
||||
signal op_rom2_cs : std_logic;
|
||||
signal col_pix : std_logic_vector(7 downto 0);
|
||||
signal char_pix_n : std_logic_vector(7 downto 0);
|
||||
signal char_pix_l : std_logic_vector(7 downto 0);
|
||||
signal sprite_pix_l : std_logic_vector(7 downto 0);
|
||||
signal sprite_pix_h : std_logic_vector(7 downto 0);
|
||||
signal col_addr : std_logic_vector(10 downto 0);
|
||||
signal sprite_addr : std_logic_vector(11 downto 0);
|
||||
signal col_ad : std_logic_vector(10 downto 0);
|
||||
signal op_pix : std_logic_vector(7 downto 0);
|
||||
signal op_pix2 : std_logic_vector(7 downto 0);
|
||||
signal op_ad : std_logic_vector(10 downto 0);
|
||||
signal op_ad2 : std_logic_vector(10 downto 0);
|
||||
signal op_addr : std_logic_vector(10 downto 0);
|
||||
|
||||
-- Sprites
|
||||
type LBA is array (0 to 1,0 to 255) of std_logic_vector(2 downto 0);
|
||||
signal linebuffer : LBA;
|
||||
|
||||
type SA is array (0 to 7) of std_logic_vector(7 downto 0);
|
||||
signal Sprite_N : SA;
|
||||
signal Sprite_X : SA;
|
||||
signal Sprite_Y : SA;
|
||||
signal Sprite_C : SA;
|
||||
|
||||
type LC is array (0 to 7, 0 to 3) of std_logic_vector(7 downto 0);
|
||||
signal Colour_P : LC;
|
||||
|
||||
signal sprite_ad : std_logic_vector(11 downto 0);
|
||||
signal sprite_buffer : std_logic := '0';
|
||||
signal sprite_line : integer;
|
||||
signal sprite : integer;
|
||||
signal sprite_pos : integer;
|
||||
signal draw_sprite : std_logic := '0';
|
||||
signal I_Flip : std_logic := '0';
|
||||
|
||||
signal charcolour : std_logic_vector(3 downto 0);
|
||||
signal sprite_red : std_logic_vector(3 downto 0);
|
||||
signal sprite_green : std_logic_vector(3 downto 0);
|
||||
signal sprite_blue : std_logic_vector(3 downto 0);
|
||||
signal sprite_pixel : std_logic := '0';
|
||||
|
||||
-- Background related
|
||||
signal back_red : std_logic_vector(3 downto 0);
|
||||
signal back_green : std_logic_vector(3 downto 0);
|
||||
signal back_blue : std_logic_vector(3 downto 0);
|
||||
signal frame : std_logic_vector(7 downto 0) := "00000000";
|
||||
signal RLECount : std_logic_vector(7 downto 0);
|
||||
signal RLEPIX : std_logic_vector(7 downto 0) := "00000000";
|
||||
signal RLEMask : std_logic_vector(7 downto 0);
|
||||
signal RLEDelay : std_logic;
|
||||
signal Tree : std_logic_vector(3 downto 0);
|
||||
signal River : std_logic_vector(3 downto 0);
|
||||
signal Riverframe : std_logic_vector(7 downto 0) := "00000000";
|
||||
type VA is array (0 to 255) of std_logic;
|
||||
signal Vertical : VA;
|
||||
|
||||
begin
|
||||
-- Load rom signals
|
||||
sprite_l_cs <= '1' when dn_addr(15 downto 12) = "0100" else '0'; -- 4000-4FFF
|
||||
sprite_h_cs <= '1' when dn_addr(15 downto 12) = "0101" else '0'; -- 5000-5FFF
|
||||
col_cs <= '1' when dn_addr(15 downto 11) = "01100" else '0'; -- 6000-67FF
|
||||
map_cs <= '1' when dn_addr(15 downto 5) = "01101000000" else '0'; -- 6800-681F
|
||||
op_rom1_cs <= '1' when dn_addr(15 downto 11) = "01110" else '0'; -- 7000-77FF
|
||||
op_rom2_cs <= '1' when dn_addr(15 downto 5) = "01111000000" else '0'; -- 7800-781F
|
||||
|
||||
-- Address multiplex
|
||||
col_ad <= dn_addr(10 downto 0) when dn_ld='1' else col_addr;
|
||||
sprite_ad <= dn_addr(11 downto 0) when dn_ld='1' else sprite_addr;
|
||||
op_ad <= dn_addr(10 downto 0) when dn_ld='1' else op_addr;
|
||||
|
||||
col_rom : entity work.spram
|
||||
generic map (
|
||||
addr_width => 11
|
||||
)
|
||||
port map (
|
||||
q => col_pix,
|
||||
data => dn_data(7 downto 0),
|
||||
address => col_ad,
|
||||
wren => dn_wr and col_cs,
|
||||
clock => clk
|
||||
);
|
||||
|
||||
sprite_rom_l : entity work.spram
|
||||
generic map (
|
||||
addr_width => 12
|
||||
)
|
||||
port map (
|
||||
q => sprite_pix_l,
|
||||
data => dn_data(7 downto 0),
|
||||
address => sprite_ad,
|
||||
wren => dn_wr and sprite_l_cs,
|
||||
clock => clk
|
||||
);
|
||||
|
||||
sprite_rom_h : entity work.spram
|
||||
generic map (
|
||||
addr_width => 12
|
||||
)
|
||||
port map (
|
||||
q => sprite_pix_h,
|
||||
data => dn_data(7 downto 0),
|
||||
address => sprite_ad,
|
||||
wren => dn_wr and sprite_h_cs,
|
||||
clock => clk
|
||||
);
|
||||
|
||||
-- RLE data for DevZone add 1, else second plane add $400
|
||||
op_ad2 <= op_ad + '1' when Game=4 else op_ad + "10000000000";
|
||||
|
||||
op_rom : entity work.dpram
|
||||
generic map (
|
||||
addr_width => 11
|
||||
)
|
||||
port map (
|
||||
q_a => op_pix,
|
||||
data_a => dn_data(7 downto 0),
|
||||
address_a => op_ad,
|
||||
wren_a => dn_wr and op_rom1_cs,
|
||||
clock => clk,
|
||||
|
||||
address_b => op_ad2,
|
||||
q_b => op_pix2
|
||||
);
|
||||
|
||||
-- Load pallette array
|
||||
pallette : process
|
||||
variable Entry, Color : integer;
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
if (dn_wr='1') then
|
||||
if (map_cs='1') then
|
||||
Entry := to_integer(unsigned(dn_addr(4 downto 2)));
|
||||
Color := to_integer(unsigned(dn_addr(1 downto 0)));
|
||||
Colour_P(Entry,Color) <= dn_data(7 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Vertical lines for Devil Zone
|
||||
Vertical_Load : process
|
||||
variable Entry : integer;
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
if (dn_wr='1') then
|
||||
if (op_rom2_cs='1') then
|
||||
Entry := to_integer(unsigned(dn_addr(4 downto 0))) * 8;
|
||||
Vertical(Entry) <= dn_data(7);
|
||||
Vertical(Entry+1) <= dn_data(6);
|
||||
Vertical(Entry+2) <= dn_data(5);
|
||||
Vertical(Entry+3) <= dn_data(4);
|
||||
Vertical(Entry+4) <= dn_data(3);
|
||||
Vertical(Entry+5) <= dn_data(2);
|
||||
Vertical(Entry+6) <= dn_data(1);
|
||||
Vertical(Entry+7) <= dn_data(0);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- if both software and hardware flip the same, then don't flip background
|
||||
I_FLIP <= '0' when (I_S_FLIP = I_H_FLIP) else '1';
|
||||
|
||||
-- Video is bitmap using paged colour rom for colour map
|
||||
vid_address : process
|
||||
variable HADD : std_logic_vector(8 downto 0);
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
if (PIX_CLK = '1') then
|
||||
|
||||
if ((I_HCNT(8)='1' and I_VCNT(8)='1' and I_HCNT(2 downto 0)="101") or (I_HCNT="011111101")) then
|
||||
-- set address for video ram and colour ram
|
||||
HADD := I_HCNT + 3; -- we want data for next character
|
||||
|
||||
-- need to allow for screen flip (hardware and software!)
|
||||
if I_FLIP='0' then
|
||||
O_VADDR <= I_VCNT(7 downto 0) & HADD(7 downto 3); -- character = (v * 32) + ((h+3)/8) (H = 0 to 31, V = 0,32,64 etc)
|
||||
case Game is
|
||||
when x"01" =>
|
||||
-- Space Panic
|
||||
col_addr <= I_COL(2) & I_COL(0) & HADD(7 downto 4) & I_VCNT(7 downto 3); -- col = page + (v/8 * 32) + ((h+3)/8) (H = 0 to 31, V = 0,32,64 etc)
|
||||
when x"02" | x"04" | x"05" =>
|
||||
-- Magical Spot, Devil Zone and No Mans Land
|
||||
col_addr <= '0' & I_COL(0) & HADD(7 downto 3) & I_VCNT(7 downto 4);
|
||||
when x"03" =>
|
||||
-- Cosmic Alien
|
||||
col_addr <= '0' & I_COL(0) & HADD(7 downto 4) & I_VCNT(7 downto 3);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
else
|
||||
O_VADDR <= not I_VCNT(7 downto 0) & not HADD(7 downto 3); -- inverted draw from bottom up
|
||||
case Game is
|
||||
when x"01" =>
|
||||
col_addr <= I_COL(2) & I_COL(0) & not HADD(7 downto 4) & not I_VCNT(7 downto 3);
|
||||
when x"02" | x"04" | x"05" =>
|
||||
col_addr <= '0' & I_COL(0) & not HADD(7 downto 3) & not I_VCNT(7 downto 4);
|
||||
when x"03" =>
|
||||
col_addr <= '0' & I_COL(0) & not HADD(7 downto 4) & not I_VCNT(7 downto 3);
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if ((I_HCNT(8)='1' and I_VCNT(8)='1' and I_HCNT(2 downto 0)="111") or (I_HCNT="011111111")) then
|
||||
|
||||
if (I_COL(1)='1') then
|
||||
charcolour <= col_pix(7 downto 4);
|
||||
else
|
||||
charcolour <= col_pix(3 downto 0);
|
||||
end if;
|
||||
|
||||
-- Only space panic uses 4 bits of colour info
|
||||
if GAME /= 1 then
|
||||
charcolour(3) <= '0';
|
||||
end if;
|
||||
|
||||
if I_FLIP='1' then
|
||||
char_pix_n <= I_BITMAP;
|
||||
else
|
||||
char_pix_n <= I_BITMAP(0) & I_BITMAP(1) & I_BITMAP(2) & I_BITMAP(3) & I_BITMAP(4) & I_BITMAP(5) & I_BITMAP(6) & I_BITMAP(7);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
backround_draw : process
|
||||
variable pixel : std_logic;
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
if (PIX_CLK = '1') then
|
||||
|
||||
if (PAUSED = '0') then
|
||||
-- Frame counter (for background circuits)
|
||||
if I_HCNT="011111100" then
|
||||
if I_VCNT="011111111" then
|
||||
frame <= frame + 1;
|
||||
if I_FLIP='0' then
|
||||
Riverframe <= frame;
|
||||
else
|
||||
Riverframe <= not frame;
|
||||
end if;
|
||||
else
|
||||
Riverframe <= Riverframe + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- if in visible area
|
||||
if I_HCNT(8)='1' and I_VCNT(8)='1' and I_VCNT(7 downto 5) /= "111" then -- skip rows one side and > 224 : and I_VCNT(7 downto 3) /= "00000"
|
||||
case I_HCNT(2 downto 0) is
|
||||
when "000" => pixel := char_pix_n(0);
|
||||
char_pix_l <= char_pix_n;
|
||||
when "001" => pixel := char_pix_l(1);
|
||||
when "010" => pixel := char_pix_l(2);
|
||||
when "011" => pixel := char_pix_l(3);
|
||||
when "100" => pixel := char_pix_l(4);
|
||||
when "101" => pixel := char_pix_l(5);
|
||||
when "110" => pixel := char_pix_l(6);
|
||||
when "111" => pixel := char_pix_l(7);
|
||||
end case;
|
||||
|
||||
-- Sprite have priority over background
|
||||
if (sprite_blue /= "0000" or sprite_green /= "0000" or sprite_red /= "0000") then
|
||||
O_BLUE <= sprite_blue;
|
||||
O_GREEN <= sprite_green;
|
||||
O_RED <= sprite_red;
|
||||
else
|
||||
if pixel='1' then
|
||||
-- Blue has 2 options on Space Panic (using charcolour 3)
|
||||
if charcolour(2)='1' then
|
||||
O_BLUE <= "1111";
|
||||
elsif charcolour(3)='1' then
|
||||
O_BLUE <= "1100";
|
||||
else
|
||||
O_BLUE <= "0000";
|
||||
end if;
|
||||
O_GREEN <= charcolour(1) & charcolour(1) & charcolour(1) & charcolour(1);
|
||||
O_RED <= charcolour(0) & charcolour(0) & charcolour(0) & charcolour(0);
|
||||
else
|
||||
if I_BACKGND='1' or Game=3 then
|
||||
-- use feed from background generator
|
||||
O_BLUE <= back_blue;
|
||||
O_RED <= back_red;
|
||||
O_GREEN <= back_green;
|
||||
else
|
||||
-- No background, so black
|
||||
O_BLUE <= "0000";
|
||||
O_GREEN <= "0000";
|
||||
O_RED <= "0000";
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
O_BLUE <= "0000";
|
||||
O_GREEN <= "0000";
|
||||
O_RED <= "0000";
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-- Some games have prom drive backgrounds
|
||||
|
||||
background_circuits : process
|
||||
variable X1,X2 : unsigned(9 downto 0);
|
||||
variable H,V : integer;
|
||||
variable Plane1, Plane2 : std_logic;
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
if (PIX_CLK = '1') then
|
||||
|
||||
back_red <= "0000";
|
||||
back_green <= "0000";
|
||||
back_blue <= "0000";
|
||||
|
||||
if Game = 3 then
|
||||
|
||||
-- Cosmic Alien - Stars
|
||||
|
||||
if (I_VCNT(8)='1' and (I_HCNT(8)='1' or I_HCNT="011111101" or I_HCNT="011111110")) then
|
||||
|
||||
-- Pixel we are looking for
|
||||
X2 := "0000000011" + unsigned(I_HCNT(7 downto 0));
|
||||
if I_FLIP='1' then
|
||||
X1 := X2 - unsigned(frame);
|
||||
else
|
||||
X1 := X2 + unsigned(frame);
|
||||
end if;
|
||||
|
||||
-- Set address for prom
|
||||
if X1(4 downto 0) = "00000" then
|
||||
op_addr(10) <= '0';
|
||||
op_addr(9 downto 3) <= std_logic_vector(I_VCNT(7 downto 1));
|
||||
op_addr(2 downto 0) <= std_logic_vector(X1(7 downto 5));
|
||||
end if;
|
||||
|
||||
-- Use prom to set stars
|
||||
if (X1(2)='0' or I_VCNT(0)='0') and (I_HCNT(5) /= I_VCNT(1)) then
|
||||
if X1(4) /= op_pix(4) and X1(3) /= op_pix(3) and X1(2) /= op_pix(2) and X1(1) /= op_pix(1) and (X1(0) = op_pix(0) or X1(2)='0') then
|
||||
-- Draw a star!
|
||||
back_red <= op_pix(7) & op_pix(7) & op_pix(7) & op_pix(7);
|
||||
back_green <= op_pix(6) & op_pix(6) & op_pix(6) & op_pix(6);
|
||||
back_blue <= op_pix(5) & op_pix(5) & op_pix(5) & op_pix(5);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
elsif Game = 4 then
|
||||
|
||||
-- Devil Zone : Grid
|
||||
|
||||
if (I_VCNT(8)='1' and (I_HCNT(8)='1' or I_HCNT="011111111")) then
|
||||
|
||||
-- Get Horizontal and Vertical counters
|
||||
H := to_integer(unsigned(I_HCNT(7 downto 0))) + 1;
|
||||
V := to_integer(unsigned(I_VCNT(7 downto 0)));
|
||||
|
||||
-- Adjust So doesn't exceed boundary
|
||||
if H > 255 then
|
||||
H := 0;
|
||||
end if;
|
||||
|
||||
|
||||
-- Other lines (RLE from prom 1)
|
||||
-- only goes from vertical row 32 to 224
|
||||
CASE V is
|
||||
|
||||
when 30 =>
|
||||
-- Start of screen
|
||||
if I_HCNT="100000000" then -- "011111111"
|
||||
if I_FLIP='1' then
|
||||
-- go backwards
|
||||
op_addr <= "11111111101"; -- $7FD
|
||||
else
|
||||
-- Skip 1st 2 bytes
|
||||
op_addr <= "00000000010"; -- $002
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when 31 =>
|
||||
-- Load starter characters
|
||||
if I_HCNT="100000000" then -- "011111111"
|
||||
if I_FLIP='1' then
|
||||
-- go backwards (data and count reversed)
|
||||
RLECount <= op_pix2;
|
||||
RLEMask <= op_pix(0) & op_pix(1) & op_pix(2) & op_pix(3) & op_pix(4) & op_pix(5) & op_pix(6) & op_pix(7);
|
||||
op_addr <= op_addr - 2;
|
||||
else
|
||||
RLECount <= op_pix;
|
||||
RLEMask <= op_pix2;
|
||||
op_addr <= op_addr + 2;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when 32 to 224 =>
|
||||
|
||||
-- every pixel, rotate PIX to use on screen
|
||||
RLEPIX <= RLEPIX(6 downto 0) & '1';
|
||||
|
||||
-- every character, increment counter and check if next data pair needed
|
||||
if I_H_FLIP='1' and I_S_FLIP='1' then
|
||||
X2(2 downto 0) := unsigned(I_HCNT(2 downto 0)) + 1;
|
||||
else
|
||||
X2(2 downto 0) := unsigned(I_HCNT(2 downto 0));
|
||||
end if;
|
||||
|
||||
if X2(2 downto 0) = "110" then -- check 6 as we want 7! - was I_HCNT
|
||||
if RLECount = "11111111" then
|
||||
-- Action data for this pair and load next pair
|
||||
RLEPIX <= RLEMask;
|
||||
RLECount <= op_pix;
|
||||
if I_FLIP='1' then
|
||||
-- go backwards (data and count reversed)
|
||||
RLECount <= op_pix2;
|
||||
RLEMask <= op_pix(0) & op_pix(1) & op_pix(2) & op_pix(3) & op_pix(4) & op_pix(5) & op_pix(6) & op_pix(7);
|
||||
op_addr <= op_addr - 2;
|
||||
else
|
||||
RLECount <= op_pix;
|
||||
RLEMask <= op_pix2;
|
||||
op_addr <= op_addr + 2;
|
||||
end if;
|
||||
else
|
||||
RLECount <= RLECount + 1;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
-- Hardware flip needs offset each mode (real hardware doesn't have it, just cocktail flip)
|
||||
if I_H_FLIP='1' then
|
||||
if I_S_FLIP='1' then
|
||||
H := H + 2;
|
||||
else
|
||||
H := 255 - H;
|
||||
end if;
|
||||
else
|
||||
if I_S_FLIP='1' then
|
||||
H := 257 - H;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Vertical lines or RLE data
|
||||
if I_H_FLIP='1' then
|
||||
if Vertical(H)='0' or RLEPIX(7)='0' then
|
||||
back_blue <= "1111";
|
||||
end if;
|
||||
else
|
||||
if I_S_FLIP='0' then
|
||||
if Vertical(H)='0' or RLEPIX(7)='0' then
|
||||
back_blue <= "1111";
|
||||
end if;
|
||||
else
|
||||
-- Delay RLE data by 1 pixel if software flipped
|
||||
if Vertical(H)='0' or RLEDelay='0' then
|
||||
back_blue <= "1111";
|
||||
end if;
|
||||
RLEDelay <= RLEPIX(7);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
elsif Game = 5 then
|
||||
|
||||
-- No mans land : Trees and River
|
||||
Tree <= "0000";
|
||||
River <= "0000";
|
||||
|
||||
if (I_VCNT(8)='1' and (I_HCNT(8)='1' or I_HCNT="011111110"or I_HCNT="011111111")) then
|
||||
|
||||
-- Get corrected Horizontal and Vertical counters (H in 2 pixels time)
|
||||
if I_FLIP='0' then
|
||||
X1 := "0000000010" + unsigned(I_HCNT(7 downto 0));
|
||||
X2(8 downto 0) := unsigned(I_VCNT);
|
||||
else
|
||||
X1 := 511 - ("0000000010" + unsigned(I_HCNT(7 downto 0)));
|
||||
X2(8 downto 0) := 511 - unsigned(I_VCNT);
|
||||
end if;
|
||||
|
||||
|
||||
if X2(7 downto 5)="010" or X2(7 downto 5)="101" then
|
||||
|
||||
-- Trees
|
||||
if X1(7 downto 5)="010" then
|
||||
|
||||
op_addr <= "000" & I_FLIP & std_logic_vector(X2(4 downto 0)) & std_logic_vector(X1(4 downto 3));
|
||||
Tree <= '1' & std_logic_vector(X1(2 downto 0));
|
||||
|
||||
end if;
|
||||
|
||||
else
|
||||
|
||||
-- Water
|
||||
if X1(7 downto 4)="1010" then
|
||||
|
||||
op_addr <= "01" & std_logic_vector(Riverframe) & X1(7);
|
||||
River <= '1' & std_logic_vector(X1(2 downto 0));
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
if Tree(3)='1' then
|
||||
|
||||
Plane1 := op_pix(7 - to_integer(unsigned(Tree(2 downto 0))));
|
||||
Plane2 := op_pix2(7 - to_integer(unsigned(Tree(2 downto 0))));
|
||||
|
||||
if plane1='1' and plane2='1' then back_red <= "1111"; end if;
|
||||
if plane2='1' then back_green <= "1111"; end if;
|
||||
if plane1='1' and plane2='0' then back_blue <= "1111"; end if;
|
||||
|
||||
elsif River(3)='1' then
|
||||
|
||||
Plane1 := op_pix(7 - to_integer(unsigned(River(2 downto 0))));
|
||||
Plane2 := op_pix2(7 - to_integer(unsigned(River(2 downto 0))));
|
||||
|
||||
if plane1='1' and plane2='1' then back_red <= "1111"; end if;
|
||||
if plane1='1' or Plane2='1' then back_green <= "1111"; end if;
|
||||
if plane1='0' then back_blue <= "1111"; end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
-- ditto for sprite drawing (sprite block, which could be any position H & V!)
|
||||
|
||||
-- _N zero = no sprite to be drawn
|
||||
-- bit 7 : 0 = 32x32,1 = 16x16
|
||||
-- bit 6 : 0 = left to right, 1 = right to left
|
||||
-- rest : inverse of sprite number (see C)
|
||||
-- _X horizontal position inverted
|
||||
-- _Y vertical position inverted - 1 (from Mame)
|
||||
-- _C bit 3 : extended sprite number (for some games)
|
||||
-- bits 0-2 : colour map entry
|
||||
|
||||
-- hardware supports 8 sprites in 16x16 or 32x32
|
||||
sprite_draw : process
|
||||
variable V_OFF,H_OFF : integer;
|
||||
variable SP : std_logic_vector(2 downto 0);
|
||||
variable pixel : std_logic_vector(1 downto 0);
|
||||
variable Entry : integer;
|
||||
variable Color : integer;
|
||||
begin
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
if (PIX_CLK = '1') then
|
||||
|
||||
if (I_HCNT = "011111110") then
|
||||
-- just before start of line, set up variables to use
|
||||
if I_H_FLIP='0' then
|
||||
sprite_line <= to_integer(unsigned(I_VCNT(7 downto 0))) + 1; -- Line to draw
|
||||
else
|
||||
sprite_line <= 254 - to_integer(unsigned(I_VCNT(7 downto 0))); -- Line to draw
|
||||
end if;
|
||||
sprite_buffer <= I_VCNT(0); -- buffer to write to
|
||||
sprite <= 0; -- sprite number to draw
|
||||
elsif (I_HCNT(8)='1' and I_HCNT(4 downto 0)="11110") then
|
||||
sprite <= sprite + 1;
|
||||
end if;
|
||||
|
||||
if ((I_HCNT(8)='1' and I_HCNT(4 downto 0)="11111") or I_HCNT = "011111111") then
|
||||
if (Sprite_N(sprite) /= "00000000") then
|
||||
-- see if sprite visible on this line
|
||||
V_OFF := sprite_line - to_integer(unsigned(Sprite_Y(sprite)));
|
||||
-- 16x16 or 32x32 - based on Sprite_N(sprite)(7)
|
||||
if ((Sprite_N(sprite)(7)='1' and V_OFF>=0 and V_OFF<=15) or (Sprite_N(sprite)(7)='0' and V_OFF>=0 and V_OFF<=31)) then
|
||||
-- Sprite inverted, modify row data to draw correct sprite data.
|
||||
if (Sprite_N(sprite)(6)='0') then
|
||||
if (Sprite_N(sprite)(7)='1') then
|
||||
V_OFF := 15 - V_OFF;
|
||||
else
|
||||
V_OFF := 31 - V_OFF;
|
||||
end if;
|
||||
end if;
|
||||
-- set address for sprite data
|
||||
if GAME = 1 then
|
||||
-- Extended sprite range
|
||||
sprite_addr <= Sprite_C(sprite)(3) & (not Sprite_N(sprite)(5 downto 0)) & std_logic_vector(to_unsigned(V_OFF, 5));
|
||||
else
|
||||
-- Normal sprite range
|
||||
sprite_addr <= '0' & (not Sprite_N(sprite)(5 downto 0)) & std_logic_vector(to_unsigned(V_OFF, 5));
|
||||
end if;
|
||||
sprite_pos <= 256 - to_integer(unsigned(Sprite_X(sprite)));
|
||||
draw_sprite <= '1';
|
||||
else
|
||||
draw_sprite <= '0';
|
||||
end if;
|
||||
else
|
||||
draw_sprite <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Copy sprite to buffer
|
||||
if (draw_sprite='1' and I_HCNT(8)='1') then
|
||||
H_OFF := to_integer(unsigned(I_HCNT(4 downto 0)));
|
||||
sprite_pos <= sprite_pos + 1;
|
||||
|
||||
case H_OFF is
|
||||
|
||||
when 0 | 8 | 16 | 24 => pixel := sprite_pix_l(7) & sprite_pix_h(7);
|
||||
when 1 | 9 | 17 | 25 => pixel := sprite_pix_l(6) & sprite_pix_h(6);
|
||||
when 2 | 10 | 18 | 26 => pixel := sprite_pix_l(5) & sprite_pix_h(5);
|
||||
when 3 | 11 | 19 | 27 => pixel := sprite_pix_l(4) & sprite_pix_h(4);
|
||||
when 4 | 12 | 20 | 28 => pixel := sprite_pix_l(3) & sprite_pix_h(3);
|
||||
when 5 | 13 | 21 | 29 => pixel := sprite_pix_l(2) & sprite_pix_h(2);
|
||||
when 6 | 14 | 22 | 30 => pixel := sprite_pix_l(1) & sprite_pix_h(1);
|
||||
when 7 =>
|
||||
pixel := sprite_pix_l(0) & sprite_pix_h(0);
|
||||
-- get next byte of sprite data
|
||||
if Sprite_N(sprite)(7)='1' then
|
||||
sprite_addr <= sprite_addr + 16;
|
||||
else
|
||||
sprite_addr <= sprite_addr + 32;
|
||||
end if;
|
||||
when 15 =>
|
||||
pixel := sprite_pix_l(0) & sprite_pix_h(0);
|
||||
if Sprite_N(sprite)(7)='1' then
|
||||
draw_sprite <= '0';
|
||||
else
|
||||
sprite_addr <= sprite_addr + 32;
|
||||
end if;
|
||||
when 23 =>
|
||||
pixel := sprite_pix_l(0) & sprite_pix_h(0);
|
||||
sprite_addr <= sprite_addr + 32;
|
||||
when 31 =>
|
||||
pixel := sprite_pix_l(0) & sprite_pix_h(0);
|
||||
draw_sprite <= '0';
|
||||
|
||||
when others => pixel := "00";
|
||||
end case;
|
||||
|
||||
-- plot pixel into linebuffer (after converting to colours)
|
||||
if (pixel /= "00") then -- Transparency
|
||||
Entry := to_integer(unsigned(not Sprite_C(sprite)(2 downto 0)));
|
||||
Color := to_integer(unsigned(pixel));
|
||||
|
||||
if (sprite_buffer='0') then
|
||||
linebuffer(0,sprite_pos) <= Colour_P(Entry,Color)(2 downto 0);
|
||||
else
|
||||
linebuffer(1,sprite_pos) <= Colour_P(Entry,Color)(2 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Read and clear other buffer for drawing
|
||||
if (I_HCNT(8)='1' or I_HCNT = "011111111") then
|
||||
if I_H_FLIP='0' then
|
||||
H_OFF := to_integer(unsigned(I_HCNT(7 downto 0))) + 1;
|
||||
else
|
||||
H_OFF := 254-to_integer(unsigned(I_HCNT(7 downto 0))); -- Was 255
|
||||
end if;
|
||||
|
||||
if (sprite_buffer='0') then
|
||||
SP := linebuffer(1,H_OFF);
|
||||
linebuffer(1,H_OFF) <= "000";
|
||||
else
|
||||
SP := linebuffer(0,H_OFF);
|
||||
linebuffer(0,H_OFF) <= "000";
|
||||
end if;
|
||||
|
||||
sprite_blue <= SP(2) & SP(2) & SP(2) & SP(2);
|
||||
sprite_green <= SP(1) & SP(1) & SP(1) & SP(1);
|
||||
sprite_red <= SP(0) & SP(0) & SP(0) & SP(0);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
-- Sprite register writes, store in arrays for ease of processing
|
||||
SPR_Write : process (CLK)
|
||||
variable spr_no : integer;
|
||||
begin
|
||||
if rising_edge(CLK) then
|
||||
if (CPU_ENA='1' and I_SPR_WR ='1') then
|
||||
|
||||
spr_no := to_integer(unsigned(I_SPR_ADD(4 downto 2)));
|
||||
|
||||
case I_SPR_ADD(1 downto 0) is
|
||||
when "00" => Sprite_N(spr_no) <= I_SPR_DAT;
|
||||
when "01" => Sprite_Y(spr_no) <= I_SPR_DAT;
|
||||
when "10" => Sprite_X(spr_no) <= I_SPR_DAT;
|
||||
when "11" => Sprite_C(spr_no) <= I_SPR_DAT;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
||||
199
Arcade_MiST/Universal Cosmic Hardware/rtl/bram.vhd
Normal file
199
Arcade_MiST/Universal Cosmic Hardware/rtl/bram.vhd
Normal file
@ -0,0 +1,199 @@
|
||||
--------------------------------------------------------------
|
||||
-- Single port Block RAM
|
||||
--------------------------------------------------------------
|
||||
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.altera_mf_components.all;
|
||||
|
||||
ENTITY spram IS
|
||||
generic (
|
||||
addr_width : integer := 8;
|
||||
data_width : integer := 8;
|
||||
mem_init_file : string := " ";
|
||||
mem_name : string := "MEM" -- for InSystem Memory content editor.
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clock : in STD_LOGIC;
|
||||
address : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0);
|
||||
data : in STD_LOGIC_VECTOR (data_width-1 DOWNTO 0) := (others => '0');
|
||||
enable : in STD_LOGIC := '1';
|
||||
wren : in STD_LOGIC := '0';
|
||||
q : out STD_LOGIC_VECTOR (data_width-1 DOWNTO 0);
|
||||
cs : in std_logic := '1'
|
||||
);
|
||||
END spram;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF spram IS
|
||||
signal q0 : std_logic_vector((data_width - 1) downto 0);
|
||||
|
||||
BEGIN
|
||||
q<= q0 when cs = '1' else (others => '1');
|
||||
|
||||
altsyncram_component : altsyncram
|
||||
GENERIC MAP (
|
||||
clock_enable_input_a => "BYPASS",
|
||||
clock_enable_output_a => "BYPASS",
|
||||
intended_device_family => "Cyclone III",
|
||||
lpm_hint => "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME="&mem_name,
|
||||
lpm_type => "altsyncram",
|
||||
numwords_a => 2**addr_width,
|
||||
operation_mode => "SINGLE_PORT",
|
||||
outdata_aclr_a => "NONE",
|
||||
outdata_reg_a => "UNREGISTERED",
|
||||
power_up_uninitialized => "FALSE",
|
||||
read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ",
|
||||
init_file => mem_init_file,
|
||||
widthad_a => addr_width,
|
||||
width_a => data_width,
|
||||
width_byteena_a => 1
|
||||
)
|
||||
PORT MAP (
|
||||
address_a => address,
|
||||
clock0 => clock,
|
||||
data_a => data,
|
||||
wren_a => wren and cs,
|
||||
q_a => q0
|
||||
);
|
||||
|
||||
END SYN;
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- Dual port Block RAM same parameters on both ports
|
||||
--------------------------------------------------------------
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.altera_mf_components.all;
|
||||
|
||||
entity dpram is
|
||||
generic (
|
||||
addr_width : integer := 8;
|
||||
data_width : integer := 8;
|
||||
mem_init_file : string := " "
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clock : in STD_LOGIC;
|
||||
|
||||
address_a : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0);
|
||||
data_a : in STD_LOGIC_VECTOR (data_width-1 DOWNTO 0) := (others => '0');
|
||||
enable_a : in STD_LOGIC := '1';
|
||||
wren_a : in STD_LOGIC := '0';
|
||||
q_a : out STD_LOGIC_VECTOR (data_width-1 DOWNTO 0);
|
||||
cs_a : in std_logic := '1';
|
||||
|
||||
address_b : in STD_LOGIC_VECTOR (addr_width-1 DOWNTO 0) := (others => '0');
|
||||
data_b : in STD_LOGIC_VECTOR (data_width-1 DOWNTO 0) := (others => '0');
|
||||
enable_b : in STD_LOGIC := '1';
|
||||
wren_b : in STD_LOGIC := '0';
|
||||
q_b : out STD_LOGIC_VECTOR (data_width-1 DOWNTO 0);
|
||||
cs_b : in std_logic := '1'
|
||||
);
|
||||
end entity;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF dpram IS
|
||||
BEGIN
|
||||
ram : work.dpram_dif generic map(addr_width,data_width,addr_width,data_width,mem_init_file)
|
||||
port map(clock,address_a,data_a,enable_a,wren_a,q_a,cs_a,address_b,data_b,enable_b,wren_b,q_b,cs_b);
|
||||
END SYN;
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- Dual port Block RAM different parameters on ports
|
||||
--------------------------------------------------------------
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.altera_mf_components.all;
|
||||
|
||||
entity dpram_dif is
|
||||
generic (
|
||||
addr_width_a : integer := 8;
|
||||
data_width_a : integer := 8;
|
||||
addr_width_b : integer := 8;
|
||||
data_width_b : integer := 8;
|
||||
mem_init_file : string := " "
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clock : in STD_LOGIC;
|
||||
|
||||
address_a : in STD_LOGIC_VECTOR (addr_width_a-1 DOWNTO 0);
|
||||
data_a : in STD_LOGIC_VECTOR (data_width_a-1 DOWNTO 0) := (others => '0');
|
||||
enable_a : in STD_LOGIC := '1';
|
||||
wren_a : in STD_LOGIC := '0';
|
||||
q_a : out STD_LOGIC_VECTOR (data_width_a-1 DOWNTO 0);
|
||||
cs_a : in std_logic := '1';
|
||||
|
||||
address_b : in STD_LOGIC_VECTOR (addr_width_b-1 DOWNTO 0) := (others => '0');
|
||||
data_b : in STD_LOGIC_VECTOR (data_width_b-1 DOWNTO 0) := (others => '0');
|
||||
enable_b : in STD_LOGIC := '1';
|
||||
wren_b : in STD_LOGIC := '0';
|
||||
q_b : out STD_LOGIC_VECTOR (data_width_b-1 DOWNTO 0);
|
||||
cs_b : in std_logic := '1'
|
||||
);
|
||||
end entity;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF dpram_dif IS
|
||||
|
||||
signal q0 : std_logic_vector((data_width_a - 1) downto 0);
|
||||
signal q1 : std_logic_vector((data_width_b - 1) downto 0);
|
||||
|
||||
BEGIN
|
||||
q_a<= q0 when cs_a = '1' else (others => '1');
|
||||
q_b<= q1 when cs_b = '1' else (others => '1');
|
||||
|
||||
altsyncram_component : altsyncram
|
||||
GENERIC MAP (
|
||||
address_reg_b => "CLOCK1",
|
||||
clock_enable_input_a => "NORMAL",
|
||||
clock_enable_input_b => "NORMAL",
|
||||
clock_enable_output_a => "BYPASS",
|
||||
clock_enable_output_b => "BYPASS",
|
||||
indata_reg_b => "CLOCK1",
|
||||
intended_device_family => "Cyclone III",
|
||||
lpm_type => "altsyncram",
|
||||
numwords_a => 2**addr_width_a,
|
||||
numwords_b => 2**addr_width_b,
|
||||
operation_mode => "BIDIR_DUAL_PORT",
|
||||
outdata_aclr_a => "NONE",
|
||||
outdata_aclr_b => "NONE",
|
||||
outdata_reg_a => "UNREGISTERED",
|
||||
outdata_reg_b => "UNREGISTERED",
|
||||
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",
|
||||
init_file => mem_init_file,
|
||||
widthad_a => addr_width_a,
|
||||
widthad_b => addr_width_b,
|
||||
width_a => data_width_a,
|
||||
width_b => data_width_b,
|
||||
width_byteena_a => 1,
|
||||
width_byteena_b => 1,
|
||||
wrcontrol_wraddress_reg_b => "CLOCK1"
|
||||
)
|
||||
PORT MAP (
|
||||
address_a => address_a,
|
||||
address_b => address_b,
|
||||
clock0 => clock,
|
||||
clock1 => clock,
|
||||
clocken0 => enable_a,
|
||||
clocken1 => enable_b,
|
||||
data_a => data_a,
|
||||
data_b => data_b,
|
||||
wren_a => wren_a and cs_a,
|
||||
wren_b => wren_b and cs_b,
|
||||
q_a => q0,
|
||||
q_b => q1
|
||||
);
|
||||
|
||||
END SYN;
|
||||
|
||||
35
Arcade_MiST/Universal Cosmic Hardware/rtl/build_id.tcl
Normal file
35
Arcade_MiST/Universal Cosmic Hardware/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
|
||||
4
Arcade_MiST/Universal Cosmic Hardware/rtl/pll_mist.qip
Normal file
4
Arcade_MiST/Universal Cosmic Hardware/rtl/pll_mist.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 VHDL_FILE [file join $::quartus(qip_path) "pll_mist.vhd"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_mist.ppf"]
|
||||
397
Arcade_MiST/Universal Cosmic Hardware/rtl/pll_mist.vhd
Normal file
397
Arcade_MiST/Universal Cosmic Hardware/rtl/pll_mist.vhd
Normal file
@ -0,0 +1,397 @@
|
||||
-- megafunction wizard: %ALTPLL%
|
||||
-- GENERATION: STANDARD
|
||||
-- VERSION: WM1.0
|
||||
-- MODULE: altpll
|
||||
|
||||
-- ============================================================
|
||||
-- File Name: pll_mist.vhd
|
||||
-- Megafunction Name(s):
|
||||
-- altpll
|
||||
--
|
||||
-- Simulation Library Files(s):
|
||||
-- altera_mf
|
||||
-- ============================================================
|
||||
-- ************************************************************
|
||||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
--
|
||||
-- 13.1.4 Build 182 03/12/2014 SJ Web Edition
|
||||
-- ************************************************************
|
||||
|
||||
|
||||
--Copyright (C) 1991-2014 Altera Corporation
|
||||
--Your use of Altera Corporation's design tools, logic functions
|
||||
--and other software and tools, and its AMPP partner logic
|
||||
--functions, and any output files from any of the foregoing
|
||||
--(including device programming or simulation files), and any
|
||||
--associated documentation or information are expressly subject
|
||||
--to the terms and conditions of the Altera Program License
|
||||
--Subscription Agreement, Altera MegaCore Function License
|
||||
--Agreement, or other applicable license agreement, including,
|
||||
--without limitation, that your use is for the sole purpose of
|
||||
--programming logic devices manufactured by Altera and sold by
|
||||
--Altera or its authorized distributors. Please refer to the
|
||||
--applicable agreement for further details.
|
||||
|
||||
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.all;
|
||||
|
||||
ENTITY pll_mist IS
|
||||
PORT
|
||||
(
|
||||
areset : IN STD_LOGIC := '0';
|
||||
inclk0 : IN STD_LOGIC := '0';
|
||||
c0 : OUT STD_LOGIC ;
|
||||
c1 : OUT STD_LOGIC ;
|
||||
locked : OUT STD_LOGIC
|
||||
);
|
||||
END pll_mist;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF pll_mist IS
|
||||
|
||||
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0);
|
||||
SIGNAL sub_wire1 : STD_LOGIC ;
|
||||
SIGNAL sub_wire2 : STD_LOGIC ;
|
||||
SIGNAL sub_wire3 : STD_LOGIC ;
|
||||
SIGNAL sub_wire4 : STD_LOGIC ;
|
||||
SIGNAL sub_wire5 : STD_LOGIC_VECTOR (1 DOWNTO 0);
|
||||
SIGNAL sub_wire6_bv : BIT_VECTOR (0 DOWNTO 0);
|
||||
SIGNAL sub_wire6 : STD_LOGIC_VECTOR (0 DOWNTO 0);
|
||||
|
||||
|
||||
|
||||
COMPONENT altpll
|
||||
GENERIC (
|
||||
bandwidth_type : STRING;
|
||||
clk0_divide_by : NATURAL;
|
||||
clk0_duty_cycle : NATURAL;
|
||||
clk0_multiply_by : NATURAL;
|
||||
clk0_phase_shift : STRING;
|
||||
clk1_divide_by : NATURAL;
|
||||
clk1_duty_cycle : NATURAL;
|
||||
clk1_multiply_by : NATURAL;
|
||||
clk1_phase_shift : STRING;
|
||||
compensate_clock : STRING;
|
||||
inclk0_input_frequency : NATURAL;
|
||||
intended_device_family : STRING;
|
||||
lpm_hint : STRING;
|
||||
lpm_type : STRING;
|
||||
operation_mode : STRING;
|
||||
pll_type : STRING;
|
||||
port_activeclock : STRING;
|
||||
port_areset : STRING;
|
||||
port_clkbad0 : STRING;
|
||||
port_clkbad1 : STRING;
|
||||
port_clkloss : STRING;
|
||||
port_clkswitch : STRING;
|
||||
port_configupdate : STRING;
|
||||
port_fbin : STRING;
|
||||
port_inclk0 : STRING;
|
||||
port_inclk1 : STRING;
|
||||
port_locked : STRING;
|
||||
port_pfdena : STRING;
|
||||
port_phasecounterselect : STRING;
|
||||
port_phasedone : STRING;
|
||||
port_phasestep : STRING;
|
||||
port_phaseupdown : STRING;
|
||||
port_pllena : STRING;
|
||||
port_scanaclr : STRING;
|
||||
port_scanclk : STRING;
|
||||
port_scanclkena : STRING;
|
||||
port_scandata : STRING;
|
||||
port_scandataout : STRING;
|
||||
port_scandone : STRING;
|
||||
port_scanread : STRING;
|
||||
port_scanwrite : STRING;
|
||||
port_clk0 : STRING;
|
||||
port_clk1 : STRING;
|
||||
port_clk2 : STRING;
|
||||
port_clk3 : STRING;
|
||||
port_clk4 : STRING;
|
||||
port_clk5 : STRING;
|
||||
port_clkena0 : STRING;
|
||||
port_clkena1 : STRING;
|
||||
port_clkena2 : STRING;
|
||||
port_clkena3 : STRING;
|
||||
port_clkena4 : STRING;
|
||||
port_clkena5 : STRING;
|
||||
port_extclk0 : STRING;
|
||||
port_extclk1 : STRING;
|
||||
port_extclk2 : STRING;
|
||||
port_extclk3 : STRING;
|
||||
self_reset_on_loss_lock : STRING;
|
||||
width_clock : NATURAL
|
||||
);
|
||||
PORT (
|
||||
areset : IN STD_LOGIC ;
|
||||
clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0);
|
||||
inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
|
||||
locked : OUT STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
BEGIN
|
||||
sub_wire6_bv(0 DOWNTO 0) <= "0";
|
||||
sub_wire6 <= To_stdlogicvector(sub_wire6_bv);
|
||||
sub_wire3 <= sub_wire0(0);
|
||||
sub_wire1 <= sub_wire0(1);
|
||||
c1 <= sub_wire1;
|
||||
locked <= sub_wire2;
|
||||
c0 <= sub_wire3;
|
||||
sub_wire4 <= inclk0;
|
||||
sub_wire5 <= sub_wire6(0 DOWNTO 0) & sub_wire4;
|
||||
|
||||
altpll_component : altpll
|
||||
GENERIC MAP (
|
||||
bandwidth_type => "AUTO",
|
||||
clk0_divide_by => 3375,
|
||||
clk0_duty_cycle => 50,
|
||||
clk0_multiply_by => 5408,
|
||||
clk0_phase_shift => "0",
|
||||
clk1_divide_by => 3375,
|
||||
clk1_duty_cycle => 50,
|
||||
clk1_multiply_by => 1352,
|
||||
clk1_phase_shift => "0",
|
||||
compensate_clock => "CLK0",
|
||||
inclk0_input_frequency => 37037,
|
||||
intended_device_family => "Cyclone III",
|
||||
lpm_hint => "CBX_MODULE_PREFIX=pll_mist",
|
||||
lpm_type => "altpll",
|
||||
operation_mode => "NORMAL",
|
||||
pll_type => "AUTO",
|
||||
port_activeclock => "PORT_UNUSED",
|
||||
port_areset => "PORT_USED",
|
||||
port_clkbad0 => "PORT_UNUSED",
|
||||
port_clkbad1 => "PORT_UNUSED",
|
||||
port_clkloss => "PORT_UNUSED",
|
||||
port_clkswitch => "PORT_UNUSED",
|
||||
port_configupdate => "PORT_UNUSED",
|
||||
port_fbin => "PORT_UNUSED",
|
||||
port_inclk0 => "PORT_USED",
|
||||
port_inclk1 => "PORT_UNUSED",
|
||||
port_locked => "PORT_USED",
|
||||
port_pfdena => "PORT_UNUSED",
|
||||
port_phasecounterselect => "PORT_UNUSED",
|
||||
port_phasedone => "PORT_UNUSED",
|
||||
port_phasestep => "PORT_UNUSED",
|
||||
port_phaseupdown => "PORT_UNUSED",
|
||||
port_pllena => "PORT_UNUSED",
|
||||
port_scanaclr => "PORT_UNUSED",
|
||||
port_scanclk => "PORT_UNUSED",
|
||||
port_scanclkena => "PORT_UNUSED",
|
||||
port_scandata => "PORT_UNUSED",
|
||||
port_scandataout => "PORT_UNUSED",
|
||||
port_scandone => "PORT_UNUSED",
|
||||
port_scanread => "PORT_UNUSED",
|
||||
port_scanwrite => "PORT_UNUSED",
|
||||
port_clk0 => "PORT_USED",
|
||||
port_clk1 => "PORT_USED",
|
||||
port_clk2 => "PORT_UNUSED",
|
||||
port_clk3 => "PORT_UNUSED",
|
||||
port_clk4 => "PORT_UNUSED",
|
||||
port_clk5 => "PORT_UNUSED",
|
||||
port_clkena0 => "PORT_UNUSED",
|
||||
port_clkena1 => "PORT_UNUSED",
|
||||
port_clkena2 => "PORT_UNUSED",
|
||||
port_clkena3 => "PORT_UNUSED",
|
||||
port_clkena4 => "PORT_UNUSED",
|
||||
port_clkena5 => "PORT_UNUSED",
|
||||
port_extclk0 => "PORT_UNUSED",
|
||||
port_extclk1 => "PORT_UNUSED",
|
||||
port_extclk2 => "PORT_UNUSED",
|
||||
port_extclk3 => "PORT_UNUSED",
|
||||
self_reset_on_loss_lock => "OFF",
|
||||
width_clock => 5
|
||||
)
|
||||
PORT MAP (
|
||||
areset => areset,
|
||||
inclk => sub_wire5,
|
||||
clk => sub_wire0,
|
||||
locked => sub_wire2
|
||||
);
|
||||
|
||||
|
||||
|
||||
END SYN;
|
||||
|
||||
-- ============================================================
|
||||
-- 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 "3"
|
||||
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "9"
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "43.264000"
|
||||
-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "10.816000"
|
||||
-- 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 "deg"
|
||||
-- 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 "6"
|
||||
-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "2"
|
||||
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "43.26400000"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "10.81600000"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
|
||||
-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
|
||||
-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "deg"
|
||||
-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
|
||||
-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
|
||||
-- Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_mist.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 "3375"
|
||||
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "5408"
|
||||
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "3375"
|
||||
-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "1352"
|
||||
-- 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: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..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_mist.vhd TRUE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.ppf TRUE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.inc FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.cmp FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist.bsf FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_mist_inst.vhd FALSE
|
||||
-- Retrieval info: LIB_FILE: altera_mf
|
||||
-- Retrieval info: CBX_MODULE_PREFIX: ON
|
||||
348
Arcade_MiST/Universal Cosmic Hardware/rtl/samples.vhd
Normal file
348
Arcade_MiST/Universal Cosmic Hardware/rtl/samples.vhd
Normal file
@ -0,0 +1,348 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity samples is
|
||||
port(
|
||||
-- Sound related
|
||||
audio_enabled : in std_logic;
|
||||
audio_port_0 : in std_logic_vector( 7 downto 0);
|
||||
audio_port_1 : in std_logic_vector( 7 downto 0);
|
||||
audio_stop : in std_logic_vector(15 downto 0);
|
||||
|
||||
audio_in : in std_logic_vector(15 downto 0);
|
||||
audio_out_L : out std_logic_vector(15 downto 0);
|
||||
audio_out_R : out std_logic_vector(15 downto 0);
|
||||
|
||||
-- Access to samples
|
||||
wave_addr : out std_logic_vector(24 downto 0);
|
||||
wave_read : out std_logic;
|
||||
wave_data : in std_logic_vector(15 downto 0);
|
||||
|
||||
-- table loading
|
||||
dl_addr : in std_logic_vector(24 downto 0);
|
||||
dl_wr : in std_logic;
|
||||
dl_data : in std_logic_vector( 7 downto 0);
|
||||
dl_download : in std_logic;
|
||||
samples_ok : out std_logic;
|
||||
|
||||
-- Clocks and things
|
||||
CLK_SYS : in std_logic; -- (for loading table)
|
||||
clock : in std_logic; -- 43.264 Mhz (this drives the rest)
|
||||
reset : in std_logic -- high to reset
|
||||
);
|
||||
end samples;
|
||||
|
||||
architecture struct of samples is
|
||||
|
||||
-- Clock dividers
|
||||
signal wav_clk_cnt : std_logic_vector(11 downto 0); -- 44kHz divider / sound counter (43.264 Mhz count to 981 (x"3D5") for 44khz clock)
|
||||
signal wav_freq_cnt : std_logic_vector(1 downto 0); -- divide further to give 22Khz (0) and 11Khz (1)
|
||||
signal wav_freq_lst : std_logic_vector(1 downto 0); -- for rising edge checks
|
||||
|
||||
-- wave info (aka Table)
|
||||
type addr_t is array (0 to 15) of std_logic_vector(23 downto 0);
|
||||
type mode_t is array (0 to 15) of std_logic_vector(15 downto 0);
|
||||
|
||||
signal wav_addr_start : addr_t;
|
||||
signal wav_addr_end : addr_t;
|
||||
signal wav_mode : mode_t := (others=>(others=>'0'));
|
||||
signal table_loaded : std_logic register := '0';
|
||||
|
||||
signal wave_left : std_logic_vector(15 downto 0) register := (others=>'0');
|
||||
signal wave_right : std_logic_vector(15 downto 0) register := (others=>'0');
|
||||
signal wave_read_ct : std_logic_vector(2 downto 0) register := (others=>'0');
|
||||
|
||||
-- sound control info
|
||||
signal snd_id : integer;
|
||||
signal snd_addr_play : addr_t := (others=>(others=>'1'));
|
||||
signal ports : std_logic_vector(15 downto 0);
|
||||
signal last_ports : std_logic_vector(15 downto 0);
|
||||
signal this_ports : std_logic_vector(15 downto 0);
|
||||
signal next_ports : std_logic_vector(15 downto 0);
|
||||
signal this_stop : std_logic_vector(15 downto 0);
|
||||
signal next_stop : std_logic_vector(15 downto 0);
|
||||
|
||||
-- Audio variables
|
||||
signal audio_sum_l : signed(19 downto 0);
|
||||
signal audio_sum_r : signed(19 downto 0);
|
||||
signal audio_l : signed(19 downto 0);
|
||||
signal audio_r : signed(19 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
----------------
|
||||
-- Table Load --
|
||||
----------------
|
||||
|
||||
-- wav_mode - 8 bits - if byte = 00 then this bit does not trigger anything
|
||||
-- bit 0 = 11khz
|
||||
-- bit 1 = 22khz
|
||||
-- bit 2 = 44khz
|
||||
-- bit 4 = 16 bit (off = 8 bit)
|
||||
-- bit 5 = Stereo (off = mono)
|
||||
--
|
||||
-- trigger mode - 8 bits
|
||||
-- bit 0 = ON one shot (sample plays once)
|
||||
-- bit 0 = OFF restarts if bit still active at end (loops)
|
||||
-- bit 1 = ON cuts off sample if bit goes low (should it fade?)
|
||||
-- bit 1 = OFF continues until end of sample reached
|
||||
-- bit 4 = output LEFT channel
|
||||
-- bit 5 = output RIGHT channel (set both for MONO/STEREO)
|
||||
|
||||
process (CLK_SYS,dl_download,dl_wr,dl_data)
|
||||
variable ID : integer;
|
||||
begin
|
||||
if rising_edge(CLK_SYS) then
|
||||
|
||||
if dl_download='1' and dl_wr='1' then
|
||||
|
||||
ID := to_integer(unsigned(dl_addr(6 downto 3)));
|
||||
|
||||
case dl_addr(2 downto 0) is
|
||||
when "000" => -- Wave mode
|
||||
wav_mode(ID)(7 downto 0) <= dl_data;
|
||||
if dl_data(2 downto 0) /= "000" then
|
||||
table_loaded <= '1';
|
||||
end if;
|
||||
when "001" => -- Trigger mode
|
||||
wav_mode(ID)(15 downto 8) <= dl_data;
|
||||
when "010" => -- Start Address
|
||||
wav_addr_start(ID)(23 downto 16) <= dl_data;
|
||||
when "011" => -- Start Address
|
||||
wav_addr_start(ID)(15 downto 8) <= dl_data;
|
||||
when "100" => -- Start Address
|
||||
wav_addr_start(ID)(7 downto 0) <= dl_data;
|
||||
when "101" => -- End Address
|
||||
wav_addr_end(ID)(23 downto 16) <= dl_data;
|
||||
when "110" => -- End Address
|
||||
wav_addr_end(ID)(15 downto 8) <= dl_data;
|
||||
when "111" => -- End Address
|
||||
wav_addr_end(ID)(7 downto 0) <= dl_data;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-----------------
|
||||
-- Wave player --
|
||||
-----------------
|
||||
|
||||
-- current IO bit & sample to be looking at
|
||||
snd_id <= to_integer(unsigned(wav_clk_cnt(11 downto 5)));
|
||||
ports <= audio_port_1 & audio_port_0;
|
||||
samples_ok <= table_loaded;
|
||||
|
||||
--wave_data <= wave_data1 & wave_data1;
|
||||
|
||||
-- wave player
|
||||
process (clock, reset, table_loaded)
|
||||
begin
|
||||
if table_loaded='1' then
|
||||
if reset='1' then
|
||||
wav_clk_cnt <= (others=>'0');
|
||||
wav_freq_cnt <= "00";
|
||||
snd_addr_play <= (others=>(others=>'1'));
|
||||
wave_read <= '0';
|
||||
audio_out_L <= x"0000";
|
||||
audio_out_R <= x"0000";
|
||||
else
|
||||
-- Use falling edge to interleave commands with SDRAM module
|
||||
if falling_edge(clock) then
|
||||
|
||||
-- make sure we don't miss any bits being set
|
||||
next_ports <= next_ports or ports;
|
||||
next_stop <= next_stop or audio_stop;
|
||||
|
||||
if snd_id <= 15 then
|
||||
if snd_addr_play(snd_id)=x"FFFFFF" then
|
||||
-- All Start play on 0 to 1 transition
|
||||
if (last_ports(snd_id)='0' and this_ports(snd_id)='1') then
|
||||
snd_addr_play(snd_id) <= wav_addr_start(snd_id);
|
||||
end if;
|
||||
else
|
||||
-- cut out when signal zero
|
||||
if (wav_mode(snd_id)(9)='1' and this_ports(snd_id)='0') then
|
||||
snd_addr_play(snd_id) <= x"FFFFFF";
|
||||
end if;
|
||||
-- cut out when STOP set high
|
||||
if (this_stop(snd_id)='1') then
|
||||
-- But may just want to restart this sample
|
||||
if this_ports(snd_id)='1' then
|
||||
snd_addr_play(snd_id) <= wav_addr_start(snd_id);
|
||||
else
|
||||
snd_addr_play(snd_id) <= x"FFFFFF";
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- 44.1kHz base tempo / high bits for scanning sound
|
||||
if wav_clk_cnt = x"3D5" then -- divide 43.264 Mhz by 981 => 44.102kHz
|
||||
|
||||
wav_clk_cnt <= (others=>'0');
|
||||
wav_freq_lst <= wav_freq_cnt;
|
||||
wav_freq_cnt <= wav_freq_cnt + '1';
|
||||
|
||||
-- cycle along ports last / this
|
||||
last_ports <= this_ports;
|
||||
this_ports <= next_ports;
|
||||
next_ports <= ports;
|
||||
|
||||
this_stop <= next_stop;
|
||||
next_stop <= audio_stop;
|
||||
|
||||
-- latch final audio / reset sum
|
||||
audio_r <= audio_sum_r;
|
||||
audio_l <= audio_sum_l;
|
||||
audio_sum_r <= resize(signed(audio_in), 20);
|
||||
audio_sum_l <= resize(signed(audio_in), 20);
|
||||
else
|
||||
wav_clk_cnt <= wav_clk_cnt + 1;
|
||||
end if;
|
||||
|
||||
if audio_enabled='1' then
|
||||
-- -- clip audio
|
||||
-- if audio_r(19 downto 2) > 32767 then
|
||||
-- audio_out_R <= x"7FFF";
|
||||
-- elsif audio_r(19 downto 2) < -32768 then
|
||||
-- audio_out_R <= x"8000";
|
||||
-- else
|
||||
-- audio_out_R <= std_logic_vector(audio_r(17 downto 2));
|
||||
-- end if;
|
||||
--
|
||||
-- if audio_l(19 downto 2) > 32767 then
|
||||
-- audio_out_L <= x"7FFF";
|
||||
-- elsif audio_l(19 downto 2) < -32768 then
|
||||
-- audio_out_L <= x"8000";
|
||||
-- else
|
||||
-- audio_out_L <= std_logic_vector(audio_l(17 downto 2));
|
||||
-- end if;
|
||||
|
||||
audio_out_R <= std_logic_vector(audio_r(17 downto 2));
|
||||
audio_out_L <= std_logic_vector(audio_l(17 downto 2));
|
||||
|
||||
else
|
||||
audio_out_L <= x"0000";
|
||||
audio_out_R <= x"0000";
|
||||
end if;
|
||||
|
||||
-- sdram read trigger (and auto refresh period)
|
||||
if wav_clk_cnt(4 downto 0) = "00001" then wave_read <= '1';end if;
|
||||
if wav_clk_cnt(4 downto 0) = "00011" then wave_read <= '0';end if;
|
||||
|
||||
-- select only useful cycles (0-15)
|
||||
if snd_id <= 15 then
|
||||
|
||||
-- is this sample present
|
||||
if wav_mode(snd_id)(2 downto 0) /= "000" then
|
||||
|
||||
if snd_addr_play(snd_id) /= x"FFFFFF" then
|
||||
|
||||
---------------
|
||||
-- Data read --
|
||||
---------------
|
||||
|
||||
-- set addr for first byte (but it reads 4 bytes anyway)
|
||||
if wav_clk_cnt(4 downto 0) = "00000" then
|
||||
wave_addr <= '0' & snd_addr_play(snd_id);
|
||||
end if;
|
||||
|
||||
if wav_clk_cnt(4 downto 0) = "01000" then -- "11101" then
|
||||
-- SDRAM bit : data returned, put into left / right accordingly
|
||||
case wav_mode(snd_id)(5 downto 4) is
|
||||
|
||||
when "00" => -- 8 bit mono
|
||||
if snd_addr_play(snd_id)(0)='0' then
|
||||
-- Low byte
|
||||
wave_left <= (not wave_data(7)) & wave_data(6 downto 0) & x"00";
|
||||
wave_right <= (not wave_data(7)) & wave_data(6 downto 0) & x"00";
|
||||
else
|
||||
-- high byte
|
||||
wave_left <= (not wave_data(15)) & wave_data(14 downto 8) & x"00";
|
||||
wave_right <= (not wave_data(15)) & wave_data(14 downto 8) & x"00";
|
||||
end if;
|
||||
|
||||
when "01" => -- 16 bit mono
|
||||
wave_left <= wave_data;
|
||||
wave_right <= wave_data;
|
||||
|
||||
when "10" => -- 8 bit stereo
|
||||
wave_left <= (not wave_data(7)) & wave_data(6 downto 0) & x"00";
|
||||
wave_right <= (not wave_data(15)) & wave_data(14 downto 8) & x"00";
|
||||
|
||||
when "11" => -- 16 bit stereo (won't work with curent SDRAM controller!)
|
||||
wave_left <= wave_data;
|
||||
wave_right <= wave_data;
|
||||
|
||||
end case;
|
||||
end if;
|
||||
|
||||
-- Data all read, add to output counters
|
||||
if wav_clk_cnt(4 downto 0) = "01001" then -- "111110" then
|
||||
|
||||
-- Left channel
|
||||
if wav_mode(snd_id)(12)='1' then
|
||||
audio_sum_l <= audio_sum_l + to_integer(signed(wave_left));
|
||||
end if;
|
||||
|
||||
-- Right channel
|
||||
if wav_mode(snd_id)(13)='1' then
|
||||
audio_sum_r <= audio_sum_r + to_integer(signed(wave_right));
|
||||
--audio_sum_r <= audio_sum_r + to_integer(signed(samp_data));
|
||||
end if;
|
||||
|
||||
--wave_left <= x"0000";
|
||||
--wave_right <= x"0000";
|
||||
|
||||
-- Increment address depending on frequency and size
|
||||
if wav_mode(snd_id)(2)='1' or
|
||||
(wav_mode(snd_id)(1)='1' and wav_freq_lst(0)='0' and wav_freq_cnt(0)='1') or
|
||||
(wav_mode(snd_id)(0)='1' and wav_freq_lst(1)='0' and wav_freq_cnt(1)='1') then
|
||||
|
||||
case wav_mode(snd_id)(5 downto 4) is
|
||||
when "00" =>
|
||||
-- 8 bit mono
|
||||
snd_addr_play(snd_id) <= snd_addr_play(snd_id) + 1;
|
||||
when "01" | "10" =>
|
||||
-- 16 bit mono or 8 bit stereo
|
||||
snd_addr_play(snd_id) <= snd_addr_play(snd_id) + 2;
|
||||
when "11" =>
|
||||
-- 16 bit stereo
|
||||
snd_addr_play(snd_id) <= snd_addr_play(snd_id) + 4;
|
||||
end case;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
if wav_clk_cnt(4 downto 0) = "01111" then -- "111111" then
|
||||
-- End of Wave data ?
|
||||
if snd_addr_play(snd_id) > wav_addr_end(snd_id) then
|
||||
-- Restart ?
|
||||
if (wav_mode(snd_id)(8)='0' and this_ports(snd_id)='1') then
|
||||
-- Loop back to the start
|
||||
snd_addr_play(snd_id) <= wav_addr_start(snd_id);
|
||||
else
|
||||
-- Stop
|
||||
snd_addr_play(snd_id) <= x"FFFFFF";
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end if; -- Playing
|
||||
|
||||
end if; -- Bit Active
|
||||
|
||||
end if; -- useful
|
||||
|
||||
end if; -- rising clock
|
||||
|
||||
end if; -- reset
|
||||
|
||||
end if; -- table loaded
|
||||
|
||||
end process;
|
||||
|
||||
end;
|
||||
209
Arcade_MiST/Universal Cosmic Hardware/rtl/sdram.sv
Normal file
209
Arcade_MiST/Universal Cosmic Hardware/rtl/sdram.sv
Normal file
@ -0,0 +1,209 @@
|
||||
//
|
||||
// sdram.v
|
||||
//
|
||||
// Static RAM controller implementation using SDRAM MT48LC16M16A2
|
||||
//
|
||||
// Copyright (c) 2015-2019 Sorgelig
|
||||
//
|
||||
// Some parts of SDRAM code used from project:
|
||||
// http://hamsterworks.co.nz/mediawiki/index.php/Simple_SDRAM_Controller
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
// ------------------------------------------
|
||||
//
|
||||
// v2.1 - Add universal 8/16 bit mode.
|
||||
//
|
||||
|
||||
module sdram
|
||||
(
|
||||
input init, // reset to initialize RAM
|
||||
input clk, // clock ~100MHz
|
||||
//
|
||||
// SDRAM_* - signals 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, //
|
||||
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
|
||||
output SDRAM_CKE, // clock enable
|
||||
//
|
||||
input [24:0] addr, // 25 bit address for 8bit mode. addr[0] = 0 for 16bit mode for correct operations.
|
||||
output [15:0] dout, // data output to cpu
|
||||
input [7:0] din, // data input from cpu
|
||||
input we, // cpu requests write
|
||||
input rd, // cpu requests read
|
||||
output reg ready // dout is valid. Ready to accept new read/write.
|
||||
);
|
||||
|
||||
assign SDRAM_CKE = 1;
|
||||
assign SDRAM_nCS = 0;
|
||||
assign SDRAM_nRAS = command[2];
|
||||
assign SDRAM_nCAS = command[1];
|
||||
assign SDRAM_nWE = command[0];
|
||||
assign {SDRAM_DQMH,SDRAM_DQML} = SDRAM_A[12:11];
|
||||
|
||||
|
||||
// no burst configured
|
||||
localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8
|
||||
localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
|
||||
localparam CAS_LATENCY = 3'd2; // 2 for < 100MHz, 3 for >100MHz
|
||||
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};
|
||||
|
||||
localparam sdram_startup_cycles= 14'd12100;// 100us, plus a little more, @ 100MHz
|
||||
localparam cycles_per_refresh = 14'd780; // (64000*100)/8192-1 Calc'd as (64ms @ 100MHz)/8192 rose
|
||||
localparam startup_refresh_max = 14'b11111111111111;
|
||||
|
||||
// SDRAM commands
|
||||
wire [2:0] CMD_NOP = 3'b111;
|
||||
wire [2:0] CMD_ACTIVE = 3'b011;
|
||||
wire [2:0] CMD_READ = 3'b101;
|
||||
wire [2:0] CMD_WRITE = 3'b100;
|
||||
wire [2:0] CMD_PRECHARGE = 3'b010;
|
||||
wire [2:0] CMD_AUTO_REFRESH = 3'b001;
|
||||
wire [2:0] CMD_LOAD_MODE = 3'b000;
|
||||
|
||||
reg [13:0] refresh_count = startup_refresh_max - sdram_startup_cycles;
|
||||
reg [2:0] command;
|
||||
reg [24:0] save_addr;
|
||||
|
||||
reg [15:0] data;
|
||||
assign dout = data;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STATE_STARTUP,
|
||||
STATE_OPEN_1, STATE_OPEN_2,
|
||||
STATE_IDLE, STATE_IDLE_1, STATE_IDLE_2, STATE_IDLE_3,
|
||||
STATE_IDLE_4, STATE_IDLE_5, STATE_IDLE_6, STATE_IDLE_7
|
||||
} state_t;
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg old_we, old_rd;
|
||||
reg [CAS_LATENCY:0] data_ready_delay;
|
||||
|
||||
reg [7:0] new_data;
|
||||
reg new_we;
|
||||
reg new_rd;
|
||||
reg save_we = 1;
|
||||
|
||||
state_t state = STATE_STARTUP;
|
||||
|
||||
SDRAM_DQ <= 16'bZ;
|
||||
command <= CMD_NOP;
|
||||
refresh_count <= refresh_count+1'b1;
|
||||
|
||||
data_ready_delay <= {1'b0, data_ready_delay[CAS_LATENCY:1]};
|
||||
|
||||
if(data_ready_delay[0]) {ready, data} <= {1'b1, SDRAM_DQ};
|
||||
|
||||
case(state)
|
||||
STATE_STARTUP: begin
|
||||
SDRAM_A <= 0;
|
||||
SDRAM_BA <= 0;
|
||||
|
||||
if (refresh_count == startup_refresh_max-31) begin
|
||||
command <= CMD_PRECHARGE;
|
||||
SDRAM_A[10] <= 1; // all banks
|
||||
SDRAM_BA <= 2'b00;
|
||||
end
|
||||
if (refresh_count == startup_refresh_max-23) begin
|
||||
command <= CMD_AUTO_REFRESH;
|
||||
end
|
||||
if (refresh_count == startup_refresh_max-15) begin
|
||||
command <= CMD_AUTO_REFRESH;
|
||||
end
|
||||
if (refresh_count == startup_refresh_max-7) begin
|
||||
command <= CMD_LOAD_MODE;
|
||||
SDRAM_A <= MODE;
|
||||
end
|
||||
|
||||
if(!refresh_count) begin
|
||||
state <= STATE_IDLE;
|
||||
ready <= 1;
|
||||
refresh_count <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_IDLE_7: state <= STATE_IDLE_6;
|
||||
STATE_IDLE_6: state <= STATE_IDLE_5;
|
||||
STATE_IDLE_5: state <= STATE_IDLE_4;
|
||||
STATE_IDLE_4: state <= STATE_IDLE_3;
|
||||
STATE_IDLE_3: state <= STATE_IDLE_2;
|
||||
STATE_IDLE_2: state <= STATE_IDLE_1;
|
||||
STATE_IDLE_1: begin
|
||||
state <= STATE_IDLE;
|
||||
// mask possible refresh to reduce colliding.
|
||||
if(refresh_count > cycles_per_refresh) begin
|
||||
state <= STATE_IDLE_7;
|
||||
command <= CMD_AUTO_REFRESH;
|
||||
refresh_count <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
STATE_IDLE: begin
|
||||
// Priority is to issue a refresh if one is outstanding
|
||||
if(refresh_count > (cycles_per_refresh<<1)) state <= STATE_IDLE_1;
|
||||
else if(new_rd | new_we) begin
|
||||
new_we <= 0;
|
||||
new_rd <= 0;
|
||||
save_addr<= addr;
|
||||
save_we <= new_we;
|
||||
state <= STATE_OPEN_1;
|
||||
command <= CMD_ACTIVE;
|
||||
SDRAM_A <= addr[13:1];
|
||||
SDRAM_BA <= addr[24:23];
|
||||
end
|
||||
end
|
||||
|
||||
STATE_OPEN_1: state <= STATE_OPEN_2;
|
||||
|
||||
STATE_OPEN_2: begin
|
||||
SDRAM_A <= {save_we & ~save_addr[0], save_we & save_addr[0], 2'b10, save_addr[22:14]};
|
||||
if(save_we) begin
|
||||
command <= CMD_WRITE;
|
||||
SDRAM_DQ <= {new_data[7:0], new_data[7:0]};
|
||||
ready <= 1;
|
||||
state <= STATE_IDLE_2;
|
||||
end
|
||||
else begin
|
||||
command <= CMD_READ;
|
||||
data_ready_delay[CAS_LATENCY] <= 1;
|
||||
state <= STATE_IDLE_5;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
if(init) begin
|
||||
state <= STATE_STARTUP;
|
||||
refresh_count <= startup_refresh_max - sdram_startup_cycles;
|
||||
end
|
||||
|
||||
old_we <= we;
|
||||
if(we & ~old_we) {ready, new_we, new_data} <= {1'b0, 1'b1, din};
|
||||
|
||||
old_rd <= rd;
|
||||
if(rd & ~old_rd) begin
|
||||
if(ready & ~save_we & (save_addr[24:1] == addr[24:1])) save_addr <= addr;
|
||||
else {ready, new_rd} <= {1'b0, 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@ -107,8 +107,8 @@ always @(*) begin
|
||||
begin
|
||||
BTN = { m_one_player, m_two_players, m_coin1 | m_coin2, reset };
|
||||
// Fire Up/Down/Left/Right maps to joystick 1/2/3/4 and keyboard R/F/D/G (MAME style)
|
||||
JA = ~{ m_fireD|m_right2, m_fireC|m_left2, m_fireB|m_down2, m_fireA|m_up2, m_right, m_left, m_down, m_up };
|
||||
JB = ~{ m_fireD|m_right2, m_fireC|m_left2, m_fireB|m_down2, m_fireA|m_up2, m_right, m_left, m_down, m_up };
|
||||
JA = ~{ m_fireD|m_right2|m_rightB, m_fireC|m_left2|m_leftB, m_fireB|m_down2|m_downB, m_fireA|m_up2|m_upB, m_right, m_left, m_down, m_up };
|
||||
JB = ~{ m_fireD|m_right2|m_rightB, m_fireC|m_left2|m_leftB, m_fireB|m_down2|m_downB, m_fireA|m_up2|m_upB, m_right, m_left, m_down, m_up };
|
||||
end
|
||||
7'h1: // JOUST
|
||||
begin
|
||||
@ -121,8 +121,8 @@ always @(*) begin
|
||||
blitter_sc2 = 1;
|
||||
BTN = { m_one_player, m_two_players, m_coin1 | m_coin2, reset };
|
||||
// Fire Up/Down/Left/Right maps to joystick 1/2/3/4 and keyboard R/F/D/G (MAME style)
|
||||
JA = ~{ m_fireD|m_right2, m_fireC|m_left2, m_fireB|m_down2, m_fireA|m_up2, m_right, m_left, m_down, m_up };
|
||||
JB = ~{ m_fireD|m_right2, m_fireC|m_left2, m_fireB|m_down2, m_fireA|m_up2, m_right, m_left, m_down, m_up };
|
||||
JA = ~{ m_fireD|m_right2|m_rightB, m_fireC|m_left2|m_leftB, m_fireB|m_down2|m_downB, m_fireA|m_up2|m_upB, m_right, m_left, m_down, m_up };
|
||||
JB = ~{ m_fireD|m_right2|m_rightB, m_fireC|m_left2|m_leftB, m_fireB|m_down2|m_downB, m_fireA|m_up2|m_upB, m_right, m_left, m_down, m_up };
|
||||
end
|
||||
7'h3: // BUBBLES
|
||||
begin
|
||||
@ -225,8 +225,8 @@ pll_aud pll_aud (
|
||||
wire [31:0] status;
|
||||
wire [1:0] buttons;
|
||||
wire [1:0] switches;
|
||||
wire [7:0] joystick_0;
|
||||
wire [7:0] joystick_1;
|
||||
wire [19:0] joystick_0;
|
||||
wire [19:0] joystick_1;
|
||||
wire scandoublerD;
|
||||
wire no_csync;
|
||||
wire ypbpr;
|
||||
@ -487,11 +487,11 @@ always @(posedge clk_sys) begin
|
||||
else if (m_down | m_down2) sin_y <= 1;
|
||||
end
|
||||
|
||||
// General controls
|
||||
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_up3, m_down3, m_left3, m_right3, m_fire3A, m_fire3B, m_fire3C, m_fire3D, m_fire3E, m_fire3F;
|
||||
wire m_up4, m_down4, m_left4, m_right4, m_fire4A, m_fire4B, m_fire4C, m_fire4D, m_fire4E, m_fire4F;
|
||||
// Common inputs
|
||||
wire m_up, m_down, m_left, m_right, m_fireA, m_fireB, m_fireC, m_fireD, m_fireE, m_fireF, m_upB, m_downB, m_leftB, m_rightB;
|
||||
wire m_up2, m_down2, m_left2, m_right2, m_fire2A, m_fire2B, m_fire2C, m_fire2D, m_fire2E, m_fire2F, m_up2B, m_down2B, m_left2B, m_right2B;
|
||||
wire m_up3, m_down3, m_left3, m_right3, m_fire3A, m_fire3B, m_fire3C, m_fire3D, m_fire3E, m_fire3F, m_up3B, m_down3B, m_left3B, m_right3B;
|
||||
wire m_up4, m_down4, m_left4, m_right4, m_fire4A, m_fire4B, m_fire4C, m_fire4D, m_fire4E, m_fire4F, m_up4B, m_down4B, m_left4B, m_right4B;
|
||||
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 (
|
||||
@ -506,10 +506,10 @@ arcade_inputs inputs (
|
||||
.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} ),
|
||||
.player3 ( {m_fire3F, m_fire3E, m_fire3D, m_fire3C, m_fire3B, m_fire3A, m_up3, m_down3, m_left3, m_right3} ),
|
||||
.player4 ( {m_fire4F, m_fire4E, m_fire4D, m_fire4C, m_fire4B, m_fire4A, m_up4, m_down4, m_left4, m_right4} )
|
||||
.player1 ( {m_upB, m_downB, m_leftB, m_rightB, 6'd0, m_fireF, m_fireE, m_fireD, m_fireC, m_fireB, m_fireA, m_up, m_down, m_left, m_right} ),
|
||||
.player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, 6'd0, m_fire2F, m_fire2E, m_fire2D, m_fire2C, m_fire2B, m_fire2A, m_up2, m_down2, m_left2, m_right2} ),
|
||||
.player3 ( {m_up3B, m_down3B, m_left3B, m_right3B, 6'd0, m_fire3F, m_fire3E, m_fire3D, m_fire3C, m_fire3B, m_fire3A, m_up3, m_down3, m_left3, m_right3} ),
|
||||
.player4 ( {m_up4B, m_down4B, m_left4B, m_right4B, 6'd0, m_fire4F, m_fire4E, m_fire4D, m_fire4C, m_fire4B, m_fire4A, m_up4, m_down4, m_left4, m_right4} )
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
@ -8,10 +8,10 @@ module arcade_inputs(
|
||||
input key_strobe,
|
||||
input key_pressed,
|
||||
input [7:0] key_code,
|
||||
input [15:0] joystick_0,
|
||||
input [15:0] joystick_1,
|
||||
input [15:0] joystick_2,
|
||||
input [15:0] joystick_3,
|
||||
input [19:0] joystick_0,
|
||||
input [19:0] joystick_1,
|
||||
input [19:0] joystick_2,
|
||||
input [19:0] joystick_3,
|
||||
|
||||
// required rotating of controls
|
||||
input rotate,
|
||||
@ -24,36 +24,43 @@ module arcade_inputs(
|
||||
|
||||
// tilt, coin4-1, start4-1
|
||||
output [8:0] controls,
|
||||
// fire12-1, up, down, left, right
|
||||
output [15:0] player1,
|
||||
output [15:0] player2,
|
||||
output [15:0] player3,
|
||||
output [15:0] player4
|
||||
// up2, down2, left2, right2, fire12-1, up, down, left, right
|
||||
output [19:0] player1,
|
||||
output [19:0] player2,
|
||||
output [19:0] player3,
|
||||
output [19:0] player4
|
||||
);
|
||||
|
||||
assign controls = { btn_tilt,
|
||||
btn_coin | btn_coin4_mame, btn_coin | btn_coin3_mame, btn_coin | btn_coin2_mame, btn_coin | btn_coin1_mame,
|
||||
btn_four_players | btn_start4_mame, btn_three_players | btn_start3_mame, btn_two_players | btn_start2_mame, btn_one_player | btn_start1_mame };
|
||||
btn_four_players | btn_start4_mame, btn_three_players | btn_start3_mame, btn_two_players | btn_start2_mame, btn_one_player | btn_start1_mame };
|
||||
|
||||
wire [15:0] joy0 = joyswap ? joystick_1 : joystick_0;
|
||||
wire [15:0] joy1 = joyswap ? joystick_0 : joystick_1;
|
||||
wire [15:0] joy2 = joystick_2;
|
||||
wire [15:0] joy3 = joystick_3;
|
||||
wire [19:0] joy0 = joyswap ? joystick_1 : joystick_0;
|
||||
wire [19:0] joy1 = joyswap ? joystick_0 : joystick_1;
|
||||
wire [19:0] joy2 = joystick_2;
|
||||
wire [19:0] joy3 = joystick_3;
|
||||
|
||||
wire [15:0] p1;
|
||||
wire [15:0] p2;
|
||||
wire [15:0] p3;
|
||||
wire [15:0] p4;
|
||||
wire [19:0] p1;
|
||||
wire [19:0] p2;
|
||||
wire [19:0] p3;
|
||||
wire [19:0] p4;
|
||||
|
||||
assign p1[15:4] = joy0[15:4] | { 4'h0, btn_fireH, btn_fireG, btn_fireF, btn_fireE, btn_fireD, btn_fireC, btn_fireB, btn_fireA };
|
||||
assign p2[15:4] = joy1[15:4] | { 4'h0, btn_fire2H, btn_fire2G, btn_fire2F, btn_fire2E, btn_fire2D, btn_fire2C, btn_fire2B, btn_fire2A };
|
||||
assign p3[15:4] = joy2[15:4];
|
||||
assign p4[15:4] = joy3[15:4];
|
||||
|
||||
control_rotator r1(joy0[3:0], {btn_up, btn_down, btn_left, btn_right }, rotate, orientation, p1[3:0]);
|
||||
control_rotator r2(joy1[3:0], {btn_up2, btn_down2, btn_left2, btn_right2}, rotate, orientation, p2[3:0]);
|
||||
control_rotator r3(joy2[3:0], 4'd0, rotate, orientation, p3[3:0]);
|
||||
control_rotator r4(joy3[3:0], 4'd0, rotate, orientation, p4[3:0]);
|
||||
// Left or only stick
|
||||
control_rotator l1(joy0[3:0], {btn_up, btn_down, btn_left, btn_right }, rotate, orientation, p1[3:0]);
|
||||
control_rotator l2(joy1[3:0], {btn_up2, btn_down2, btn_left2, btn_right2}, rotate, orientation, p2[3:0]);
|
||||
control_rotator l3(joy2[3:0], 4'd0, rotate, orientation, p3[3:0]);
|
||||
control_rotator l4(joy3[3:0], 4'd0, rotate, orientation, p4[3:0]);
|
||||
|
||||
// Right stick
|
||||
control_rotator r1(joy0[19:16], 4'd0, rotate, orientation, p1[19:16]);
|
||||
control_rotator r2(joy1[19:16], 4'd0, rotate, orientation, p2[19:16]);
|
||||
control_rotator r3(joy2[19:16], 4'd0, rotate, orientation, p3[19:16]);
|
||||
control_rotator r4(joy3[19:16], 4'd0, rotate, orientation, p4[19:16]);
|
||||
|
||||
assign player1 = oneplayer ? p1 | p2 : p1;
|
||||
assign player2 = oneplayer ? p1 | p2 : p2;
|
||||
|
||||
@ -17,21 +17,24 @@ generic(
|
||||
PS2DIV : integer := 100;
|
||||
ROM_DIRECT_UPLOAD : boolean := false;
|
||||
SD_IMAGES: integer := 2;
|
||||
PS2BIDIR : boolean := false
|
||||
PS2BIDIR : boolean := false;
|
||||
FEATURES: std_logic_vector(31 downto 0) := (others=>'0')
|
||||
);
|
||||
port (
|
||||
clk_sys : in std_logic;
|
||||
clk_sd : in std_logic := '0';
|
||||
SPI_CLK, SPI_SS_IO, SPI_MOSI :in std_logic;
|
||||
SPI_MISO : out std_logic;
|
||||
conf_str : in std_logic_vector(8*STRLEN-1 downto 0);
|
||||
conf_str : in std_logic_vector(8*STRLEN-1 downto 0) := (others => '0');
|
||||
conf_addr : out std_logic_vector(9 downto 0);
|
||||
conf_chr : in std_logic_vector(7 downto 0) := (others => '0');
|
||||
joystick_0 : out std_logic_vector(31 downto 0);
|
||||
joystick_1 : out std_logic_vector(31 downto 0);
|
||||
joystick_2 : out std_logic_vector(31 downto 0);
|
||||
joystick_3 : out std_logic_vector(31 downto 0);
|
||||
joystick_4 : out std_logic_vector(31 downto 0);
|
||||
joystick_analog_0 : out std_logic_vector(15 downto 0);
|
||||
joystick_analog_1 : out std_logic_vector(15 downto 0);
|
||||
joystick_analog_0 : out std_logic_vector(31 downto 0);
|
||||
joystick_analog_1 : out std_logic_vector(31 downto 0);
|
||||
status : out std_logic_vector(63 downto 0);
|
||||
switches : out std_logic_vector(1 downto 0);
|
||||
buttons : out std_logic_vector(1 downto 0);
|
||||
@ -117,4 +120,4 @@ port (
|
||||
);
|
||||
end component mist_video;
|
||||
|
||||
end package;
|
||||
end package;
|
||||
|
||||
@ -36,7 +36,7 @@ module sd_card (
|
||||
output sd_sdhc,
|
||||
|
||||
input img_mounted,
|
||||
input [31:0] img_size,
|
||||
input [63:0] img_size,
|
||||
|
||||
output reg sd_busy = 0,
|
||||
// data coming in from io controller
|
||||
@ -49,6 +49,9 @@ module sd_card (
|
||||
input [8:0] sd_buff_addr,
|
||||
|
||||
// configuration input
|
||||
// in case of a VHD file, this will determine the SD Card type returned to the SPI master
|
||||
// in case of a pass-through, the firmware will display a warning if SDHC is not allowed,
|
||||
// but the card inserted is SDHC
|
||||
input allow_sdhc,
|
||||
|
||||
input sd_cs,
|
||||
@ -57,9 +60,9 @@ module sd_card (
|
||||
output reg sd_sdo
|
||||
);
|
||||
|
||||
wire [31:0] OCR = { 1'b1, sd_sdhc, 6'h0, 9'h1f, 15'h0 }; // bit31 = finished powerup
|
||||
// bit30 = 1 -> high capaciry card (sdhc)
|
||||
// 15-23 supported voltage range
|
||||
wire [31:0] OCR = { 1'b1, sdhc, 6'h0, 9'h1f, 15'h0 }; // bit31 = finished powerup
|
||||
// bit30 = 1 -> high capaciry card (sdhc)
|
||||
// 15-23 supported voltage range
|
||||
wire [7:0] READ_DATA_TOKEN = 8'hfe;
|
||||
|
||||
// number of bytes to wait after a command before sending the reply
|
||||
@ -131,12 +134,16 @@ assign sd_conf = sd_configuring;
|
||||
|
||||
reg sd_configuring = 1;
|
||||
reg [4:0] conf_buff_ptr;
|
||||
reg [7:0] conf_byte;
|
||||
reg [7:0] conf_byte_orig;
|
||||
reg[255:0] csdcid;
|
||||
|
||||
reg vhd = 0;
|
||||
reg [40:0] vhd_size;
|
||||
|
||||
// conf[0]==1 -> io controller is using an sdhc card
|
||||
wire sd_has_sdhc = conf[0];
|
||||
assign sd_sdhc = allow_sdhc && sd_has_sdhc;
|
||||
assign sd_sdhc = (allow_sdhc & sd_has_sdhc) | vhd; // report to user_io
|
||||
wire sdhc = allow_sdhc & (sd_has_sdhc | vhd); // used internally
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
reg old_mounted;
|
||||
@ -148,22 +155,72 @@ always @(posedge clk_sys) begin
|
||||
end
|
||||
else csdcid[(31-sd_buff_addr) << 3 +:8] <= sd_buff_dout;
|
||||
end
|
||||
conf_byte <= csdcid[(31-conf_buff_ptr) << 3 +:8];
|
||||
conf_byte_orig <= csdcid[(31-conf_buff_ptr) << 3 +:8];
|
||||
|
||||
old_mounted <= img_mounted;
|
||||
if (~old_mounted & img_mounted) begin
|
||||
// update card size in case of a virtual SD image
|
||||
if (sd_sdhc)
|
||||
// CSD V2.0 size = (c_size + 1) * 512K
|
||||
csdcid[69:48] <= {9'd0, img_size[31:19] } - 1'd1;
|
||||
else begin
|
||||
// CSD V1.0 no. of blocks = c_size ** (c_size_mult + 2)
|
||||
csdcid[49:47] <= 3'd7; //c_size_mult
|
||||
csdcid[73:62] <= img_size[29:18]; //c_size
|
||||
end
|
||||
vhd <= |img_size;
|
||||
vhd_size <= img_size[40:0];
|
||||
end
|
||||
end
|
||||
|
||||
// CSD V1.0 no. of blocks = c_size ** (c_size_mult + 2)
|
||||
wire [127:0] csd_sd = {
|
||||
8'h00, // CSD_STRUCTURE + reserved
|
||||
8'h2d, // TAAC
|
||||
8'd0, // NSAC
|
||||
8'h32, // TRAN_SPEED
|
||||
12'h5b5, // CCC
|
||||
4'h9, // READ_BL_LEN
|
||||
1'b1, 1'b0, 1'b0, 1'b0, // READ_BL_PARTIAL, WRITE_BLK_MISALIGN, READ_BLK_MISALIGN, DSR_IMP
|
||||
2'd0, vhd_size[29:18], // reserved + C_SIZE
|
||||
3'b111, // VDD_R_CURR_MIN
|
||||
3'b110, // VDD_R_CURR_MAX
|
||||
3'b111, // VDD_W_CURR_MIN
|
||||
3'b110, // VDD_W_CURR_MAX
|
||||
3'd7, // C_SIZE_MULT
|
||||
1'b1, // ERASE_BLK_EN
|
||||
7'd127, // SECTOR_SIZE
|
||||
7'd0, // WP_GRP_SIZE
|
||||
1'b0, // WP_GRP_ENABLE,
|
||||
2'b00, // reserved,
|
||||
3'd5, // R2W_FACTOR,
|
||||
4'h9, // WRITE_BL_LEN,
|
||||
1'b0, // WRITE_BL_PARTIAL,
|
||||
5'd0, // reserved,
|
||||
8'd0,
|
||||
7'h67, // CRC (wrong, but usually not checked)
|
||||
1'b1 };
|
||||
|
||||
// CSD V2.0 size = (c_size + 1) * 512K
|
||||
wire [127:0] csd_sdhc = {
|
||||
8'h40, // CSD_STRUCTURE + reserved
|
||||
8'h0e, // TAAC
|
||||
8'd0, // NSAC
|
||||
8'h32, // TRAN_SPEED
|
||||
12'h5b5, // CCC
|
||||
4'h9, // READ_BL_LEN
|
||||
1'b0, 1'b0, 1'b0, 1'b0, // READ_BL_PARTIAL, WRITE_BLK_MISALIGN, READ_BLK_MISALIGN, DSR_IMP
|
||||
6'd0, // reserved
|
||||
vhd_size[40:19] - 1'd1, // C_SIZE
|
||||
1'b0, // reserved
|
||||
1'b1, // ERASE_BLK_EN
|
||||
7'd127, // SECTOR_SIZE
|
||||
7'd0, // WP_GRP_SIZE
|
||||
1'b0, // WP_GRP_ENABLE,
|
||||
2'b00, // reserved,
|
||||
3'd2, // R2W_FACTOR,
|
||||
4'h9, // WRITE_BL_LEN,
|
||||
1'b0, // WRITE_BL_PARTIAL,
|
||||
5'd0, // reserved,
|
||||
8'd0,
|
||||
7'h78, // CRC (wrong, but usually not checked)
|
||||
1'b1 };
|
||||
|
||||
wire [7:0] conf_byte = (!conf_buff_ptr[4] | !vhd) ? conf_byte_orig : // CID or CSD if not VHD
|
||||
sdhc ? csd_sdhc[(15-conf_buff_ptr[3:0]) << 3 +:8] :
|
||||
csd_sd[(15-conf_buff_ptr[3:0]) << 3 +:8];
|
||||
|
||||
always@(posedge clk_sys) begin
|
||||
|
||||
reg old_sd_sck;
|
||||
@ -223,7 +280,7 @@ always@(posedge clk_sys) begin
|
||||
RD_STATE_WAIT_BUSY:
|
||||
if (~sd_busy) begin
|
||||
sd_buff_sel <= 0;
|
||||
sd_lba <= sd_sdhc?args[39:8]:{9'd0, args[39:17]};
|
||||
sd_lba <= sdhc?args[39:8]:{9'd0, args[39:17]};
|
||||
sd_rd <= 1; // trigger request to io controller
|
||||
sd_busy <= 1;
|
||||
read_state <= RD_STATE_WAIT_IO;
|
||||
@ -501,7 +558,7 @@ always@(posedge clk_sys) begin
|
||||
if (~sd_busy) begin
|
||||
if (wr_first) begin
|
||||
sd_buff_sel <= 0;
|
||||
sd_lba <= sd_sdhc?args[39:8]:{9'd0, args[39:17]};
|
||||
sd_lba <= sdhc?args[39:8]:{9'd0, args[39:17]};
|
||||
wr_first <= 0;
|
||||
end else begin
|
||||
sd_buff_sel <= !sd_buff_sel;
|
||||
|
||||
@ -40,8 +40,8 @@ module user_io (
|
||||
output reg [31:0] joystick_2,
|
||||
output reg [31:0] joystick_3,
|
||||
output reg [31:0] joystick_4,
|
||||
output reg [15:0] joystick_analog_0,
|
||||
output reg [15:0] joystick_analog_1,
|
||||
output reg [31:0] joystick_analog_0,
|
||||
output reg [31:0] joystick_analog_1,
|
||||
output [1:0] buttons,
|
||||
output [1:0] switches,
|
||||
output scandoubler_disable,
|
||||
@ -104,6 +104,7 @@ parameter PS2DIV=100; // master clock divider for psk2_kbd/mouse clk
|
||||
parameter ROM_DIRECT_UPLOAD=0; // direct upload used for file uploads from the ARM
|
||||
parameter SD_IMAGES=2; // number of block-access images (max. 4 supported in current firmware)
|
||||
parameter PS2BIDIR=0; // bi-directional PS2 interface
|
||||
parameter FEATURES=0; // requested features from the firmware
|
||||
|
||||
localparam W = $clog2(SD_IMAGES);
|
||||
|
||||
@ -139,8 +140,8 @@ wire [7:0] sd_cmd = { 4'h6, sd_conf, sd_sdhc, sd_wr[drive_sel], sd_rd[drive_sel]
|
||||
wire spi_sck = SPI_CLK;
|
||||
|
||||
// ---------------- PS2 ---------------------
|
||||
// 8 byte fifos to store ps2 bytes
|
||||
localparam PS2_FIFO_BITS = 3;
|
||||
// 16 byte fifos to store ps2 bytes
|
||||
localparam PS2_FIFO_BITS = 4;
|
||||
|
||||
reg ps2_clk;
|
||||
always @(posedge clk_sys) begin
|
||||
@ -495,6 +496,11 @@ always@(posedge spi_sck or posedge SPI_SS_IO) begin : spi_transmitter
|
||||
if(byte_cnt[0]) spi_byte_out <= serial_out_status;
|
||||
else spi_byte_out <= serial_out_byte;
|
||||
|
||||
// core features
|
||||
8'h80:
|
||||
if (byte_cnt == 0) spi_byte_out <= 8'h80;
|
||||
else spi_byte_out <= FEATURES[(4-byte_cnt)<<3 +:8];
|
||||
|
||||
endcase
|
||||
end
|
||||
end
|
||||
@ -624,6 +630,18 @@ always @(posedge clk_sys) begin : cmd_block
|
||||
joystick_analog_0[7:0] <= spi_byte_in;
|
||||
else if(stick_idx == 1)
|
||||
joystick_analog_1[7:0] <= spi_byte_in;
|
||||
end else if(abyte_cnt == 4) begin
|
||||
// fourth byte is 2nd x axis
|
||||
if(stick_idx == 0)
|
||||
joystick_analog_0[31:24] <= spi_byte_in;
|
||||
else if(stick_idx == 1)
|
||||
joystick_analog_1[31:24] <= spi_byte_in;
|
||||
end else if(abyte_cnt == 5) begin
|
||||
// fifth byte is 2nd y axis
|
||||
if(stick_idx == 0)
|
||||
joystick_analog_0[23:16] <= spi_byte_in;
|
||||
else if(stick_idx == 1)
|
||||
joystick_analog_1[23:16] <= spi_byte_in;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user